[DRE-commits] [ruby-gnome2] 18/31: New upstream version 3.0.8

Daisuke Higuchi dai at moszumanska.debian.org
Mon Oct 10 13:40:19 UTC 2016


This is an automated email from the git hooks/post-receive script.

dai pushed a commit to branch exp/debian
in repository ruby-gnome2.

commit 103ba97d4f9d5e13e401feb85f8577683ce9cd90
Author: HIGUCHI Daisuke (VDR dai) <dai at debian.org>
Date:   Sun Oct 9 21:56:50 2016 +0900

    New upstream version 3.0.8
---
 .travis.yml                                        |   6 +-
 NEWS                                               | 270 ++++++++++
 Rakefile                                           |   4 +-
 atk/Rakefile                                       |   2 +-
 atk/ext/atk/extconf.rb                             |   1 +
 build/Vagrantfile                                  |   4 +-
 build/build-windows.sh                             |   9 +-
 cairo-gobject/ext/cairo-gobject/extconf.rb         |   1 +
 clutter-gstreamer/Rakefile                         |   2 +-
 clutter-gtk/Rakefile                               |   2 +-
 clutter/Rakefile                                   |   6 +-
 gdk3-no-gi/ext/gdk3-no-gi/extconf.rb               |   1 +
 gdk3/Rakefile                                      |   7 +-
 gdk3/patches/gtk+-3.16.6-add-missing-exeext.diff   |  24 -
 gdk_pixbuf2/Rakefile                               |   2 +-
 gdk_pixbuf2/ext/gdk_pixbuf2/extconf.rb             |   1 +
 gio2/ext/gio2/extconf.rb                           |   1 +
 gio2/ext/gio2/rb-gio2.c                            |  45 --
 gio2/lib/gio2/application-command-line.rb          |  12 +
 gio2/test/test-application-command-line.rb         |   6 +-
 glib2/Rakefile                                     |  36 +-
 glib2/ext/glib2/extconf.rb                         |   1 +
 glib2/ext/glib2/glib2.def                          |   4 +
 glib2/ext/glib2/rbglib-variant.c                   | 175 ++++++-
 glib2/ext/glib2/rbglib.c                           |  39 +-
 glib2/ext/glib2/rbglib.h                           |  16 +-
 glib2/ext/glib2/rbglib2conversions.h               |   3 +
 glib2/ext/glib2/rbglib_iochannel.c                 |   3 -
 glib2/ext/glib2/rbglib_iochannel_win32_socket.c    |   1 -
 glib2/ext/glib2/rbglib_matchinfo.c                 | 179 +++++++
 glib2/ext/glib2/rbglib_regex.c                     | 484 +++++++++++++++++
 glib2/ext/glib2/rbgobj_value.c                     |   8 +-
 glib2/ext/glib2/rbgprivate.h                       |   2 +
 glib2/ext/glib2/rbgutil.c                          |   7 +
 glib2/ext/glib2/rbgutil.h                          |   2 +
 glib2/lib/glib2.rb                                 |   3 +-
 .../test-gtk-box.rb => glib2/lib/glib2/regex.rb    |  17 +-
 glib2/lib/gnome2/rake/external-package.rb          |   7 +-
 glib2/lib/gnome2/rake/package-task.rb              |   2 +-
 glib2/lib/gnome2/rake/package.rb                   |   9 +
 glib2/lib/gnome2/rake/windows-binary-build-task.rb |  46 +-
 glib2/lib/mkmf-gnome2.rb                           |   4 +-
 glib2/patches/glib-2.38.2-add-missing-exeext.diff  |  24 -
 glib2/patches/glib-2.48.0-add-missing-exeext.diff  |  36 ++
 glib2/test/test-match-info.rb                      | 113 ++++
 glib2/test/test-regex.rb                           | 320 ++++++++++++
 gobject-introspection/Rakefile                     |   4 +-
 .../ext/gobject-introspection/extconf.rb           |   1 +
 .../ext/gobject-introspection/rb-gi-argument.c     | 149 +++++-
 .../gobject-introspection/rb-gi-function-info.c    | 577 ++++++++++++++++++++-
 .../ext/gobject-introspection/rb-gi-repository.c   |   9 +
 .../rb-gobject-introspection.h                     |   3 +
 .../lib/gobject-introspection/loader.rb            |   2 +-
 .../patches/cross-g-ir-scanner.diff                |  90 ++--
 .../patches/support-external-g-ir-scanner.diff     |  97 ++--
 gstreamer/Rakefile                                 |  52 +-
 gstreamer/ext/gstreamer/extconf.rb                 |   1 +
 ...2-remove-introspection-compiler-dependency.diff |  36 --
 .../gst-plugins-bad-1.5.2-use-portable-cast.diff   |  12 -
 .../gst-plugins-bad-1.8.0-add-missing-lole32.diff  |  12 +
 ....diff => gst-plugins-bad-1.8.0-use-only-I.diff} |  10 +-
 ...2-remove-introspection-compiler-dependency.diff | 132 -----
 ...5.2-use-portable-64bit-data-print-modifier.diff |  12 -
 .../gst-plugins-base-1.5.2-use-portable-cast.diff  |  21 -
 ...2-remove-introspection-compiler-dependency.diff |  60 ---
 gstreamer/sample/stream-status.rb                  |   4 +-
 gtk2/Rakefile                                      |   4 +-
 gtk2/ext/gtk2/extconf.rb                           |   1 +
 gtk2/sample/misc/threads.rb                        |   1 -
 gtk3-no-gi/ext/gtk3/extconf.rb                     |   1 +
 gtk3/ext/gtk3/extconf.rb                           |   1 +
 gtk3/ext/gtk3/rb-gtk3-tree-view.c                  |   4 +
 gtk3/ext/gtk3/rb-gtk3.c                            | 305 ++++++++---
 gtk3/lib/gtk3/box.rb                               |  22 +
 gtk3/lib/gtk3/builder.rb                           |  79 +--
 gtk3/lib/gtk3/deprecated.rb                        |   7 +
 gtk3/lib/gtk3/{menu-item.rb => entry-buffer.rb}    |  15 +-
 gtk3/lib/gtk3/list-store.rb                        |  22 +-
 gtk3/lib/gtk3/loader.rb                            |   6 +
 gtk3/lib/gtk3/menu-item.rb                         |  15 +-
 gtk3/lib/gtk3/tree-iter.rb                         |  26 +-
 gtk3/lib/gtk3/tree-model.rb                        |  41 ++
 gtk3/lib/gtk3/tree-store.rb                        |  13 +-
 gtk3/lib/gtk3/widget.rb                            |  19 +-
 gtk3/sample/gtk-demo/TODO                          |  84 +--
 gtk3/sample/gtk-demo/assistant.rb                  | 123 +++++
 gtk3/sample/gtk-demo/builder.rb                    | 113 ++--
 gtk3/sample/gtk-demo/button-box.rb                 |  82 ---
 gtk3/sample/gtk-demo/button_box.rb                 | 100 ++++
 gtk3/sample/gtk-demo/colorsel.rb                   | 114 ++--
 gtk3/sample/gtk-demo/css_accordion.rb              |  88 ++--
 gtk3/sample/gtk-demo/css_basics.rb                 | 135 ++---
 gtk3/sample/gtk-demo/css_multiplebgs.rb            | 112 ++++
 gtk3/sample/gtk-demo/css_pixbufs.rb                |  84 +++
 gtk3/sample/gtk-demo/css_shadows.rb                | 101 ++++
 gtk3/sample/gtk-demo/cursors.rb                    | 114 ++++
 gtk3/sample/gtk-demo/dialog.rb                     | 220 ++++----
 gtk3/sample/gtk-demo/entry_buffer.rb               |  44 ++
 gtk3/sample/gtk-demo/entry_completion.rb           |  92 ++--
 gtk3/sample/gtk-demo/expander.rb                   |  86 ++-
 gtk3/sample/gtk-demo/filtermodel.rb                | 119 +++++
 gtk3/sample/gtk-demo/font_features.rb              | 117 +++++
 gtk3/sample/gtk-demo/headerbar.rb                  |  57 ++
 gtk3/sample/gtk-demo/iconview_edit.rb              |  79 +++
 gtk3/sample/gtk-demo/infobar.rb                    | 134 ++---
 gtk3/sample/gtk-demo/links.rb                      |  93 ++--
 gtk3/sample/gtk-demo/main.rb                       | 396 ++++++++++++--
 gtk3/sample/gtk-demo/main.ui                       |  18 +-
 gtk3/sample/gtk-demo/markup.rb                     |  46 ++
 gtk3/sample/gtk-demo/menus.rb                      | 273 ++++------
 gtk3/sample/gtk-demo/modelbutton.rb                |  47 ++
 gtk3/sample/gtk-demo/overlay.rb                    |  61 +++
 gtk3/sample/gtk-demo/overlay2.rb                   |  75 +++
 gtk3/sample/gtk-demo/panes.rb                      | 247 ++++-----
 gtk3/sample/gtk-demo/pickers.rb                    |  70 +++
 gtk3/sample/gtk-demo/popover.rb                    | 110 ++++
 gtk3/sample/gtk-demo/printing.rb                   | 151 +++---
 gtk3/sample/gtk-demo/revealer.rb                   |  53 ++
 gtk3/sample/gtk-demo/scale.rb                      |  26 +
 gtk3/sample/gtk-demo/search_entry2.rb              | 107 ++++
 gtk3/sample/gtk-demo/sidebar.rb                    |  68 +++
 gtk3/sample/gtk-demo/sizegroup.rb                  | 198 ++++---
 gtk3/sample/gtk-demo/spinner.rb                    | 103 ++--
 gtk3/sample/gtk-demo/stack.rb                      |  28 +
 gtk3/sample/gtk-demo/test_mod.rb                   |  22 +
 gtk3/sample/gtk-demo/textmask.rb                   |  61 +++
 gtk3/sample/gtk-demo/theming_style_classes.rb      |  28 +-
 gtk3/sample/misc/app-menu.ui                       |  19 +
 gtk3/sample/misc/button-menu.ui                    |  19 +
 gtk3/sample/misc/icons-theme-viewer.rb             |  65 +++
 gtk3/sample/misc/menu.rb                           |   6 +-
 .../sample/misc/menus_from_resources.gresource.xml |   8 +
 gtk3/sample/misc/menus_from_resources.rb           |  91 ++++
 gtk3/sample/misc/statusicon.rb                     |   2 +-
 gtk3/sample/misc/toolbar-menu.ui                   |  23 +
 gtk3/sample/misc/treestore.rb                      |  63 +++
 gtk3/sample/tutorial/README.md                     | 374 ++++++++++++-
 gtk3/test/test-gtk-box.rb                          |  13 +
 gtk3/test/test-gtk-builder.rb                      |   2 +-
 gtk3/test/test-gtk-clipboard.rb                    | 124 +++++
 gtk3/test/test-gtk-container.rb                    |   6 +-
 .../{test-gtk-box.rb => test-gtk-entry-buffer.rb}  |  16 +-
 gtk3/test/test-gtk-list-store.rb                   |  42 +-
 gtk3/test/{test-gtk-box.rb => test-gtk-menu.rb}    |  24 +-
 gtk3/test/test-gtk-tree-iter.rb                    |  66 ++-
 gtk3/test/test-gtk-tree-path.rb                    |  27 +-
 .../{test-gtk-box.rb => test-gtk-tree-sortable.rb} |  21 +-
 .../{test-gtk-box.rb => test-gtk-tree-store.rb}    |  20 +-
 gtk3/test/test-gtk-widget.rb                       |  35 +-
 gtksourceview2/ext/gtksourceview2/extconf.rb       |   1 +
 gtksourceview3-no-gi/ext/gtksourceview3/extconf.rb |   1 +
 gtksourceview3/Rakefile                            |   2 +-
 gvlc/ext/gvlc/extconf.rb                           |   1 +
 pango/Rakefile                                     |  12 +-
 pango/ext/pango/extconf.rb                         |   1 +
 pango/lib/pango.rb                                 |  12 +-
 poppler/Rakefile                                   |  12 +-
 poppler/ext/poppler/extconf.rb                     |   1 +
 poppler/ext/poppler/rbpoppler.c                    |   1 -
 poppler/lib/poppler.rb                             |   2 +-
 poppler/test/poppler-test-utils.rb                 |   2 +-
 release.rd                                         |  51 +-
 rsvg2/Rakefile                                     |   4 +-
 rsvg2/ext/rsvg2/extconf.rb                         |   1 +
 travis-before-script.sh                            |   6 +-
 vte/ext/vte/extconf.rb                             |   1 +
 vte3-no-gi/ext/vte3/extconf.rb                     |   1 +
 vte3/Rakefile                                      |   2 +-
 webkit2-gtk/Rakefile                               |   4 +-
 webkit2-gtk/lib/webkit2-gtk.rb                     |   2 +-
 170 files changed, 7353 insertions(+), 2125 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 3b6b898..7a71363 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,5 @@
+sudo: required
+dist: trusty
 env:
   global:
     - DISPLAY=":99.0"
@@ -6,14 +8,16 @@ notifications:
     recipients:
       - ruby-gnome2-cvs at lists.sourceforge.net
 rvm:
-  - 2.0.0
   - 2.1
   - 2.2
+  - 2.3.0
   - ruby-head
 matrix:
   # allow_failures:
   #   - rvm: 2.1
   fast_finish: true
+before_install:
+  - gem install bundler
 before_script:
   - ./travis-before-script.sh
   - sh -e /etc/init.d/xvfb start
diff --git a/NEWS b/NEWS
index c5f8c72..ba0a661 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,276 @@
 
 = NEWS
 
+== Ruby-GNOME2 3.0.8: 2016-04-03
+
+It's a release that improves GTK+ 3 support.
+
+=== Changes
+
+==== All
+
+  * Droped Ruby 2.0.0 support.
+  * Travis: use Trusty beta image.
+    [Patch by Hiroshi Hatake]
+  * Added AltLinux to supported OSes.
+    [Patch by Malo Skrylevo]
+
+==== Ruby/GLib2
+
+  * Improvements
+    * Added (({RVAL2CSTR_PTR_ACCEPT_NIL})).
+    * Added (({RVAL2CSTR_RAW})).
+    * Added (({RVAL2CSTR_RAW_ACCEPT_NIL})).
+    * Supported (({GLib::Variant.new(value, type)})).
+    * Added (({GLib::Regex})) class.
+      [Patch by cedlemo]
+    * Supported more variant types in (({rbg_variant_to_ruby})).
+      [Patch by Aurélien Jacobs]
+    * Supported array in (({rg_ruby_to_variant})).
+      [Patch by Aurélien Jacobs]
+    * Added (({GLib::Regex#split})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#match})).
+      [Patch by cedlemo]
+    * Added (({GLib::MatchInfo})) class.
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#max_backref})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#capture_count})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#has_cr_or_lf?})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#max_lookbehind})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#string_number})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex.escape_string})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#match?})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#match_all})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#split})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#replace})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#check_replacement})).
+      [Patch by cedlemo]
+    * Added (({GLib::Regex#replace_eval})).
+      [Patch by cedlemo]
+    * Added (({GLib::MatchInfo#partial_match})).
+      [Patch by cedlemo]
+    * Added (({GLib::MatchInfo#fetch})).
+      [Patch by cedlemo]
+    * Added (({GLib::MatchInfo#[]})).
+    * Added (({GLib::MatchInfo#fetch_pos})).
+      [Patch by cedlemo]
+    * Added (({GLib::MatchInfo#fetch_position})).
+    * Added (({GLib::MatchInfo#fetch_all})).
+      [Patch by cedlemo]
+    * Added (({GLib::MatchInfo#next})).
+      [Patch by cedlemo]
+
+  * Fixes
+    * Fixed a bug that raw string is converted to UTF-8.
+    * Fixed handling of 64 bits (({FIXNUM})) variant initialization.
+
+==== Ruby/GObjectIntrospection
+
+  * Improvements
+    * Supported allocated output parameter.
+    * Supported dynamic callback.
+    * Supported enum as output value.
+    * Added function type name in error message.
+    * Added (({RB_ZALLOC})).
+    * Supported freeing GType-ed union.
+      [GitHub#700][Reported by cedlemo]
+    * Added (({GI::Repository#get_version})).
+  * Fixes
+    * Fixed a bug that block is always ignored in singleton method.
+      [ruby-gnome2-devel-ja][Reported by Yuuki Harano]
+
+==== Ruby/GIO2
+
+  * Improvements
+    * Supported (({Gio::Application.new(:arguments => [...]})).
+      [GitHub#519][Reported by Mamoru TASAKA]
+    * Started to use dynamic callback.
+
+==== Ruby/GTK3
+
+  * Improvements
+    * Supported (({Gtk::Clipboard#request_text})).
+      [ruby-gnome2-devel-en][Reported by Detlef Reichl]
+    * Supported (({Gtk::Clipboard#request_contents})).
+    * Supported (({Gtk::Clipboard#request_image})).
+    * Supported (({Gtk::Clipboard#request_targets})).
+    * Supported (({Gtk::Clipboard#request_rich_text})).
+    * Supported (({Gtk::Clipboard#request_uris})).
+    * Updated main demo application.
+      [Patch by cedlemo]
+    * Updated and finished sample tutorial.
+      [Patch by cedlemo]
+    * Supported (({Gtk::TreeModel#set_sort_func})).
+      [GitHub#596][Reported by Christopher L. Ramsey]
+    * Supported (({Gtk::Box#set_child_packing})).
+      [GitHub#602][Reported by Ibrahim Tencer]
+    * Updated stack demo.
+      [Patch by cedlemo]
+    * Added scale demo.
+      [Patch by cedlemo]
+    * Updated theming style classes demo.
+      [Patch by cedlemo]
+    * Created entry buffer demo.
+      [Patch by cedlemo]
+    * Made (({Gtk::EntryBuffer#new more rubyish})).
+      [Patch by cedlemo]
+    * Added markup demo.
+      [Patch by cedlemo]
+    * Added headerbar demo.
+      [Patch by cedlemo]
+    * Updated css accordion demo.
+      [Patch by cedlemo]
+    * Added pickers demo.
+      [Patch by cedlemo]
+    * Updated links demo.
+      [Patch by cedlemo]
+    * Added overlay demo.
+      [Patch by cedlemo]
+    * Added textmask demo.
+      [Patch by cedlemo]
+    * Added sidebar demo.
+      [Patch by cedlemo]
+    * Updated spinner demo.
+      [Patch by cedlemo]
+    * Updated entry completion demo.
+      [Patch by cedlemo]
+    * Added revealer demo.
+      [Patch by cedlemo]
+    * Updated expander demo.
+      [Patch by cedlemo]
+    * Added overlay2 demo.
+      [Patch by cedlemo]
+    * Updated colorsel demo.
+      [Patch by cedlemo]
+    * (({rbgobj_gc_mark_instance})) has to be called
+      for the (({Gtk::TreeSelection})).
+      [Patch by Hiroyuki Ito]
+    * Updated css basics demo.
+      [Patch by cedlemo]
+    * Made (({Gtk::TreeModel#iter_nth_child})) and
+      (({Gtk::TreeModel#iter_children})) work like
+      (({#get_value})).
+    * Added methods to Gtk::TreeIter:
+        * (({Gtk::TreeIter#previous!}))
+        * (({Gtk::TreeIter#has_child?}))
+        * (({Gtk::TreeIter#n_children}))
+        * (({Gtk::TreeIter#nth_child}))
+        * (({Gtk::TreeIter#children})).
+      [Patch by Hiroyuki Ito]
+    * Added support for (({Gtk::TreeSelection})).
+      [Patch by dutchhome]
+    * Updated builder demo.
+      [Patch by cedlemo]
+    * Updated css pixbufs demo.
+      [Patch by cedlemo]
+    * Updated button box demo.
+      [Patch by cedlemo]
+    * Created css shadows demo.
+      [Patch by cedlemo]
+    * Updated infobar demo.
+      [Patch by cedlemo]
+    * Added support for MenuPositionFunc in
+      (({Gtk::Menu#popup})).
+      [GitHub#61][Reported by Abby Archer]
+    * Made (({Gtk::Widget#translate_coordinates})) more
+      rubyish.
+      [Patch by cedlemo]
+    * Added support for (({EntryCompletionMatchFunc})).
+      [Patch by Hiroyuki Ito]
+    * Updated iconview edit demo.
+      [Patch by cedlemo]
+    * Updated sizegroup demo.
+      [Patch by cedlemo]
+    * Updated cursors demo.
+      [Patch by cedlemo]
+    * Made (({Gtk::MenuItem#new})) like
+      (({Gtk::CheckMenuItem#new})).
+      [Patch by Hiroyuki Ito]
+    * Move the (({#set_values})) implementation to
+      (({Gtk::TreeModel})) instead of (({Gtk::ListStore})).
+      [GitHub#659][Reported by detlef]
+    * Updated search entry2 demo.
+      [Patch by cedlemo]
+    * Updated menus demo.
+      [Patch by cedlemo]
+    * Updated css multiplebgs demo.
+      [Patch by cedlemo]
+    * Added auto generated callback for AssistantPageFunc.
+    * Added auto generated callback for BuilderConnectFunc.
+    * Updated model button demo.
+      [Patch by cedlemo]
+    * Updated dialog demo.
+      [Patch by cedlemo]
+    * Added another example sample for (({Gtk::TreeStore})).
+      [Patch by cedlemo]
+    * Added the methods:
+        * (({Gtk::TreePath#next!}))
+        * (({Gtk::TreePath#prev!}))
+        * (({Gtk::TreePath#up!}))
+        * (({Gtk::TreePath#down!})).
+      [Patch by cedlemo]
+    * Added (({Gtk::TreeIter#first_child})).
+      [Patch by cedlemo]
+    * Updated filtermodel demo.
+      [Patch by cedlemo]
+    * Updated popover demo.
+      [Patch by cedlemo]
+    * Supported (({Gtk::Builder#connect_signals})).
+    * Added new sample icons-theme-viewer.rb.
+      [Patch by cedlemo]
+    * Added new sample menus_from_resources.rb.
+      [Patch by cedlemo]
+    * Updated printing demo.
+      [Patch by cedlemo]
+    * Updated assistant demo.
+      [Patch by cedlemo]
+    * Updated panes demo.
+      [Patch by cedlemo]
+    * Updated font features demo.
+      [Patch by cedlemo]
+
+  * Fixes:
+    * Fixed a bug that (({Gtk::Widget.set_connect_func})) doesn't work.
+      [GitHub#703][Reported by cedlemo]
+
+==== Ruby/Poppler
+
+  * Improvements:
+    * Removed needless (({POPPLER_TYPE_ORIENTATION})) binding.
+      [GiHub#653][Reported by Rob Brackett]
+
+==== Ruby/WebKit2GTK
+
+  * Improvements:
+    * Supported old WebKit2GTK+.
+
+=== Thanks
+
+  * Detlef Reichl
+  * Mamoru TASAKA
+  * cedlemo
+  * Christopher L. Ramsey
+  * Hiroyuki Ito
+  * dutchhome Jon Raiford
+  * Rob Brackett
+  * Abby Archer
+  * Yuuki Harano
+  * detlef
+  * Aurélien Jacobs
+  * Hiroshi Hatake
+  * Malo Skrylevo
+
 == Ruby-GNOME2 3.0.7: 2015-10-06
 
 It is a bug fix release of 3.0.6.
diff --git a/Rakefile b/Rakefile
index 2615812..8ccecbc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -113,7 +113,7 @@ namespace :windows do
     architectures.each do |architecture|
       desc "build all packages for Windows #{architecture}"
       task_name = "win#{architecture}"
-      build_tasks << task_name
+      build_tasks << "windows:build:#{task_name}"
       task task_name do
         cd("build") do
           sh("vagrant", "destroy", "--force", task_name)
@@ -196,7 +196,7 @@ namespace :dist do
     package(gnome2_base_name, base_files + gnome2_packages)
   end
 
-  ruby_versions = ["2.0.0-p645", "2.1.6", "2.2.2"]
+  ruby_versions = ["2.1.10", "2.2.4", "2.3.0"]
   namespace :test do
     ruby_base_url = "ftp://ftp.ruby-lang.org/pub/ruby"
     ruby_versions.each do |ruby_version|
diff --git a/atk/Rakefile b/atk/Rakefile
index d775e90..5013e5a 100644
--- a/atk/Rakefile
+++ b/atk/Rakefile
@@ -15,7 +15,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "atk",
       :download_site => :gnome,
       :label => "atk",
-      :version => "2.16.0",
+      :version => "2.20.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/atk/ext/atk/extconf.rb b/atk/ext/atk/extconf.rb
index aef1a80..9b04d98 100644
--- a/atk/ext/atk/extconf.rb
+++ b/atk/ext/atk/extconf.rb
@@ -45,6 +45,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 1, 12, 0],
+                                   :altlinux => "libatk-devel",
                                    :debian => "libatk1.0-dev",
                                    :redhat => "atk-devel",
                                    :arch => "atk",
diff --git a/build/Vagrantfile b/build/Vagrantfile
index 84483b6..ca809f2 100644
--- a/build/Vagrantfile
+++ b/build/Vagrantfile
@@ -12,8 +12,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 
   targets.each do |target|
     config.vm.define(target) do |node|
-      node.vm.box = "ubuntu-15.04-x86_64"
-      node.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-15.04_chef-provisionerless.box"
+      node.vm.box = "ubuntu-15.10-x86_64"
+      node.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-15.10_chef-provisionerless.box"
 
       node.vm.synced_folder("../", "/ruby-gnome2")
       node.vm.synced_folder("../../pkg-config", "/pkg-config")
diff --git a/build/build-windows.sh b/build/build-windows.sh
index 375e684..d0edcdb 100755
--- a/build/build-windows.sh
+++ b/build/build-windows.sh
@@ -3,8 +3,8 @@
 export LANG=C
 export DEBIAN_FRONTEND=noninteractive
 
-ruby_versions="2.0.0-p647 2.1.7 2.2.3"
-export RUBY_CC_VERSION="2.0.0:2.1.7:2.2.3"
+ruby_versions="2.1.10 2.2.4 2.3.0"
+export RUBY_CC_VERSION="2.1.10:2.2.4:2.3.0"
 
 N_CPUS=$(grep '^processor' /proc/cpuinfo | wc -l)
 export MAKE_N_JOBS=${N_CPUS}
@@ -53,7 +53,8 @@ if [ ! -f ~/setup.timestamp ]; then
     python-dev \
     wine1.6 \
     mingw-w64 \
-    cmake
+    cmake \
+    valac
 
   run git clone file:///pkg-config/.git
   run git clone file:///rcairo/.git rcairo.${DIRECTORY_SUFFIX}
@@ -72,7 +73,7 @@ if [ ! -f ~/setup.timestamp ]; then
     until [ -f ~/.wine/system.reg ]; do
       sleep 1
     done
-    sleep 1
+    sleep 10
     wine_home="z:/home/vagrant"
     wine_rcairo="${wine_home}/rcairo.${DIRECTORY_SUFFIX}"
     wine_ruby_gnome2="${wine_home}/ruby-gnome2.${DIRECTORY_SUFFIX}"
diff --git a/cairo-gobject/ext/cairo-gobject/extconf.rb b/cairo-gobject/ext/cairo-gobject/extconf.rb
index 411ca63..03372f3 100755
--- a/cairo-gobject/ext/cairo-gobject/extconf.rb
+++ b/cairo-gobject/ext/cairo-gobject/extconf.rb
@@ -61,6 +61,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libcairo-devel",
                                    :debian => "libcairo2-dev",
                                    :fedora => "cairo-gobject-devel",
                                    :arch => "cairo",
diff --git a/clutter-gstreamer/Rakefile b/clutter-gstreamer/Rakefile
index 4a675d7..38ac8b6 100644
--- a/clutter-gstreamer/Rakefile
+++ b/clutter-gstreamer/Rakefile
@@ -46,7 +46,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "clutter-gst",
       :download_site => :gnome,
       :label => "Clutter-GStreamer",
-      :version => "3.0.10",
+      :version => "3.0.18",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/clutter-gtk/Rakefile b/clutter-gtk/Rakefile
index 2e78ed1..ce235a9 100644
--- a/clutter-gtk/Rakefile
+++ b/clutter-gtk/Rakefile
@@ -46,7 +46,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "clutter-gtk",
       :download_site => :gnome,
       :label => "Clutter-GTK",
-      :version => "1.6.2",
+      :version => "1.8.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/clutter/Rakefile b/clutter/Rakefile
index 9b9c14f..179b8ce 100644
--- a/clutter/Rakefile
+++ b/clutter/Rakefile
@@ -81,7 +81,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "cogl",
       :download_site => :gnome,
       :label => "Cogl",
-      :version => "1.20.0",
+      :version => "1.22.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -95,7 +95,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "json-glib",
       :download_site => :gnome,
       :label => "JSON-GLib",
-      :version => "1.0.4",
+      :version => "1.2.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -112,7 +112,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "clutter",
       :download_site => :gnome,
       :label => "Clutter",
-      :version => "1.22.4",
+      :version => "1.26.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/gdk3-no-gi/ext/gdk3-no-gi/extconf.rb b/gdk3-no-gi/ext/gdk3-no-gi/extconf.rb
index f7933c6..23f8196 100644
--- a/gdk3-no-gi/ext/gdk3-no-gi/extconf.rb
+++ b/gdk3-no-gi/ext/gdk3-no-gi/extconf.rb
@@ -49,6 +49,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libgtk+3-devel",
                                    :debian => "libgtk-3-dev",
                                    :fedora => "gtk3-devel",
                                    :homebrew => "gtk+3",
diff --git a/gdk3/Rakefile b/gdk3/Rakefile
index aad7536..0b74d95 100644
--- a/gdk3/Rakefile
+++ b/gdk3/Rakefile
@@ -59,7 +59,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gtk+",
       :download_site => :gnome,
       :label => "GTK+",
-      :version => "3.16.6",
+      :version => "3.20.2",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -67,7 +67,6 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
           "--with-included-immodules",
         ],
         :patches => [
-          "gtk+-3.16.6-add-missing-exeext.diff",
         ],
         :need_autoreconf => true,
         :build_concurrently => false,
@@ -76,7 +75,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "hicolor-icon-theme",
-      :download_base_url => "http://icon-theme.freedesktop.org/releases",
+      :download_base_url => "https://icon-theme.freedesktop.org/releases",
       :label => "gtk-hi-color-icon-theme",
       :version => "0.15",
       :compression_method => "xz",
@@ -90,7 +89,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "adwaita-icon-theme",
       :download_site => :gnome,
       :label => "adwaita-icon-theme",
-      :version => "3.16.2",
+      :version => "3.20",
       :compression_method => "xz",
       :windows => {
         :configure_args => [],
diff --git a/gdk3/patches/gtk+-3.16.6-add-missing-exeext.diff b/gdk3/patches/gtk+-3.16.6-add-missing-exeext.diff
deleted file mode 100644
index 609b5b9..0000000
--- a/gdk3/patches/gtk+-3.16.6-add-missing-exeext.diff
+++ /dev/null
@@ -1,24 +0,0 @@
-diff -ru gtk+-3.16.6.orig/demos/gtk-demo/Makefile.am gtk+-3.16.6/demos/gtk-demo/Makefile.am
---- gtk+-3.16.6.orig/demos/gtk-demo/Makefile.am	2015-07-21 21:07:10.000000000 +0900
-+++ gtk+-3.16.6/demos/gtk-demo/Makefile.am	2015-09-06 17:27:45.369228871 +0900
-@@ -173,7 +173,7 @@
- dist_appsicon48_DATA = data/48x48/gtk3-demo.png data/48x48/gtk3-demo-symbolic.symbolic.png
- dist_appsicon256_DATA = data/256x256/gtk3-demo.png data/256x256/gtk3-demo-symbolic.symbolic.png
- 
--update_icon_cache = $(top_builddir)/gtk/gtk-update-icon-cache --ignore-theme-index --force
-+update_icon_cache = $(top_builddir)/gtk/gtk-update-icon-cache$(EXEEXT) --ignore-theme-index --force
- 
- install-data-hook: install-update-icon-cache
- uninstall-hook: uninstall-update-icon-cache
-diff -ru gtk+-3.16.6.orig/demos/widget-factory/Makefile.am gtk+-3.16.6/demos/widget-factory/Makefile.am
---- gtk+-3.16.6.orig/demos/widget-factory/Makefile.am	2015-07-18 10:06:51.000000000 +0900
-+++ gtk+-3.16.6/demos/widget-factory/Makefile.am	2015-09-06 17:27:55.368984992 +0900
-@@ -47,7 +47,7 @@
- dist_appsicon48_DATA = data/48x48/gtk3-widget-factory.png data/48x48/gtk3-widget-factory-symbolic.symbolic.png
- dist_appsicon256_DATA = data/256x256/gtk3-widget-factory.png data/256x256/gtk3-widget-factory-symbolic.symbolic.png
- 
--update_icon_cache = $(top_builddir)/gtk/gtk-update-icon-cache --ignore-theme-index --force
-+update_icon_cache = $(top_builddir)/gtk/gtk-update-icon-cache$(EXEEXT) --ignore-theme-index --force
- 
- install-data-hook: install-update-icon-cache
- uninstall-hook: uninstall-update-icon-cache
diff --git a/gdk_pixbuf2/Rakefile b/gdk_pixbuf2/Rakefile
index b7e36c7..7e32f75 100644
--- a/gdk_pixbuf2/Rakefile
+++ b/gdk_pixbuf2/Rakefile
@@ -34,7 +34,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gdk-pixbuf",
       :download_site => :gnome,
       :label => "gdk-pixbuf",
-      :version => "2.30.8",
+      :version => "2.34.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/gdk_pixbuf2/ext/gdk_pixbuf2/extconf.rb b/gdk_pixbuf2/ext/gdk_pixbuf2/extconf.rb
index 4907c00..73e0d56 100644
--- a/gdk_pixbuf2/ext/gdk_pixbuf2/extconf.rb
+++ b/gdk_pixbuf2/ext/gdk_pixbuf2/extconf.rb
@@ -42,6 +42,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "gdk-pixbuf-devel",
                                    :debian => "libgdk-pixbuf2.0-dev",
                                    :redhat => "gtk2-devel",
                                    :fedora => "gdk-pixbuf2-devel",
diff --git a/gio2/ext/gio2/extconf.rb b/gio2/ext/gio2/extconf.rb
index f6e7a0e..3ec069c 100755
--- a/gio2/ext/gio2/extconf.rb
+++ b/gio2/ext/gio2/extconf.rb
@@ -52,6 +52,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libgio-devel",
                                    :debian => "libglib2.0-dev",
                                    :redhat => "glib2-devel",
                                    :arch => "glib2",
diff --git a/gio2/ext/gio2/rb-gio2.c b/gio2/ext/gio2/rb-gio2.c
index 20f0a82..1a8cbb1 100644
--- a/gio2/ext/gio2/rb-gio2.c
+++ b/gio2/ext/gio2/rb-gio2.c
@@ -22,49 +22,6 @@
 
 #define RG_TARGET_NAMESPACE rb_mGio
 
-static gboolean
-name_equal(GIArgInfo *info, const gchar *target_name)
-{
-    GITypeInfo type_info;
-    GIBaseInfo *interface_info;
-    const gchar *namespace;
-    const gchar *name;
-    gboolean equal_name_p = FALSE;
-
-    g_arg_info_load_type(info, &type_info);
-    interface_info = g_type_info_get_interface(&type_info);
-    namespace = g_base_info_get_namespace(interface_info);
-    name = g_base_info_get_name(interface_info);
-    if (strcmp(namespace, "Gio") == 0 && strcmp(name, target_name) == 0) {
-        equal_name_p = TRUE;
-    }
-    g_base_info_unref(interface_info);
-
-    return equal_name_p;
-}
-
-static void
-rb_gio2_async_ready_callback_callback(GObject *source_object,
-                                      GAsyncResult *result,
-                                      gpointer user_data)
-{
-    RBGICallbackData *callback_data = user_data;
-    ID id_call;
-
-    CONST_ID(id_call, "call");
-    rb_funcall(callback_data->rb_callback, id_call, 2,
-               GOBJ2RVAL(source_object), GOBJ2RVAL(result));
-}
-
-static gpointer
-rb_gio2_async_ready_callback_finder(GIArgInfo *info)
-{
-    if (!name_equal(info, "AsyncReadyCallback")) {
-        return NULL;
-    }
-    return rb_gio2_async_ready_callback_callback;
-}
-
 void
 Init_gio2 (void)
 {
@@ -74,6 +31,4 @@ Init_gio2 (void)
 
     rb_gio2_init_application(RG_TARGET_NAMESPACE);
     rb_gio2_init_pollable_source(RG_TARGET_NAMESPACE);
-
-    rb_gi_callback_register_finder(rb_gio2_async_ready_callback_finder);
 }
diff --git a/gio2/lib/gio2/application-command-line.rb b/gio2/lib/gio2/application-command-line.rb
index 97fbb30..c739064 100644
--- a/gio2/lib/gio2/application-command-line.rb
+++ b/gio2/lib/gio2/application-command-line.rb
@@ -16,6 +16,18 @@
 
 module Gio
   class ApplicationCommandLine
+    def initialize(properties=nil)
+      if properties
+        arguments = properties[:arguments]
+        if arguments and !arguments.is_a?(GLib::Variant)
+          arguments = GLib::Variant.new(arguments,
+                                        GLib::VariantType::BYTESTRING_ARRAY)
+          properties = properties.merge(:arguments => arguments)
+        end
+      end
+      super(properties)
+    end
+
     alias_method :arguments_raw, :arguments
     def arguments
       arguments_raw[0]
diff --git a/gio2/test/test-application-command-line.rb b/gio2/test/test-application-command-line.rb
index 441bb81..d699551 100644
--- a/gio2/test/test-application-command-line.rb
+++ b/gio2/test/test-application-command-line.rb
@@ -16,12 +16,10 @@
 
 class TestApplicationCommandLine < Test::Unit::TestCase
   include GioTestUtils::Omissions
-  def setup
-    @command_line = Gio::ApplicationCommandLine.new
-  end
 
   test "#arguments" do
     omit_on_travis_ci
-    assert_equal([], @command_line.arguments)
+    command_line = Gio::ApplicationCommandLine.new(:arguments => ["hello"])
+    assert_equal(["hello"], command_line.arguments)
   end
 end
diff --git a/glib2/Rakefile b/glib2/Rakefile
index 97872e7..03c6546 100644
--- a/glib2/Rakefile
+++ b/glib2/Rakefile
@@ -54,7 +54,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gettext",
       :download_site => :gnu,
       :label => "gettext-runtime",
-      :version => "0.19.5",
+      :version => "0.19.7",
       :base_dir_in_package => "gettext-runtime",
       :windows => {
         :built_file => "bin/libintl-8.dll",
@@ -70,24 +70,36 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       },
     },
     {
+      :name => "pcre",
+      :download_base_url => "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre",
+      :label => "PCRE",
+      :version => "8.38",
+      :windows => {
+        :configure_args => [
+          "--enable-unicode-properties",
+        ],
+        :built_file => "bin/libpcre-1.dll",
+      },
+    },
+    {
       :name => "glib",
       :download_site => :gnome,
       :label => "GLib",
-      :version => "2.44.1",
+      :version => "2.48.0",
       :compression_method => "xz",
       :windows => {
         :need_autoreconf => true,
         :patches => [
-          "glib-2.38.2-add-missing-exeext.diff",
+          "glib-2.48.0-add-missing-exeext.diff",
         ],
         :built_file => "bin/libglib-2.0-0.dll",
       },
     },
     {
       :name => "gmp",
-      :download_base_url => "ftp://ftp.gmplib.org/pub/gmp-6.0.0",
+      :download_base_url => "ftp://ftp.gmplib.org/pub/gmp-6.1.0",
       :label => "GNU MP",
-      :version => "6.0.0",
+      :version => "6.1.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -101,17 +113,17 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "nettle",
       :download_base_url => "http://www.lysator.liu.se/~nisse/archive",
       :label => "Nettle",
-      :version => "3.1.1",
+      :version => "3.2",
       :windows => {
         :configure_args => [],
-        :built_file => "bin/libnettle-6-1.dll",
+        :built_file => "bin/libnettle-6-2.dll",
       },
     },
     {
       :name => "libtasn1",
       :download_site => :gnu,
       :label => "Libtasn1",
-      :version => "4.6",
+      :version => "4.7",
       :windows => {
         :built_file => "bin/libtasn1-6.dll",
       },
@@ -127,9 +139,9 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "p11-kit",
-      :download_base_url => "http://p11-glue.freedesktop.org/releases",
+      :download_base_url => "https://p11-glue.freedesktop.org/releases",
       :label => "p11-kit",
-      :version => "0.23.1",
+      :version => "0.23.2",
       :windows => {
         :built_file => "bin/libp11-kit-0.dll",
       },
@@ -138,7 +150,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gnutls",
       :download_base_url => "ftp://ftp.gnutls.org/gcrypt/gnutls/v3.4",
       :label => "GnuTLS",
-      :version => "3.4.4",
+      :version => "3.4.10",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -156,7 +168,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "glib-networking",
       :download_site => :gnome,
       :label => "glib-networking",
-      :version => "2.44.0",
+      :version => "2.48.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/glib2/ext/glib2/extconf.rb b/glib2/ext/glib2/extconf.rb
index 44497ee..ada704c 100644
--- a/glib2/ext/glib2/extconf.rb
+++ b/glib2/ext/glib2/extconf.rb
@@ -17,6 +17,7 @@ require 'mkmf-gnome2'
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 2, 12, 0],
+                                   :altlinux => "glib2-devel",
                                    :debian => "libglib2.0-dev",
                                    :redhat => "glib2-devel",
                                    :arch => "glib2",
diff --git a/glib2/ext/glib2/glib2.def b/glib2/ext/glib2/glib2.def
index 263e3ec..ee8ca1b 100644
--- a/glib2/ext/glib2/glib2.def
+++ b/glib2/ext/glib2/glib2.def
@@ -69,8 +69,11 @@ EXPORTS
 	rbg_rval_inspect
 	rbg_string_value_ptr
 	rbg_rval2cstr
+	rbg_rval2cstr_raw
 	rbg_rval2cstr_ptr
 	rbg_rval2cstr_accept_nil
+	rbg_rval2cstr_raw_accept_nil
+	rbg_rval2cstr_ptr_accept_nil
 	rbg_rval2cstr_accept_symbol
 	rbg_rval2cstr_accept_symbol_accept_nil
 	rbg_rval2glibid
@@ -116,6 +119,7 @@ EXPORTS
 	rbg_inspect
 	rbg_interrupt_source_new
 	rbg_name_to_nick
+	rbg_memzero
 	rbgutil_id_module_eval		DATA
 	rbgutil_def_setters
 	rbgutil_glist2ary
diff --git a/glib2/ext/glib2/rbglib-variant.c b/glib2/ext/glib2/rbglib-variant.c
index e4c7530..1a33005 100644
--- a/glib2/ext/glib2/rbglib-variant.c
+++ b/glib2/ext/glib2/rbglib-variant.c
@@ -39,11 +39,45 @@ rbg_variant_to_ruby(GVariant *variant)
 
     if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) {
         return CBOOL2RVAL(g_variant_get_boolean(variant));
-    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING)) {
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) {
+        return UINT2NUM(g_variant_get_byte(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) {
+        return INT2NUM(g_variant_get_int16(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) {
+        return UINT2NUM(g_variant_get_uint16(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) {
+        return INT2NUM(g_variant_get_int32(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) {
+        return UINT2NUM(g_variant_get_uint32(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) {
+        return rbglib_int64_to_num(g_variant_get_int64(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) {
+        return rbglib_uint64_to_num(g_variant_get_uint64(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) {
+        return rb_float_new(g_variant_get_double(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING) ||
+               g_variant_type_equal(type, G_VARIANT_TYPE_OBJECT_PATH) ||
+               g_variant_type_equal(type, G_VARIANT_TYPE_SIGNATURE)) {
         const gchar *string;
         gsize string_length;
         string = g_variant_get_string(variant, &string_length);
         return CSTR2RVAL_LEN(string, string_length);
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_HANDLE)) {
+        return INT2NUM(g_variant_get_handle(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT)) {
+        GVariant *val = g_variant_get_variant(variant);
+        VALUE value = rbg_variant_to_ruby(val);
+        g_variant_unref(val);
+        return value;
+    } else if (g_variant_type_is_array(type)) {
+        gsize i, len = g_variant_n_children(variant);
+        VALUE ary = rb_ary_new2(len);
+        for (i = 0; i < len; i++) {
+            GVariant *val = g_variant_get_child_value(variant, i);
+            rb_ary_store(ary, i, rbg_variant_to_ruby(val));
+            g_variant_unref(val);
+        }
+        return ary;
     } else {
         rb_raise(rb_eNotImpError,
                  "TODO: GVariant(%.*s) -> Ruby",
@@ -78,21 +112,138 @@ rg_variant_allocate(VALUE klass)
     return Data_Wrap_Struct(klass, NULL, rg_variant_free, NULL);
 }
 
-static VALUE
-rg_initialize(VALUE self, VALUE rb_value)
+static GVariant *
+rg_ruby_to_variant(VALUE rb_value, VALUE rb_variant_type)
 {
-    GVariant *variant;
+    const GVariantType *variant_type;
+
+    if (NIL_P(rb_variant_type)) {
+        switch (rb_type(rb_value)) {
+          case RUBY_T_TRUE:
+          case RUBY_T_FALSE:
+            variant_type = G_VARIANT_TYPE_BOOLEAN;
+            break;
+          case RUBY_T_FIXNUM:
+            variant_type = G_VARIANT_TYPE_INT64;
+            break;
+          case RUBY_T_FLOAT:
+            variant_type = G_VARIANT_TYPE_DOUBLE;
+            break;
+          case RUBY_T_STRING:
+            variant_type = G_VARIANT_TYPE_STRING;
+            break;
+          case RUBY_T_ARRAY:
+            variant_type = G_VARIANT_TYPE_ARRAY;
+            break;
+          default:
+            rb_raise(rb_eNotImpError,
+                     "TODO: Ruby -> GVariantType: %s",
+                     RBG_INSPECT(rb_value));
+            break;
+        }
+    } else {
+        variant_type = RVAL2GVARIANTTYPE(rb_variant_type);
+    }
+
+    if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BOOLEAN)) {
+        return g_variant_new_boolean(RVAL2CBOOL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BYTE)) {
+        return g_variant_new_byte(NUM2UINT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT16)) {
+        return g_variant_new_int16(NUM2INT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT16)) {
+        return g_variant_new_uint16(NUM2UINT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT32)) {
+        return g_variant_new_int32(NUM2INT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT32)) {
+        return g_variant_new_uint32(NUM2UINT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT64)) {
+        return g_variant_new_int64(NUM2LONG(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT64)) {
+        return g_variant_new_uint64(NUM2ULONG(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_HANDLE)) {
+        return g_variant_new_handle(NUM2INT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_DOUBLE)) {
+        return g_variant_new_double(NUM2DBL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_STRING)) {
+        return g_variant_new_string(RVAL2CSTR_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_OBJECT_PATH)) {
+        return g_variant_new_object_path(RVAL2CSTR_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_SIGNATURE)) {
+        return g_variant_new_signature(RVAL2CSTR_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_VARIANT)) {
+        return g_variant_new_variant(rbg_variant_from_ruby(rb_value));
+    } else if (g_variant_type_equal(variant_type,
+                                    G_VARIANT_TYPE_STRING_ARRAY) ||
+               g_variant_type_equal(variant_type,
+                                    G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
+        const gchar **strings;
+        gssize length;
+        if (NIL_P(rb_value)) {
+            strings = NULL;
+            length = 0;
+        } else {
+            gssize i;
+
+            length = RARRAY_LEN(rb_value);
+            strings = ALLOCA_N(const gchar *, length);
+            for (i = 0; i < length; i++) {
+                VALUE rb_string = RARRAY_PTR(rb_value)[i];
+                strings[i] = RVAL2CSTR_ACCEPT_NIL(rb_string);
+            }
+        }
+        if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_STRING_ARRAY)) {
+            return g_variant_new_strv(strings, length);
+        } else {
+            return g_variant_new_objv(strings, length);
+        }
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_ARRAY)) {
+        int i;
+        GVariantBuilder builder;
+        g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+        for (i = 0; i < RARRAY_LEN(rb_value); i++) {
+            GVariant *val = rg_ruby_to_variant(rb_ary_entry(rb_value, i), Qnil);
+            g_variant_builder_add_value(&builder, val);
+        }
+        return g_variant_builder_end(&builder);
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BYTESTRING)) {
+        return g_variant_new_bytestring(RVAL2CSTR_RAW_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type,
+                                    G_VARIANT_TYPE_BYTESTRING_ARRAY)) {
+        const gchar **strings;
+        gssize length;
+        if (NIL_P(rb_value)) {
+            strings = NULL;
+            length = 0;
+        } else {
+            gssize i;
 
-    switch (rb_type(rb_value)) {
-      case RUBY_T_STRING:
-        variant = g_variant_new_string(RVAL2CSTR(rb_value));
-        break;
-      default:
+            length = RARRAY_LEN(rb_value);
+            strings = ALLOCA_N(const gchar *, length);
+            for (i = 0; i < length; i++) {
+                VALUE rb_string = RARRAY_PTR(rb_value)[i];
+                strings[i] = RVAL2CSTR_RAW_ACCEPT_NIL(rb_string);
+            }
+        }
+        return g_variant_new_bytestring_array(strings, length);
+    } else {
         rb_raise(rb_eNotImpError,
-                 "TODO: Ruby -> GVariant: %s",
+                 "TODO: Ruby -> GVariant(%.*s): %s",
+                 (int)g_variant_type_get_string_length(variant_type),
+                 g_variant_type_peek_string(variant_type),
                  RBG_INSPECT(rb_value));
-        break;
     }
+}
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    GVariant *variant;
+    VALUE rb_value;
+    VALUE rb_variant_type;
+
+    rb_scan_args(argc, argv, "11", &rb_value, &rb_variant_type);
+    variant = rg_ruby_to_variant(rb_value, rb_variant_type);
     g_variant_ref_sink(variant);
     DATA_PTR(self) = variant;
 
@@ -126,7 +277,7 @@ Init_glib_variant(void)
 
     rb_define_alloc_func(RG_TARGET_NAMESPACE, rg_variant_allocate);
 
-    RG_DEF_METHOD(initialize, 1);
+    RG_DEF_METHOD(initialize, -1);
     RG_DEF_METHOD(value, 0);
     RG_DEF_METHOD(type, 0);
 }
diff --git a/glib2/ext/glib2/rbglib.c b/glib2/ext/glib2/rbglib.c
index d456223..f435d94 100644
--- a/glib2/ext/glib2/rbglib.c
+++ b/glib2/ext/glib2/rbglib.c
@@ -43,14 +43,17 @@ rbg_rval2cstr(VALUE *str)
 }
 
 const gchar *
-rbg_rval2cstr_ptr(VALUE *str)
+rbg_rval2cstr_raw(VALUE *str)
 {
     StringValue(*str);
 
-#ifdef HAVE_RUBY_ENCODING_H
-    if (rb_enc_get(*str) != rb_utf8_encoding())
-        *str = rb_str_export_to_enc(*str, rb_utf8_encoding());
-#endif
+    return StringValueCStr(*str);
+}
+
+const gchar *
+rbg_rval2cstr_ptr(VALUE *str)
+{
+    StringValue(*str);
 
     return RSTRING_PTR(*str);
 }
@@ -75,6 +78,18 @@ rbg_rval2cstr_accept_nil(VALUE *str)
     return NIL_P(*str) ? NULL : RVAL2CSTR(*str);
 }
 
+const gchar *
+rbg_rval2cstr_raw_accept_nil(VALUE *str)
+{
+    return NIL_P(*str) ? NULL : RVAL2CSTR_RAW(*str);
+}
+
+const gchar *
+rbg_rval2cstr_ptr_accept_nil(VALUE *str)
+{
+    return NIL_P(*str) ? NULL : RVAL2CSTR_PTR(*str);
+}
+
 /* TODO: How do we deal with encodings? */
 const gchar *
 rbg_rval2cstr_accept_symbol(volatile VALUE *value)
@@ -879,11 +894,17 @@ rbg_scan_options (VALUE options, ...)
     VALUE *value;
     va_list args;
 
-    options = rbg_check_hash_type(options);
     if (NIL_P(options)) {
         options = rb_hash_new();
-    } else if (options == original_options) {
-        options = rb_funcall(options, rb_intern("dup"), 0);
+    } else {
+        options = rbg_check_hash_type(options);
+        if (options == original_options) {
+            options = rb_funcall(options, rb_intern("dup"), 0);
+        } else if (NIL_P(options)) {
+            rb_raise(rb_eArgError,
+                     "options must be Hash or nil: %+" PRIsVALUE,
+                     original_options);
+        }
     }
 
     available_keys = rb_ary_new();
@@ -1170,4 +1191,6 @@ union       GDoubleIEEE754;
     Init_glib_bookmark_file();
     Init_glib_variant_type();
     Init_glib_variant();
+    Init_glib_regex();
+    Init_glib_matchinfo();
 }
diff --git a/glib2/ext/glib2/rbglib.h b/glib2/ext/glib2/rbglib.h
index a13687f..917c636 100644
--- a/glib2/ext/glib2/rbglib.h
+++ b/glib2/ext/glib2/rbglib.h
@@ -36,7 +36,15 @@ extern "C" {
 
 #define RBGLIB_MAJOR_VERSION 3
 #define RBGLIB_MINOR_VERSION 0
-#define RBGLIB_MICRO_VERSION 7
+#define RBGLIB_MICRO_VERSION 8
+
+#ifndef RB_ZALLOC
+#  ifdef ZALLOC
+#    define RB_ZALLOC(type) ZALLOC(type)
+#  else
+#    define RB_ZALLOC(type) rbg_memzero(ALLOC(type), sizeof(type))
+#  endif
+#endif
 
 #ifndef RSTRING_PTR
 #  define RSTRING_PTR(s) (RSTRING(s)->ptr)
@@ -71,8 +79,11 @@ extern "C" {
 #define RBG_INSPECT(object) (rbg_rval_inspect(object))
 
 #define RVAL2CSTR(v) (rbg_rval2cstr(&(v)))
+#define RVAL2CSTR_RAW(v) (rbg_rval2cstr_raw(&(v)))
 #define RVAL2CSTR_PTR(v) (rbg_rval2cstr_ptr(&(v)))
 #define RVAL2CSTR_ACCEPT_NIL(v) (rbg_rval2cstr_accept_nil(&(v)))
+#define RVAL2CSTR_RAW_ACCEPT_NIL(v) (rbg_rval2cstr_raw_accept_nil(&(v)))
+#define RVAL2CSTR_PTR_ACCEPT_NIL(v) (rbg_rval2cstr_ptr_accept_nil(&(v)))
 #define RVAL2CSTR2(v) (RVAL2CSTR_ACCEPT_NIL(v))
 #define RVAL2CSTR_ACCEPT_SYMBOL(v) (rbg_rval2cstr_accept_symbol(&(v)))
 #define RVAL2CSTR_ACCEPT_SYMBOL_ACCEPT_NIL(v) (rbg_rval2cstr_accept_symbol_accept_nil(&(v)))
@@ -147,8 +158,11 @@ extern const gchar *rbg_rval_inspect(VALUE object);
 
 extern gchar* rbg_string_value_ptr(volatile VALUE* ptr); /* no longer used */
 extern const gchar *rbg_rval2cstr(VALUE *str);
+extern const gchar *rbg_rval2cstr_raw(VALUE *str);
 extern const gchar *rbg_rval2cstr_ptr(VALUE *str);
 extern const gchar *rbg_rval2cstr_accept_nil(VALUE *str);
+extern const gchar *rbg_rval2cstr_raw_accept_nil(VALUE *str);
+extern const gchar *rbg_rval2cstr_ptr_accept_nil(VALUE *str);
 extern const gchar *rbg_rval2cstr_accept_symbol(volatile VALUE *value);
 extern const gchar *rbg_rval2cstr_accept_symbol_accept_nil(volatile VALUE *value);
 extern const gchar *rbg_rval2glibid(volatile VALUE *value, volatile VALUE *buf, gboolean accept_nil);
diff --git a/glib2/ext/glib2/rbglib2conversions.h b/glib2/ext/glib2/rbglib2conversions.h
index 489f2f8..0378359 100644
--- a/glib2/ext/glib2/rbglib2conversions.h
+++ b/glib2/ext/glib2/rbglib2conversions.h
@@ -59,4 +59,7 @@
 
 #define RVAL2GBINDINGFLAGS(o)              (RVAL2GFLAGS(o, G_TYPE_BINDING_FLAGS))
 #define GBINDINGFLAGS2RVAL(o)              (GFLAGS2RVAL(o, G_TYPE_BINDING_FLAGS))
+#define RVAL2GREGEXMATCHOPTIONSFLAGS(o)    (RVAL2GFLAGS(o, G_TYPE_REGEX_MATCH_FLAGS))
+#define RVAL2GREGEXCOMPILEOPTIONSFLAGS(o)  (RVAL2GFLAGS(o, G_TYPE_REGEX_COMPILE_FLAGS))
+#define GMATCHINFO2RVAL(o)                 (BOXED2RVAL(o, G_TYPE_MATCH_INFO))
 #endif /* __GLIB2CONVERSIONS_H__ */
diff --git a/glib2/ext/glib2/rbglib_iochannel.c b/glib2/ext/glib2/rbglib_iochannel.c
index 869541e..51024b0 100644
--- a/glib2/ext/glib2/rbglib_iochannel.c
+++ b/glib2/ext/glib2/rbglib_iochannel.c
@@ -52,7 +52,6 @@ rg_initialize(gint argc, VALUE *argv, VALUE self)
     VALUE arg1, arg2;
 
     GIOChannel* io = NULL;
-    rb_secure(4);
     rb_scan_args(argc, argv, "11", &arg1, &arg2);
 
     if (TYPE(arg1) != T_STRING){
@@ -406,7 +405,6 @@ rg_write(VALUE self, VALUE buf)
     GIOStatus status;
     GError* err = NULL;
 
-    rb_secure(4);
     buf = rb_obj_as_string(buf);
 
     StringValue(buf);
@@ -426,7 +424,6 @@ rg_putc(VALUE self, VALUE thechar)
     GIOStatus status;
     gunichar unichar;
 
-    rb_secure(4);
     if (TYPE(thechar) == T_FIXNUM) {
         unichar = NUM2UINT(thechar);
     } else {
diff --git a/glib2/ext/glib2/rbglib_iochannel_win32_socket.c b/glib2/ext/glib2/rbglib_iochannel_win32_socket.c
index da28872..5eaa8f2 100644
--- a/glib2/ext/glib2/rbglib_iochannel_win32_socket.c
+++ b/glib2/ext/glib2/rbglib_iochannel_win32_socket.c
@@ -31,7 +31,6 @@ rg_initialize(VALUE self, VALUE socket)
     GIOChannel *io = NULL;
     int fd;
 
-    rb_secure(4);
     /* TODO: support IO object */
     fd = NUM2INT(socket);
     io = g_io_channel_win32_new_socket(rb_w32_get_osfhandle(fd));
diff --git a/glib2/ext/glib2/rbglib_matchinfo.c b/glib2/ext/glib2/rbglib_matchinfo.c
new file mode 100644
index 0000000..9ea4648
--- /dev/null
+++ b/glib2/ext/glib2/rbglib_matchinfo.c
@@ -0,0 +1,179 @@
+/*
+ *  Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cMatchInfo
+#define _SELF(s) ((GMatchInfo*)RVAL2BOXED(s, G_TYPE_MATCH_INFO))
+
+static VALUE
+rg_regex(VALUE self)
+{
+    GRegex *regex;
+    regex = g_match_info_get_regex(_SELF(self));
+    return BOXED2RVAL(regex, G_TYPE_REGEX);
+}
+
+static VALUE
+rg_string(VALUE self)
+{
+    return rb_iv_get(self, "@string");
+}
+
+static VALUE
+rg_matches_p(VALUE self)
+{
+    return CBOOL2RVAL(g_match_info_matches(_SELF(self)));
+}
+
+static VALUE
+rg_match_count(VALUE self)
+{
+    return INT2NUM(g_match_info_get_match_count(_SELF(self)));
+}
+
+static VALUE
+rg_partial_match_p(VALUE self)
+{
+    return CBOOL2RVAL(g_match_info_is_partial_match(_SELF(self)));
+}
+
+static VALUE
+rg_fetch(VALUE self, VALUE rb_match_reference)
+{
+    gchar *match;
+
+    switch (TYPE(rb_match_reference)) {
+      case RUBY_T_FIXNUM:
+        {
+            gint match_num;
+            match_num = NUM2INT(rb_match_reference);
+            match = g_match_info_fetch(_SELF(self), match_num);
+        }
+        break;
+      case RUBY_T_STRING:
+      case RUBY_T_SYMBOL:
+        {
+            const gchar *match_name;
+            match_name = RVAL2CSTR_ACCEPT_SYMBOL(rb_match_reference);
+            match = g_match_info_fetch_named(_SELF(self), match_name);
+        }
+        break;
+      default:
+        rb_raise(rb_eArgError, "Expected a String, a Symbol or an Integer");
+        break;
+    }
+
+    return CSTR2RVAL_FREE(match);
+}
+
+static VALUE
+rg_fetch_pos(VALUE self, VALUE rb_match_reference)
+{
+    gint start_pos = 0;
+    gint end_pos = 0;
+    gboolean fetched = FALSE;
+
+    switch (TYPE(rb_match_reference)) {
+      case RUBY_T_FIXNUM:
+        {
+            gint match_num;
+            match_num = NUM2INT(rb_match_reference);
+            fetched = g_match_info_fetch_pos(_SELF(self), match_num,
+                                             &start_pos, &end_pos);
+        }
+        break;
+      case RUBY_T_STRING:
+      case RUBY_T_SYMBOL:
+        {
+            const gchar *match_name;
+            match_name = RVAL2CSTR_ACCEPT_SYMBOL(rb_match_reference);
+            fetched = g_match_info_fetch_named_pos(_SELF(self), match_name,
+                                                   &start_pos, &end_pos);
+        }
+        break;
+      default:
+        rb_raise(rb_eArgError, "Expected a String, a Symbol or an Integer");
+        break;
+    }
+
+    if (!fetched) {
+        return Qnil;
+    }
+
+    return rb_ary_new_from_args(2, INT2NUM(start_pos), INT2NUM(end_pos));
+}
+
+static VALUE
+rg_fetch_all(VALUE self)
+{
+    gchar **strings;
+    strings = g_match_info_fetch_all(_SELF(self));
+    return STRV2RVAL_FREE(strings);
+}
+
+static VALUE
+rg_next(VALUE self)
+{
+    gboolean matched;
+    GError *error = NULL;
+
+    matched = g_match_info_next(_SELF(self), &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return CBOOL2RVAL(matched);
+}
+
+static VALUE
+rg_expand_references(VALUE self, VALUE rb_string)
+{
+    const gchar *string = RVAL2CSTR(rb_string);
+    gchar *expanded_string = NULL;
+    GError *error = NULL;
+
+    expanded_string = g_match_info_expand_references(_SELF(self),
+                                                     string,
+                                                     &error);
+    if (error)
+        RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(expanded_string);
+}
+
+void
+Init_glib_matchinfo(void)
+{
+    VALUE RG_TARGET_NAMESPACE;
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MATCH_INFO, "MatchInfo", mGLib);
+    RG_DEF_METHOD(regex, 0);
+    RG_DEF_METHOD(string, 0);
+    RG_DEF_METHOD_P(matches, 0);
+    RG_DEF_METHOD(match_count, 0);
+    RG_DEF_METHOD_P(partial_match, 0);
+    RG_DEF_METHOD(fetch, 1);
+    RG_DEF_ALIAS("[]", "fetch");
+    RG_DEF_METHOD(fetch_pos, 1);
+    RG_DEF_ALIAS("fetch_position", "fetch_pos");
+    RG_DEF_METHOD(fetch_all, 0);
+    RG_DEF_METHOD(next, 0);
+    RG_DEF_METHOD(expand_references, 1);
+}
diff --git a/glib2/ext/glib2/rbglib_regex.c b/glib2/ext/glib2/rbglib_regex.c
new file mode 100644
index 0000000..be2fa81
--- /dev/null
+++ b/glib2/ext/glib2/rbglib_regex.c
@@ -0,0 +1,484 @@
+/*
+ *  Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+/* They MRI are internal definitions. Using them reduces
+ * maintainability. We should reconsider about using them when they
+ * are changed in MRI. */
+/* from vm_core.h */
+#define RUBY_TAG_BREAK 0x2
+
+/* from internal.h */
+struct vm_throw_data {
+    VALUE flags;
+    VALUE reserved;
+    const VALUE throw_obj;
+    /* const struct rb_control_frame_struct *catch_frame; */
+    /* VALUE throw_state; */
+};
+/* from vm_insnhelper.h */
+#define THROW_DATA_VAL(obj) (((struct vm_throw_data *)(obj))->throw_obj)
+
+
+#define RG_TARGET_NAMESPACE cRegex
+#define _SELF(s) ((GRegex*)RVAL2BOXED(s, G_TYPE_REGEX))
+
+static VALUE
+rg_initialize(gint argc, VALUE *argv, VALUE self)
+{
+    GError *error = NULL;
+    GRegex *regex = NULL;
+
+    VALUE rb_pattern, rb_compile_options, rb_match_options;
+    VALUE rb_options;
+    const char *pattern;
+    GRegexCompileFlags compile_options = 0;
+    GRegexMatchFlags match_options = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_pattern, &rb_options);
+    rbg_scan_options(rb_options,
+                     "compile_options", &rb_compile_options,
+                     "match_options", &rb_match_options,
+                     NULL);
+
+    pattern = RVAL2CSTR(rb_pattern);
+    if (!NIL_P(rb_compile_options))
+        compile_options = RVAL2GREGEXCOMPILEOPTIONSFLAGS(rb_compile_options);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+    regex = g_regex_new(pattern,
+                        compile_options,
+                        match_options,
+                        &error);
+    if (error)
+        RAISE_GERROR(error);
+
+    G_INITIALIZE(self, regex);
+    return Qnil;
+}
+
+static VALUE
+rg_pattern(VALUE self)
+{
+    return CSTR2RVAL(g_regex_get_pattern(_SELF(self)));
+}
+
+static VALUE
+rg_compile_flags(VALUE self)
+{
+    return UINT2NUM(g_regex_get_compile_flags(_SELF(self)));
+}
+
+static VALUE
+rg_match_flags(VALUE self)
+{
+    return UINT2NUM(g_regex_get_match_flags(_SELF(self)));
+}
+
+static VALUE
+rg_split(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string, rb_start_position, rb_match_options, rb_max_tokens, rb_options;
+    GError *error = NULL;
+    gchar **strings;
+    const gchar *string;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+    gint max_tokens = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "start_position", &rb_start_position,
+                     "match_options", &rb_match_options,
+                     "max_tokens", &rb_max_tokens,
+                     NULL);
+    string = RVAL2CSTR(rb_string);
+    string_len = RSTRING_LEN(rb_string);
+
+    if (!NIL_P(rb_start_position))
+        start_position = NUM2INT(rb_start_position);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+    if (!NIL_P(rb_max_tokens))
+        max_tokens = NUM2INT(rb_max_tokens);
+
+    strings = g_regex_split_full(_SELF(self),
+                                 string,
+                                 string_len,
+                                 start_position,
+                                 match_options,
+                                 max_tokens,
+                                 &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return STRV2RVAL_FREE(strings);
+}
+
+static VALUE
+rg_match(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string, rb_start_position, rb_match_options, rb_options;
+    VALUE rb_frozen_string, rb_match_info;
+    GMatchInfo *match_info = NULL;
+    GError *error = NULL;
+    const gchar *string;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "start_position", &rb_start_position,
+                     "match_options", &rb_match_options,
+                     NULL);
+
+    if (OBJ_FROZEN(rb_string)) {
+        rb_frozen_string = rb_string;
+    } else {
+        rb_frozen_string = rb_str_dup(rb_string);
+        rb_str_freeze(rb_frozen_string);
+    }
+
+    string = RVAL2CSTR(rb_frozen_string);
+    string_len = RSTRING_LEN(rb_frozen_string);
+
+
+    if (!NIL_P(rb_start_position))
+        start_position = NUM2INT(rb_start_position);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+    g_regex_match_full(_SELF(self),
+                       string,
+                       string_len,
+                       start_position,
+                       match_options,
+                       &match_info,
+                       &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    if (!match_info)
+        return Qnil;
+
+    rb_match_info = GMATCHINFO2RVAL(match_info);
+    g_match_info_unref(match_info);
+    rb_iv_set(rb_match_info, "@string", rb_frozen_string);
+    return rb_match_info;
+}
+
+static VALUE
+rg_max_backref(VALUE self)
+{
+    return INT2NUM(g_regex_get_max_backref(_SELF(self)));
+}
+
+static VALUE
+rg_capture_count(VALUE self)
+{
+    return INT2NUM(g_regex_get_capture_count(_SELF(self)));
+}
+
+static VALUE
+rg_has_cr_or_lf_p(VALUE self)
+{
+    return CBOOL2RVAL(g_regex_get_has_cr_or_lf(_SELF(self)));
+}
+
+static VALUE
+rg_max_lookbehind(VALUE self)
+{
+    return INT2NUM(g_regex_get_max_lookbehind(_SELF(self)));
+}
+
+static VALUE
+rg_string_number(VALUE self, VALUE string)
+{
+    return INT2NUM(g_regex_get_string_number(_SELF(self), RVAL2CSTR(string)));
+}
+
+static VALUE
+rg_match_all(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string, rb_start_position, rb_match_options, rb_options;
+    VALUE rb_frozen_string, rb_match_info;
+    GMatchInfo *match_info = NULL;
+    GError *error = NULL;
+    const gchar *string;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "start_position", &rb_start_position,
+                     "match_options", &rb_match_options,
+                     NULL);
+
+    if (OBJ_FROZEN(rb_string)) {
+        rb_frozen_string = rb_string;
+    } else {
+        rb_frozen_string = rb_str_dup(rb_string);
+        rb_str_freeze(rb_frozen_string);
+    }
+
+    string = RVAL2CSTR(rb_frozen_string);
+    string_len = RSTRING_LEN(rb_frozen_string);
+
+
+    if (!NIL_P(rb_start_position))
+        start_position = NUM2INT(rb_start_position);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+    g_regex_match_all_full(_SELF(self),
+                           string,
+                           string_len,
+                           start_position,
+                           match_options,
+                           &match_info,
+                           &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    if (!match_info)
+        return Qnil;
+
+    rb_match_info = GMATCHINFO2RVAL(match_info);
+    g_match_info_unref(match_info);
+    rb_iv_set(rb_match_info, "@string", rb_frozen_string);
+    return rb_match_info;
+}
+
+typedef struct {
+    VALUE callback;
+    const GMatchInfo *match_info;
+    int status;
+} RGRegexEvalCallbackData;
+
+static VALUE
+rg_regex_eval_callback_body(VALUE user_data)
+{
+    RGRegexEvalCallbackData *data = (RGRegexEvalCallbackData *)user_data;
+    VALUE rb_match_info;
+
+    rb_match_info = BOXED2RVAL((GMatchInfo *)(data->match_info),
+                               G_TYPE_MATCH_INFO);
+
+    return rb_funcall(data->callback, rb_intern("call"), 1, rb_match_info);
+}
+
+static gboolean
+rg_regex_eval_callback(const GMatchInfo *match_info,
+                       GString *result,
+                       gpointer user_data)
+{
+    VALUE returned_data;
+    RGRegexEvalCallbackData *data = user_data;
+
+    data->match_info = match_info;
+    returned_data = rb_protect(rg_regex_eval_callback_body,
+                               (VALUE)data,
+                               &(data->status));
+
+    if (data->status == RUBY_TAG_BREAK) {
+        returned_data = THROW_DATA_VAL(rb_errinfo());
+    }
+
+    if (NIL_P(returned_data)) {
+        gchar *matched;
+        matched = g_match_info_fetch(match_info, 0);
+        g_string_append(result, matched);
+        g_free(matched);
+    } else {
+        g_string_append(result, RVAL2CSTR(returned_data));
+    }
+
+    return data->status != 0;
+}
+
+static VALUE
+rg_replace(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string;
+    VALUE rb_replacement;
+    VALUE rb_options;
+    VALUE rb_start_position;
+    VALUE rb_match_options;
+    VALUE rb_literal;
+    GError *error = NULL;
+    gchar *modified_string;
+    const gchar *string;
+    const gchar *replacement;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+
+
+    if (rb_block_given_p()) {
+        RGRegexEvalCallbackData data;
+
+        rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+        rbg_scan_options(rb_options,
+                         "start_position", &rb_start_position,
+                         "match_options", &rb_match_options,
+                         NULL);
+
+        string = RVAL2CSTR(rb_string);
+        string_len = RSTRING_LEN(rb_string);
+
+        if (!NIL_P(rb_start_position))
+            start_position = NUM2INT(rb_start_position);
+        if (!NIL_P(rb_match_options))
+            match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+        data.callback = rb_block_proc();
+        data.status = 0;
+
+        modified_string = g_regex_replace_eval(_SELF(self),
+                                               string,
+                                               string_len,
+                                               start_position,
+                                               match_options,
+                                               rg_regex_eval_callback,
+                                               &data,
+                                               &error);
+        if (!(data.status == 0 || data.status == RUBY_TAG_BREAK)) {
+            if (error)
+                g_error_free(error);
+            g_free(modified_string);
+            rb_jump_tag(data.status);
+        }
+    } else {
+        rb_scan_args(argc, argv, "21", &rb_string, &rb_replacement, &rb_options);
+
+        rbg_scan_options(rb_options,
+                         "start_position", &rb_start_position,
+                         "match_options", &rb_match_options,
+                         "literal", &rb_literal,
+                         NULL);
+
+        string = RVAL2CSTR(rb_string);
+        string_len = RSTRING_LEN(rb_string);
+        replacement = RVAL2CSTR(rb_replacement);
+
+        if (!NIL_P(rb_start_position))
+            start_position = NUM2INT(rb_start_position);
+        if (!NIL_P(rb_match_options))
+            match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+        if (RVAL2CBOOL(rb_literal)) {
+            modified_string = g_regex_replace_literal(_SELF(self),
+                                                      string,
+                                                      string_len,
+                                                      start_position,
+                                                      replacement,
+                                                      match_options,
+                                                      &error);
+
+        } else {
+            modified_string = g_regex_replace(_SELF(self),
+                                              string,
+                                              string_len,
+                                              start_position,
+                                              replacement,
+                                              match_options,
+                                              &error);
+        }
+    }
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(modified_string);
+}
+
+
+static VALUE
+rg_s_escape_string(G_GNUC_UNUSED VALUE self, VALUE string)
+{
+    return CSTR2RVAL(g_regex_escape_string(RVAL2CSTR(string), RSTRING_LEN(string)));
+}
+
+static VALUE
+rg_s_check_replacement(G_GNUC_UNUSED VALUE self, VALUE rb_replacement)
+{
+    const gchar *replacement;
+    GError *error = NULL;
+
+    replacement = RVAL2CSTR(rb_replacement);
+    g_regex_check_replacement(replacement, NULL, &error);
+    if (error)
+        RAISE_GERROR(error);
+
+    return Qtrue;
+}
+
+static VALUE
+rg_s_have_reference_p(G_GNUC_UNUSED VALUE self, VALUE rb_replacement)
+{
+    const gchar *replacement;
+    gboolean has_references;
+    GError *error = NULL;
+
+    replacement = RVAL2CSTR(rb_replacement);
+    g_regex_check_replacement(replacement, &has_references, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return CBOOL2RVAL(has_references);
+}
+
+void
+Init_glib_regex(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_REGEX, "Regex", mGLib);
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(pattern, 0);
+    RG_DEF_METHOD(compile_flags, 0);
+    RG_DEF_METHOD(match_flags, 0);
+    RG_DEF_METHOD(split, -1);
+    RG_DEF_METHOD(match, -1);
+    RG_DEF_METHOD(max_backref, 0);
+    RG_DEF_METHOD(capture_count, 0);
+    RG_DEF_METHOD_P(has_cr_or_lf, 0);
+    RG_DEF_METHOD(max_lookbehind, 0);
+    RG_DEF_METHOD(string_number, 1);
+    RG_DEF_METHOD(match_all, -1);
+    RG_DEF_METHOD(replace, -1);
+
+    RG_DEF_SMETHOD(escape_string, 1);
+    RG_DEF_SMETHOD(check_replacement, 1);
+    RG_DEF_SMETHOD_P(have_reference, 1);
+
+    G_DEF_CLASS(G_TYPE_REGEX_MATCH_FLAGS, "RegexMatchFlags", mGLib);
+    G_DEF_CLASS(G_TYPE_REGEX_COMPILE_FLAGS, "RegexCompileFlags", mGLib);
+}
diff --git a/glib2/ext/glib2/rbgobj_value.c b/glib2/ext/glib2/rbgobj_value.c
index 52fae52..8169874 100644
--- a/glib2/ext/glib2/rbgobj_value.c
+++ b/glib2/ext/glib2/rbgobj_value.c
@@ -122,12 +122,14 @@ rbgobj_gvalue_to_rvalue(const GValue* value)
                 return func(value);
             }
         }
+#if GLIB_CHECK_VERSION(2, 26, 0)
       case G_TYPE_VARIANT:
         {
             GVariant *variant = g_value_peek_pointer(value);
             rvalue = rbg_variant_to_ruby(variant);
             return rvalue;
         }
+#endif
       default:
         if (!rbgobj_convert_gvalue2rvalue(fundamental_type, value, &rvalue)) {
             GValueToRValueFunc func;
@@ -308,7 +310,11 @@ rbgobj_rvalue_to_gvalue(VALUE val, GValue* result)
                 return;
             }
         }
-
+#if GLIB_CHECK_VERSION(2, 26, 0)
+      case G_TYPE_VARIANT:
+        g_value_set_variant(result, rbg_variant_from_ruby(val));
+        break;
+#endif
       default:
         if (!rbgobj_convert_rvalue2gvalue(fundamental_type, val, result)) {
             RValueToGValueFunc func =
diff --git a/glib2/ext/glib2/rbgprivate.h b/glib2/ext/glib2/rbgprivate.h
index 2ee9ac8..15d5d5c 100644
--- a/glib2/ext/glib2/rbgprivate.h
+++ b/glib2/ext/glib2/rbgprivate.h
@@ -152,6 +152,8 @@ G_GNUC_INTERNAL void Init_glib_keyfile(void);
 G_GNUC_INTERNAL void Init_glib_bookmark_file(void);
 G_GNUC_INTERNAL void Init_glib_variant_type(void);
 G_GNUC_INTERNAL void Init_glib_variant(void);
+G_GNUC_INTERNAL void Init_glib_regex(void);
+G_GNUC_INTERNAL void Init_glib_matchinfo(void);
 
 G_GNUC_INTERNAL void Init_gobject_convert(void);
 G_GNUC_INTERNAL void Init_gobject_gtype(void);
diff --git a/glib2/ext/glib2/rbgutil.c b/glib2/ext/glib2/rbgutil.c
index e6c5374..cee70fb 100644
--- a/glib2/ext/glib2/rbgutil.c
+++ b/glib2/ext/glib2/rbgutil.c
@@ -201,6 +201,13 @@ rbg_name_to_nick(const gchar *name)
     return nick;
 }
 
+void *
+rbg_memzero(void *pointer, size_t size)
+{
+    memset(pointer, 0, size);
+    return pointer;
+}
+
 void
 Init_gutil(void)
 {
diff --git a/glib2/ext/glib2/rbgutil.h b/glib2/ext/glib2/rbgutil.h
index b6a82bd..7634adb 100644
--- a/glib2/ext/glib2/rbgutil.h
+++ b/glib2/ext/glib2/rbgutil.h
@@ -109,6 +109,8 @@ extern GSource *rbg_interrupt_source_new(void);
 
 extern gchar *rbg_name_to_nick(const gchar *name);
 
+extern void *rbg_memzero(void *poitner, size_t size);
+
 /*< protected >*/
 RUBY_GLIB2_VAR ID rbgutil_id_module_eval;
 extern void rbgutil_glibid_r2g_func(VALUE from, GValue* to);
diff --git a/glib2/lib/glib2.rb b/glib2/lib/glib2.rb
index 6b1123e..fee7fad 100644
--- a/glib2/lib/glib2.rb
+++ b/glib2/lib/glib2.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2005-2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2005-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -241,6 +241,7 @@ GLib::Log.set_log_domain(GLib::Thread::LOG_DOMAIN)
 GLib::Log.set_log_domain(GLib::Module::LOG_DOMAIN)
 
 require 'glib2/version'
+require "glib2/regex"
 =begin
 Don't we need this?
 ObjectSpace.define_finalizer(GLib) {
diff --git a/gtk3/test/test-gtk-box.rb b/glib2/lib/glib2/regex.rb
similarity index 71%
copy from gtk3/test/test-gtk-box.rb
copy to glib2/lib/glib2/regex.rb
index 1b909d2..9879c3f 100644
--- a/gtk3/test/test-gtk-box.rb
+++ b/glib2/lib/glib2/regex.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -14,14 +14,15 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-class TestGtkBox < Test::Unit::TestCase
-  include GtkTestUtils
+module GLib
+  class Regex
+    class << self
+      def match?(pattern, string, options={})
+        new(pattern, options).match(string, options).matches?
+      end
 
-  sub_test_case ".new" do
-    sub_test_case "spacing" do
-      def test_nil
-        box = Gtk::Box.new(:vertical, nil)
-        assert_equal(0, box.spacing)
+      def split(pattern, string, options={})
+        new(pattern, options).split(string, options)
       end
     end
   end
diff --git a/glib2/lib/gnome2/rake/external-package.rb b/glib2/lib/gnome2/rake/external-package.rb
index 257ca3e..3b03f85 100644
--- a/glib2/lib/gnome2/rake/external-package.rb
+++ b/glib2/lib/gnome2/rake/external-package.rb
@@ -123,7 +123,8 @@ module GNOME2
                                               :need_autogen,
                                               :need_autoreconf,
                                               :build_concurrently,
-                                              :use_cc_environment_variable)
+                                              :use_cc_environment_variable,
+                                              :gobject_introspection_compiler_split_args)
         def initialize(properties)
           super()
           properties.each do |key, value|
@@ -178,6 +179,10 @@ module GNOME2
         def use_cc_environment_variable?
           use_cc_environment_variable.nil? ? true : use_cc_environment_variable
         end
+
+        def gobject_introspection_compiler_split_args?
+          gobject_introspection_compiler_split_args
+        end
       end
 
       class NativeConfiguration < Struct.new(:build,
diff --git a/glib2/lib/gnome2/rake/package-task.rb b/glib2/lib/gnome2/rake/package-task.rb
index 434077e..9988e44 100644
--- a/glib2/lib/gnome2/rake/package-task.rb
+++ b/glib2/lib/gnome2/rake/package-task.rb
@@ -119,7 +119,7 @@ module GNOME2
           s.author                = @author
           s.email                 = @email
           s.homepage              = @homepage
-          s.licenses              = ["LGPLv2.1 or later"]
+          s.licenses              = ["LGPLv2.1+"]
           s.version               = version
           extensions              = FileList["ext/#{@name}/extconf.rb"]
           extensions.existing!
diff --git a/glib2/lib/gnome2/rake/package.rb b/glib2/lib/gnome2/rake/package.rb
index 366d88d..f969c59 100644
--- a/glib2/lib/gnome2/rake/package.rb
+++ b/glib2/lib/gnome2/rake/package.rb
@@ -126,6 +126,15 @@ module GNOME2
           end
         end
 
+        def build_arch
+          case build_architecture
+          when "x86"
+            "i686"
+          when "x64"
+            "x86_64"
+          end
+        end
+
         def build_architecture
           ENV["RUBY_GNOME2_BUILD_ARCHITECTURE"] || "x86"
         end
diff --git a/glib2/lib/gnome2/rake/windows-binary-build-task.rb b/glib2/lib/gnome2/rake/windows-binary-build-task.rb
index 1a45f50..f5cc0fc 100644
--- a/glib2/lib/gnome2/rake/windows-binary-build-task.rb
+++ b/glib2/lib/gnome2/rake/windows-binary-build-task.rb
@@ -120,7 +120,7 @@ class GNOME2WindowsBinaryBuildTask
       if package.windows.use_cc_environment_variable?
         common_make_args << cc_env(package)
       end
-      add_gobject_introspection_make_args(common_make_args)
+      add_gobject_introspection_make_args(package, common_make_args)
       build_make_args = common_make_args.dup
       install_make_args = common_make_args.dup
       if package.windows.build_concurrently?
@@ -128,6 +128,9 @@ class GNOME2WindowsBinaryBuildTask
         build_make_args << "-j#{make_n_jobs}" if make_n_jobs
       end
       ENV["GREP_OPTIONS"] = "--text"
+      # ENV["GI_SCANNER_DEBUG"] = "save-temps"
+      # build_make_args << "--debug"
+      # build_make_args << "V=1"
       sh("nice", "make", *build_make_args) or exit(false)
       sh("make", "install", *install_make_args) or exit(false)
 
@@ -152,9 +155,10 @@ class GNOME2WindowsBinaryBuildTask
 
   def configure(package)
     sh("./autogen.sh") if package.windows.need_autogen?
-    sh("autoreconf --install") if package.windows.need_autoreconf?
+    sh("autoreconf", "--install", "--force") if package.windows.need_autoreconf?
     sh("./configure",
        cc_env(package),
+       dlltool_env,
        "CPPFLAGS=#{cppflags(package)}",
        "LDFLAGS=#{ldflags(package)}",
        "--prefix=#{dist_dir}",
@@ -177,6 +181,10 @@ class GNOME2WindowsBinaryBuildTask
     "CC=#{cc(package)}"
   end
 
+  def dlltool_env
+    "DLLTOOL=#{dlltool}"
+  end
+
   def build_packages
     packages = @package.external_packages.select do |package|
       package.windows.build?
@@ -241,6 +249,10 @@ class GNOME2WindowsBinaryBuildTask
     cxx_command_line.compact.join(" ")
   end
 
+  def dlltool
+    "#{@package.windows.build_host}-dlltool"
+  end
+
   def cppflags(package)
     include_paths = package.windows.include_paths
     if @package.windows.build_dependencies.include?("glib2")
@@ -282,7 +294,7 @@ class GNOME2WindowsBinaryBuildTask
     paths
   end
 
-  def add_gobject_introspection_make_args(common_make_args)
+  def add_gobject_introspection_make_args(package, common_make_args)
     unless @package.windows.build_dependencies.include?("gobject-introspection")
       return
     end
@@ -299,21 +311,33 @@ class GNOME2WindowsBinaryBuildTask
     ]
     dependencies += @package.windows.gobject_introspection_dependencies
 
-    compute_base_dir = lambda do |package|
-      "#{@package.project_root_dir}/#{package}/vendor/local"
+    compute_base_dir = lambda do |dependent_package|
+      "#{@package.project_root_dir}/#{dependent_package}/vendor/local"
     end
 
     gi_base_dir = compute_base_dir.call("gobject-introspection")
     introspection_compiler = "INTROSPECTION_COMPILER="
     introspection_compiler << "#{gi_base_dir}/bin/g-ir-compiler.exe"
-    dependencies.each do |package|
-      gir_dir = "#{compute_base_dir.call(package)}/share/gir-1.0"
-      introspection_compiler << " --includedir=#{gir_dir}"
+    introspection_compiler_args = ""
+    dependencies.each do |dependent_package|
+      gir_dir = "#{compute_base_dir.call(dependent_package)}/share/gir-1.0"
+      introspection_compiler_args << " --includedir=#{gir_dir}"
+    end
+    if package.windows.gobject_introspection_compiler_split_args?
+      common_make_args << introspection_compiler
+      common_make_args <<
+        "INTROSPECTION_COMPILER_ARGS=#{introspection_compiler_args}"
+      common_make_args <<
+        "INTROSPECTION_COMPILER_OPTS=#{introspection_compiler_args}"
+    else
+      introspection_compiler << " #{introspection_compiler_args}"
+      common_make_args << introspection_compiler
     end
-    common_make_args << introspection_compiler
 
-    data_dirs = dependencies.collect do |package|
-      "#{compute_base_dir.call(package)}/share"
+    common_make_args << dlltool_env
+
+    data_dirs = dependencies.collect do |dependent_package|
+      "#{compute_base_dir.call(dependent_package)}/share"
     end
     common_make_args << "XDG_DATA_DIRS=#{data_dirs.join(File::PATH_SEPARATOR)}"
   end
diff --git a/glib2/lib/mkmf-gnome2.rb b/glib2/lib/mkmf-gnome2.rb
index 9454f9d..eab9b62 100644
--- a/glib2/lib/mkmf-gnome2.rb
+++ b/glib2/lib/mkmf-gnome2.rb
@@ -503,6 +503,8 @@ def package_platform
     :redhat
   elsif File.exist?("/etc/SuSE-release")
     :suse
+  elsif File.exist?("/etc/altlinux-release")
+    :altlinux
   elsif find_executable("pacman")
     :arch
   elsif find_executable("brew")
@@ -536,7 +538,7 @@ def install_missing_native_package(native_package_info)
   package_command_line = [package_name, *options].join(" ")
   need_super_user_priviledge = true
   case platform
-  when :debian
+  when :debian, :altlinux
     install_command = "apt-get install -V -y #{package_command_line}"
   when :fedora, :redhat
     install_command = "yum install -y #{package_command_line}"
diff --git a/glib2/patches/glib-2.38.2-add-missing-exeext.diff b/glib2/patches/glib-2.38.2-add-missing-exeext.diff
deleted file mode 100644
index 0196b9a..0000000
--- a/glib2/patches/glib-2.38.2-add-missing-exeext.diff
+++ /dev/null
@@ -1,24 +0,0 @@
-diff -ru glib-2.38.2.orig/gio/tests/Makefile.am glib-2.38.2/gio/tests/Makefile.am
---- glib-2.38.2.orig/gio/tests/Makefile.am	2013-11-12 14:30:22.000000000 +0900
-+++ glib-2.38.2/gio/tests/Makefile.am	2013-12-23 15:13:59.328468099 +0900
-@@ -431,7 +431,7 @@
- if CROSS_COMPILING
-   glib_compile_resources=$(GLIB_COMPILE_RESOURCES)
- else
--  glib_compile_resources=$(top_builddir)/gio/glib-compile-resources
-+  glib_compile_resources=$(top_builddir)/gio/glib-compile-resources$(EXEEXT)
- endif
- 
- resources.o: test_resources2.h
-diff -ru glib-2.38.2.orig/tests/gobject/Makefile.am glib-2.38.2/tests/gobject/Makefile.am
---- glib-2.38.2.orig/tests/gobject/Makefile.am	2013-11-08 00:29:13.000000000 +0900
-+++ glib-2.38.2/tests/gobject/Makefile.am	2013-12-23 15:12:21.190876890 +0900
-@@ -51,7 +51,7 @@
- if CROSS_COMPILING
-   glib_genmarshal=$(GLIB_GENMARSHAL)
- else
--  glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal
-+  glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT)
- endif
- 
- testmarshal.h: stamp-testmarshal.h
diff --git a/glib2/patches/glib-2.48.0-add-missing-exeext.diff b/glib2/patches/glib-2.48.0-add-missing-exeext.diff
new file mode 100644
index 0000000..cf0cc44
--- /dev/null
+++ b/glib2/patches/glib-2.48.0-add-missing-exeext.diff
@@ -0,0 +1,36 @@
+diff -ru glib-2.48.0.orig/gio/tests/Makefile.am glib-2.48.0/gio/tests/Makefile.am
+--- glib-2.48.0.orig/gio/tests/Makefile.am	2016-03-23 00:15:18.000000000 +0900
++++ glib-2.48.0/gio/tests/Makefile.am	2016-04-01 23:57:17.701727371 +0900
+@@ -532,7 +532,7 @@
+ libresourceplugin_la_LDFLAGS += -rpath /
+ endif
+ 
+-glib_compile_resources=$(top_builddir)/gio/glib-compile-resources
++glib_compile_resources=$(top_builddir)/gio/glib-compile-resources$(EXEEXT)
+ 
+ resources.o: test_resources2.h
+ test_resources.c: test2.gresource.xml Makefile $(shell $(glib_compile_resources) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/test2.gresource.xml)
+diff -ru glib-2.48.0.orig/gobject/tests/Makefile.am glib-2.48.0/gobject/tests/Makefile.am
+--- glib-2.48.0.orig/gobject/tests/Makefile.am	2016-02-29 23:32:08.000000000 +0900
++++ glib-2.48.0/gobject/tests/Makefile.am	2016-04-02 00:03:17.344944211 +0900
+@@ -36,7 +36,7 @@
+ # cross-compiling
+ 
+ if !CROSS_COMPILING
+-glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal
++glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT)
+ 
+ test_programs += signals
+ signals_SOURCES = signals.c
+diff -ru glib-2.48.0.orig/tests/gobject/Makefile.am glib-2.48.0/tests/gobject/Makefile.am
+--- glib-2.48.0.orig/tests/gobject/Makefile.am	2016-02-24 07:25:37.000000000 +0900
++++ glib-2.48.0/tests/gobject/Makefile.am	2016-04-02 00:00:07.259367148 +0900
+@@ -51,7 +51,7 @@
+ # The marshal test requires running a binary, which means we cannot
+ # build it when cross-compiling
+ if !CROSS_COMPILING
+-glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal
++glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT)
+ 
+ testmarshal.h: stamp-testmarshal.h
+ 	@true
diff --git a/glib2/test/test-match-info.rb b/glib2/test/test-match-info.rb
new file mode 100644
index 0000000..9046f69
--- /dev/null
+++ b/glib2/test/test-match-info.rb
@@ -0,0 +1,113 @@
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestMatchInfo < Test::Unit::TestCase
+  def test_string
+    regex = GLib::Regex.new("[A-Z]+")
+    match_info = regex.match("abc def")
+    assert_equal("abc def", match_info.string)
+  end
+
+  def test_regex
+    regex = GLib::Regex.new("[A-Z]+")
+    match_info = regex.match("abc def")
+    assert_equal("[A-Z]+", match_info.regex.pattern)
+  end
+
+  def test_partial_match
+    flags = GLib::RegexMatchFlags::PARTIAL_SOFT
+    regex = GLib::Regex.new("jan")
+    match_info = regex.match_all("ja", :match_options => flags)
+    assert do
+      !match_info.matches?
+    end
+    assert do
+      match_info.partial_match?
+    end
+  end
+
+  sub_test_case "fetch" do
+    test "Integer" do
+      regex = GLib::Regex.new("[A-Z]+")
+      match_info = regex.match_all("abc DEF ghi JKL mnop")
+      assert_equal("DEF", match_info.fetch(0))
+      assert_equal("DE", match_info.fetch(1))
+    end
+
+    test "String" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal("foo", match_info.fetch("a_name"))
+    end
+
+    test "Symbol" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal("foo", match_info.fetch(:a_name))
+    end
+
+    test "[]" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal("foo", match_info[:a_name])
+    end
+  end
+
+  sub_test_case "fetch_pos" do
+    test "Integer" do
+      regex = GLib::Regex.new("[A-Z]+")
+      match_info = regex.match_all("abc DEF ghi JKL mnop")
+      assert_equal([4, 7], match_info.fetch_pos(0))
+      assert_equal([4, 6], match_info.fetch_pos(1))
+    end
+
+    test "String" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal([4, 7], match_info.fetch_pos("a_name"))
+    end
+
+    test "Symbol" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal([4, 7], match_info.fetch_pos(:a_name))
+    end
+  end
+
+  def test_fetch_all
+    regex = GLib::Regex.new("[A-Z]+")
+    str = "abc DEF ghi JKL mnop"
+    match_info = regex.match_all(str)
+    assert_equal(["DEF", "DE", "D"], match_info.fetch_all)
+  end
+
+  def test_next
+    regex = GLib::Regex.new("[A-Z]+")
+    str = "abc DEF ghi JKL mnop"
+    match_info = regex.match(str)
+    assert_equal("DEF", match_info[0])
+    assert {match_info.next}
+    assert_equal("JKL", match_info[0])
+    assert {!match_info.next}
+  end
+
+  def test_expand_references
+    regex = GLib::Regex.new("a(?P<G>.)c")
+    match_info = regex.match("xabcy")
+    expanded_string = match_info.expand_references("X\\g<G>X")
+    assert_equal("XbX", expanded_string)
+  end
+end
diff --git a/glib2/test/test-regex.rb b/glib2/test/test-regex.rb
new file mode 100644
index 0000000..61a96ff
--- /dev/null
+++ b/glib2/test/test-regex.rb
@@ -0,0 +1,320 @@
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestRegex < Test::Unit::TestCase
+  def test_enum_match_flags
+    assert_const_defined(GLib, :RegexMatchFlags)
+    assert_kind_of(GLib::RegexMatchFlags, GLib::RegexMatchFlags::PARTIAL_HARD)
+  end
+
+  def test_enum_compile_flags
+    assert_const_defined(GLib, :RegexCompileFlags)
+    assert_kind_of(GLib::RegexCompileFlags, GLib::RegexCompileFlags::CASELESS)
+  end
+
+  def test_pattern
+    regex = GLib::Regex.new("to??")
+    assert_equal("to??", regex.pattern)
+  end
+
+  def test_compile_flags
+    flags = GLib::RegexCompileFlags::CASELESS
+    regex = GLib::Regex.new("to??", :compile_options => flags)
+    assert_equal(flags, regex.compile_flags)
+  end
+
+  def test_match_flags
+    flags = GLib::RegexMatchFlags::PARTIAL_HARD
+    regex = GLib::Regex.new("to??", :match_options => flags)
+    assert_equal(flags, regex.match_flags)
+  end
+
+  sub_test_case "split" do
+    test "no options" do
+      regex = GLib::Regex.new("\s")
+      string_to_split = "a bc"
+      splited_strings = regex.split(string_to_split)
+      assert_equal(["a", "bc"], splited_strings)
+    end
+
+    test "start_position" do
+      regex = GLib::Regex.new("\s")
+      string_to_split = "a bc"
+      splited_strings = regex.split(string_to_split, :start_position => 2)
+      assert_equal(["bc"], splited_strings)
+    end
+
+    test "max_tokens" do
+      regex = GLib::Regex.new("\s")
+      string_to_split = "a bc de fg"
+      splited_strings = regex.split(string_to_split, :max_tokens => 2)
+      assert_equal(["a", "bc de fg"], splited_strings)
+    end
+
+    test "match_options" do
+      regex = GLib::Regex.new("a?b?")
+      string_to_split = "toto ab"
+      splited_strings = regex.split(string_to_split)
+      assert_equal(["t", "o", "t", "o", " "],
+                   splited_strings)
+      splited_strings = regex.split(string_to_split,
+                                    :match_options => :notempty)
+      assert_equal(["toto ", ""], splited_strings)
+    end
+  end
+
+  sub_test_case "match" do
+    setup do
+      @regex = GLib::Regex.new("[A-Z]+")
+    end
+
+    test "no match no options" do
+      match_info = @regex.match("abc def")
+      assert do
+        not match_info.matches?
+      end
+    end
+
+    test "matched no options" do
+      match_info = @regex.match("abc DEF")
+      assert do
+        match_info.matches?
+      end
+    end
+
+    test "no match and start position option" do
+      match_info = @regex.match("abc def", :start_position => 4)
+      assert do
+        not match_info.matches?
+      end
+    end
+
+    test "matched and start position option" do
+      match_info = @regex.match("abc DEF", :start_position => 4)
+      assert do
+        match_info.matches?
+      end
+    end
+  end
+
+  sub_test_case "max_backref" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert_equal(0, regex.max_backref)
+    end
+
+    test "one" do
+      regex = GLib::Regex.new("(to(?)o)\\g1")
+      assert_equal(1, regex.max_backref)
+    end
+  end
+
+  sub_test_case "capture_count" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert_equal(0, regex.capture_count)
+    end
+
+    test "one" do
+      regex = GLib::Regex.new("(to(\?)o)")
+      assert_equal(1, regex.capture_count)
+    end
+
+    test "three" do
+      regex = GLib::Regex.new("((red|white) (king|queen))")
+      assert_equal(3, regex.capture_count)
+    end
+  end
+
+  sub_test_case "has_cr_or_lf" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert do
+        not regex.has_cr_or_lf?
+      end
+    end
+
+    test "both" do
+      regex = GLib::Regex.new("to\no")
+      assert do
+        regex.has_cr_or_lf?
+      end
+    end
+
+    test "cr" do
+      regex = GLib::Regex.new("to\rtiti")
+      assert do
+        regex.has_cr_or_lf?
+      end
+    end
+  end
+
+  sub_test_case "max_lookbehind" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert_equal(0, regex.max_lookbehind)
+    end
+
+    test "three" do
+      regex = GLib::Regex.new("(?<!foo)bar")
+      assert_equal(3, regex.max_lookbehind)
+    end
+  end
+
+  sub_test_case "string_number" do
+    test "none" do
+      regex = GLib::Regex.new("too")
+      assert_equal(-1, regex.string_number("a_name"))
+    end
+
+    test "one" do
+      regex = GLib::Regex.new("(?<a_name>foo)bar")
+      assert_equal(1, regex.string_number("a_name"))
+    end
+
+    test "two" do
+      regex = GLib::Regex.new("(?<another_name>foo)(?<a_name>bar)")
+      assert_equal(2, regex.string_number("a_name"))
+    end
+  end
+
+  def test_regex_escape_string
+    assert_equal("a\\.b\\*c", GLib::Regex.escape_string("a.b*c"))
+  end
+
+  sub_test_case "match?" do
+    test "true" do
+      assert do
+        GLib::Regex.match?("to", "tatota")
+      end
+    end
+
+    test "false" do
+      assert do
+        not GLib::Regex.match?("ti", "tatota")
+      end
+    end
+  end
+
+  sub_test_case "match_all" do
+    test "no match" do
+      regex = GLib::Regex.new("[A-Z]+")
+      assert do
+        not regex.match_all("abc def").matches?
+      end
+    end
+
+    test ":start_position" do
+      regex = GLib::Regex.new("[A-Z]")
+      assert do
+        regex.match_all("a B c", :start_position => 2).matches?
+      end
+      assert do
+        not regex.match_all("a B c", :start_position => 3).matches?
+      end
+    end
+
+    test "match all" do
+      regex = GLib::Regex.new("<.*>")
+      assert_equal(3, regex.match_all("<a> <b> <c>").match_count)
+    end
+  end
+
+  sub_test_case "split simple" do
+    test "no options" do
+      splited_strings = GLib::Regex.split("\s", "a bc")
+      assert_equal(["a", "bc"], splited_strings)
+    end
+
+    test "match_options" do
+      splited_strings = GLib::Regex.split("a?b?", "toto ab")
+      assert_equal(["t", "o", "t", "o", " "], splited_strings)
+
+      splited_strings = GLib::Regex.split("a?b?",
+                                    "toto ab",
+                                    :match_options => :notempty)
+      assert_equal(["toto ", ""], splited_strings)
+    end
+  end
+
+  sub_test_case "replace" do
+    test "simple" do
+      regex = GLib::Regex.new("\\s")
+      assert_equal("a_bc", regex.replace("a bc", "_"))
+    end
+
+    test "back reference" do
+      regex = GLib::Regex.new("\\s")
+      assert_equal("a_ _bc", regex.replace("a bc", "_\\0_"))
+    end
+
+    test "literal" do
+      regex = GLib::Regex.new("\\s")
+      assert_equal("a_\\0_bc",
+                   regex.replace("a bc",
+                                 "_\\0_",
+                                 :literal => true))
+    end
+
+    sub_test_case "eval" do
+      test "all" do
+        regex = GLib::Regex.new("1|2|3|4")
+        modified_string = regex.replace(" 4 3 2 1") do |match_info|
+          "to"
+        end
+        assert_equal(" to to to to", modified_string)
+      end
+
+      test "break" do
+        regex = GLib::Regex.new("1|2|3|4")
+        modified_string = regex.replace(" 4 3 2 1") do |match_info|
+          break "to"
+        end
+        assert_equal(" to 3 2 1", modified_string)
+      end
+    end
+  end
+
+  sub_test_case "check_replacement" do
+    test "no references" do
+      assert_true(GLib::Regex.check_replacement("foo\\n"))
+    end
+
+    test "with references" do
+      assert_true(GLib::Regex.check_replacement("\\0\\1"))
+    end
+
+    test "invalid" do
+      assert_raise(GLib::Error) do
+        GLib::Regex.check_replacement("\\")
+      end
+    end
+  end
+
+  sub_test_case "have_reference?" do
+    test "no references" do
+      assert do
+        not GLib::Regex.have_reference?("foo\\n")
+      end
+    end
+
+    test "with references" do
+      assert do
+        GLib::Regex.have_reference?("\\0\\1")
+      end
+    end
+  end
+end
diff --git a/gobject-introspection/Rakefile b/gobject-introspection/Rakefile
index 892896d..4c701ce 100644
--- a/gobject-introspection/Rakefile
+++ b/gobject-introspection/Rakefile
@@ -32,7 +32,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "glib",
       :download_site => :gnome,
       :label => "GLib",
-      :version => "2.44.1",
+      :version => "2.48.0",
       :compression_method => "xz",
       :windows => {
         :build => false,
@@ -47,7 +47,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gobject-introspection",
       :download_site => :gnome,
       :label => "gobject-introspection",
-      :version => "1.44.0",
+      :version => "1.48.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/gobject-introspection/ext/gobject-introspection/extconf.rb b/gobject-introspection/ext/gobject-introspection/extconf.rb
index 763ca35..0e88ac3 100755
--- a/gobject-introspection/ext/gobject-introspection/extconf.rb
+++ b/gobject-introspection/ext/gobject-introspection/extconf.rb
@@ -57,6 +57,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "gobject-introspection-devel",
                                    :debian => "libgirepository1.0-dev",
                                    :redhat => "gobject-introspection-devel",
                                    :homebrew => "gobject-introspection",
diff --git a/gobject-introspection/ext/gobject-introspection/rb-gi-argument.c b/gobject-introspection/ext/gobject-introspection/rb-gi-argument.c
index 37cedbf..319df93 100644
--- a/gobject-introspection/ext/gobject-introspection/rb-gi-argument.c
+++ b/gobject-introspection/ext/gobject-introspection/rb-gi-argument.c
@@ -559,9 +559,9 @@ interface_variant_to_ruby(GVariant *variant)
 }
 
 static VALUE
-interface_to_ruby(GIArgument *argument,
-                  gboolean duplicate,
-                  GITypeInfo *type_info)
+rb_gi_argument_to_ruby_interface(GIArgument *argument,
+                                 gboolean duplicate,
+                                 GITypeInfo *type_info)
 {
     VALUE rb_interface;
     GIBaseInfo *interface_info;
@@ -1098,7 +1098,9 @@ rb_gi_argument_to_ruby(GIArgument *argument,
                                                    args_metadata);
         break;
     case GI_TYPE_TAG_INTERFACE:
-        rb_argument = interface_to_ruby(argument, duplicate, type_info);
+        rb_argument = rb_gi_argument_to_ruby_interface(argument,
+                                                       duplicate,
+                                                       type_info);
         break;
     case GI_TYPE_TAG_GLIST:
         rb_argument = rb_gi_argument_to_ruby_glist(argument, type_info);
@@ -1298,16 +1300,20 @@ rb_gi_out_argument_init_array(GIArgument *argument, GIArgInfo *arg_info,
 }
 
 static void
-rb_gi_out_argument_init_interface(GIArgument *argument, GIArgInfo *arg_info,
+rb_gi_out_argument_init_interface(GIArgument *argument,
+                                  G_GNUC_UNUSED GIArgInfo *arg_info,
                                   GITypeInfo *type_info)
 {
     GIBaseInfo *interface_info;
     GIInfoType interface_type;
 
+    /* TODO: Can we use the following code? */
+    /*
     if (!g_arg_info_is_caller_allocates(arg_info)) {
         argument->v_pointer = ALLOC(gpointer);
         return;
     }
+    */
 
     interface_info = g_type_info_get_interface(type_info);
     interface_type = g_base_info_get_type(interface_info);
@@ -1330,10 +1336,32 @@ rb_gi_out_argument_init_interface(GIArgument *argument, GIArgInfo *arg_info,
     }
     break;
     case GI_INFO_TYPE_BOXED:
+      rb_raise(rb_eNotImpError,
+               "TODO: allocates GIArgument(interface)[%s] for output",
+               g_info_type_to_string(interface_type));
+      break;
     case GI_INFO_TYPE_ENUM:
+      {
+          gint *pointer = ALLOC(gint);
+          *pointer = 0;
+          argument->v_pointer = pointer;
+      }
+      break;
     case GI_INFO_TYPE_FLAGS:
+      {
+          guint *pointer = ALLOC(guint);
+          *pointer = 0;
+          argument->v_pointer = pointer;
+      }
+      break;
     case GI_INFO_TYPE_OBJECT:
     case GI_INFO_TYPE_INTERFACE:
+      {
+          gpointer *pointer = ALLOC(gpointer);
+          *pointer = NULL;
+          argument->v_pointer = pointer;
+      }
+      break;
     case GI_INFO_TYPE_CONSTANT:
     case GI_INFO_TYPE_INVALID_0:
     case GI_INFO_TYPE_UNION:
@@ -1370,48 +1398,102 @@ rb_gi_out_argument_init(GIArgument *argument, GIArgInfo *arg_info)
     switch (type_tag) {
       case GI_TYPE_TAG_VOID:
         if (g_type_info_is_pointer(&type_info)) {
-            argument->v_pointer = ALLOC(gpointer);
+            gpointer *pointer = ALLOC(gpointer);
+            *pointer = NULL;
+            argument->v_pointer = pointer;
         }
         break;
       case GI_TYPE_TAG_BOOLEAN:
-        argument->v_pointer = ALLOC(gboolean);
+        {
+            gboolean *pointer = ALLOC(gboolean);
+            *pointer = FALSE;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_INT8:
-        argument->v_pointer = ALLOC(gint8);
+        {
+            gint8 *pointer = ALLOC(gint8);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_UINT8:
-        argument->v_pointer = ALLOC(guint8);
+        {
+            guint8 *pointer = ALLOC(guint8);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_INT16:
-        argument->v_pointer = ALLOC(gint16);
+        {
+            gint16 *pointer = ALLOC(gint16);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_UINT16:
-        argument->v_pointer = ALLOC(guint16);
+        {
+            guint16 *pointer = ALLOC(guint16);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_INT32:
-        argument->v_pointer = ALLOC(gint32);
+        {
+            gint32 *pointer = ALLOC(gint32);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_UINT32:
-        argument->v_pointer = ALLOC(guint32);
+        {
+            guint32 *pointer = ALLOC(guint32);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_INT64:
-        argument->v_pointer = ALLOC(gint64);
+        {
+            gint64 *pointer = ALLOC(gint64);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_UINT64:
-        argument->v_pointer = ALLOC(guint64);
+        {
+            guint64 *pointer = ALLOC(guint64);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_FLOAT:
-        argument->v_pointer = ALLOC(gfloat);
+        {
+            gfloat *pointer = ALLOC(gfloat);
+            *pointer = 0.0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_DOUBLE:
-        argument->v_pointer = ALLOC(gdouble);
+        {
+            gdouble *pointer = ALLOC(gdouble);
+            *pointer = 0.0;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_GTYPE:
-        argument->v_pointer = ALLOC(GType);
+        {
+            GType *pointer = ALLOC(GType);
+            *pointer = G_TYPE_INVALID;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_UTF8:
       case GI_TYPE_TAG_FILENAME:
-        argument->v_pointer = ALLOC(gchar *);
+        {
+            gchar **pointer = ALLOC(gchar *);
+            *pointer = NULL;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_ARRAY:
         rb_gi_out_argument_init_array(argument, arg_info, &type_info);
@@ -1422,14 +1504,25 @@ rb_gi_out_argument_init(GIArgument *argument, GIArgInfo *arg_info)
       case GI_TYPE_TAG_GLIST:
       case GI_TYPE_TAG_GSLIST:
       case GI_TYPE_TAG_GHASH:
-        argument->v_pointer = ALLOC(gpointer);
+        {
+            gpointer *pointer = ALLOC(gpointer);
+            *pointer = NULL;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_ERROR:
-        argument->v_pointer = ALLOC(GError *);
-        memset(argument->v_pointer, 0, sizeof(GError *));
+        {
+            GError **pointer = ALLOC(GError *);
+            *pointer = NULL;
+            argument->v_pointer = pointer;
+        }
         break;
       case GI_TYPE_TAG_UNICHAR:
-        argument->v_pointer = ALLOC(gunichar);
+        {
+            gunichar *pointer = ALLOC(gunichar);
+            *pointer = 0;
+            argument->v_pointer = pointer;
+        }
         break;
       default:
         g_assert_not_reached();
@@ -1824,9 +1917,13 @@ rb_gi_return_argument_free_everything_interface(GIArgument *argument,
         g_assert_not_reached();
         break;
     case GI_INFO_TYPE_UNION:
-        rb_raise(rb_eNotImpError,
-                 "TODO: free GIArgument(interface)[union] everything");
-        break;
+      if (gtype == G_TYPE_NONE) {
+          rb_raise(rb_eNotImpError,
+                   "TODO: free GIArgument(interface)[union] everything");
+      } else {
+          g_boxed_free(gtype, argument->v_pointer);
+      }
+      break;
     case GI_INFO_TYPE_VALUE:
         rb_raise(rb_eNotImpError,
                  "TODO: free GIArgument(interface)[value] everything");
diff --git a/gobject-introspection/ext/gobject-introspection/rb-gi-function-info.c b/gobject-introspection/ext/gobject-introspection/rb-gi-function-info.c
index 881501e..1621dca 100644
--- a/gobject-introspection/ext/gobject-introspection/rb-gi-function-info.c
+++ b/gobject-introspection/ext/gobject-introspection/rb-gi-function-info.c
@@ -1,6 +1,6 @@
 /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
 /*
- *  Copyright (C) 2012-2015  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2012-2016  Ruby-GNOME2 Project Team
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -34,6 +34,14 @@
 #define RG_TARGET_NAMESPACE rb_cGIFunctionInfo
 #define SELF(self) RVAL2GI_FUNCTION_INFO(self)
 
+typedef struct _RBGICallback {
+    GIArgInfo *arg_info;
+    GITypeInfo *type_info;
+    GICallbackInfo *callback_info;
+    ffi_cif cif;
+    ffi_closure *closure;
+} RBGICallback;
+
 static VALUE RG_TARGET_NAMESPACE;
 static VALUE rb_cGLibError;
 static const char *callbacks_key = "gi_callbacks";
@@ -148,9 +156,6 @@ fill_metadata_callback(GPtrArray *args_metadata)
         gint destroy_index;
 
         metadata = g_ptr_array_index(args_metadata, i);
-        if (!metadata->callback_p) {
-            continue;
-        }
 
         arg_info = &(metadata->arg_info);
         closure_index = g_arg_info_get_closure(arg_info);
@@ -274,9 +279,22 @@ callback_data_unguard_from_gc(RBGICallbackData *callback_data)
     rb_hash_delete(rb_callbacks, callback_data->rb_gc_guard_key);
 }
 
+static void
+rb_gi_callback_free(RBGICallback *callback)
+{
+    g_callable_info_free_closure(callback->callback_info,
+                                 callback->closure);
+    g_base_info_unref(callback->callback_info);
+    g_base_info_unref(callback->type_info);
+    xfree(callback);
+}
+
 void
 rb_gi_callback_data_free(RBGICallbackData *callback_data)
 {
+    if (callback_data->callback) {
+        rb_gi_callback_free(callback_data->callback);
+    }
     callback_data_unguard_from_gc(callback_data);
     xfree(callback_data->metadata);
     xfree(callback_data);
@@ -380,14 +398,535 @@ source_func_callback_finder(GIArgInfo *arg_info)
     return source_func_callback;
 }
 
+static void arguments_init(GArray **in_args,
+                           GArray **out_args,
+                           GPtrArray **args_metadata);
+static void arguments_free(VALUE rb_arguments,
+                           GArray *in_args,
+                           GArray *out_args,
+                           GPtrArray *args_metadata);
+
+static void
+argument_from_raw_data_interface(GICallableInfo *callable_info,
+                                 void *raw_arg,
+                                 GIArgument *argument,
+                                 GITypeInfo *type_info)
+{
+    GIBaseInfo *interface_info;
+    GIInfoType interface_type;
+
+    interface_info = g_type_info_get_interface(type_info);
+    interface_type = g_base_info_get_type(interface_info);
+
+    switch (interface_type) {
+    case GI_INFO_TYPE_INVALID:
+    case GI_INFO_TYPE_FUNCTION:
+    case GI_INFO_TYPE_CALLBACK:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    case GI_INFO_TYPE_STRUCT:
+      argument->v_pointer = *((gpointer *)(raw_arg));
+      break;
+    case GI_INFO_TYPE_BOXED:
+    case GI_INFO_TYPE_ENUM:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    case GI_INFO_TYPE_FLAGS:
+      argument->v_int32= *((gint32 *)(raw_arg));
+      break;
+    case GI_INFO_TYPE_OBJECT:
+    case GI_INFO_TYPE_INTERFACE:
+      argument->v_pointer = *((gpointer *)(raw_arg));
+      break;
+    case GI_INFO_TYPE_CONSTANT:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    case GI_INFO_TYPE_INVALID_0:
+        g_assert_not_reached();
+        break;
+    case GI_INFO_TYPE_UNION:
+    case GI_INFO_TYPE_VALUE:
+    case GI_INFO_TYPE_SIGNAL:
+    case GI_INFO_TYPE_VFUNC:
+    case GI_INFO_TYPE_PROPERTY:
+    case GI_INFO_TYPE_FIELD:
+    case GI_INFO_TYPE_ARG:
+    case GI_INFO_TYPE_TYPE:
+    case GI_INFO_TYPE_UNRESOLVED:
+    default:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: raw data -> GIArgument(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    }
+
+    g_base_info_unref(interface_info);
+}
+
+static void
+argument_from_raw_data(GICallableInfo *callable_info,
+                       void **raw_args,
+                       GArray *in_args,
+                       GArray *out_args,
+                       GPtrArray *args_metadata,
+                       guint i)
+{
+    RBGIArgMetadata *metadata;
+    GIArgument *argument;
+    GITypeInfo *type_info;
+    GITypeTag type_tag;
+
+    metadata = g_ptr_array_index(args_metadata, i);
+
+    if (metadata->direction == GI_DIRECTION_INOUT) {
+        argument = &g_array_index(in_args, GIArgument, metadata->in_arg_index);
+        argument->v_pointer = *((gpointer *)(raw_args[i]));
+        return;
+    } else if (metadata->direction == GI_DIRECTION_OUT) {
+        argument = &g_array_index(out_args, GIArgument, metadata->out_arg_index);
+        argument->v_pointer = *((gpointer *)(raw_args[i]));
+        return;
+    }
+
+    argument = &g_array_index(in_args, GIArgument, metadata->in_arg_index);
+    type_info = g_arg_info_get_type(&(metadata->arg_info));
+    type_tag = g_type_info_get_tag(type_info);
+
+    switch (type_tag) {
+      case GI_TYPE_TAG_VOID:
+        argument->v_pointer = *((gpointer *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_BOOLEAN:
+        argument->v_boolean = *((gboolean *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_INT8:
+        argument->v_int8 = *((gint8 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_UINT8:
+        argument->v_uint8 = *((guint8 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_INT16:
+        argument->v_int16 = *((gint16 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_UINT16:
+        argument->v_uint16 = *((guint16 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_INT32:
+        argument->v_int32 = *((gint32 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_UINT32:
+        argument->v_uint32 = *((guint32 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_INT64:
+        argument->v_int64 = *((gint64 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_UINT64:
+        argument->v_uint64 = *((guint64 *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_FLOAT:
+        argument->v_float = *((gfloat *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_DOUBLE:
+        argument->v_double = *((gdouble *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_GTYPE:
+        argument->v_size = *((gsize *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_UTF8:
+      case GI_TYPE_TAG_FILENAME:
+        argument->v_string = *((gchar **)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_ARRAY:
+        argument->v_pointer = *((gpointer *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_INTERFACE:
+        argument_from_raw_data_interface(callable_info,
+                                         raw_args[i],
+                                         argument,
+                                         type_info);
+        break;
+      case GI_TYPE_TAG_GLIST:
+      case GI_TYPE_TAG_GSLIST:
+      case GI_TYPE_TAG_GHASH:
+        argument->v_pointer = *((gpointer *)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_ERROR:
+        argument->v_pointer = *((GError **)(raw_args[i]));
+        break;
+      case GI_TYPE_TAG_UNICHAR:
+        argument->v_uint32 = *((gunichar *)(raw_args[i]));
+        break;
+      default:
+        g_assert_not_reached();
+        break;
+    }
+
+    g_base_info_unref(type_info);
+}
+
+static void
+arguments_from_raw_data(GICallableInfo *callable_info,
+                        void **args,
+                        GArray *in_args,
+                        GArray *out_args,
+                        GPtrArray *args_metadata)
+{
+    guint i;
+
+    for (i = 0; i < args_metadata->len; i++) {
+        argument_from_raw_data(callable_info,
+                               args,
+                               in_args,
+                               out_args,
+                               args_metadata,
+                               i);
+    }
+}
+
+static void
+in_arguments_to_ruby(GArray *in_args,
+                     GArray *out_args,
+                     GPtrArray *args_metadata,
+                     GArray *rb_args)
+{
+    guint i;
+
+    for (i = 0; i < args_metadata->len; i++) {
+        RBGIArgMetadata *metadata;
+        GIArgument *argument;
+        GITypeInfo *type_info;
+        VALUE rb_arg;
+
+        metadata = g_ptr_array_index(args_metadata, i);
+
+        if (metadata->direction == GI_DIRECTION_OUT) {
+            continue;
+        }
+        if (metadata->closure_p) {
+            continue;
+        }
+
+        argument = &g_array_index(in_args, GIArgument, metadata->in_arg_index);
+        type_info = g_arg_info_get_type(&(metadata->arg_info));
+        rb_arg = GI_ARGUMENT2RVAL(argument,
+                                  FALSE,
+                                  type_info,
+                                  in_args,
+                                  out_args,
+                                  args_metadata);
+        g_array_append_val(rb_args, rb_arg);
+    }
+}
+
+static void
+out_argument_to_raw_data_interface(GICallableInfo *callable_info,
+                                   GIArgument *argument,
+                                   gpointer result,
+                                   GITypeInfo *type_info,
+                                   G_GNUC_UNUSED GITransfer transfer /* TODO */)
+{
+    GIBaseInfo *interface_info;
+    GIInfoType interface_type;
+
+    interface_info = g_type_info_get_interface(type_info);
+    interface_type = g_base_info_get_type(interface_info);
+
+    switch (interface_type) {
+    case GI_INFO_TYPE_INVALID:
+    case GI_INFO_TYPE_FUNCTION:
+    case GI_INFO_TYPE_CALLBACK:
+    case GI_INFO_TYPE_STRUCT:
+    case GI_INFO_TYPE_BOXED:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: out raw data(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    case GI_INFO_TYPE_ENUM:
+      *((gint *)result) = argument->v_int;
+      break;
+    case GI_INFO_TYPE_FLAGS:
+    case GI_INFO_TYPE_OBJECT:
+    case GI_INFO_TYPE_INTERFACE:
+    case GI_INFO_TYPE_CONSTANT:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: out raw data(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    case GI_INFO_TYPE_INVALID_0:
+        g_assert_not_reached();
+        break;
+    case GI_INFO_TYPE_UNION:
+    case GI_INFO_TYPE_VALUE:
+    case GI_INFO_TYPE_SIGNAL:
+    case GI_INFO_TYPE_VFUNC:
+    case GI_INFO_TYPE_PROPERTY:
+    case GI_INFO_TYPE_FIELD:
+    case GI_INFO_TYPE_ARG:
+    case GI_INFO_TYPE_TYPE:
+    case GI_INFO_TYPE_UNRESOLVED:
+    default:
+        rb_raise(rb_eNotImpError,
+                 "TODO: %s::%s: out raw data(interface)[%s]: <%s>",
+                 g_base_info_get_namespace(callable_info),
+                 g_base_info_get_name(callable_info),
+                 g_info_type_to_string(interface_type),
+                 g_base_info_get_name(interface_info));
+        break;
+    }
+
+    g_base_info_unref(interface_info);
+}
+
+static void
+out_argument_to_raw_data(GICallableInfo *callable_info,
+                         VALUE rb_result,
+                         gpointer result,
+                         GITypeInfo *type_info,
+                         GITransfer transfer)
+{
+    GIArgument argument;
+    GITypeTag type_tag;
+
+    rb_gi_value_argument_from_ruby(&argument,
+                                   type_info,
+                                   rb_result,
+                                   rb_result);
+    type_tag = g_type_info_get_tag(type_info);
+    switch (type_tag) {
+      case GI_TYPE_TAG_VOID:
+        g_assert_not_reached();
+        break;
+      case GI_TYPE_TAG_BOOLEAN:
+        *((gboolean *)result) = argument.v_boolean;
+        break;
+      case GI_TYPE_TAG_INT8:
+        *((gint8 *)result) = argument.v_int8;
+        break;
+      case GI_TYPE_TAG_UINT8:
+        *((guint8 *)result) = argument.v_uint8;
+        break;
+      case GI_TYPE_TAG_INT16:
+        *((gint16 *)result) = argument.v_int16;
+        break;
+      case GI_TYPE_TAG_UINT16:
+        *((guint16 *)result) = argument.v_uint16;
+        break;
+      case GI_TYPE_TAG_INT32:
+        *((gint32 *)result) = argument.v_int32;
+        break;
+      case GI_TYPE_TAG_UINT32:
+        *((guint32 *)result) = argument.v_uint32;
+        break;
+      case GI_TYPE_TAG_INT64:
+        *((gint64 *)result) = argument.v_int64;
+        break;
+      case GI_TYPE_TAG_UINT64:
+        *((guint64 *)result) = argument.v_uint64;
+        break;
+      case GI_TYPE_TAG_FLOAT:
+        *((gfloat *)result) = argument.v_float;
+        break;
+      case GI_TYPE_TAG_DOUBLE:
+        *((gdouble *)result) = argument.v_double;
+        break;
+      case GI_TYPE_TAG_GTYPE:
+        *((gsize *)result) = argument.v_size;
+        break;
+      case GI_TYPE_TAG_UTF8:
+      case GI_TYPE_TAG_FILENAME:
+        *((gchar **)result) = argument.v_string;
+        break;
+      case GI_TYPE_TAG_ARRAY:
+        *((gpointer *)result) = argument.v_pointer;
+        break;
+      case GI_TYPE_TAG_INTERFACE:
+        out_argument_to_raw_data_interface(callable_info,
+                                           &argument,
+                                           result,
+                                           type_info,
+                                           transfer);
+        break;
+      case GI_TYPE_TAG_GLIST:
+      case GI_TYPE_TAG_GSLIST:
+      case GI_TYPE_TAG_GHASH:
+        *((gpointer *)result) = argument.v_pointer;
+        break;
+      case GI_TYPE_TAG_ERROR:
+        *((GError **)result) = argument.v_pointer;
+        break;
+      case GI_TYPE_TAG_UNICHAR:
+        *((gunichar *)result) = argument.v_uint32;
+        break;
+      default:
+        g_assert_not_reached();
+        break;
+    }
+}
+
+static void
+out_arguments_to_raw_data(GICallableInfo *callable_info,
+                          VALUE rb_results,
+                          void *result,
+                          GArray *out_args,
+                          GPtrArray *args_metadata)
+{
+    int i_rb_result = 0;
+    guint i;
+    GITypeInfo *return_type_info;
+    GITypeTag return_type_tag;
+
+    return_type_info = g_callable_info_get_return_type(callable_info);
+    return_type_tag = g_type_info_get_tag(return_type_info);
+    if (return_type_tag != GI_TYPE_TAG_VOID) {
+        GITransfer transfer;
+        transfer = g_callable_info_get_caller_owns(callable_info);
+        if (out_args->len == 0) {
+            VALUE rb_return_value = rb_results;
+            out_argument_to_raw_data(callable_info,
+                                     rb_return_value,
+                                     result,
+                                     return_type_info,
+                                     transfer);
+        } else {
+            out_argument_to_raw_data(callable_info,
+                                     RARRAY_AREF(rb_results, i_rb_result),
+                                     result,
+                                     return_type_info,
+                                     transfer);
+            i_rb_result++;
+        }
+    }
+    g_base_info_unref(return_type_info);
+
+    for (i = 0; i < args_metadata->len; i++) {
+        RBGIArgMetadata *metadata;
+        GIArgument *argument;
+        GITypeInfo *type_info;
+        GITransfer transfer;
+
+        metadata = g_ptr_array_index(args_metadata, i);
+
+        /* TODO: support GI_DIRECTION_INOUT */
+        if (metadata->direction != GI_DIRECTION_OUT) {
+            continue;
+        }
+
+        argument = &g_array_index(out_args, GIArgument, metadata->out_arg_index);
+        type_info = g_arg_info_get_type(&(metadata->arg_info));
+        transfer = g_arg_info_get_ownership_transfer(&(metadata->arg_info));
+        out_argument_to_raw_data(callable_info,
+                                 RARRAY_AREF(rb_results, i_rb_result),
+                                 argument->v_pointer,
+                                 type_info,
+                                 transfer);
+        i_rb_result++;
+        g_base_info_unref(type_info);
+    }
+}
+
+static void
+ffi_closure_callback(G_GNUC_UNUSED ffi_cif *cif,
+                     void *result,
+                     void **raw_args,
+                     void *data)
+{
+    RBGICallback *callback = data;
+    RBGICallbackData *callback_data = NULL;
+    GArray *in_args;
+    GArray *out_args;
+    GPtrArray *args_metadata;
+    VALUE rb_results;
+
+    arguments_init(&in_args, &out_args, &args_metadata);
+    allocate_arguments(callback->callback_info,
+                       in_args,
+                       out_args,
+                       args_metadata);
+    fill_metadata(args_metadata);
+    arguments_from_raw_data(callback->callback_info,
+                            raw_args,
+                            in_args,
+                            out_args,
+                            args_metadata);
+
+    {
+        guint i;
+
+        for (i = 0; i < args_metadata->len; i++) {
+            RBGIArgMetadata *metadata;
+
+            metadata = g_ptr_array_index(args_metadata, i);
+            if (!metadata->closure_p) {
+                continue;
+            }
+
+            callback_data = *((RBGICallbackData **)(raw_args[i]));
+            break;
+        }
+    }
+
+    {
+        ID id_call;
+        GArray *rb_args;
+
+        rb_args = g_array_new(FALSE, FALSE, sizeof(VALUE));
+        in_arguments_to_ruby(in_args,
+                             out_args,
+                             args_metadata,
+                             rb_args);
+        CONST_ID(id_call, "call");
+        /* TODO: use rb_protect() */
+        rb_results = rb_funcallv(callback_data->rb_callback,
+                                 id_call,
+                                 rb_args->len,
+                                 (VALUE *)(rb_args->data));
+        g_array_free(rb_args, TRUE);
+    }
+
+    out_arguments_to_raw_data(callback->callback_info,
+                              rb_results,
+                              result,
+                              out_args,
+                              args_metadata);
+
+    if (callback_data->metadata->scope_type == GI_SCOPE_TYPE_ASYNC) {
+        rb_gi_callback_data_free(callback_data);
+    }
+}
+
 static void
 in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args)
 {
-    gpointer callback;
+    gpointer callback_function;
     GIArgInfo *arg_info;
     GIArgument *callback_argument;
     GIArgument *closure_argument = NULL;
     GIArgument *destroy_argument = NULL;
+    RBGICallback *callback = NULL;
 
     arg_info = &(metadata->arg_info);
 
@@ -416,26 +955,26 @@ in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args)
         return;
     }
 
-    callback = find_callback_function(arg_info);
-    if (!callback) {
-        GITypeInfo type_info;
-        GIBaseInfo *interface_info;
-        VALUE rb_type_name;
-        g_arg_info_load_type(arg_info, &type_info);
-        interface_info = g_type_info_get_interface(&type_info);
-        rb_type_name = CSTR2RVAL(g_base_info_get_name(interface_info));
-        g_base_info_unref(interface_info);
-        rb_raise(rb_eNotImpError,
-                 "TODO: <%s>(%s) callback is not supported yet.",
-                 RVAL2CSTR(rb_type_name),
-                 g_base_info_get_name(arg_info));
+    callback_function = find_callback_function(arg_info);
+    if (callback_function) {
+        callback_argument->v_pointer = callback_function;
+    } else {
+        callback = RB_ZALLOC(RBGICallback);
+        callback->type_info = g_arg_info_get_type(arg_info);
+        callback->callback_info = g_type_info_get_interface(callback->type_info);
+        callback->closure =
+            g_callable_info_prepare_closure(callback->callback_info,
+                                            &(callback->cif),
+                                            ffi_closure_callback,
+                                            callback);
+        callback_argument->v_pointer = callback->closure;
     }
-    callback_argument->v_pointer = callback;
 
     if (closure_argument) {
         RBGICallbackData *callback_data;
 
         callback_data = ALLOC(RBGICallbackData);
+        callback_data->callback = callback;
         callback_data->metadata = metadata;
         callback_data->rb_callback = rb_block_proc();
         callback_data_guard_from_gc(callback_data);
diff --git a/gobject-introspection/ext/gobject-introspection/rb-gi-repository.c b/gobject-introspection/ext/gobject-introspection/rb-gi-repository.c
index f7cbd3d..100f5ac 100644
--- a/gobject-introspection/ext/gobject-introspection/rb-gi-repository.c
+++ b/gobject-introspection/ext/gobject-introspection/rb-gi-repository.c
@@ -243,6 +243,14 @@ rg_find(int argc, VALUE *argv, VALUE self)
     return GI_BASE_INFO2RVAL(info);
 }
 
+static VALUE
+rg_get_version(VALUE self, VALUE rb_namespace)
+{
+    const gchar *version;
+    version = g_irepository_get_version(SELF(self), RVAL2CSTR(rb_namespace));
+    return CSTR2RVAL(version);
+}
+
 void
 rb_gi_repository_init(VALUE rb_mGI)
 {
@@ -259,6 +267,7 @@ rb_gi_repository_init(VALUE rb_mGI)
     RG_DEF_METHOD(get_n_infos, 1);
     RG_DEF_METHOD(get_info, 2);
     RG_DEF_METHOD(find, -1);
+    RG_DEF_METHOD(get_version, 1);
 
     G_DEF_CLASS(G_TYPE_I_REPOSITORY_LOAD_FLAGS, "RepositoryLoadFlags", rb_mGI);
     G_DEF_CLASS(G_TYPE_I_REPOSITORY_ERROR, "RepositoryError", rb_mGI);
diff --git a/gobject-introspection/ext/gobject-introspection/rb-gobject-introspection.h b/gobject-introspection/ext/gobject-introspection/rb-gobject-introspection.h
index 2c51042..3b260b1 100644
--- a/gobject-introspection/ext/gobject-introspection/rb-gobject-introspection.h
+++ b/gobject-introspection/ext/gobject-introspection/rb-gobject-introspection.h
@@ -28,6 +28,8 @@
 
 typedef gpointer (*RBGICallbackFinderFunc)(GIArgInfo *info);
 
+typedef struct _RBGICallback RBGICallback;
+
 typedef struct
 {
     GIArgInfo arg_info;
@@ -49,6 +51,7 @@ typedef struct
 } RBGIArgMetadata;
 
 typedef struct {
+    RBGICallback *callback;
     RBGIArgMetadata *metadata;
     VALUE rb_gc_guard_key;
     VALUE rb_callback;
diff --git a/gobject-introspection/lib/gobject-introspection/loader.rb b/gobject-introspection/lib/gobject-introspection/loader.rb
index a284d7a..549ae47 100644
--- a/gobject-introspection/lib/gobject-introspection/loader.rb
+++ b/gobject-introspection/lib/gobject-introspection/loader.rb
@@ -100,7 +100,7 @@ module GObjectIntrospection
 
     def define_singleton_method(klass, name, info)
       unlock_gvl = should_unlock_gvl?(info, klass)
-      prepare = lambda do |arguments|
+      prepare = lambda do |arguments, &block|
         arguments, block = build_arguments(info, arguments, &block)
         validate_arguments(info, "#{klass}.#{name}", arguments)
         [arguments, block]
diff --git a/gobject-introspection/patches/cross-g-ir-scanner.diff b/gobject-introspection/patches/cross-g-ir-scanner.diff
index 76b6db3..7c64618 100644
--- a/gobject-introspection/patches/cross-g-ir-scanner.diff
+++ b/gobject-introspection/patches/cross-g-ir-scanner.diff
@@ -1,48 +1,70 @@
 diff --git a/giscanner/ccompiler.py b/giscanner/ccompiler.py
-index 1c66aac..e922feb 100644
+index 57df9d6..8c34cec 100644
 --- a/giscanner/ccompiler.py
 +++ b/giscanner/ccompiler.py
-@@ -137,17 +137,16 @@ class CCompiler(object):
-             is_msvc = False
-             libtool = utils.get_libtool_command(options)
-             if libtool:
--                args.append(utils.which(os.environ.get('SHELL', 'sh.exe')))
+@@ -20,6 +20,7 @@
+ 
+ import os
+ import subprocess
++import shlex
+ import tempfile
+ 
+ import sys
+@@ -73,6 +74,7 @@ class CCompiler(object):
+         else:
+             self.compiler = distutils.ccompiler.new_compiler(compiler=compiler_name)
+         customize_compiler(self.compiler)
++        self.compiler.exe_extension = '.exe'
+ 
+         # customize_compiler() from distutils only does customization
+         # for 'unix' compiler type.  Also, avoid linking to msvcrxx.dll
+@@ -232,6 +234,7 @@ class CCompiler(object):
+ 
+         includes.extend(include_paths)
+         extra_postargs.extend(extra_args)
++        extra_postargs.append('-fno-stack-protector')
+ 
+         return self.compiler.compile(sources=source,
+                                      macros=macros,
+@@ -287,12 +290,15 @@ class CCompiler(object):
                  args.extend(libtool)
                  args.append('--mode=execute')
--            # FIXME: it could have prefix (i686-w64-mingw32-dlltool.exe)
--            args.extend(['dlltool.exe', '--identify'])
-+            args.extend([compiler_cmd.replace('gcc', 'dlltool'), '--identify'])
-             proc = subprocess.Popen([compiler_cmd, '-print-search-dirs'],
+             args.extend([os.environ.get('DLLTOOL', 'dlltool.exe'), '--identify'])
+-            proc = subprocess.Popen([self.compiler_cmd, '-print-search-dirs'],
++            search_dirs_args = shlex.split(self.compiler_cmd)
++            search_dirs_args += ['-print-search-dirs']
++            proc = subprocess.Popen(search_dirs_args,
                                      stdout=subprocess.PIPE)
              o, e = proc.communicate()
-             for line in o.splitlines():
+             for line in o.decode('ascii').splitlines():
                  if line.startswith('libraries: '):
-                     libsearch = line[len('libraries: '):].split(';')
+                     libsearch = line[len('libraries: '):].split(os.pathsep)
 +        libsearch = options.library_paths + libsearch
  
          shlibs = []
          not_resolved = []
-diff --git a/giscanner/dumper.py b/giscanner/dumper.py
-index 45a09fc..3c70be6 100644
---- a/giscanner/dumper.py
-+++ b/giscanner/dumper.py
-@@ -160,6 +160,7 @@ class DumpCompiler(object):
-         else:
-             o_path = self._generate_tempfile(tmpdir, '.o')
+diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py
+old mode 100644
+new mode 100755
+index c93d20c..e155200
+--- a/giscanner/shlibs.py
++++ b/giscanner/shlibs.py
+@@ -31,6 +31,7 @@ import subprocess
  
-+        os.name = 'nt'
-         if os.name == 'nt':
-             ext = '.exe'
-         else:
-@@ -263,10 +264,7 @@ class DumpCompiler(object):
+ from .utils import get_libtool_command, extract_libtool_shlib
+ from .ccompiler import CCompiler
++from distutils.cygwinccompiler import Mingw32CCompiler
+ 
+ 
+ # For .la files, the situation is easy.
+@@ -94,8 +95,8 @@ def _resolve_non_libtool(options, binary, libraries):
          else:
-             args.extend(['-o', output])
-         if libtool:
--            if os.name == 'nt':
--                args.append('-Wl,--export-all-symbols')
--            else:
--                args.append('-export-dynamic')
-+            args.append('-export-dynamic')
- 
-         cppflags = os.environ.get('CPPFLAGS', '')
-         for cppflag in cppflags.split():
+             binary.args[0] = old_argdir
+ 
+-    if os.name == 'nt':
+-        cc = CCompiler()
++    cc = CCompiler()
++    if cc.compiler.exe_extension == '.exe':
+         shlibs = cc.resolve_windows_libs(libraries, options)
+ 
+     else:
diff --git a/gobject-introspection/patches/support-external-g-ir-scanner.diff b/gobject-introspection/patches/support-external-g-ir-scanner.diff
index c4bd75d..f4f2488 100644
--- a/gobject-introspection/patches/support-external-g-ir-scanner.diff
+++ b/gobject-introspection/patches/support-external-g-ir-scanner.diff
@@ -1,5 +1,5 @@
 diff --git a/Makefile-gir.am b/Makefile-gir.am
-index 52f7ee3..c03f4e2 100644
+index a09260a..540e2d1 100644
 --- a/Makefile-gir.am
 +++ b/Makefile-gir.am
 @@ -68,7 +68,8 @@ GLib_2_0_gir_SCANNERFLAGS = \
@@ -46,7 +46,7 @@ index 52f7ee3..c03f4e2 100644
  
  GModule_2_0_gir_PACKAGES = gmodule-2.0
  GModule_2_0_gir_INCLUDES = GLib-2.0
-@@ -171,7 +179,8 @@ Gio_2_0_gir_SCANNERFLAGS = \
+@@ -173,7 +181,8 @@ Gio_2_0_gir_SCANNERFLAGS = \
              --c-include="gio/gio.h" \
              $(GIO_CINCLUDES) \
              --add-include-path=. \
@@ -57,7 +57,7 @@ index 52f7ee3..c03f4e2 100644
  Gio_2_0_gir_PACKAGES = gio-2.0 $(GIO_UNIX_PACKAGES)
  Gio_2_0_gir_INCLUDES = GObject-2.0
 diff --git a/Makefile-giscanner.am b/Makefile-giscanner.am
-index c2273cd..0f47126 100644
+index b0e1373..fd618c9 100644
 --- a/Makefile-giscanner.am
 +++ b/Makefile-giscanner.am
 @@ -1,17 +1,21 @@
@@ -93,41 +93,40 @@ index c2273cd..0f47126 100644
  	giscanner/__init__.py		\
  	giscanner/annotationmain.py	\
 diff --git a/Makefile-tools.am b/Makefile-tools.am
-index 34d2a25..87c3a1f 100644
+index dbd264c..c9b58c2 100644
 --- a/Makefile-tools.am
 +++ b/Makefile-tools.am
-@@ -1,5 +1,8 @@
+@@ -1,5 +1,7 @@
  bin_PROGRAMS += g-ir-compiler g-ir-generate
-+
 +if BUILD_SCANNER
  bin_SCRIPTS += g-ir-scanner g-ir-annotation-tool
 +endif
  
  if BUILD_DOCTOOL
  bin_SCRIPTS += g-ir-doc-tool
-@@ -12,6 +15,7 @@ EXTRA_DIST += 				\
+@@ -10,6 +12,7 @@ EXTRA_DIST += 				\
  
- TOOL_SUBSTITUTIONS = sed -e s, at libdir\@,$(libdir), -e s, at datarootdir\@,$(datarootdir), -e s, at PYTHON\@,$(PYTHON),
+ TOOL_SUBSTITUTIONS = -e s, at libdir\@,$(libdir), -e s, at datarootdir\@,$(datarootdir), -e s, at PYTHON\@,$(PYTHON),
  
 +if BUILD_SCANNER
- g-ir-scanner: tools/g-ir-scanner.in _giscanner.la Makefile
- 	$(AM_V_GEN) $(TOOL_SUBSTITUTIONS) $< > $@.tmp && mv $@.tmp $@
+ g-ir-scanner: tools/g-ir-tool-template.in _giscanner.la Makefile
+ 	$(AM_V_GEN) sed $(TOOL_SUBSTITUTIONS) -e s, at TOOL_MODULE\@,scannermain, -e s, at TOOL_FUNCTION\@,scanner_main, $< > $@.tmp && mv $@.tmp $@
  	@chmod a+x $@
-@@ -19,10 +23,13 @@ g-ir-scanner: tools/g-ir-scanner.in _giscanner.la Makefile
- g-ir-annotation-tool: tools/g-ir-annotation-tool.in _giscanner.la Makefile
- 	$(AM_V_GEN) $(TOOL_SUBSTITUTIONS) $< > $@.tmp && mv $@.tmp $@
+@@ -17,10 +20,13 @@ g-ir-scanner: tools/g-ir-tool-template.in _giscanner.la Makefile
+ g-ir-annotation-tool: tools/g-ir-tool-template.in _giscanner.la Makefile
+ 	$(AM_V_GEN) sed $(TOOL_SUBSTITUTIONS) -e s, at TOOL_MODULE\@,annotationmain, -e s, at TOOL_FUNCTION\@,annotation_main, $< > $@.tmp && mv $@.tmp $@
  	@chmod a+x $@
 +endif
  
 +if BUILD_DOCTOOL
- g-ir-doc-tool: tools/g-ir-doc-tool.in _giscanner.la Makefile
- 	$(AM_V_GEN) $(TOOL_SUBSTITUTIONS) $< > $@.tmp && mv $@.tmp $@
+ g-ir-doc-tool: tools/g-ir-tool-template.in _giscanner.la Makefile
+ 	$(AM_V_GEN) sed $(TOOL_SUBSTITUTIONS) -e s, at TOOL_MODULE\@,docmain, -e s, at TOOL_FUNCTION\@,doc_main, $< > $@.tmp && mv $@.tmp $@
  	@chmod a+x $@
 +endif
  
  g_ir_compiler_SOURCES = tools/compiler.c
  g_ir_compiler_CPPFLAGS = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" \
-@@ -46,4 +53,10 @@ GCOVSOURCES =					\
+@@ -44,4 +50,10 @@ GCOVSOURCES =					\
  	$(g_ir_compiler_SOURCES)		\
  	$(g_ir_generate_SOURCES)
  
@@ -140,7 +139,7 @@ index 34d2a25..87c3a1f 100644
 +CLEANFILES += g-ir-doc-tool
 +endif
 diff --git a/Makefile.am b/Makefile.am
-index 1a988a5..b14b745 100644
+index b080a89..344598a 100644
 --- a/Makefile.am
 +++ b/Makefile.am
 @@ -35,8 +35,11 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-doctool
@@ -150,14 +149,14 @@ index 1a988a5..b14b745 100644
 -	docs/g-ir-generate.1	\
 +	docs/g-ir-generate.1
 +if BUILD_SCANNER
-+man_MANS +=			\
++man_MANS +=	\
  	docs/g-ir-scanner.1
 +endif
  
  pkgconfigdir = $(libdir)/pkgconfig
  pkgconfig_DATA = gobject-introspection-1.0.pc gobject-introspection-no-export-1.0.pc
 diff --git a/common.mk b/common.mk
-index 303622f..30a011a 100644
+index b778f7a..9d10e65 100644
 --- a/common.mk
 +++ b/common.mk
 @@ -9,11 +9,14 @@
@@ -179,15 +178,28 @@ index 303622f..30a011a 100644
  INTROSPECTION_SCANNER_ARGS = \
      --verbose \
 diff --git a/configure.ac b/configure.ac
-index 1fd260a..615ff18 100644
+index 6c91fa5..168a813 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -250,19 +250,42 @@ AC_FUNC_STRTOD
+@@ -250,32 +250,55 @@ AC_FUNC_STRTOD
  AC_CHECK_FUNCS([memchr strchr strspn strstr strtol strtoull])
  AC_CHECK_FUNCS([backtrace backtrace_symbols])
  
 -# Python
--AM_PATH_PYTHON([2.6])
+-# option to specify python interpreter to use; this just sets $PYTHON, so that
+-# we will fallback to reading $PYTHON if --with-python is not given, and
+-# python.m4 will get the expected input
+-AC_ARG_WITH(python,
+-  AS_HELP_STRING([--with-python=PATH],[Path to Python interpreter; searches $PATH if only a program name is given; if not given, searches for a few standard names such as "python3" or "python2"]),
+-  [PYTHON="$withval"], [])
+-if test x"$PYTHON" = xyes; then
+-    AC_MSG_ERROR([--with-python option requires a path or program argument])
+-fi
+-if test -n "$PYTHON" && ! which "$PYTHON"; then
+-    AC_MSG_ERROR([Python interpreter $PYTHON does not exist])
+-fi
+-
+-AM_PATH_PYTHON([2.7])
 -case "$host" in
 -*-*-mingw*)
 -	# Change backslashes to forward slashes in pyexecdir to avoid
@@ -207,13 +219,26 @@ index 1fd260a..615ff18 100644
 +        build_g_ir_scanner=no
 +        ;;
 +xno)
-+        # Python
-+        AM_PATH_PYTHON([2.6])
-+        case "$host" in
-+        *-*-mingw*)
-+                # Change backslashes to forward slashes in pyexecdir to avoid
-+                # quoting issues
-+                pyexecdir=`echo $pyexecdir | tr '\\\\' '/'`
++	# Python
++	# option to specify python interpreter to use; this just sets $PYTHON, so that
++	# we will fallback to reading $PYTHON if --with-python is not given, and
++	# python.m4 will get the expected input
++	AC_ARG_WITH(python,
++	  AS_HELP_STRING([--with-python=PATH],[Path to Python interpreter; searches $PATH if only a program name is given; if not given, searches for a few standard names such as "python3" or "python2"]),
++	  [PYTHON="$withval"], [])
++	if test x"$PYTHON" = xyes; then
++	    AC_MSG_ERROR([--with-python option requires a path or program argument])
++	fi
++	if test -n "$PYTHON" && ! which "$PYTHON"; then
++	    AC_MSG_ERROR([Python interpreter $PYTHON does not exist])
++	fi
++	
++	AM_PATH_PYTHON([2.7])
++	case "$host" in
++	*-*-mingw*)
++		# Change backslashes to forward slashes in pyexecdir to avoid
++		# quoting issues
++		pyexecdir=`echo $pyexecdir | tr '\\\\' '/'`
 +                ;;
 +        esac
 +        AM_CHECK_PYTHON_HEADERS(, AC_MSG_ERROR([Python headers not found]))
@@ -237,7 +262,7 @@ index 1fd260a..615ff18 100644
  
  dnl Not enabled by default until 3.6 cycle when we can propose mako as
  dnl an external dependency
-@@ -347,6 +370,13 @@ fi
+@@ -360,6 +383,13 @@ fi
  
  AC_SUBST(EXTRA_LINK_FLAGS)
  
@@ -276,7 +301,7 @@ index bdd0fa7..70f1825 100644
  CLEANFILES += \
      $(BUILT_SOURCES) \
 diff --git a/tests/offsets/Makefile.am b/tests/offsets/Makefile.am
-index 65d8773..66b00b1 100644
+index a40e90b..9e67a3e 100644
 --- a/tests/offsets/Makefile.am
 +++ b/tests/offsets/Makefile.am
 @@ -11,7 +11,9 @@ EXTRA_PROGRAMS =
@@ -312,7 +337,7 @@ index 65d8773..66b00b1 100644
  ############################################################
  
 diff --git a/tests/repository/Makefile.am b/tests/repository/Makefile.am
-index 882fa9e..89c9069 100644
+index d1cbaa5..6960e29 100644
 --- a/tests/repository/Makefile.am
 +++ b/tests/repository/Makefile.am
 @@ -2,8 +2,10 @@ AM_CFLAGS = $(GOBJECT_CFLAGS)
@@ -320,17 +345,17 @@ index 882fa9e..89c9069 100644
  LIBS = $(GOBJECT_LIBS)
  
 +if ENABLE_TESTS
- EXTRA_PROGRAMS = gitestrepo gitestthrows gitypelibtest
+ EXTRA_PROGRAMS = gitestrepo giteststructinfo gitestthrows gitypelibtest
  CLEANFILES = $(EXTRA_PROGRAMS)
 +endif
  
  gitestrepo_SOURCES = $(srcdir)/gitestrepo.c
  gitestrepo_CPPFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository
 diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am
-index 92ab12a..41f4de8 100644
+index 13156c3..81f50ef 100644
 --- a/tests/scanner/Makefile.am
 +++ b/tests/scanner/Makefile.am
-@@ -9,6 +9,7 @@ INTROSPECTION_SCANNER_ARGS += --warn-all
+@@ -9,6 +9,7 @@ INTROSPECTION_SCANNER_ARGS += --warn-all --reparse-validate
  
  CLEANFILES =
  
@@ -347,7 +372,7 @@ index 92ab12a..41f4de8 100644
  GI_SCANNER_CFLAGS = -I$(top_srcdir)/tests
  AM_CPPFLAGS = -I$(top_srcdir)/girepository
 @@ -147,7 +149,7 @@ Typedefs_1_0_gir_FILES = $(libtypedefs_la_SOURCES)
- Typedefs_1_0_gir_SCANNERFLAGS = --c-include="typedefs.h" --identifier-prefix=Typedefs --symbol-prefix=typedefs
+ Typedefs_1_0_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS) --c-include="typedefs.h" --identifier-prefix=Typedefs --symbol-prefix=typedefs
  GIRS += Typedefs-1.0.gir
  
 -if !OS_WIN32
diff --git a/gstreamer/Rakefile b/gstreamer/Rakefile
index 5e6dc10..7058bea 100644
--- a/gstreamer/Rakefile
+++ b/gstreamer/Rakefile
@@ -29,14 +29,14 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     "glib2", "atk", "pango", "gdk_pixbuf2", "gtk2", "gobject-introspection",
   ]
   xiph_download_url_base = "http://downloads.xiph.org/releases"
-  freedesktop_download_url_base = "http://gstreamer.freedesktop.org/src"
+  freedesktop_download_url_base = "https://gstreamer.freedesktop.org/src"
   sf_net_download_url_base = "http://downloads.sourceforge.net/project"
   libmad_version = "0.15.1b"
   package.external_packages = [
     {
       :name => "libjpeg",
-      :base_name => "jpeg-9a",
-      :archive_base_name => "jpegsrc.v9a.tar.gz",
+      :base_name => "jpeg-9b",
+      :archive_base_name => "jpegsrc.v9b.tar.gz",
       :download_base_url => "http://www.ijg.org/files",
       :label => "libjpeg",
       :windows => {
@@ -46,9 +46,9 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "sqlite-autoconf",
-      :download_base_url => "http://www.sqlite.org/2015",
+      :download_base_url => "http://www.sqlite.org/2016",
       :label => "SQLite",
-      :version => "3081101",
+      :version => "3120000",
       :compression_method => "gz",
       :windows => {
         :configure_args => [],
@@ -59,7 +59,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "libsoup",
       :download_site => :gnome,
       :label => "libsoup",
-      :version => "2.50.0",
+      :version => "2.54.0.1",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -135,7 +135,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "opus",
       :download_base_url => "#{xiph_download_url_base}/opus",
       :label => "Opus",
-      :version => "1.1",
+      :version => "1.1.2",
       :windows => {
         :configure_args => [],
         :built_file => "bin/libopus-0.dll",
@@ -145,19 +145,19 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gstreamer",
       :download_base_url => "#{freedesktop_download_url_base}/gstreamer",
       :label => "GStreamer",
-      :version => "1.5.2",
+      :version => "1.8.0",
       :compression_method => "xz",
       :windows => {
         :cc_args => "-std=gnu99",
         :configure_args => [
-          "--enable-check",
+          "--disable-check",
           "--enable-introspection",
         ],
         :build_concurrently => false,
         :patches => [
-          "gstreamer-1.5.2-remove-introspection-compiler-dependency.diff",
         ],
         :need_autoreconf => true,
+        :gobject_introspection_compiler_split_args => true,
         :built_file => "bin/libgstreamer-1.0-0.dll",
       },
     },
@@ -165,19 +165,20 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gst-plugins-base",
       :download_base_url => "#{freedesktop_download_url_base}/gst-plugins-base",
       :label => "GStreamer plugins (base)",
-      :version => "1.5.2",
+      :version => "1.8.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
           "--enable-introspection",
         ],
+        :cc_args => [
+          "-std=gnu99",
+        ],
         :build_concurrently => false,
         :patches => [
-          "gst-plugins-base-1.5.2-use-portable-64bit-data-print-modifier.diff",
-          "gst-plugins-base-1.5.2-use-portable-cast.diff",
-          "gst-plugins-base-1.5.2-remove-introspection-compiler-dependency.diff",
         ],
         :need_autoreconf => true,
+        :gobject_introspection_compiler_split_args => true,
         :built_file => "lib/gstreamer-1.0/libgstgio.dll",
       },
     },
@@ -185,12 +186,13 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gst-plugins-good",
       :download_base_url => "#{freedesktop_download_url_base}/gst-plugins-good",
       :label => "GStreamer plugins (good)",
-      :version => "1.5.2",
+      :version => "1.8.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
           "--disable-shout2",
         ],
+        :gobject_introspection_compiler_split_args => true,
         :built_file => "lib/gstreamer-1.0/libgstcairo.dll",
       },
     },
@@ -198,18 +200,18 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gst-plugins-bad",
       :download_base_url => "#{freedesktop_download_url_base}/gst-plugins-bad",
       :label => "GStreamer plugins (bad)",
-      :version => "1.5.2",
+      :version => "1.8.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => ["--disable-librfb"],
         :cc_args => [
-          "-std=c99",
+          "-std=gnu99",
         ],
         :need_autoreconf => true,
+        :gobject_introspection_compiler_split_args => true,
         :patches => [
-          "gst-plugins-bad-1.5.2-use-only-I.diff",
-          "gst-plugins-bad-1.5.2-use-portable-cast.diff",
-          "gst-plugins-bad-1.5.2-remove-introspection-compiler-dependency.diff",
+          "gst-plugins-bad-1.8.0-use-only-I.diff",
+          "gst-plugins-bad-1.8.0-add-missing-lole32.diff",
         ],
         :built_file => "lib/gstreamer-1.0/libgstmxf.dll",
       },
@@ -218,28 +220,30 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     #   :name => "gst-plugins-ugly",
     #   :download_base_url => "#{freedesktop_download_url_base}/gst-plugins-ugly",
     #   :label => "GStreamer plugins (ugly)",
-    #   :version => "1.5.2",
+    #   :version => "1.8.0",
     #   :compression_method => "xz",
     #   :windows => {
     #     :configure_args => [],
+    #     :gobject_introspection_compiler_split_args => true,
     #   },
     # },
     {
       :name => "gst-libav",
       :download_base_url => "#{freedesktop_download_url_base}/gst-libav",
       :label => "GStreamer libav",
-      :version => "1.5.2",
+      :version => "1.8.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
           "--with-libav-extra-configure=" +
             "--cross-prefix=#{package.windows.build_host}- " +
             "--target-os=mingw32 " +
-            "--arch=i686 " +
+            "--arch=#{package.windows.build_arch} " +
             "--pkg-config=pkg-config " +
             "--disable-gpl " +
             "--disable-yasm",
         ],
+        :gobject_introspection_compiler_split_args => true,
         :built_file => "lib/gstreamer-1.0/libgstlibav.dll",
       },
       :bundled_packages => [
@@ -247,7 +251,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
           :name => "libav",
           :path => "gst-libs/ext/libav",
           :license_files => [
-            "LICENSE",
+            "LICENSE.md",
             "CREDITS",
             "COPYING.GPLv2",
             "COPYING.GPLv3",
diff --git a/gstreamer/ext/gstreamer/extconf.rb b/gstreamer/ext/gstreamer/extconf.rb
index a55726d..81fa7f6 100644
--- a/gstreamer/ext/gstreamer/extconf.rb
+++ b/gstreamer/ext/gstreamer/extconf.rb
@@ -44,6 +44,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "gstreamer1.0-devel",
                                    :debian => "libgstreamer1.0-dev",
                                    :redhat => "gstreamer1-devel",
                                    :arch => "gstreamer",
diff --git a/gstreamer/patches/gst-plugins-bad-1.5.2-remove-introspection-compiler-dependency.diff b/gstreamer/patches/gst-plugins-bad-1.5.2-remove-introspection-compiler-dependency.diff
deleted file mode 100644
index a73d54d..0000000
--- a/gstreamer/patches/gst-plugins-bad-1.5.2-remove-introspection-compiler-dependency.diff
+++ /dev/null
@@ -1,36 +0,0 @@
-diff -ru gst-plugins-bad-1.5.2.orig/gst-libs/gst/gl/Makefile.am gst-plugins-bad-1.5.2/gst-libs/gst/gl/Makefile.am
---- gst-plugins-bad-1.5.2.orig/gst-libs/gst/gl/Makefile.am	2015-06-22 17:19:18.000000000 +0900
-+++ gst-plugins-bad-1.5.2/gst-libs/gst/gl/Makefile.am	2015-09-21 15:14:55.847844366 +0900
-@@ -165,7 +165,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-bad-1.5.2.orig/gst-libs/gst/insertbin/Makefile.am gst-plugins-bad-1.5.2/gst-libs/gst/insertbin/Makefile.am
---- gst-plugins-bad-1.5.2.orig/gst-libs/gst/insertbin/Makefile.am	2015-04-27 16:59:55.000000000 +0900
-+++ gst-plugins-bad-1.5.2/gst-libs/gst/insertbin/Makefile.am	2015-09-21 15:14:55.847844366 +0900
-@@ -62,7 +62,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-bad-1.5.2.orig/gst-libs/gst/mpegts/Makefile.am gst-plugins-bad-1.5.2/gst-libs/gst/mpegts/Makefile.am
---- gst-plugins-bad-1.5.2.orig/gst-libs/gst/mpegts/Makefile.am	2015-04-27 16:59:55.000000000 +0900
-+++ gst-plugins-bad-1.5.2/gst-libs/gst/mpegts/Makefile.am	2015-09-21 15:14:55.847844366 +0900
-@@ -97,7 +97,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
diff --git a/gstreamer/patches/gst-plugins-bad-1.5.2-use-portable-cast.diff b/gstreamer/patches/gst-plugins-bad-1.5.2-use-portable-cast.diff
deleted file mode 100644
index 776a4d4..0000000
--- a/gstreamer/patches/gst-plugins-bad-1.5.2-use-portable-cast.diff
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -ru gst-plugins-bad-1.5.2.orig/sys/directsound/gstdirectsoundsrc.c gst-plugins-bad-1.5.2/sys/directsound/gstdirectsoundsrc.c
---- gst-plugins-bad-1.5.2.orig/sys/directsound/gstdirectsoundsrc.c	2015-04-13 15:56:11.000000000 +0900
-+++ gst-plugins-bad-1.5.2/sys/directsound/gstdirectsoundsrc.c	2015-09-09 13:36:58.665602689 +0900
-@@ -730,7 +730,7 @@
-     if (mmres != MMSYSERR_NOERROR)
-       continue;
- 
--    mmres = mixerGetDevCaps ((UINT) dsoundsrc->mixer,
-+    mmres = mixerGetDevCaps (GPOINTER_TO_UINT (dsoundsrc->mixer),
-         mixer_caps, sizeof (MIXERCAPS));
- 
-     if (mmres != MMSYSERR_NOERROR) {
diff --git a/gstreamer/patches/gst-plugins-bad-1.8.0-add-missing-lole32.diff b/gstreamer/patches/gst-plugins-bad-1.8.0-add-missing-lole32.diff
new file mode 100644
index 0000000..a921745
--- /dev/null
+++ b/gstreamer/patches/gst-plugins-bad-1.8.0-add-missing-lole32.diff
@@ -0,0 +1,12 @@
+diff -ru gst-plugins-bad-1.8.0.orig/sys/directsound/Makefile.am gst-plugins-bad-1.8.0/sys/directsound/Makefile.am
+--- gst-plugins-bad-1.8.0.orig/sys/directsound/Makefile.am	2015-04-13 15:56:11.000000000 +0900
++++ gst-plugins-bad-1.8.0/sys/directsound/Makefile.am	2016-04-03 17:42:06.389387506 +0900
+@@ -5,7 +5,7 @@
+ 	$(GST_PLUGINS_BASE_CFLAGS) $(DIRECTX_CFLAGS)
+ libgstdirectsoundsrc_la_LIBADD = \
+ 	$(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
+-	$(DIRECTX_LDFLAGS) $(DIRECTSOUND_LIBS)
++	$(DIRECTX_LDFLAGS) $(DIRECTSOUND_LIBS) -lole32
+ libgstdirectsoundsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+ libgstdirectsoundsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
+ 
diff --git a/gstreamer/patches/gst-plugins-bad-1.5.2-use-only-I.diff b/gstreamer/patches/gst-plugins-bad-1.8.0-use-only-I.diff
similarity index 57%
rename from gstreamer/patches/gst-plugins-bad-1.5.2-use-only-I.diff
rename to gstreamer/patches/gst-plugins-bad-1.8.0-use-only-I.diff
index be4b3bd..64370fc 100644
--- a/gstreamer/patches/gst-plugins-bad-1.5.2-use-only-I.diff
+++ b/gstreamer/patches/gst-plugins-bad-1.8.0-use-only-I.diff
@@ -1,12 +1,12 @@
-diff -ru gst-plugins-bad-1.5.2.orig/gst-libs/gst/gl/Makefile.am gst-plugins-bad-1.5.2/gst-libs/gst/gl/Makefile.am
---- gst-plugins-bad-1.5.2.orig/gst-libs/gst/gl/Makefile.am	2015-06-22 17:19:18.000000000 +0900
-+++ gst-plugins-bad-1.5.2/gst-libs/gst/gl/Makefile.am	2015-09-06 18:43:44.930668366 +0900
-@@ -139,7 +139,7 @@
+diff -ru gst-plugins-bad-1.8.0.orig/gst-libs/gst/gl/Makefile.am gst-plugins-bad-1.8.0/gst-libs/gst/gl/Makefile.am
+--- gst-plugins-bad-1.8.0.orig/gst-libs/gst/gl/Makefile.am	2016-03-12 19:41:42.000000000 +0900
++++ gst-plugins-bad-1.8.0/gst-libs/gst/gl/Makefile.am	2016-04-03 15:59:50.446978896 +0900
+@@ -160,7 +160,7 @@
  		--c-include "gst/gl/gl.h" \
  		-I$(top_srcdir)/gst-libs \
  		-I$(top_builddir)/gst-libs \
 -		$(GST_PLUGINS_BASE_CFLAGS) \
 +		`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --cflags-only-I gstreamer-base- at GST_API_VERSION@` \
+ 		$(GL_CFLAGS) \
  		--add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer- at GST_API_VERSION@` \
  		--add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-base- at GST_API_VERSION@` \
- 		--library=libgstgl- at GST_API_VERSION@.la \
diff --git a/gstreamer/patches/gst-plugins-base-1.5.2-remove-introspection-compiler-dependency.diff b/gstreamer/patches/gst-plugins-base-1.5.2-remove-introspection-compiler-dependency.diff
deleted file mode 100644
index 4d8aba2..0000000
--- a/gstreamer/patches/gst-plugins-base-1.5.2-remove-introspection-compiler-dependency.diff
+++ /dev/null
@@ -1,132 +0,0 @@
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/allocators/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/allocators/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/allocators/Makefile.am	2015-04-27 17:00:36.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/allocators/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -53,7 +53,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/app/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/app/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/app/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/app/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -70,7 +70,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/audio/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/audio/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/audio/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/audio/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -124,7 +124,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/fft/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/fft/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/fft/Makefile.am	2015-04-27 17:00:36.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/fft/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -80,7 +80,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/pbutils/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/pbutils/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/pbutils/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/pbutils/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -114,7 +114,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/riff/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/riff/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/riff/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/riff/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -66,7 +66,7 @@
- #
- #typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- #
--#%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+#%.typelib: %.gir
- #	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- #		$(INTROSPECTION_COMPILER) \
- #		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/rtp/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/rtp/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/rtp/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/rtp/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -82,7 +82,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/rtsp/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/rtsp/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/rtsp/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/rtsp/Makefile.am	2015-09-21 14:56:41.571230796 +0900
-@@ -90,7 +90,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/sdp/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/sdp/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/sdp/Makefile.am	2015-04-27 17:00:36.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/sdp/Makefile.am	2015-09-21 14:56:41.575230697 +0900
-@@ -47,7 +47,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/tag/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/tag/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/tag/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/tag/Makefile.am	2015-09-21 14:56:41.575230697 +0900
-@@ -62,7 +62,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/video/Makefile.am gst-plugins-base-1.5.2/gst-libs/gst/video/Makefile.am
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/video/Makefile.am	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/video/Makefile.am	2015-09-21 14:56:41.575230697 +0900
-@@ -131,7 +131,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
- 		$(INTROSPECTION_COMPILER) \
- 		--includedir=$(srcdir) \
diff --git a/gstreamer/patches/gst-plugins-base-1.5.2-use-portable-64bit-data-print-modifier.diff b/gstreamer/patches/gst-plugins-base-1.5.2-use-portable-64bit-data-print-modifier.diff
deleted file mode 100644
index f3d447f..0000000
--- a/gstreamer/patches/gst-plugins-base-1.5.2-use-portable-64bit-data-print-modifier.diff
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -ru gst-plugins-base-1.5.2.orig/gst-libs/gst/video/video-dither.c gst-plugins-base-1.5.2/gst-libs/gst/video/video-dither.c
---- gst-plugins-base-1.5.2.orig/gst-libs/gst/video/video-dither.c	2015-06-22 17:15:57.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst-libs/gst/video/video-dither.c	2015-09-06 18:10:34.794869331 +0900
-@@ -413,7 +413,7 @@
-   }
-   dither->orc_mask64 = GUINT64_FROM_BE (dither->orc_mask64);
-   dither->orc_mask32 = GUINT32_FROM_BE (dither->orc_mask32);
--  GST_DEBUG ("mask64 %08llx", (unsigned long long int) dither->orc_mask64);
-+  GST_DEBUG ("mask64 %08" G_GINT64_MODIFIER "x", (unsigned long long int) dither->orc_mask64);
-   GST_DEBUG ("mask32 %08x", dither->orc_mask32);
- 
-   switch (method) {
diff --git a/gstreamer/patches/gst-plugins-base-1.5.2-use-portable-cast.diff b/gstreamer/patches/gst-plugins-base-1.5.2-use-portable-cast.diff
deleted file mode 100644
index a88e35c..0000000
--- a/gstreamer/patches/gst-plugins-base-1.5.2-use-portable-cast.diff
+++ /dev/null
@@ -1,21 +0,0 @@
-diff -ru gst-plugins-base-1.5.2.orig/gst/playback/gstplaybin2.c gst-plugins-base-1.5.2/gst/playback/gstplaybin2.c
---- gst-plugins-base-1.5.2.orig/gst/playback/gstplaybin2.c	2015-06-23 22:28:58.000000000 +0900
-+++ gst-plugins-base-1.5.2/gst/playback/gstplaybin2.c	2015-09-09 13:17:22.244128964 +0900
-@@ -3438,7 +3438,7 @@
-             G_CALLBACK (notify_tags_cb), ntdata, (GClosureNotify) g_free,
-             (GConnectFlags) 0);
-         g_object_set_data (G_OBJECT (sinkpad), "playbin.notify_tags_handler",
--            (gpointer) (guintptr) notify_tags_handler);
-+            GUINT_TO_POINTER (notify_tags_handler));
-       }
- 
-       /* store the pad in the array */
-@@ -3473,7 +3473,7 @@
-       gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-       _uridecodebin_event_probe, group, NULL);
-   g_object_set_data (G_OBJECT (pad), "playbin.event_probe_id",
--      (gpointer) group_id_probe_handler);
-+      GUINT_TO_POINTER (group_id_probe_handler));
- 
-   if (changed) {
-     int signal;
diff --git a/gstreamer/patches/gstreamer-1.5.2-remove-introspection-compiler-dependency.diff b/gstreamer/patches/gstreamer-1.5.2-remove-introspection-compiler-dependency.diff
deleted file mode 100644
index 851aabf..0000000
--- a/gstreamer/patches/gstreamer-1.5.2-remove-introspection-compiler-dependency.diff
+++ /dev/null
@@ -1,60 +0,0 @@
-diff -ru gstreamer-1.5.2.orig/gst/Makefile.am gstreamer-1.5.2/gst/Makefile.am
---- gstreamer-1.5.2.orig/gst/Makefile.am	2015-06-22 17:13:25.000000000 +0900
-+++ gstreamer-1.5.2/gst/Makefile.am	2015-09-21 14:56:32.995446061 +0900
-@@ -309,7 +309,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)$(INTROSPECTION_COMPILER) --includedir=$(srcdir) --includedir=$(builddir) $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
- 
- CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
-diff -ru gstreamer-1.5.2.orig/libs/gst/base/Makefile.am gstreamer-1.5.2/libs/gst/base/Makefile.am
---- gstreamer-1.5.2.orig/libs/gst/base/Makefile.am	2015-06-22 17:13:25.000000000 +0900
-+++ gstreamer-1.5.2/libs/gst/base/Makefile.am	2015-09-21 14:56:32.995446061 +0900
-@@ -96,7 +96,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)$(INTROSPECTION_COMPILER) --includedir=$(srcdir) --includedir=$(builddir) --includedir=$(top_builddir)/gst $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
- 
- CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
-diff -ru gstreamer-1.5.2.orig/libs/gst/check/Makefile.am gstreamer-1.5.2/libs/gst/check/Makefile.am
---- gstreamer-1.5.2.orig/libs/gst/check/Makefile.am	2015-06-22 17:13:25.000000000 +0900
-+++ gstreamer-1.5.2/libs/gst/check/Makefile.am	2015-09-21 14:56:32.999445960 +0900
-@@ -171,7 +171,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)$(INTROSPECTION_COMPILER) --includedir=$(srcdir) --includedir=$(builddir) --includedir=$(top_builddir)/gst $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
- 
- CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
-diff -ru gstreamer-1.5.2.orig/libs/gst/controller/Makefile.am gstreamer-1.5.2/libs/gst/controller/Makefile.am
---- gstreamer-1.5.2.orig/libs/gst/controller/Makefile.am	2015-06-22 17:13:25.000000000 +0900
-+++ gstreamer-1.5.2/libs/gst/controller/Makefile.am	2015-09-21 14:56:32.999445960 +0900
-@@ -68,7 +68,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)$(INTROSPECTION_COMPILER) --includedir=$(srcdir) --includedir=$(builddir) --includedir=$(top_builddir)/gst $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
- 
- CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
-diff -ru gstreamer-1.5.2.orig/libs/gst/net/Makefile.am gstreamer-1.5.2/libs/gst/net/Makefile.am
---- gstreamer-1.5.2.orig/libs/gst/net/Makefile.am	2015-06-22 17:13:25.000000000 +0900
-+++ gstreamer-1.5.2/libs/gst/net/Makefile.am	2015-09-21 14:56:32.999445960 +0900
-@@ -89,7 +89,7 @@
- 
- typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
- 
--%.typelib: %.gir $(INTROSPECTION_COMPILER)
-+%.typelib: %.gir
- 	$(AM_V_GEN)$(INTROSPECTION_COMPILER) --includedir=$(srcdir) --includedir=$(builddir) --includedir=$(top_builddir)/gst $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
- 
- CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
diff --git a/gstreamer/sample/stream-status.rb b/gstreamer/sample/stream-status.rb
index b20579c..6c2f083 100755
--- a/gstreamer/sample/stream-status.rb
+++ b/gstreamer/sample/stream-status.rb
@@ -73,13 +73,13 @@ bin.bus.sync_handler do |bus, message|
 
     val = message.stream_status_object
 
-    puts "type:   #{type}"
+    puts "type:   #{type.inspect}"
     puts "source: #{message.src.path_string}"
     puts "owner:  #{owner.path_string}"
     puts "object: type #{val.type.name}, value #{val.value}"
 
     # see if we know how to deal with this object
-    if val.type == Gst::Task
+    if val.type == Gst::Task.gtype
       task = val.value
     end
 
diff --git a/gtk2/Rakefile b/gtk2/Rakefile
index c850797..35cec8e 100644
--- a/gtk2/Rakefile
+++ b/gtk2/Rakefile
@@ -33,7 +33,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gtk+",
       :download_site => :gnome,
       :label => "gtk+",
-      :version => "2.24.28",
+      :version => "2.24.30",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -49,7 +49,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "hicolor-icon-theme",
-      :download_base_url => "http://icon-theme.freedesktop.org/releases",
+      :download_base_url => "https://icon-theme.freedesktop.org/releases",
       :label => "gtk-hi-color-icon-theme",
       :version => "0.15",
       :compression_method => "xz",
diff --git a/gtk2/ext/gtk2/extconf.rb b/gtk2/ext/gtk2/extconf.rb
index 9eb3405..9c70c33 100644
--- a/gtk2/ext/gtk2/extconf.rb
+++ b/gtk2/ext/gtk2/extconf.rb
@@ -49,6 +49,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 2, 10, 0],
+                                   :altlinux => "libgtk+2-devel",
                                    :debian => "libgtk2.0-dev",
                                    :redhat => "gtk2-devel",
                                    :arch => "gtk2",
diff --git a/gtk2/sample/misc/threads.rb b/gtk2/sample/misc/threads.rb
index 3e01425..4f66c96 100644
--- a/gtk2/sample/misc/threads.rb
+++ b/gtk2/sample/misc/threads.rb
@@ -9,7 +9,6 @@
 =end
 
 require 'gtk2'
-require 'thread'
 
 label = Gtk::Label.new
 
diff --git a/gtk3-no-gi/ext/gtk3/extconf.rb b/gtk3-no-gi/ext/gtk3/extconf.rb
index 1ddea26..27757dd 100644
--- a/gtk3-no-gi/ext/gtk3/extconf.rb
+++ b/gtk3-no-gi/ext/gtk3/extconf.rb
@@ -50,6 +50,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libgtk+3-devel",
                                    :debian => "libgtk-3-dev",
                                    :fedora => "gtk3-devel",
                                    :homebrew => "gtk+3",
diff --git a/gtk3/ext/gtk3/extconf.rb b/gtk3/ext/gtk3/extconf.rb
index 12b74a2..d444333 100755
--- a/gtk3/ext/gtk3/extconf.rb
+++ b/gtk3/ext/gtk3/extconf.rb
@@ -64,6 +64,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libgtk+3-devel",
                                    :debian => "libgtk-3-dev",
                                    :redhat => "gtk3-devel",
                                    :arch => "gtk3",
diff --git a/gtk3/ext/gtk3/rb-gtk3-tree-view.c b/gtk3/ext/gtk3/rb-gtk3-tree-view.c
index 9dd56b4..0ecf7aa 100644
--- a/gtk3/ext/gtk3/rb-gtk3-tree-view.c
+++ b/gtk3/ext/gtk3/rb-gtk3-tree-view.c
@@ -26,6 +26,7 @@ rb_gtk3_tree_view_mark(gpointer object)
     GtkTreeView *tree_view = object;
     GList *node;
     GList *columns;
+    GtkTreeSelection *selection;
 
     columns = gtk_tree_view_get_columns(tree_view);
     for (node = columns; node; node = g_list_next(node)) {
@@ -33,6 +34,9 @@ rb_gtk3_tree_view_mark(gpointer object)
         rbgobj_gc_mark_instance(column);
     }
     g_list_free(columns);
+
+    selection = gtk_tree_view_get_selection(tree_view);
+    rbgobj_gc_mark_instance(selection);
 }
 
 void
diff --git a/gtk3/ext/gtk3/rb-gtk3.c b/gtk3/ext/gtk3/rb-gtk3.c
index f7d90d1..ddb2fb9 100644
--- a/gtk3/ext/gtk3/rb-gtk3.c
+++ b/gtk3/ext/gtk3/rb-gtk3.c
@@ -20,6 +20,9 @@
 
 #include "rb-gtk3-private.h"
 
+static ID id_call;
+static VALUE cGdkAtom;
+
 /*
 #if GTK_CHECK_VERSION(3, 10, 0)
 #    define RB_GTK_ACTION_IS_DEPRECATED
@@ -53,51 +56,11 @@ static void
 rb_gtk3_callback_callback(GtkWidget *widget, gpointer user_data)
 {
     RBGICallbackData *callback_data = user_data;
-    ID id_call;
 
-    CONST_ID(id_call, "call");
     rb_funcall(callback_data->rb_callback, id_call, 1,
                GOBJ2RVAL(widget));
 }
 
-static gint
-rb_gtk3_assistant_page_func_callback(gint current_page, gpointer user_data)
-{
-    RBGICallbackData *callback_data = user_data;
-    ID id_call;
-    VALUE rb_next_page;
-
-    CONST_ID(id_call, "call");
-    rb_next_page = rb_funcall(callback_data->rb_callback, id_call, 1,
-                              INT2NUM(current_page));
-    return NUM2INT(rb_next_page);
-}
-
-static void
-rb_gtk3_builder_connect_func_callback(GtkBuilder *builder,
-                                      GObject *object,
-                                      const gchar *signal_name,
-                                      const gchar *handler_name,
-                                      GObject *connect_object,
-                                      GConnectFlags flags,
-                                      gpointer user_data)
-{
-    RBGICallbackData *callback_data = user_data;
-    ID id___connect_signals__;
-    VALUE rb_object;
-
-    CONST_ID(id___connect_signals__, "__connect_signals__");
-    rb_object = GOBJ2RVAL(object);
-    G_RELATIVE(rb_object, callback_data->rb_callback);
-    rb_funcall(GOBJ2RVAL(builder), id___connect_signals__, 6,
-               callback_data->rb_callback,
-               rb_object,
-               CSTR2RVAL(signal_name),
-               CSTR2RVAL(handler_name),
-               GOBJ2RVAL(connect_object),
-               GCONNECTFLAGS2RVAL(flags));
-}
-
 static void
 rb_gtk3_cell_layout_data_func_callback(GtkCellLayout *cell_layout,
                                        GtkCellRenderer *cell,
@@ -107,7 +70,6 @@ rb_gtk3_cell_layout_data_func_callback(GtkCellLayout *cell_layout,
 {
     RBGICallbackData *callback_data = user_data;
     ID id_set_model;
-    ID id_call;
     VALUE rb_model;
     VALUE rb_iter;
 
@@ -116,7 +78,6 @@ rb_gtk3_cell_layout_data_func_callback(GtkCellLayout *cell_layout,
     rb_iter = BOXED2RVAL(iter, GTK_TYPE_TREE_ITER);
     rb_funcall(rb_iter, id_set_model, 1, rb_model);
 
-    CONST_ID(id_call, "call");
     rb_funcall(callback_data->rb_callback,
                id_call,
                4,
@@ -126,15 +87,179 @@ rb_gtk3_cell_layout_data_func_callback(GtkCellLayout *cell_layout,
                rb_iter);
 }
 
+static void
+rb_gtk3_clipboard_received_func_callback(GtkClipboard *clipboard,
+                                         GtkSelectionData *selection_data,
+                                         gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+
+    rb_funcall(callback_data->rb_callback,
+               id_call,
+               2,
+               GOBJ2RVAL(clipboard),
+               BOXED2RVAL(selection_data, GTK_TYPE_SELECTION_DATA));
+}
+
+static void
+rb_gtk3_clipboard_rich_text_received_func_callback(GtkClipboard *clipboard,
+                                                   GdkAtom format,
+                                                   const guint *text,
+                                                   G_GNUC_UNUSED gsize length,
+                                                   gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+
+    rb_funcall(callback_data->rb_callback,
+               id_call,
+               3,
+               GOBJ2RVAL(clipboard),
+               Data_Wrap_Struct(cGdkAtom, NULL, NULL, format),
+               CSTR2RVAL((const gchar *)text));
+}
+
+static void
+rb_gtk3_clipboard_image_received_func_callback(GtkClipboard *clipboard,
+                                               GdkPixbuf *pixbuf,
+                                               gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+
+    rb_funcall(callback_data->rb_callback,
+               id_call,
+               2,
+               GOBJ2RVAL(clipboard),
+               GOBJ2RVAL(pixbuf));
+}
+
+static void
+rb_gtk3_clipboard_targets_received_func_callback(GtkClipboard *clipboard,
+                                                 GdkAtom *atoms,
+                                                 gint n_atoms,
+                                                 gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+    VALUE rb_atoms;
+    gint i;
+
+    if (!atoms) {
+        rb_atoms = Qnil;
+    } else {
+        rb_atoms = rb_ary_new2(n_atoms);
+        for (i = 0; i < n_atoms; i++) {
+            VALUE rb_atom;
+            rb_atom = Data_Wrap_Struct(cGdkAtom, NULL, NULL, atoms[i]);
+            rb_ary_push(rb_atoms, rb_atom);
+        }
+    }
+
+    rb_funcall(callback_data->rb_callback,
+               id_call,
+               2,
+               GOBJ2RVAL(clipboard),
+               rb_atoms);
+}
+
+static void
+rb_gtk3_clipboard_text_received_func_callback(GtkClipboard *clipboard,
+                                              const gchar *text,
+                                              gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+
+    rb_funcall(callback_data->rb_callback,
+               id_call,
+               2,
+               GOBJ2RVAL(clipboard),
+               CSTR2RVAL(text));
+}
+
+static void
+rb_gtk3_clipboard_uri_received_func_callback(GtkClipboard *clipboard,
+                                             gchar **uris,
+                                             gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+
+    rb_funcall(callback_data->rb_callback,
+               id_call,
+               2,
+               GOBJ2RVAL(clipboard),
+               STRV2RVAL((const gchar **)uris));
+}
+
+static gboolean
+rb_gtk3_entry_completion_match_func_callback(GtkEntryCompletion *completion,
+                                             const gchar *key,
+                                             GtkTreeIter *iter,
+                                             gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+    ID id_set_model;
+    VALUE rb_model;
+    VALUE rb_iter;
+    GtkTreeModel *model;
+    VALUE rb_match;
+    gboolean match = FALSE;
+
+    model = gtk_entry_completion_get_model(completion);
+    CONST_ID(id_set_model, "model=");
+    rb_model = GOBJ2RVAL(model);
+    rb_iter = BOXED2RVAL(iter, GTK_TYPE_TREE_ITER);
+    rb_funcall(rb_iter, id_set_model, 1, rb_model);
+
+    rb_match = rb_funcall(callback_data->rb_callback,
+                       id_call,
+                       3,
+                       GOBJ2RVAL(completion),
+                       CSTR2RVAL(key),
+                       rb_iter);
+
+    match = RVAL2CBOOL(rb_match);
+    return match;
+}
+
+static void
+rb_gtk3_menu_position_func_callback(GtkMenu *menu,
+                                    gint *x,
+                                    gint *y,
+                                    gboolean *push_in,
+                                    gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+    VALUE rb_result_raw;
+    VALUE rb_result;
+
+    rb_result_raw = rb_funcall(callback_data->rb_callback,
+                               id_call,
+                               3,
+                               GOBJ2RVAL(menu),
+                               INT2NUM(*x),
+                               INT2NUM(*y));
+    rb_result = rbg_check_array_type(rb_result_raw);
+    if (NIL_P(rb_result) ||
+        !(RARRAY_LEN(rb_result) == 2 ||
+          RARRAY_LEN(rb_result) == 3)) {
+        /* TODO: Raising an error will abort the program. :< */
+        rb_raise(rb_eArgError,
+                 "block should return [x, y, push_in]: %s",
+                 RBG_INSPECT(rb_result_raw));
+    }
+
+    *x = NUM2INT(RARRAY_PTR(rb_result)[0]);
+    *y = NUM2INT(RARRAY_PTR(rb_result)[1]);
+    if (RARRAY_LEN(rb_result) == 3) {
+        *push_in = RVAL2CBOOL(RARRAY_PTR(rb_result)[2]);
+    }
+}
+
 static const gchar *
 rb_gtk3_translate_func_callback(const gchar *path,
                                 gpointer user_data)
 {
     RBGICallbackData *callback_data = user_data;
-    ID id_call;
     VALUE rb_translated;
 
-    CONST_ID(id_call, "call");
     rb_translated = rb_funcall(callback_data->rb_callback,
                                id_call,
                                1,
@@ -151,7 +276,6 @@ rb_gtk3_tree_cell_data_func_callback(GtkTreeViewColumn *column,
 {
     RBGICallbackData *callback_data = user_data;
     ID id_set_model;
-    ID id_call;
     VALUE rb_model;
     VALUE rb_iter;
 
@@ -160,7 +284,6 @@ rb_gtk3_tree_cell_data_func_callback(GtkTreeViewColumn *column,
     rb_iter = BOXED2RVAL(iter, GTK_TYPE_TREE_ITER);
     rb_funcall(rb_iter, id_set_model, 1, rb_model);
 
-    CONST_ID(id_call, "call");
     rb_funcall(callback_data->rb_callback,
                id_call,
                4,
@@ -170,6 +293,37 @@ rb_gtk3_tree_cell_data_func_callback(GtkTreeViewColumn *column,
                rb_iter);
 }
 
+static gint
+rb_gtk3_tree_iter_compare_func_callback(GtkTreeModel *model,
+                                        GtkTreeIter *iter1,
+                                        GtkTreeIter *iter2,
+                                        gpointer user_data)
+{
+    RBGICallbackData *callback_data = user_data;
+    ID id_set_model;
+    VALUE rb_model;
+    VALUE rb_iter1;
+    VALUE rb_iter2;
+    VALUE rb_result;
+
+    CONST_ID(id_set_model, "model=");
+    rb_model = GOBJ2RVAL(model);
+
+    rb_iter1 = BOXED2RVAL(iter1, GTK_TYPE_TREE_ITER);
+    rb_funcall(rb_iter1, id_set_model, 1, rb_model);
+
+    rb_iter2 = BOXED2RVAL(iter2, GTK_TYPE_TREE_ITER);
+    rb_funcall(rb_iter2, id_set_model, 1, rb_model);
+
+    rb_result = rb_funcall(callback_data->rb_callback,
+                           id_call,
+                           3,
+                           rb_model,
+                           rb_iter1,
+                           rb_iter2);
+    return NUM2INT(rb_result);
+}
+
 static void
 rb_gtk3_tree_model_filter_modify_func_callback(GtkTreeModel *model,
                                                GtkTreeIter *iter,
@@ -179,7 +333,6 @@ rb_gtk3_tree_model_filter_modify_func_callback(GtkTreeModel *model,
 {
     RBGICallbackData *callback_data = user_data;
     ID id_set_model;
-    ID id_call;
     VALUE rb_model;
     VALUE rb_iter;
     VALUE rb_value;
@@ -191,7 +344,6 @@ rb_gtk3_tree_model_filter_modify_func_callback(GtkTreeModel *model,
     rb_funcall(rb_iter, id_set_model, 1, rb_model);
     rb_column = INT2NUM(column);
 
-    CONST_ID(id_call, "call");
     rb_value = rb_funcall(callback_data->rb_callback,
                           id_call,
                           3,
@@ -208,7 +360,6 @@ rb_gtk3_tree_model_filter_visible_func_callback(GtkTreeModel *model,
 {
     RBGICallbackData *callback_data = user_data;
     ID id_set_model;
-    ID id_call;
     VALUE rb_model;
     VALUE rb_iter;
     VALUE rb_visible;
@@ -219,7 +370,6 @@ rb_gtk3_tree_model_filter_visible_func_callback(GtkTreeModel *model,
     rb_iter = BOXED2RVAL(iter, GTK_TYPE_TREE_ITER);
     rb_funcall(rb_iter, id_set_model, 1, rb_model);
 
-    CONST_ID(id_call, "call");
     rb_visible = rb_funcall(callback_data->rb_callback,
                             id_call,
                             2,
@@ -238,7 +388,6 @@ rb_gtk3_tree_model_foreach_func_callback(GtkTreeModel *model,
 {
     RBGICallbackData *callback_data = user_data;
     ID id_set_model;
-    ID id_call;
     VALUE rb_model;
     VALUE rb_iter;
     gboolean stop = FALSE;
@@ -248,7 +397,6 @@ rb_gtk3_tree_model_foreach_func_callback(GtkTreeModel *model,
     rb_iter = BOXED2RVAL(iter, GTK_TYPE_TREE_ITER);
     rb_funcall(rb_iter, id_set_model, 1, rb_model);
 
-    CONST_ID(id_call, "call");
     rb_funcall(callback_data->rb_callback,
                id_call,
                3,
@@ -267,7 +415,6 @@ rb_gtk3_tree_selection_foreach_func_callback(GtkTreeModel *model,
 {
     RBGICallbackData *callback_data = user_data;
     ID id_set_model;
-    ID id_call;
     VALUE rb_model;
     VALUE rb_iter;
 
@@ -276,7 +423,6 @@ rb_gtk3_tree_selection_foreach_func_callback(GtkTreeModel *model,
     rb_iter = BOXED2RVAL(iter, GTK_TYPE_TREE_ITER);
     rb_funcall(rb_iter, id_set_model, 1, rb_model);
 
-    CONST_ID(id_call, "call");
     rb_funcall(callback_data->rb_callback,
                id_call,
                3,
@@ -285,15 +431,34 @@ rb_gtk3_tree_selection_foreach_func_callback(GtkTreeModel *model,
                rb_iter);
 }
 
+static gboolean
+rb_gtk3_tree_selection_func_callback(GtkTreeSelection *selection,
+                                     GtkTreeModel *model,
+                                     GtkTreePath *path,
+                                     gboolean path_currently_selected,
+                                     gpointer data)
+{
+    RBGICallbackData *callback_data = data;
+    VALUE rb_selection_is_changeable;
+
+    rb_selection_is_changeable =
+        rb_funcall(callback_data->rb_callback,
+                   id_call,
+                   4,
+                   GOBJ2RVAL(selection),
+                   GOBJ2RVAL(model),
+                   BOXED2RVAL(path, GTK_TYPE_TREE_PATH),
+                   CBOOL2RVAL(path_currently_selected));
+    return RVAL2CBOOL(rb_selection_is_changeable);
+}
+
 static void
 rb_gtk3_tree_view_mapping_func_callback(GtkTreeView *tree_view,
                                         GtkTreePath *path,
                                         gpointer user_data)
 {
     RBGICallbackData *callback_data = user_data;
-    ID id_call;
 
-    CONST_ID(id_call, "call");
     rb_funcall(callback_data->rb_callback,
                id_call,
                2,
@@ -306,16 +471,30 @@ rb_gtk3_callback_finder(GIArgInfo *info)
 {
     if (name_equal(info, "Callback")) {
         return rb_gtk3_callback_callback;
-    } else if (name_equal(info, "AssistantPageFunc")) {
-        return rb_gtk3_assistant_page_func_callback;
-    } else if (name_equal(info, "BuilderConnectFunc")) {
-        return rb_gtk3_builder_connect_func_callback;
     } else if (name_equal(info, "CellLayoutDataFunc")) {
         return rb_gtk3_cell_layout_data_func_callback;
+    } else if (name_equal(info, "ClipboardReceivedFunc")) {
+        return rb_gtk3_clipboard_received_func_callback;
+    } else if (name_equal(info, "ClipboardRichTextReceivedFunc")) {
+        return rb_gtk3_clipboard_rich_text_received_func_callback;
+    } else if (name_equal(info, "ClipboardImageReceivedFunc")) {
+        return rb_gtk3_clipboard_image_received_func_callback;
+    } else if (name_equal(info, "ClipboardTargetsReceivedFunc")) {
+        return rb_gtk3_clipboard_targets_received_func_callback;
+    } else if (name_equal(info, "ClipboardTextReceivedFunc")) {
+        return rb_gtk3_clipboard_text_received_func_callback;
+    } else if (name_equal(info, "ClipboardURIReceivedFunc")) {
+        return rb_gtk3_clipboard_uri_received_func_callback;
+    } else if (name_equal(info, "EntryCompletionMatchFunc")) {
+        return rb_gtk3_entry_completion_match_func_callback;
+    } else if (name_equal(info, "MenuPositionFunc")) {
+        return rb_gtk3_menu_position_func_callback;
     } else if (name_equal(info, "TranslateFunc")) {
         return rb_gtk3_translate_func_callback;
     } else if (name_equal(info, "TreeCellDataFunc")) {
         return rb_gtk3_tree_cell_data_func_callback;
+    } else if (name_equal(info, "TreeIterCompareFunc")) {
+        return rb_gtk3_tree_iter_compare_func_callback;
     } else if (name_equal(info, "TreeModelFilterModifyFunc")) {
         return rb_gtk3_tree_model_filter_modify_func_callback;
     } else if (name_equal(info, "TreeModelFilterVisibleFunc")) {
@@ -324,6 +503,8 @@ rb_gtk3_callback_finder(GIArgInfo *info)
         return rb_gtk3_tree_model_foreach_func_callback;
     } else if (name_equal(info, "TreeSelectionForeachFunc")) {
         return rb_gtk3_tree_selection_foreach_func_callback;
+    } else if (name_equal(info, "TreeSelectionFunc")) {
+        return rb_gtk3_tree_selection_func_callback;
     } else if (name_equal(info, "TreeViewMappingFunc")) {
         return rb_gtk3_tree_view_mapping_func_callback;
     } else {
@@ -417,6 +598,10 @@ rbgtk3_initialize(VALUE self)
 void
 Init_gtk3(void)
 {
+    id_call = rb_intern("call");
+    cGdkAtom = rb_const_get(rb_const_get(rb_cObject, rb_intern("Gdk")),
+                            rb_intern("Atom"));
+
     rb_gi_callback_register_finder(rb_gtk3_callback_finder);
 
 #ifndef RB_GTK_ACTION_IS_DEPRECATED
diff --git a/gtk3/lib/gtk3/box.rb b/gtk3/lib/gtk3/box.rb
index 7610c92..1db48b3 100644
--- a/gtk3/lib/gtk3/box.rb
+++ b/gtk3/lib/gtk3/box.rb
@@ -36,5 +36,27 @@ module Gtk
       padding = options[:padding] || 0
       pack_end_raw(child, expand, fill, padding)
     end
+
+    alias_method :set_child_packing_raw, :set_child_packing
+    def set_child_packing(child, options={})
+      expand    = options[:expand]
+      fill      = options[:fill]
+      padding   = options[:padding]
+      pack_type = options[:pack_type]
+
+      old_expand, old_fill, old_padding, old_pack_type =
+        query_child_packing(child)
+
+      expand    = old_expand    if expand.nil?
+      fill      = old_fill      if fill.nil?
+      padding   = old_padding   if padding.nil?
+      pack_type = old_pack_type if pack_type.nil?
+
+      set_child_packing_raw(child,
+                            expand,
+                            fill,
+                            padding,
+                            pack_type)
+    end
   end
 end
diff --git a/gtk3/lib/gtk3/builder.rb b/gtk3/lib/gtk3/builder.rb
index 62c42ee..fd6ada9 100644
--- a/gtk3/lib/gtk3/builder.rb
+++ b/gtk3/lib/gtk3/builder.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,51 @@
 
 module Gtk
   class Builder
+    class << self
+      def connect_signal(builder,
+                         object,
+                         signal_name,
+                         handler_name,
+                         connect_object,
+                         flags,
+                         &block)
+        handler_name = normalize_handler_name(handler_name)
+        if connect_object
+          handler = connect_object.method(handler_name)
+        else
+          handler = block.call(handler_name)
+        end
+
+        unless handler
+          $stderr.puts("Undefined handler: #{handler_name}") if $DEBUG
+          return
+        end
+
+        if flags.is_a?(Integer)
+          flags = GLib::ConnectFlags.new(flags)
+        end
+
+        if flags.after?
+          signal_connect_method = :signal_connect_after
+        else
+          signal_connect_method = :signal_connect
+        end
+
+        if handler.arity.zero?
+          object.__send__(signal_connect_method, signal_name) do
+            handler.call
+          end
+        else
+          object.__send__(signal_connect_method, signal_name, &handler)
+        end
+      end
+
+      private
+      def normalize_handler_name(name)
+        name.gsub(/[-\s]+/, "_")
+      end
+    end
+
     alias_method :initialize_raw, :initialize
     def initialize(options={})
       path      = options[:path] || options[:file]
@@ -100,34 +145,10 @@ module Gtk
       self
     end
 
-    private
-    def normalize_handler_name(name)
-      name.gsub(/[-\s]+/, "_")
-    end
-
-    def __connect_signals__(connector, object, signal_name,
-                            handler_name, connect_object, flags)
-      handler_name = normalize_handler_name(handler_name)
-      if connect_object
-        handler = connect_object.method(handler_name)
-      else
-        handler = connector.call(handler_name)
-      end
-      unless handler
-        $stderr.puts("Undefined handler: #{handler_name}") if $DEBUG
-        return
-      end
-
-      if flags.after?
-        signal_connect_method = :signal_connect_after
-      else
-        signal_connect_method = :signal_connect
-      end
-
-      if handler.arity.zero?
-        object.send(signal_connect_method, signal_name) {handler.call}
-      else
-        object.send(signal_connect_method, signal_name, &handler)
+    alias_method :connect_signals_raw, :connect_signals
+    def connect_signals(&block)
+      connect_signals_raw do |*args|
+        self.class.connect_signal(*args, &block)
       end
     end
   end
diff --git a/gtk3/lib/gtk3/deprecated.rb b/gtk3/lib/gtk3/deprecated.rb
index dfcb6ab..4ad295b 100644
--- a/gtk3/lib/gtk3/deprecated.rb
+++ b/gtk3/lib/gtk3/deprecated.rb
@@ -569,6 +569,13 @@ module Gtk
 
   class MenuItem
     extend GLib::Deprecatable
+
+    define_deprecated_method_by_hash_args :initialize,
+        "label, use_underline=false",
+        ":label => label, :use_underline => use_underline" do |_self, label, use_underline|
+      [{:label => label, :use_underline => use_underline}]
+    end
+
     define_deprecated_method :remove_submenu, :warn => "Use '#{self}#set_submenu'." do |_self|
       _self.set_submenu(nil)
     end
diff --git a/gtk3/lib/gtk3/menu-item.rb b/gtk3/lib/gtk3/entry-buffer.rb
similarity index 79%
copy from gtk3/lib/gtk3/menu-item.rb
copy to gtk3/lib/gtk3/entry-buffer.rb
index 2301b27..027f3d9 100644
--- a/gtk3/lib/gtk3/menu-item.rb
+++ b/gtk3/lib/gtk3/entry-buffer.rb
@@ -15,18 +15,13 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 module Gtk
-  class MenuItem
+  class EntryBuffer
     alias_method :initialize_raw, :initialize
-    def initialize(*args)
-      if args.size == 1
-        label = args.first
-        if label.nil?
-          initialize_raw
-        else
-          initialize_raw(label)
-        end
+    def initialize(text=nil)
+      if text.nil?
+        initialize_raw(nil, -1)
       else
-        initialize_raw(*args)
+        initialize_raw(text, text.size)
       end
     end
   end
diff --git a/gtk3/lib/gtk3/list-store.rb b/gtk3/lib/gtk3/list-store.rb
index 86e19bf..5fada19 100644
--- a/gtk3/lib/gtk3/list-store.rb
+++ b/gtk3/lib/gtk3/list-store.rb
@@ -24,25 +24,6 @@ module Gtk
       initialize_raw(columns)
     end
 
-    def set_values(iter, values)
-      columns = []
-      _values = []
-      if values.is_a?(Hash)
-        values.each do |column_id, value|
-          type = get_column_type(column_id)
-          columns << column_id
-          _values << GLib::Value.new(type, value)
-        end
-      else
-        values.each_with_index do |value, i|
-          type = get_column_type(i)
-          columns << i
-          _values << GLib::Value.new(type, value)
-        end
-      end
-      set(iter, columns, _values)
-    end
-
     alias_method :append_raw, :append
     def append
       iter = append_raw
@@ -58,9 +39,10 @@ module Gtk
     end
 
     alias_method :insert_raw, :insert
-    def insert(index)
+    def insert(index, values=nil)
       iter = insert_raw(index)
       setup_iter(iter)
+      set_values(iter, values) if values
       iter
     end
 
diff --git a/gtk3/lib/gtk3/loader.rb b/gtk3/lib/gtk3/loader.rb
index 9e9bfa8..0d64819 100644
--- a/gtk3/lib/gtk3/loader.rb
+++ b/gtk3/lib/gtk3/loader.rb
@@ -107,6 +107,7 @@ module Gtk
       require "gtk3/container"
       require "gtk3/css-provider"
       require "gtk3/dialog"
+      require "gtk3/entry-buffer"
       require "gtk3/file-chooser-dialog"
       require "gtk3/font-chooser-dialog"
       require "gtk3/gesture-multi-press"
@@ -337,6 +338,11 @@ module Gtk
           # Ignore deprecated methods
           return
         end
+      when "Gtk::TreePath"
+        case method_name
+        when "next", "prev", "up", "down"
+          method_name += "!"
+        end
       when "Gtk::TreeSelection"
         case method_name
         when "selected_foreach"
diff --git a/gtk3/lib/gtk3/menu-item.rb b/gtk3/lib/gtk3/menu-item.rb
index 2301b27..ea2f1b5 100644
--- a/gtk3/lib/gtk3/menu-item.rb
+++ b/gtk3/lib/gtk3/menu-item.rb
@@ -17,16 +17,17 @@
 module Gtk
   class MenuItem
     alias_method :initialize_raw, :initialize
-    def initialize(*args)
-      if args.size == 1
-        label = args.first
-        if label.nil?
-          initialize_raw
+    def initialize(options={})
+      label = options[:label]
+
+      if label
+        if options[:use_underline]
+          initialize_new_with_mnemonic(label)
         else
-          initialize_raw(label)
+          initialize_new_with_label(label)
         end
       else
-        initialize_raw(*args)
+        initialize_raw
       end
     end
   end
diff --git a/gtk3/lib/gtk3/tree-iter.rb b/gtk3/lib/gtk3/tree-iter.rb
index e729b91..d269b2c 100644
--- a/gtk3/lib/gtk3/tree-iter.rb
+++ b/gtk3/lib/gtk3/tree-iter.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2014-2016 Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -45,6 +45,10 @@ module Gtk
       @model.get_path(self)
     end
 
+    def previous!
+      @model.iter_previous(self)
+    end
+
     def next!
       @model.iter_next(self)
     end
@@ -53,6 +57,26 @@ module Gtk
       @model.iter_parent(self)
     end
 
+    def has_child?
+      @model.iter_has_child(self)
+    end
+
+    def n_children
+      @model.iter_n_children(self)
+    end
+
+    def nth_child(n)
+      @model.iter_nth_child(self, n)
+    end
+
+    def children
+      @model.iter_children(self)
+    end
+
+    def first_child
+      nth_child(0)
+    end
+
     def ==(other)
       other.is_a?(self.class) and
         @model == other.model and
diff --git a/gtk3/lib/gtk3/tree-model.rb b/gtk3/lib/gtk3/tree-model.rb
index 6919249..78a4d85 100644
--- a/gtk3/lib/gtk3/tree-model.rb
+++ b/gtk3/lib/gtk3/tree-model.rb
@@ -59,6 +59,47 @@ module Gtk
       get_value_raw(iter, column).value
     end
 
+    alias_method :iter_nth_child_raw, :iter_nth_child
+    def iter_nth_child(iter, n)
+      got, iter = iter_nth_child_raw(iter, n)
+      if got
+        setup_iter(iter)
+        iter
+      else
+        nil
+      end
+    end
+
+    alias_method :iter_children_raw, :iter_children
+    def iter_children(iter)
+      got, iter = iter_children_raw(iter)
+      if got
+        setup_iter(iter)
+        iter
+      else
+        nil
+      end
+    end
+
+    def set_values(iter, values)
+      columns = []
+      _values = []
+      if values.is_a?(Hash)
+        values.each do |column_id, value|
+          type = get_column_type(column_id)
+          columns << column_id
+          _values << GLib::Value.new(type, value)
+        end
+      else
+        values.each_with_index do |value, i|
+          type = get_column_type(i)
+          columns << i
+          _values << GLib::Value.new(type, value)
+        end
+      end
+      set(iter, columns, _values)
+    end
+
     private
     def setup_iter(iter)
       iter.model = self
diff --git a/gtk3/lib/gtk3/tree-store.rb b/gtk3/lib/gtk3/tree-store.rb
index 211ee93..9b5e1c4 100644
--- a/gtk3/lib/gtk3/tree-store.rb
+++ b/gtk3/lib/gtk3/tree-store.rb
@@ -22,37 +22,38 @@ module Gtk
     end
 
     alias_method :insert_raw, :insert
-    def insert(parent, position)
+    def insert(parent, position, values=nil)
       iter = insert_raw(parent, position)
-      iter.model = self
+      setup_iter(iter)
+      set_values(iter, values) if values
       iter
     end
 
     alias_method :insert_before_raw, :insert_before
     def insert_before(parent, sibling)
       iter = insert_before_raw(parent, sibling)
-      iter.model = self
+      setup_iter(iter)
       iter
     end
 
     alias_method :insert_after_raw, :insert_after
     def insert_after(parent, sibling)
       iter = insert_after_raw(parent, sibling)
-      iter.model = self
+      setup_iter(iter)
       iter
     end
 
     alias_method :prepend_raw, :prepend
     def prepend(parent)
       iter = prepend_raw(parent)
-      iter.model = self
+      setup_iter(iter)
       iter
     end
 
     alias_method :append_raw, :append
     def append(parent)
       iter = append_raw(parent)
-      iter.model = self
+      setup_iter(iter)
       iter
     end
   end
diff --git a/gtk3/lib/gtk3/widget.rb b/gtk3/lib/gtk3/widget.rb
index 1529f52..d23a03e 100644
--- a/gtk3/lib/gtk3/widget.rb
+++ b/gtk3/lib/gtk3/widget.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -54,6 +54,13 @@ module Gtk
       def style_properties
         style_properties_raw[0]
       end
+
+      alias_method :set_connect_func_raw, :set_connect_func
+      def set_connect_func(&block)
+        set_connect_func_raw do |*args|
+          Builder.connect_signal(*args, &block)
+        end
+      end
     end
 
     alias_method :events_raw, :events
@@ -106,6 +113,16 @@ module Gtk
       render_icon_pixbuf_raw(stock_id, size)
     end
 
+    alias_method :translate_coordinates_raw, :translate_coordinates
+    def translate_coordinates(widget, x, y)
+      translated, x, y = translate_coordinates_raw(widget, x, y)
+      if translated
+        [x, y]
+      else
+        nil
+      end
+    end
+
     private
     def initialize_post
       klass = self.class
diff --git a/gtk3/sample/gtk-demo/TODO b/gtk3/sample/gtk-demo/TODO
index 27af42c..3b13529 100644
--- a/gtk3/sample/gtk-demo/TODO
+++ b/gtk3/sample/gtk-demo/TODO
@@ -1,69 +1,75 @@
-# C version (3.18.0) versus Ruby version
+# C version (3.19.1) versus Ruby version
 
 C version             Ruby version    Updated
 application.c           no              no
-assistant.c             no              no
-builder.c               ok              no
+assistant.c             ok              ok
+builder.c               ok              ok
 button_box.c            ok              ok
 changedisplay.c         ok              no
 clipboard.c             ok              no
-colorsel.c              ok              no
+colorsel.c              ok              ok
 combobox.c              no              no
-css_accordion.c         ok              no
-css_basics.c            ok              no
-css_multiplebgs.c       no              no
-css_pixbufs.c           no              no
-css_shadows.c           no              no
-cursors.c               no              no
-dialog.c                ok              no
+css_accordion.c         ok              ok
+css_basics.c            ok              ok
+css_multiplebgs.c       ok              ok
+css_pixbufs.c           ok              ok
+css_shadows.c           ok              ok
+cursors.c               ok              ok
+dialog.c                ok              ok
 drawingarea.c           ok              no
 editable_cells.c        ok              no
-entry_buffer.c          no              no
-entry_completion.c      ok              no
+entry_buffer.c          ok              ok
+entry_completion.c      ok              ok
 event_axes.c            no              no
-expander.c              ok              no
-filtermodel.c           no              no
-font_features.c         no              no
+expander.c              ok              ok
+filtermodel.c           ok              ok
+flowbox.c               no              no
+font_features.c         ok              ok
 gestures.c              no              no
 glarea.c                no              no
-headerbar.c             no              no
+headerbar.c             ok              ok
 hypertext.c             ok              no
 iconview.c              ok              no
-iconview_edit.c         no              no
+iconview_edit.c         ok              ok
 images.c                ok              no
-infobar.c               ok              no
-links.c                 ok              no
+infobar.c               ok              ok
+links.c                 ok              ok
 listbox.c               no              no
-flowbox.c               no              no
 list_store.c            ok              no
-markup.c                no              no
-menus.c                 ok              no
+markup.c                ok              ok
+menus.c                 ok              ok
+modelbutton.c           ok              ok
 offscreen_window.c      no              no
 offscreen_window2.c     no              no
-overlay.c               no              no
-overlay2.c              no              no
-panes.c                 ok              no
-pickers.c               no              no
+overlay.c               ok              ok
+overlay2.c              ok              ok
+panes.c                 ok              ok
+pickers.c               ok              ok
 pixbufs.c               ok              no
-popover.c               no              no
-printing.c              ok              no
-revealer.c              no              no
+popover.c               ok              ok
+printing.c              ok              ok
+revealer.c              ok              ok
 rotated_text.c          ok              no
-scale.c                 no              no
+scale.c                 ok              ok
 search_entry.c          no              no
-search_entry2.c         no              no
-sidebar.c               no              no
-sizegroup.c             ok              no
+search_entry2.c         ok              ok
+shortcuts.c             no              no
+sidebar.c               ok              ok
+sizegroup.c             ok              ok
 spinbutton.c            no              no
-spinner.c               ok              no
-stack.c                 no              no
-textmask.c              no              no
-textview.c              ok              no
+spinner.c               ok              ok
+stack.c                 ok              ok
+textmask.c              ok              ok
 textscroll.c            no              no
-theming_style_classes.c ok              no
+textview.c              ok              no
+theming_style_classes.c ok              ok
 toolpalette.c           no              no
 transparent.c           no              no
 tree_store.c            ok              no
 
 # Ruby version
 Check all the ruby demos that doesn't correspond to a C version.
+
+# Demo that are not to be done
+pagesetup.c
+
diff --git a/gtk3/sample/gtk-demo/assistant.rb b/gtk3/sample/gtk-demo/assistant.rb
new file mode 100644
index 0000000..5ec588e
--- /dev/null
+++ b/gtk3/sample/gtk-demo/assistant.rb
@@ -0,0 +1,123 @@
+# Copyright (c) 2016 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Assistant
+
+ Demonstrates a sample multi-step assistant. Assistants are used to divide
+ an operation into several simpler sequential steps, and to guide the user
+ through these steps.
+=end
+module AssistantDemo
+  def self.run_demo(main_window)
+    assistant = Gtk::Assistant.new
+    assistant.screen = main_window.screen
+
+    create_page1(assistant)
+    create_page2(assistant)
+    create_page3(assistant)
+    progress_bar = create_page4(assistant)
+
+    assistant.signal_connect("cancel", &:destroy)
+
+    assistant.signal_connect("close", &:destroy)
+
+    assistant.signal_connect "apply" do |widget|
+      GLib::Timeout.add(100) do
+        fraction = progress_bar.fraction + 0.05
+        if fraction < 1.0
+          progress_bar.fraction = fraction
+        else
+          widget.destroy
+          GLib::Source::REMOVE
+        end
+      end
+    end
+
+    assistant.signal_connect "prepare" do |widget, _page|
+      current_page = widget.current_page
+      n_pages = widget.n_pages
+
+      widget.title = "Sample assistant (#{current_page + 1} of #{n_pages}"
+
+      widget.commit if current_page == 3
+    end
+
+    if !assistant.visible?
+      assistant.show_all
+    else
+      assistant.destroy
+    end
+    assistant
+  end
+
+  def self.create_page1(assistant)
+    box = Gtk::Box.new(:horizontal, 12)
+    box.border_width = 12
+
+    label = Gtk::Label.new("You must fill out this entry to continue")
+    box.pack_start(label, :expand => true, :fill => true, :padding => 0)
+
+    entry = Gtk::Entry.new
+    entry.activates_default = true
+    box.pack_start(entry, :expand => true, :fill => true, :padding => 0)
+
+    entry.signal_connect "changed" do |widget|
+      page_number = assistant.current_page
+      current_page = assistant.get_nth_page(page_number)
+
+      if widget.text
+        assistant.set_page_complete(current_page, true)
+      else
+        assistant.set_page_complete(current_page, false)
+      end
+    end
+
+    box.show_all
+    assistant.append_page(box)
+    assistant.set_page_title(box, "Page 1")
+    assistant.set_page_type(box, :intro)
+  end
+
+  def self.create_page2(assistant)
+    box = Gtk::Box.new(:horizontal, 12)
+    box.border_width = 12
+
+    checkbutton = Gtk::CheckButton.new(<<-LABEL)
+This is optional data, you may continue
+even if you do not check this
+LABEL
+    box.pack_start(checkbutton, :expand => false, :fill => false, :padding => 0)
+
+    box.show_all
+    assistant.append_page(box)
+    assistant.set_page_complete(box, true)
+    assistant.set_page_title(box, "Page 1")
+  end
+
+  def self.create_page3(assistant)
+    label = Gtk::Label.new("This is a confirmation page, press 'Apply' to apply changes")
+    label.show
+
+    assistant.append_page(label)
+    assistant.set_page_type(label, :confirm)
+    assistant.set_page_complete(label, true)
+    assistant.set_page_title(label, "Confirmation")
+  end
+
+  def self.create_page4(assistant)
+    progress_bar = Gtk::ProgressBar.new
+    progress_bar.halign = :center
+    progress_bar.valign = :center
+
+    progress_bar.show
+    assistant.append_page(progress_bar)
+    assistant.set_page_type(progress_bar, :progress)
+    assistant.set_page_title(progress_bar, "Applying changes")
+
+    # This prevents the assistant window from being
+    # closed while we're "busy" applying changes.
+    assistant.set_page_complete(progress_bar, false)
+    progress_bar
+  end
+end
diff --git a/gtk3/sample/gtk-demo/builder.rb b/gtk3/sample/gtk-demo/builder.rb
index c849c2c..c6a2594 100644
--- a/gtk3/sample/gtk-demo/builder.rb
+++ b/gtk3/sample/gtk-demo/builder.rb
@@ -1,51 +1,88 @@
-# Copyright (c) 2008-2015 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
 =begin
-= Interface Builder
+=  Builder
 
-Demonstrates an interface loaded from a XML description.
+ Demonstrates an interface loaded from a XML description.
 =end
+module BuilderDemo
+  def self.run_demo(_main_window)
+    builder = Gtk::Builder.new(:resource => "/builder/demo.ui")
+    builder.connect_signals {}
 
-require 'common'
-
-module Demo
-  class Dialog < Demo::BasicWindow
-    def initialize
-      super('Interface Builder')
-
-      available = Gtk::Version.or_later?(2, 12, 0)
-      if available
-        label = Gtk::Label.new("Build an interface from XML description.")
-      else
-        label = Gtk::Label.new("You need GTK+ >= 2.12.0 to run this demo.")
-      end
-      add(label)
-      return unless available
-
-      @builder = Gtk::Builder.new
-      filename = File.join(File.dirname(__FILE__), "demo.ui")
-      @builder << filename
-      @builder.connect_signals {|name| method(name)}
-      @window = @builder["window1"]
-      @window.show_all
-
-      signal_connect("destroy") do
-        @window.destroy unless @window.destroyed?
-      end
+    window = builder["window1"]
+    toolbar = builder["toolbar1"]
+    toolbar.style_context.add_class("primary-toolbar")
+
+    actions = Gio::SimpleActionGroup.new
+
+    action = Gio::SimpleAction.new("quit")
+    action.signal_connect "activate" do |_simple_action, _parameter|
+      window.destroy
     end
+    actions.add_action(action)
 
-    private
-    def quit_activate
-      @window.destroy
-      destroy unless destroyed?
+    action = Gio::SimpleAction.new("about")
+    actions.add_action(action)
+    action.signal_connect "activate" do |_simple_action, _parameter|
+      about_dlg = builder["aboutdialog1"]
+      about_dlg.run
+      about_dlg.hide
     end
 
-    def about_activate
-      dialog = @builder["aboutdialog1"]
-      dialog.run
-      dialog.hide
+    action = Gio::SimpleAction.new("help")
+    actions.add_action(action)
+    action.signal_connect "activate" do |_simple_action, _parameter|
+      puts "Help not available"
     end
+
+    window.insert_action_group("win", actions)
+
+    accel_group = Gtk::AccelGroup.new
+    window.add_accel_group(accel_group)
+
+    builder["new_item"].add_accelerator("activate", accel_group,
+                                        Gdk::Keyval::KEY_n,
+                                        Gdk::ModifierType::CONTROL_MASK,
+                                        Gtk::AccelFlags::VISIBLE)
+    builder["open_item"].add_accelerator("activate", accel_group,
+                                         Gdk::Keyval::KEY_o,
+                                         Gdk::ModifierType::CONTROL_MASK,
+                                         Gtk::AccelFlags::VISIBLE)
+    builder["save_item"].add_accelerator("activate", accel_group,
+                                         Gdk::Keyval::KEY_s,
+                                         Gdk::ModifierType::CONTROL_MASK,
+                                         Gtk::AccelFlags::VISIBLE)
+    builder["quit_item"].add_accelerator("activate", accel_group,
+                                         Gdk::Keyval::KEY_q,
+                                         Gdk::ModifierType::CONTROL_MASK,
+                                         Gtk::AccelFlags::VISIBLE)
+    builder["copy_item"].add_accelerator("activate", accel_group,
+                                         Gdk::Keyval::KEY_c,
+                                         Gdk::ModifierType::CONTROL_MASK,
+                                         Gtk::AccelFlags::VISIBLE)
+    builder["cut_item"].add_accelerator("activate", accel_group,
+                                        Gdk::Keyval::KEY_x,
+                                        Gdk::ModifierType::CONTROL_MASK,
+                                        Gtk::AccelFlags::VISIBLE)
+    builder["paste_item"].add_accelerator("activate", accel_group,
+                                          Gdk::Keyval::KEY_v,
+                                          Gdk::ModifierType::CONTROL_MASK,
+                                          Gtk::AccelFlags::VISIBLE)
+    builder["help_item"].add_accelerator("activate", accel_group,
+                                         Gdk::Keyval::KEY_F1,
+                                         0,
+                                         Gtk::AccelFlags::VISIBLE)
+    builder["about_item"].add_accelerator("activate", accel_group,
+                                          Gdk::Keyval::KEY_F7,
+                                          0,
+                                          Gtk::AccelFlags::VISIBLE)
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
   end
 end
-
diff --git a/gtk3/sample/gtk-demo/button-box.rb b/gtk3/sample/gtk-demo/button-box.rb
deleted file mode 100644
index bcdc639..0000000
--- a/gtk3/sample/gtk-demo/button-box.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) 2003-2015 Ruby-GNOME2 Project Team
-# This program is licenced under the same licence as Ruby-GNOME2.
-#
-=begin
-= Button Boxes
-
-The Button Box widgets are used to arrange buttons with padding.
-=end
-require "common"
-
-module Demo
-  class ButtonBox < BasicWindow
-    def initialize
-      super("Button Boxes")
-      set_border_width(10)
-
-      main_vbox = Gtk::Box.new(:vertical)
-      add(main_vbox)
-
-      frame_horiz = Gtk::Frame.new("Horizontal Button Boxes")
-      main_vbox.pack_start(frame_horiz, :expand => true, :fill => true, :padding => 10)
-
-      vbox = Gtk::Box.new(:vertical)
-      vbox.set_border_width(10)
-      frame_horiz.add(vbox)
-
-      vbox.pack_start(create_bbox(true, "Spread", 40, :spread),
-                      :expand => true, :fill => true, :padding => 0)
-
-      vbox.pack_start(create_bbox(true, "Edge", 40, :edge),
-                      :expand => true, :fill => true, :padding => 5)
-
-      vbox.pack_start(create_bbox(true, "Start", 40, :start),
-                      :expand => true, :fill => true, :padding => 5)
-
-      vbox.pack_start(create_bbox(true, "End", 40, :end),
-                      :expand => true, :fill => true, :padding => 5)
-
-      frame_vert = Gtk::Frame.new("Vertical Button Boxes")
-      main_vbox.pack_start(frame_vert, :expand => true, :fill => true, :padding => 10)
-
-     hbox = Gtk::Box.new(:horizontal, 0)
-      hbox.set_border_width(10)
-      frame_vert.add(hbox)
-
-      hbox.pack_start(create_bbox(false, "Spread", 30, :spread),
-                      :expand => true, :fill => true, :padding => 0)
-
-      hbox.pack_start(create_bbox(false, "Edge", 30, :edge),
-                      :expand => true, :fill => true, :padding => 5)
-
-      hbox.pack_start(create_bbox(false, "Start", 30, :start),
-                      :expand => true, :fill => true, :padding => 5)
-
-      hbox.pack_start(create_bbox(false, "End", 30, :end),
-                      :expand => true, :fill => true, :padding => 5)
-    end
-
-    def create_bbox(horizontal, title, spacing, layout)
-      frame = Gtk::Frame.new(title)
-
-      bbox = if horizontal
-               Gtk::ButtonBox.new(:horizontal)
-             else
-               Gtk::ButtonBox.new(:vertical)
-             end
-
-      bbox.set_border_width(5)
-      frame.add(bbox)
-
-      bbox.layout_style = layout
-      bbox.set_spacing(spacing)
-
-      %w(OK(_O) Cancel(_C) Help(_H)).each do |name|
-        button = Gtk::Button.new(:label => name, :use_underline => true)
-        bbox.add(button)
-      end
-
-      frame
-    end
-  end
-end
diff --git a/gtk3/sample/gtk-demo/button_box.rb b/gtk3/sample/gtk-demo/button_box.rb
new file mode 100644
index 0000000..5399c1c
--- /dev/null
+++ b/gtk3/sample/gtk-demo/button_box.rb
@@ -0,0 +1,100 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Button Boxes
+
+ The Button Box widgets are used to arrange buttons with padding.
+=end
+module ButtonBoxDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Button Boxes")
+    window.set_border_width(10)
+
+    main_vbox = Gtk::Box.new(:vertical, 0)
+    window.add(main_vbox)
+
+    frame_horz = Gtk::Frame.new("Horizontal Button Boxes")
+    main_vbox.pack_start(frame_horz, :expand => true, :fill => true, :padding => 10)
+
+    vbox = Gtk::Box.new(:vertical, 0)
+    vbox.set_border_width(10)
+    frame_horz.add(vbox)
+
+    bbox = create_bbox(true, "Spread", 40, :spread)
+    vbox.pack_start(bbox, :expand => true, :fill => true, :padding => 0)
+
+    bbox = create_bbox(true, "Edge", 40, :edge)
+    vbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(true, "Start", 40, :start)
+    vbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(true, "End", 40, :end)
+    vbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(true, "Center", 40, :center)
+    vbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(true, "Expand", 0, :expand)
+    vbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    frame_vert = Gtk::Frame.new("Vertical Button Boxes")
+    main_vbox.pack_start(frame_vert, :expand => true, :fill => true, :padding => 10)
+
+    hbox = Gtk::Box.new(:horizontal, 0)
+    hbox.set_border_width(10)
+
+    frame_vert.add(hbox)
+
+    bbox = create_bbox(false, "Spread", 10, :spread)
+    hbox.pack_start(bbox, :expand => true, :fill => true, :padding => 0)
+
+    bbox = create_bbox(false, "Edge", 10, :edge)
+    hbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(false, "Start", 10, :start)
+    hbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(false, "End", 10, :end)
+    hbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(false, "Center", 10, :center)
+    hbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    bbox = create_bbox(false, "Expand", 0, :expand)
+    hbox.pack_start(bbox, :expand => true, :fill => true, :padding => 5)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.create_bbox(horizontal, title, spacing, layout)
+    frame = Gtk::Frame.new(title)
+    bbox = nil
+
+    if horizontal
+      bbox = Gtk::ButtonBox.new(:horizontal)
+    else
+      bbox = Gtk::ButtonBox.new(:vertical)
+    end
+
+    bbox.set_border_width(5)
+    frame.add(bbox)
+    bbox.set_layout(layout)
+    bbox.set_spacing(spacing)
+
+    %w(OK(_O) Cancel(_C) Help(_H)).each do |name|
+      button = Gtk::Button.new(:label => name, :use_underline => true)
+      bbox.add(button)
+    end
+
+    frame
+  end
+end
diff --git a/gtk3/sample/gtk-demo/colorsel.rb b/gtk3/sample/gtk-demo/colorsel.rb
index 8f8193d..319a5a7 100644
--- a/gtk3/sample/gtk-demo/colorsel.rb
+++ b/gtk3/sample/gtk-demo/colorsel.rb
@@ -1,82 +1,66 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
-# $Id: colorsel.rb,v 1.4 2005/02/12 23:02:43 kzys Exp $
 =begin
-= Color Selector
+= Color Chooser
 
-Gtk::ColorSelection lets the user choose a color. Gtk::ColorSelectionDialog
-is a prebuilt dialog containing a Gtk::ColorSelection.
+A GtkColorChooser lets the user choose a color. There are several
+implementations of the GtkColorChooser interface in GTK+. The
+GtkColorChooserDialog is a prebuilt dialog containing a
+GtkColorChooserWidget.
 =end
-require 'common'
-
-module Demo
-  class ColorSel < BasicWindow
-    def initialize
-      super('Color Selection')
-
-      @color = Gdk::RGBA.new(0, 0, 1, 1)
+module ColorselDemo
+  def self.run_demo(main_window)
+    color = Gdk::RGBA.new(0, 0, 1, 1)
+
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Color Chooser")
+    window.set_border_width(8)
+
+    vbox = Gtk::Box.new(:vertical, 8)
+    vbox.set_border_width(8)
+    window.add(vbox)
+
+    frame = Gtk::Frame.new
+    frame.set_shadow_type(:in)
+    vbox.pack_start(frame, :expand => true, :fill => true, :padding => 0)
+
+    da = Gtk::DrawingArea.new
+    da.signal_connect "draw" do |_widget, cr|
+      cr.set_source(color.to_a)
+      cr.paint
+    end
 
-      set_border_width(8)
+    da.set_size_request(200, 200)
 
-      vbox = Gtk::Box.new(:vertical, 0)
-      vbox.set_border_width(8)
-      add(vbox)
+    frame.add(da)
 
-      ## Create the color swatch area
-      @frame = Gtk::Frame.new
-      @frame.set_shadow_type(:in)
-      vbox.pack_start(@frame, :expand => true, :fill => true, :padding => 0)
+    button = Gtk::Button.new(:mnemonic => "_Change the above color")
+    button.set_halign(:end)
+    button.set_valign(:center)
 
-      @da = Gtk::DrawingArea.new
+    vbox.pack_start(button, :expand => false, :fill => false, :padding => 0)
+    button.signal_connect "clicked" do |_widget|
+      dialog = Gtk::ColorChooserDialog.new(:title => "Changing Color",
+                                           :parent => window)
+      dialog.set_modal(true)
+      dialog.set_rgba(color)
 
-      @da.signal_connect('draw') do |widget, event|
-        if widget.window
-          context = widget.style_context
-          background_color = context.get_background_color(:normal)
-          event.set_source_rgba(background_color.to_a)
-          event.paint
-        end
+      dialog.signal_connect "response" do |widget, response_id|
+        color = widget.rgba if response_id == Gtk::ResponseType::OK
+        da.queue_draw # force da to use the new color now
+        widget.destroy
       end
 
-      # set a minimum size
-      @da.set_size_request(200, 200)
-      # set the color
-      @da.override_background_color(:normal, @color)
-
-      @frame.add(@da)
-
-      alignment = Gtk::Alignment.new(1.0, 0.5, 0.0, 0.0)
-
-      button = Gtk::Button.new(:mnemonic => '_Change the above color')
-      alignment.add(button)
-
-      vbox.pack_start(alignment, :expand => false, :fill => false, :padding => 0)
-
-      button.signal_connect('clicked') do
-        change_color_callback
-      end
+      dialog.show_all
     end
 
-    def change_color_callback
-      dialog = Gtk::ColorSelectionDialog.new(:title => 'Changing color')
-
-      dialog.set_transient_for(self)
-
-      colorsel = dialog.color_selection
-
-      colorsel.set_previous_rgba(@color)
-      colorsel.set_current_rgba(@color)
-      colorsel.set_has_palette(true)
-
-      response = dialog.run
-
-      if response == Gtk::ResponseType::OK
-        @color = colorsel.current_rgba
-        @da.override_background_color(:normal, @color)
-      end
-
-      dialog.destroy
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
+    window
   end
 end
diff --git a/gtk3/sample/gtk-demo/css_accordion.rb b/gtk3/sample/gtk-demo/css_accordion.rb
index 32060e2..9628f9d 100644
--- a/gtk3/sample/gtk-demo/css_accordion.rb
+++ b/gtk3/sample/gtk-demo/css_accordion.rb
@@ -1,75 +1,53 @@
-# This sample code is a port of gtk3/demos/gtk-demo/css_accordion.c. The
-# CSS files used in this sample code are copied from gtk3/demos/gtk-demo.
-# They are licensed under the terms of the GNU Lesser General Public
-# License, version 2.1 or (at your option) later.
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
 #
-# Copyright (C) 2013-2015  Ruby-GNOME2 Project Team
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 =begin
 = CSS Theming/CSS Accordion
 
 A simple accordion demo written using CSS transitions and multiple backgrounds
 =end
+module CssAccordionDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
 
-require "common"
-
-module Demo
-  class CssAccordion < BasicWindow
-    def initialize
-      super("CSS Accordion")
-      set_default_size(600, 300)
-
-      container = Gtk::Box.new(:horizontal, 0)
-      container.set_halign(:center)
-      container.set_valign(:center)
-      add(container)
-
-      child = Gtk::Button.new(:label => "This")
-      container.add(child)
+    window.set_title("CSS Accordion")
+    window.set_default_size(600, 300)
 
-      child = Gtk::Button.new(:label => "Is")
-      container.add(child)
+    container = Gtk::Box.new(:horizontal, 0)
+    container.set_halign(:center)
+    container.set_valign(:center)
 
-      child = Gtk::Button.new(:label => "A")
-      container.add(child)
+    window.add(container)
 
-      child = Gtk::Button.new(:label => "CSS")
+    %w(This Is A CSS Accordion :-).each do |label|
+      child = Gtk::Button.new(:label => label)
       container.add(child)
+    end
 
-      child = Gtk::Button.new(:label => "Accordion")
-      container.add(child)
+    provider = Gtk::CssProvider.new
+    provider.load_from_resource("/css_accordion/css_accordion.css")
 
-      child = Gtk::Button.new(:label => ":-)")
-      container.add(child)
+    style_context = window.style_context
+    style_context.add_provider(provider, Gtk::StyleProvider::PRIORITY_USER)
 
-      provider = Gtk::CssProvider.new
-      Dir.chdir(__dir__) do
-        provider.load(:data => File.read("css_accordion.css"))
-      end
+    apply_style(window, provider)
 
-      apply_css(self, provider)
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
 
-    def apply_css(widget, provider)
-      widget.style_context.add_provider(provider, GLib::MAXUINT)
-      if widget.is_a?(Gtk::Container)
-        widget.each_all do |child|
-          apply_css(child, provider)
-        end
-      end
+    window
+  end
+
+  def self.apply_style(widget, provider)
+    style_context = widget.style_context
+    style_context.add_provider(provider, Gtk::StyleProvider::PRIORITY_USER)
+    return unless widget.respond_to?(:children)
+    widget.children.each do |child|
+      apply_style(child, provider)
     end
   end
 end
diff --git a/gtk3/sample/gtk-demo/css_basics.rb b/gtk3/sample/gtk-demo/css_basics.rb
index 00d1a1f..c6c529b 100644
--- a/gtk3/sample/gtk-demo/css_basics.rb
+++ b/gtk3/sample/gtk-demo/css_basics.rb
@@ -1,103 +1,78 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
 #
-# This sample code is a port of gtk3/demos/gtk-demo/css_basic.c. The
-# CSS file used in this sample code is copied from gtk3/demos/gtk-demo.
-# They are licensed under the terms of the GNU Lesser General Public
-# License, version 2.1 or (at your option) later.
-#
-# Copyright (C) 2013  Ruby-GNOME2 Project Team
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 =begin
 = CSS Theming/CSS Basics
 
 Gtk themes are written using CSS. Every widget is build of multiple items
 that you can style very similarly to a regular website.
 =end
-
-require "common"
-
-module Demo
-  class CssBasics < BasicWindow
-    def initialize
-      super("CSS Basics")
-      set_default_size(400, 300)
-
-      text = Gtk::TextBuffer.new
-      text.create_tag("warning", "underline" => Pango::AttrUnderline::SINGLE)
-      text.create_tag("error", "underline" => Pango::AttrUnderline::ERROR)
-
-      provider = Gtk::CssProvider.new
-
-      container = Gtk::ScrolledWindow.new(nil, nil)
-      add(container)
-      child = Gtk::TextView.new(text)
-      container.add(child)
-      text.signal_connect("changed") do |_text|
-        css_text_changed(_text, provider)
+module CssBasicsDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_title("CSS Basics")
+    window.set_transient_for(main_window)
+    window.set_default_size(400, 300)
+
+    text = Gtk::TextBuffer.new
+    text.create_tag("warning", "underline" => Pango::UNDERLINE_SINGLE)
+    text.create_tag("error", "underline" => Pango::UNDERLINE_ERROR)
+    default_css = Gio::Resources.lookup_data("/css_basics/css_basics.css", 0)
+    text.text = default_css
+
+    provider = Gtk::CssProvider.new
+    provider.load_from_data(default_css)
+
+    container = Gtk::ScrolledWindow.new
+    window.add(container)
+
+    child = Gtk::TextView.new(text)
+    container.add(child)
+
+    text.signal_connect "changed" do |buffer|
+      buffer.remove_all_tags(buffer.start_iter, buffer.end_iter)
+      modified_text = buffer.get_text(buffer.start_iter,
+                                      buffer.end_iter,
+                                      false)
+      begin
+        provider.load_from_data(modified_text)
+      rescue
+        provider.load_from_data(default_css)
       end
 
-      text.text = File.read(File.join(__dir__, "css_basics.css"))
-
-      provider.signal_connect("parsing-error") do |_provider, section, error|
-        p section
-        p error
-        show_parsing_error(section, error, child.buffer)
-      end
-
-      apply_css(self, provider)
+      Gtk::StyleContext.reset_widgets
     end
 
-    private
-    def show_parsing_error(section, error, buffer)
-      p buffer.methods.grep /iter/
-      start = buffer.get_iter_at_line_index(section.start_line,
-                                            section.start_position)
-
-      end_ = buffer.get_iter_at_line_index(section.end_line,
-                                           section.end_position)
-
-      if error == Gtk::CssProvider::ERROR ||
-          error ==  Gtk::CssProvider::ERROR_DEPRECATED
+    provider.signal_connect "parsing-error" do |_css_provider, section, error|
+      start_i = text.get_iter_at(:line => section.start_line,
+                                 :index => section.start_position)
+      end_i =  text.get_iter_at(:line => section.end_line,
+                                :index => section.end_position)
+      tag_name = nil
+      if error == Gtk::CssProviderError::DEPRECATED
         tag_name = "warning"
       else
         tag_name = "error"
       end
-
-      buffer.apply_tag_by_name(buffer, tag_name, start, end_)
+      text.apply_tag_by_name(tag_name, start_i, end_i)
     end
 
-    def css_text_changed(buffer, provider)
-      start = buffer.start_iter
-      end_ = buffer.end_iter
-      buffer.remove_all_tags(start, end_)
+    apply_style(window, provider)
 
-      text = buffer.get_text(start, end_, false)
-      Dir.chdir(__dir__) do
-        provider.load(:data => text)
-      end
-
-      Gtk::StyleContext.reset_widgets
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
+    window
+  end
 
-    def apply_css(widget, provider)
-      widget.style_context.add_provider(provider, GLib::MAXUINT)
-      if widget.is_a?(Gtk::Container)
-        widget.each_all do |child|
-          apply_css(child, provider)
-        end
-      end
+  def self.apply_style(widget, provider)
+    style_context = widget.style_context
+    style_context.add_provider(provider, Gtk::StyleProvider::PRIORITY_USER)
+    return unless widget.respond_to?(:children)
+    widget.children.each do |child|
+      apply_style(child, provider)
     end
   end
 end
diff --git a/gtk3/sample/gtk-demo/css_multiplebgs.rb b/gtk3/sample/gtk-demo/css_multiplebgs.rb
new file mode 100644
index 0000000..8b9e783
--- /dev/null
+++ b/gtk3/sample/gtk-demo/css_multiplebgs.rb
@@ -0,0 +1,112 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  CSS Theming/Multiple Backgrounds
+
+ Gtk themes are written using CSS. Every widget is build of multiple items
+ that you can style very similarly to a regular website.
+=end
+module CssMultiplebgsDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.title = "Mutiple Backgrounds"
+    window.transient_for = main_window
+    window.set_default_size(400, 300)
+
+    container = Gtk::Overlay.new
+    container.add_events([:enter_notify_mask, :leave_notify_mask, :pointer_motion_mask])
+    window.add(container)
+
+    child = Gtk::DrawingArea.new
+    child.name = "canvas"
+
+    child.signal_connect "draw" do |widget, cr|
+      context = widget.style_context
+      Gtk.render_background(context, cr, 0, 0,
+                            widget.allocated_width,
+                            widget.allocated_height)
+      Gtk.render_frame(context, cr, 0, 0,
+                       widget.allocated_width,
+                       widget.allocated_height)
+      false
+    end
+    container.add(child)
+
+    child = Gtk::Button.new
+    child.add_events([:enter_notify_mask, :leave_notify_mask, :pointer_motion_mask])
+    child.name = "bricks-button"
+    child.halign = :center
+    child.valign = :center
+    child.set_size_request(250, 84)
+    container.add_overlay(child)
+
+    paned = Gtk::Paned.new(:vertical)
+    container.add_overlay(paned)
+
+    # Need a filler so we get a handle
+    child = Gtk::Box.new(:vertical, 0)
+    paned.add(child)
+
+    text = Gtk::TextBuffer.new
+    text.create_tag("warning", "underline" => :single)
+    text.create_tag("error", "underline" => :error)
+    default_css = Gio::Resources.lookup_data("/css_multiplebgs/css_multiplebgs.css")
+    text.text = default_css
+
+    provider = Gtk::CssProvider.new
+    provider.load_from_data(default_css)
+
+    container = Gtk::ScrolledWindow.new
+    paned.add(container)
+
+    child = Gtk::TextView.new(text)
+    container.add(child)
+
+    text.signal_connect "changed" do |buffer|
+      buffer.remove_all_tags(buffer.start_iter, buffer.end_iter)
+      modified_text = buffer.get_text(buffer.start_iter,
+                                      buffer.end_iter,
+                                      false)
+      begin
+        provider.load_from_data(modified_text)
+      rescue
+        provider.load_from_data(default_css)
+      end
+
+      Gtk::StyleContext.reset_widgets
+    end
+
+    provider.signal_connect "parsing-error" do |_css_provider, section, error|
+      start_i = text.get_iter_at(:line => section.start_line,
+                                 :index => section.start_position)
+      end_i =  text.get_iter_at(:line => section.end_line,
+                                :index => section.end_position)
+      tag_name = nil
+      if error == Gtk::CssProviderError::DEPRECATED
+        tag_name = "warning"
+      else
+        tag_name = "error"
+      end
+      text.apply_tag_by_name(tag_name, start_i, end_i)
+    end
+    apply_style(window, provider)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.apply_style(widget, provider)
+    style_context = widget.style_context
+    style_context.add_provider(provider, Gtk::StyleProvider::PRIORITY_USER)
+    return unless widget.respond_to?(:children)
+    widget.children.each do |child|
+      apply_style(child, provider)
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/css_pixbufs.rb b/gtk3/sample/gtk-demo/css_pixbufs.rb
new file mode 100644
index 0000000..0d7a3f6
--- /dev/null
+++ b/gtk3/sample/gtk-demo/css_pixbufs.rb
@@ -0,0 +1,84 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  CSS Theming/Animated Backgrounds
+
+ This demo is done in honour of the Pixbufs demo further down.
+ It is done exclusively with CSS as the background of the window.
+=end
+module CssPixbufsDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_title("Animated Backgrounds")
+    window.set_transient_for(main_window)
+    window.set_default_size(400, 300)
+
+    text = Gtk::TextBuffer.new
+    text.create_tag("warning", "underline" => Pango::UNDERLINE_SINGLE)
+    text.create_tag("error", "underline" => Pango::UNDERLINE_ERROR)
+    default_css = Gio::Resources.lookup_data("/css_pixbufs/gtk.css", 0)
+    text.text = default_css
+
+    provider = Gtk::CssProvider.new
+    provider.load_from_data(default_css)
+
+    paned = Gtk::Paned.new(:vertical)
+    window.add(paned)
+
+    child = Gtk::Box.new(:vertical, 0)
+    paned.add(child)
+
+    container = Gtk::ScrolledWindow.new
+    paned.add(container)
+
+    child = Gtk::TextView.new(text)
+    container.add(child)
+
+    text.signal_connect "changed" do |buffer|
+      buffer.remove_all_tags(buffer.start_iter, buffer.end_iter)
+      modified_text = buffer.get_text(buffer.start_iter,
+                                      buffer.end_iter,
+                                      false)
+      begin
+        provider.load_from_data(modified_text)
+      rescue
+        provider.load_from_data(default_css)
+      end
+
+      Gtk::StyleContext.reset_widgets
+    end
+
+    provider.signal_connect "parsing-error" do |_css_provider, section, error|
+      start_i = text.get_iter_at(:line => section.start_line,
+                                 :index => section.start_position)
+      end_i =  text.get_iter_at(:line => section.end_line,
+                                :index => section.end_position)
+      tag_name = nil
+      if error == Gtk::CssProviderError::DEPRECATED
+        tag_name = "warning"
+      else
+        tag_name = "error"
+      end
+      text.apply_tag_by_name(tag_name, start_i, end_i)
+    end
+
+    apply_style(window, provider)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.apply_style(widget, provider)
+    style_context = widget.style_context
+    style_context.add_provider(provider, Gtk::StyleProvider::PRIORITY_USER)
+    return unless widget.respond_to?(:children)
+    widget.children.each do |child|
+      apply_style(child, provider)
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/css_shadows.rb b/gtk3/sample/gtk-demo/css_shadows.rb
new file mode 100644
index 0000000..e42cf99
--- /dev/null
+++ b/gtk3/sample/gtk-demo/css_shadows.rb
@@ -0,0 +1,101 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  CSS Theming/Shadows
+
+ This demo shows how to use CSS shadows.
+=end
+module CssShadowsDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_title("Shadows")
+    window.set_transient_for(main_window)
+    window.set_default_size(400, 300)
+
+    paned = Gtk::Paned.new(:vertical)
+    window.add(paned)
+
+    child = create_toolbar
+    paned.add(child)
+
+    text = Gtk::TextBuffer.new
+    text.create_tag("warning", "underline" => :single)
+    text.create_tag("error", "underline" => :error)
+    default_css = Gio::Resources.lookup_data("/css_shadows/gtk.css")
+    text.text = default_css
+
+    provider = Gtk::CssProvider.new
+    provider.load_from_data(default_css)
+
+    container = Gtk::ScrolledWindow.new
+    paned.add(container)
+
+    child = Gtk::TextView.new(text)
+    container.add(child)
+
+    text.signal_connect "changed" do |buffer|
+      buffer.remove_all_tags(buffer.start_iter, buffer.end_iter)
+      modified_text = buffer.get_text(buffer.start_iter,
+                                      buffer.end_iter,
+                                      false)
+      begin
+        provider.load_from_data(modified_text)
+      rescue
+        provider.load_from_data(default_css)
+      end
+
+      Gtk::StyleContext.reset_widgets
+    end
+
+    provider.signal_connect "parsing-error" do |_css_provider, section, error|
+      start_i = text.get_iter_at(:line => section.start_line,
+                                 :index => section.start_position)
+      end_i =  text.get_iter_at(:line => section.end_line,
+                                :index => section.end_position)
+      tag_name = nil
+      if error == Gtk::CssProviderError::DEPRECATED
+        tag_name = "warning"
+      else
+        tag_name = "error"
+      end
+      text.apply_tag_by_name(tag_name, start_i, end_i)
+    end
+    apply_style(window, provider)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.create_toolbar
+    toolbar = Gtk::Toolbar.new
+    toolbar.set_valign(:center)
+
+    item = Gtk::ToolButton.new
+    item.set_icon_name("go-next")
+    toolbar.insert(item, -1)
+
+    item = Gtk::ToolButton.new
+    item.set_icon_name("go-previous")
+    toolbar.insert(item, -1)
+
+    item = Gtk::ToolButton.new(:label => "Hello World")
+    item.set_is_important(true)
+    toolbar.insert(item, -1)
+
+    toolbar
+  end
+
+  def self.apply_style(widget, provider)
+    style_context = widget.style_context
+    style_context.add_provider(provider, Gtk::StyleProvider::PRIORITY_USER)
+    return unless widget.respond_to?(:children)
+    widget.children.each do |child|
+      apply_style(child, provider)
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/cursors.rb b/gtk3/sample/gtk-demo/cursors.rb
new file mode 100644
index 0000000..3420870
--- /dev/null
+++ b/gtk3/sample/gtk-demo/cursors.rb
@@ -0,0 +1,114 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Cursors
+
+ Demonstrates a useful set of available cursors.
+=end
+module CursorsDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Cursors")
+    window.set_default_size(500, 500)
+
+    sw = Gtk::ScrolledWindow.new(nil, nil)
+    sw.set_policy(:never, :automatic)
+    window.add(sw)
+
+    box = Gtk::Box.new(:vertical, 0)
+    box.set_property("margin-start", 20)
+    box.set_property("margin-end", 20)
+    box.set_property("margin-bottom", 20)
+    sw.add(box)
+
+    section = Section.new(box, "General")
+    %w(default none).each do |cursor_name|
+      section.add_button(cursor_name)
+    end
+
+    section = Section.new(box, "Link & Status")
+    %w(context-menu help
+       pointer progress wait).each do |cursor_name|
+      section.add_button(cursor_name)
+    end
+
+    section = Section.new(box, "Selection")
+    %w(cell crosshair text vertical-text).each do |cursor_name|
+      section.add_button(cursor_name)
+    end
+
+    section = Section.new(box, "Drag & Drop")
+    %w(alias copy move no-drop
+       not-allowed grab grabbing).each do |cursor_name|
+      section.add_button(cursor_name)
+    end
+
+    section = Section.new(box, "Resize & Scrolling")
+    %w(all-scroll col-resize row-resize n-resize
+       e-resize s-resize w-resize ne-resize nw-resize
+       se-resize sw-resize ew-resize ns-resize nesw-resize
+       nwse-resize).each do |cursor_name|
+      section.add_button(cursor_name)
+    end
+
+    section = Section.new(box, "Zoom")
+    %w(zoom-in zoom-out).each do |cursor_name|
+      section.add_button(cursor_name)
+    end
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  class Section
+    def initialize(container, title)
+      label = Gtk::Label.new(title)
+      label.set_xalign(0.0)
+      label.set_margin_top(10)
+      label.set_margin_bottom(10)
+      container.pack_start(label, :expand => false, :fill => true, :padding => 0)
+
+      @section = Gtk::FlowBox.new
+      @section.set_halign(:start)
+      @section.set_selection_mode(:none)
+      @section.set_min_children_per_line(2)
+      @section.set_min_children_per_line(20)
+      container.pack_start(@section, :expand => false, :fill => true, :padding => 0)
+    end
+
+    def add_button(css_name)
+      cursor = Gdk::Cursor.new(css_name)
+      image = nil
+      if !cursor
+        image = Gtk::Image.new(:icon_name => "image-missing", :size => :menu)
+      else
+        path = "/cursors/#{css_name.tr('-', '_')}_cursor.png"
+        image = Gtk::Image.new(:resource => path)
+      end
+      image.set_size_request(32, 32)
+
+      button = Gtk::Button.new
+      button.add(image)
+      button.style_context.add_class("image-button")
+      button.signal_connect("clicked") do |_widget|
+        apply_cursor(cursor)
+      end
+      button.set_tooltip_text(css_name)
+      @section.add(button)
+    end
+
+    private
+
+    def apply_cursor(cursor)
+      toplevel = @section.toplevel
+      window = toplevel.window
+      window.set_cursor(cursor)
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/dialog.rb b/gtk3/sample/gtk-demo/dialog.rb
index 7fb1bda..a05fa46 100644
--- a/gtk3/sample/gtk-demo/dialog.rb
+++ b/gtk3/sample/gtk-demo/dialog.rb
@@ -1,137 +1,127 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
-# $Id: dialog.rb,v 1.5 2005/02/12 23:02:43 kzys Exp $
 =begin
-= Dialog and Message Boxes
+=  Dialogs and Message Boxes
 
-Dialog widgets are used to pop up a transient window for user feedback.
+ Dialog widgets are used to pop up a transient window for user feedback.
 =end
-
-require 'common'
-
-module Demo
-  class Dialog < Demo::BasicWindow
-    def initialize
-      @count = 1
-
-      super('Dialogs')
-      set_border_width(8)
-
-      frame = Gtk::Frame.new('Dialogs')
-      add(frame)
-
-      vbox = Gtk::VBox.new(false, 8)
-      vbox.set_border_width(8)
-      frame.add(vbox)
-
-      # Standard message dialog
-      hbox = Gtk::Box.new(:horizontal, 0)
-      vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
-      button = Gtk::Button.new('_Message Dialog', true)
-      button.signal_connect('clicked') do
-        message_dialog_clicked
-      end
-      hbox.pack_start(button, :expand => false, :fill => false, :padding => 0)
-
-      vbox.pack_start(Gtk::HSeparator.new, :expand => false, :fill => false, :padding => 0)
-
-      # Interactive dialog
-      hbox = Gtk::Box.new(:horizontal, 8)
-      vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
-      vbox2 = Gtk::VBox.new(false, 0)
-
-      button = Gtk::Button.new('_Interactive Dialog')
-      button.signal_connect('clicked') do
-        interactive_dialog_clicked
-      end
-      hbox.pack_start(vbox2, :expand => false, :fill => false, :padding => 0)
-      vbox2.pack_start(button, :expand => false, :fill => false, :padding => 0)
-
-      table = Gtk::Table.new(2, 2, false)
-      table.set_row_spacings(4)
-      table.set_column_spacings(4)
-      hbox.pack_start(table, :expand => false, :fill => false, :padding => 0)
-
-      label = Gtk::Label.new('_Entry 1', true)
-      table.attach_defaults(label, 0, 1, 0, 1)
-
-      @entry1 = Gtk::Entry.new
-      table.attach_defaults(@entry1, 1, 2, 0, 1)
-      label.set_mnemonic_widget(@entry1)
-
-      label = Gtk::Label.new('E_ntry 2', true)
-
-      table.attach_defaults(label, 0, 1, 1, 2)
-
-      @entry2 = Gtk::Entry.new
-      table.attach_defaults(@entry2, 1, 2, 1, 2)
-      label.set_mnemonic_widget(@entry2)
-    end
-
-    def message_dialog_clicked
-      dialog = Gtk::MessageDialog.new(self,
-                                      Gtk::Dialog::MODAL |
-                                      Gtk::Dialog::DESTROY_WITH_PARENT,
-                                      Gtk::MessageDialog::INFO,
-                                      Gtk::MessageDialog::BUTTONS_OK,
-                                      <<EOS)
-This message box has been popped up the following
+module DialogDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.title = "Dialogs and Message Boxes"
+    window.border_width = 8
+
+    frame = Gtk::Frame.new("Dialogs")
+    window.add(frame)
+
+    vbox = Gtk::Box.new(:vertical, 8)
+    vbox.border_width = 8
+    frame.add(vbox)
+
+    # Standard message dialog
+    hbox = Gtk::Box.new(:horizontal, 8)
+    vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
+    button = Gtk::Button.new(:label => "_Message Dialog",
+                             :use_underline => true)
+    i = 0
+
+    button.signal_connect "clicked" do
+      dialog = Gtk::MessageDialog.new(:parent => window,
+                                      :flags => [:modal, :destroy_with_parent],
+                                      :type => :info,
+                                      :buttons => :ok_cancel,
+                                      :message => <<-MESSAGE)
+This message has been popped up the following
 number of times:
-
-#{@count}
-EOS
+MESSAGE
+      dialog.secondary_text = "#{i}"
       dialog.run
       dialog.destroy
-      @count += 1
+      i += 1
     end
 
-    def interactive_dialog_clicked
-      dialog = Gtk::Dialog.new('Interactive Dialog',
-                               self,
-                               Gtk::Dialog::MODAL |
-                               Gtk::Dialog::DESTROY_WITH_PARENT,
-                               [Gtk::Stock::OK, Gtk::ResponseType::OK],
-                               ["_Non-stock Button", Gtk::ResponseType::CANCEL]
-                               )
-
-      hbox = Gtk::Box.new(:horizontal, 0)
-      hbox.set_border_width(8)
-      dialog.vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
-
-      stock = Gtk::Image.new(Gtk::Stock::DIALOG_QUESTION, Gtk::IconSize::DIALOG)
-      hbox.pack_start(stock, :expand => false, :fill => false, :padding => 0)
-
-      table = Gtk::Table.new(2, 2, false)
-      table.set_row_spacings(4)
-      table.set_column_spacings(4)
-      hbox.pack_start(table, :expand => true, :fill => true, :padding => 0)
-      label = Gtk::Label.new('_Entry 1', true)
-      table.attach_defaults(label,
-                            0, 1, 0, 1)
+    hbox.pack_start(button, :expand => false, :fill => false, :padding => 0)
+    vbox.pack_start(Gtk::Separator.new(:horizontal),
+                    :expand => false,
+                    :fill => false,
+                    :padding => 0)
+
+    # Interactive dialog
+    hbox = Gtk::Box.new(:horizontal, 8)
+    vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
+    vbox2 = Gtk::Box.new(:vertical, 0)
+
+    button = Gtk::Button.new(:label => "_Interactive Dialog",
+                             :use_underline => true)
+
+    hbox.pack_start(vbox2, :expand => false, :fill => false, :padding => 0)
+    vbox2.pack_start(button, :expand => false, :fill => false, :padding => 0)
+
+    table = Gtk::Grid.new
+    table.row_spacing = 4
+    table.column_spacing = 4
+    hbox.pack_start(table, :expand => false, :fill => false, :padding => 0)
+
+    label = Gtk::Label.new("_Entry 1", :use_underline => true)
+    table.attach(label, 0, 0, 1, 1)
+
+    entry1 = Gtk::Entry.new
+    table.attach(entry1, 1, 0, 1, 1)
+    label.set_mnemonic_widget(entry1)
+
+    entry2 = Gtk::Entry.new
+    label = Gtk::Label.new("E_ntry 2", :use_underline => true)
+    table.attach(entry2, 1, 1, 1, 1)
+
+    button.signal_connect "clicked" do
+      dialog = Gtk::Dialog.new(:parent => window,
+                               :title => "Interactive Dialog",
+                               :flags => [:modal, :destroy_with_parent],
+                               :buttons => [["_OK", :ok],
+                                            ["_Cancel", :cancel]]
+                              )
+      content_area = dialog.content_area
+      local_hbox = Gtk::Box.new(:horizontal, 8)
+      local_hbox.border_width = 8
+      content_area.pack_start(local_hbox)
+
+      image = Gtk::Image.new(:icon_name => "dialog-question", :size => :dialog)
+      local_hbox.pack_start(image)
+
+      local_table = Gtk::Grid.new
+      local_table.row_spacing = 4
+      local_table.column_spacing = 4
+      local_hbox.pack_start(local_table, :expand => false, :fill => false, :padding => 0)
+
+      label = Gtk::Label.new("_Entry 1", :use_underline => true)
+      local_table.attach(label, 0, 0, 1, 1)
+
       local_entry1 = Gtk::Entry.new
-      local_entry1.text = @entry1.text
-      table.attach_defaults(local_entry1, 1, 2, 0, 1)
+      local_table.attach(local_entry1, 1, 0, 1, 1)
       label.set_mnemonic_widget(local_entry1)
 
-      label = Gtk::Label.new('E_ntry 2', true)
-      table.attach_defaults(label,
-                            0, 1, 1, 2)
-
       local_entry2 = Gtk::Entry.new
-      local_entry2.text = @entry2.text
-      table.attach_defaults(local_entry2, 1, 2, 1, 2)
-      label.set_mnemonic_widget(local_entry2)
+      label = Gtk::Label.new("E_ntry 2", :use_underline => true)
+      local_table.attach(local_entry2, 1, 1, 1, 1)
 
-      hbox.show_all
+      local_hbox.show_all
       response = dialog.run
 
-      if response == Gtk::ResponseType::OK
-        @entry1.text = local_entry1.text
-        @entry2.text = local_entry2.text
+      if response == :ok
+        entry1.text = local_entry1.text
+        entry2.text = local_entry2.text
       end
+
       dialog.destroy
     end
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
   end
 end
-
diff --git a/gtk3/sample/gtk-demo/entry_buffer.rb b/gtk3/sample/gtk-demo/entry_buffer.rb
new file mode 100644
index 0000000..025296f
--- /dev/null
+++ b/gtk3/sample/gtk-demo/entry_buffer.rb
@@ -0,0 +1,44 @@
+# Copyright (c) 2008-2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Entry/Entry Buffer
+
+Gtk::EntryBuffer provides the text content in a Gtk::Entry.
+Applications can provide their own buffer implementation,
+e.g. to provide secure handling for passwords in memory.
+=end
+module EntryBufferDemo
+
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Entry Buffer")
+    window.set_resizable(false)
+
+    vbox = Gtk::Box.new(:vertical, 5)
+    window.add(vbox)
+    vbox.set_border_width(5)
+
+    label = Gtk::Label.new
+    label.set_markup("Entries share a buffer. Typing in one is reflected in the other.")
+    vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
+
+    # Create the buffer that will be shared
+    buffer = Gtk::EntryBuffer.new
+
+    # first entry
+    entry = Gtk::Entry.new(buffer)
+    vbox.pack_start(entry, :expand => false, :fill => false, :padding => 0)
+
+    # second entry
+    entry = Gtk::Entry.new(buffer)
+    vbox.pack_start(entry, :expand => false, :fill => false, :padding => 0)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/entry_completion.rb b/gtk3/sample/gtk-demo/entry_completion.rb
index f26860c..7214658 100644
--- a/gtk3/sample/gtk-demo/entry_completion.rb
+++ b/gtk3/sample/gtk-demo/entry_completion.rb
@@ -1,63 +1,51 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
-# $Id: entry_completion.rb,v 1.3 2005/02/25 17:09:24 kzys Exp $
+#
 =begin
-= Entry Completion (EntryCompletion)
+= Entry/Entry Completion
 
 GtkEntryCompletion provides a mechanism for adding support for
 completion in GtkEntry.
 =end
-
-require 'common'
-
-module Demo
-  class EntryCompletion < Gtk::Dialog
-    def initialize
-      super('GtkEntryCompletion',
-            nil, # parent
-            0,
-            [Gtk::Stock::CLOSE, Gtk::ResponseType::NONE])
-
-      self.resizable = false
-
-      signal_connect('response') do
-        self.destroy
-      end
-
-      vbox = Gtk::VBox.new(false, 5)
-      self.vbox.pack_start(vbox, :expand => true, :fill => true)
-      vbox.border_width = 5
-
-      label = Gtk::Label.new
-      label.markup = 'Completion demo, try writing <b>total</b> or <b>gnome</b> for example'
-      vbox.pack_start(label, :expand => false, :fill => false)
-
-      # Create our entry
-      entry = Gtk::Entry.new
-      vbox.pack_start(entry, :expand => false, :fill => false)
-
-      # Create the completion object
-      completion = Gtk::EntryCompletion.new
-
-      # Assign the completion to the entry
-      entry.completion = completion
-
-      # Create a tree model and use it as the completion model
-      completion.model = create_completion_model
-
-      # Use model column 0 as the text column
-      completion.text_column = 0
+module EntryCompletionDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Entry Completion")
+    window.set_resizable(true)
+
+    vbox = Gtk::Box.new(:vertical, 5)
+    window.add(vbox)
+    vbox.set_border_width(5)
+
+    label = Gtk::Label.new
+    label.set_markup("Completion demo, try writing <b>total</b> or <b>gnome</b> for example.")
+    vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
+
+    entry = Gtk::Entry.new
+    vbox.pack_start(entry, :expand => false, :fill => false, :padding => 0)
+
+    completion = Gtk::EntryCompletion.new
+    entry.completion = completion
+
+    completion.set_model(create_completion_model)
+    completion.set_text_column(0)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
+    window
+  end
 
-
-    def create_completion_model
-      store = Gtk::ListStore.new(String)
-      %w(GNOME total totally).each do |word|
-        iter = store.append
-        iter[0] = word
-      end
-
-      store
+  def self.create_completion_model
+    store = Gtk::ListStore.new(String)
+    %w(GNOME total totally).each do |word|
+      iter = store.append
+      iter[0] = word
     end
+
+    store
   end
 end
diff --git a/gtk3/sample/gtk-demo/expander.rb b/gtk3/sample/gtk-demo/expander.rb
index b6cdc4d..c9ab720 100644
--- a/gtk3/sample/gtk-demo/expander.rb
+++ b/gtk3/sample/gtk-demo/expander.rb
@@ -1,42 +1,76 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
-# $Id: expander.rb,v 1.2 2005/02/25 17:09:25 kzys Exp $
+#
 =begin
-= Expander (Expander)
+= Expander
 
 GtkExpander allows to provide additional content that is initially hidden.
 This is also known as "disclosure triangle".
+
+This example also shows how to make the window resizable only if the expander is expanded.
 =end
+module ExpanderDemo
+  def self.run_demo(main_window)
+    toplevel = main_window.toplevel
+    message = "<big><b>Something went wrong</b></big>"
+    window = Gtk::MessageDialog.new(:parent => toplevel,
+                                    :flags  => :destroy_with_parent,
+                                    :type   => :error,
+                                    :buttons_type => :close,
+                                    :message      => message)
+
+    window.set_use_markup(true)
+
+    message = "Here are some more details but not the full story."
+    window.set_secondary_text(message)
+
+    area = window.message_area
+    box = area.parent
+    box.parent.child_set_property(box, "expand", true)
+    box.parent.child_set_property(box, "fill", true)
 
-require 'common'
+    area.each do |child|
+      child.parent.child_set_property(child, "expand", false)
+    end
+
+    expander = Gtk::Expander.new("Details:")
+    sw = Gtk::ScrolledWindow.new
+    sw.set_min_content_height(100)
+    sw.set_shadow_type(:in)
+    sw.set_policy(:never, :automatic)
 
-module Demo
-  class Expander < Gtk::Dialog
-    def initialize
-      # as opposed to the GTK2 dialog, the buttons have to be enclodes by brackeds
-      # together with their ResponseType AND all groups have to bracketed together
-      super(:title => 'GtkExpander',
-            :parent => nil,
-            :flags => 0,
-            :buttons => [[Gtk::Stock::CLOSE, Gtk::ResponseType::NONE]])
-      self.resizable = false
+    tv = Gtk::TextView.new
+    tv.set_editable(false)
+    tv.set_wrap_mode(:word)
+    tv.buffer.text = <<TEXT
+Finally, the full story with all details.
+And all the inside information, including
+error codes, etc etc. Pages of information,
+you might have to scroll down to read it all,
+or even resize the window - it works !
 
-      signal_connect('response') do
-        self.destroy
-      end
+A second paragraph will contain even more
+innuendo, just to make you scroll down or
+resize the window. Do it already !"
+TEXT
 
-      vbox = Gtk::Box.new(:vertical, 5)
-      self.child.pack_start(vbox, :expand => true, :fill => true)
-      vbox.border_width = 5
+    sw.add(tv)
+    expander.add(sw)
+    area.pack_end(expander, :expand => true, :fill => true, :padding => 0)
+    expander.show_all
 
-      label = Gtk::Label.new('Expander demo. CLick on the triangle for details.')
-      vbox.pack_start(label, :expand => false, :fill => false)
+    expander.signal_connect "notify::expanded" do
+      window.set_resizable(expander.expanded?)
+    end
 
-      # Create the expander
-      expander = Gtk::Expander.new('Details')
-      vbox.pack_start(expander, :expand => false, :fill => false)
+    window.signal_connect "response" do |dialog, _response_id|
+      dialog.destroy
+    end
 
-      expander.add(Gtk::Label.new('Details can be shown or hidden.'))
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
   end
 end
diff --git a/gtk3/sample/gtk-demo/filtermodel.rb b/gtk3/sample/gtk-demo/filtermodel.rb
new file mode 100644
index 0000000..3da2182
--- /dev/null
+++ b/gtk3/sample/gtk-demo/filtermodel.rb
@@ -0,0 +1,119 @@
+# Copyright (c) 2016 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Tree View/Filter Model
+
+ This example demonstrates how GtkTreeModelFilter can be used not
+ just to show a subset of the rows, but also to compute columns
+ that are not actually present in the underlying model.
+=end
+module FiltermodelDemo
+  WIDTH_COLUMN = 0
+  HEIGHT_COLUMN = 1
+  AREA_COLUMN = 2
+  SQUARE_COLUMN = 3
+
+  def self.run_demo(main_window)
+    builder = Gtk::Builder.new(:resource => "/filtermodel/filtermodel.ui")
+    builder.connect_signals {}
+
+    window = builder["window1"]
+    window.screen = main_window.screen
+
+    column = builder["treeviewcolumn1"]
+    cell = builder["cellrenderertext1"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[WIDTH_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    column = builder["treeviewcolumn2"]
+    cell = builder["cellrenderertext2"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[HEIGHT_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    column = builder["treeviewcolumn3"]
+    cell = builder["cellrenderertext3"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[WIDTH_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    column = builder["treeviewcolumn4"]
+    cell = builder["cellrenderertext4"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[HEIGHT_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    column = builder["treeviewcolumn5"]
+    cell = builder["cellrenderertext5"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[AREA_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    column = builder["treeviewcolumn6"]
+    cell = builder["cellrendererpixbuf1"]
+    column.add_attribute(cell, "visible", SQUARE_COLUMN)
+
+    store = builder["liststore1"]
+    tree = builder["treeview2"]
+
+    types = [Integer, Integer, Integer, TrueClass]
+
+    model = Gtk::TreeModelFilter.new(store)
+    model.set_modify_func(*types) do |filter_model, filter_iter, filter_column|
+      value = nil
+      child_iter = filter_model.convert_iter_to_child_iter(filter_iter)
+      width = child_iter[WIDTH_COLUMN]
+      height = child_iter[HEIGHT_COLUMN]
+      case filter_column
+      when WIDTH_COLUMN
+        value = width
+      when HEIGHT_COLUMN
+        value = height
+      when AREA_COLUMN
+        value = width * height
+      when SQUARE_COLUMN
+        value = (width == height)
+      end
+      value
+    end
+
+    tree.model = model
+
+    column = builder["treeviewcolumn7"]
+    cell = builder["cellrenderertext6"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[WIDTH_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    column = builder["treeviewcolumn8"]
+    cell = builder["cellrenderertext7"]
+    column.set_cell_data_func(cell) do |_column, current_cell, _current_model, current_iter|
+      num = current_iter[HEIGHT_COLUMN]
+      current_cell.text = num.to_s
+    end
+
+    tree = builder["treeview3"]
+
+    model = Gtk::TreeModelFilter.new(store)
+    model.set_visible_func do |_current_model, current_iter|
+      current_iter[WIDTH_COLUMN] < 10
+    end
+
+    tree.model = model
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+end
diff --git a/gtk3/sample/gtk-demo/font_features.rb b/gtk3/sample/gtk-demo/font_features.rb
new file mode 100644
index 0000000..e37741a
--- /dev/null
+++ b/gtk3/sample/gtk-demo/font_features.rb
@@ -0,0 +1,117 @@
+# Copyright (c) 2016 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Pango/Font Features
+
+ This demonstrates support for OpenType font features with
+ Pango attributes. The attributes can be used manually or
+ via Pango markup.
+=end
+module FontFeaturesDemo
+  def self.run_demo(main_window)
+    builder = Gtk::Builder.new(:resource => "/font-features/font-features.ui")
+    window = builder["window"]
+    label = builder["label"]
+    settings = builder["settings"]
+    resetbutton = builder["reset"]
+    font = builder["font"]
+    numcasedefault = builder["numcasedefault"]
+    numspacedefault = builder["numspacedefault"]
+    fractiondefault = builder["fractiondefault"]
+    stack = builder["stack"]
+    entry = builder["entry"]
+    toggle = []
+
+    %w(kern liga dlig hlig clig smcp c2sc lnum onum pnum tnum frac afrc zero
+       nalt swsh calt hist salt ss01 ss02 ss03 ss04 ss05).each do |name|
+      toggle << builder[name]
+    end
+    text = nil
+
+    builder.connect_signals do |name|
+      case name
+      when "reset"
+        proc do |button|
+          numcasedefault.active = true
+          numspacedefault.active = true
+          fractiondefault.active = true
+          toggle.each do |widget|
+            if widget.class != Gtk::RadioButton
+              widget.active = false
+              widget.sensitive = false
+            end
+          end
+        end
+      when "update"
+        proc do
+          update(toggle, entry, font, settings, label)
+        end
+      when "switch_to_entry"
+        proc do
+          text = entry.text
+          stack.visible_child_name = "entry"
+        end
+      when "switch_to_label"
+        proc do
+          text = nil
+          stack.set_visible_child_name("label")
+          update(toggle, entry, font, settings, label)
+        end
+      when "entry_key_press"
+        proc do |entry, event|
+          if event.keyval == Gdk::Keyval::KEY_Escape
+            entry.text = text
+            text = nil
+            stack.set_visible_child_name("label")
+            update(toggle, entry, font, settings, label)
+          end
+          Gdk::Event::PROPAGATE
+        end
+      end
+    end
+
+    update(toggle, entry, font, settings, label)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.update(toggle, entry, font, settings, label)
+    text = entry.text
+    font_desc = font.font
+    s = ""
+    has_feature = false
+
+    toggle.each do |widget|
+      next unless widget.sensitive?
+
+      if widget.class == Gtk::RadioButton
+        if widget.active?
+          s += ", " if has_feature
+          s += widget.builder_name
+          s += " 1"
+          has_feature = true
+        end
+      else
+        s += ", " if has_feature
+        s += widget.builder_name
+        if widget.active?
+          s += " 1"
+        else
+          s += " 0"
+        end
+        has_feature = true
+      end
+    end
+    font_settings = s
+    settings.text = font_settings
+
+    s = "<span font_desc='#{font_desc}' font_features='#{font_settings}'>#{text}</span>"
+    label.markup = s
+  end
+end
diff --git a/gtk3/sample/gtk-demo/headerbar.rb b/gtk3/sample/gtk-demo/headerbar.rb
new file mode 100644
index 0000000..d558acc
--- /dev/null
+++ b/gtk3/sample/gtk-demo/headerbar.rb
@@ -0,0 +1,57 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Header Bar
+
+GtkHeaderBar is a container that is suitable for implementing
+window titlebars. One of its features is that it can position
+a title (and optional subtitle) centered with regard to the
+full width, regardless of variable-width content at the left
+or right.
+
+It is commonly used with gtk_window_set_titlebar()
+=end
+module HeaderbarDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_default_size(600, 400)
+
+    header = Gtk::HeaderBar.new
+    header.set_show_close_button(true)
+    header.set_title("Welcome to Facebook - Log in, sign up or learn more")
+    header.set_has_subtitle(false)
+
+    button = Gtk::Button.new()
+
+    icon = Gio::ThemedIcon.new("mail-send-receive-symbolic")
+    image = Gtk::Image.new(:icon => icon, :size => :button)
+
+    button.add(image)
+    header.pack_end(button)
+
+    box = Gtk::Box.new(:horizontal, 0)
+    box.style_context.add_class("linked")
+
+    button = Gtk::Button.new
+    image = Gtk::Image.new(:icon_name => "pan-start-symbolic", :size => :button)
+    button.add(image)
+    box.add(button)
+
+    button = Gtk::Button.new
+    image = Gtk::Image.new(:icon_name => "pan-end-symbolic", :size => :button)
+    button.add(image)
+    box.add(button)
+
+    header.pack_start(box)
+    window.set_titlebar(header)
+    window.add(Gtk::TextView.new())
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/iconview_edit.rb b/gtk3/sample/gtk-demo/iconview_edit.rb
new file mode 100644
index 0000000..3ecb974
--- /dev/null
+++ b/gtk3/sample/gtk-demo/iconview_edit.rb
@@ -0,0 +1,79 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Icon View/Editing and Drag-and-Drop
+
+ The GtkIconView widget supports Editing and Drag-and-Drop.
+ This example also demonstrates using the generic GtkCellLayout
+ interface to set up cell renderers in an icon view.
+=end
+module IconviewEditDemo
+  COL_TEXT = 0
+  NUM_COLS = 1
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Editing and Drag-and-drop")
+
+    store = create_store
+    fill_store(store)
+
+    icon_view = Gtk::IconView.new(:model => store)
+    icon_view.set_selection_mode(:single)
+    icon_view.set_item_orientation(:horizontal)
+    icon_view.set_columns(2)
+    icon_view.set_reorderable(true)
+
+    renderer = Gtk::CellRendererPixbuf.new
+    icon_view.pack_start(renderer, true)
+
+    icon_view.set_cell_data_func(renderer) do |_layout, cell_renderer, model, iter|
+      text = model.get_value(iter, COL_TEXT)
+      if text
+        color = Gdk::RGBA.parse(text)
+        pixel = nil
+        if color
+          pixel = (color.red * 255).to_i << 24 |
+                  (color.green * 255).to_i << 16 |
+                  (color.blue * 255).to_i << 8 |
+                  (color.alpha * 255).to_i
+        end
+        pixbuf = Gdk::Pixbuf.new(Gdk::Pixbuf::COLORSPACE_RGB, true, 8, 24, 24)
+        pixbuf.fill!(pixel) if pixel
+        cell_renderer.set_property("pixbuf", pixbuf)
+      end
+    end
+
+    renderer = Gtk::CellRendererText.new
+    icon_view.pack_start(renderer, true)
+    renderer.set_property("editable", true)
+    renderer.signal_connect("edited") do |_cell, path_string, text|
+      model = icon_view.model
+      path = Gtk::TreePath.new(path_string)
+      iter = model.get_iter(path)
+      iter[COL_TEXT] = text
+    end
+
+    icon_view.set_attributes(renderer, "text" => COL_TEXT)
+    window.add(icon_view)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.create_store
+    store = Gtk::ListStore.new(String)
+    store
+  end
+
+  def self.fill_store(store)
+    %w(Red Green Blue Yellow).each do |color|
+      store.append.set_values([color])
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/infobar.rb b/gtk3/sample/gtk-demo/infobar.rb
index 43597ea..525d07a 100644
--- a/gtk3/sample/gtk-demo/infobar.rb
+++ b/gtk3/sample/gtk-demo/infobar.rb
@@ -1,78 +1,94 @@
-# Copyright (c) 2013 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
 =begin
-= Info bar
+=  Info Bars
 
-Info bar widgets are used to report important messages to the user.
+ Info bar widgets are used to report important messages to the user.
 =end
-require 'common'
-
-module Demo
-  class InfoBar < BasicWindow
-    def initialize
-      super('Info Bars')
-
-      self.border_width = 8
+module InfobarDemo
+  def self.run_demo(main_window)
+    actions = Gtk::Box.new(:horizontal, 0)
+
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Info Bars")
+    window.set_border_width(8)
+
+    vbox = Gtk::Box.new(:vertical, 0)
+    window.add(vbox)
+
+    generate_simple_infobar_and_button("info", vbox, actions)
+    generate_simple_infobar_and_button("warning", vbox, actions)
+
+    bar = Gtk::InfoBar.new
+    bar.add_button("_OK", Gtk::ResponseType::OK)
+    bar.set_show_close_button(true)
+    bar.signal_connect "response" do |info_bar, response_id|
+      info_bar.hide if response_id == Gtk::ResponseType::CLOSE
+      dialog = Gtk::MessageDialog.new(:parent => info_bar.toplevel,
+                                      :flags => [:modal, :destroy_with_parent],
+                                      :type => :info,
+                                      :buttons => :ok,
+                                      :message => "You clicked a button on an info bar")
+      dialog.secondary_text = "Your response has id #{response_id}"
+      dialog.signal_connect("response") { |widget| widget.destroy }
+      dialog.show_all
+    end
 
+    vbox.pack_start(bar,
+                    :expand => false,
+                    :fill => false,
+                    :padding => 0)
 
-      vbox = Gtk::Box.new :vertical
-      self.add vbox
+    bar.set_message_type(:question)
+    label = Gtk::Label.new("This is an info bar with message type Gtk::MessageType::QUESTION")
+    label.set_line_wrap(true)
+    label.set_xalign(0)
 
-      bar = Gtk::InfoBar.new
-      vbox.pack_start bar, :expand => false, :fill => false, :padding => 0
-      bar.message_type = :info
-      label = Gtk::Label.new 'This is an info bar with message type GTK_MESSAGE_INFO'
-      bar.content_area.pack_start label, :expand => false, :fill => false, :padding => 0
+    bar.content_area.pack_start(label, :expand => false, :fill => false, :padding => 0)
 
-      bar = Gtk::InfoBar.new
-      vbox.pack_start bar, :expand => false, :fill => false, :padding => 0
-      bar.message_type = :warning
-      label = Gtk::Label.new 'This is an info bar with message type GTK_MESSAGE_WARNING'
-      bar.content_area.pack_start label, :expand => false, :fill => false, :padding => 0
+    button = Gtk::ToggleButton.new(:label => "Question")
+    button.bind_property("active", bar, "visible", :bidirectional)
+    actions.add(button)
+    button.set_active(false)
 
-      bar = Gtk::InfoBar.new [:ok, :ok]
-      bar.signal_connect(:response) {|widget, response_id| on_bar_response widget, response_id}
-      vbox.pack_start bar, :expand => false, :fill => false, :padding => 0
-      bar.message_type = :question
-      label = Gtk::Label.new 'This is an info bar with message type GTK_MESSAGE_QUESTION'
-      bar.content_area.pack_start label, :expand => false, :fill => false, :padding => 0
+    generate_simple_infobar_and_button("error", vbox, actions)
+    generate_simple_infobar_and_button("other", vbox, actions)
 
-      bar = Gtk::InfoBar.new
-      vbox.pack_start bar, :expand => false, :fill => false, :padding => 0
-      bar.message_type = :error
-      label = Gtk::Label.new 'This is an info bar with message type GTK_MESSAGE_ERROR'
-      bar.content_area.pack_start label, :expand => false, :fill => false, :padding => 0
+    frame = Gtk::Frame.new("Info bars")
+    vbox.pack_start(frame, :expand => false, :fill => false, :padding => 8)
 
-      bar = Gtk::InfoBar.new
-      vbox.pack_start bar, :expand => false, :fill => false, :padding => 0
-      bar.message_type = :other
-      label = Gtk::Label.new 'This is an info bar with message type GTK_MESSAGE_OTHER'
-      bar.content_area.pack_start label, :expand => false, :fill => false, :padding => 0
+    vbox2 = Gtk::Box.new(:vertical, 8)
+    vbox2.set_border_width(8)
+    frame.add(vbox2)
 
+    label = Gtk::Label.new("An example of different info bars")
+    vbox2.pack_start(label, :expand => false, :fill => false, :padding => 0)
+    actions.show_all
+    vbox2.pack_start(actions, :expand => false, :fill => false, :padding => 0)
 
-      frame = Gtk::Frame.new 'Info bars'
-      vbox.pack_start frame, :expand => false, :fill => false, :padding => 8
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
 
-      vbox2 = Gtk::Box.new :vertical, 8
-      vbox2.border_width = 8
-      frame.add vbox2
+  def self.generate_simple_infobar_and_button(message_type, bar_parent, button_parent)
+    bar = Gtk::InfoBar.new
+    bar_parent.pack_start(bar, :expand => false, :fill => false, :padding => 0)
+    bar.set_message_type(message_type.to_sym)
 
-      # Standard message dialog
-      label = Gtk::Label.new 'An example of different info bars'
-      vbox2.pack_start label, :expand => false, :fill => false, :padding => 0
-    end
+    label = Gtk::Label.new("This is an info bar with message type Gtk::MessageType::#{message_type.upcase}")
+    label.set_line_wrap(true)
+    label.set_xalign(0)
 
-    def on_bar_response info_bar, response_id
-      dialog = Gtk::MessageDialog.new :parent => self,
-                                      :flags => [:modal, :destroy_with_parent],
-                                      :type => :info,
-                                      :buttons_type => :ok,
-                                      :message => 'You clicked a button on an info bar'
+    bar.content_area.pack_start(label, :expand => false, :fill => false, :padding => 0)
 
-      dialog.set_secondary_text "Your response has id %d" % response_id
-      dialog.signal_connect(:response) {dialog.destroy}
-      dialog.show_all
-    end
+    button = Gtk::ToggleButton.new(:label => "Message")
+    button.bind_property("active", bar, "visible", :bidirectional)
+    button_parent.add(button)
   end
-end
\ No newline at end of file
+end
diff --git a/gtk3/sample/gtk-demo/links.rb b/gtk3/sample/gtk-demo/links.rb
index 303240c..3d95c31 100644
--- a/gtk3/sample/gtk-demo/links.rb
+++ b/gtk3/sample/gtk-demo/links.rb
@@ -1,53 +1,66 @@
-# Copyright (c) 2013 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
 =begin
 = Links
 
-GtkLabel can show hyperlinks. The default action is to call gtk_show_uri() on their URI, but it is possible to override this with a custom handler.
+GtkLabel can show hyperlinks. The default action is to call
+gtk_show_uri() on their URI, but it is possible to override
+this with a custom handler.
 =end
-require 'common'
+module LinksDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Links")
+    window.set_border_width(12)
 
-module Demo
-  class Links < BasicWindow
-    def initialize
-      super('Links')
+    label = Gtk::Label.new(<<-MESSAGE)
+Some <a href="http://en.wikipedia.org/wiki/Text"
+title="plain text">text</a> may be marked up
+as hyperlinks, which can be clicked
+or activated via <a href="keynav">keynav</a>
+and they work fine with other markup, like when
+searching on <a href="http://www.google.com/">
+<span color="#0266C8">G</span><span color="#F90101">o</span>
+<span color="#F2B50F">o</span><span color="#0266C8">g</span>
+<span color="#00933B">l</span><span color="#F90101">e</span>
+</a>.
+    MESSAGE
+    label.set_use_markup(true)
 
-      title = 'Links'
-      border_width = 12
-      signal_connect(:destroy) {self.destroy}
-
-      label = Gtk::Label.new "Some <a href=\"http://en.wikipedia.org/wiki/Text\"" +
-                             "title=\"plain text\">text</a> may be marked up\n" +
-                             "as hyperlinks, which can be clicked\n" +
-                             "or activated via <a href=\"keynav\">keynav</a>\n" +
-                             "and they work fine with other markup, like when\n" +
-                             "searching on <a href=\"http://www.google.com/\">" +
-                             "<span color=\"#0266C8\">G</span><span color=\"#F90101\">o</span>" +
-                             "<span color=\"#F2B50F\">o</span><span color=\"#0266C8\">g</span>" +
-                             "<span color=\"#00933B\">l</span><span color=\"#F90101\">e</span>" +
-                             "</a>."
-      label.use_markup = true
-      label.signal_connect(:activate_link) {|widget, uri| activate_link uri}
-      add label
-      label.show
+    label.signal_connect "activate-link" do |_widget, uri|
+      if uri == "keynav"
+        parent = label.toplevel
+        dialog = Gtk::MessageDialog.new(:parent => parent,
+                                        :flags => :destroy_with_parent,
+                                        :type => :info,
+                                        :buttons => :ok,
+                                        :message => <<-MESSAGE)
+The term <i>keynav</i> is a shorthand for
+keyboard navigation and refers to the process of using
+a program (exclusively) via keyboard input.
+        MESSAGE
+        dialog.set_use_markup(true)
+        dialog.set_modal(true)
+        dialog.present
+        dialog.signal_connect "response" do
+          dialog.destroy
+        end
+        true
+      else
+        false
+      end
     end
 
-    def activate_link uri
-      if uri == 'keynav'
-        dialog = Gtk::MessageDialog.new :parent => self,
-                   :flags => :destroy_with_parent,
-                   :type => :info,
-                   :buttons_type => :ok
+    window.add(label)
+    label.show
 
-        dialog.markup = "The term <i>keynav</i> is a shorthand for " +
-                        "keyboard navigation and refers to the process of using " +
-                        "a program (exclusively) via keyboard input."
-        dialog.present
-        dialog.signal_connect(:response) {dialog.destroy}
-        return true
-      end
-      false
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
+    window
   end
-end
\ No newline at end of file
+end
diff --git a/gtk3/sample/gtk-demo/main.rb b/gtk3/sample/gtk-demo/main.rb
index 8a795a6..2981eac 100755
--- a/gtk3/sample/gtk-demo/main.rb
+++ b/gtk3/sample/gtk-demo/main.rb
@@ -21,6 +21,7 @@ require "optparse"
 require "fileutils"
 
 current_path = File.expand_path(File.dirname(__FILE__))
+
 gresource_bin = "#{current_path}/demo.gresource"
 gresource_xml = "#{current_path}/demo.gresource.xml"
 
@@ -42,24 +43,205 @@ Gio::Resources.register(resource)
 
 ENV["GSETTINGS_SCHEMA_DIR"] = current_path
 
+TITLE_COLUMN = 0
+FILENAME_COLUMN = 1
+STYLE_COLUMN = 2
+
+def script_info(path)
+  title = depend = nil
+  file = File.open(path)
+  file.each do |ln|
+    if !title && ln =~ /^=\s+(.*)$/
+      title = Regexp.last_match(1)
+      if title =~ /^(.*)\((.+?)\)$/
+        title = Regexp.last_match(1)
+        depend = Regexp.last_match(2)
+      end
+    end
+
+    break if title
+  end
+
+  [title, depend]
+end
+
+def generate_index
+  # Target scripts
+  scripts = Dir.glob(File.join(File.dirname(__FILE__), "*.rb"))
+  # Generate index tree
+  children = {}
+  index = []
+
+  scripts.each do |script|
+    next if ["common.rb", "main.rb"].include?(File.basename(script))
+    title, depend = script_info(script)
+
+    next if depend && !Gtk.const_defined?(depend)
+
+    if title =~ %r{^(.+?)/(.+)$}
+      parent = Regexp.last_match(1)
+      child = Regexp.last_match(2)
+
+      unless children[parent]
+        children[parent] = []
+        index += [[parent, nil, []]]
+      end
+      children[parent] += [[child, script]]
+    else
+      index += [[title, script]]
+    end
+  end
+
+  # Sort children
+  children.each_key do |parent|
+    children[parent].sort! do |a, b|
+      a[0] <=> b[0]
+    end
+  end
+
+  # Expand children
+  index.collect! do |row|
+    row[2] = children[row[0]] if row[2]
+
+    row
+  end
+
+  index.sort! do |a, b|
+    a[0] <=> b[0]
+  end
+
+  index
+end
+
+def append_children(model, source, parent = nil)
+  source.each do |title, filename, children|
+    iter = model.append(parent)
+    iter[TITLE_COLUMN] = title
+    iter[FILENAME_COLUMN] = filename
+    iter[STYLE_COLUMN] = Pango::FontDescription::STYLE_NORMAL
+
+    append_children(model, children, iter) if children
+  end
+end
+
+def get_demo_name_from_filename(filename)
+  File.basename(filename, ".rb").tr("-", "_")
+end
+
+def get_module_name_from_filename(filename)
+  pattern = get_demo_name_from_filename(filename)
+  module_name = pattern.split("_").map(&:capitalize).join
+  module_name << "Demo"
+end
+
+def list_demos(source, is_child = false)
+  source.each do |title, filename, children|
+    if is_child
+      printf("%-30.30s", "\t" + title)
+      printf("%-30.30s", get_demo_name_from_filename(filename))
+      puts ""
+    elsif filename
+      printf("%-38.38s", title)
+      printf("%-30.30s", get_demo_name_from_filename(filename))
+      puts ""
+    else
+      puts "#{title} : "
+    end
+
+    list_demos(children, true) if children
+  end
+end
 
+def find_demo_filename_from_name(source, name)
+  demo_filename = nil
+  source.each do |_title, filename, children|
+    if filename && name == get_demo_name_from_filename(filename)
+      demo_filename = filename
+    end
+    break if demo_filename
+    (demo_filename = find_demo_filename_from_name(children, name)) if children
+  end
+  demo_filename
+end
+
+def get_demo_filename_from_name(name)
+  index = generate_index
+  filename = find_demo_filename_from_name(index, name)
+  puts "Demo not found" unless filename
+
+  filename
+end
+
+def run_demo_from_file(filename, window)
+  module_name = get_module_name_from_filename(filename)
+
+  unless Module.const_defined?(module_name) == true
+    require filename
+  end
+
+  module_object = Module.const_get(module_name)
+  demo = module_object.send(:run_demo, window)
+
+  if demo && demo.class == Gtk::Window
+    demo.set_transient_for(window)
+    demo.modal = true
+  end
+  demo
+end
 
 class Demo < Gtk::Application
   def initialize
     super("org.gtk.Demo", [:non_unique, :handles_command_line])
 
+    action = Gio::SimpleAction.new("quit")
+    action.signal_connect "activate" do |_action, _parameter|
+      quit
+    end
+    add_action(action)
+
+    action = Gio::SimpleAction.new("about")
+    action.signal_connect "activate" do |_action, _parameter|
+      Gtk::AboutDialog.show(active_window,
+                            "program_name" => "GTK+ Demo",
+                            "version" => Gtk::Version::STRING,
+                            "copyright" => "(C) 1997-2013 The GTK+ Team",
+                            "license_type" => Gtk::License::LGPL_2_1,
+                            "website" => "http://www.gtk.org",
+                            "comments" => "Program to demonstrate GTK+ widgets",
+                            "authors" => ["The GTK+ Team"],
+                            "logo_icon_name" => "gtk3-demo",
+                            "title" => "About GTK+ Demo"
+                           )
+    end
+
+    add_action(action)
     @options = {}
     @exit_status = 0
 
     signal_connect "startup" do |application|
-      puts "startup"
       @builder = Gtk::Builder.new(:resource => "/ui/main.ui")
       appmenu = @builder["appmenu"]
       application.set_app_menu(appmenu)
+
+      @info_buffer = Gtk::TextBuffer.new
+      @source_buffer = Gtk::TextBuffer.new
+
+      @info_buffer.create_tag("title",
+                              "font" => "Sans 18")
+
+      @source_buffer.create_tag("comment",
+                                "foreground" => "red")
+      @source_buffer.create_tag("const",
+                                "foreground" => "ForestGreen")
+      @source_buffer.create_tag("string",
+                                "foreground" => "RosyBrown",
+                                "weight" => Pango::FontDescription::WEIGHT_BOLD
+                               )
+      @source_buffer.create_tag("reserved",
+                                "foreground" => "purple")
     end
 
-    signal_connect "activate" do |application|
-      puts "activate"
+    signal_connect "activate" do |_application|
       begin
         run_application
       rescue => error
@@ -68,8 +250,7 @@ class Demo < Gtk::Application
       end
     end
 
-    signal_connect "command-line" do |application, command_line|
-      puts "cmd"
+    signal_connect "command-line" do |_application, command_line|
       begin
         parse_command_line(command_line.arguments)
       rescue SystemExit => error
@@ -85,9 +266,10 @@ class Demo < Gtk::Application
         @exit_status
       end
     end
- end
+  end
 
   private
+
   def parse_command_line(arguments)
     parser = OptionParser.new
     parser.on("-r", "--run EXAMPLE", "Run an example") do |example|
@@ -109,66 +291,194 @@ class Demo < Gtk::Application
 
   def run_application
     if @options[:list]
-      puts "list"
-      # list_demos
+      list_demos(generate_index)
       quit
     end
 
-    if @options[:name]
-      puts "name"
-      # lookup_for_corresponding_demo
-      # load_demo
-    end
-
-    if @options[:autoquit]
-      puts "autoquit"
-      GLib::Timeout.add(1) do
-        #implement auto_quit
-      end
-    end
-
     window = @builder["window"]
     add_window(window)
-
     action = Gio::SimpleAction.new("run")
+
     action.signal_connect "activate" do |_action, _parameter|
-      # activate_run
+      selection = @treeview.selection
+      iter = selection.selected
+      filename = iter[1]
+      run_demo_from_file(filename, windows.first) if filename
     end
-    add_action(action)
+    window.add_action(action)
 
-    notebook = @builder["notebook"]
-    info_textwiew = @builder["info-textview"]
-    source_textview = @builder["source-textview"]
+    @notebook = @builder["notebook"]
+    @info_view = @builder["info-textview"]
+    @source_view = @builder["source-textview"]
     headerbar = @builder["headerbar"]
-    treeview = @builder["treeview"]
-    model = treeview.model
+    @treeview = @builder["treeview"]
+    model = @treeview.model
+    append_children(model, generate_index)
 
-    sw = @builder["source-scrolledwindow"]
-    scrollbar = sw.vscrollbar
+    @source_sw = @builder["source-scrolledwindow"]
+    scrollbar = @source_sw.vscrollbar
 
-    menu = Gtk::Menu.new
+    @menu = Gtk::Menu.new
 
-    item = Gtk::MenuItem.new("Start")
-    menu.append(item)
+    item = Gtk::MenuItem.new(:label => "Start")
+    @menu.append(item)
     item.signal_connect "activate" do
-      adj = scrollbar.adjustement
-      adj.value = adj.get_lower
+      adj = scrollbar.adjustment
+      adj.value = adj.lower
     end
 
-    item = Gtk::MenuItem.new("End")
-    menu.append(item)
+    item = Gtk::MenuItem.new(:label => "End")
+    @menu.append(item)
     item.signal_connect "activate" do
-      adj = scrollbar.adjustement
-      adj.value = adj.get_upper - adj.get_page_size
+      adj = scrollbar.adjustment
+      adj.value = adj.upper - adj.page_size
     end
 
-    menu.show_all
+    @info_sw = @builder["info-scrolledwindow"]
+
+    @menu.show_all
 
-    scrollbar.signal_connect "popup-menu" do
-      menu.popup(nil, nil, Gtk.current_event_time)
+    scrollbar.signal_connect "popup-menu" do |widget, button, activate_time|
+      @menu.popup(nil, nil, 0, Gtk.current_event_time)
+    end
+
+    @treeview.signal_connect "row-activated" do |_tree_view, path, _column|
+      iter = model.get_iter(path)
+      filename = iter[1]
+      iter[2] = Pango::FontDescription::STYLE_ITALIC
+      demo = run_demo_from_file(filename, windows.first)
+      demo.signal_connect "destroy" do
+        iter[2] = Pango::FontDescription::STYLE_NORMAL
+      end
+    end
+
+    treeview_selection = @builder["treeview-selection"]
+    treeview_selection.signal_connect "changed" do |selection, _model|
+      iter = selection.selected
+      filename = iter[1]
+      title = iter[0]
+      load_file(filename) if filename
+      headerbar.set_title(title)
     end
 
     window.show_all
+
+    if @options[:name]
+      filename = get_demo_filename_from_name(@options[:name])
+      run_demo_from_file(filename, windows.first)
+    end
+
+    if @options[:autoquit]
+      GLib::Timeout.add_seconds(1) do
+        quit
+      end
+    end
+  end
+
+  def fill_buffers_from(file)
+    start = @info_buffer.get_iter_at(:offset => 0)
+    state = :before_header
+
+    file.each do |line|
+      case state
+      when :before_header
+        state = :in_header if line =~ /^=begin$/
+      when :in_header
+        if line =~ /^=end$/
+          state = :body
+          start = @source_buffer.get_iter_at(:offset => 0)
+        elsif line =~ /^=\s+(.*)$/
+          title = Regexp.last_match(1)
+          title.gsub!(/\s*\(.*\)$/, "") # Delete depend field
+
+          last = start
+
+          @info_buffer.insert(last, title)
+          start = last.clone
+
+          start.backward_chars(title.length)
+          @info_buffer.apply_tag("title", start, last)
+
+          start = last
+        else
+          @info_buffer.insert(start, line)
+        end
+      when :body # Reading program body
+        @source_buffer.insert(start, line)
+      end
+    end
+  end
+
+  def load_file(filename)
+    return if filename == @current_file
+
+    # implement add_data_tab
+
+    @info_buffer.delete(*@info_buffer.bounds)
+
+    @source_buffer.delete(*@source_buffer.bounds)
+
+    file = begin
+             File.open(filename)
+           rescue
+             $stderr.puts "Cannot open: #{$ERROR_INFO}" if $DEBUG
+             return
+           end
+
+    fill_buffers_from(file)
+
+    fontify
+
+    @source_view.buffer = @source_buffer
+    @info_view.buffer = @info_buffer
+
+    @current_file = filename
+  end
+
+  def fontify(start_iter = @source_buffer.start_iter,
+                end_iter = @source_buffer.end_iter)
+    str = @source_buffer.get_text(start_iter, end_iter, true)
+    tokenizer = RubyTokonizer.new
+    tokenizer.tokenize(str, start_iter.offset) do |tag, start, last|
+      @source_buffer.apply_tag(tag.to_s,
+                               @source_buffer.get_iter_at(:offset => start),
+                               @source_buffer.get_iter_at(:offset => last))
+    end
+  end
+
+  class RubyTokonizer
+    RESERVED_WORDS = %w(begin end module class def if then else
+                        while unless do case when require yield)
+    RESERVED_WORDS_PATTERN = Regexp.compile(/(^|\s+)(#{RESERVED_WORDS.collect do |pat| Regexp.quote(pat) end.join("|")})(\s+|$)/)
+
+    def tokenize(str, index = 0)
+      until str.empty?
+        tag = nil
+
+        case str
+        when /".+?"/, /'.+?'/
+          tag = :string
+        when /#.*$/
+          tag = :comment
+        when RESERVED_WORDS_PATTERN
+          tag = :reserved
+        when /[A-Z][A-Za-z0-9_]+/
+          tag = :const
+        end
+
+        if tag
+          tokenize($LAST_MATCH_INFO.pre_match, index) do |*args|
+            yield(*args)
+          end
+          yield(tag, index + $LAST_MATCH_INFO.begin(0), index + $LAST_MATCH_INFO.end(0))
+          index += (str.length - $LAST_MATCH_INFO.post_match.length)
+          str = $LAST_MATCH_INFO.post_match
+        else
+          index += str.length
+          str = ""
+        end
+      end
+    end
   end
 end
 
diff --git a/gtk3/sample/gtk-demo/main.ui b/gtk3/sample/gtk-demo/main.ui
index ff73c7d..03493d7 100644
--- a/gtk3/sample/gtk-demo/main.ui
+++ b/gtk3/sample/gtk-demo/main.ui
@@ -18,14 +18,14 @@
   </menu>
   <object class="GtkTreeStore" id="treestore">
     <columns>
-      <!-- column-name NAME -->
-      <column type="gchararray"/>
+      <!-- column-name NAME
+      <column type="gchararray"/> -->
       <!-- column-name TITLE -->
       <column type="gchararray"/>
       <!-- column-name FILENAME -->
       <column type="gchararray"/>
-      <!-- column-name FUNC -->
-      <column type="gpointer"/>
+      <!-- column-name FUNC
+      <column type="gpointer"/> -->
       <!-- column-name STYLE -->
       <column type="gint"/>
     </columns>
@@ -87,13 +87,13 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn0">
                         <property name="title" translatable="yes">column</property>
                         <child>
-                          <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                          <object class="GtkCellRendererText" id="cellrenderertext0"/>
                           <attributes>
-                            <attribute name="style">4</attribute>
-                            <attribute name="text">1</attribute>
+                            <attribute name="style">2</attribute>
+                            <attribute name="text">0</attribute>
                           </attributes>
                         </child>
                       </object>
@@ -112,7 +112,7 @@
             <property name="enable_popup">1</property>
             <property name="show_border">0</property>
             <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow1">
+              <object class="GtkScrolledWindow" id="info-scrolledwindow">
                 <property name="visible">1</property>
                 <property name="can_focus">1</property>
                 <child>
diff --git a/gtk3/sample/gtk-demo/markup.rb b/gtk3/sample/gtk-demo/markup.rb
new file mode 100644
index 0000000..643826e
--- /dev/null
+++ b/gtk3/sample/gtk-demo/markup.rb
@@ -0,0 +1,46 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Text View/Markup
+
+Gtk::TextBuffer lets you define your own tags that can influence
+text formatting in a variety of ways. In this example, we show
+that Gtk::TextBuffer can load Pango markup and automatically generate
+suitable tags.
+
+=end
+module MarkupDemo
+
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_default_size(450, 450)
+
+    window.set_title("Markup")
+
+    view = Gtk::TextView.new
+    view.set_wrap_mode(:word)
+    view.set_left_margin(10)
+    view.set_right_margin(10)
+
+    sw = Gtk::ScrolledWindow.new(nil, nil)
+    sw.set_policy(:never, :automatic)
+
+    window.add(sw)
+    sw.add(view)
+
+    markup = Gio::Resources.lookup_data("/markup/markup.txt", 0)
+    
+    buffer = view.buffer
+    buffer.insert_markup(buffer.start_iter, markup, -1)
+
+    sw.show_all
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/menus.rb b/gtk3/sample/gtk-demo/menus.rb
index 1d2c968..eaeef1e 100644
--- a/gtk3/sample/gtk-demo/menus.rb
+++ b/gtk3/sample/gtk-demo/menus.rb
@@ -1,172 +1,121 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
-# $Id: menus.rb,v 1.4 2005/02/12 23:02:43 kzys Exp $
 =begin
-= Menus
-
-There are several widgets involved in displaying menus. The
-Gtk::MenuBar widget is a horizontal menu bar, which normally appears
-at the top of an application. The Gtk::Menu widget is the actual menu
-that pops up. Both Gtk::MenuBar and Gtk::Menu are subclasses of
-Gtk::MenuShell; a Gtk::MenuShell contains menu items
-(Gtk::MenuItem). Each menu item contains text and/or images and can
-be selected by the user.
-
-There are several kinds of menu item, including plain Gtk::MenuItem,
-Gtk::CheckMenuItem which can be checked/unchecked, Gtk::RadioMenuItem
-which is a check menu item that's in a mutually exclusive group,
-Gtk::SeparatorMenuItem which is a separator bar, Gtk::TearoffMenuItem
-which allows a Gtk::Menu to be torn off, and Gtk::ImageMenuItem which
-can place a Gtk::Image or other widget next to the menu text.
-
-A Gtk::MenuItem can have a submenu, which is simply a Gtk::Menu to pop
-up when the menu item is selected. Typically, all menu items in a menu bar
-have submenus.
-
-The Gtk::OptionMenu widget is a button that pops up a Gtk::Menu when clicked.
-It's used inside dialogs and such.
-
-Gtk::ItemFactory provides a higher-level interface for creating menu bars
-and menus; while you can construct menus manually, most people don't
-do that. There's a separate demo for Gtk::ItemFactory.
+=  Menus
+
+ There are several widgets involved in displaying menus. The
+ GtkMenuBar widget is a menu bar, which normally appears horizontally
+ at the top of an application, but can also be layed out vertically.
+ The GtkMenu widget is the actual menu that pops up. Both GtkMenuBar
+ and GtkMenu are subclasses of GtkMenuShell; a GtkMenuShell contains
+ menu items (GtkMenuItem). Each menu item contains text and/or images
+ and can be selected by the user.
+
+ There are several kinds of menu item, including plain GtkMenuItem,
+ GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
+ which is a check menu item that's in a mutually exclusive group,
+ GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
+ which allows a GtkMenu to be torn off, and GtkImageMenuItem which
+ can place a GtkImage or other widget next to the menu text.
+
+ A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
+ up when the menu item is selected. Typically, all menu items in a menu bar
+ have submenus.
 =end
-require 'common'
-
-module Demo
-  class Menus < BasicWindow
-    def initialize
-      super('menus')
-      self.border_width = 0
-
-      accel_group = Gtk::AccelGroup.new
-      add_accel_group(accel_group)
-
-
-      box1 = Gtk::VBox.new(false, 0)
-      add(box1)
-
-      menubar = Gtk::MenuBar.new
-      box1.pack_start(menubar, :expand => false, :fill => true, :padding => 0)
-
-      menu = create_menu(2, true)
-
-      menuitem = Gtk::MenuItem.new("test\nline2")
-      menuitem.submenu = menu
-      menubar.append(menuitem)
-      menuitem.show
-
-      menuitem = Gtk::MenuItem.new('foo')
-      menuitem.submenu = create_menu(3, true)
-      menubar.append(menuitem)
-      menuitem.show
-
-      menuitem = Gtk::MenuItem.new('bar')
-      menuitem.submenu = create_menu(4, true)
-      menuitem.right_justified = true
-      menubar.append(menuitem)
-      menuitem.show
-
-      box2 = Gtk::VBox.new(false, 10)
-      box2.border_width = 10
-      box1.pack_start(box2, :expand => true, :fill => true, :padding => 0)
-      box2.show
-
-      menu = create_menu(1, false)
-      # menu.accel_group = accel_group
-
-      menuitem = Gtk::SeparatorMenuItem.new
-      menu.append(menuitem)
-      menuitem.show
-
-      menuitem = Gtk::CheckMenuItem.new('Accelerate Me')
-      menu.append(menuitem)
-      menuitem.show
-      menuitem.add_accelerator('activate',
-                               accel_group,
-                               Gdk::Keyval::KEY_F1,
-                               0,
-                               Gtk::ACCEL_VISIBLE)
-      menuitem = Gtk::CheckMenuItem.new('Accelerator Locked')
-      menu.append(menuitem)
-      menuitem.show
-      menuitem.add_accelerator('activate',
-                               accel_group,
-                               Gdk::Keyval::KEY_F2,
-                               0,
-                               Gtk::ACCEL_VISIBLE | Gtk::ACCEL_LOCKED)
-      menuitem = Gtk::CheckMenuItem.new('Accelerators Frozen')
-      menu.append(menuitem)
-      menuitem.show
-      menuitem.add_accelerator('activate',
-                               accel_group,
-                               Gdk::Keyval::KEY_F2,
-                               0,
-                               Gtk::ACCEL_VISIBLE)
-      menuitem.add_accelerator('activate',
-                               accel_group,
-                               Gdk::Keyval::KEY_F3,
-                               0,
-                               Gtk::ACCEL_VISIBLE)
-
-      optionmenu = Gtk::OptionMenu.new
-      optionmenu.menu = menu
-      optionmenu.history = 3
-      box2.pack_start(optionmenu, :expand => true, :fill => true, :padding => 0)
-      optionmenu.show
-
-      separator = Gtk::HSeparator.new
-      box1.pack_start(separator, :expand => false, :fill => true, :padding => 0)
-      separator.show
-
-      box2 = Gtk::VBox.new(false, 10)
-      box2.border_width = 10
-      box1.pack_start(box2, :expand => false, :fill => true, :padding => 0)
-      box2.show
-
-      button = Gtk::Button.new('close')
-      button.signal_connect('clicked') do
-        quit
+module MenusDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.title = "Menus"
+
+    accel_group = Gtk::AccelGroup.new
+    window.add_accel_group(accel_group)
+    window.border_width = 0
+
+    box = Gtk::Box.new(:horizontal, 0)
+    window.add(box)
+    box.show
+
+    box1 = Gtk::Box.new(:horizontal, 0)
+    box.add(box1)
+    box1.show
+
+    menubar = Gtk::MenuBar.new
+    menubar.expand = true
+    box1.pack_start(menubar, :expand => false, :fill => true, :padding => 0)
+    menubar.show
+
+    menu = create_menu(2)
+
+    menuitem = Gtk::MenuItem.new(:label => "test\nline2")
+    menuitem.submenu = menu
+    menubar.append(menuitem)
+    menuitem.show
+
+    menuitem = Gtk::MenuItem.new(:label => "foo")
+    menuitem.submenu = create_menu(3)
+    menubar.append(menuitem)
+    menuitem.show
+
+    menuitem = Gtk::MenuItem.new(:label => "bar")
+    menuitem.submenu = create_menu(4)
+    menubar.append(menuitem)
+    menuitem.show
+
+    box2 = Gtk::Box.new(:vertical, 10)
+    box2.border_width = 10
+    box1.pack_start(box2, :expand => false, :fill => true, :padding => 0)
+    box2.show
+
+    button = Gtk::Button.new(:label => "Flip")
+    button.signal_connect("clicked") do |_widget|
+      parent = menubar.parent
+      orientation = parent.orientation.to_i
+      parent.orientation = 1 - orientation
+
+      if orientation == Gtk::Orientation::VERTICAL
+        menubar.set_property("pack-direction", Gtk::PackDirection::TTB)
+      else
+        menubar.set_property("pack-direction", Gtk::PackDirection::LTR)
       end
-      box2.pack_start(button, :expand => true, :fill => true, :padding => 0)
-      button.flags = Gtk::Widget::CAN_DEFAULT
-      button.grab_default
-      button.show
     end
+    box2.pack_start(button, :expand => true, :fill => true, :padding => 0)
+    button.show
+    button = Gtk::Button.new(:label => "Close")
+    button.signal_connect("clicked") do |_widget|
+      window.destroy
+    end
+    box2.pack_start(button, :expand => true, :fill => true, :padding => 0)
+    button.can_default = true
+    button.grab_default
+    button.show
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
 
-
-    def create_menu (depth, tearoff)
-      if depth < 1
-        return nil
-      end
-
-      menu = Gtk::Menu.new
-      group = nil
-
-      if tearoff
-        menuitem = Gtk::TearoffMenuItem.new
-        menu.append(menuitem)
-        menuitem.show
-      end
-
-      5.times do |i|
-        buf = sprintf('item %2d - %d', depth, i + 1)
-        menuitem = Gtk::RadioMenuItem.new(buf)
-        group = menuitem.group
-
-        menu.append(menuitem)
-        menuitem.show
-        if i == 3
-          menuitem.sensitive = false
-        end
-
-        if submenu = create_menu(depth - 1, true)
-          menuitem.submenu = submenu
-        end
-      end
-
-      menu.show
-      return menu
+  def self.create_menu(depth)
+    return nil if depth < 1
+
+    menu = Gtk::Menu.new
+    last_item = nil
+    (0..5).each do |i|
+      j = i + 1
+      label = "item #{depth} - #{j}"
+      menu_item = Gtk::RadioMenuItem.new(nil, label)
+      menu_item.join_group(last_item) if last_item
+      last_item = menu_item
+      menu.append(menu_item)
+      menu_item.show
+      menu_item.sensitive = false if i == 3
+      menu_item.submenu = create_menu(depth - 1)
     end
+
+    menu
   end
 end
diff --git a/gtk3/sample/gtk-demo/modelbutton.rb b/gtk3/sample/gtk-demo/modelbutton.rb
new file mode 100644
index 0000000..5662592
--- /dev/null
+++ b/gtk3/sample/gtk-demo/modelbutton.rb
@@ -0,0 +1,47 @@
+# Copyright (c) 2008-2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Model Button
+
+GtkModelButton is a button widget that is designed to be used with
+a GAction as model. The button will adjust its appearance according
+to the kind of action it is connected to.
+
+It is also possible to use GtkModelButton without a GAction. In this
+case, you should set the "role" attribute yourself, and connect to the
+"clicked" signal as you would for any other button.
+
+A common use of GtkModelButton is to implement menu-like content
+in popovers.
+=end
+module ModelbuttonDemo
+  def self.run_demo(main_window)
+    builder = Gtk::Builder.new(:resource => "/modelbutton/modelbutton.ui")
+
+    builder.connect_signals do |name|
+      if name == "tool_clicked"
+        proc do |button|
+          button.active = !button.active?
+        end
+      end
+    end
+    window = builder["window1"]
+    window.screen = main_window.screen
+    actions = Gio::SimpleActionGroup.new
+    actions.add_actions([
+      { :name => "color", :parameter_type => "s", :state => "'red'" },
+      { :name => "chocolate", :state => "true" },
+      { :name => "vanilla", :state => "false" },
+      { :name => "sprinkles" }
+    ])
+
+    window.insert_action_group("win", actions)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/overlay.rb b/gtk3/sample/gtk-demo/overlay.rb
new file mode 100644
index 0000000..8796493
--- /dev/null
+++ b/gtk3/sample/gtk-demo/overlay.rb
@@ -0,0 +1,61 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Overlay/Interactive Overlay
+
+Shows widgets in static positions over a main widget.
+
+The overlayed widgets can be interactive controls such
+as the entry in this example, or just decorative, like
+the big blue label.
+=end
+module OverlayDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_default_size(500, 510)
+    window.set_title("Interactive Overlay")
+    window.screen = main_window.screen
+
+    overlay = Gtk::Overlay.new
+    grid = Gtk::Grid.new
+    overlay.add(grid)
+
+    entry = Gtk::Entry.new
+
+    (0..4).each do |i|
+      (0..4).each do |j|
+        text = "#{5 * j + i}"
+        button = Gtk::Button.new(:label => text)
+        button.set_hexpand(true)
+        button.set_vexpand(true)
+        button.signal_connect "clicked" do |widget|
+          entry.text = widget.label
+        end
+        grid.attach(button, i, j, 1, 1)
+      end
+    end
+
+    vbox = Gtk::Box.new(:vertical, 10)
+    overlay.add_overlay(vbox)
+    overlay.set_overlay_pass_through(vbox, true)
+    vbox.set_halign(:center)
+    vbox.set_valign(:center)
+
+    label = Gtk::Label.new("<span foreground='blue' weight='ultrabold' font='40'>Numbers</span>")
+    label.set_use_markup(true)
+    vbox.pack_start(label, :expand => false, :fill => false, :padding => 8)
+
+    entry.set_placeholder_text("Your Lucky Number")
+    vbox.pack_start(entry, :expand => false, :fill => false, :padding => 8)
+
+    window.add(overlay)
+    overlay.show_all
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/overlay2.rb b/gtk3/sample/gtk-demo/overlay2.rb
new file mode 100644
index 0000000..e3bcf96
--- /dev/null
+++ b/gtk3/sample/gtk-demo/overlay2.rb
@@ -0,0 +1,75 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Overlay/Decorative Overlay
+
+Another example of an overlay with some decorative
+and some interactive controls.
+=end
+module Overlay2Demo
+  def self.run_demo(_main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_default_size(500, 510)
+    window.set_title("Decorative Overlay")
+
+    overlay = Gtk::Overlay.new
+
+    sw = Gtk::ScrolledWindow.new
+    sw.set_policy(:automatic, :automatic)
+
+    text = Gtk::TextView.new
+    buffer = text.buffer
+    buffer.text = "Dear Diary..."
+
+    tag = buffer.create_tag("top-margin", "pixels-above-lines" => 0)
+
+    word_end = buffer.start_iter
+    word_end.forward_word_end
+    buffer.apply_tag(tag, buffer.start_iter, word_end)
+
+    window.add(overlay)
+    overlay.add(sw)
+    sw.add(text)
+
+    image = Gtk::Image.new(:resource => "/overlay2/decor1.png")
+    overlay.add_overlay(image)
+    overlay.set_overlay_pass_through(image, true)
+    image.set_halign(:start)
+    image.set_valign(:start)
+
+    image = Gtk::Image.new(:resource => "/overlay2/decor2.png")
+    overlay.add_overlay(image)
+    overlay.set_overlay_pass_through(image, true)
+    image.set_halign(:end)
+    image.set_valign(:end)
+
+    adjustment = Gtk::Adjustment.new(0, 0, 100, 1, 1, 0)
+    adjustment.signal_connect "value-changed" do |widget|
+      value = widget.value
+      text.set_left_margin(value)
+      tag.set_property("pixels-above-lines", value)
+    end
+
+    scale = Gtk::Scale.new(:horizontal, adjustment)
+    scale.set_draw_value(false)
+    scale.set_size_request(120, -1)
+    scale.set_margin_start(20)
+    scale.set_margin_end(20)
+    scale.set_margin_bottom(20)
+    overlay.add_overlay(scale)
+    scale.set_halign(:start)
+    scale.set_valign(:end)
+    scale.set_tooltip_text("Margin")
+
+    adjustment.value = 100
+    overlay.show_all
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+end
diff --git a/gtk3/sample/gtk-demo/panes.rb b/gtk3/sample/gtk-demo/panes.rb
index 16f01dd..76144c5 100644
--- a/gtk3/sample/gtk-demo/panes.rb
+++ b/gtk3/sample/gtk-demo/panes.rb
@@ -1,156 +1,137 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2016 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
-# $Id: panes.rb,v 1.5 2005/02/12 23:06:07 kzys Exp $
 =begin
-= Paned Widgets
+=  Paned Widgets
 
-The Gtk::HPaned and Gtk::VPaned Widgets divide their content
-area into two panes with a divider in between that the
-user can adjust. A separate child is placed into each
-pane.
+ The GtkPaned Widget divides its content area into two panes
+ with a divider in between that the user can adjust. A separate
+ child is placed into each pane. GtkPaned widgets can be split
+ horizontally or vertically.
 
-There are a number of options that can be set for each pane.
-This test contains both a horizontal (HPaned) and a vertical
-(VPaned) widget, and allows you to adjust the options for
-each side of each widget.
+ There are a number of options that can be set for each pane.
+ This test contains both a horizontal and a vertical GtkPaned
+ widget, and allows you to adjust the options for each side of
+ each widget.
 =end
-require 'common'
-
-module Demo
-  class Panes < BasicWindow
-    def initialize
-      super('Panes')
-      self.border_width = 0
+module PanesDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.title = "Paned Widgets"
+    window.border_width = 0
+
+    vbox = Gtk::Box.new(:vertical, 0)
+    window.add(vbox)
+
+    vpaned = Gtk::Paned.new(:vertical)
+    vbox.pack_start(vpaned, :expand => true, :fill => true, :padding => 0)
+    vpaned.border_width = 5
+
+    hpaned = Gtk::Paned.new(:horizontal)
+    vpaned.add1(hpaned)
+
+    frame = Gtk::Frame.new
+    frame.shadow_type = :in
+    frame.set_size_request(60, 60)
+    hpaned.add1(frame)
+
+    button = Gtk::Button.new(:label => "_Hi there", :use_underline => true)
+    frame.add(button)
+
+    frame = Gtk::Frame.new
+    frame.shadow_type = :in
+    frame.set_size_request(80, 60)
+    hpaned.add2(frame)
+
+    frame = Gtk::Frame.new
+    frame.shadow_type = :in
+    frame.set_size_request(60, 80)
+    vpaned.add2(frame)
+
+    # Now create toggle buttons to control sizing
+    buttons = create_pane_options(hpaned,
+                                  "Horizontal",
+                                  "Left",
+                                  "Right")
+    vbox.pack_start(buttons, :expand => false, :fill => false, :padding => 0)
+    buttons = create_pane_options(hpaned,
+                                  "Vertical",
+                                  "Top",
+                                  "Bottom")
+    vbox.pack_start(buttons, :expand => false, :fill => false, :padding => 0)
+    vbox.show_all
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
 
-      vbox = Gtk::VBox.new(false, 0)
-      add(vbox)
+  def self.create_pane_options(paned, frame_label, label1, label2)
+    child1 = paned.child1
+    child2 = paned.child2
 
-      vpaned = Gtk::VPaned.new
-      vbox.pack_start(vpaned, :expand => true, :fill => true, :padding => 0)
-      vpaned.border_width = 5
+    frame = Gtk::Frame.new(frame_label)
+    frame.border_width = 4
 
-      hpaned = Gtk::HPaned.new
-      vpaned.add1(hpaned)
+    table = Gtk::Grid.new
+    frame.add(table)
 
-      frame = Gtk::Frame.new
-      frame.shadow_type = :in
-      frame.set_size_request(60, 60)
-      hpaned.add1(frame)
+    label = Gtk::Label.new(label1)
+    table.attach(label, 0, 0, 1, 1)
 
-      button = Gtk::Button.new('_Hi there', true)
-      frame.add(button)
+    check_button = Gtk::CheckButton.new("_Resize")
+    check_button.use_underline = true
+    table.attach(check_button, 0, 1, 1, 1)
+    check_button.signal_connect "toggled" do
+      resize = paned.child_get_property(child1, "resize")
+      shrink = paned.child_get_property(child1, "shrink")
 
-      frame = Gtk::Frame.new
-      frame.shadow_type = :in
-      frame.set_size_request(80, 60)
-      hpaned.add2(frame)
+      paned.remove(child1)
+      paned.pack1(child1, :resize => !resize, :shrink => shrink)
+    end
 
-      frame = Gtk::Frame.new
-      frame.shadow_type = :in
-      frame.set_size_request(60, 80)
-      vpaned.add2(frame)
+    check_button = Gtk::CheckButton.new("_Shrink")
+    check_button.use_underline = true
+    table.attach(check_button, 0, 2, 1, 1)
+    check_button.active = true
+    check_button.signal_connect "toggled" do
+      resize = paned.child_get_property(child1, "resize")
+      shrink = paned.child_get_property(child1, "shrink")
 
-      # Now create toggle buttons to control sizing
+      paned.remove(child1)
+      paned.pack1(child1, :resize => resize, :shrink => !shrink)
+    end
 
-      vbox.pack_start(create_pane_options(hpaned,
-                                          'Horizontal', 'Left', 'Right'),
-                      :expand => false, :fill => false, :padding => 0)
+    label = Gtk::Label.new(label2)
+    table.attach(label, 1, 0, 1, 1)
 
-      vbox.pack_start(create_pane_options(vpaned,
-                                          'Vertical', 'Top', 'Bottom'),
-                      :expand => false, :fill => false, :padding => 0)
-    end
+    check_button = Gtk::CheckButton.new("_Resize")
+    check_button.use_underline = true
+    table.attach(check_button, 1, 1, 1, 1)
+    check_button.active = true
+    check_button.signal_connect "toggled" do
+      resize = paned.child_get_property(child2, "resize")
+      shrink = paned.child_get_property(child2, "shrink")
 
-    def create_pane_options(paned, frame_label, label1, label2)
-      frame = Gtk::Frame.new(frame_label)
-      frame.border_width = 4
-
-      table = Gtk::Table.new(3, 2, true)
-      frame.add(table)
-
-      label = Gtk::Label.new(label1)
-      table.attach_defaults(label, 0, 1, 0, 1)
-
-      check_button = Gtk::CheckButton.new('_Resize', true)
-      table.attach_defaults(check_button, 0, 1, 1, 2)
-      check_button.signal_connect('toggled') do
-        toggle_resize(paned.child1)
-      end
-
-      check_button = Gtk::CheckButton.new('_Shrink', true)
-      table.attach_defaults(check_button, 0, 1, 2, 3)
-      check_button.active = true
-      check_button.signal_connect('toggled') do
-        toggle_shrink(paned.child1)
-      end
-
-      label = Gtk::Label.new(label2)
-      table.attach_defaults(label, 1, 2, 0, 1)
-
-      check_button = Gtk::CheckButton.new('_Resize')
-      table.attach_defaults(check_button, 1, 2, 1, 2)
-      check_button.active = true
-      check_button.signal_connect('toggled') do
-        toggle_resize(paned.child2)
-      end
-
-      check_button = Gtk::CheckButton.new('_Shrink')
-      table.attach_defaults(check_button, 1, 2, 2, 3)
-      check_button.active = true
-      check_button.signal_connect('toggled') do
-        toggle_shrink(paned.child2)
-      end
-
-      return frame
+      paned.remove(child2)
+      paned.pack2(child2, :resize => !resize, :shrink => shrink)
     end
 
-    def toggle_resize(child)
-      paned = child.parent
-      is_child1 = (child == paned.child1)
-
-      resize = if is_child1
-                 paned.child1_resize?
-               else
-                 paned.child2_resize?
-               end
-
-      shrink = if is_child1
-                 paned.child1_shrink?
-               else
-                 paned.child2_shrink?
-               end
-
-      child.parent.remove(child)
-      if is_child1
-        paned.pack1(child, !resize, shrink)
-      else
-        paned.pack2(child, !resize, shrink)
-      end
-    end
+    check_button = Gtk::CheckButton.new("_Shrink")
+    check_button.use_underline = true
+    table.attach(check_button, 1, 2, 1, 1)
+    check_button.active = true
+    check_button.signal_connect "toggled" do
+      resize = paned.child_get_property(child2, "resize")
+      shrink = paned.child_get_property(child2, "shrink")
 
-    def toggle_shrink(child)
-      paned = child.parent
-      is_child1 = (child == paned.child1)
-
-      resize = if is_child1
-                 paned.child1_resize?
-               else
-                 paned.child2_resize?
-               end
-
-      shrink = if is_child1
-                 paned.child1_shrink?
-               else
-                 paned.child2_shrink?
-               end
-
-      child.parent.remove(child)
-      if is_child1
-        paned.pack1(child, resize, !shrink)
-      else
-        paned.pack2(child, resize, !shrink)
-      end
+      paned.remove(child2)
+      paned.pack2(child2, :resize => resize, :shrink => !shrink)
     end
+    frame
   end
 end
diff --git a/gtk3/sample/gtk-demo/pickers.rb b/gtk3/sample/gtk-demo/pickers.rb
new file mode 100644
index 0000000..3ed9fa2
--- /dev/null
+++ b/gtk3/sample/gtk-demo/pickers.rb
@@ -0,0 +1,70 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Pickers
+
+These widgets are mainly intended for use in preference dialogs.
+They allow to select colors, fonts, files, directories and applications.
+=end
+module PickersDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Pickers")
+    window.set_border_width(10)
+
+    table = Gtk::Grid.new
+    table.set_row_spacing(3)
+    table.set_column_spacing(10)
+    window.add(table)
+
+    label = Gtk::Label.new("Color:")
+    label.set_halign(:start)
+    label.set_valign(:center)
+    label.set_hexpand(true)
+    picker = Gtk::ColorButton.new
+    table.attach(label, 0, 0, 1, 1)
+    table.attach(picker, 1, 0, 1, 1)
+
+    label = Gtk::Label.new("Font:")
+    label.set_halign(:start)
+    label.set_valign(:center)
+    label.set_hexpand(true)
+    picker = Gtk::FontButton.new
+    table.attach(label, 0, 1, 1, 1)
+    table.attach(picker, 1, 1, 1, 1)
+
+    label = Gtk::Label.new("File:")
+    label.set_halign(:start)
+    label.set_valign(:center)
+    label.set_hexpand(true)
+    picker = Gtk::FileChooserButton.new("Pick a file", :open)
+    table.attach(label, 0, 2, 1, 1)
+    table.attach(picker, 1, 2, 1, 1)
+
+    label = Gtk::Label.new("Folder:")
+    label.set_halign(:start)
+    label.set_valign(:center)
+    label.set_hexpand(true)
+    picker = Gtk::FileChooserButton.new("Pick a folder", :select_folder)
+    table.attach(label, 0, 3, 1, 1)
+    table.attach(picker, 1, 3, 1, 1)
+
+    label = Gtk::Label.new("Mail:")
+    label.set_halign(:start)
+    label.set_valign(:center)
+    label.set_hexpand(true)
+    picker = Gtk::AppChooserButton.new("x-scheme-handler/mailto")
+    picker.set_show_dialog_item(true)
+    table.attach(label, 0, 4, 1, 1)
+    table.attach(picker, 1, 4, 1, 1)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+end
diff --git a/gtk3/sample/gtk-demo/popover.rb b/gtk3/sample/gtk-demo/popover.rb
new file mode 100644
index 0000000..49a83ee
--- /dev/null
+++ b/gtk3/sample/gtk-demo/popover.rb
@@ -0,0 +1,110 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Popovers
+
+ A bubble-like window containing contextual information or options.
+ GtkPopovers can be attached to any widget, and will be displayed
+ within the same window, but on top of all its content.
+=end
+module PopoverDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    box = Gtk::Box.new(:vertical, 24)
+    box.border_width = 24
+    window.add(box)
+
+    widget = Gtk::ToggleButton.new(:label => "Button")
+    toggle_popover = create_popover(widget,
+                                    Gtk::Label.new(
+                                      "This popover does not grab input"
+                                    ),
+                                    :top)
+    toggle_popover.modal = false
+    widget.signal_connect "toggled" do |button|
+      toggle_popover.visible = button.active?
+    end
+
+    box.add(widget)
+
+    widget = CustomEntry.new
+    entry_popover = create_complex_popover(widget, :top)
+    widget.set_icon_from_icon_name(:primary, "edit-find")
+    widget.set_icon_from_icon_name(:secondary, "edit-clear")
+    widget.signal_connect "icon-press" do  |entry, icon_pos, _event|
+      rect = entry.get_icon_area(icon_pos)
+      entry_popover.set_pointing_to(rect)
+      entry_popover.show
+      entry.popover_icon_pos = icon_pos
+    end
+
+    widget.signal_connect "size-allocate" do |entry, _allocation|
+      if entry_popover.visible?
+        popover_pos = entry.popover_icon_pos
+        rect = entry.get_icon_area(popover_pos)
+        entry_popover.set_pointing_to(rect)
+      end
+    end
+
+    box.add(widget)
+
+    widget = Gtk::Calendar.new
+    widget.signal_connect "day-selected" do |calendar|
+      event = Gtk.current_event
+      if event.type == :button_press
+        x, y = event.window.coords_to_parent(event.x,
+                                             event.y)
+        allocation = calendar.allocation
+        rect = Gdk::Rectangle.new(x - allocation.x,
+                                  y - allocation.y,
+                                  1,
+                                  1)
+        cal_popover = create_popover(calendar, CustomEntry.new, :bottom)
+        cal_popover.set_pointing_to(rect)
+        cal_popover.show
+      end
+    end
+
+    box.add(widget)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+
+  def self.create_popover(parent, child, pos)
+    popover = Gtk::Popover.new(parent)
+    popover.position = pos
+    popover.add(child)
+    popover.border_width = 6
+    child.show
+    popover
+  end
+
+  def self.create_complex_popover(parent, pos)
+    builder = Gtk::Builder.new(:resource => "/popover/popover.ui")
+    window = builder["window"]
+    content = window.child
+    content.parent.remove(content)
+    window.destroy
+    popover = create_popover(parent, content, pos)
+    popover.set_size_request(200, -1)
+    popover.vexpand = true
+    popover.margin_start = 10
+    popover.margin_end = 10
+    popover.margin_bottom = 10
+    popover
+  end
+
+  class CustomEntry < Gtk::Entry
+    attr_accessor :popover_icon_pos
+    def initialize
+      super
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/printing.rb b/gtk3/sample/gtk-demo/printing.rb
index ac88e31..1f4d04d 100644
--- a/gtk3/sample/gtk-demo/printing.rb
+++ b/gtk3/sample/gtk-demo/printing.rb
@@ -1,80 +1,41 @@
-# Copyright (c) 2008 Ruby-GNOME2 Project Team
+# Copyright (c) 2016 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
+#
 =begin
-= Printing
+=  Printing/Printing
 
-Gtk::PrintOperation offers a simple API to support printing
-in a cross-platform way.
-=end
-
-require 'common'
-
-module Demo
-  class Printing < BasicWindow
-    Data = Struct.new(:font_size, :lines_per_page, :lines, :n_pages)
-    HEADER_HEIGHT = 10 * 72 / 25.4
-    HEADER_GAP = 3 * 72 / 25.4
-
-    def initialize
-      super('Printing')
-
-      button = Gtk::Button.new("Print...")
-      button.signal_connect("clicked") do
-        begin
-          run_print_operation
-        rescue
-          dialog = Gtk::MessageDialog.new(self, :destroy_with_parent, :error,
-                                          :close, $!.message)
-          dialog.signal_connect("response") do
-            dialog.destroy
-            true
-          end
-          dialog.show
-        end
-        true
-      end
-      add(button)
-    end
-
-    private
-    def run_print_operation
-      operation = Gtk::PrintOperation.new
+ GtkPrintOperation offers a simple API to support printing
+ in a cross-platform way.
 
-      data = Data.new
-      data.font_size = 12.0
-      operation.signal_connect("begin-print") do |_operation, context|
-        on_begin_print(_operation, context, data)
-      end
-      operation.signal_connect("draw-page") do |_operation, context, page_number|
-        on_draw_page(_operation, context, page_number, data)
-      end
-      operation.signal_connect("end-print") do |_operation, context|
-        on_end_print(_operation, context, data)
-      end
+=end
+module PrintingDemo
+  HEADER_HEIGHT = 10 * 72 / 25.4
+  HEADER_GAP = 3 * 72 / 25.4
 
-      operation.use_full_page = false
-      operation.unit = :points
+  def self.run_demo(main_window)
+    print_operation = Gtk::PrintOperation.new
 
-      operation.run(:print_dialog, self)
-    end
+    resource_name = File.expand_path(__FILE__)
+    font_size = 12.0
+    num_pages = 0
+    lines_per_page = 0
+    lines = []
 
-    def on_begin_print(operation, context, data)
+    print_operation.signal_connect "begin-print" do |operation, context|
       height = context.height - HEADER_HEIGHT - HEADER_GAP
-      data.lines_per_page = (height / data.font_size).floor
-      data.lines = File.readlines(__FILE__)
-      data.n_pages = (data.lines.size - 1) / data.lines_per_page + 1
-      operation.set_n_pages(data.n_pages)
+      lines_per_page = (height / font_size).floor
+      File.open(resource_name, "r") do |file|
+        file.each_line do |line|
+          lines << line
+        end
+      end
+      num_pages = lines.size / (lines_per_page + 1)
+      operation.n_pages = num_pages
     end
 
-    def on_draw_page(operation, context, page_number, data)
+    print_operation.signal_connect "draw-page" do |_operation, context, page_nr|
       cr = context.cairo_context
-      draw_header(cr, operation, context, page_number, data)
-      draw_body(cr, operation, context, page_number, data)
-    end
-
-    def draw_header(cr, operation, context, page_number, data)
       width = context.width
-
       cr.rectangle(0, 0, width, HEADER_HEIGHT)
       cr.set_source_rgb(0.8, 0.8, 0.8)
       cr.fill_preserve
@@ -84,45 +45,69 @@ module Demo
       cr.stroke
 
       layout = context.create_pango_layout
-      layout.font_description = "sans 14"
+      desc = Pango::FontDescription.new("sans 14")
+      layout.font_description = desc
 
-      layout.text = File.basename(__FILE__)
+      layout.text = resource_name
       text_width, text_height = layout.pixel_size
 
-      if (text_width > width)
+      if text_width > width
         layout.width = width
         layout.ellipsize = :start
         text_width, text_height = layout.pixel_size
       end
-
-      y = (HEADER_HEIGHT - text_height) / 2
-
-      cr.move_to((width - text_width) / 2, y)
+      cr.move_to((width - text_width) / 2,
+                 (HEADER_HEIGHT - text_height) / 2)
       cr.show_pango_layout(layout)
 
-      layout.text = "#{page_number + 1}/#{data.n_pages}"
+      layout.text = "#{page_nr + 1}/#{num_pages}"
       layout.width = -1
       text_width, text_height = layout.pixel_size
-      cr.move_to(width - text_width - 4, y)
+
+      cr.move_to(width - text_width - 4,
+                 (HEADER_HEIGHT - text_height) / 2)
       cr.show_pango_layout(layout)
-    end
 
-    def draw_body(cr, operation, context, page_number, data)
       layout = context.create_pango_layout
-      description = Pango::FontDescription.new("monosapce")
-      description.size = data.font_size * Pango::SCALE
-      layout.font_description = description
+      desc = Pango::FontDescription.new("monospace")
+      desc.size = font_size * Pango::SCALE
+      layout.font_description = desc
 
       cr.move_to(0, HEADER_HEIGHT + HEADER_GAP)
-      start_line = page_number * data.lines_per_page
-      data.lines[start_line, data.lines_per_page].each do |line|
+      start_line = page_nr * lines_per_page
+
+      lines[start_line, lines_per_page].each do |line|
         layout.text = line
         cr.show_pango_layout(layout)
-        cr.rel_move_to(0, data.font_size)
+        cr.rel_move_to(0, font_size)
       end
     end
 
-    def on_end_print(operation, context, data)
+    print_operation.signal_connect "end-print" do
+      puts "End of print"
+    end
+
+    print_operation.use_full_page = false
+    print_operation.unit = :points
+    print_operation.embed_page_setup = true
+
+    settings = Gtk::PrintSettings.new
+    settings.set(:ouput_basename, "gtk-demo")
+
+    print_operation.print_settings = settings
+
+    begin
+      print_operation.run(:print_dialog, main_window)
+    rescue => error
+      dialog = Gtk::MessageDialog.new(:parent => main_window,
+                                      :flags => :destroy_with_parent,
+                                      :type => :error,
+                                      :buttons => :close,
+                                      :message => error.message)
+      dialog.signal_connect "response" do
+        dialog.destroy
+      end
+      dialog.show
     end
   end
 end
diff --git a/gtk3/sample/gtk-demo/revealer.rb b/gtk3/sample/gtk-demo/revealer.rb
new file mode 100644
index 0000000..ce99fda
--- /dev/null
+++ b/gtk3/sample/gtk-demo/revealer.rb
@@ -0,0 +1,53 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Revealer
+
+GtkRevealer is a container that animates showing and hiding
+of its sole child with nice transitions.
+=end
+module RevealerDemo
+  def self.run_demo(main_window)
+    builder = Gtk::Builder.new(:resource => "/revealer/revealer.ui")
+    builder.connect_signals {}
+
+    timeout = nil
+    count = 0
+
+    window = builder["window"]
+    window.screen = main_window.screen
+    window.signal_connect "destroy" do
+      if timeout
+        GLib::Source.remove(timeout)
+        timeout = nil
+      end
+    end
+
+    if !window.visible?
+      timeout = GLib::Timeout.add(690) do
+        name = "revealer#{count}"
+
+        revealer = builder[name]
+        revealer.set_reveal_child(true)
+
+        revealer.signal_connect "notify::child-revealed" do |widget|
+          revealed = widget.child_revealed?
+          widget.set_reveal_child(!revealed)
+        end
+
+        count += 1
+        if count >= 9
+          timeout = nil
+          false
+        else
+          true
+        end
+      end
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+end
diff --git a/gtk3/sample/gtk-demo/scale.rb b/gtk3/sample/gtk-demo/scale.rb
new file mode 100644
index 0000000..983066f
--- /dev/null
+++ b/gtk3/sample/gtk-demo/scale.rb
@@ -0,0 +1,26 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Scale
+
+GtkScale is a way to select a value from a range.
+Scales can have marks to help pick special values,
+and they can also restrict the values that can be
+chosen.
+=end
+
+module ScaleDemo
+  def self.run_demo(main_window)
+    builder = Gtk::Builder.new(:resource => "/scale/scale.ui")
+    builder.connect_signals {}
+    window = builder["window1"]
+    window.screen = main_window.screen
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/search_entry2.rb b/gtk3/sample/gtk-demo/search_entry2.rb
new file mode 100644
index 0000000..f4a4b18
--- /dev/null
+++ b/gtk3/sample/gtk-demo/search_entry2.rb
@@ -0,0 +1,107 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+=  Entry/Delayed Search Entry
+
+ GtkSearchEntry sets up GtkEntries ready for search. Search entries
+ have their "changed" signal delayed and should be used
+ when the searched operation is slow such as loads of entries
+ to search, or online searches.
+=end
+module SearchEntry2Demo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.title = "Delayed Search Entry"
+    window.transient_for = main_window
+    window.resizable = true
+    window.set_size_request(200, -1)
+
+    vbox = Gtk::Box.new(:vertical, 0)
+    window.add(vbox)
+    vbox.border_width = 0
+
+    entry = Gtk::SearchEntry.new
+    container = Gtk::Box.new(:horizontal, 10)
+    container.halign = :center
+    container.pack_start(entry, :expand => false, :fill => false, :padding => 0)
+
+    searchbar = Gtk::SearchBar.new
+    searchbar.connect_entry(entry)
+    searchbar.show_close_button = false
+    searchbar.add(container)
+    vbox.pack_start(searchbar, :expand => false, :fill => false, :padding => 0)
+
+    # Hook the search bar to key presses
+    window.signal_connect("key-press-event") do |_widget, event|
+      searchbar.handle_event(event)
+    end
+
+    # Help
+    label = Gtk::Label.new("Start Typing to search")
+    vbox.pack_start(label, :expand => true, :fill => true, :padding => 0)
+
+    # Toggle button
+    button = Gtk::ToggleButton.new(:label => "Search")
+    button.bind_property("active", searchbar, "search-mode-enabled", :bidirectional)
+    vbox.pack_start(button, :expand => true, :fill => true, :padding => 0)
+
+    # Result
+    hbox = Gtk::Box.new(:horizontal, 10)
+    vbox.pack_start(hbox, :expand => true, :fill => true, :padding => 0)
+    hbox.border_width = 0
+
+    label = Gtk::Label.new("Result:")
+    label.xalign = 0.0
+    label.margin_start = 6
+    hbox.pack_start(label, :expand => true, :fill => true, :padding => 0)
+
+    label = Gtk::Label.new("")
+    hbox.pack_start(label, :expand => true, :fill => true, :padding => 0)
+
+    entry.signal_connect("search-changed") do |widget|
+      puts "search changed: #{widget.text || ''}"
+      label.text = widget.text || ""
+    end
+
+    entry.signal_connect("changed") do |_widget|
+      puts "changed: #{label.text || ''}"
+    end
+
+    hbox = Gtk::Box.new(:horizontal, 10)
+    vbox.pack_start(hbox, :expand => true, :fill => true, :padding => 0)
+    hbox.border_width = 0
+
+    label = Gtk::Label.new("Signal:")
+    label.xalign = 0.0
+    label.margin_start = 6
+    hbox.pack_start(label, :expand => true, :fill => true, :padding => 0)
+
+    label = Gtk::Label.new("")
+    hbox.pack_start(label, :expand => true, :fill => true, :padding => 0)
+
+    entry.signal_connect("search-changed") do |widget|
+      puts "search changed: #{widget.text || ''}"
+      label.text = widget.text || ""
+    end
+
+    entry.signal_connect("next-match") do |_widget|
+      label.text = "next-match"
+    end
+
+    entry.signal_connect("previous-match") do |_widget|
+      label.text = "previous-match"
+    end
+
+    entry.signal_connect("stop-search") do |_widget|
+      label.text = "stop-search"
+    end
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
+  end
+end
diff --git a/gtk3/sample/gtk-demo/sidebar.rb b/gtk3/sample/gtk-demo/sidebar.rb
new file mode 100644
index 0000000..45f7185
--- /dev/null
+++ b/gtk3/sample/gtk-demo/sidebar.rb
@@ -0,0 +1,68 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Stack Sidebar
+
+GtkStackSidebar provides an automatic sidebar widget to control
+navigation of a GtkStack object. This widget automatically updates it
+content based on what is presently available in the GtkStack object,
+and using the "title" child property to set the display labels.
+=end
+module SidebarDemo
+  def self.run_demo(_main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_resizable(true)
+    window.set_size_request(500, 350)
+
+    header = Gtk::HeaderBar.new
+    header.set_show_close_button(true)
+    window.set_titlebar(header)
+    window.set_title("Stack Sidebar")
+
+    box = Gtk::Box.new(:horizontal, 0)
+    sidebar = Gtk::StackSidebar.new
+    box.pack_start(sidebar, :expand => false, :fill => false, :padding => 0)
+
+    stack = Gtk::Stack.new
+    stack.set_transition_type(:slide_up_down)
+    sidebar.set_stack(stack)
+
+    widget = Gtk::Separator.new(:vertical)
+    box.pack_start(widget, :expand => false, :fill => false, :padding => 0)
+
+    box.pack_start(stack, :expand => true, :fill => true, :padding => 0)
+
+    pages = ["Welcome to GTK+",
+             "GtkStackSidebar Widget",
+             "Automatic navigation",
+             "Consistent appearance",
+             "Scrolling",
+             "Page 6",
+             "Page 7",
+             "Page 8",
+             "Page 9"
+            ]
+
+    pages.each_with_index do |page_string, i|
+      child = nil
+      if i == 0
+        child = Gtk::Image.new(:icon_name => "help-about", :size => :menu)
+        child.set_pixel_size(256)
+      else
+        child = Gtk::Label.new(page_string)
+      end
+
+      stack.add_named(child, page_string)
+      stack.child_set_property(child, "title", page_string)
+    end
+
+    window.add(box)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/sizegroup.rb b/gtk3/sample/gtk-demo/sizegroup.rb
index 436e998..8feca70 100644
--- a/gtk3/sample/gtk-demo/sizegroup.rb
+++ b/gtk3/sample/gtk-demo/sizegroup.rb
@@ -1,118 +1,106 @@
-# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
-# $Id: sizegroup.rb,v 1.5 2005/02/12 23:02:43 kzys Exp $
 =begin
-= Size Groups
-
-Gtk::SizeGroup provides a mechanism for grouping a number of
-widgets together so they all request the same amount of space.
-This is typically useful when you want a column of widgets to
-have the same size, but you can't use a Gtk::Table widget.
-
-Note that size groups only affect the amount of space requested,
-not the size that the widgets finally receive. If you want the
-widgets in a Gtk::SizeGroup to actually be the same size, you need
-to pack them in such a way that they get the size they request
-and not more. For example, if you are packing your widgets
-into a table, you would not include the Gtk::FILL flag.
+=  Size Groups
+
+ GtkSizeGroup provides a mechanism for grouping a number of
+ widgets together so they all request the same amount of space.
+ This is typically useful when you want a column of widgets to
+ have the same size, but you can't use a GtkTable widget.
+
+ Note that size groups only affect the amount of space requested,
+ not the size that the widgets finally receive. If you want the
+ widgets in a GtkSizeGroup to actually be the same size, you need
+ to pack them in such a way that they get the size they request
+ and not more. For example, if you are packing your widgets
+ into a table, you would not include the GTK_FILL flag.
 =end
-require 'common'
-
-module Demo
-  class SizeGroup < Gtk::Dialog
-    def initialize
-      super('GtkSizeGroup', nil, 0,
-            [Gtk::Stock::CLOSE, Gtk::ResponseType::NONE])
-
-      color_options = %w(Red Green Blue)
-      dash_options = %w(Solid Dashed Dotted)
-      end_options = %w(Square Round Arrow)
-
-      set_resizable(false)
-
-      signal_connect('response') do
-        destroy
-      end
-
-      vbox = Gtk::VBox.new(false, 5)
-      self.vbox.pack_start(vbox, :expand => true, :fill => true, :padding => 0)
-      vbox.set_border_width(5)
-
-      size_group = Gtk::SizeGroup.new(Gtk::SizeGroup::HORIZONTAL)
-
-      ## Create one frame holding color options
-      frame = Gtk::Frame.new('Color Options')
-      vbox.pack_start(frame, :expand => true, :fill => true, :padding => 0)
-
-      table = Gtk::Table.new(2, 2, false)
-      table.set_border_width(5)
-      table.set_row_spacings(5)
-      table.set_column_spacings(10)
-      frame.add(table)
-
-      add_row(table, 0, size_group, '_Foreground', color_options)
-      add_row(table, 1, size_group, '_Background', color_options)
-
-      ## And another frame holding line style options
-      frame = Gtk::Frame.new('Line Options')
-      vbox.pack_start(frame, :expand => false, :fill => false, :padding => 0)
-
-      table = Gtk::Table.new(2, 2, false)
-      table.set_border_width(5)
-      table.set_row_spacings(5)
-      table.set_column_spacings(10)
-      frame.add(table)
-
-      add_row(table, 0, size_group, '_Dashing', dash_options)
-      add_row(table, 1, size_group, '_Line ends', end_options)
-
-      # And a check button to turn grouping on and off
-      check_button = Gtk::CheckButton.new('_Enable grouping', true)
-      vbox.pack_start(check_button, :expand => false, :fill => false, :padding => 0)
-
-      check_button.set_active(true)
-      check_button.signal_connect('toggled', size_group) do |check_button, size_group|
-        new_mode = if check_button.active?
-                     Gtk::SizeGroup::HORIZONTAL
-                   else
-                     Gtk::SizeGroup::VERTICAL
-                   end
-        size_group.set_mode(new_mode)
+module SizegroupDemo
+  def self.run_demo(main_window)
+    color_options = %w(Red Green Blue)
+    dash_options = %w(Solid Dashed Dotted)
+    end_options = %w(Square Round Double Arrow)
+
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Size Groups")
+    window.set_resizable(false)
+
+    vbox = Gtk::Box.new(:vertical, 5)
+    window.add(vbox)
+    vbox.set_border_width(5)
+
+    size_group = Gtk::SizeGroup.new(:horizontal)
+
+    # Create one frame holding color options
+    frame = Gtk::Frame.new("Color Options")
+    vbox.pack_start(frame, :expand => true, :fill => true, :padding => 0)
+
+    table = Gtk::Grid.new
+    table.set_border_width(5)
+    table.set_row_spacing(5)
+    table.set_column_spacing(10)
+    frame.add(table)
+
+    add_row(table, 0, size_group, "_Foreground", color_options)
+    add_row(table, 1, size_group, "_Background", color_options)
+
+    # And another frame holding line style options
+    frame = Gtk::Frame.new("Line options")
+    vbox.pack_start(frame, :expand => false, :fill => false, :padding => 0)
+
+    table = Gtk::Grid.new
+    table.set_border_width(5)
+    table.set_row_spacing(5)
+    table.set_column_spacing(10)
+    frame.add(table)
+
+    add_row(table, 0, size_group, "_Dashing", dash_options)
+    add_row(table, 1, size_group, "_Line ends", end_options)
+
+    # And a check button to turn grouping on and off
+    check_button = Gtk::CheckButton.new("_Enable grouping")
+    check_button.set_use_underline(true)
+    vbox.pack_start(check_button, :expand => false, :fill => false, :padding => 0)
+
+    check_button.signal_connect("toggled") do |widget|
+      if widget.active?
+        size_group.set_mode(:horizontal)
+      else
+        size_group.set_mode(:none)
       end
     end
 
-    def add_row(table, row, size_group, label_text, options)
-      label = Gtk::Label.new(label_text, true)
-      label.set_alignment(0, 1)
-      table.attach(label,
-                   0, 1,                    row, row + 1,
-                   Gtk::EXPAND | Gtk::FILL, 0,
-                   0,                       0)
-
-      option_menu = create_option_menu(options)
-      label.set_mnemonic_widget(option_menu)
-      size_group.add_widget(option_menu)
-      table.attach(option_menu,
-                   1, 2,                    row, row + 1,
-                   0,                       0,
-                   0,                       0)
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
+    window
+  end
 
-    def create_option_menu(strings)
-      menu = Gtk::Menu.new
-
-      strings.each do |str|
-        menu_item = Gtk::MenuItem.new(str)
-        menu_item.show
-
-        menu.append(menu_item)
-      end
-
-      option_menu = Gtk::OptionMenu.new
-      option_menu.set_menu(menu)
+  def self.add_row(table, row, size_group, label_text, options)
+    label = Gtk::Label.new(label_text, :use_underline => true)
+    label.set_halign(:start)
+    label.set_valign(:baseline)
+    label.set_hexpand(true)
+    table.attach(label, 0, row, 1, 1)
+
+    combo_box = create_combo_box(options)
+    label.set_mnemonic_widget(combo_box)
+    combo_box.set_halign(:end)
+    combo_box.set_valign(:baseline)
+    size_group.add_widget(combo_box)
+    table.attach(combo_box, 1, row, 1, 1)
+  end
 
-      return option_menu
+  def self.create_combo_box(options)
+    combo_box = Gtk::ComboBoxText.new
+    options.each do |o|
+      combo_box.append_text(o)
     end
+    combo_box.set_active(0)
+    combo_box
   end
 end
diff --git a/gtk3/sample/gtk-demo/spinner.rb b/gtk3/sample/gtk-demo/spinner.rb
index 1a4452e..be0077c 100644
--- a/gtk3/sample/gtk-demo/spinner.rb
+++ b/gtk3/sample/gtk-demo/spinner.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2013 Ruby-GNOME2 Project Team
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
 # This program is licenced under the same licence as Ruby-GNOME2.
 #
 =begin
@@ -6,54 +6,57 @@
 
 GtkSpinner allows to show that background activity is on-going.
 =end
-require 'common'
-
-module Demo
-  class Spinner < Gtk::Dialog
-    def initialize
-      super(:title => 'Spinner',
-            :parent => nil,
-            :flags => nil,
-            :buttons => [[:close, :none]])
-
-      signal_connect(:response) {self.destroy}
-      signal_connect(:destroy) {self.destroy}
-
-      self.resizable = false
-
-      vbox = Gtk::Box.new :vertical, 5
-
-      self.content_area.pack_start vbox, :expand => true, :fill => true, :padding => 0
-      vbox.border_width = 5
-
-      # Sensitive
-      hbox = Gtk::Box.new :horizontal, 5
-      @spinner_sensitive = Gtk::Spinner.new
-      hbox.add @spinner_sensitive
-      hbox.add Gtk::Entry.new
-      vbox.add hbox
-
-      # Disabled
-      hbox = Gtk::Box.new :horizontal, 5
-      @spinner_insensitive = Gtk::Spinner.new
-      hbox.add @spinner_insensitive
-      hbox.add Gtk::Entry.new
-      vbox.add hbox
-      hbox.sensitive = false
-
-      button = Gtk::Button.new :stock_id => :media_play
-      button.signal_connect(:clicked) do
-        @spinner_sensitive.start
-        @spinner_insensitive.start
-      end
-      vbox.add button
-
-      button = Gtk::Button.new :stock_id => :media_stop
-      button.signal_connect(:clicked) do
-        @spinner_sensitive.stop
-        @spinner_insensitive.stop
-      end
-      vbox.add button
+module SpinnerDemo
+  def self.run_demo(main_window)
+    window = Gtk::Dialog.new(:title => "Spinner",
+                             :parent => main_window,
+                             :flags => nil,
+                             :buttons => [[:close, :none]])
+
+    window.set_resizable(false)
+    window.signal_connect("response") { window.destroy }
+    window.signal_connect("destroy") { window.destroy }
+
+    content_area = window.content_area
+
+    vbox = Gtk::Box.new(:vertical, 5)
+    content_area.pack_start(vbox, :expand => true, :fill => true, :padding => 0)
+    vbox.set_border_width(5)
+
+    # Sensitive
+    hbox = Gtk::Box.new(:horizontal, 5)
+    spinner_sensitive = Gtk::Spinner.new
+    hbox.add(spinner_sensitive)
+    hbox.add(Gtk::Entry.new)
+    vbox.add(hbox)
+
+    # Disabled
+    hbox = Gtk::Box.new(:horizontal, 5)
+    spinner_insensitive = Gtk::Spinner.new
+    hbox.add(spinner_insensitive)
+    hbox.add(Gtk::Entry.new)
+    vbox.add(hbox)
+    hbox.set_sensitive(false)
+
+    button = Gtk::Button.new(:stock_id => :media_play)
+    button.signal_connect "clicked" do
+      spinner_sensitive.start
+      spinner_insensitive.start
     end
+    vbox.add(button)
+
+    button = Gtk::Button.new(:stock_id => :media_stop)
+    button.signal_connect "clicked" do
+      spinner_sensitive.stop
+      spinner_insensitive.stop
+    end
+    vbox.add(button)
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+    window
   end
-end
\ No newline at end of file
+end
diff --git a/gtk3/sample/gtk-demo/stack.rb b/gtk3/sample/gtk-demo/stack.rb
new file mode 100644
index 0000000..e1bfcb5
--- /dev/null
+++ b/gtk3/sample/gtk-demo/stack.rb
@@ -0,0 +1,28 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Stack
+
+GtkStack is a container that shows a single child at a time,
+with nice transitions when the visible child changes.
+
+GtkStackSwitcher adds buttons to control which child is visible.
+=end
+
+module StackDemo
+  def self.run_demo(main_window)
+    builder = Gtk::Builder.new(:resource => "/stack/stack.ui")
+    builder.connect_signals {}
+    window = builder["window1"]
+    window.screen = main_window.screen
+
+    window.signal_connect("destroy") { window.destroyed(window) }
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/test_mod.rb b/gtk3/sample/gtk-demo/test_mod.rb
new file mode 100644
index 0000000..c707231
--- /dev/null
+++ b/gtk3/sample/gtk-demo/test_mod.rb
@@ -0,0 +1,22 @@
+# Copyright (c) 2008-2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= test demo 
+
+Demonstrates the demo interface.
+=end
+module TestModDemo
+
+  def self.run_demo(window)
+    puts "ok"
+    window = Gtk::Window.new(:toplevel)
+    window.add(Gtk::Label.new("This is a test"))
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+  end
+end
diff --git a/gtk3/sample/gtk-demo/textmask.rb b/gtk3/sample/gtk-demo/textmask.rb
new file mode 100644
index 0000000..353ed10
--- /dev/null
+++ b/gtk3/sample/gtk-demo/textmask.rb
@@ -0,0 +1,61 @@
+# Copyright (c) 2015 Ruby-GNOME2 Project Team
+# This program is licenced under the same licence as Ruby-GNOME2.
+#
+=begin
+= Pango/Text Mask
+
+This demo shows how to use PangoCairo to draw text with more than
+just a single color.
+=end
+module TextmaskDemo
+  def self.run_demo(_main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.set_resizable(true)
+    window.set_size_request(400, 200)
+    window.set_title("Text Mask")
+
+    da = Gtk::DrawingArea.new
+
+    window.add(da)
+
+    da.signal_connect "draw" do |_widget, cr|
+      cr.save
+
+      layout = da.create_pango_layout("Pango power!\nPango power!\nPango power!")
+      desc = Pango::FontDescription.new("sans bold 34")
+      layout.font_description = desc
+
+      cr.move_to(30, 20)
+      cr.pango_layout_path(layout)
+
+      pattern = Cairo::LinearPattern.new(0.0, 0.0,
+                                         da.allocated_width,
+                                         da.allocated_height)
+
+      pattern.add_color_stop(0.0, 1.0, 0.0, 0.0)
+      pattern.add_color_stop(0.2, 1.0, 0.0, 0.0)
+      pattern.add_color_stop(0.3, 1.0, 1.0, 0.0)
+      pattern.add_color_stop(0.4, 0.0, 1.0, 0.0)
+      pattern.add_color_stop(0.6, 0.0, 1.0, 1.0)
+      pattern.add_color_stop(0.7, 0.0, 0.0, 1.0)
+      pattern.add_color_stop(0.8, 1.0, 0.0, 1.0)
+      pattern.add_color_stop(1.0, 1.0, 0.0, 1.0)
+      cr.set_source(pattern)
+      cr.fill_preserve
+
+      cr.set_source_rgb(0.0, 0.0, 0.0)
+      cr.set_line_width(0.5)
+      cr.stroke
+      cr.restore
+      true
+    end
+
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
+    end
+
+    window
+  end
+end
diff --git a/gtk3/sample/gtk-demo/theming_style_classes.rb b/gtk3/sample/gtk-demo/theming_style_classes.rb
index c955bf4..27dfbbf 100644
--- a/gtk3/sample/gtk-demo/theming_style_classes.rb
+++ b/gtk3/sample/gtk-demo/theming_style_classes.rb
@@ -4,7 +4,7 @@
 # This is licensed under the terms of the GNU Lesser General Public
 # License, version 2.1 or (at your option) later.
 #
-# Copyright (C) 2014  Ruby-GNOME2 Project Team
+# Copyright (C) 2014-2015  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -30,19 +30,23 @@ of GTK+ are used for certain effects: primary toolbars,
 inline toolbars and linked buttons.
 =end
 
-require "common"
+module ThemingStyleClassesDemo
+  def self.run_demo(main_window)
+    window = Gtk::Window.new(:toplevel)
+    window.screen = main_window.screen
+    window.set_title("Style Classes")
+    window.set_border_width(12)
 
-module Demo
-  class ThemingStyleClasses < BasicWindow
-    def initialize
-      super("Style Claases")
-      self.border_width = 12
+    builder = Gtk::Builder.new(:resource => "/theming_style_classes/theming.ui")
+    grid = builder["grid"]
+    grid.show_all
+    window.add(grid)
 
-      builder = Gtk::Builder.new
-      builder.add("theming.ui")
-
-      grid = builder.get_object("grid")
-      add(grid)
+    if !window.visible?
+      window.show_all
+    else
+      window.destroy
     end
+    window
   end
 end
diff --git a/gtk3/sample/misc/app-menu.ui b/gtk3/sample/misc/app-menu.ui
new file mode 100644
index 0000000..6c28696
--- /dev/null
+++ b/gtk3/sample/misc/app-menu.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="appmenu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_About</attribute>
+        <attribute name="action">app.about</attribute>
+      </item>
+    </section>
+
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Quit</attribute>
+        <attribute name="action">app.quit</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/gtk3/sample/misc/button-menu.ui b/gtk3/sample/misc/button-menu.ui
new file mode 100644
index 0000000..4b84a87
--- /dev/null
+++ b/gtk3/sample/misc/button-menu.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="buttonmenu">
+    <section>
+      <attribute name="display-hint">horizontal-buttons</attribute>
+      <item>
+        <attribute name="label">Copy</attribute>
+        <attribute name="action">app.copy</attribute>
+        <attribute name="verb-icon">edit-copy-symbolic</attribute>
+      </item>
+      <item>
+        <attribute name="label">Paste</attribute>
+        <attribute name="action">app.paste</attribute>
+        <attribute name="verb-icon">edit-paste-symbolic</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/gtk3/sample/misc/icons-theme-viewer.rb b/gtk3/sample/misc/icons-theme-viewer.rb
new file mode 100644
index 0000000..d509108
--- /dev/null
+++ b/gtk3/sample/misc/icons-theme-viewer.rb
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+=begin
+  icons-theme-viewer.rb - Ruby/GTK sample script.
+
+  Copyright (c) 2016 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+=end
+
+require "gtk3"
+
+def fill_model(icons)
+  model = Gtk::ListStore.new(String, Gdk::Pixbuf)
+  icons.each do |icon|
+    pixbuf = Gtk::IconTheme.default.load_icon(icon, 32, 0)
+    iter = model.append
+    iter[0] = icon
+    iter[1] = pixbuf
+  end
+  model
+end
+
+def gen_icon_view(pattern, context = nil)
+  icon_theme = Gtk::IconTheme.default
+  icons = icon_theme.icons(context).grep(/#{pattern}/)
+  model = fill_model(icons)
+  icon_view = Gtk::IconView.new(:model => model)
+  icon_view.text_column = 0
+  icon_view.pixbuf_column = 1
+  icon_view
+end
+
+window = Gtk::Window.new("View all your icons")
+window.set_default_size(700, 700)
+window.signal_connect("delete-event") { Gtk.main_quit }
+
+icon_view = gen_icon_view("application")
+sw = Gtk::ScrolledWindow.new(nil, nil)
+sw.add(icon_view)
+
+entry = Gtk::Entry.new
+entry.buffer.text = "application"
+entry.tooltip_text = "Use a pattern to filter icons"
+entry.set_icon_from_icon_name(:secondary, "edit-clear")
+entry.set_icon_tooltip_text(:secondary, "Reset pattern")
+
+entry.signal_connect "icon-release" do |widget, position|
+  widget.buffer.text = "" if position == :secondary
+end
+
+entry.signal_connect "activate" do |widget|
+  sw.remove(icon_view)
+  pattern = widget.buffer.text
+  icon_view = gen_icon_view(pattern)
+  sw.add(icon_view)
+  window.show_all
+end
+
+box = Gtk::Box.new(:vertical, 0)
+box.pack_start(entry)
+box.pack_start(sw, :expand => true, :fill => true)
+
+window.add(box)
+window.show_all
+
+Gtk.main
diff --git a/gtk3/sample/misc/menu.rb b/gtk3/sample/misc/menu.rb
index dfaf438..e611040 100644
--- a/gtk3/sample/misc/menu.rb
+++ b/gtk3/sample/misc/menu.rb
@@ -64,15 +64,15 @@ menubar = Gtk::MenuBar.new
 box1.pack_start(menubar, :expand => false, :fill => true, :padding => 0)
 
 menu = create_menu(2)
-menuitem = Gtk::MenuItem.new("test\nline2")
+menuitem = Gtk::MenuItem.new(:label => "test\nline2")
 menuitem.set_submenu(menu)
 menubar.append(menuitem)
 
-menuitem = Gtk::MenuItem.new("foo")
+menuitem = Gtk::MenuItem.new(:label => "foo")
 menuitem.set_submenu(create_menu(3))
 menubar.append(menuitem)
 
-menuitem = Gtk::MenuItem.new("bar")
+menuitem = Gtk::MenuItem.new(:label => "bar")
 menuitem.set_submenu(create_menu(4))
 menubar.append(menuitem)
 
diff --git a/gtk3/sample/misc/menus_from_resources.gresource.xml b/gtk3/sample/misc/menus_from_resources.gresource.xml
new file mode 100644
index 0000000..57aef60
--- /dev/null
+++ b/gtk3/sample/misc/menus_from_resources.gresource.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gtk/menus_from_resources">
+    <file preprocess="xml-stripblanks">app-menu.ui</file>
+    <file preprocess="xml-stripblanks">toolbar-menu.ui</file>
+    <file preprocess="xml-stripblanks">button-menu.ui</file>
+  </gresource>
+</gresources>
diff --git a/gtk3/sample/misc/menus_from_resources.rb b/gtk3/sample/misc/menus_from_resources.rb
new file mode 100644
index 0000000..a15eb35
--- /dev/null
+++ b/gtk3/sample/misc/menus_from_resources.rb
@@ -0,0 +1,91 @@
+#!/usr/bin/env ruby
+=begin
+  menus_from_resources.rb - Ruby/GTK sample script.
+
+  Copyright (c) 2016 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+=end
+
+require "gtk3"
+require "fileutils"
+
+PATH = File.expand_path(File.dirname(__FILE__))
+
+gresource_bin = "#{PATH}/menus_from_resources.gresource"
+gresource_xml = "#{PATH}/menus_from_resources.gresource.xml"
+
+system("glib-compile-resources",
+       "--target", gresource_bin,
+       "--sourcedir", File.dirname(gresource_xml),
+       gresource_xml)
+
+at_exit do
+  FileUtils.rm_f(gresource_bin)
+end
+
+resource = Gio::Resource.load(gresource_bin)
+Gio::Resources.register(resource)
+
+application_instance = Gtk::Application.new("org.gtk.menus_from_resources",
+                                            :non_unique)
+
+application_instance.signal_connect "startup" do |application|
+  %w(about preferences quit copy paste open save close).each do |label|
+    action = Gio::SimpleAction.new(label)
+    action.signal_connect("activate") do |_action, _parameter|
+      puts label
+    end
+    application.add_action(action)
+  end
+  builder = Gtk::Builder.new(:resource => "/org/gtk/menus_from_resources/app-menu.ui")
+  app_menu = builder["appmenu"]
+  application.set_app_menu(app_menu)
+end
+
+application_instance.signal_connect "activate" do |application|
+  window = Gtk::ApplicationWindow.new(application)
+  window.set_default_size(200, 200)
+  window.border_width = 20
+
+  toolbar = Gtk::Toolbar.new
+  toolbar.style = :both
+  toolbutton = Gtk::ToolButton.new(:label => "Open a Menu", :stock_id => Gtk::Stock::OPEN)
+  toolbutton.signal_connect "clicked" do |widget|
+    builder = Gtk::Builder.new(:resource => "/org/gtk/menus_from_resources/toolbar-menu.ui")
+    menu = Gtk::Menu.new(builder["toolbarmenu"])
+    # This method is important, it links the menu to the
+    # Gio::Actions of the Gtk::Application throught one of
+    # its children
+    menu.attach_to_widget(widget)
+
+    menu.show_all
+    event = Gtk.current_event
+    menu.popup(nil, nil, event.button, event.time)
+  end
+  toolbar.insert(toolbutton, 0)
+
+  button = Gtk::Button.new(:label => "Click me")
+  button.signal_connect "clicked" do |widget|
+    builder = Gtk::Builder.new(:resource => "/org/gtk/menus_from_resources/button-menu.ui")
+    menu = Gtk::Popover.new(widget, builder["buttonmenu"])
+    event = Gtk.current_event
+    x, y = event.window.coords_to_parent(event.x,
+                                         event.y)
+    rect = Gdk::Rectangle.new(x - widget.allocation.x,
+                              y - widget.allocation.y,
+                              1,
+                              1)
+    menu.set_pointing_to(rect)
+    menu.show
+  end
+  hbox = Gtk::Box.new(:vertical, 0)
+
+  hbox.pack_start(toolbar, :expand => false, :fill => false)
+  hbox.pack_start(button, :expand => true, :fill => true)
+  window.add(hbox)
+
+  window.show_all
+  window.present
+end
+
+application_instance.run
diff --git a/gtk3/sample/misc/statusicon.rb b/gtk3/sample/misc/statusicon.rb
index ac09232..fcf4fef 100755
--- a/gtk3/sample/misc/statusicon.rb
+++ b/gtk3/sample/misc/statusicon.rb
@@ -28,7 +28,7 @@ class StatusIconSample < Gtk::StatusIcon
     signal_connect("popup-menu") do |w, button, activate_time|
       menu = Gtk::Menu.new
 
-      menuitem = Gtk::MenuItem.new("Quit")
+      menuitem = Gtk::MenuItem.new(:label => "Quit")
       menuitem.signal_connect("activate") do
         set_visible(false)
         Gtk.main_quit
diff --git a/gtk3/sample/misc/toolbar-menu.ui b/gtk3/sample/misc/toolbar-menu.ui
new file mode 100644
index 0000000..9487973
--- /dev/null
+++ b/gtk3/sample/misc/toolbar-menu.ui
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="toolbarmenu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Open</attribute>
+        <attribute name="action">app.open</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Save</attribute>
+        <attribute name="action">app.save</attribute>
+      </item>
+    </section>
+
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Close</attribute>
+        <attribute name="action">app.close</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/gtk3/sample/misc/treestore.rb b/gtk3/sample/misc/treestore.rb
new file mode 100644
index 0000000..ae69739
--- /dev/null
+++ b/gtk3/sample/misc/treestore.rb
@@ -0,0 +1,63 @@
+#!/usr/bin/env ruby
+=begin
+  treestore.rb - Gtk::TreeStore sample
+
+  Copyright (c) 2016 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+  Based on  https://developer.gnome.org/gtk3/stable/TreeWidget.html
+=end
+
+require "gtk3"
+
+TITLE_COLUMN = 0
+AUTHOR_COLUMN = 1
+CHECKED_COLUMN = 2
+
+model = Gtk::TreeStore.new(String, String, TrueClass)
+iter = model.append(nil)
+iter[TITLE_COLUMN] = "The Principle of Reason"
+iter[AUTHOR_COLUMN] = "Martin Heidegger"
+iter[CHECKED_COLUMN] = false
+
+iter = model.append(nil)
+iter.set_values(["The Art of Computer Programming", "Donald E. Knuth", true])
+
+# append child
+child_iter = model.append(iter)
+child_iter[TITLE_COLUMN] = "Volume 1: Fundamental Algorithms"
+
+# append another child
+child_iter = model.append(iter)
+child_iter.set_value(TITLE_COLUMN, "Volume 2: Seminumerical Algorithms")
+child_iter.set_value(CHECKED_COLUMN, true)
+
+# append another child
+child_iter = model.append(iter)
+child_iter.set_values(["Volume 3: Sorting and Searching",
+                       "Donald E. Knuth",
+                       true])
+
+def treeview_widget_of(model)
+  treeview = Gtk::TreeView.new(model)
+  treeview.append_column(Gtk::TreeViewColumn.new("Title",
+                                                 Gtk::CellRendererText.new,
+                                                 :text => TITLE_COLUMN))
+  treeview.append_column(Gtk::TreeViewColumn.new("Author",
+                                                 Gtk::CellRendererText.new,
+                                                 :text => AUTHOR_COLUMN))
+  treeview.append_column(Gtk::TreeViewColumn.new("Author",
+                                                 Gtk::CellRendererToggle.new,
+                                                 :active => CHECKED_COLUMN))
+  treeview
+end
+
+def display_model(model)
+  win = Gtk::Window.new(:toplevel)
+  win.title = "Simple Gtk::TreeStore"
+  win.add(treeview_widget_of(model))
+  win.show_all
+  win.signal_connect("destroy") { Gtk.main_quit }
+  Gtk.main
+end
+
+display_model(model)
diff --git a/gtk3/sample/tutorial/README.md b/gtk3/sample/tutorial/README.md
index ee7bbd6..0b9422c 100644
--- a/gtk3/sample/tutorial/README.md
+++ b/gtk3/sample/tutorial/README.md
@@ -32,6 +32,28 @@ Gtk.main
 ```
 This tutorial will mainly be focused on the use of Gtk::Application, which is the best way to create an application.
 
+## Table of Contents
+*  [Basics](#basics)
+*  [Packing](#packing)
+*  [Building user interfaces](#building-user-interfaces)
+*  [Building Applications](#building-applications)
+  *  [A trivial application](#a trivial application)
+  *  [Populating the window](#populating-the-window)
+    *  [Link a template to a custom class widget](#link-a-template-to-a-custom-class-widget)
+    *  [Load a resource file](#load-a-resource-file)
+  *  [Opening files](#opening-file)
+  *  [An application menu](#an-application-menu)
+    *  [Adding the menu interface](#adding-the-menu-interface)
+    *  [Linking menu items to actions](#linking-menu-items-to-actions)
+    *  [Add accelerators for an action](#add-accelerators-for-an-action)
+  *  [A preference dialog](#a-preference-dialog)
+    *  [Define and store settings for an application with gschemas](#define-and-store-settings-for-an-application-with-gschemas)
+    *  [Configure the settings with a dialog window](#configure-the-settings-with-a-dialog-window)
+  *  [Adding a search bar](#adding-a-search-bar)
+  *  [Adding a sidebar](#adding-a-sidebar)
+  *  [Properties](#properties)
+  *  [Header Bar](#header-bar)
+
 ## Basics
 https://developer.gnome.org/gtk3/stable/gtk-getting-started.html#id-1.2.3.5
 
@@ -54,7 +76,10 @@ puts app.run
 
 ```
 When creating a Gtk::Application you need to pick an application identifier (a name) and input to `Gtk::Application#new` as parameter. For this example *org.gtk.example* is used but for choosing an identifier for your application see this [guide](https://wiki.gnome.org/HowDoI/ChooseApplicationID).
-Lastly `Gtk::Application#new` takes a `Gio::ApplicationFlags` constants as input for your application, if your application would have special needs (those constants can be replaced by theirs respective symbol ie. `Gio::ApplicationFlags::NONE` == `:flags_none`).
+
+Lastly `Gtk::Application#new` takes a `Gio::ApplicationFlags` constants as input for your application, if your application would have special needs (those constants can be replaced by theirs respective symbol ie. `Gio::ApplicationFlags::NONE` == `:flags_none`). You must know that `GApplication` ignores arguments passed to `g_application_run()` on the Windows systems. It always uses command line arguments even when we pass an empty array to g_application_run().
+
+If you plan to create a cross-platform application, it is recommanded to use the `:handles_command_line` flags and the *command-line* signal. (reference : https://github.com/ruby-gnome2/ruby-gnome2/issues/721 ).
 
 Next we add instructions for the "activate" event of the `Gtk::Application` instance we created. The activate signal will be sent when your application is launched with the method `Gtk::Application#run` on the line below. This method also takes as arguments a ruby array of string. This allows GTK+ to parse specific command line arguments that control the behavior of GTK+ itself. The parsed arguments will be removed from the array, leaving the unrecognized ones for your application to parse.
 
@@ -516,7 +541,6 @@ stack.add_titled(scrolled, basename, basename)
 
 In this line, given that `self` is `ExampleAppWindow` the usage of `stack` is a call to the method we have created previously. So here we add a tab with a `Gtk::ScrolledWindow` in the `Gtk::Stack` widget of our template and we display the file content.
 
-
 ### An application menu
 https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.8
 
@@ -599,10 +623,10 @@ application.add_action(action)
 application.set_accels_for_action("app.quit", quit_accels)
 ```
 
-### A preferences dialog
+### A preference dialog
 https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.9
 
-### Define and store settings for an application with gschemas
+#### Define and store settings for an application with gschemas
 *    exampleapp5/exampleapp.rb
 
 A typical application will have a some preferences that should be remembered from one run to the next. Even for our simple example application, we may want to change the font that is used for the content.
@@ -824,7 +848,7 @@ def open(file)
 end
 ``` 
 
-## Adding a search bar
+### Adding a search bar
 https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.10
 
 *    exampleapp7/exampleapp.rb
@@ -934,5 +958,343 @@ In this part of code, the use of the method `set_connect_func` will allow us to
 
     <signal name="search-changed" handler="search_text_changed"/>
 
-Those pieces together mean that for the signal *search-changed* of the `Gtk::SearchEntry`, trigger the private method of `ExampleAppWindow` that is called `search_text_changed`.
+Those pieces together mean that the signal *search-changed* of the `Gtk::SearchEntry`, trigger the private method of `ExampleAppWindow` that is called `search_text_changed`.
+
+### Adding a sidebar
+https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.11
+
+*    exampleapp8/exampleapp.rb
+
+As another piece of functionality, we are adding a sidebar, which demonstrates `Gtk::MenuButton`, `Gtk::Revealer` and Gtk::ListBox`.
+
+window.ui :
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.8 -->
+  <template class="ExampleAppWindow" parent="GtkApplicationWindow">
+    <property name="title" translatable="yes">Example Application</property>
+    <property name="default-width">600</property>
+    <property name="default-height">400</property>
+    <child>
+      <object class="GtkBox" id="content_box">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHeaderBar" id="header">
+            <property name="visible">True</property>
+            <child type="title">
+              <object class="GtkStackSwitcher" id="tabs">
+                <property name="visible">True</property>
+                <property name="margin">6</property>
+                <property name="stack">stack</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="search">
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <style>
+                  <class name="image-button"/>
+                </style>
+                <child>
+                  <object class="GtkImage" id="search-icon">
+                    <property name="visible">True</property>
+                    <property name="icon-name">edit-find-symbolic</property>
+                    <property name="icon-size">1</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkMenuButton" id="gears">
+                <property name="visible">True</property>
+                <property name="direction">none</property>
+                <property name="use-popover">True</property>
+                <style>
+                  <class name="image-button"/>
+                </style>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkSearchBar" id="searchbar">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkSearchEntry" id="searchentry">
+                <signal name="search-changed" handler="search_text_changed"/>
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="hbox">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkRevealer" id="sidebar">
+                <property name="visible">True</property>
+                <property name="transition-type">slide-right</property>
+                <child>
+                 <object class="GtkScrolledWindow" id="sidebar-sw">
+                   <property name="visible">True</property>
+                   <property name="hscrollbar-policy">never</property>
+                   <property name="vscrollbar-policy">automatic</property>
+                   <child>
+                     <object class="GtkListBox" id="words">
+                       <property name="visible">True</property>
+                       <property name="selection-mode">none</property>
+                     </object>
+                   </child>
+                 </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkStack" id="stack">
+                <signal name="notify::visible-child" handler="visible_child_changed"/>
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
+```
+
+The code to populate the sidebar with buttons for the words found in each file is a little too involved to go into here. But we'll look at the code to add the gears menu.
+As expected by now, the gears menu is specified in a GtkBuilder ui file.
+
+gears-menu.ui
+
+```xml
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Words</attribute>
+        <attribute name="action">win.show-words</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
+```
+To connect the menuitem to the show-words setting, we use a `Gio::SimpleAction` corresponding to the given `Gio::Settings` key.
+
+```ruby
+class ExampleAppWindow < Gtk::ApplicationWindow
+  # some code
+  def initialize(application)
+    super(:application => application)
+    @settings = Gio::Settings.new("org.gtk.exampleapp")
+    @settings.bind("transition",
+                   stack,
+                   "transition-type",
+                   Gio::SettingsBindFlags::DEFAULT)
+    search.bind_property("active", searchbar, "search-mode-enabled", :bidirectional)
+    @settings.bind("show-words",
+                   sidebar,
+                   "reveal-child",
+                   Gio::SettingsBindFlags::DEFAULT)
+    sidebar.signal_connect "notify::reveal-child" do |_sidebar, _gparamspec|
+      update_words(self)
+    end
+    builder = Gtk::Builder.new(:resource => "/org/gtk/exampleapp/gears-menu.ui")
+    menu = builder.get_object("menu")
+    gears.set_menu_model(menu)
+    action = @settings.create_action("show-words")
+    add_action(action)
+  end
+
+  # some code
+end
+```
+
+### Properties
+
+https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.12
+
+Widgets and other objects have many useful properties.
+
+Here we show some ways to use them in new and flexible ways, by wrapping them in actions with `Gio::PropertyAction` or by binding them with `Gio::Binding`.
+To set this up, we add two labels to the header bar in our window template, named *lines_label* and *lines*, and bind them to struct members in the private struct, as we've seen a couple of times by now.
+We add a new "Lines" menu item to the gears menu, which triggers the show-lines action:
+
+```xml
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Words</attribute>
+        <attribute name="action">win.show-words</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Lines</attribute>
+        <attribute name="action">win.show-lines</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
+```
+
+To make this menu item do something, we create a property action for the visible property of the lines label, and add it to the actions of the window. The effect of this is that the visibility of the label gets toggled every time the action is activated.
+Since we want both labels to appear and disappear together, we bind the visible property of the lines_label widget to the same property of the lines widget.
+
+*    exampleapp9/exampleapp.rb
+
+```ruby
+# ...
+class ExampleAppWindow < Gtk::ApplicationWindow
+# ...
+  def initialize(application)
+    super(:application => application)
+# ...
+    action = Gio::PropertyAction.new("show-lines", lines, "visible")
+    add_action(action)
+    lines.bind_property("visible", lines_label, "visible", :default)
+  end
+```
+We also need a function that counts the lines of the currently active tab, and updates the lines label. See the full source if you are interested in the details.
+
+### Header Bar
+
+https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.13
+
+Our application already uses a `Gtk::HeaderBar`, but so far it still gets a 'normal' window titlebar on top of that. This is a bit redundant, and we will now tell GTK+ to use the header bar as replacement for the titlebar. To do so, we move it around to be a direct child of the window, and set its type to be titlebar.
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.8 -->
+  <template class="ExampleAppWindow" parent="GtkApplicationWindow">
+    <property name="title" translatable="yes">Example Application</property>
+    <property name="default-width">600</property>
+    <property name="default-height">400</property>
+        <child type="titlebar">
+          <object class="GtkHeaderBar" id="header">
+            <property name="visible">True</property>
+            <property name="show-close-button">True</property>
+            <child>
+              <object class="GtkLabel" id="lines_label">
+                <property name="visible">False</property>
+                <property name="label" translatable="yes">Lines:</property>
+              </object>
+              <packing>
+                <property name="pack-type">start</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="lines">
+                <property name="visible">False</property>
+              </object>
+              <packing>
+                <property name="pack-type">start</property>
+              </packing>
+            </child>
+            <child type="title">
+              <object class="GtkStackSwitcher" id="tabs">
+                <property name="visible">True</property>
+                <property name="margin">6</property>
+                <property name="stack">stack</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="search">
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <style>
+                  <class name="image-button"/>
+                </style>
+                <child>
+                  <object class="GtkImage" id="search-icon">
+                    <property name="visible">True</property>
+                    <property name="icon-name">edit-find-symbolic</property>
+                    <property name="icon-size">1</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkMenuButton" id="gears">
+                <property name="visible">True</property>
+                <property name="direction">none</property>
+                <property name="use-popover">True</property>
+                <style>
+                  <class name="image-button"/>
+                </style>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+    <child>
+      <object class="GtkBox" id="content_box">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkSearchBar" id="searchbar">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkSearchEntry" id="searchentry">
+                <signal name="search-changed" handler="search_text_changed"/>
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="hbox">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkRevealer" id="sidebar">
+                <property name="visible">True</property>
+                <property name="transition-type">slide-right</property>
+                <child>
+                 <object class="GtkScrolledWindow" id="sidebar-sw">
+                   <property name="visible">True</property>
+                   <property name="hscrollbar-policy">never</property>
+                   <property name="vscrollbar-policy">automatic</property>
+                   <child>
+                     <object class="GtkListBox" id="words">
+                       <property name="visible">True</property>
+                       <property name="selection-mode">none</property>
+                     </object>
+                   </child>
+                 </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkStack" id="stack">
+                <signal name="notify::visible-child" handler="visible_child_changed"/>
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
+```
 
+A small extra bonus of using a header bar is that we get a fallback application menu for free. 
diff --git a/gtk3/test/test-gtk-box.rb b/gtk3/test/test-gtk-box.rb
index 1b909d2..8934730 100644
--- a/gtk3/test/test-gtk-box.rb
+++ b/gtk3/test/test-gtk-box.rb
@@ -25,4 +25,17 @@ class TestGtkBox < Test::Unit::TestCase
       end
     end
   end
+
+  test "set_child_packing" do
+    box = Gtk::Box.new(:vertical)
+    child = Gtk::EventBox.new
+    box.add(child)
+    box.set_child_packing(child,
+                          :expand => false,
+                          :fill   => true,
+                          :padding => 100,
+                          :pack_type => :end)
+    assert_equal([false, true, 100, Gtk::PackType::END],
+                 box.query_child_packing(child))
+  end
 end
diff --git a/gtk3/test/test-gtk-builder.rb b/gtk3/test/test-gtk-builder.rb
index 45a6f25..b12c4fd 100644
--- a/gtk3/test/test-gtk-builder.rb
+++ b/gtk3/test/test-gtk-builder.rb
@@ -26,7 +26,7 @@ class TestGtkBuilder < Test::Unit::TestCase
     end
 
     test "resource" do
-      only_gtk_version(3, 10, 0)
+      only_gtk_version(3, 12, 0)
       register_resource(fixture_path("simple_window.gresource")) do
         resource_path = "/simple_window/simple_window.ui"
         builder = Gtk::Builder.new(:resource => resource_path)
diff --git a/gtk3/test/test-gtk-clipboard.rb b/gtk3/test/test-gtk-clipboard.rb
new file mode 100644
index 0000000..4906a2b
--- /dev/null
+++ b/gtk3/test/test-gtk-clipboard.rb
@@ -0,0 +1,124 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project Team
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGtkClipboard < Test::Unit::TestCase
+  include GtkTestUtils
+
+  def setup
+    @widget = Gtk::Invisible.new
+    @clipboard = @widget.get_clipboard(Gdk::Selection::CLIPBOARD)
+  end
+
+  def teardown
+    @clipboard.clear
+  end
+
+  test "#request_contents" do
+    loop = GLib::MainLoop.new
+    received_text = nil
+    utf8_string = Gdk::Atom.intern("UTF8_STRING")
+    @clipboard.request_contents(utf8_string) do |_clipboard, _selection_data|
+      compound_text = Gdk::Atom.intern("COMPOUND_TEXT")
+      @clipboard.request_contents(compound_text) do |_clipboard, _selection_data|
+        target_string = Gdk::Selection::TARGET_STRING
+        @clipboard.request_contents(target_string) do |_clipboard, selection_data|
+          received_text = selection_data.text
+          loop.quit
+        end
+      end
+    end
+    @clipboard.text = "hello"
+    loop.run
+
+    assert_equal("hello", received_text)
+  end
+
+  test "#request_text" do
+    loop = GLib::MainLoop.new
+    received_text = nil
+    @clipboard.request_text do |_clipboard, text|
+      received_text = text
+      loop.quit
+    end
+    @clipboard.text = "hello"
+    loop.run
+
+    assert_equal("hello", received_text)
+  end
+
+  test "#request_image" do
+    loop = GLib::MainLoop.new
+    received_image = nil
+    @clipboard.request_image do |_clipboard, image|
+      received_image = image
+      loop.quit
+    end
+    image = Gdk::Pixbuf.new(fixture_path("gnome-logo-icon.png"))
+    @clipboard.image = image
+    loop.run
+
+    assert_equal([image.width, image.height],
+                 [received_image.width, received_image.height])
+  end
+
+  test "#request_targets" do
+    loop = GLib::MainLoop.new
+    received_atoms = nil
+    @clipboard.request_targets do |_clipboard, atoms|
+      received_atoms = atoms
+      loop.quit
+    end
+    loop.run
+
+    assert_nil(received_atoms)
+  end
+
+  test "#request_rich_text" do
+    loop = GLib::MainLoop.new
+    received_format = nil
+    received_text = nil
+    table = Gtk::TextTagTable.new
+    buffer = Gtk::TextBuffer.new(table)
+    buffer.register_deserialize_tagset(nil)
+    @clipboard.request_rich_text(buffer) do |_clipboard, format, text|
+      received_format = format
+      received_text = text
+      loop.quit
+    end
+    loop.run
+
+    assert_equal([
+                   "application/x-gtk-text-buffer-rich-text",
+                   nil,
+                 ],
+                 [
+                   received_format.name,
+                   received_text,
+                 ])
+  end
+
+  test "#request_uris" do
+    loop = GLib::MainLoop.new
+    received_uris = nil
+    @clipboard.request_uris do |_clipboard, uris|
+      received_uris = uris
+      loop.quit
+    end
+    loop.run
+
+    assert_nil(received_uris)
+  end
+end
diff --git a/gtk3/test/test-gtk-container.rb b/gtk3/test/test-gtk-container.rb
index c89ae09..fb926f5 100644
--- a/gtk3/test/test-gtk-container.rb
+++ b/gtk3/test/test-gtk-container.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2013-2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2013-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -82,7 +82,7 @@ class TestGtkContainer < Test::Unit::TestCase
 
   class TestTemplate < self
     def test_resource
-      only_gtk_version(3, 10, 0)
+      only_gtk_version(3, 12, 0)
 
       Dir.mktmpdir do |dir|
         Dir.chdir(dir) do
@@ -151,7 +151,7 @@ class TestGtkContainer < Test::Unit::TestCase
     end
 
     def test_data
-      only_gtk_version(3, 10, 0)
+      only_gtk_version(3, 12, 0)
 
       class_name = "MyWindowData"
       label_value = "My Label"
diff --git a/gtk3/test/test-gtk-box.rb b/gtk3/test/test-gtk-entry-buffer.rb
similarity index 75%
copy from gtk3/test/test-gtk-box.rb
copy to gtk3/test/test-gtk-entry-buffer.rb
index 1b909d2..2b6278f 100644
--- a/gtk3/test/test-gtk-box.rb
+++ b/gtk3/test/test-gtk-entry-buffer.rb
@@ -14,15 +14,19 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-class TestGtkBox < Test::Unit::TestCase
+
+class TestGtkEntryBuffer < Test::Unit::TestCase
   include GtkTestUtils
 
   sub_test_case ".new" do
-    sub_test_case "spacing" do
-      def test_nil
-        box = Gtk::Box.new(:vertical, nil)
-        assert_equal(0, box.spacing)
-      end
+    test "no argument" do
+      buffer = Gtk::EntryBuffer.new
+      assert_equal("", buffer.text)
+    end
+
+    test "string" do
+      buffer = Gtk::EntryBuffer.new("some text")
+      assert_equal("some text", buffer.text)
     end
   end
 end
diff --git a/gtk3/test/test-gtk-list-store.rb b/gtk3/test/test-gtk-list-store.rb
index d77db08..11c6648 100644
--- a/gtk3/test/test-gtk-list-store.rb
+++ b/gtk3/test/test-gtk-list-store.rb
@@ -99,21 +99,39 @@ class TestGtkListStore < Test::Unit::TestCase
       assert_equal(0, @store.get_iter("1")[0])
     end
 
-    test "#insert" do
-      iter = @store.append
-      @store.set_values(iter, [0, '1'])
-      assert_equal("0", iter.path.to_s)
+    sub_test_case "#insert" do
+      test "no values" do
+        iter = @store.append
+        @store.set_values(iter, [0, '1'])
+        assert_equal("0", iter.path.to_s)
 
-      iter = @store.append
-      @store.set_values(iter, [2, '3'])
-      assert_equal("1", iter.path.to_s)
+        iter = @store.append
+        @store.set_values(iter, [2, '3'])
+        assert_equal("1", iter.path.to_s)
 
-      iter = @store.insert(1)
-      @store.set_values(iter, [4, '5'])
+        iter = @store.insert(1)
+        @store.set_values(iter, [4, '5'])
 
-      assert_equal(0, @store.get_iter("0")[0])
-      assert_equal(4, @store.get_iter("1")[0])
-      assert_equal(2, @store.get_iter("2")[0])
+        assert_equal(0, @store.get_iter("0")[0])
+        assert_equal(4, @store.get_iter("1")[0])
+        assert_equal(2, @store.get_iter("2")[0])
+      end
+
+      test "values" do
+        iter = @store.append
+        @store.set_values(iter, [0, '1'])
+        assert_equal("0", iter.path.to_s)
+
+        iter = @store.append
+        @store.set_values(iter, [2, '3'])
+        assert_equal("1", iter.path.to_s)
+
+        iter = @store.insert(1, [4, '5'])
+
+        assert_equal(0, @store.get_iter("0")[0])
+        assert_equal(4, @store.get_iter("1")[0])
+        assert_equal(2, @store.get_iter("2")[0])
+      end
     end
 
     test "#insert_before" do
diff --git a/gtk3/test/test-gtk-box.rb b/gtk3/test/test-gtk-menu.rb
similarity index 63%
copy from gtk3/test/test-gtk-box.rb
copy to gtk3/test/test-gtk-menu.rb
index 1b909d2..90c245b 100644
--- a/gtk3/test/test-gtk-box.rb
+++ b/gtk3/test/test-gtk-menu.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2015 Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -7,22 +7,26 @@
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 # Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-class TestGtkBox < Test::Unit::TestCase
+class TestGtkMenu < Test::Unit::TestCase
   include GtkTestUtils
 
-  sub_test_case ".new" do
-    sub_test_case "spacing" do
-      def test_nil
-        box = Gtk::Box.new(:vertical, nil)
-        assert_equal(0, box.spacing)
-      end
+  def setup
+    @menu = Gtk::Menu.new
+  end
+
+  def test_popup
+    only_gtk_version(3, 6, 0)
+    @menu.popup(nil, nil,
+                Gdk::BUTTON_PRIMARY,
+                Gtk.current_event_time) do |menu, x, y|
+      [x, y, true]
     end
   end
 end
diff --git a/gtk3/test/test-gtk-tree-iter.rb b/gtk3/test/test-gtk-tree-iter.rb
index 4b79c56..2b1cba6 100644
--- a/gtk3/test/test-gtk-tree-iter.rb
+++ b/gtk3/test/test-gtk-tree-iter.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -19,8 +19,8 @@ class TestGtkTreeIter < Test::Unit::TestCase
   include GtkTestUtils
 
   def setup
-    @model = Gtk::ListStore.new(String)
-    @iter = @model.append
+    @model = Gtk::TreeStore.new(String)
+    @iter = @model.append(nil)
   end
 
   def test_path
@@ -52,7 +52,7 @@ class TestGtkTreeIter < Test::Unit::TestCase
   end
 
   test "#next!" do
-    next_iter = @model.append
+    next_iter = @model.append(nil)
     @iter.values = ["first"]
     next_iter.values = ["second"]
     assert_equal("first", @iter[0])
@@ -61,6 +61,62 @@ class TestGtkTreeIter < Test::Unit::TestCase
   end
 
   test "#parent" do
-    # TODO
+    @iter.values = ["Dad"]
+    child_iter = @model.append(@iter)
+    child_iter.values = ["First son"]
+    assert_equal(@iter, child_iter.parent)
+  end
+
+  sub_test_case "#has_child?" do
+    test "false" do
+      @iter.values = ["Dad"]
+      assert do
+        not @iter.has_child?
+      end
+    end
+
+    test "true" do
+      @iter.values = ["Dad"]
+      child_iter = @model.append(@iter)
+      child_iter.values = ["First son"]
+      assert(@iter.has_child?)
+    end
+  end
+
+  def test_n_children
+    @iter.values = ["Dad"]
+    child_iter = @model.append(@iter)
+    child_iter.values = ["First son"]
+    child_iter = @model.append(@iter)
+    child_iter.values = ["First daughter"]
+    assert_equal(2, @iter.n_children)
+  end
+
+  def test_nth_children
+    @iter.values = ["Dad"]
+    first_child_iter = @model.append(@iter)
+    first_child_iter.values = ["First son"]
+    second_child_iter = @model.append(@iter)
+    second_child_iter.values = ["First daughter"]
+    assert_equal(first_child_iter, @iter.nth_child(0))
+    assert_equal(second_child_iter, @iter.nth_child(1))
+  end
+
+  def test_first_child
+    @iter.values = ["Dad"]
+    first_child_iter = @model.append(@iter)
+    first_child_iter.values = ["First son"]
+    second_child_iter = @model.append(@iter)
+    second_child_iter.values = ["First daughter"]
+    assert_equal(first_child_iter, @iter.first_child)
+  end
+
+  def test_children
+    @iter.values = ["Dad"]
+    first_child_iter = @model.append(@iter)
+    first_child_iter.values = ["First son"]
+    second_child_iter = @model.append(@iter)
+    second_child_iter.values = ["First daughter"]
+    assert_equal(first_child_iter, @iter.children)
   end
 end
diff --git a/gtk3/test/test-gtk-tree-path.rb b/gtk3/test/test-gtk-tree-path.rb
index 1abedb5..489133b 100644
--- a/gtk3/test/test-gtk-tree-path.rb
+++ b/gtk3/test/test-gtk-tree-path.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2010-2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2010-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -35,7 +35,32 @@ class TestGtkTreePath < Test::Unit::TestCase
                  [indices, depth])
   end
 
+  def test_down!
+    path = tree_path("10:4:5")
+    path.down!
+    assert_equal("10:4:5:0", path.to_s)
+  end
+
+  def test_up!
+    path = tree_path("10:4:5")
+    path.up!
+    assert_equal("10:4", path.to_s)
+  end
+
+  def test_next!
+    path = tree_path("10:4:5")
+    path.next!
+    assert_equal("10:4:6", path.to_s)
+  end
+
+  def test_prev!
+    path = tree_path("10:4:5")
+    path.prev!
+    assert_equal("10:4:4", path.to_s)
+  end
+
   private
+
   def tree_path(path)
     Gtk::TreePath.new(path)
   end
diff --git a/gtk3/test/test-gtk-box.rb b/gtk3/test/test-gtk-tree-sortable.rb
similarity index 64%
copy from gtk3/test/test-gtk-box.rb
copy to gtk3/test/test-gtk-tree-sortable.rb
index 1b909d2..426489a 100644
--- a/gtk3/test/test-gtk-box.rb
+++ b/gtk3/test/test-gtk-tree-sortable.rb
@@ -14,15 +14,22 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-class TestGtkBox < Test::Unit::TestCase
+class TestGtkTreeSortable < Test::Unit::TestCase
   include GtkTestUtils
 
-  sub_test_case ".new" do
-    sub_test_case "spacing" do
-      def test_nil
-        box = Gtk::Box.new(:vertical, nil)
-        assert_equal(0, box.spacing)
-      end
+  def setup
+    @model = Gtk::ListStore.new(String)
+  end
+
+  test "#set_sort_func" do
+    @model.append[0] = "abc"
+    @model.append[0] = "xyz"
+    @model.append[0] = "efg"
+    @model.set_sort_column_id(0, :ascending)
+    @model.set_sort_func(0) do |_model, iter1, iter2|
+      iter2[0] <=> iter1[0]
     end
+    assert_equal(["xyz", "efg", "abc"],
+                 @model.collect {|_model, _path, iter| iter[0]})
   end
 end
diff --git a/gtk3/test/test-gtk-box.rb b/gtk3/test/test-gtk-tree-store.rb
similarity index 65%
copy from gtk3/test/test-gtk-box.rb
copy to gtk3/test/test-gtk-tree-store.rb
index 1b909d2..4ce3144 100644
--- a/gtk3/test/test-gtk-box.rb
+++ b/gtk3/test/test-gtk-tree-store.rb
@@ -14,15 +14,21 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-class TestGtkBox < Test::Unit::TestCase
+class TestGtkTreeStore < Test::Unit::TestCase
   include GtkTestUtils
 
-  sub_test_case ".new" do
-    sub_test_case "spacing" do
-      def test_nil
-        box = Gtk::Box.new(:vertical, nil)
-        assert_equal(0, box.spacing)
-      end
+  sub_test_case "#insert" do
+    test "no values" do
+      store = Gtk::TreeStore.new(String)
+      iter = store.insert(nil, -1)
+      iter[0] = "xxx"
+      assert_equal("xxx", iter[0])
+    end
+
+    test "with values" do
+      store = Gtk::TreeStore.new(String, Integer)
+      iter = store.insert(nil, -1, {0 => "xxx", 1 => 29})
+      assert_equal(["xxx", 29], [iter[0], iter[1]])
     end
   end
 end
diff --git a/gtk3/test/test-gtk-widget.rb b/gtk3/test/test-gtk-widget.rb
index 7049ff6..9200428 100644
--- a/gtk3/test/test-gtk-widget.rb
+++ b/gtk3/test/test-gtk-widget.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2008-2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2008-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -137,6 +137,37 @@ class TestGtkWidget < Test::Unit::TestCase
     end
   end
 
+  sub_test_case "#translate_coordinates" do
+    test "no common toplevel" do
+      win1 = Gtk::Window.new(:toplevel)
+      label1 = Gtk::Label.new("one")
+      win1.add(label1)
+      win1.show_all
+
+      win2 = Gtk::Window.new(:toplevel)
+      label2 = Gtk::Label.new("one")
+      win2.add(label2)
+      win2.show_all
+
+      assert_nil(label1.translate_coordinates(label2, 0, 0))
+    end
+
+    test "not realized" do
+      win1 = Gtk::Window.new(:toplevel)
+      label1 = Gtk::Label.new("one")
+      win1.add(label1)
+      assert_nil(label1.translate_coordinates(win1, 0, 0))
+    end
+
+    test "translated" do
+      win1 = Gtk::Window.new(:toplevel)
+      label1 = Gtk::Label.new("one")
+      win1.add(label1)
+      win1.show_all
+      assert_equal([0, 0], label1.translate_coordinates(win1, 0, 0))
+    end
+  end
+
   sub_test_case "predicates" do
     test "#in_destruction?" do
       entry = Gtk::Entry.new
@@ -155,7 +186,7 @@ class TestGtkWidget < Test::Unit::TestCase
 
   sub_test_case ".bind_template_child" do
     setup do
-      only_gtk_version(3, 10, 0)
+      only_gtk_version(3, 12, 0)
       @resource_data = File.read(fixture_path("simple_window.ui"))
     end
 
diff --git a/gtksourceview2/ext/gtksourceview2/extconf.rb b/gtksourceview2/ext/gtksourceview2/extconf.rb
index e1be9e9..d64479e 100644
--- a/gtksourceview2/ext/gtksourceview2/extconf.rb
+++ b/gtksourceview2/ext/gtksourceview2/extconf.rb
@@ -46,6 +46,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlnux => "libgtksourceview-devel",
                                    :debian => "libgtksourceview2.0-dev",
                                    :redhat => "gtksourceview2-devel",
                                    :homebrew => "gtksourceview",
diff --git a/gtksourceview3-no-gi/ext/gtksourceview3/extconf.rb b/gtksourceview3-no-gi/ext/gtksourceview3/extconf.rb
index 6103279..7e178a9 100644
--- a/gtksourceview3-no-gi/ext/gtksourceview3/extconf.rb
+++ b/gtksourceview3-no-gi/ext/gtksourceview3/extconf.rb
@@ -46,6 +46,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libgtksourceview3-devel",
                                    :debian => "libgtksourceview-3.0-dev",
                                    :fedora => "gtksourceview3-devel",
                                    :homebrew => "gtksourceview3",
diff --git a/gtksourceview3/Rakefile b/gtksourceview3/Rakefile
index 8d7c837..18a54df 100644
--- a/gtksourceview3/Rakefile
+++ b/gtksourceview3/Rakefile
@@ -44,7 +44,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "gtksourceview",
       :download_site => :gnome,
       :label => "GtkSourceView",
-      :version => "3.16.1",
+      :version => "3.20.1",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/gvlc/ext/gvlc/extconf.rb b/gvlc/ext/gvlc/extconf.rb
index 38b9d18..8d9af79 100644
--- a/gvlc/ext/gvlc/extconf.rb
+++ b/gvlc/ext/gvlc/extconf.rb
@@ -40,6 +40,7 @@ end
 end
 
 unless required_pkg_config_package([package_id, 2, 0, 0],
+                                   :altlinux => "libvlc-devel",
                                    :debian => "libvlc-dev")
   exit(false)
 end
diff --git a/pango/Rakefile b/pango/Rakefile
index 8b8def2..e5603f3 100644
--- a/pango/Rakefile
+++ b/pango/Rakefile
@@ -1,6 +1,6 @@
 # -*- ruby -*-
 #
-# Copyright (C) 2011-2015  Ruby-GNOME2 Project Team
+# Copyright (C) 2011-2016  Ruby-GNOME2 Project Team
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -29,10 +29,10 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
   package.external_packages = [
     {
       :name => "icu",
-      :download_base_url => "http://download.icu-project.org/files/icu4c/55.1",
+      :download_base_url => "http://download.icu-project.org/files/icu4c/57.1",
       :label => "gobject-introspection",
       :base_name => "icu",
-      :archive_base_name => "icu4c-55_1-src.tgz",
+      :archive_base_name => "icu4c-57_1-src.tgz",
       :compression_method => "gz",
       :base_dir_in_package => "source",
       :windows => {
@@ -48,9 +48,9 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "harfbuzz",
-      :download_base_url => "http://www.freedesktop.org/software/harfbuzz/release",
+      :download_base_url => "https://www.freedesktop.org/software/harfbuzz/release",
       :label => "HarfBuzz",
-      :version => "1.0.3",
+      :version => "1.2.4",
       :compression_method => "bz2",
       :windows => {
         :configure_args => [
@@ -64,7 +64,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "pango",
       :download_site => :gnome,
       :label => "pango",
-      :version => "1.36.8",
+      :version => "1.40.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/pango/ext/pango/extconf.rb b/pango/ext/pango/extconf.rb
index ee5c720..612c8db 100644
--- a/pango/ext/pango/extconf.rb
+++ b/pango/ext/pango/extconf.rb
@@ -49,6 +49,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 1, 14, 0],
+                                   :altlinux => "libpango-devel",
                                    :debian => "libpango1.0-dev",
                                    :redhat => "pango-devel",
                                    :arch => "pango",
diff --git a/pango/lib/pango.rb b/pango/lib/pango.rb
index c7b2f9d..58b0550 100644
--- a/pango/lib/pango.rb
+++ b/pango/lib/pango.rb
@@ -1,21 +1,13 @@
 #
 # pango.rb
-# Copyright(C) 2005, 2009 Ruby-GNOME2 Project.
+# Copyright(C) 2005-2015 Ruby-GNOME2 Project.
 #
 # This program is licenced under the same
 # license of Ruby-GNOME2.
 #
 
 require 'glib2'
-begin
-  begin
-    require 'cairo'
-  rescue LoadError
-    require 'rubygems'
-    require 'cairo'
-  end
-rescue LoadError
-end
+require 'cairo'
 
 base_dir = Pathname.new(__FILE__).dirname.dirname.expand_path
 vendor_dir = base_dir + "vendor" + "local"
diff --git a/poppler/Rakefile b/poppler/Rakefile
index 8cf1285..5ab8012 100644
--- a/poppler/Rakefile
+++ b/poppler/Rakefile
@@ -36,8 +36,8 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
   package.external_packages = [
     {
       :name => "libjpeg",
-      :base_name => "jpeg-9a",
-      :archive_base_name => "jpegsrc.v9a.tar.gz",
+      :base_name => "jpeg-9b",
+      :archive_base_name => "jpegsrc.v9b.tar.gz",
       :download_base_url => "http://www.ijg.org/files",
       :label => "libjpeg",
       :windows => {
@@ -47,9 +47,9 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "sqlite-autoconf",
-      :download_base_url => "http://www.sqlite.org/2015",
+      :download_base_url => "http://www.sqlite.org/2016",
       :label => "SQLite",
-      :version => "3081101",
+      :version => "3120000",
       :compression_method => "gz",
       :windows => {
         :configure_args => [],
@@ -71,9 +71,9 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
     },
     {
       :name => "poppler",
-      :download_base_url => "http://poppler.freedesktop.org",
+      :download_base_url => "https://poppler.freedesktop.org",
       :label => "Poppler",
-      :version => "0.36.0",
+      :version => "0.42.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/poppler/ext/poppler/extconf.rb b/poppler/ext/poppler/extconf.rb
index 3f57388..756f105 100644
--- a/poppler/ext/poppler/extconf.rb
+++ b/poppler/ext/poppler/extconf.rb
@@ -46,6 +46,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 0, 12, 0],
+                                   :altlinux => "libpoppler-glib-devel",
                                    :debian => "libpoppler-glib-dev",
                                    :redhat => "poppler-glib-devel",
                                    :arch => "poppler",
diff --git a/poppler/ext/poppler/rbpoppler.c b/poppler/ext/poppler/rbpoppler.c
index 2b28f95..fb3bfed 100644
--- a/poppler/ext/poppler/rbpoppler.c
+++ b/poppler/ext/poppler/rbpoppler.c
@@ -56,7 +56,6 @@ Init_poppler(void)
                                 INT2FIX(POPPLER_MICRO_VERSION)));
 
     G_DEF_CLASS(POPPLER_TYPE_ERROR, "Error", RG_TARGET_NAMESPACE);
-    G_DEF_CLASS(POPPLER_TYPE_ORIENTATION, "Orientation", RG_TARGET_NAMESPACE);
 
     G_DEF_CLASS(POPPLER_TYPE_PAGE_TRANSITION_TYPE,
                 "PageTransitionType", RG_TARGET_NAMESPACE);
diff --git a/poppler/lib/poppler.rb b/poppler/lib/poppler.rb
index 25fcac2..6aa2946 100644
--- a/poppler/lib/poppler.rb
+++ b/poppler/lib/poppler.rb
@@ -54,7 +54,7 @@ module Poppler
   class Document
     private
     def pdf_data?(data)
-      /\A%PDF-1\.\d/ =~ data
+      data.start_with?("%PDF-1.")
     end
 
     def ensure_uri(uri)
diff --git a/poppler/test/poppler-test-utils.rb b/poppler/test/poppler-test-utils.rb
index c9e165c..7eee07d 100644
--- a/poppler/test/poppler-test-utils.rb
+++ b/poppler/test/poppler-test-utils.rb
@@ -22,7 +22,7 @@ module PopplerTestUtils
   def form_pdf
     file = File.join(fixtures_dir, "form.pdf")
     return file if File.exist?(file)
-    pdf = open("http://www.irs.gov/pub/irs-pdf/fw9.pdf").read
+    pdf = open("https://www.irs.gov/pub/irs-pdf/fw9.pdf").read
     File.open(file, "wb") do |output|
       output.print(pdf)
     end
diff --git a/release.rd b/release.rd
index 6583c38..771772a 100644
--- a/release.rd
+++ b/release.rd
@@ -19,28 +19,9 @@ ruby-gnome2-all-X.Y.Z.tar.gz:
 
   % rake dist
 
-Here are confirmation steps:
+Here is a confirmation step:
 
-  % cp *.tar.gz /tmp
-  % cd /tmp
-  % tar xvf ruby-gtk2-X.Y.Z.tar.gz
-  % cd ruby-gtk2-X.Y.Z
-  % ruby extconf.rb
-  % make
-  % make install DESTDIR=/tmp/ruby
-  % cd gtk2/sample/gtk-demo
-  % ruby -I/tmp/ruby/usr/local/lib/site_ruby/1.8/{,x86_64-linux} main.rb
-  (...try demo application...)
-  % cd /tmp
-  % rm -rf ruby
-  % tar xvf ruby-gnome2-all-X.Y.Z.tar.gz
-  % cd ruby-gnome2-all-X.Y.Z
-  % ruby extconf.rb
-  % make
-  % make install DESTDIR=/tmp/ruby
-  % cd gtk2/sample/gtk-demo
-  % ruby -I/tmp/ruby/usr/local/lib/site_ruby/1.8/{,x86_64-linux} main.rb
-  (...try demo application...)
+  % rake dist:test
 
 === gem
 
@@ -55,8 +36,8 @@ locally:
 
 Here are confirmation steps:
 
-  % cd gtk2/sample/gtk-demo
-  % ruby -rubygems main.rb
+  % cd gtk3/sample/gtk-demo
+  % ruby main.rb
   (...try demo application...)
   % cd -
 
@@ -67,34 +48,19 @@ gem:install':
 
 === gem for Windows
 
-NOTE: This steps are confirmed on Debian GNU/Linux
-sid. (2011-09-18)
-
 Ruby-GNOME2 gems bundled Windows binary are created by
 cross-compiling. It means that you require GNU/Linux not
 Windows for releasing.
 
-The following steps are needed only the first setup:
-
-  % sudo gem install rake-compiler
-  % sudo aptitude install -y mingw-w64
-  % rake-compiler cross-ruby VERSION=1.8.7-p352 EXTS=--without-extensions
-  % rake-compiler cross-ruby VERSION=1.9.2-p290 EXTS=--without-extensions
-
-The following command downloads GTK+ related binaries for
-Windows:
-
-  % rake gem:windows:download
-
-The following command rebuilds binary gems for Windows:
+The following command generates gem files to */pkg/*:
 
-  % rake gem:windows:clean gem:windows:build
+  % rake windows:build
 
 Here are confirmation steps:
 
   (1) copy */pkg/*-X.Y.Z-x86-mingw32.gem to Windows.
   (2) install copied gems on Windows.
-  (3) cd GEM_PATH/gtk2/sample/gtk-demo/.
+  (3) cd GEM_PATH/gtk3/sample/gtk-demo/.
   (4) run 'ruby main.rb' and try the demo application.
 
 == How to release packages
@@ -114,7 +80,8 @@ The following command uploads */pkg/*-X.Y.Z.gem to rubygems.org:
 
 === gem for Windows
 
-The following command uploads */pkg/*-X.Y.Z-x86-mingw32.gem to rubygems.org:
+The following command uploads */pkg/*-X.Y.Z-x86-mingw32.gem to
+rubygems.org:
 
   % rake gem:windows:push
 
diff --git a/rsvg2/Rakefile b/rsvg2/Rakefile
index 418983e..cea234f 100644
--- a/rsvg2/Rakefile
+++ b/rsvg2/Rakefile
@@ -44,7 +44,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "libcroco",
       :download_site => :gnome,
       :label => "libcroco",
-      :version => "0.6.8",
+      :version => "0.6.11",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
@@ -57,7 +57,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "librsvg",
       :download_site => :gnome,
       :label => "librsvg",
-      :version => "2.40.9",
+      :version => "2.40.13",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/rsvg2/ext/rsvg2/extconf.rb b/rsvg2/ext/rsvg2/extconf.rb
index 30fce33..62248ea 100644
--- a/rsvg2/ext/rsvg2/extconf.rb
+++ b/rsvg2/ext/rsvg2/extconf.rb
@@ -46,6 +46,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 2, 16, 1],
+                                   :altlinux => "librsvg-devel",
                                    :debian => "librsvg2-dev",
                                    :redhat => "librsvg2-devel",
                                    :arch => "librsvg",
diff --git a/travis-before-script.sh b/travis-before-script.sh
index 79fec3d..d3a5ce4 100755
--- a/travis-before-script.sh
+++ b/travis-before-script.sh
@@ -23,14 +23,16 @@ if ! apt-cache show gir1.2-gstreamer-1.0 > /dev/null 2>&1; then
     sudo add-apt-repository --yes ppa:gstreamer-developers/ppa
 fi
 sudo apt-get update -qq
-# TODO: we'll use gir1.2-webkit2-3.0
-#       if it's supported in Travis CI.
 sudo apt-get install -qq -y \
     libgirepository1.0-dev \
     gstreamer1.0-plugins-good \
+    gir1.2-clutter-1.0 \
+    gir1.2-clutter-gst-2.0 \
+    gir1.2-gtkclutter-1.0 \
     gir1.2-gtksource-3.0 \
     gir1.2-vte-2.90 \
     gir1.2-webkit-1.0 \
     gir1.2-webkit-3.0 \
+    gir1.2-webkit2-3.0 \
     gnome-icon-theme \
     dbus-x11
diff --git a/vte/ext/vte/extconf.rb b/vte/ext/vte/extconf.rb
index e5e3928..4822001 100644
--- a/vte/ext/vte/extconf.rb
+++ b/vte/ext/vte/extconf.rb
@@ -33,6 +33,7 @@ end
 setup_windows(module_name, base_dir)
 
 unless required_pkg_config_package(package_id,
+                                   :altlinux => "libvte-devel",
                                    :debian => "libvte-dev",
                                    :redhat => "vte-devel",
                                    :homebrew => "vte",
diff --git a/vte3-no-gi/ext/vte3/extconf.rb b/vte3-no-gi/ext/vte3/extconf.rb
index dc36171..158883b 100644
--- a/vte3-no-gi/ext/vte3/extconf.rb
+++ b/vte3-no-gi/ext/vte3/extconf.rb
@@ -33,6 +33,7 @@ end
 setup_win32(module_name, base_dir)
 
 unless required_pkg_config_package([package_id, 0, 26, 0],
+                                   :altlinux => "libvte3-devel",
                                    :debian => "libvte-2.90-dev",
                                    :redhat => "vte3-devel",
                                    :homebrew => "vte3")
diff --git a/vte3/Rakefile b/vte3/Rakefile
index b16e176..03798d5 100644
--- a/vte3/Rakefile
+++ b/vte3/Rakefile
@@ -46,7 +46,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "vte",
       :download_site => :gnome,
       :label => "vte",
-      :version => "0.41.90",
+      :version => "0.44.0",
       :compression_method => "xz",
       :windows => {
         :configure_args => [
diff --git a/webkit2-gtk/Rakefile b/webkit2-gtk/Rakefile
index d5c6b0a..022df0b 100644
--- a/webkit2-gtk/Rakefile
+++ b/webkit2-gtk/Rakefile
@@ -61,7 +61,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "libwebp",
       :download_base_url => "http://downloads.webmproject.org/releases/webp",
       :label => "WebP",
-      :version => "0.4.3",
+      :version => "0.5.0",
       :windows => {
         :built_file => "bin/libwebp-5.dll",
       },
@@ -86,7 +86,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
       :name => "webkitgtk",
       :download_base_url => "http://webkitgtk.org/releases",
       :label => "WebKitGTK+",
-      :version => "2.9.92",
+      :version => "2.12.0",
       :compression_method => "xz",
       :windows => {
         :cmake_args => [
diff --git a/webkit2-gtk/lib/webkit2-gtk.rb b/webkit2-gtk/lib/webkit2-gtk.rb
index 4fc3648..ef67d5e 100644
--- a/webkit2-gtk/lib/webkit2-gtk.rb
+++ b/webkit2-gtk/lib/webkit2-gtk.rb
@@ -66,7 +66,7 @@ module WebKit2Gtk
     end
 
     def require_libraries
-      require "webkit2-gtk/version"
+      require "webkit2-gtk/version" if @version_module.const_defined?(:MAJOR)
     end
 
     def initialize_post(object)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-gnome2.git



More information about the Pkg-ruby-extras-commits mailing list