Project import generated by Copybara.

GitOrigin-RevId: 3f33ab8e637a446002e7de8fc64cb862d3ddf759
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..13fd0fb
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,11 @@
+# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
+BasedOnStyle: GNU
+AlwaysBreakAfterDefinitionReturnType: All
+BreakBeforeBinaryOperators: None
+BinPackParameters: false
+SpaceAfterCStyleCast: true
+# Our column limit is actually 80, but setting that results in clang-format
+# making a lot of dubious hanging-indent choices; disable it and assume the
+# developer will line wrap appropriately. clang-format will still check
+# existing hanging indents.
+ColumnLimit: 0
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..abf24af
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1 @@
+((c-mode . ((indent-tabs-mode . nil)))))
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3ff37de
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+README.win32 text eol=crlf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6b1ad6a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+# for all subdirectories
+TAGS
+tags
+.libs
+.deps
+*.o
+*.lo
+*.la
+*.pc
+.*.swp
+.sw?
+*.rc
+*.gcno
+*.gcda
+*.gcov
+*.sourcefiles
+*.stp
+*.exe
+*.def
+*.test
+*.log
+*.trs
+
+INSTALL
+/glib-lcov.info
+/glib-lcov/
+
+# Meson
+/meson-build/
+/subprojects/*/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..fb0454e
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,481 @@
+stages:
+  - style-check
+  - build
+  - coverage
+  - analysis
+  - deploy
+
+cache:
+  paths:
+    - _ccache/
+
+variables:
+  FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/glib/fedora:v9"
+  DEBIAN_IMAGE: "registry.gitlab.gnome.org/gnome/glib/debian-stable:v6"
+  ANDROID_IMAGE: "registry.gitlab.gnome.org/gnome/glib/android-ndk:v3"
+  MINGW_IMAGE: "registry.gitlab.gnome.org/gnome/glib/mingw:v2"
+  MESON_TEST_TIMEOUT_MULTIPLIER: 2
+  G_MESSAGES_DEBUG: all
+  MESON_COMMON_OPTIONS_NO_WARNING: "--buildtype debug --wrap-mode=nodownload"
+  MESON_COMMON_OPTIONS: "${MESON_COMMON_OPTIONS_NO_WARNING} --fatal-meson-warnings"
+
+.only-default:
+  only:
+    - branches
+  except:
+    - tags
+
+.build:
+  extends: .only-default
+  before_script:
+    - bash .gitlab-ci/show-execution-environment.sh
+    - cp -r $HOME/subprojects/* subprojects/
+
+style-check-diff:
+  extends: .only-default
+  image: $DEBIAN_IMAGE
+  stage: style-check
+  allow_failure: true
+  script:
+    - .gitlab-ci/run-style-check-diff.sh
+
+check-todos:
+  extends: .only-default
+  image: $DEBIAN_IMAGE
+  stage: style-check
+  allow_failure: true
+  script:
+    - .gitlab-ci/run-check-todos.sh
+
+fedora-x86_64:
+  extends: .build
+  image: $FEDORA_IMAGE
+  stage: build
+  variables:
+    CFLAGS: "-coverage -ftest-coverage -fprofile-arcs"
+  script:
+    # FIXME: Cannot use MESON_COMMON_OPTIONS here because meson warns about gtkdoc
+    # feature introduced in 0.52 but we only depends on 0.49. So we cannot build
+    # with --fatal-meson-warnings.
+    - meson ${MESON_COMMON_OPTIONS_NO_WARNING}
+            --werror
+            --default-library=both
+            --prefix=$HOME/glib-installed
+            --libdir=lib
+            -Dsystemtap=true
+            -Ddtrace=true
+            -Dfam=true
+            -Dinstalled_tests=true
+            -Dgtk_doc=true
+            _build
+    - ninja -C _build
+    - mkdir -p _coverage
+    - lcov --config-file .gitlab-ci/lcovrc --directory _build --capture --initial --output-file "_coverage/${CI_JOB_NAME}-baseline.lcov"
+    - .gitlab-ci/run-tests.sh
+    - lcov --config-file .gitlab-ci/lcovrc --directory _build --capture --output-file "_coverage/${CI_JOB_NAME}.lcov"
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/docs/reference/glib/glib-undeclared.txt"
+      - "_build/docs/reference/glib/glib-undocumented.txt"
+      - "_build/docs/reference/glib/glib-unused.txt"
+      - "_build/docs/reference/gobject/gobject-undeclared.txt"
+      - "_build/docs/reference/gobject/gobject-undocumented.txt"
+      - "_build/docs/reference/gobject/gobject-unused.txt"
+      - "_build/docs/reference/gio/gio-undeclared.txt"
+      - "_build/docs/reference/gio/gio-undocumented.txt"
+      - "_build/docs/reference/gio/gio-unused.txt"
+      - "_build/${CI_JOB_NAME}-report.xml"
+      - "_coverage"
+
+debian-stable-x86_64:
+  extends: .build
+  image: $DEBIAN_IMAGE
+  stage: build
+  script:
+    - meson ${MESON_COMMON_OPTIONS}
+            --werror
+            --default-library=both
+            --prefix=$HOME/glib-installed
+            --libdir=lib
+            -Dsystemtap=true
+            -Ddtrace=true
+            -Dfam=true
+            -Dinstalled_tests=true
+            _build
+    - ninja -C _build
+    - .gitlab-ci/run-tests.sh
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/${CI_JOB_NAME}-report.xml"
+
+installed-tests:
+  extends: .build
+  image: $FEDORA_IMAGE
+  stage: build
+  script:
+    # dtrace is disabled because it breaks the static-link.py test
+    - meson ${MESON_COMMON_OPTIONS}
+            --werror
+            --prefix=/usr --libdir=/usr/lib64
+            -Dfam=true
+            -Dinstalled_tests=true
+            -Ddefault_library=both
+            -Ddtrace=false
+            _build
+    - ninja -C _build
+    - sudo ninja -C _build install
+    - sudo chown -R `id -un`:`id -gn` _build/
+    # FIXME Install newer xdg-desktop-portal with
+    # GMemoryMonitor support, see:
+    # https://github.com/flatpak/xdg-desktop-portal/pull/365
+    - git clone --single-branch https://github.com/flatpak/xdg-desktop-portal.git
+    - cd xdg-desktop-portal
+    - git reset --hard 1.6.0
+    - ./autogen.sh --prefix=/usr --libdir=/usr/lib64 --disable-libportal --disable-dependency-tracking
+    - make
+    - sudo make install
+    - cd ..
+    # FIXME install newer gobject-introspection
+    # with GMemoryMonitor support, see:
+    # https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/193
+    - git clone --single-branch https://gitlab.gnome.org/GNOME/gobject-introspection.git
+    - cd gobject-introspection
+    - /usr/bin/meson _build --prefix=/usr --libdir=/usr/lib64
+    - ninja -C _build
+    - sudo ninja -C _build install
+    - cd ..
+    # Work-around https://gitlab.gnome.org/GNOME/gnome-desktop-testing/merge_requests/2
+    - mkdir -p _build/installed-tests-report/logs/
+    - GLIB_TEST_COMPILATION=1 gnome-desktop-testing-runner
+            --report-directory=_build/installed-tests-report/failed/
+            --log-directory=_build/installed-tests-report/logs/
+            --parallel=0
+            glib
+  artifacts:
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/installed-tests-report/"
+
+G_DISABLE_ASSERT:
+  extends: .build
+  image: $FEDORA_IMAGE
+  stage: build
+  script:
+    - meson ${MESON_COMMON_OPTIONS}
+            --werror
+            -Dsystemtap=true
+            -Ddtrace=true
+            -Dfam=true
+            -Dinstalled_tests=true
+            -Dglib_assert=false
+            _build
+    - ninja -C _build
+    - bash -x ./.gitlab-ci/run-tests.sh
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/${CI_JOB_NAME}-report.xml"
+
+valgrind:
+  extends: .build
+  image: $FEDORA_IMAGE
+  stage: analysis
+  variables:
+    MESON_TEST_TIMEOUT_MULTIPLIER: 10
+  script:
+    - meson ${MESON_COMMON_OPTIONS}
+            --werror
+            -Dsystemtap=true
+            -Ddtrace=true
+            -Dfam=true
+            -Dinstalled_tests=true
+            _build
+    - ninja -C _build
+    - bash -x ./.gitlab-ci/run-tests.sh
+                 --log-file _build/meson-logs/testlog-valgrind.json
+                 --wrap "valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes --leak-check=full --leak-resolution=high --num-callers=50 --show-leak-kinds=definite,possible --show-error-list=yes --suppressions=${CI_PROJECT_DIR}/glib.supp"
+                 --no-suite no-valgrind
+                 --no-suite slow
+  # FIXME: Remove this when we have zero valgrind leaks.
+  # https://gitlab.gnome.org/GNOME/glib/issues/333
+  allow_failure: true
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+
+.cross-template: &cross-template
+  extends: .build
+  stage: build
+  artifacts:
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/meson-logs"
+
+cross-android_api21_arm64:
+  <<: *cross-template
+  image: $ANDROID_IMAGE
+  script:
+    # FIXME: add --werror
+    # We use -Diconv=auto to test that we successfully detect that iconv is not
+    # provided by android api 21, and detect the external iconv instead.
+    - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_android_arm64_21.txt -Diconv=auto -Dinternal_pcre=true _build
+    - ninja -C _build
+
+cross-android_api28_arm64:
+  <<: *cross-template
+  image: $ANDROID_IMAGE
+  script:
+    # FIXME: add --werror
+    - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_android_arm64_28.txt -Dinternal_pcre=true _build
+    - ninja -C _build
+
+cross-mingw64:
+  <<: *cross-template
+  image: $MINGW_IMAGE
+  script:
+    # FIXME: Add --werror
+    - meson ${MESON_COMMON_OPTIONS} --cross-file=/opt/cross_file_mingw64.txt _build
+    - ninja -C _build
+
+msys2-mingw32:
+  extends: .only-default
+  stage: build
+  tags:
+    - win32-ps
+  variables:
+    MSYSTEM: "MINGW32"
+    CHERE_INVOKING: "yes"
+  script:
+    - C:\msys64\usr\bin\pacman --noconfirm -Syyuu --ask 20
+    - C:\msys64\usr\bin\bash .gitlab-ci/show-execution-environment.sh
+    - C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
+  artifacts:
+    reports:
+      junit: "_build/${env:CI_JOB_NAME}-report.xml"
+    name: "glib-${env:CI_JOB_NAME}-${env:CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - _build/meson-logs
+      - "_build/${env:CI_JOB_NAME}-report.xml"
+      - _coverage/
+
+vs2017-x64:
+  extends: .only-default
+  stage: build
+  tags:
+    - win32-ps
+  script:
+    - .gitlab-ci/test-msvc.bat
+  artifacts:
+    reports:
+      junit: "_build/${env:CI_JOB_NAME}-report.xml"
+    name: "glib-${env:CI_JOB_NAME}-${env:CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - _build/meson-logs
+      - "_build/${env:CI_JOB_NAME}-report.xml"
+
+freebsd-11-x86_64:
+  stage: build
+  only:
+    - branches@GNOME/glib
+  tags:
+    # To run a FreeBSD builder, install gitlab-runner package and start both
+    # gitlab-runner and dbus service because we need /var/lib/dbus/machine-id.
+    # To compile GLib, you still have to install the following packages:
+    # desktop-file-utils gettext libiconv meson pkgconf python3 shared-mime-info
+    - freebsd-11
+  variables:
+    # CPPFLAGS is required because libintl doesn't use pkg-config.
+    CPPFLAGS: -I/usr/local/include
+    # FIXME: Workaround meson inability to set LD_LIBRARY_PATH.
+    # https://github.com/mesonbuild/meson/issues/1383
+    # https://github.com/mesonbuild/meson/issues/1635
+    # https://github.com/mesonbuild/meson/issues/2881
+    LDFLAGS: -L/usr/local/lib -Wl,--disable-new-dtags
+    # FreeBSD doesn't have C.UTF-8 locale.
+    LANG: en_US.UTF-8
+  before_script:
+    - bash .gitlab-ci/show-execution-environment.sh
+  script:
+    # We cannot use -Wl,--no-undefined because GLib uses 'environ' variable.
+    # FreeBSD iconv doesn't handle transliteration, so we use (external) GNU libiconv here.
+    # FreeBSD supports xattr, but its API is different from Linux xattr.
+    # FIXME: extattr(2) support: https://gitlab.gnome.org/GNOME/glib/issues/1404
+    - meson ${MESON_COMMON_OPTIONS} -Db_lundef=false -Diconv=external -Dxattr=false _build
+    - ninja -C _build
+    - bash -x ./.gitlab-ci/run-tests.sh
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/${CI_JOB_NAME}-report.xml"
+
+freebsd-12-x86_64:
+  stage: build
+  only:
+    - branches@GNOME/glib
+  tags:
+    - freebsd-12
+  variables:
+    CPPFLAGS: -I/usr/local/include
+    LDFLAGS: -L/usr/local/lib -Wl,--disable-new-dtags
+    LANG: en_US.UTF-8
+  before_script:
+    - bash .gitlab-ci/show-execution-environment.sh
+  script:
+    - meson ${MESON_COMMON_OPTIONS} -Db_lundef=false -Diconv=external -Dxattr=false _build
+    - ninja -C _build
+    - bash -x ./.gitlab-ci/run-tests.sh
+  except:
+    - tags
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/${CI_JOB_NAME}-report.xml"
+
+macos:
+  extends: .only-default
+  stage: build
+  only:
+    - branches@GNOME/glib
+  tags:
+    - macos
+  before_script:
+    - bash .gitlab-ci/show-execution-environment.sh
+    - pip3 install --user meson==0.49.2
+    - pip3 install --user ninja
+    - export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
+  script:
+    # FIXME: Add --werror
+    # FIXME: Use --wrap-mode=default so we download dependencies each time,
+    # until the macOS runner is a VM where we can use a pre-made image which
+    # already contains the dependencies. See:
+    #  - https://gitlab.gnome.org/GNOME/glib/merge_requests/388
+    #  - https://gitlab.gnome.org/Infrastructure/Infrastructure/issues/225
+    - meson ${MESON_COMMON_OPTIONS}
+            --wrap-mode=default
+            _build
+    - ninja -C _build
+    # FIXME: Multiple unit tests currently fails
+    - .gitlab-ci/run-tests.sh || true
+  artifacts:
+    reports:
+      junit: "_build/${CI_JOB_NAME}-report.xml"
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_build/config.h"
+      - "_build/glib/glibconfig.h"
+      - "_build/meson-logs"
+      - "_build/${CI_JOB_NAME}-report.xml"
+
+coverage:
+  extends: .only-default
+  image: $FEDORA_IMAGE
+  stage: coverage
+  artifacts:
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    paths:
+      - _coverage/
+  before_script:
+    - bash .gitlab-ci/show-execution-environment.sh
+  script:
+    - bash -x ./.gitlab-ci/coverage-docker.sh
+  coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
+
+scan-build:
+  extends: .build
+  image: $FEDORA_IMAGE
+  stage: analysis
+  script:
+    - meson ${MESON_COMMON_OPTIONS}
+            --werror
+            --default-library=both
+            --prefix=$HOME/glib-installed
+            --libdir=lib
+            -Dsystemtap=true
+            -Ddtrace=true
+            -Dfam=true
+            -Dinstalled_tests=true
+            _scan_build
+    - ninja -C _scan_build scan-build
+  artifacts:
+    name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+    when: always
+    paths:
+      - "_scan_build/meson-logs/scanbuild"
+
+pages:
+  stage: deploy
+  only:
+    - master
+  script:
+    - mv _coverage/ public/
+  artifacts:
+    paths:
+      - public
+
+dist-job:
+  image: $FEDORA_IMAGE
+  stage: build
+  only:
+    - tags
+  script:
+    # FIXME: Cannot use --fatal-meson-warnings here because meson warns about gtkdoc
+    # feature introduced in 0.52 but we only depends on 0.49.
+    - meson ${MESON_COMMON_OPTIONS_NO_WARNING} --buildtype release -Dgtk_doc=true -Dman=true _build
+    - cd _build
+    - ninja dist
+    - ninja glib-doc gobject-doc gio-doc
+    - tar -c -J -f "glib-docs-$CI_COMMIT_TAG.tar.xz" -C docs/reference/glib html
+    - tar -c -J -f "gobject-docs-$CI_COMMIT_TAG.tar.xz" -C docs/reference/gobject html
+    - tar -c -J -f "gio-docs-$CI_COMMIT_TAG.tar.xz" -C docs/reference/gio html
+  artifacts:
+    paths:
+      - "${CI_PROJECT_DIR}/_build/glib-docs-$CI_COMMIT_TAG.tar.xz"
+      - "${CI_PROJECT_DIR}/_build/gobject-docs-$CI_COMMIT_TAG.tar.xz"
+      - "${CI_PROJECT_DIR}/_build/gio-docs-$CI_COMMIT_TAG.tar.xz"
+      - "${CI_PROJECT_DIR}/_build/meson-dist/glib-*.tar.xz"
diff --git a/.gitlab-ci/README.md b/.gitlab-ci/README.md
new file mode 100644
index 0000000..f56cbbd
--- /dev/null
+++ b/.gitlab-ci/README.md
@@ -0,0 +1,23 @@
+# CI support stuff
+
+## Docker image
+
+GitLab CI jobs run in a Docker image, defined here. To update that image
+(perhaps to install some more packages):
+
+1. Edit `.gitlab-ci/Dockerfile` with the changes you want
+1. Run `.gitlab-ci/run-docker.sh build --base=debian-stable --base-version=1` to
+   build the new image (bump the version from the latest listed for that `base`
+   on https://gitlab.gnome.org/GNOME/glib/container_registry)
+1. Run `.gitlab-ci/run-docker.sh push  --base=debian-stable --base-version=1` to
+   upload the new image to the GNOME GitLab Docker registry
+    * If this is the first time you're doing this, you'll need to log into the
+      registry
+    * If you use 2-factor authentication on your GNOME GitLab account, you'll
+      need to [create a personal access token][pat] and use that rather than
+      your normal password — the token should have `read_registry` and
+      `write_registry` permissions
+1. Edit `.gitlab-ci.yml` (in the root of this repository) to use your new
+   image
+
+[pat]: https://gitlab.gnome.org/profile/personal_access_tokens
diff --git a/.gitlab-ci/android-download-ndk.sh b/.gitlab-ci/android-download-ndk.sh
new file mode 100755
index 0000000..7739e39
--- /dev/null
+++ b/.gitlab-ci/android-download-ndk.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Collabora ltd.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author: Xavier Claessens <xavier.claessens@collabora.com>
+#
+
+set -e
+
+# Download Android NDK
+ANDROID_NDK_VERSION="r17b"
+ANDROID_NDK_SHA512="062fac12f747730f5563995089a8b4abab683fbbc621aa8582fdf35fe327daee5d69ed2437af257c10ec4ef54ecd3805a8f134a1400eb8f34ee76f55c8dc9ae9"
+wget --quiet "https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip"
+echo "${ANDROID_NDK_SHA512}  android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip" | sha512sum -c
+unzip "android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip"
+rm "android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip"
+mv "android-ndk-${ANDROID_NDK_VERSION}" "${ANDROID_NDK_PATH}"
diff --git a/.gitlab-ci/android-ndk.Dockerfile b/.gitlab-ci/android-ndk.Dockerfile
new file mode 100644
index 0000000..56b186c
--- /dev/null
+++ b/.gitlab-ci/android-ndk.Dockerfile
@@ -0,0 +1,78 @@
+FROM fedora:28
+
+RUN dnf -y install \
+    autoconf \
+    automake \
+    bindfs \
+    clang \
+    clang-analyzer \
+    desktop-file-utils \
+    elfutils-libelf-devel \
+    findutils \
+    fuse \
+    gamin-devel \
+    gcc \
+    gcc-c++ \
+    gettext \
+    git \
+    glibc-devel \
+    glibc-headers \
+    glibc-langpack-de \
+    glibc-langpack-el \
+    glibc-langpack-el \
+    glibc-langpack-en \
+    glibc-langpack-es \
+    glibc-langpack-es \
+    glibc-langpack-fa \
+    glibc-langpack-fr \
+    glibc-langpack-hr \
+    glibc-langpack-ja \
+    glibc-langpack-lt \
+    glibc-langpack-pl \
+    glibc-langpack-ru \
+    glibc-langpack-tr \
+    gtk-doc \
+    itstool \
+    lcov \
+    libattr-devel \
+    libffi-devel \
+    libmount-devel \
+    libselinux-devel \
+    libtool \
+    libxslt \
+    make \
+    ncurses-compat-libs \
+    ninja-build \
+    pcre-devel \
+    python3 \
+    python3-pip \
+    python3-wheel \
+    systemtap-sdt-devel \
+    unzip \
+    wget \
+    xz \
+    zlib-devel \
+ && dnf clean all
+
+WORKDIR /opt
+ENV ANDROID_NDK_PATH /opt/android-ndk
+COPY android-download-ndk.sh .
+RUN ./android-download-ndk.sh
+COPY android-setup-env.sh .
+RUN ./android-setup-env.sh arm64 21
+RUN ./android-setup-env.sh arm64 28
+RUN rm -rf $ANDROID_NDK_PATH
+
+RUN pip3 install meson==0.49.2
+
+ARG HOST_USER_ID=5555
+ENV HOST_USER_ID ${HOST_USER_ID}
+RUN useradd -u $HOST_USER_ID -ms /bin/bash user
+
+USER user
+WORKDIR /home/user
+
+COPY cache-subprojects.sh .
+RUN ./cache-subprojects.sh
+
+ENV LANG C.UTF-8
diff --git a/.gitlab-ci/android-setup-env.sh b/.gitlab-ci/android-setup-env.sh
new file mode 100755
index 0000000..42620cc
--- /dev/null
+++ b/.gitlab-ci/android-setup-env.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+
+#
+# Copyright 2018 Collabora ltd.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author: Xavier Claessens <xavier.claessens@collabora.com>
+#
+
+set -e
+
+arch=$1
+api=$2
+toolchain_path=$(pwd)/android-toolchain-$arch-$api
+prefix_path=$(pwd)/android-$arch-$api
+
+# Create standalone toolchains
+"${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py" --arch "${arch}" --api "${api}" --install-dir "${toolchain_path}"
+
+target_host=aarch64-linux-android
+export AR=$target_host-ar
+export AS=$target_host-clang
+export CC=$target_host-clang
+export CXX=$target_host-clang++
+export LD=$target_host-ld
+export STRIP=$target_host-strip
+export PATH=$PATH:$toolchain_path/bin
+
+# Cross build libiconv when using API level <= 28.
+# Newer Android has it in its libc already.
+if [ "$api" -lt "28" ]; then
+  wget --quiet http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz
+  echo "1233fe3ca09341b53354fd4bfe342a7589181145a1232c9919583a8c9979636855839049f3406f253a9d9829908816bb71fd6d34dd544ba290d6f04251376b1a  libiconv-1.15.tar.gz" | sha512sum -c
+  tar xzf libiconv-1.15.tar.gz
+  pushd libiconv-1.15
+  ./configure --host="${target_host}" --prefix="${prefix_path}"  --libdir="${prefix_path}/lib64"
+  make
+  make install
+  popd
+  rm libiconv-1.15.tar.gz
+  rm -r libiconv-1.15
+fi
+
+# Cross build libffi
+wget --quiet https://github.com/libffi/libffi/releases/download/v3.3-rc0/libffi-3.3-rc0.tar.gz
+echo "e6e695d32cd6eb7d65983f32986fccdfc786a593d2ea18af30ce741f58cfa1eb264b1a8d09df5084cb916001aea15187b005c2149a0620a44397a4453b6137d4  libffi-3.3-rc0.tar.gz" | sha512sum -c
+tar xzf libffi-3.3-rc0.tar.gz
+pushd libffi-3.3-rc0
+./configure --host="${target_host}" --prefix="${prefix_path}" --libdir="${prefix_path}/lib64"
+make
+make install
+popd
+rm libffi-3.3-rc0.tar.gz
+rm -r libffi-3.3-rc0
+
+# Create a pkg-config wrapper that won't pick fedora libraries
+mkdir -p "${prefix_path}/bin"
+export PKG_CONFIG=$prefix_path/bin/pkg-config
+cat > "${PKG_CONFIG}" <<- EOM
+#!/bin/sh
+SYSROOT=${prefix_path}
+export PKG_CONFIG_DIR=
+export PKG_CONFIG_LIBDIR=\${SYSROOT}/lib64/pkgconfig
+export PKG_CONFIG_SYSROOT_DIR=\${SYSROOT}
+exec pkg-config "\$@"
+EOM
+chmod +x "${PKG_CONFIG}"
+
+# Create a cross file that can be passed to meson
+cat > "cross_file_android_${arch}_${api}.txt" <<- EOM
+[host_machine]
+system = 'android'
+cpu_family = 'aarch64'
+cpu = 'aarch64'
+endian = 'little'
+
+[properties]
+c_args = ['-I${prefix_path}/include']
+c_link_args = ['-L${prefix_path}/lib64',
+               '-fuse-ld=gold']
+growing_stack = true
+
+[binaries]
+c = '${toolchain_path}/bin/${CC}'
+cpp = '${toolchain_path}/bin/${CXX}'
+ar = '${toolchain_path}/bin/${AR}'
+ld = '${toolchain_path}/bin/${LD}'
+strip = '${toolchain_path}/bin/${STRIP}'
+pkgconfig = '${PKG_CONFIG}'
+EOM
diff --git a/.gitlab-ci/cache-subprojects.sh b/.gitlab-ci/cache-subprojects.sh
new file mode 100755
index 0000000..421631e
--- /dev/null
+++ b/.gitlab-ci/cache-subprojects.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+git clone https://gitlab.gnome.org/GNOME/glib.git
+meson subprojects download --sourcedir glib
+rm glib/subprojects/*.wrap
+mv glib/subprojects/ .
+rm -rf glib
diff --git a/.gitlab-ci/check-todos.py b/.gitlab-ci/check-todos.py
new file mode 100755
index 0000000..83b3eee
--- /dev/null
+++ b/.gitlab-ci/check-todos.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+#
+# Copyright © 2019 Endless Mobile, Inc.
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Original author: Philip Withnall
+
+"""
+Checks that a merge request doesn’t add any instances of the string ‘todo’
+(in uppercase), or similar keywords. It may remove instances of that keyword,
+or move them around, according to the logic of `git log -S`.
+"""
+
+import argparse
+import re
+import subprocess
+import sys
+
+
+# We have to specify these keywords obscurely to avoid the script matching
+# itself. The keyword ‘fixme’ (in upper case) is explicitly allowed because
+# that’s conventionally used as a way of marking a workaround which needs to
+# be merged for now, but is to be grepped for and reverted or reworked later.
+BANNED_KEYWORDS = [
+    'TO' + 'DO',
+    'X' + 'XX',
+    'W' + 'IP',
+]
+
+
+def main():
+    parser = argparse.ArgumentParser(
+        description='Check a range of commits to ensure they don’t contain '
+                    'banned keywords.')
+    parser.add_argument('commits',
+                        help='SHA to diff from, or range of commits to diff')
+    args = parser.parse_args()
+
+    banned_words_seen = set()
+    seen_in_log = False
+    seen_in_diff = False
+
+    # Check the log messages for banned words.
+    log_process = subprocess.run(
+        ['git', 'log', '--no-color', args.commits + '..HEAD'],
+        stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8',
+        check=True)
+    log_lines = log_process.stdout.strip().split('\n')
+
+    for line in log_lines:
+        for keyword in BANNED_KEYWORDS:
+            if re.search('(^|\W+){}(\W+|$)'.format(keyword), line):
+                banned_words_seen.add(keyword)
+                seen_in_log = True
+
+    # Check the diff for banned words.
+    diff_process = subprocess.run(
+        ['git', 'diff', '-U0', '--no-color', args.commits],
+        stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8',
+        check=True)
+    diff_lines = diff_process.stdout.strip().split('\n')
+
+    for line in diff_lines:
+        if not line.startswith('+ '):
+            continue
+
+        for keyword in BANNED_KEYWORDS:
+            if re.search('(^|\W+){}(\W+|$)'.format(keyword), line):
+                banned_words_seen.add(keyword)
+                seen_in_diff = True
+
+    if banned_words_seen:
+        if seen_in_log and seen_in_diff:
+            where = 'commit message and diff'
+        elif seen_in_log:
+            where = 'commit message'
+        elif seen_in_diff:
+            where = 'commit diff'
+
+        print('Saw banned keywords in a {}: {}. '
+              'This indicates the branch is a work in progress and should not '
+              'be merged in its current '
+              'form.'.format(where, ', '.join(banned_words_seen)))
+        sys.exit(1)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/.gitlab-ci/coverage-docker.sh b/.gitlab-ci/coverage-docker.sh
new file mode 100755
index 0000000..bf79561
--- /dev/null
+++ b/.gitlab-ci/coverage-docker.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+# Fixup Windows paths
+python3 ./.gitlab-ci/fixup-cov-paths.py _coverage/*.lcov
+
+for path in _coverage/*.lcov; do
+    # Remove coverage from generated code in the build directory
+    lcov --config-file .gitlab-ci/lcovrc -r "${path}" '*/_build/*' -o "$(pwd)/${path}"
+    # Remove any coverage from system files
+    lcov --config-file .gitlab-ci/lcovrc -e "${path}" "$(pwd)/*" -o "$(pwd)/${path}"
+done
+
+genhtml \
+    --ignore-errors=source \
+    --config-file .gitlab-ci/lcovrc \
+    _coverage/*.lcov \
+    -o _coverage/coverage
+
+cd _coverage
+rm -f ./*.lcov
+
+cat >index.html <<EOL
+<html>
+<body>
+<ul>
+<li><a href="coverage/index.html">Coverage</a></li>
+</ul>
+</body>
+</html>
+EOL
diff --git a/.gitlab-ci/cross_file_ios_example.txt b/.gitlab-ci/cross_file_ios_example.txt
new file mode 100644
index 0000000..0afeef0
--- /dev/null
+++ b/.gitlab-ci/cross_file_ios_example.txt
@@ -0,0 +1,25 @@
+[host_machine]
+system = 'darwin'
+cpu_family = 'aarch64'
+cpu = 'arm64'
+endian = 'little'
+
+[properties]
+c_args = ['-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-miphoneos-version-min=11.0']
+cpp_args = ['-stdlib=libc++', '-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-miphoneos-version-min=11.0']
+objc_args = ['-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-miphoneos-version-min=11.0']
+objcpp_args = ['-stdlib=libc++', '-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-miphoneos-version-min=11.0']
+c_link_args = ['-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-Wl,-iphoneos_version_min,11.0']
+cpp_link_args = ['-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-Wl,-iphoneos_version_min,11.0']
+objc_link_args = ['-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-Wl,-iphoneos_version_min,11.0']
+objcpp_link_args = ['-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk', '-Wl,-iphoneos_version_min,11.0']
+growing_stack = true
+
+
+[binaries]
+c = ['clang']
+cpp = ['clang++']
+objc = ['clang']
+objcpp = ['clang++']
+ar = ['ar']
+strip = ['strip']
diff --git a/.gitlab-ci/cross_file_mingw64.txt b/.gitlab-ci/cross_file_mingw64.txt
new file mode 100644
index 0000000..7c9176b
--- /dev/null
+++ b/.gitlab-ci/cross_file_mingw64.txt
@@ -0,0 +1,19 @@
+[host_machine]
+system = 'windows'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
+
+[properties]
+c_args = []
+c_link_args = []
+
+[binaries]
+c = 'x86_64-w64-mingw32-gcc'
+cpp = 'x86_64-w64-mingw32-g++'
+ar = 'x86_64-w64-mingw32-ar'
+ld = 'x86_64-w64-mingw32-ld'
+objcopy = 'x86_64-w64-mingw32-objcopy'
+strip = 'x86_64-w64-mingw32-strip'
+pkgconfig = 'x86_64-w64-mingw32-pkg-config'
+windres = 'x86_64-w64-mingw32-windres'
diff --git a/.gitlab-ci/debian-stable.Dockerfile b/.gitlab-ci/debian-stable.Dockerfile
new file mode 100644
index 0000000..54d2d8c
--- /dev/null
+++ b/.gitlab-ci/debian-stable.Dockerfile
@@ -0,0 +1,78 @@
+FROM debian:buster
+
+RUN apt-get update -qq && apt-get install --no-install-recommends -qq -y \
+    bindfs \
+    clang \
+    clang-tools-7 \
+    clang-format-7 \
+    dbus \
+    desktop-file-utils \
+    elfutils \
+    findutils \
+    fuse \
+    gcc \
+    g++ \
+    gettext \
+    git \
+    libc6-dev \
+    gtk-doc-tools \
+    itstool \
+    lcov \
+    libattr1-dev \
+    libdbus-1-dev \
+    libelf-dev \
+    libffi-dev \
+    libgamin-dev \
+    libmount-dev \
+    libpcre2-dev \
+    libselinux1-dev \
+    libxml2-utils \
+    libxslt1-dev \
+    libz3-dev \
+    locales \
+    ninja-build \
+    python3 \
+    python3-pip \
+    python3-setuptools \
+    python3-wheel \
+    shared-mime-info \
+    systemtap-sdt-dev \
+    unzip \
+    wget \
+    xsltproc \
+    xz-utils \
+    zlib1g-dev \
+ && rm -rf /usr/share/doc/* /usr/share/man/*
+
+# Locale for our build
+RUN locale-gen C.UTF-8 && /usr/sbin/update-locale LANG=C.UTF-8
+
+# Locales for our tests
+RUN locale-gen de_DE.UTF-8 \
+ && locale-gen el_GR.UTF-8 \
+ && locale-gen en_US.UTF-8 \
+ && locale-gen es_ES.UTF-8 \
+ && locale-gen fa_IR.UTF-8 \
+ && locale-gen fr_FR.UTF-8 \
+ && locale-gen hr_HR.UTF-8 \
+ && locale-gen ja_JP.UTF-8 \
+ && locale-gen lt_LT.UTF-8 \
+ && locale-gen pl_PL.UTF-8 \
+ && locale-gen ru_RU.UTF-8 \
+ && locale-gen tr_TR.UTF-8
+
+ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8
+
+RUN pip3 install meson==0.49.2
+
+ARG HOST_USER_ID=5555
+ENV HOST_USER_ID ${HOST_USER_ID}
+RUN useradd -u $HOST_USER_ID -ms /bin/bash user
+
+USER user
+WORKDIR /home/user
+
+COPY cache-subprojects.sh .
+RUN ./cache-subprojects.sh
+
+ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8
diff --git a/.gitlab-ci/fedora.Dockerfile b/.gitlab-ci/fedora.Dockerfile
new file mode 100644
index 0000000..39553e2
--- /dev/null
+++ b/.gitlab-ci/fedora.Dockerfile
@@ -0,0 +1,92 @@
+FROM fedora:31
+
+RUN dnf -y update \
+ && dnf -y install \
+    bindfs \
+    clang \
+    clang-analyzer \
+    dbus-daemon \
+    dbus-devel \
+    desktop-file-utils \
+    elfutils-libelf-devel \
+    findutils \
+    fuse \
+    gamin-devel \
+    gcc \
+    gcc-c++ \
+    gettext \
+    git \
+    glibc-devel \
+    glibc-headers \
+    glibc-langpack-de \
+    glibc-langpack-el \
+    glibc-langpack-el \
+    glibc-langpack-en \
+    glibc-langpack-es \
+    glibc-langpack-es \
+    glibc-langpack-fa \
+    glibc-langpack-fr \
+    glibc-langpack-hr \
+    glibc-langpack-ja \
+    glibc-langpack-lt \
+    glibc-langpack-pl \
+    glibc-langpack-ru \
+    glibc-langpack-tr \
+    "gnome-desktop-testing >= 2018.1" \
+    gtk-doc \
+    itstool \
+    lcov \
+    libattr-devel \
+    libffi-devel \
+    libmount-devel \
+    libselinux-devel \
+    libxslt \
+    ncurses-compat-libs \
+    ninja-build \
+    pcre-devel \
+    "python3-dbusmock >= 0.18.3-2" \
+    python3-pip \
+    python3-pygments \
+    python3-wheel \
+    shared-mime-info \
+    systemtap-sdt-devel \
+    unzip \
+    valgrind \
+    wget \
+    xdg-desktop-portal \
+    xz \
+    zlib-devel \
+ && dnf -y install \
+    meson \
+    flex \
+    bison \
+    python3-devel \
+    autoconf \
+    automake \
+    gettext-devel \
+    libtool \
+    diffutils \
+    fontconfig-devel \
+    json-glib-devel \
+    geoclue2-devel \
+    pipewire-devel \
+    fuse-devel \
+    make \
+ && dnf clean all
+
+RUN pip3 install meson==0.52.1
+
+# Enable sudo for wheel users
+RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
+
+ARG HOST_USER_ID=5555
+ENV HOST_USER_ID ${HOST_USER_ID}
+RUN useradd -u $HOST_USER_ID -G wheel -ms /bin/bash user
+
+USER user
+WORKDIR /home/user
+
+COPY cache-subprojects.sh .
+RUN ./cache-subprojects.sh
+
+ENV LANG C.UTF-8
diff --git a/.gitlab-ci/fixup-cov-paths.py b/.gitlab-ci/fixup-cov-paths.py
new file mode 100644
index 0000000..d614b60
--- /dev/null
+++ b/.gitlab-ci/fixup-cov-paths.py
@@ -0,0 +1,29 @@
+import sys
+import os
+import io
+
+
+def main(argv):
+    # Fix paths in lcov files generated on a Windows host so they match our
+    # current source layout.
+    paths = argv[1:]
+
+    for path in paths:
+        print("cov-fixup:", path)
+        text = io.open(path, "r", encoding="utf-8").read()
+        text = text.replace("\\\\", "/")
+        glib_dir = "/glib/"
+        end = text.index(glib_dir)
+        start = text[:end].rindex(":") + 1
+        old_root = text[start:end]
+        assert os.path.basename(os.getcwd()) == "glib"
+        new_root = os.path.dirname(os.getcwd())
+        if old_root != new_root:
+            print("replacing %r with %r" % (old_root, new_root))
+        text = text.replace(old_root, new_root)
+        with io.open(path, "w", encoding="utf-8") as h:
+            h.write(text)
+
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/.gitlab-ci/lcovrc b/.gitlab-ci/lcovrc
new file mode 100644
index 0000000..3901f81
--- /dev/null
+++ b/.gitlab-ci/lcovrc
@@ -0,0 +1,13 @@
+# lcov and genhtml configuration
+# See http://ltp.sourceforge.net/coverage/lcov/lcovrc.5.php
+
+# Always enable branch coverage
+lcov_branch_coverage = 1
+
+# Exclude precondition assertions, as we can never reasonably get full branch
+# coverage of them, as they should never normally fail.
+# See https://github.com/linux-test-project/lcov/issues/44
+lcov_excl_br_line = LCOV_EXCL_BR_LINE|g_return_if_fail|g_return_val_if_fail|g_assert|g_assert_
+
+# Similarly for unreachable assertions.
+lcov_excl_line = LCOV_EXCL_LINE|g_return_if_reached|g_return_val_if_reached|g_assert_not_reached
\ No newline at end of file
diff --git a/.gitlab-ci/meson-junit-report.py b/.gitlab-ci/meson-junit-report.py
new file mode 100755
index 0000000..90939ff
--- /dev/null
+++ b/.gitlab-ci/meson-junit-report.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+
+# Turns a Meson testlog.json file into a JUnit XML report
+#
+# Copyright 2019  GNOME Foundation
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Original author: Emmanuele Bassi
+
+import argparse
+import datetime
+import json
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
+aparser.add_argument('--project-name', metavar='NAME',
+                     help='The project name',
+                     default='unknown')
+aparser.add_argument('--job-id', metavar='ID',
+                     help='The job ID for the report',
+                     default='Unknown')
+aparser.add_argument('--branch', metavar='NAME',
+                     help='Branch of the project being tested',
+                     default='master')
+aparser.add_argument('--output', metavar='FILE',
+                     help='The output file, stdout by default',
+                     type=argparse.FileType('w', encoding='UTF-8'),
+                     default=sys.stdout)
+aparser.add_argument('infile', metavar='FILE',
+                     help='The input testlog.json, stdin by default',
+                     type=argparse.FileType('r', encoding='UTF-8'),
+                     default=sys.stdin)
+
+args = aparser.parse_args()
+
+outfile = args.output
+
+testsuites = ET.Element('testsuites')
+testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
+testsuites.set('package', args.project_name)
+testsuites.set('timestamp', datetime.datetime.utcnow().isoformat())
+
+suites = {}
+for line in args.infile:
+    data = json.loads(line)
+    (full_suite, unit_name) = data['name'].split(' / ')
+    try:
+        (project_name, suite_name) = full_suite.split(':')
+    except ValueError:
+        project_name = full_suite
+        suite_name = full_suite
+
+    duration = data['duration']
+    return_code = data['returncode']
+    log = data['stdout']
+    log_stderr = data.get('stderr', '')
+
+    unit = {
+        'suite': suite_name,
+        'name': unit_name,
+        'duration': duration,
+        'returncode': return_code,
+        'stdout': log,
+        'stderr': log_stderr,
+    }
+
+    units = suites.setdefault(suite_name, [])
+    units.append(unit)
+
+for name, units in suites.items():
+    print('Processing suite {} (units: {})'.format(name, len(units)))
+
+    def if_failed(unit):
+        if unit['returncode'] != 0:
+            return True
+        return False
+
+    def if_succeded(unit):
+        if unit['returncode'] == 0:
+            return True
+        return False
+
+    successes = list(filter(if_succeded, units))
+    failures = list(filter(if_failed, units))
+    print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures)))
+
+    testsuite = ET.SubElement(testsuites, 'testsuite')
+    testsuite.set('name', '{}/{}'.format(args.project_name, name))
+    testsuite.set('tests', str(len(units)))
+    testsuite.set('errors', str(len(failures)))
+    testsuite.set('failures', str(len(failures)))
+
+    for unit in successes:
+        testcase = ET.SubElement(testsuite, 'testcase')
+        testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
+        testcase.set('name', unit['name'])
+        testcase.set('time', str(unit['duration']))
+
+    for unit in failures:
+        testcase = ET.SubElement(testsuite, 'testcase')
+        testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
+        testcase.set('name', unit['name'])
+        testcase.set('time', str(unit['duration']))
+
+        failure = ET.SubElement(testcase, 'failure')
+        failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
+        failure.set('name', unit['name'])
+        failure.set('type', 'error')
+        failure.text = unit['stdout'] + '\n' + unit['stderr']
+
+output = ET.tostring(testsuites, encoding='unicode')
+outfile.write(output)
diff --git a/.gitlab-ci/mingw.Dockerfile b/.gitlab-ci/mingw.Dockerfile
new file mode 100644
index 0000000..d89de8c
--- /dev/null
+++ b/.gitlab-ci/mingw.Dockerfile
@@ -0,0 +1,73 @@
+FROM fedora:29
+
+RUN dnf -y install \
+    bindfs \
+    clang \
+    clang-analyzer \
+    desktop-file-utils \
+    elfutils-libelf-devel \
+    findutils \
+    fuse \
+    gamin-devel \
+    gcc \
+    gcc-c++ \
+    gettext \
+    git \
+    glibc-devel \
+    glibc-headers \
+    glibc-langpack-de \
+    glibc-langpack-el \
+    glibc-langpack-el \
+    glibc-langpack-en \
+    glibc-langpack-es \
+    glibc-langpack-es \
+    glibc-langpack-fa \
+    glibc-langpack-fr \
+    glibc-langpack-hr \
+    glibc-langpack-ja \
+    glibc-langpack-lt \
+    glibc-langpack-pl \
+    glibc-langpack-ru \
+    glibc-langpack-tr \
+    gtk-doc \
+    itstool \
+    lcov \
+    libattr-devel \
+    libffi-devel \
+    libmount-devel \
+    libselinux-devel \
+    libxslt \
+    mingw64-gcc \
+    mingw64-gcc-c++ \
+    mingw64-gettext \
+    mingw64-libffi \
+    mingw64-zlib \
+    ncurses-compat-libs \
+    ninja-build \
+    pcre-devel \
+    python3 \
+    python3-pip \
+    python3-wheel \
+    systemtap-sdt-devel \
+    unzip \
+    wget \
+    xz \
+    zlib-devel \
+ && dnf clean all
+
+WORKDIR /opt
+COPY cross_file_mingw64.txt /opt
+
+RUN pip3 install meson==0.49.2
+
+ARG HOST_USER_ID=5555
+ENV HOST_USER_ID ${HOST_USER_ID}
+RUN useradd -u $HOST_USER_ID -ms /bin/bash user
+
+USER user
+WORKDIR /home/user
+
+COPY cache-subprojects.sh .
+RUN ./cache-subprojects.sh
+
+ENV LANG C.UTF-8
diff --git a/.gitlab-ci/run-check-todos.sh b/.gitlab-ci/run-check-todos.sh
new file mode 100755
index 0000000..8af1027
--- /dev/null
+++ b/.gitlab-ci/run-check-todos.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+# We need to add a new remote for the upstream target branch, since this script
+# could be running in a personal fork of the repository which has out of date
+# branches.
+git remote add upstream https://gitlab.gnome.org/GNOME/glib.git
+git fetch upstream
+
+# Work out the newest common ancestor between the detached HEAD that this CI job
+# has checked out, and the upstream target branch (which will typically be
+# `upstream/master` or `upstream/glib-2-62`).
+# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
+# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
+newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
+./.gitlab-ci/check-todos.py "${newest_common_ancestor_sha}"
diff --git a/.gitlab-ci/run-docker.sh b/.gitlab-ci/run-docker.sh
new file mode 100755
index 0000000..9b6fce4
--- /dev/null
+++ b/.gitlab-ci/run-docker.sh
@@ -0,0 +1,132 @@
+#!/bin/bash
+
+read_arg() {
+    # $1 = arg name
+    # $2 = arg value
+    # $3 = arg parameter
+    local rematch='^[^=]*=(.*)$'
+    if [[ $2 =~ $rematch ]]; then
+        read -r "$1" <<< "${BASH_REMATCH[1]}"
+    else
+        read -r "$1" <<< "$3"
+        # There is no way to shift our callers args, so
+        # return 1 to indicate they should do it instead.
+        return 1
+    fi
+}
+
+SUDO_CMD="sudo"
+if docker -v |& grep -q podman; then
+        # Using podman
+        SUDO_CMD=""
+        # Docker is actually implemented by podman, and its OCI output
+        # is incompatible with some of the dockerd instances on GitLab
+        # CI runners.
+        export BUILDAH_FORMAT=docker
+fi
+
+set -e
+
+base=""
+base_version=""
+build=0
+run=0
+push=0
+list=0
+print_help=0
+no_login=0
+
+while (($# > 0)); do
+        case "${1%%=*}" in
+                build) build=1;;
+                run) run=1;;
+                push) push=1;;
+                list) list=1;;
+                help) print_help=1;;
+                --base|-b) read_arg base "$@" || shift;;
+                --base-version) read_arg base_version "$@" || shift;;
+                --no-login) no_login=1;;
+                *) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
+        esac
+        shift
+done
+
+if [ $print_help == 1 ]; then
+        echo "$0 - Build and run Docker images"
+        echo ""
+        echo "Usage: $0 <command> [options] [basename]"
+        echo ""
+        echo "Available commands"
+        echo ""
+        echo "  build --base=<BASENAME> - Build Docker image <BASENAME>.Dockerfile"
+        echo "  run --base=<BASENAME>   - Run Docker image <BASENAME>"
+        echo "  push --base=<BASENAME>  - Push Docker image <BASENAME> to the registry"
+        echo "  list                    - List available images"
+        echo "  help                    - This help message"
+        echo ""
+        exit 0
+fi
+
+cd "$(dirname "$0")"
+
+if [ $list == 1 ]; then
+        echo "Available Docker images:"
+        for f in *.Dockerfile; do
+                filename=$( basename -- "$f" )
+                basename="${filename%.*}"
+
+                echo -e "  \e[1;39m$basename\e[0m"
+        done
+        exit 0
+fi
+
+# All commands after this require --base to be set
+if [ -z "${base}" ]; then
+        echo "Usage: $0 <command>"
+        exit 1
+fi
+
+if [ ! -f "$base.Dockerfile" ]; then
+        echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found"
+        exit 1
+fi
+
+if [ -z "${base_version}" ]; then
+        base_version="latest"
+else
+        base_version="v$base_version"
+fi
+
+TAG="registry.gitlab.gnome.org/gnome/glib/${base}:${base_version}"
+
+if [ $build == 1 ]; then
+        echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
+        $SUDO_CMD docker build \
+                --build-arg HOST_USER_ID="$UID" \
+                --tag "${TAG}" \
+                --file "${base}.Dockerfile" .
+        exit $?
+fi
+
+if [ $push == 1 ]; then
+        echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}"
+
+        if [ $no_login == 0 ]; then
+                $SUDO_CMD docker login registry.gitlab.gnome.org
+        fi
+
+        $SUDO_CMD docker push $TAG
+        exit $?
+fi
+
+if [ $run == 1 ]; then
+        echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
+        $SUDO_CMD docker run \
+                --rm \
+                --volume "$(pwd)/..:/home/user/app" \
+                --workdir "/home/user/app" \
+                --tty \
+                --interactive "${TAG}" \
+                bash
+        exit $?
+fi
diff --git a/.gitlab-ci/run-style-check-diff.sh b/.gitlab-ci/run-style-check-diff.sh
new file mode 100755
index 0000000..1f7b8c1
--- /dev/null
+++ b/.gitlab-ci/run-style-check-diff.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+set -e
+
+# Wrap everything in a subshell so we can propagate the exit status.
+(
+
+# We need to add a new remote for the upstream target branch, since this script
+# could be running in a personal fork of the repository which has out of date
+# branches.
+git remote add upstream https://gitlab.gnome.org/GNOME/glib.git
+git fetch upstream
+
+# Work out the newest common ancestor between the detached HEAD that this CI job
+# has checked out, and the upstream target branch (which will typically be
+# `upstream/master` or `upstream/glib-2-62`).
+# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
+# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
+newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
+git diff -U0 --no-color "${newest_common_ancestor_sha}" | ./clang-format-diff.py -binary "clang-format-7" -p1
+
+)
+exit_status=$?
+
+# The style check is not infallible. The clang-format configuration cannot
+# perfectly describe GLib’s coding style: in particular, it cannot align
+# function arguments. The documented coding style for GLib takes priority over
+# clang-format suggestions. Hopefully we can eventually improve clang-format to
+# be configurable enough for our coding style. That’s why this CI check is OK
+# to fail: the idea is that people can look through the output and ignore it if
+# it’s wrong. (That situation can also happen if someone touches pre-existing
+# badly formatted code and it doesn’t make sense to tidy up the wider coding
+# style with the changes they’re making.)
+echo ""
+echo "Note that clang-format output is advisory and cannot always match the GLib coding style, documented at"
+echo "   https://gitlab.gnome.org/GNOME/gtk/blob/master/docs/CODING-STYLE"
+echo "Warnings from this tool can be ignored in favour of the documented coding style,"
+echo "or in favour of matching the style of existing surrounding code."
+
+exit ${exit_status}
diff --git a/.gitlab-ci/run-tests.sh b/.gitlab-ci/run-tests.sh
new file mode 100755
index 0000000..b545a6f
--- /dev/null
+++ b/.gitlab-ci/run-tests.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set +e
+
+case "$1" in
+  --log-file)
+    log_file="$2"
+    shift
+    shift
+    ;;
+  *)
+    log_file="_build/meson-logs/testlog.json"
+esac
+
+meson test \
+        -C _build \
+        --timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
+        --no-suite flaky \
+        "$@"
+
+exit_code=$?
+
+python3 .gitlab-ci/meson-junit-report.py \
+        --project-name=glib \
+        --job-id "${CI_JOB_NAME}" \
+        --output "_build/${CI_JOB_NAME}-report.xml" \
+        "${log_file}"
+
+exit $exit_code
diff --git a/.gitlab-ci/show-execution-environment.sh b/.gitlab-ci/show-execution-environment.sh
new file mode 100755
index 0000000..0c22651
--- /dev/null
+++ b/.gitlab-ci/show-execution-environment.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -eux -o pipefail
+
+id || :
+capsh --print || :
+env -0 | sort -z | perl -pe 's/\0/\n/g' || :
+setpriv --dump || :
+ulimit -a || :
+cat /proc/self/status || :
+cat /proc/self/mountinfo || :
diff --git a/.gitlab-ci/test-msvc.bat b/.gitlab-ci/test-msvc.bat
new file mode 100644
index 0000000..6cc6d80
--- /dev/null
+++ b/.gitlab-ci/test-msvc.bat
@@ -0,0 +1,24 @@
+@echo on
+:: vcvarsall.bat sets various env vars like PATH, INCLUDE, LIB, LIBPATH for the
+:: specified build architecture
+call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
+@echo on
+
+:: FIXME: make warnings fatal
+pip3 install --upgrade --user meson==0.49.2  || goto :error
+meson _build || goto :error
+ninja -C _build || goto :error
+
+:: FIXME: dont ignore test errors
+meson test -C _build --timeout-multiplier %MESON_TEST_TIMEOUT_MULTIPLIER% --no-suite flaky
+
+:: FIXME: can we get code coverage support?
+
+
+python "%CD%\.gitlab-ci\meson-junit-report.py" --project-name glib ^
+--job-id "%CI_JOB_NAME%" --output "%CD%/_build/%CI_JOB_NAME%-report.xml" ^
+"%CD%/_build/meson-logs/testlog.json"
+
+goto :EOF
+:error
+exit /b 1
diff --git a/.gitlab-ci/test-msys2.sh b/.gitlab-ci/test-msys2.sh
new file mode 100755
index 0000000..9845b1a
--- /dev/null
+++ b/.gitlab-ci/test-msys2.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+set -e
+
+export PATH="/c/msys64/$MSYSTEM/bin:$PATH"
+if [[ "$MSYSTEM" == "MINGW32" ]]; then
+    export MSYS2_ARCH="i686"
+else
+    export MSYS2_ARCH="x86_64"
+fi
+
+pacman --noconfirm -Suy
+
+pacman --noconfirm -S --needed \
+    base-devel \
+    mingw-w64-$MSYS2_ARCH-ccache \
+    mingw-w64-$MSYS2_ARCH-gettext \
+    mingw-w64-$MSYS2_ARCH-libffi \
+    mingw-w64-$MSYS2_ARCH-meson \
+    mingw-w64-$MSYS2_ARCH-pcre \
+    mingw-w64-$MSYS2_ARCH-python3 \
+    mingw-w64-$MSYS2_ARCH-python3-pip \
+    mingw-w64-$MSYS2_ARCH-toolchain \
+    mingw-w64-$MSYS2_ARCH-zlib \
+    mingw-w64-$MSYS2_ARCH-libelf
+
+curl -O -J -L "https://github.com/linux-test-project/lcov/releases/download/v1.14/lcov-1.14.tar.gz"
+echo "14995699187440e0ae4da57fe3a64adc0a3c5cf14feab971f8db38fb7d8f071a  lcov-1.14.tar.gz" | sha256sum -c
+tar -xzf lcov-1.14.tar.gz
+# FIXME: not currently using lcov, see below
+#LCOV="$(pwd)/lcov-1.14/bin/lcov"
+
+mkdir -p _coverage
+mkdir -p _ccache
+CCACHE_BASEDIR="$(pwd)"
+CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
+export CCACHE_BASEDIR CCACHE_DIR
+
+pip3 install --upgrade --user meson==0.49.2
+
+PATH="$(cygpath "$USERPROFILE")/.local/bin:$HOME/.local/bin:$PATH"
+CFLAGS="-coverage -ftest-coverage -fprofile-arcs"
+DIR="$(pwd)"
+export PATH CFLAGS
+
+meson --werror --buildtype debug _build
+cd _build
+ninja
+
+# FIXME: lcov doesn't support gcc9 yet:
+# https://github.com/linux-test-project/lcov/issues/58
+#"${LCOV}" \
+#    --quiet \
+#    --config-file "${DIR}"/.gitlab-ci/lcovrc \
+#    --directory "${DIR}/_build" \
+#    --capture \
+#    --initial \
+#    --output-file "${DIR}/_coverage/${CI_JOB_NAME}-baseline.lcov"
+
+# FIXME: fix the test suite
+meson test --timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" --no-suite flaky || true
+
+python3 "${DIR}"/.gitlab-ci/meson-junit-report.py \
+        --project-name glib \
+        --job-id "${CI_JOB_NAME}" \
+        --output "${DIR}/_build/${CI_JOB_NAME}-report.xml" \
+        "${DIR}/_build/meson-logs/testlog.json"
+
+# FIXME: see above
+#"${LCOV}" \
+#    --quiet \
+#    --config-file "${DIR}"/.gitlab-ci/lcovrc \
+#    --directory "${DIR}/_build" \
+#    --capture \
+#    --output-file "${DIR}/_coverage/${CI_JOB_NAME}.lcov"
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..16884db
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,40 @@
+Below are just a few of the people who have contributed
+to GLib. Please don't mail these people about problems you
+have with GLib; see the README.md file for information about
+filing bugs and submitting changes.
+
+GLib-2.0 Team
+-------------
+Hans Breuer        <hans@breuer.org>
+Matthias Clasen    <mclasen@redhat.com>
+Tor Lillqvist      <tml@iki.fi>
+Tim Janik          <timj@gtk.org>
+Havoc Pennington   <hp@redhat.com> 
+Ron Steinke        <rsteinke@w-link.net>
+Owen Taylor        <otaylor@redhat.com>
+Sebastian Wilhelmi <seppi@seppi.de>
+
+GLib-1.2 Team
+-------------
+Shawn T. Amundson  <amundson@gimp.org>
+Jeff Garzik        <jgarzik@pobox.com>
+Raja R Harinath    <harinath@cs.umn.edu>
+Tim Janik          <timj@gtk.org>
+Elliot Lee         <sopwith@redhat.com>
+Tor Lillqvist      <tml@iki.fi>
+Paolo Molaro       <lupus@debian.org>
+Havoc Pennington   <hp@pobox.com>
+Manish Singh       <yosh@gimp.org>
+Owen Taylor        <otaylor@gtk.org>
+Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+The random number generator "Mersenne Twister", which is used by GLib,
+was developed and originally coded by:
+Makoto Matsumoto   <matumoto@math.keio.ac.jp>
+Takuji Nishimura   <nisimura@math.keio.ac.jp>
+
+Original Authors
+----------------
+Peter Mattis       <petm@xcf.berkeley.edu>
+Spencer Kimball    <spencer@xcf.berkeley.edu>
+Josh MacDonald     <jmacd@xcf.berkeley.edu>
diff --git a/Android.mk b/Android.mk
new file mode 100755
index 0000000..6571161
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1 @@
+include $(all-subdir-makefiles)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..52f17b1
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,274 @@
+# Contribution guidelines
+
+Thank you for considering contributing to the GLib project!
+
+These guidelines are meant for new contributors, regardless of their level
+of proficiency; following them allows the core developers of the GLib project to
+more effectively evaluate your contribution, and provide prompt feedback to
+you. Additionally, by following these guidelines you clearly communicate
+that you respect the time and effort that the people developing GLib put into
+managing the project.
+
+GLib is a complex free software utility library, and it would not exist without
+contributions from the free and open source software community. There are
+many things that we value:
+
+ - bug reporting and fixing
+ - documentation and examples
+ - tests
+ - testing and support for other platforms
+ - new features
+
+Please, do not use the issue tracker for support questions. If you have
+questions on how to use GLib effectively, you can use:
+
+ - the `#gtk` IRC channel on irc.gnome.org
+ - the [`glib` tag on GNOME's Discourse](https://discourse.gnome.org/tags/glib)
+
+You can also look at the [`glib` tag on Stack
+Overflow](https://stackoverflow.com/questions/tagged/glib).
+
+The issue tracker is meant to be used for actionable issues only.
+
+## How to report bugs
+
+### Security issues
+
+You should not open a new issue for security related questions.
+
+When in doubt, send an email to the [security](mailto:security@gnome.org)
+mailing list.
+
+### Bug reports
+
+If you’re reporting a bug make sure to list:
+
+ 0. which version of GLib are you using?
+ 0. which operating system are you using?
+ 0. the necessary steps to reproduce the issue
+ 0. the expected outcome
+ 0. a description of the behavior
+ 0. a small, self-contained example exhibiting the behavior
+
+If the issue includes a crash, you should also include:
+
+ 0. the eventual warnings printed on the terminal
+ 0. a backtrace, obtained with tools such as GDB or LLDB
+
+If the issue includes a memory leak, you should also include:
+
+ 0. a log of definite leaks from a tool such as [valgrind’s
+    memcheck](http://valgrind.org/docs/manual/mc-manual.html)
+
+For small issues, such as:
+
+ - spelling/grammar fixes in the documentation,
+ - typo correction,
+ - comment clean ups,
+ - changes to metadata files (CI, `.gitignore`),
+ - build system changes, or
+ - source tree clean ups and reorganizations;
+
+or for self-contained bug fixes where you have implemented and tested a solution
+already, you should directly open a merge request instead of filing a new issue.
+
+### Features and enhancements
+
+Feature discussion can be open ended and require high bandwidth channels; if
+you are proposing a new feature on the issue tracker, make sure to make
+an actionable proposal, and list:
+
+ 0. what you’re trying to achieve and the problem it solves
+ 0. three (or more) existing pieces of software which would benefit from the
+    new feature
+ 0. how the feature is implementable on platforms other than Linux
+
+New APIs, in particular, should follow the ‘rule of three’, where there should
+be three (or more) pieces of software which are ready to use the new APIs. This
+allows us to check that the new APIs are usable in real-life code, and fit well
+with related APIs. This reduces the chances of awkward or unusable APIs becoming
+stable in GLib and having to be supported forever.
+
+A common way to introduce new APIs or data types to GLib is to prototype them in
+another code base for a while, to gain real-life experience with them before
+they are imported into GLib and marked as stable.
+
+Each feature should also come fully documented, and with tests which approach
+full branch coverage of the new code. GLib’s CI system generates code coverage
+reports which are viewable for each merge request.
+
+If proposing a large feature or change, it’s better to discuss it (on the
+`#gtk` IRC channel or on [Discourse](https://discourse.gnome.org) before
+putting time into writing an actionable issue — and certainly before putting
+time into writing a merge request.
+
+## Your first contribution
+
+### Prerequisites
+
+If you want to contribute to the GLib project, you will need to have the
+development tools appropriate for your operating system, including:
+
+ - Python 3.x
+ - Meson
+ - Ninja
+ - Gettext (19.7 or newer)
+ - a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
+
+Up-to-date instructions about developing GNOME applications and libraries
+can be found on [the GNOME Developer Center](https://developer.gnome.org).
+
+The [GLib project uses GitLab](https://gitlab.gnome.org/GNOME/glib/) for code
+hosting and for tracking issues. More information about using GitLab can be
+found [on the GNOME wiki](https://wiki.gnome.org/GitLab).
+
+### Getting started
+
+You should start by forking the GLib repository from the GitLab web UI, and
+cloning from your fork:
+
+```sh
+$ git clone https://gitlab.gnome.org/yourusername/glib.git
+$ cd glib
+```
+
+**Note**: if you plan to push changes to back to the main repository and
+have a GNOME account, you can skip the fork, and use the following instead:
+
+```sh
+$ git clone git@gitlab.gnome.org:GNOME/glib.git
+$ cd glib
+```
+
+To compile the Git version of GLib on your system, you will need to
+configure your build using Meson:
+
+```sh
+$ meson _builddir .
+$ cd _builddir
+$ ninja
+```
+
+Typically, you should work on your own branch:
+
+```sh
+$ git checkout -b your-branch
+```
+
+Once you’ve finished working on the bug fix or feature, push the branch
+to the Git repository and open a new merge request, to let the GLib
+core developers review your contribution.
+
+### Code reviews
+
+Each contribution is reviewed by the core developers of the GLib project.
+
+The [CODEOWNERS](./docs/CODEOWNERS) document contains the list of core
+contributors to GLib and the areas for which they are responsible; you
+should ensure to receive their review and signoff on your changes.
+
+It is our intention that every commit to GLib is reviewed by at least one other
+person, including commits from core developers. We all make mistakes and can
+always learn from each other, and code review allows that. It also reduces
+[bus factor](https://en.wikipedia.org/wiki/Bus_factor) by spreading knowledge
+of each commit between at least two people.
+
+With each code review, we intend to:
+
+ 0. Identify if this is a desirable change or new feature. Ideally for larger
+    features this will have been discussed (in an issue, on IRC, or on Discourse)
+    already, so that effort isn’t wasted on putting together merge requests
+    which will be rejected.
+ 0. Check the design of any new API.
+ 0. Provide realistic estimates of how long a review might take, if it can’t
+    happen immediately.
+ 0. Ensure that all significant contributions of new code, or bug fixes, are
+    adequately tested, either through requiring tests to be submitted at the
+    same time, or as a follow-up.
+ 0. Ensure that all new APIs are documented and have [introspection
+    annotations](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations).
+ 0. Check that the contribution is split into logically separate commits, each
+    with a good commit message.
+ 0. Encourage further high quality contributions.
+ 0. Ensure code style and quality is upheld.
+
+If a code review is stalled (due to not receiving comments for two or more
+weeks; or due to a technical disagreement), please ping another GLib core
+developer on the merge request, or on IRC, to ask for a second opinion.
+
+### Commit messages
+
+The expected format for git commit messages is as follows:
+
+```plain
+Short explanation of the commit
+
+Longer explanation explaining exactly what’s changed, whether any
+external or private interfaces changed, what bugs were fixed (with bug
+tracker reference if applicable) and so forth. Be concise but not too
+brief.
+
+Closes #1234
+```
+
+ - Always add a brief description of the commit to the _first_ line of
+ the commit and terminate by two newlines (it will work without the
+ second newline, but that is not nice for the interfaces).
+
+ - First line (the brief description) must only be one sentence and
+ should start with a capital letter unless it starts with a lowercase
+ symbol or identifier. Don’t use a trailing period either. Don’t exceed
+ 72 characters.
+
+ - The main description (the body) is normal prose and should use normal
+ punctuation and capital letters where appropriate. Consider the commit
+ message as an email sent to the developers (or yourself, six months
+ down the line) detailing **why** you changed something. There’s no need
+ to specify the **how**: the changes can be inlined.
+
+ - When committing code on behalf of others use the `--author` option, e.g.
+ `git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
+
+ - If your commit is addressing an issue, use the
+ [GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
+ to automatically close the issue when merging the commit with the upstream
+ repository:
+
+```plain
+Closes #1234
+Fixes #1234
+Closes: https://gitlab.gnome.org/GNOME/glib/issues/1234
+```
+
+ - If you have a merge request with multiple commits and none of them
+ completely fixes an issue, you should add a reference to the issue in
+ the commit message, e.g. `Bug: #1234`, and use the automatic issue
+ closing syntax in the description of the merge request.
+
+### Merge access to the GLib repository
+
+GLib is part of the GNOME infrastructure. At the current time, any
+person with write access to the GNOME repository can merge merge requests to
+GLib. This is a good thing, in that it allows maintainership to be delegated
+and shared as needed. However, GLib is a fairly large and complicated package
+that many other things depend on, and which has platform specific behavior — so
+to avoid unnecessary breakage, and to take advantage of the knowledge about GLib
+that has been built up over the years, we’d like to ask people contributing to
+GLib to follow a few rules:
+
+0. Never push to the `master` branch, or any stable branches, directly; you
+   should always go through a merge request, to ensure that the code is
+   tested on the CI infrastructure at the very least. A merge request is
+   also the proper place to get a comprehensive code review from the core
+   developers of GLib.
+
+0. Always get a code review, even for seemingly trivial changes.
+
+0. Pay attention to the CI results. Merge requests cannot be merged until the
+   CI passes. If they consistently fail, either something is wrong with the
+   change, or the CI tests need fixing — in either case, please bring this to
+   the attention of a core developer rather than overriding the CI.
+
+If you have been contributing to GLib for a while and you don’t have commit
+access to the repository, you may ask to obtain it following the [GNOME account
+process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..4362b49
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/HACKING b/HACKING
new file mode 100644
index 0000000..3306350
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,17 @@
+If you want to hack on the GLib project, you'll need to have the
+following packages installed:
+
+        - Meson 0.48.0
+        - GNU gettext 0.10.40
+        - pkg-config 0.16
+        - gtk-doc
+        - libffi 3.0.0
+
+To compile a Git version of glib on your system, you will need to take
+several steps to setup the tree for compilation.  You can do all these
+steps at once by running:
+
+        checkout/glib# meson _build
+
+For information about submitting patches see the CONTRIBUTING.md file. For
+information about major design decisions, see the README.rationale file.
diff --git a/INSTALL.in b/INSTALL.in
new file mode 100644
index 0000000..12774c3
--- /dev/null
+++ b/INSTALL.in
@@ -0,0 +1,125 @@
+Simple install procedure
+========================
+
+  % tar xf glib-@GLIB_VERSION@.tar.gz       # unpack the sources
+  % cd glib-@GLIB_VERSION@                  # change to the toplevel directory
+  % meson _build                            # configure the build
+  % ninja -C _build                         # build GLib
+
+  [ Become root if necessary ]
+  % ninja -C _build install                 # install GLib
+
+Requirements
+============
+
+GLib requires a C90-compliant (but not necessarily C99-compliant) C
+compiler and libc. On UNIX-like systems, it also assumes compliance
+with at least the original 1990 version of POSIX.
+
+GLib-2.0 requires pkg-config, which is tool for tracking the
+compilation flags needed for libraries. (For each library, a small .pc
+text file is installed in a standard location that contains the
+compilation flags needed for that library along with version number
+information.) Information about pkg-config can be found at:
+
+  http://www.freedesktop.org/software/pkgconfig/
+
+Meson (http://mesonbuild.com/) is also required.
+
+In order to implement conversions between character sets,
+GLib requires an implementation of the standard iconv() routine.
+Most modern systems will have a suitable implementation, however
+many older systems lack an iconv() implementation. On such systems,
+you must install the libiconv library. This can be found at:
+
+ http://www.gnu.org/software/libiconv/
+
+If your system has an iconv implementation but you want to use
+libiconv instead, you can pass the --with-libiconv option to
+configure. This forces libiconv to be used.
+
+Note that if you have libiconv installed in your default include
+search path (for instance, in /usr/local/), but don't enable
+it, you will get an error while compiling GLib because the
+iconv.h that libiconv installs hides the system iconv.
+
+If you are using the native iconv implementation on Solaris
+instead of libiconv, you'll need to make sure that you have
+the converters between locale encodings and UTF-8 installed.
+At a minimum you'll need the SUNWuiu8 package. You probably
+should also install the SUNWciu8, SUNWhiu8, SUNWjiu8, and
+SUNWkiu8 packages.
+
+The native iconv on Compaq Tru64 doesn't contain support for
+UTF-8, so you'll need to use GNU libiconv instead. (When
+using GNU libiconv for GLib, you'll need to use GNU libiconv
+for GNU gettext as well.) This probably applies to related
+operating systems as well.
+
+Finally, for message catalog handling, GLib requires an implementation
+of gettext(). If your system doesn't provide this functionality,
+you should use the libintl library from the GNU gettext package,
+available from:
+
+ http://www.gnu.org/software/gettext/
+
+Support for extended attributes and SELinux in GIO requires
+libattr and libselinux.
+
+Some of the mimetype-related functionality in GIO requires the
+update-mime-database and update-desktop-database utilities, which
+are part of shared-mime-info and desktop-file-utils, respectively.
+
+GObject uses libffi to implement generic marshalling functionality.
+
+The Nitty-Gritty
+================
+
+Complete information about installing GLib can be found
+in the file:
+
+ docs/reference/glib/html/glib-building.html
+
+Or online at:
+
+ https://developer.gnome.org/glib/stable/glib-building.html
+
+
+Installation directories
+========================
+
+The location of the installed files is determined by the --prefix
+and --exec-prefix options given to configure. There are also more
+detailed flags to control individual directories. However, the
+use of these flags is not tested.
+
+One particular detail to note, is that the architecture-dependent
+include file glibconfig.h is installed in:
+
+  $exec_prefix/lib/glib/include/
+
+if you have a version in $prefix/include, this is out of date
+and should be deleted.
+
+.pc files for the various libraries are installed in
+$exec_prefix/lib/pkgconfig to provide information when compiling
+other packages that depend on GLib. If you set PKG_CONFIG_PATH
+so that it points to this directory, then you can get the
+correct include flags and library flags for compiling a GLib
+application with:
+
+ pkg-config --cflags glib-2.0
+ pkg-config --libs glib-2.0
+
+
+Cross-compiling GLib
+====================
+
+Information about cross-compilation of GLib can be found
+in the file:
+
+ docs/reference/glib/html/glib-cross-compiling.html
+
+Or online at:
+
+ https://developer.gnome.org/glib/stable/glib-cross-compiling.html
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..fe32008
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,12294 @@
+Overview of changes in GLib 2.64.0
+==================================
+
+* Use `posix_spawn()` to speed up launching test D-Bus instances (!1388)
+
+* Bugs fixed:
+ - #1783 Document using glib-mkenums with meson
+ - #2049 Crash in g_array_copy
+ - !1384 Some minor clang warning fixes
+ - !1386 docs: Document generated headers caveats for genmarshal
+ - !1387 ci: Correctly propagate exit status in run-style-check-diff.sh
+ - !1388 gtestdbus: Use posix_spawn() to spawn dbus-daemon
+ - !1389 Update GError docs to use G_DEFINE_QUARK
+
+* Translation updates:
+ - Czech
+ - Danish
+
+
+Overview of changes in GLib 2.63.6
+==================================
+
+* Fix potential relative read when calling g_printerr(), which could lead to a
+  denial of service from a setuid-root process being used to block access to the
+  TTY for another user (#1919)
+
+* Fix SOCKS proxy resolver sometimes not being used when resolving addresses
+  via Happy Eyeballs (CVE-2020-6750) (#1989)
+
+* Several other Happy Eyeballs fixes for address resolution (#1871, #1872, #1902)
+
+* Various race fixes in `GDBusConnection` and its unit tests (#1515)
+
+* Fix a race condition with D-Bus name ownership (#1517)
+
+* Drop `gio-launch-desktop` helper application in favour of calling `sh` directly (#1633)
+
+* Fix win32 exception handling with C# exceptions (#2025)
+
+* Fix thread safety of `GUnixMountMonitor` (#2030)
+
+* Additional fixes to new thread pool attribute behaviour from GLib 2.63.4 to
+  check if sched_setattr() is allowed by system policies before depending on it (#2039, !1356)
+
+* Fix memory leaks and corruption when freeing `GSource`s while freeing a `GMainContext` (!1353)
+
+* Drop inappropriate installation of object manager example documentation (!1359)
+
+* Bugs fixed:
+ - #938 gdbus call -a doesn't support message bus connections
+ - #1515 gio/gdbus-threading test sometimes fails in CI
+ - #1517 g_bus_own_name does not always call name_lost_handler when _REPLACE and _ALLOW_REPLACEMENT are set
+ - #1633 should not install gio-launch-desktop into PATH
+ - #1919 read from relative path in g_printerr() in 2.58.3
+ - #1995 Tracker issue for Happy Eyeballs regressions
+ - #2002 g_io_channel_read_line does not honour the line_term symbols set
+ - #2025 W32 exception handling misbehaves when C# exceptions are thrown when running inside the Visual Studio debugger
+ - #2030 Random nautilus test suite failures involving GUnixMountMonitor
+ - #2039 sched_setattr() still can cause EPERM through natural causes
+ - #2043 Low memory monitor test failed in CI
+ - #2044 GApplication docs suggest invalid GVariant type
+ - !1185 gtimezone: Tidy up UTC timezone creation
+ - !1281 ci: Update Docker packages
+ - !1283 gmodule: change _g_module_close to only take a handle.
+ - !1298 tests: Speed up the GIO actions test
+ - !1299 gapplication: Fix a minor typo in the documentation
+ - !1339 gsocketclient: Refactor g_socket_client_connect_async()
+ - !1353 GMainContext - Fix memory leaks and memory corruption when freeing sources while freeing a context
+ - !1354 GThreadPool - Add test for !1340
+ - !1355 glist: Add docs examples of how to combine with g_steal_pointer()
+ - !1356 GThread - Check if sched_setattr is allowed by the system policies before depending on it
+ - !1359 docs: Don’t install object manager example separately
+ - !1363 Make tests pass if we are euid != 0 with capabilities
+ - !1366 Fix oss-fuzz coverage link
+ - !1372 gobject: Fix strict aliasing warnings with g_set_object()
+ - !1376 gitlab-ci: 64-bit ARM is aarch64, not arm64
+ - !1381 ghash: Document the iteration order over a hash table is not defined
+ - !1382 tests: Bump the refcount timeout in gdbus-threading
+ - !1383 ci: Enable parallelisation when running installed tests
+
+* Translation updates:
+ - Basque
+ - English (United Kingdom)
+ - French
+ - Galician
+ - German
+ - Greek, Modern (1453-)
+ - Hungarian
+ - Indonesian
+ - Japanese
+ - Korean
+ - Lithuanian
+ - Polish
+ - Portuguese (Brazil)
+ - Spanish
+ - Swedish
+ - Turkish
+
+
+Overview of changes in GLib 2.63.5
+==================================
+
+* Fix behaviour of `g_file_move()` fallback code to not follow symlinks (#986)
+
+* Rename `--glib-min-version` argument of `gdbus-codegen` to `--glib-min-required`
+  (this is not an API break as `--glib-min-version` was added earlier in the
+  2.63 cycle) (#1993)
+
+* Add gtk-doc checks to CI and fix a number of documentation issues
+  (thanks to Xavier Claessens) (!978)
+
+* Add `G_SIZEOF_MEMBER()` macro (!1333)
+
+* Add a debug message if `g_setenv()` or `g_unsetenv()` are used after any
+  threads have been spawned — this will be upgraded to a warning in future (!1337, #715)
+
+* Skip memory monitor tests if xdg-desktop-portal or dbusmock are not available (!1296, !1338)
+
+* Change the `libmount` configure option from a boolean to a Meson `feature` (!1344)
+
+* Do not return `target-uri` from `g_file_peek_path()` when called on trash/recent files (!1346)
+
+* Drop new TLS certificate API for PKCS #11 backed certificates, as the implementation
+  is not ready yet (this is not an API break as the API was added earlier in the
+  2.63 cycle) (!1347)
+
+* Bugs fixed:
+ - #986 g_file_move: remove G_FILE_COPY_NOFOLLOW_SYMLINKS section
+ - #1551 CI: Add checks for `TODO` in MRs
+ - #1925 Large number of routes installed into kernel cause high cpu usage
+ - #1993 Rename gdbus-codegen --glib-min-version argument to --glib-min-required and add --glib-max-allowed
+ - #2012 spawn_thread_queue not initialised in GThreadPool
+ - #2020 g_network_monitor_base_add_network() improperly unrefs GInetAddressMask
+ - !978 Various fixes to make gtkdoc-check pass on glib
+ - !1018 docs: tag enclose 'all' and 'help' values
+ - !1170 Avoid C++20 deprecated assignment to volatile
+ - !1296 tests: Skip GMemoryMonitor tests if the dbusmock template is not available
+ - !1307 Remove global declaration of GMemoryMonitor
+ - !1322 gmain: Mark G_SOURCE_FUNC as available in 2.58
+ - !1333 Add and use G_SIZEOF_MEMBER() macro
+ - !1337 genviron: Message if g_setenv()/g_unsetenv() are used after threads spawned
+ - !1338 tests: Skip GMemoryMonitor tests if xdg-desktop-portal is not available
+ - !1344 meson: libmount autodectection
+ - !1345 gio-tool-info: Print unix mount information where available
+ - !1346 gfile: Do not return target-uri from g_file_peek_path()
+ - !1347 Revert "gtlscertificate: Add support for PKCS #11 backed certificates"
+ - !1348 ghash: Clarify that g_hash_table_add() always consumes the key
+ - !1349 doc: Clarify that _locker_new() does not actually allocate memory
+ - !1351 glib.supp: update g-threaded-resolver-getaddrinfo-config
+
+* Translation updates:
+ - Japanese
+ - Lithuanian
+ - Malay
+ - Portuguese (Brazil)
+ - Swedish
+
+
+Overview of changes in GLib 2.63.4
+==================================
+
+* Fix various race conditions on signal emission in GDBus (#604, #978, #1232)
+
+* Change thread pools so that thread attributes (in particular, priority) are
+  inherited from the thread which created the `GThreadPool` initially, rather
+  than from the thread which is pushing a new job into the pool (#1834, #2007)
+
+* Expand support for running Windows apps with
+  `g_app_info_launch_default_for_uri()` using rundll32 on Windows (#1932)
+
+* Support multiple directories in `GSETTINGS_SCHEMA_DIR` environment variable (#1998)
+
+* Support full Julian day range in `TZ` environment variable (#1999)
+
+* Apply recursion depth limits to variants in D-Bus messages (!1201)
+
+* Support adding call flags and timeouts to method calls generated by
+  `gdbus-codegen` through the new `--glib-min-version` option (!1286)
+
+* Fully deprecate TLS rehandshakes; they are now ignored due to TLS protocol
+  changes (!1305)
+
+* Bugs fixed:
+ - #198 g_fopen and friends: should also state how to close a stream
+ - #604 GDBus name watching dispatch is buggy/excessively-complicated
+ - #833 g_object_set: document the need to cast varargs
+ - #978 SIGSEGV in on_name_lost_or_acquired
+ - #1232 Insufficient thread safety around GDBusObjectManagerClient
+ - #1416 Re-add macOS CI
+ - #1834 Unwanted priority/etc inheritance with GThreadPool and GThread and the POSIX implementation
+ - #1932 Windows: Gio.AppInfo.launch_default_for_uri seems not to work for local files/folders
+ - #1983 glib:gio / dbus-appinfo test fails: GLib-GIO:ERROR:../../../../Projects/glib/gio/tests/dbus-appinfo.c:326:on_flatpak_open: 'g_file_equal (files[0], f)' should be TRUE
+ - #1997 Base64 encoding with "break_lines" claims to wrap at 72 characters but seems to wrap at 76
+ - #1998 support multiple directories in GSETTINGS_SCHEMA_DIR
+ - #1999 GTimeZone fails to accept full Julian day range when parsing the direct $TZ string format
+ - #2007 Thread scheduler attributes fail under valgrind
+ - !388 ci: Avoid downloading subprojects for each job
+ - !1111 gio: test that launch_uris() exports files with the document portal when launching a flatpak
+ - !1201 gdbusmessage: Limit recursion of variants in D-Bus messages
+ - !1279 tests: Fix an error message set by foo_set_property()
+ - !1286 gdbus-codegen: Add a GDBusCallFlags arg to method calls
+ - !1291 gio-tool-list: Add an option to print display names
+ - !1294 GMemoryMonitor docs fixes
+ - !1295 gio: Fix socket test
+ - !1301 GThread - Inherit parent thread priority by default for new Win32 threads
+ - !1303 gvariant-core: Don't pass NULL second argument to memcpy
+ - !1305 Fully deprecate TLS rehandshakes
+ - !1308 gsocketclient: run timeout source on the task's main context
+ - !1309 Fix crash in gutils when application is prevented access to passwd file
+ - !1317 gfdonotificationbackend: remove notifications when bus name vanishes
+ - !1320 subprojects: Temporarily avoid using wrapdb while it’s down
+ - !1324 ci: Add some documentation to the style check CI test
+ - !1325 Check for SYS_sched_getattr before using it unconditionally
+ - !1330 W32: Correctly set st_ino when doing private stat()
+ - !1334 gthread: Ensure GThreadSchedulerSettings is always defined
+
+* Translation updates:
+ - Catalan
+ - Galician
+ - Hungarian
+ - Indonesian
+ - Polish
+ - Portuguese (Brazil)
+ - Spanish
+
+
+Overview of changes in GLib 2.63.3
+==================================
+
+* Add a `--glib-min-version` argument to `gdbus-codegen` which controls breaks in the API of generated code (#1726)
+
+* Add `g_clear_list()` API to clear `GList`s to `NULL` (#1943)
+
+* Add a `GMemoryMonitor` API to be notified of memory pressure situations using the low-memory-monitor project (!1005)
+
+* Add support for dispose functions for `GSource` implementations (!1175)
+
+* Tighten up validation of GObject signal and property names, allowing performance improvements (!1224)
+
+* Fix installation path of GIO modules on MSVC to be the bindir (!1254)
+
+* Bugs fixed:
+ - #650 g_signal_lookup gives too many warnings
+ - #1011 GListStore, easily find if the item is already inserted
+ - #1130 gdbus-codegen: Add an option to strictly generate markdown in source comments
+ - #1687 glocalvfs.c uses non-thread-safe getpwnam()
+ - #1726 Warn when method/signal uses type 'h' but lacks GDBus.C.UnixFD annotation
+ - #1935 Assert in _kqsub_free seems to be too strict
+ - #1943 Consider g_clear_list()
+ - #1947 Documentation clarification for g_uuid_string_random()
+ - #1953 Documentation for g_type_init() and others missing from online gtk-doc documentation
+ - #1961 A typo in the comment of `g_settings_schema_get_path`: threfore -> therefore
+ - !1005 gio: Add GMemoryMonitor to monitor for low-memory
+ - !1172 gptrarray: Add an example to the g_ptr_array_steal() docs
+ - !1175 Implement a dispose function for GSource
+ - !1223 Add additional valgrind suppressions
+ - !1224 Signal name handling improvements
+ - !1230 ci: Run installed-tests on Fedora
+ - !1235 Add sudo to Fedora docker image
+ - !1239 tests: Run "timeout tests" sequentially
+ - !1248 ci: Update all Debian CI runners to use v5 of the Dockerfile
+ - !1249 gio-tool-mount: Allow mounting by the given UUID
+ - !1252 ci: Fix running all jobs on merge requests
+ - !1253 gthread: Fix "zero as null pointer" warning
+ - !1254 giomodule: gio modules are no longer installed in bindir on MSVC
+ - !1255 ci: Build Docker images rather than OCI images if using podman
+ - !1256 gdate: Add autoptr support
+ - !1258 Minor CI fixups
+ - !1261 gtk-doc: Ensure we have recent enough version
+ - !1262 tests: Add tests for the gdbus-codegen executable
+ - !1265 build: don't check for protected visibility
+ - !1267 Revert "doc: Workaround gtkdoc-scan bug leading to undocumented symbols"
+ - !1268 ci: Work-around successful installed tests having no logs
+ - !1269 gvariant: Add guard to g_variant_get()
+ - !1271 tests: Enable GDBus debug for a number of unreliable tests
+ - !1274 trash portal: Don't follow symlinks
+ - !1275 Small doc correction
+ - !1277 Various gtk-doc improvements
+ - !1278 Update installed tests CI
+ - !1280 clang-format-diff: Output diff for multiple files, not just one
+ - !1282 Revert "Revert "docs: remove GDBusObjectManager example""
+ - !1284 Update POTFILES.in 191212
+ - !1287 atomic/tests: test g_atomic_pointer_compare_and_exchange() with const pointers
+ - !1289 gtype: Define auto-cleanup functions for Module class
+
+* Translation updates:
+ - Spanish
+
+
+Overview of changes in GLib 2.63.2
+==================================
+
+* Use `lldb` rather than `gdb` on macOS for debugging (#1004)
+
+* Switch the atomic builtins from `__sync_fetch_*()` to the slightly more modern
+  `__atomic_*()` (#1750)
+
+* Fix calculation of `gsize` width on various platforms (including OpenBSD) (#1777)
+
+* Fix undefined behaviour causing brokenness in `g_utf8_find_prev_char()` when
+  compiling with GCC ≥ 8 (#1917)
+
+* Revert UNIX mode changes in `G_FILE_ATTRIBUTE_ID_UNIX_MODE` which broke OSTree (#1934)
+
+* Slightly improve performance for signal emissions when no handlers are connected (!1083)
+
+* Add `g_task_return_value()` and `g_task_propagate_value()` APIs to allow
+  `GTask` to be used from language bindings more easily (!1216)
+
+* Fix a file monitoring crash on kqueue-based systems (BSD) (!1221)
+
+* Bugs fixed:
+ - #1004 [PATCH] Make gbacktrace use lldb on Mac OS X
+ - #1552 CI: Add code style checks
+ - #1750 Switch from  __sync_fetch_*() to __atomic_*() in glib/gatomic.h
+ - #1777 gsize: improper typedef on (at least) OpenBSD
+ - #1895 Regression: glib does not compile on centos 6: "objcopy: unrecognized option '--add-symbol'"
+ - #1917 Test utf8-pointer fails with static build, LTO, optimisations, and new GCC
+ - #1930 glib/tests/bookmarkfile.c:385:test_modify: assertion failed: (stamp == now)
+ - #1934 ostree tests broken since bfdc5fc4fc84ef8518d2d1a328c8482cf5a38e98: File '/tmp/test-tmp-libostree_test-basic-user.sh.test-QB4SA0/diff-test2' is not empty
+ - #1938 GDateTime doesn't support leap seconds
+ - #1940 atomics test fails on FreeBSD CI since !1123
+ - !1039 Improve documentation for footgun function g_tls_client_connection_copy_session_state()
+ - !1083 Use the GObject hole on 64bit arches for some flags to improve performance
+ - !1202 CI updates after !1177
+ - !1208 gutils: Slightly improve docs formatting for g_get_os_info()
+ - !1209 Make ld executable configurable
+ - !1210 gdbus-server-auth test: Include gcredentialsprivate.h
+ - !1213 gsocket: Improve diagnostics on bind() failure
+ - !1214 gvariant, gbytes: Avoid memcmp (NULL, ., 0) or memcmp (., NULL, 0)
+ - !1216 Make GTask more binding-friendly
+ - !1218 gdb: Fix GHashTable pretty printer off-by-one error
+ - !1220 gparam: fix memory leak in g_param_value_defaults()
+ - !1221 Add NOTE_REVOKE to the list of the monitoring events
+ - !1225 gtlsconnection: clarify handshake() documentation
+ - !1227 Deprecate old GTlsConnection functionality even harder!
+ - !1231 Fix build on old libc that does not define _SC_HOST_NAME_MAX
+ - !1238 gstrfuncs: use gsize type internally for strv functions
+ - !1242 gfileinfo: Clarify the documentation for G_FILE_ATTRIBUTE_UNIX_MODE
+ - !1243 docs: Fix "occurred" typos in API documentation
+
+* Translation updates:
+ - Spanish
+
+
+Overview of changes in GLib 2.63.1
+==================================
+
+* Several usability improvements to command line `gio` tool (!1153)
+
+* Add `g_array_steal()`, `g_ptr_array_steal()` and `g_byte_array_steal()` APIs (#285)
+
+* Add `g_get_os_info()` API (!1063, !1160)
+
+* Add `g_warning_once()` API (!1028)
+
+* Always resolve `localhost` to loopback address in `GResolver` (!616)
+
+* Add `GMainContextPusher` API (!983)
+
+* Limit recursion in `g_variant_parse()` (!1173)
+
+* Fix crash in `g_spawn()` with high FD numbers due to use of `select()` rather
+  than `poll()` (#954)
+
+* Allow passing empty `GValue`s to `g_param_value_set_default()` (!1186)
+
+* Escape header guards generated by `gdbus-codegen` better (#1379)
+
+* Bugs fixed:
+ - #285 [PATCH] add array steal and memdup functions
+ - #954 The g_spawn_sync() function uses select() which has limitations
+ - #1318 rare failure in gdbus-peer test: invalid uninstantiatable type '(null)' in cast to 'GDBusServer'
+ - #1379 gdbus-codegen generates invalid header guards when build directory contains a + character
+ - #1622 NULL pointer derefs on g_vasprintf() failure
+ - #1813 g_option_context_add_main_entries() is missing array annotation for entries parameter
+ - #1831 No reply on private socket due to auth problem
+ - #1836 gobject.c uses undefined annotation “(not optional)”
+ - #1858 docs/reference/gobject/tut_gobject.xml: object properties example uses deprecated API
+ - #1877 g_cancellable_source_new annotated with 'skip'
+ - #1896 Use after free when calling g_dbus_connection_flush_sync() in a dedicated thread
+ - #1897 glib 2.62.0 fails test 'test_writev_no_vectors' wih gcc7
+ - #1903 use-after-free in mimeapps test causes intermittent segfault during testing
+ - #1906 test_os_info fails on FreeBSD
+ - #1916 objcopy not used from cross-compilation file in GIO tests
+ - #1923 Recent Versions of GLib Break Dolphin File-Manager's Thumbnailing when Using 'gtk2' Style
+ - !616 Always resolve localhost to loopback address
+ - !983 gmain: Add GMainContextPusher convenience API
+ - !1014 tests: Add a test for g_assert_finalize_object()
+ - !1028 gmessages: Add g_warning_once()
+ - !1035 Switching from C gnu89 to C gnu99 standard
+ - !1063 gutils: Add g_get_os_info()
+ - !1082 gdatetime: Document RFC 3339 extensions when parsing ISO 8601
+ - !1105 syscall flood on every time*() function call
+ - !1120 Update documentation with FreeBSD build instructions
+ - !1135 gmain: use atomic operation instead of GMutex to access g_main_context_default()
+ - !1146 Solaris build fixes
+ - !1147 gmodule: fix typo in doc comment
+ - !1148 gio/gfileinfo: fix parameter references
+ - !1149 gio/gfile: fix parameter reference for value_p
+ - !1150 gio/gfile: fix parameter references to @contents
+ - !1151 gio/gfile: fix typo in doc comment
+ - !1152 gwinhttpvfs: Handle g_get_prgname() returning NULL
+ - !1153 Several gio-tool bash completion fixes and improvements
+ - !1155 Strict-aliasing fixes to new atomic built-ins
+ - !1157 Fix various compiler warnings on Android
+ - !1160 Add Windows support to g_get_os_info()
+ - !1161 hash: Remove an assertion from the hot path
+ - !1163 gcharset: Expand the documentation for g_get_locale_variants()
+ - !1165 Use uname as a fallback to get OS info
+ - !1167 Fix some minor leaks in testfilemonitor
+ - !1168 Fix gdatetime tests on toolbox
+ - !1171 Revert "gdbus-codegen: emit GUnixFDLists if an arg has type 'h'"
+ - !1173 gvariant: Limit recursion in g_variant_parse()
+ - !1177 ci: Add libdbus development files to CI Docker images
+ - !1179 Improve GPtrArray doc-comments
+ - !1180 array: Avoid use of memcpy(dest, NULL, 0)
+ - !1181 gmain: Clarify thread safety of some common GSource functions
+ - !1182 gio: Fix typo in URL
+ - !1186 Allow using an empty GValue with g_param_value_set_default()
+ - !1189 gparamspecs: Fix type class leaks on error handling paths
+ - !1197 Fix GDBus test failures on non-Linux (in particular FreeBSD)
+ - !1200 Minor fixes from a scan-build run
+
+* Translation updates:
+ - Catalan
+ - Chinese (Taiwan)
+ - Spanish
+
+
+Overview of changes in GLib 2.63.0
+==================================
+
+* Add g_fsync() API (#35)
+
+* Fix regression in g_file_copy() when passing
+  `G_FILE_COPY_TARGET_DEFAULT_PERMS` flag; the destination permissions would be
+  private rather than following the process’ umask (!1142)
+
+* Several `GDateTime` parsing fixes (!1127)
+
+* Always build the tests if installed-tests are enabled, so that the tests can
+  actually be installed (!1141)
+
+* Rework atomic function implementations to use memory barrier in the correct
+  place (when compiler intrinsics aren’t providing the atomics), and fix
+  signedness issues (#1449, #1565)
+
+* Use the OS’ `fdwalk()` function (if safe) to speed up `g_spawn_*()` on BSD (#1638)
+
+* Remove the macOS `dyld` `GModule` implementation in favour of `dl` instead (!1093)
+
+* Bump Python requirement to ≥ 3.5, which we implicitly relied on anyway through
+  our Meson dependency (!1132)
+
+* Bugs fixed:
+ - #35 add g_fsync to API
+ - #174 g_file_copy always preserves  permissions, even if G_FILE_COPY_ALL_METADATA flag is not set
+ - #259 docs: fix a misunderstanding in g_type_add_interface_*
+ - #767 g_signal_lookup fails if class is not referenced
+ - #1052 g_io_write_chars calls abort when given a null byte as input
+ - #1449 glib fallback atomic int/ptr get/set have memory barrier in wrong place
+ - #1565 Signedness of atomic operations
+ - #1638 g_spawn_*() is extremely slow under certain circumstances
+ - #1809 Provide API for working with PKCS11 backed certificates
+ - #1843 TSAN false positive with g_atomic_pointer_get/g_atomic_pointer_set under Clang
+ - #1865 g_variant_get_data_as_bytes fails after serializing a variant
+ - #1875 Segfault and Overflow in __gio_xdg_cache_mime_type_subclass() with Wps-Office installed
+ - #1887 glib 2.62.0 breaks loading dylibs as modules
+ - #1888 2.62: docs build on Windows broken
+ - #1897 glib 2.62.0 fails test 'test_writev_no_vectors' wih gcc7
+ - !1020 docs: Remove priv pointers from the tutorial example
+ - !1062 gtype: mark the inline functions in G_DECLARE_*_TYPE() as UNUSED
+ - !1080 tests: Fix skipping mkdir-with-parents-permission test
+ - !1088 Various small scan-build fixes
+ - !1090 giochannel: Clarify type of GSource callback in documentation
+ - !1093 gmodule: remove macOS dyld implementation
+ - !1095 Define G_IOV_MAX to 512 on macOS/iOS
+ - !1099 gmem: clarify that g_malloc always uses the system allocator
+ - !1109 doc: fix typo in gio/gsettings.c
+ - !1110 gio: Add missing "gio remove" option to bash completion script
+ - !1112 Add version macros for GLib 2.64
+ - !1115 gdatetime: Fix error handling in g_date_time_new_ordinal()
+ - !1116 gmarkup: Add a limit on the number of attributes in an element
+ - !1119 Annotate the return value of various utility functions
+ - !1124 docs: Fix typo in GConverter{Input,Output}Stream section titles
+ - !1125 gdatetime: Fix error handling in g_date_time_new_week()
+ - !1126 fileinfo: Mention that usec mtimes are set
+ - !1129 gdate: Fix tautological comparison warnings on Android
+ - !1130 Improve GLIB_DEPRECATED_MACRO_FOR output
+ - !1131 gio/gfileinfo: fix param reference in doc comment
+ - !1132 build: Bump Python requirement to ≥ 3.5
+ - !1137 gregistrysettings: bump key name length to 2048
+ - !1138 Always build tests if we enabled installed-tests
+ - !1139 g_file_info_get_modification_date_time: Calculate in integer domain
+
+* Translation updates:
+ - Danish
+ - Italian
+ - Panjabi
+ - Serbian
+ - Turkish
+
+
+Overview of changes in GLib 2.62.0
+==================================
+
+* Fix new `GFileInfo` APIs to work when `G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC`
+  was not queried (!1087)
+
+* Bugs fixed:
+ - #487 Add valgrind test runs to CI
+ - !1084 garray: Fix reference to GLIB_SIZEOF_INT
+ - !1086 glib.supp: make gobject_init() calloc also of the possible kind
+ - !1087 fileinfo: ignore USEC if not available
+
+* Translation updates:
+ - Friulian
+ - Portuguese (Brazil)
+
+
+Overview of changes in GLib 2.61.3
+==================================
+
+* Support setting thread name on BSD systems (#1761)
+
+* Install previously-uninstalled headers for public `GNativeSocketAddress`
+  object (#1854)
+
+* Very initial support for Windows apps (UWP) (!1057)
+
+* Add various new valgrind suppressions to `glib.supp` (#1879, !1075)
+
+* Bugs fixed:
+ - #83 Optimisation for g_nearest_pow() in garray.c
+ - #512 GSignal: accumulator function not called to accumulate G_SIGNAL_RUN_CLEANUP object handler return values
+ - #873 allow NULL arguments to parse_strv
+ - #905 Patches from static analysis run on 2.40
+ - #1057 goption: add sanity check to input parameters
+ - #1309 GSettings object stops emitting "changed" signal on g_settings_reset after call to g_settings_delay
+ - #1620 GDBus criticals from GVfs with GLib master
+ - #1761 Setting thread-name on BSD systems
+ - #1803 GDK_SCALE=X is not respected when using "gio open"
+ - #1819 Invalid characters in Open Location dialog crashes GIMP
+ - #1852 Regression: g_mkdir_with_parents() returns 0 on failure
+ - #1854 glib/gio: GNativeSocketAddress headers not installed.
+ - #1860 g_clear_handle_id does not trigger GLIB_VERSION_MAX_ALLOWED warning
+ - #1863 Potential invalid writes on g_utf8_strreverse
+ - #1867 A couple of en_GBisms
+ - #1870 GSettingsBackend watches not thread-safe
+ - #1879 Incomplete valgrind suppressions - 16 KiB leak reported by valgrind from loading libglib-2.0.so
+ - #1880 glib/gbacktrace.c: If dup2 happened to return -1, don't call dup2 with same value
+ - #1881 GIO_USE_VOLUME_MONITOR and GIO_USE_FILE_MONITOR do not work as documented
+ - !1002 Remove mentions of mailing lists from the documentation
+ - !1011 gapplication: Fix a leaking GRemoteActionGroup member
+ - !1015 Post-release version bump
+ - !1016 gnetworkmonitornm fixups
+ - !1017 Improve ISO 8601 parsing by GDateTime
+ - !1023 g_object_get_property: Improve documentation for use of G_VALUE_INIT
+ - !1026 gutf8: Assert that written memory stays in bounds
+ - !1027 gfileutils: Fix error propagation for other than ENOENT
+ - !1031 meson: build gnulib if printf isn't good enough
+ - !1032 meson: small printf check cleanups
+ - !1033 win32: don't assume the format specifier for the stdlib printf/scanf like functions
+ - !1034 glib/tests/fileutils: Add a reproducer for #1852
+ - !1036 cond test: Don't make assumptions about struct sigaction member order
+ - !1037 Meson: Override glib-compile-resources/schemas
+ - !1044 Relax use of g_test_bug() to not require g_test_bug_base() to be called first
+ - !1049 minor typos in the documentation
+ - !1050 tests: Fix a pragma warning on FreeBSD
+ - !1054 gerror: Add a docs paragraph about not displaying errors verbatim in UI
+ - !1057 Some (probably) easy uwp patches
+ - !1059 Update win32 readme, add myself to codeowners
+ - !1066 libffi.wrap: Meson port has moved to FDO gitlab
+ - !1068 gsubprocesslauncher.c: fix documentation
+ - !1071 meson: Move libdl_dep to the top level
+ - !1074 Adjust README formatting
+ - !1075 glib.supp: add suppression for g_type_class_ref()
+
+* Translation updates:
+ - Basque
+ - Catalan
+ - Czech
+ - English (United Kingdom)
+ - French
+ - Galician
+ - German
+ - Hungarian
+ - Indonesian
+ - Korean
+ - Lithuanian
+ - Polish
+ - Romanian
+ - Spanish
+ - Swedish
+
+
+Overview of changes in GLib 2.61.2
+==================================
+
+* Add various new array functions (#236, #269, #373)
+ - `g_array_copy()`
+ - `g_ptr_array_copy()`
+ - `g_ptr_array_extend()`
+ - `g_ptr_array_extend_and_steal()`
+ - `g_array_binary_search()`
+
+* Add `g_assert_finalize_object()` helper function for writing tests (#488)
+
+* Rework how D-Bus connections are closed/unreffed when `g_test_dbus_down()` is
+  called. Tests which leak a `GDBusConnection` may now time out and abort,
+  rather than silently leaking. (#787)
+
+* Add a deprecation macro for GLib macros, and use it; third-party uses of
+  long-deprecated GLib macros may now start causing warnings. (#1060)
+
+* Deprecate `GTime` and `GTimeVal`, and various functions which use them.
+  Use `GDateTime` and `guint64` UNIX timestamps instead. (#1438)
+
+* Stop using `G_DISABLE_DEPRECATED` to allow disabling deprecation warnings;
+  third-party code should now be using
+  `GLIB_VERSION_{MIN_REQUIRED, MAX_ALLOWED}` to control symbol usage (!871)
+
+* Improve support for running `ninja test` when GLib is built statically (#1648)
+
+* Improve `GNetworkMonitor` detection of offline states (#1788)
+
+* Fix build failure on macOS related to missing `_g_content_type_get_mime_dirs`
+  function (#1791)
+
+* Add various installed utilities’ paths to `gio-2.0.pc` (#1796)
+
+* Fix keyfile `GSettings` backend and portal (especially relevant to any version
+  of GLib included in a flatpak runtime) (#1822, !985)
+
+* More IPv6 ‘Happy Eyeballs’ fixes in `GNetworkAddress` (!865)
+
+* Fix CVE-2019-12450, wide permissions of files when copying using GIO (!876)
+
+* Bump the Meson dependency from 0.48.0 to 0.49.2; we won’t depend on anything
+  higher than this for a while, as Debian 10 ships 0.49 (!924)
+
+* Various test fixes for Windows (!930, !931)
+
+* Initial support for Universal Windows Platform (UWP): certification, and use
+  of packaged libraries (!951)
+
+* Add experimental clang-cl support on Windows, allowing `g_autoptr()` support
+  on Windows (!979)
+
+* Bugs fixed:
+ - #77 G_STDIO_NO_WRAP_ON_UNIX wraps
+ - #236 Add a function to copy an array
+ - #269 Additional convenience functions for g_ptr_array
+ - #373 GArray could use a binary search function
+ - #436 running tests leaves lots of coredumps
+ - #453 find-enclosing-mount docs confusing
+ - #488 Add g_object_assert_last_unref() helper macro to detect object leaks in tests
+ - #590 A reader lock can be obtained even if a writer is already waiting for a lock
+ - #638 g_atexit is defined when not declared
+ - #737 Initialize GValue in g_object_get_property()
+ - #787 gtestdbus: Properly close server connections
+ - #804 gdbusproxy prefixes unstripped error
+ - #870 Fix and enhance GDatetime for Windows
+ - #872 ucs4 functions have wrong return transfer
+ - #887 gdusmessage.c mishandles bounds of GDBusMessageType and related enums
+ - #894 gvalue: Avoid expensive checks where possible
+ - #940 Docs for g_socket_listener_set_backlog are not very helpful
+ - #943 G_DEFINE_TYPE_WITH_PRIVATE docs not helpful
+ - #1018 Allow guid key in dbus addresses
+ - #1060 Add deprecation macro for macros
+ - #1169 Tools can display gibberish messages from translations
+ - #1270 g_get_charset always returns 8-bit codepage on Windows, crippling UTF-8 output
+ - #1438 Deprecate GTimeVal- and GTime-based APIs
+ - #1635 g_socket_join_multicast_group iface parameter fails on win32/64
+ - #1648 2.58.2: Assorted asserts fail in Arch Linux when built statically
+ - #1729 g_content_type_guess segfaults when passed an empty data buffer on Mac OS
+ - #1788 GNetworkMonitor claims I am offline
+ - #1790 documentation on g_file_info_get_attribute_as_string
+ - #1791 _g_content_type_get_mime_dirs missing from libgio-2.0.0.dylib on MacOS
+ - #1792 glib-genmarshal generated valist marshal does not respect static scope for some types
+ - #1793 glib-genmarshal generates wrong code for va marshaler for VARIANT type
+ - #1794 API Proposal: g_timer_is_active
+ - #1796 Add gio-querymodules variable to pkg-config file
+ - #1797 glib/tests/win32 test failing on 64-bit Visual Studio builds
+ - #1798 /contenttype/tree reliably fails on FreeBSD since !863
+ - #1807 g_dbus_server_new_sync() documentation references nonexistent function
+ - #1808 Stopping a GDBusServer should clean up Unix socket paths (if not abstract) and nonce-tcp nonce files
+ - #1811 Introspection info for g_unichar_compose's 3rd arg should be OUT
+ - #1822 keyfile gsettings backend not loading
+ - #1823 Documentation for disabling selinux is incorrect
+ - #1825 GKeyFileSettingsBackend created without filename construct property and unchecked assertion
+ - #1828 Small typo in gio manpage
+ - #1837 Specify for each (optional) parameter, whether it is OUT or INOUT
+ - #1838 Reword documentation for G_DECLARE_FINAL_TYPE
+ - #1847 Setting GLIB_VERSION_{MIN_REQUIRED, MAX_ALLOWED} to before 2.56 triggers warnings
+ - !533 docs: Document pitfall of deprecation pragmas
+ - !563 ci: Add scan-build job in a new ‘analysis’ pipeline stage
+ - !678 glib-compile-schemas: Improve translatable strings
+ - !817 gdate: Officially mark GTime as deprecated
+ - !851 gsettings: Document that lists are returned in no defined order
+ - !853 gobject: Fix apostrophe usage in a few small bits of documentation
+ - !859 gobject: Add a g_assert_finalize_object() macro
+ - !863 gunicollate/cygwin: Don't use __STDC_ISO_10646__ for wchar_t related checks
+ - !865 gnetworkaddress: fix "happy eyeballs" logic
+ - !867 Post-release version bump
+ - !871 Drop G_DISABLE_DEPRECATED
+ - !873 Use atomic reference counting for GSource
+ - !874 Clamp number of vectors to IOV_MAX / UIO_MAXIOV for GOutputStream writev()...
+ - !875 CI/msys2: disable coverage reporting, lcov doesn't support gcc9 yet
+ - !876 CVE-2019-12450: gfile: Limit access to files when copying
+ - !877 gio: specify proper c_marshaller and va_marshallers
+ - !883 tests: Fix small race in GSubprocess tests
+ - !884 garcbox.c: Fix typo atomit => atomic
+ - !885 goption: Clarify G_OPTION_ARG_FILENAME documentation
+ - !889 Include <sys/filio.h> for FIONREAD
+ - !901 gmain: Clarify that g_source_destroy() doesn’t drop a reference
+ - !904 Add glib-genmarshal tests and fix some valist marshaller bugs
+ - !906 property action: Add state hints
+ - !908 Improve testfilemonitor test repeatability and debuggability
+ - !909 D-Bus auth mechanism improvements
+ - !914 ci: Run scan-build in a different build directory
+ - !915 docs: fix typo on arrays examples in gvariant-text
+ - !917 docs: Fix name of IRC channel in CONTRIBUTING.md
+ - !919 glib/tests/refcount.c: Fix tests on non-GCC-isque compilers
+ - !920 gmacros: Only use deprecated attributes on enumerators with GCC ≥ 6.5
+ - !923 Check if compiler symbols are defined before using them
+ - !924 Bump the required version of Meson
+ - !930 glib/tests/convert.c: Skip tests that aren't meaningful for Windows
+ - !931 glib/tests/fileutils.c: Fix stdio Wrapper Test on Windows
+ - !934 build: Increase the slow test timeout to 180s
+ - !935 Ignore */__pycache__/* directories
+ - !937 Fix module tests on Visual Studio builds
+ - !939 gstdio: minor cleanups
+ - !941 list model: Expand items-changed docs
+ - !944 gutils: Don't limit the length of the host name to 99
+ - !945 Avoid overrunning stack at the end of the varargs.
+ - !947 gobject/tests/signals.c: Fix tests on Windows
+ - !948 GObject: Fix mkenums.py and genmarshal.py tests on Windows
+ - !950 ci: Enable CI on FreeBSD 12
+ - !951 Preliminary patches for Universal Windows Platform support
+ - !952 gio: Make minor docs improvements
+ - !953 g_utf8_normalize: Doc comment return missing nullable annotation
+ - !954 Fix the ISO 15924 code for Manichaean
+ - !955 gmacros: Use _Static_assert when C11 is available
+ - !958 gthread: fix minor errno problem in GCond
+ - !961 gmain: Fix g_main_context_prepare priority annotation
+ - !962 gmacros: Use _Static_assert only for non-expr static assert
+ - !964 gmacros.h: Use static_assert on MSVC if possible
+ - !968 Fix typo in request handle
+ - !970 gdatetime: Unset LC_ALL for the test as well
+ - !971 docs.c: Forward link from g_auto* → G_DEFINE_AUTO*
+ - !973 doc: fix typo in gio/gresource.c
+ - !979 Experimental clang-cl support
+ - !980 gmacros.h: Add better support for clang-cl
+ - !981 gio: fix typo in g_settings_reset documentation
+ - !982 Various doc fixes
+ - !985 Keyfile portal fixes
+ - !987 gio/tests: Remove code and comments referring to libtool
+ - !991 fix atomic detection on older gcc versions
+ - !992 docs: Add example to g_test_summary() documentation
+ - !994 gio: Fix minor docs mistakes
+ - !996 Small array test fixes
+ - !997 gdbusaddress: Add missing transfer annotation
+ - !1007 Resubmission of !832 “Try to create the complete path right away and fall back”
+ - !1009 gapplication: remove inactivity_timeout source on finalize
+
+* Translation updates:
+ - Hungarian
+ - Indonesian
+ - Portuguese (Brazil)
+ - Spanish
+
+
+Overview of changes in GLib 2.61.1
+==================================
+
+* `g_unichar_isxdigit()` and `g_unichar_xdigit_value()` now handle full-width
+  characters (U+FF21–U+FF26 and U+FF41–U+FF46) (#58)
+
+* Deprecate `gtester` utility and its test reporting format and enable TAP
+  output by default instead — the `--tap` option to tests is now a no-op
+  (#1441, #1619)
+
+* Add `g_test_summary()` to allow test authors to programmatically summarise
+  what each unit test in a test suite does (#1450)
+
+* Upgrade to Unicode Character Database v12.1 (#1713, !822)
+
+* More IPv6 Happy Eyeballs fixes to `GNetworkAddress` and `GSocketClient`
+  (#1747, #1771, #1774)
+
+* Fix valgrind and gdb support for the new `GHashTable` changes (#1749, #1780)
+
+* Fix GTask wait times growing faster than the number of task threads (#1683)
+
+* Change `GApplication` to ignore `-psn_*` arguments on the macOS command line,
+  as they are irrelevant (#1784)
+
+* Add `g_autoqueue()` helper macros, similar to `g_autolist()` (!474)
+
+* Add pre-allocated link helpers for `GList` and `GQueue`:
+ - `g_list_insert_before_link()`
+ - `g_queue_insert_before_link()`
+ - `g_queue_insert_after_link()`
+
+* Improve network availability detection with NetworkManager to treat lower
+  levels of connectivity as having reduced availability (!781)
+
+* Add `g_clear_signal_handler()` to allow disconnecting from a `GObject` signal
+  and clearing the signal handler ID to zero in a single call (!819)
+
+* Add `g_autoptr()` support for `GRWLock` (!825)
+
+* Define `G_OS_UNIX`, not `G_OS_WIN32`, when GLib is built agains Cygwin (!862)
+
+* Bugs fixed:
+ - #29 GScanner: should explicitly document modifiable fields (value, next_value, ...)
+ - #58 g_unichar_isxdigit() and g_unichar_xdigit_value() should deal with full-width a-fA-F
+ - #106 Boxed types should be documented better
+ - #135 g_unichar_totitle(0) returns 0x00001F88 instead of 0
+ - #429 g_format_size() is broken on Windows
+ - #1441 Deprecate gtester
+ - #1450 Add API for tests to describe what they're checking
+ - #1619 GTest should have a way to default to TAP
+ - #1683 GTask: task_wait_time is increased constantly when the number of running thread is greather than 10
+ - #1713 Upgrade to Unicode Character Database v12
+ - #1739 meson build failure libdl
+ - #1747 Critical in g_socket_client_async_connect_complete
+ - #1749 New GHashTable implementation confuses valgrind
+ - #1753 Remove memory leaks from gio/test/resolver.c
+ - #1755 Please revert #535 gmacros: Try to use the standard __func__ first in G_STRFUNC
+ - #1759 test_month_names: assertion failed
+ - #1760 Document for g_resolver_lookup_records why it returns a list of list of gchar*.
+ - #1763 tests: -p runs tests in the reverse of the specified order
+ - #1768 g_strlcat(): Possible buffer overflow in implementation
+ - #1771 GNetworkAddressAddressEnumerator unsafely modifies cache in GNetworkAddress
+ - #1774 Leaks in gsocketclient.c connection code
+ - #1776 glib/date test fails
+ - #1780 GDB pretty-printer for GHashTable no longer works
+ - #1782 Error in documentation for cross-compile.
+ - #1784 MacOS adds a -psn_X_XXXXXX parameter to the command line
+ - !474 Add g_autoqueue
+ - !476 Add pre-allocated link helpers for GList and GQueue
+ - !556 gtestutils: Make --tap compatible with -p and --GTestSkipCount
+ - !732 gsocket: Clarify in docs that `flags` arguments can be platform specific
+ - !766 W32: swap special g_get_prgname() for platform_get_argv0()
+ - !774 Only build tests if certain conditions are met.
+ - !780 Add copyright and licensing terms to test report generator
+ - !781 gnetworkmonitornm: Fix network available detection
+ - !782 build: Fix check for RTLD_NEXT
+ - !785 Remove monitor test
+ - !787 build: Remove */.gitignore files
+ - !791 glib/gconstructor.h: Include stdlib.h for MSVC builds
+ - !792 general: Remove a few unhelpful references to ‘master’
+ - !795 gdesktopappinfo: Add support for MATE and Xfce4 terminals
+ - !802 gio: tests, don't check for libdl on OpenBSD
+ - !806 Get to 100% coverage on GQueue tests
+ - !808 Update the Docker images used for CI
+ - !809 Modified version of !784 — Adding tests cases for a better coverage of glib/tests/strfuncs.c
+ - !813 gappinfo: Add precondition checks to GAppLaunchContext env methods
+ - !814 gschema.dtd: Add target attribute to alias
+ - !819 Clear signal handler
+ - !820 ci: Keep JUnit report script working on Debian stable
+ - !821 Various minor cleanups to autoptrs
+ - !822 glib: Update Unicode Character Database to version 12.1.0
+ - !825 Add autoptr support for GRWLock
+ - !831 build: (Long time after) post-release version bump
+ - !835 Fix typo in German translation
+ - !836 Document the best practices for binding GInitiallyUnowned
+ - !862 build: define G_OS_UNIX, not G_OS_WIN32 under cygwin
+
+* Translation updates:
+ - Basque
+ - Catalan
+ - German
+ - Indonesian
+ - Spanish
+
+
+Overview of changes in GLib 2.61.0
+==================================
+
+* Changes to `iconv` configure options, including the default iconv
+  implementation on macOS — distributors may need to check their configure
+  scripts (#1557)
+
+* Build fixes when building GLib with `G_DISABLE_ASSERT` defined (#1708)
+
+* Fix documentation for `gdbus-tool wait` to use correct units (#1737)
+
+* Improvements to symlink handling on Windows (!269)
+
+* Add exception handling for crashes on Windows (!582)
+
+* Set `G_WITH_CYGWIN` again when GLib is built on Cygwin (this was a regression
+  from the autotools build) (!736)
+
+* Use `GCocoaNotificationBackend` by default on macOS, rather than
+  `GGtkNotificationBackend` (!745)
+
+* Use Windows symbol visibility when GLib is built on Cygwin, as PE binaries
+  are subject to W32 visibility mechanics — this affects the definition of
+  `_GLIB_EXTERN` (!752)
+
+* Add coloured output support to `gdbus introspect` (!761)
+
+* Bugs fixed:
+ - #682 docs: advise not to use non-literal strings as qdata keys
+ - #1177 gparted crashes due to g_quark_from_static_string used in global initialization
+ - #1258 the buffer written to by g_input_stream_read is not marked as an out parameter
+ - #1557 By default glib tries to use libc instead of native iconv on OSX
+ - #1566 Meld Windows shows error on startup "There was a problem starting c:\Program"
+ - #1614 GIO tests fail on FreeBSD CI with: Unexpected error from C library during 'pthread_mutex_lock': Invalid argument
+ - #1708 Building GLib with G_DISABLE_ASSERT fails
+ - #1709 GResource generation test incompatible with stable LLVM on Linux
+ - #1710 Crash in g_cancellable_cancel
+ - #1712 gdbus-proxy test is flaky
+ - #1724 unconditional check in fuzzing/meson.build
+ - #1725 gosxappinfo.h is not installed on macOS
+ - #1727 Cannot use trash folder with an NFS mount using automount / autofs
+ - #1728 GSocket does not support ENOTSOCK
+ - #1732 Win32: lookup_by_name_async segfaults for not available domains
+ - #1737 gdbus-tool wait command timeout argument incorrect unit reference
+ - !67 glib: update internal gnulib from upstream
+ - !269 Win32 symlink code refactoring
+ - !493 tests: Check that cancelling g_file_replace don't overwrite existing file
+ - !582 Basic W32 exception handling for glib
+ - !680 Fix warnings glib
+ - !690 Fix thread safety issues
+ - !694 gvariant-parser: Fix pattern coalesce of M and *
+ - !706 Fix data races in task test and gmenumodel test
+ - !709 Bump release version for 2.62 series
+ - !710 socket: Fix annotation for flags in g_socket_receive_message
+ - !712 gwin32: Fix comment for g_win32_veh_handler
+ - !716 Various minor documentation fixes
+ - !717 Improve formatting of GCC attribute documentation
+ - !718 GSocketClient - Free last error if a connection attempt fails and on retry the...
+ - !719 Handle an UNKNOWN NetworkManager connectivity as NONE
+ - !721 codegen: Fix use of uninitialised variable
+ - !723 Provide examples for GNUC attribute macros
+ - !724 meson: do a build-time check for strlcpy before attempting runtime check
+ - !728 gsocket: Remove (type) annotation from flags arguments
+ - !730 Improve gdbus-address parsing tests
+ - !735 docs: Use the right g_autoptr function when using an auxiliary function
+ - !736 Set G_WITH_CYGWIN again
+ - !737 gresolver: Don’t use gai_strerror() on Windows, as it isn’t threadsafe
+ - !741 Fix use-after-free triggered by gnome-session-binary
+ - !745 gcocoanotificationbackend: give more priority than the gtk one
+ - !749 gio: Add missing autocleanup definition for GSettingsSchema{Key,Source}
+ - !750 Check for RTLD_NEXT
+ - !752 Use W32 visibility for Cygwin
+ - !754 Check for /proc/self/cmdline
+ - !757 Fix gnulib build on older Visual Studio builds
+ - !760 Properly ensure the cocoa notification backend type
+ - !761 RFC: gdbus-tool: Add --color option for introspect
+ - !762 gutils: Add (nullable) annotation to g_get_prgname()
+ - !765 gslice: Use a convenience macro
+ - !769 ci: Generate a cover report for the test suite
+ - !772 tests: Check that option-argv0 test succeeds on Linux
+ - !776 tests: Only run --external-data test on GNU ld/objcopy
+ - !779 Fix 2.62 documentation symbols
+
+* Translation updates:
+ - Dutch
+
+
+Overview of changes in GLib 2.60.0
+==================================
+
+* Further fixes to the Happy Eyeballs (RFC 8305) implementation (#1653, #1679, #1693)
+
+* Add support for the XDG trash portal (#1676, !276)
+
+* Bugs fixed:
+ - #1653 gsocketclient-slow test is flaky
+ - #1658 keyfile settings backend: Consider tightening permissions
+ - #1668 Fill in CODE-OWNERS file
+ - #1675 glib-compile-resources: c_name generation issue
+ - #1676 Trash portal tries to open files as read-only but D-Bus API documents against that
+ - #1679 socket-service test is flaky
+ - #1693 Happy Eyeballs failure in gsocketclient-slow test
+ - #1697 gthreadresolver: do_lookup_records does res_ninit with an uninitialized state
+ - #1698 g_base64_encode(NULL, 0) causes critical warnings
+ - !276 Support the trash portal
+ - !639 gvariant-parser: Fix error handling when type coalescing fails
+ - !666 Socket fixes to W32 test suite
+ - !674 Update gvdb submodule
+ - !676 Initialize a variable
+ - !677 gerror: Add a missing precondition assertion in documentation
+ - !686 gio: Also support modules built with MSVC
+ - !688 gsocketclient: Fix critical on cancellation
+ - !689 glib-compile-resources: Fix a minor leak
+ - !691 gtask: Separate GTask fields memory locations to avoid data races
+ - !692 glib.supp: Add more variations of existing suppressions
+ - !696 Move closures refcount test to gobject/tests/
+ - !698 gthreadedresolver: Remove unused thread pool
+ - !699 tests: Fix closure-refcount to preserve old semantics
+ - !702 Rename gobjectenumtypes.[ch] to glib-enumtypes.[ch]
+ - !703 Clean up gmarshal.[ch]
+
+* Translation updates:
+ - Catalan
+ - Czech
+ - French
+ - Friulian
+ - German
+ - Italian
+ - Korean
+ - Romanian
+ - Serbian
+
+
+Overview of changes in GLib 2.59.3
+==================================
+
+* Fix support for g_get_user_special_dir() on macOS, including support for the Downloads directory (#1048)
+
+* Ensure that cancelling a GTask cannot cause its callback to be called synchronously (in the same call chain as the original *_async() call) (#1608)
+
+* Further fixes to the Happy Eyeballs (RFC 8305) implementation (#1644, #1680)
+
+* Various fixes for installation of installed tests (thanks to Iain Lane) (!649, !651)
+
+* Various fixes for tests when run on Windows (thanks to LRN) (!665, !667)
+
+* Bugs fixed:
+ - #535 gmacros: Try to use the standard __func__ first in G_STRFUNC
+ - #875 gio-gvfs on Windows: Don't mishandle other non-native URIs in gwinhttpvfs.c
+ - #1048 "Desktop" shortcut appears twice in file chooser sidebar on OSX
+ - #1608 Cancellation might not be asynchronous under certain circumstances
+ - #1644 network-address test failure in CI: IPv6 Broken (g-io-error-quark, 24)
+ - #1680 Regression: g_socket_client_connect_to_host_async() sometimes gets "Connection refused" when connecting to localhost
+ - #1686 gdbus-peer test is sometimes timing out
+ - !613 Use win32 io channel on windows for the protocol test
+ - !634 Win32: gio/gsocket.c: Set WSAEWOULDBLOCK on G_POLLABLE_RETURN_WOULD_BLOCK
+ - !638 gvariant-parser: Fix parsing of G_MININT* values in GVariant text format
+ - !640 tests: Tag socket-service test as ‘flaky’
+ - !641 Minor typo fixes to GSpawn documentation
+ - !645 gsocketlistener: Fix multiple returns of GTask when accepting sockets
+ - !647 gsocketclient: Ensure task is always returned on cancel
+ - !648 gio/tests/task: Run the worker indefinitely until it's cancelled
+ - !649 gio tests: Install test1.overlay file when building installed tests
+ - !650 gstring: fully document semantics of @len for g_string_insert_len
+ - !651 tests: Install the slow-connect-preload.so library and use it
+ - !667 GSubprocess fixes for W32 test suite
+ - !668 tests: Mark gdbus-peer test as flaky
+ - !669 GWin32VolumeMonitor: Sort the volumes correctly
+ - !670 gpollableoutputstream: Fix the description of the interface
+ - !672 Fix some tests when running as root
+
+* Translation updates:
+ - Catalan
+ - Danish
+ - French
+ - Indonesian
+ - Kazakh
+ - Portuguese (Brazil)
+ - Slovenian
+ - Turkish
+
+
+Overview of changes in GLib 2.59.2
+==================================
+
+* Fix check on GDBusMessage size when reading it. (#1642)
+
+* Add async GIO API: g_file_query_default_handler_async(), g_app_info_launch_uris_async() (#1249, #1347)
+
+* Fix some bugs in the Happy Eyeballs implementation. (#1646, #1649)
+
+* Install a new generated header with enum types for Unicode enums. (!481)
+
+* Support the XDG trash portal. (!276)
+
+* Bugs fixed:
+ - #1224 TSAN patches
+ - #1249 xdg-open/gnome-open doesn't work if service isn't started
+ - #1347 g_app_info_launch_default_for_uri_async  is not really async
+ - #1376 gmarkup: Optimize g_markup_escape_text()
+ - #1642 minor mismatch between error and code in g_dbus_message_bytes_needed
+ - #1646 Criticals in g_socket_client_enumerator_callback()
+ - #1649 Critical in g_socket_client_connected_callback
+ - #1673 G_MININT constants broken in g-i
+ - !276 Support the trash portal
+ - !481 Define enum types for Unicode enums
+ - !585 gio: do not pass O_PATH file descriptors to portal APIs
+ - !593 Don't fail trash test if ~/.local doesn't exist or mount points can't be determined (master)
+ - !609 Make `g_app_info_launch_uris_async()` really asynchronous
+ - !619 gvariant: Fix a mistake in docs
+ - !622 Fixing warnings
+ - !626 gdbus: Avoid printing null strings
+ - !627 gsocketclient: Fix criticals
+ - !629 Various memory leak cleanups to GSettings tests (subset)
+ - !630 docs: Ignore more version macros
+
+* Translation updates:
+ - Galician
+ - Hungarian
+ - Lithuanian
+ - Polish
+ - Spanish
+
+
+Overview of changes in GLib 2.59.1
+==================================
+
+* Autotools support is gone. (!580)
+
+* g_format_size() now uses a no-break space to separate digits and units;
+  translations will need to be updated accordingly. (#1625)
+
+* New g_queue_clear_full() API. (#1464)
+
+* Fix argument quoting on win32 when spawning subprocesses. (!419)
+
+* Allow polling more than 64 handles on win32 using g_poll(). (#1071)
+
+* Tag various tests as ‘flaky’. These are no longer run routinely on our
+  upstream CI machines, and downstream packagers may want to not run them (or
+  not treat those test failures as package build failures) on their test
+  machines either. They are in the `flaky` test suite. (!579)
+
+* Add overlay support to g_resources_get_info(). (#1445)
+
+* Support defaults and locks in the keyfile GSettings backend. This will be
+  used for flatpaks. (!450)
+
+* Accept unquoted strings in the keyfile GSettings backend to simplify things
+  for sysadmins. (!603)
+
+* Update our contribution guidelines (`CONTRIBUTING.md`). (!590)
+
+* Add writev() and writev_all() APIs to GOutputStream and GPollableOutputStream,
+  and provide implementations of them for many subclasses. (#1431)
+
+* Bugs fixed:
+ - #424 Add 'proxy' debugging support
+ - #1055 Provide alignment macros
+ - #1071 Eliminate MAXIMUM_WAIT_OBJECTS limitation in g_poll() on Windows
+ - #1445 g_resources_get_info doesn't respect resource overlays
+ - #1464 Add g_queue_clear_full() API
+ - #1500 GListStore needs double checking on some warnings
+ - #1623 xdg-open: file with colon results in “The specified location is not supported”
+ - #1625 Unbreakable space needed when showing size of folder/file
+ - #1636 GTask getters don’t return TRUE/FALSE after bitfield changes
+ - #1637 EXCEPTION_ACCESS_VIOLATION in g_clear_pointer
+ - #1639 GListStore implementation of g_list_model_get_item() returns wrong results on integer overflow
+ - #1655 gvariant-parser warnings
+ - #1663 G_MININT32 triggers compiler warning C4146 with Visual C++
+ - #1666 `G_DEFINE_DYNAMIC_TYPE_EXTENDED` causes warnings with -Wcast-function-type
+ - !319 giomodule: Print the type of each default GIO module
+ - !333 Add writev() API to GOutputStream and GPollableOutputStream
+ - !419 gspawn, win32: qouted args - escape end backslash
+ - !450 Settings portal
+ - !512 gtype: Clarify type of GInterfaceInitFunc
+ - !516 gthread: Add g_private_set_alloc0() convenience API
+ - !535 win32 gpoll: overcome the 64 handles limit
+ - !545 goption: Fix an annotation on g_option_context_parse_strv()
+ - !560 docs: Fix dconf GSETTINGS_BACKEND name in gio overview
+ - !564 gtype: Document type for iface_default_init() function
+ - !568 Add separate definitions of g_assert_[non]null() for C++
+ - !571 docs: Add note on how to check a gboolean condition
+ - !575 gio: Update bad cert error in accept-certificate and GTlsError docs
+ - !579 Temporarily disable flaky tests
+ - !580 Drop autotools support
+ - !583 gmacros: MSVC supports the noreturn function attribute
+ - !587 Remove unused .pc.in files
+ - !588 MSVC: Move dirent implementation to glib/dirent/
+ - !590 Update contribution documentation
+ - !591 gfileinfo: Fix annotation for g_file_info_set_attribute_stringv
+ - !592 Remove leftover build/ directory
+ - !595 gtestutils: pass open file descriptors to subprocess
+ - !597 tests: Tag gsocketclient-slow test as ‘flaky’
+ - !598 gdbus-proxy test fails with GLib-GIO:ERROR:glib/gio/tests/gdbus-proxy.c:832:fail_test: code should not be reached
+ - !599 gdtlsconnection: do not return on a void method
+ - !601 gio: Support "help" in extension point env vars
+ - !602 Update POTFILES.in
+ - !603 keyfile settings: Accept unquoted strings
+ - !608 build: Add -Wno-pedantic flag to compiler arguments
+ - !611 gnetworkaddress: fix use-after-free for network address
+ - !612 gdir: shutup a warning when building with msvc
+ - !615 Fix a couple of wrong compiler warnings
+
+* Translation updates:
+ - Spanish
+ - Swedish
+
+
+Overview of changes in GLib 2.59.0
+==================================
+
+* This will be the last development release with autotools support. As our
+  Meson support has been around since 2.56.x, and was used to release tarballs
+  in 2.58.x, the next development release (2.59.1) will drop autotools as used
+  to build GLib. The macros installed for other packages to use will remain.
+
+* Add `G_TEST_OPTION_ISOLATE_DIRS` to redirect `XDG_*_HOME` to a temporary
+  directory for each unit test. (#538)
+
+* Support `Property.EmitsChangedSignal` annotations in `gdbus-codegen`. (#542)
+
+* Add `g_assert_cmpvariant()` API for unit tests. (#1191)
+
+* Hide bind mounts from GIO mount listings. (#1271)
+
+* Automatically realign data passed to `g_variant_new_from_bytes()` or
+  `g_variant_new_from_data()` if it is not correctly aligned. This prevents
+  misaligned accesses on architectures which don’t support them. Callers should
+  still aim to correctly align data to get higher performance. (#1342)
+
+* Support `ld -b binary` (on platforms which support it; i.e. Linux) to provide
+  large pre-compiled `GResource` resources with a fast compilation time. (#1489)
+
+* Unconditionally install GLib m4 macros, so that projects which depend on GLib
+  and which still build using autotools can continue to build even once GLib has
+  ported entirely to Meson. (#1520)
+
+* Various fixes to the Meson build.
+
+* Drop Python 2 support and require Python 3.4+. See discussion on
+  https://mail.gnome.org/archives/desktop-devel-list/2018-July/msg00004.html.
+  (!196)
+
+* `GHashTable` performance and memory improvements for common cases. See
+  https://hpjansson.org/blag/2018/07/24/a-hash-table-re-hash/. (!208)
+
+* Add flags that allow a `GApplication` to signal and replace a currently
+  running other instance of the same `GApplication`. This will be used for app
+  upgrades with flatpak. (!250)
+
+* Autostart xdg-desktop-portal when using the network monitor and proxy monitor
+  portal backends. (!317)
+
+* Add a g_task_set_name() API to allow `GTask`s to be described; useful for
+  debugging. (!384)
+
+* Enable FreeBSD CI on every commit for upstream GLib. (!387)
+
+* Various GVariant, GMarkup and GDBus fuzzing fixes, including buffer overflow
+  fixes. (!411)
+
+* Various fixes to eliminate thread races, found by thread sanitizer (tsan).
+
+* Deprecate TLS/DTLS rehandshaking, as it has been removed from the protocol in
+  TLS 1.3. (!478)
+
+* Support reading arguments from a file with `glib-mkenums`, which is useful
+  for long argument lists due to having deeply nested build directories, on
+  systems with a low limit on the command line length. (!489)
+
+* Make `g_environ_*()` case-insensitive on Windows, as the environment itself
+  is case-insensitive on Windows. (!500)
+
+* Add Application Layer Protocol Negotiation (ALPN) support to `GTlsConnection`
+  and `GDtlsConnection`, so that higher layer protocols can be negotiated when
+  setting up a TLS connection, without additional round trips and latency. This
+  is needed for eventual HTTP/2 support. (!520)
+
+* Add support for TPM keys in PEM files when loading TLS certificates. (!522)
+
+* Add a `GRecMutexLocker` auto-pointer wrapper for `GRecMutex`. (!528)
+
+* Bugs fixed:
+ - #107 The "g_key_file_get_comment" interface returns comment with unexpected new line symbol at the end
+ - #179 g_object_unref assert in debug code
+ - #277 'destroy_data' in g_cclosure_new is registered as finalize notifier instread invalidate.
+ - #538 Add helpers to redirect XDG_*_HOME to a temp dir for unit tests
+ - #542 gdbus-codegen does not honor "Property.EmitsChangedSignal" annotations
+ - #656 check for -Werror=format-security broken
+ - #734 Provide a way to instantiate a GDBusProxy-derived class from a GDBusConnection and a object path without blocking
+ - #827 gmain: Clarify that g_source_set_callback() is safe on attached sources
+ - #1055 Provide alignment macros
+ - #1119 GVolumeMonitor: Results don't reflect current state but state when application was launched
+ - #1191 add g_assert_equal_variants
+ - #1261 Add option to leave <default> in gschema empty
+ - #1271 fstab binds appear as mounts (x-gvfs-hide is being ignored)
+ - #1310 gdbusproxy: make g-name-owner property useful with unique names
+ - #1313 Meson: Rework the config.h generation
+ - #1342 Automatically realign data passed to g_variant_new_from_bytes() or g_variant_new_from_data()
+ - #1343 g_date_set_parse: Parses "September" in Polish incorrectly
+ - #1362 Incorrect documentation about GSettings child add/remove notifications
+ - #1452 GFileInfo: unable to retrieve correct modification time of links and mounted volumes on Windows
+ - #1471 Incorporate oss-fuzz fuzz targets into GLib
+ - #1489 Use `ld -b binary` to speed up GResource generation for linking
+ - #1498 distcheck fails in distclean
+ - #1506 error: redefinition of typedef 'GKqueueFileMonitor'
+ - #1509 test_timeval_to_iso8601_overflow: 'out' should be NULL
+ - #1513 GIcon regression?
+ - #1514 gio/appinfo test sometimes fails in CI
+ - #1518 /network-monitor/create-in-thread fails in (LXC) containers on glib-2-56
+ - #1520 Change conditions for installing m4 macros
+ - #1522 Trash not working on NTFS folder accessed from symlink
+ - #1523 GIO NetworkMonitor doesn't reflect the current network state
+ - #1525 GTask allows (buggy) application code to cause callback to be called twice, without warning
+ - #1527 Meson doesn't install data for installed-tests
+ - #1528 Meson tests are hard to debug in an autobuilder environment
+ - #1530 tests/mainloop-test appears to be flaky
+ - #1535 meson: installed-test metadata not run in TAP mode
+ - #1536 meson: spurious dependencies on convenience libraries in .pc files
+ - #1537 meson: absolute paths to ${builddir} included in gtk-doc HTML
+ - #1538 meson: G_HAVE_GROWING_STACK defined differently
+ - #1539 meson: Some files are unnecessarily installed executable
+ - #1541 meson: timeloop-closure test not installed
+ - #1542 meson: /usr/lib/glib2.0/installed-tests/glib/gdbus-peer: error while loading shared libraries: libgdbus-example-objectmanager.so: cannot open shared object file: No such file or directory
+ - #1544 meson: gtester-report #! not replaced with ${PYTHON}
+ - #1546 Cross-compilation fails in 2.58
+ - #1556 build: Too long file path issue with meson on Windows
+ - #1562 GDate test suite fails with latest glibc
+ - #1570 ghash.c:694:27: left shift of 1 by 31 places cannot be represented in type 'int'
+ - #1572 Flags validation fails
+ - #1575 g_date_time_format() should have format attribute
+ - #1576 Fails to build with Meson on Debian armel (armv5te EABI softfloat little-endian)
+ - #1580 glib-compile-resources using strings breaks building e.g. GTK+ on MS Visual C, which limits strings to 65535 chars
+ - #1581 Memory used for reference counted data might be misaligned.
+ - #1588 Moving a bookmark item to the same URI causes a crash
+ - #1589 g_log_writer_is_journald memoizes a single result, even though it accepts a parameter
+ - #1590 tests: g-file-info-filesystem-readonly fails if run more than once with fuse & bindfs installed
+ - #1594 Return value of g_dbus_connection_get_unique_name not annotated as nullable
+ - #1600 g_timeout_source_new_seconds overflows when given interval > (G_MAXUINT / 1000)
+ - #1601 appinfo test fix is defective
+ - #1605 g_date_time_format fails when used with non ASCII format string on POSIX locale
+ - #1615 gdbus-codegen not generating nullable annotation
+ - !196 [RFC] build: Drop Python 2 support and require Python 3.4+
+ - !200 Add a new GTlsError to indicate protocol downgrade attacks
+ - !208 GHashTable improvements
+ - !219 glocalfilemonitor: Fallback to poll file monitor for NFS
+ - !238 W32 GFileInfo improvements
+ - !250 Application replace
+ - !264 glib-compile-resources: encode data as string
+ - !268 build: simplify alloca checks. See #1313
+ - !272 dtrace: Add missing const attributes to types in glib_probes.d
+ - !273 gtlsbackend: add support for setting the default TLS database
+ - !277 Use "command -v" instead of "which"
+ - !282 meson: Add macOS libtool versioning for ABI compatibility
+ - !286 gspawn: Fix build on systems without O_CLOEXEC
+ - !287 glib-compile-resources: Fix generated code compiling with C++ compilers
+ - !289 tests: Add more tests to finish branch coverage of GHashTable
+ - !290 build: fix installation dir of glib-gettextize
+ - !292 Remove all ChangeLog files
+ - !293 Document new volume class `loop`
+ - !294 portal network monitor: Always emit changed signal on changed
+ - !295 meson: fix typo
+ - !296 Add G_GNUC_FALLTHROUGH for __attribute__(fallthrough))
+ - !297 build: Drop AC_C_CONST from configure.ac
+ - !302 Document that GTimeVal is subject to the year 2038 problem on 32-bit systems
+ - !303 liststore: Simplify code
+ - !304 Add more GListStore/GListModel tests
+ - !309 codegen: Change pointer casting to remove type-punning warnings
+ - !312 Enable GIO tests on Windows
+ - !316 gdbus: Improve error when well-known name is unowned
+ - !317 Autostart xdg-desktop-portal if needed
+ - !322 gnetworkmonitornm: Set a GError properly on an error handling path
+ - !332 gmarkup: Make the documentation even more explicit about untrusted input
+ - !334 gio: automake: Add libgmodule dependency
+ - !338 gcharset: fix leaking g_get_language_names_with_category
+ - !339 Add g_desktop_app_info_get_string_list(); fix g_key_file_free()
+ - !340 tests: Mark two more tests as slow
+ - !345 Fix build failure on systems without POSIX spawn
+ - !347 Use Meson 0.48.0 for CI
+ - !348 Documentation tweaks for g_array_free
+ - !353 Meson: Do not run tests/refcount with --tap
+ - !354 Fix spelling mistakes detected by Debian's Lintian tool
+ - !358 Autotools: Move libmount from Libs.private to Requires.private
+ - !360 CI: Test static build on installed glib
+ - !363 Tests: Mark printf wrappers with G_GNUC_PRINTF
+ - !364 ci: Enable FreeBSD CI
+ - !366 gunixmounts: Mark mounts as system internal instead of filtering out
+ - !372 gmacros: Fix G_[UN]LIKELY to not mask -Wparentheses
+ - !374 gthreadpool: Include prgname in thread name
+ - !375 m4macros: Allow information from pkg-config to be overridden
+ - !376 gthread: Clarify priority handling in GRWLock
+ - !379 Ignore g_return_*if_fail() branches in lcov coverage report
+ - !381 Add UTF-8 communication tests for GSubprocess
+ - !384 gtask: Add a g_task_set_name() method
+ - !387 ci: Enable FreeBSD CI in the official repository
+ - !396 m4: Fix AM_PATH_GLIB_2_0 macro
+ - !400 grefcount: add missing gatomic.h
+ - !403 build-sys: Pass CFLAGS to $(DTRACE)
+ - !405 ci/msys2: fix path to the lcov config file
+ - !406 meson: Mark 1bit-emufutex test as slow
+ - !407 meson: Increase test timeouts
+ - !410 gfileutils: Add examples to g_path_get_dirname() documentation
+ - !411 Various GVariant, GMarkup and GDBus fuzzing fixes
+ - !412 Enable compile time check of g_date_time_format() format
+ - !413 Add support for g_auto(s)list to G_DECLARE'd types
+ - !414 gio, tests: ensure objectmanager sources are generated
+ - !415 gseekable: fix 'attmepting' typo
+ - !416 gdbus-peer: Make sure to not include objectmanager-gen.c source
+ - !417 Fix ^*ay handling in g_variant_iter_loop()
+ - !418 Meson: Cleanup a FIXME now that we have dict addition
+ - !420 gdbus-codegen: add autocleanup for FooObject
+ - !422 GMarkup buffer overflow fixes for error handling, round 2
+ - !423 gutils: Check whether getauxval function exists
+ - !424 ci: Fix Docker image version
+ - !425 gdate: Reinitialize using_twodigit_years and locale_era_adjust.
+ - !435 gdatetime: Fix formatting of time zones offsets in range -01:00 to +00:00
+ - !436 valgrind: Add glib_init()-related suppressions
+ - !440 Fix minor memory leaks in tests
+ - !443 tests: Avoid multithreaded use of g_test_rand_int_range
+ - !444 gvarianttypeinfo: Consistently use atomics to access ref_count
+ - !446 gmain: Fix data races in GUnixSignalWatchSource and GChildWatchSource
+ - !451 closures test: Avoid timeout on ARM64 CPUs
+ - !452 Atomic reference count in GVariant, ContainerInfo and GDBus introspection
+ - !453 tests: Fix some data races in tests
+ - !454 gdbusproxy: make g-name-owner property useful with unique names
+ - !458 glib-compile-resources: Fix size allocation for compressed streams
+ - !460 gatomicrefcount: Make g_atomic_ref_count_init non-atomic
+ - !461 Meson: Fix build error in gdbus-example-objectmanager
+ - !462 meson: add aarch64 memory barrier handling
+ - !463 gio, tests: fix leak of dbus connection.
+ - !467 Update documentation of g_tls_connection_handshake() again
+ - !469 docs: add index of new symbols for gio > 2.52
+ - !470 docs: Clarify return/error behaviour of D-Bus signal subscriptions
+ - !472 gdbusmessage: Gracefully handle message signatures with invalid types
+ - !477 gthread: Remove unsynchronized access to g_once_init_list from assertion
+ - !478 Deprecate TLS rehandshaking
+ - !480 docs: add a missing semicolon
+ - !482 Check for 'z' library before fallbacking to subproject
+ - !483 meson: Turn selinux into a meson feature and make it auto by default
+ - !484 Meson: Add 'nls' option to disable translation
+ - !485 gdbus-codegen: Tag interfaces and properties so annotated with G_PARAM_DEPRECATED
+ - !486 Check for zlib header
+ - !489 glib-mkenums: Support reading @rspfiles for arguments
+ - !490 gspawn: Fix g_spawn deadlock in a multi-threaded program on Linux
+ - !491 Meson: Add missing include_directories when using glib as subproject
+ - !492 g_value_get_variant: return value is transfer-none not transfer-full
+ - !494 Resolve "Follow-up from "gunixmounts: Stop considering cifs/nfs as system file systems""
+ - !500 genviron: make g_environ_* case-insensitive on Windows
+ - !504 tests: Unset LANGUAGE when running gdatetime tests
+ - !505 Support isolating directories for unit tests
+ - !508 ci: Install additional locales used during tests
+ - !510 Add new Linux Testing project version number to configure script
+ - !511 gvariant: Fix error handling for parsing Unicode escapes
+ - !514 fix gdbus-codegen --interface-info-{header,body}
+ - !515 binding: Clarify the use of g_object_unref() to remove a binding
+ - !517 Meson: Fix deprecation warning with upcoming 0.49.0 release
+ - !518 Meson: Fix declare_dependency() calls
+ - !520 GTlsConnection: add ALPN support
+ - !521 tests: Rename macro to avoid conflict with encoding prefix
+ - !522 gtlscertificate: Add support for TPM keys in PEM files
+ - !524 gdatetime: Fix typo in the comment
+ - !528 Add GRecMutexLocker
+ - !530 tests: Minor improvements to mkenums.py and taptestrunner.py used by it
+ - !534 gtlscertificate: Fix bug in PEM private key parser
+ - !536 Various minor docs fixes
+ - !541 gtimezone: Fallback to /etc/timezone on Gentoo
+ - !546 spawn: add shebang line to script
+ - !547 Do not check for NULL when calling free()
+ - !549 Improve documentation of g_assert_error()
+ - !551 Revert "tests: Fix GOptionContext leak in GSubprocess tests"
+ - !554 Only subscribe to owner-changed signals on message bus connections
+ - !555 Suppress -Wint-in-bool-context warning with G_DEFINE_INTERFACE and g++
+
+* Translation updates:
+ - Brazilian Portuguese
+ - Czech
+ - Danish
+ - Greek
+ - Hungarian
+ - Lithuanian
+ - Norwegian bokmål
+ - Polish
+ - Slovak
+ - Slovenian
+ - Spanish
+ - Swedish
+ - Turkish
+
+
+Overview of changes in GLib 2.58.0
+==================================
+
+* Tarball built with `ninja dist`, so if you want to build this release with
+  autotools (which is supported), you will need to re-run autogen.sh. This
+  release, and all micro releases in the 2.58.x series, support being built
+  with Meson or autotools. See:
+  https://mail.gnome.org/archives/gtk-devel-list/2018-June/msg00012.html
+
+* Fix cancellation of g_subprocess_communicate_async() calls. See !266.
+
+* Drop support for the __int64 type, which further breaks compilation on old
+  MSVC versions (before VS2013). See #1313.
+
+* Expose GSettings schema directory in gio-2.0.pc as `schemasdir`. See !274.
+
+* Support v3 of the xdg-desktop-portal network monitor API. See !265, !279.
+
+* Fix G_MODULE_SUFFIX on macOS when GLib is built with Meson — it should be `so`
+  rather than `dylib`. Projects that use Meson and the `g_module_build_path()`
+  API such as glib-networking should pass `name_suffix:` to `shared_module()` to
+  ensure that plugins continue to be called libfoo.so on macOS. See !280.
+
+Bugs fixed:
+ !280 meson: Always set G_MODULE_SUFFIX to `so` on macOS
+ !266 subprocess: Fix communicate_cancelled signature
+ !279 Revert "Add a gnet utility" (see !265)
+ !265 Network monitor again
+ !274 gio: Provide schemas directory information in pkg-config file
+ !239 gvariant: Fix more bounds checking in GVariant text format parser
+ !195 garray: add overflow checks before expanding array
+ #1497 g_strdup_printf warns on invalid format specifier with G_GUINT64_FORMAT on Win32
+ !270 autotools: remove support for the __int64 type. See #1313
+ !267 ci: Add an autotools job
+
+* Translation updates:
+ Czech
+ Galician
+ Indonesian
+ Italian
+ Kazakh
+ Korean
+ Turkish
+
+
+Overview of changes in GLib 2.57.3
+==================================
+
+* G_GNUC_MALLOC’s definition has been tightened up to match an updated
+  definition from GCC. Many uses of G_GNUC_MALLOC which were previously
+  appropriate may cause miscompilation with newer GCC versions. Check your uses
+  of it against the updated documentation. See #1465.
+
+* Many minor documentation fixes.
+
+* Fix for gint64 and int64_t compatibility on macOS and BSD. See #972.
+
+* Fix free space metadata on some file systems (notably FAT). See #328.
+
+* Support installed-tests with our Meson build system. See #1444.
+
+* Forbid @filename@/@basename@ in glib-mkenums templates, which is a change to
+  its long-standing behaviour (which was long-standing nonsensical). See !241.
+
+* Various stat() fixes on Windows. See #1452, #1476.
+
+* MinGW-w64 ABI warning: In case you build 64 bit glib without LFS support by
+  passing --disable-largefile (not the default) and use GStatBuf, you need to
+  rebuild your application as the size of GStatBuf has changed for this case.
+  See #1476.
+
+* Improve TAP compatibility of g_test_incomplete(). See #1474.
+
+* Change fallback preferences when loading icons. See !72.
+
+Bugs fixed:
+ !263 build: Clean files left behind after gio/tests/gresource.c test
+ !262 gmem: Only evaluate pointer argument to g_clear_pointer() once
+ #1465 Many uses of G_GNUC_MALLOC are incorrect
+ #1448 g_error does not abort() as documented
+ #1494 g_clear_pointer may not use the correct calling convention with its callback
+ #972 Mismatch between gint64 and int64_t on 64-bit macOS/BSD
+ !251 gtestdbus: Fix watcher crash on FreeBSD
+ #1492 gcc-8: -Wcast-function-type: new warnings for g_list_copy_deep()
+ !252 tests: fix gnotification tests broken due to the recent icon name fallback changes
+ #328 filesystem::{free,size,used} not set for full FAT fs
+ !248 network monitor portal: update properties initially
+ #1373 Incorrect transfer annotation for g_binding_unbind.
+ #1444 the meson build doesn't support installed tests
+ #1027 Fix trashing on overlayfs
+ #1454 gvdb does not treat corrupt files as empty as promised; dconf suffers
+ !243 tests: Explicitly set TZ=UTC for g_time_val_from_iso8601() testing
+ #1488 ‘O_CLOEXEC’ undeclared (first use in this function)
+ !241 glib-mkenums: forbid @filename@/@basename@ in fhead and ftail
+ !240 gtimer: Ensure arithmetic is correctly signed for ISO 8601 parsing
+ #1452 GFileInfo: unable to retrieve correct modification time of links and mounted volumes on Windows
+ !234 DOC: Documentation fix in GTask description
+ #1363 Meson: Review cross compilation properties
+ !225 gtimer: Add overflow checks to g_time_val_from_iso8601()
+ !230 gbookmarkfile: Fix some more minor leaks when metadata elements are repeated
+ !229 Fix up g_bytes_compare() documentation
+ #1476 g_stat - possbile memory corruption causing SEGFAULT
+ !199 Update TLS documentation
+ #1474 g_test_incomplete() makes test_case_run() return FALSE
+ #1475 glib/tests/atomic.c test_types() trips -Werror=bad-function-cast on Debian armel
+ #1472 Test for BROKEN_IP_MREQ_SOURCE_STRUCT is broken on Windows / Mingw
+ !220 date test: Use g_test_skip(), not g_test_incomplete()
+ #1467 malloc difference causes refstring test to fail on FreeBSD
+ !230 gbookmarkfile: Fix some more minor leaks when metadata elements are repeated
+ #1466 Not Able to Build glib 2.57.2 in Mingw-w64 x64 bits
+ #1433 test_posix_parse: assertion failed (g_time_zone_get_abbreviation (tz, 0) == "UTC"): ("LMT" == "UTC")
+ #1446 Follow-up from "Document difference between g_assert() and g_assert_*() wrt G_DISABLE_ASSERT"
+ !206 grefstring: Avoid an unnecessary NUL assignment
+ #1458 g_volume_get_mount returns NULL value after g_volume_mount_finish is called with no error
+ !72 gio: icons should fallback to non-preferred style appropriately.
+
+* Translation updates:
+ Brazilian
+ Chinese (Taiwan)
+ French
+ German
+ Lithuanian
+ Polish
+ Romanian
+ Turkish
+
+
+Overview of changes in GLib 2.57.2
+==================================
+
+* Require pcre 8.31
+* Require meson 0.47.0
+
+* Bugs fixed:
+ 742456 Add g_steal_pointer() convenience function to mark ownership...
+ 795569 MinGW CI: fix tests
+ 796341 gmem.h: Use typeof() in g_steal_pointer() macro
+ #1013 Support for per-session overrides
+ #1360 glib-mkenums breaks if option specified but no nick
+ #1175 Add names and tags to various GSources and GTasks constructed in GLib
+ #903 g_main_context_wait() not deprecated in API, but emits a g_critical()...
+ #786 Fix memory leaks in libgio tests
+ #927 gio/gresource.c:do_lookup check for terminating "/"
+ #976 Document difference between g_assert() and g_assert_*()...
+ #1447 glib 2.57.1: test_month_names: assertion failed...
+ #1407 Update to Unicode Character Database 11
+ #1455 glib python tools have full python path in shebang, limits to 128 characters
+ #1459 Missing g_return_val_if_fail in g_async_queue_timeout_pop
+
+* Translation updates:
+ Friulian
+ German
+ Romanian
+ Spanish
+
+
+Overview of changes in GLib 2.57.1
+==================================
+
+* New api:
+ - g_hash_table_steal_extended
+ - G_GNUC_NO_INLINE 
+
+* Bug fixes:
+ 668132 Use libmount and expose mount options on GUnixMountEntry type
+ 736741 Update private copy of valgrind.h
+ 748620 g_regex_* utf-8 validity requirements are not stated clearly
+ 784995 meson: some Windows improvements
+ 788771 NODELETE missing when built with meson
+ 788773 meson does not install correct pc files
+ 789968 Add g_autoptr() support for GTypeClass
+ 794325 Various fixes to compile on OSX
+ 795152 gdesktopappinfo: Mark GDesktopAppInfo constructors as nullable.
+ 795165 Add g_date_time_get_timezone() and g_time_zone_get_identifier()
+ 795180 Investigate performance impacts of recent compiler features on hot functions
+ 795302 Add g_hash_table_steal_extended() API
+ 795376 Add g_ptr_array_steal()
+ 795544 Add binary/textfile/zero size detection
+ 795569 MinGW CI: fix tests
+ 795636 gitlab-ci: generate test coverage reports
+ 795735 Fix comparison for GVariant property values
+ 795802 gdbus-codegen doesn't accept --output-directory with --output for --body and --header
+ 795849 gwin32: Fix detection of MinGW32 vs MinGW-w64
+ 795876 meson: Fix checks for posix_memalign and stpcpy
+ 795960 g_format_size_for_display() is deprecated since 2.30
+ 796085 Meson: Many apps breaks on non-glibc because of missing libintl
+ 796138 Fix typo in g_file_info_set_attribute docs
+ 796139 Add g_autoptr() support for GParamSpec
+ 796164 Fix atomic ops check in meson.build
+ 796186 Typo: "instead off" in gsignal.c
+ 796213 Meson: Fail to build on macosx
+ 796220 meson: do not run atomic test with msvc
+ 796264 Add android CI
+ 796325 meson: Add exception for atomic ops test for Android
+ 796328 gengiotypefuncs.py: Read and parse files in binary mode 
+
+* Translation updates:
+ Czech
+ Indonesian
+
+
+Overview of changes in GLib 2.57.0
+==================================
+
+* Bug fixes:
+ 739424	Rewrite kqueue GFileMonitor backend to drop threading
+ 751826	Use g_get_language_names() for other locale categories
+ 788773	meson does not install correct pc files
+ 793400	g_application_id_is_valid() not strict enough
+ 793578	gdatetime tests depend on Japanese translation of month names
+ 793645	test_month_names: Updated translations needed for el_GR, hr_HR, ru_RU
+ 793729	gitlab-ci: Add Windows MinGW support
+ 793994	GUnixVolumeMonitor doesn’t show user mounts when run as root
+ 794170	gdbus: hexdecode() and hexencode() do not return/use decoded/encoded s...
+ 794194	gobject_gdb.py: 'address' is a property of gdb.Value not a function
+ 794207	leak: g_socket_listener_add_inet_port increases ref-count on socket-li...
+ 794284	Support whitespace stripping for JSON resources
+ 794285	glib-compile-resources should not noisily g_printerr() when xmllint is...
+ 794473	Remove duplicated option in gio.xml
+ 794506	glib-mkenums: Enters infinite loop if using typedef enum SomeIdentifier
+ 794528	Fix segfault caused by use-after-free in GPollFileMonitor
+ 794555	glib meson build fails on MinGW due to misdetected functions
+ 794557	gtkdoc-scangobj fails on gio in meson builds
+ 794606	glib-2.56.0 fails to compile when res_nquery is not available
+ 794635	gmacros: Don't define bogus __has_* macros
+ 794636	G_HAVE_GNUC_VISIBILITY is defined in meson MinGW builds
+ 794686	Date (except weekday) displayed in English
+ 794732	Fix various compiler warnings 
+
+* Translation updates
+ Hungarian
+ Slowak
+ Slovenian
+ Spanish
+
+
+Overview of changes in GLib 2.56.0
+==================================
+
+* Bugs fixed:
+ 672777 Error in gdummyfile.c
+ 732184 GObject: warn on use of deprecated properties
+ 733338 Don't segfault in GNetworkMonitor when IPv6 support is unavailable
+ 742124 g_data_input_stream_read_upto()'s documentation should say that the...
+ 749206 GDateTime: month names in the genitive case
+ 768507 simplify qguark functions
+ 791457 Slow transfer rate when writing to smb/cifs
+ 793272 fix GCC 8.0's -Wcast-function-type warnings
+ 793300 g_hash_table_add() return value change in 2.40 not mentioned in docs
+ 793399 Fix some cases of -Wduplicated-branches
+ 793555 -Wimplicit-function-declaration when using g_abort()
+ 793565 GLib does not compile on macOS 10.13 due to .m file naming
+ 793597 gdbus-tool: Make --dest optional for emit again
+ 793635 Enable CI for GLib
+ 793880 gnetworkmonitor: Minor fixes based on code review 
+ 793578 gdatetime tests depend on Japanese translation of month names 
+ 794180 test_month_names fails unless installed
+
+* Translation updates:
+ Brazilian Portuguese
+ British English
+ Catalan
+ Czech
+ Danish
+ Dutch
+ Finnish
+ French
+ Friulian
+ Galician
+ German
+ Hungarian
+ Indonesian
+ Italian
+ Kazakh
+ Korean
+ Lithuanian
+ Polish
+ Scottish Gaelic
+ Serbian
+ Serbian Latin
+ Spanish
+ Swedish
+ Turkish
+
+
+Overview of changes in GLib 2.55.2
+==================================
+
+* GFile now has API to get the path without copying
+
+* A network monitor implementation for Windows has been added
+
+* Bugs fixed:
+ 520116 g_utf8_strlcpy()
+ 584284 g_data_input_stream_read_until_async behaves confusingly different f...
+ 605700 request for g_key_file_get_locale()
+ 658713 ngettext (plural forms) needed for "Message has %d file descriptors ...
+ 685442 windows GNetworkMonitor implementation
+ 723003 gsettings list-recursively reports some keys multiple times
+ 749583 GSequence performance improvements
+ 757284 Move G_DIR_SEPARATOR* and G_SEARCHPATH_SEPARATOR* into glibconfig.h
+ 760324 [PATCH] gkeyfile.c: find_file_in_data_dirs fails to return the path ...
+ 761102 Increase performance for main loop
+ 767976 GFile: Add g_file_peek_path()
+ 770335 gdbus-codegen: generated getter for 'ao' property is actually (trans...
+ 772989 Totem allows invalid urls that might cause segfault that's irrecover...
+ 790698 convert: test failure on NetBSD
+ 791015 gdbus-codegen: Split generation of header and source
+ 791622 Disable strict-aliasing in GLib
+ 792050 GResolver is not thread-safe
+ 792217 Deprecate GTlsClientConnection:use-ssl3
+ 792338 meson, autotools: figure out if mem barrier is needed for arm64 host...
+ 792351 gbookmarkfile: check length before dereferencing groups
+ 792364 gdbus-threading test method-calls-in-thread: assertion failed (elaps...
+ 792370 GNetworkMonitor: Rename "network-changed" signal argument
+ 792410 GDateTime new_from_iso8601 test broken in 2.55 on i386
+ 792432 flush stdout after logging (debug) messages
+ 792455 Improve docs of GSequence
+ 792499 deadlock on startup with TCP session bus
+ 792516 gconvert: More consistent handling of embedded NUL bytes
+ 792777 g_notification_set_urgent() unconditionally sets G_NOTIFICATION_PRIO...
+ 792780 gbytes should reference toplevel bytes when slicing with g_bytes_new...
+ 792856 off64_t isn't a part of C standard
+ 792862 gpollableoutputstream: document side effects of WOULD_BLOCK on D/TLS
+ 792903 Clarification between g_try_.. functions and their counterparts
+ 793006 High CPU load for GUnixMountsMonitor consumers
+ 793026 possible mem leak in g_mutex_impl_new
+ 793074 g_message() does not get -Wformat warnings when compiling with G_LOG...
+
+* Translation updates:
+ Hungarian
+ Indonesian
+ Polish
+
+
+Overview of changes in GLib 2.55.1
+==================================
+
+* Build:
+ - The --enable-rebuilds configure option has been removed
+ - The --with-charsetalias-dir configure option has been added
+
+* GList and GSList now have autoptr support
+
+* The gsettings list-schemas command has gained a --print-paths option
+
+* Bugs fixed:
+ 346816 Refactor LIBDIR in libcharset Makefile
+ 508976 Does g_slist_sort preserve the order of equal elements?
+ 562334 2.18.2 break libglade on Solaris
+ 662802 systemtap multiarch issue
+ 684282 Add support static link of GIO modules
+ 692034 Install an invalidation notifier for GClosure in g_source_set_closure()
+ 694723 Get rid of REBUILD stuff in configure.ac
+ 697715 floating point precision problem in check test gst/gstvalue
+ 701156 testgobject assumes that the priv data follows the instance data
+ 720380 Segfault when using GDBusMenuModel on a peer-to-peer connection
+ 724383 glib: document restrictions on various foreach() functions
+ 724412 GLib mappedfile.c test uses g_get_user_runtime_dir instead of a tempo...
+ 724794 Fix "on on" typo in tap-driver.sh comment
+ 732003 gnode: Eliminate implicit signed-to-unsigned integer conversion
+ 734479 G_VALUE_HOLDS etc. cause -Wcast-qual warnings for a const GValue *
+ 737677 gmain: Make GSourceCallback thread-safe
+ 741167 gdbus-codegen fix for boxed out parameters
+ 748534 gtest: if a subprocess assertion fails, print its stdout and stderr
+ 749527 add weak pointer helpers similar to g_set_object
+ 749652 compilation errors with gcc 4.8
+ 754634 Update the list of Linux filesystem magic numbers used in get_fs_type
+ 756011 Fix up annotations for GBookmarkFile
+ 761102 Increase performance for main loop
+ 773980 GIR scanner doesn't interpret array type properly
+ 776147 gio/glocalfilemonitor.c doesn't handle case G_FILE_MONITOR_EVENT_MOVE...
+ 776195 -z nodelete configure check does not work on Solaris
+ 777075 Potential leak of memory pointed to by 'list'
+ 779413 Translated X-Geoclue-Reason string not used in a dialog window
+ 780309 gio/tests/appinfo build fails: gdesktopappinfo.c skipped on OS X
+ 780893 Reword licensing header for gdbus-codegen
+ 782057 Unit tests fail in run-assert-msg-test.sh
+ 784995 meson: some Windows improvements
+ 786796 gtk-doc build fails with meson
+ 788806 Impossible to build static glib via meson
+ 788936 Show mime type icons on OS X
+ 790416 g_date_time_format returns empty string on %r with German locale
+ 790588 Generated file missing from .gitignore
+ 790697 g_object_ref API should propagate parameter type
+ 790785 glib-tap: Add missing mkdir for .test generation rule
+ 790829 glib-genmarshal --body must not generate alias implementations
+ 790830 Mismatch between number of interface methods in text and example code
+ 790837 Meson: missing many configure options
+ 790839 GApplication command line: lacks parameter_string, summary and descri...
+ 790877 fix non-portable check in G_GNUC_CHECK_VERSION
+ 790894 Do not connect to the session bus when trying GProxyResolverPortal io...
+ 790896 docs/reference/README has broken link to http://www.gtk.org/rdp/
+ 790914 gdesktopappinfo: Downgrade a warning to a debug message
+ 790934 gtester doesn't handle skipped tests
+ 790948 GSourceFuncs documentation is confusing: when will dispatch be called?
+ 791036 Guard for g_output_stream_vprintf makes no sense
+ 791128 C runtime complains about bad arguments on each g_log() call
+ 791221 po/README.translators has no useful information in 2017
+ 791235 Fix gschema.dtd regarding flags.
+ 791267 Make gschema.dtd usable.
+ 791296 gtester-report: fix range usage when running as python3 app
+ 791318 GBytes: Improve documentation
+ 791325 Gio handling of thumbnail:: attribute namespace causes inconsistent b...
+ 791334 gbinding.c:898: The target object of type GNetworkAddress has no prop...
+ 791337 Crash opening URIs with g_desktop_app_info_launch_uris_with_spawn()
+ 791342 Add autoptr support for lists
+ 791460 meson: fixes for OSX
+ 791532 Implicit declaration of function ‘memcmp’ in gtestutils.h
+ 791622 Disable strict-aliasing in GLib
+ 791720 Criticals in gio/xdp-dbus.h leading to crash under flatpak
+ 791744 gmenumodel test sometimes fails: assertion failed (items_changed_coun...
+ 791745 not immediately clear whether g_test_slow() is in effect by default
+ 791906 GSocketListenerClass.event has wrong signature
+ 792064 gsettings list-schemas --print-paths
+ 792098 Binding: bind_property’s @notify func is nullable
+ 792099 gdbus-test-codegen: Cast to void* to printf "%p"
+ 792129 meson: skip optional linux/unix deps that default to true when buildi...
+ 792322 GLib-GIO:ERROR:gschema-compile.c:51:test_schema: child process (/gsch...
+ 792324 gkeyfile: Document need for KEEP_TRANSLATIONS with get_locale_string()
+
+* Translation updates
+ Hebrew
+ Indonesian
+
+
+Overview of changes in GLib 2.55.0
+==================================
+
+* New API:
+  - g_clear_handle_id, to simplify removing sources from the default mainloop
+  - g_file_load_bytes, to make it more convenient to load files into GBytes
+
+* Bugs fixed:
+ 330458 Sample code for the GLib Key-value parser
+ 483341 g_error and friends create warnings when not used in MSVC
+ 569375 g[u]intptr undocumented
+ 573251 documentation for g_seekable_truncate() needs some love
+ 629347 Missing annotations in GFile (was: Perf throws an exception in cur...
+ 630983 [PATCH] Type accuracy for result of strlen() in string utilities.
+ 632953 Clarify documentation of GValueTransform.
+ 636210 Document that pre-unmount is not guaranteed and backend-dependant
+ 656502 type information for GSettings::backend missing from .gir
+ 661442 Nautilus crashes when refreshing home folder after modifying ~/.co...
+ 668035 gtester-report broken with python 2.7.2 and glib 2.30.1
+ 670139 gbytes.c:try_steal_and_unref nit
+ 677233 (transfer full) annotation not correct for g_closure_new_simple re...
+ 679347 glocalfile seems to leak 'fstype'
+ 679467 Mention translation in g_warning() documentation
+ 689323 Variable scoping in gunixmounts.c
+ 691436 glib-mkenums output arch dependent
+ 695681 gsettings bash completion put error messages
+ 705331 AM_PATH_GLIB_2_0 macro fails with -Wstrict-prototypes -Werror
+ 706667 Fix permission denied error when installing from an nfs directory
+ 711809 gdbus-proxy: Fix erroneous timeout during following tests
+ 722256 gslist: Simplified node removal and got rid of some code duplication
+ 723655 Socket source is left in the poll after the socket is closed
+ 723743 g_child_watch_add() doesn't check for non-pids
+ 725014 g_settings_schema_source_ref should check for NULL pointer
+ 727346 docs: Escape some backslashes for markdown
+ 730296 gsignal: Fix a potential NULL pointer dereference
+ 731625 Improve test for darwin printf format-strings
+ 731705 gio/tests/desktop-app-info assumes /bin/true
+ 737278 Clarify relationship of g_application_quit() to hold count
+ 738176 Skip GSpawnChildSetupFunc closures in introspection
+ 740223 source_object for GAsyncResult should be nullable
+ 740791 gio: cannot specify the source when joining a multicast group (IGM...
+ 740826 glib doesn't know fuse filesystems
+ 742548 configure.ac: stay out of autoconf's namespace
+ 742997 Don't skip invalid enum values in schemas
+ 745723 -Wunused-but-set-variable work-around no longer sufficient
+ 749371 Use a GHashTable as a set when possible
+ 751738 Unused-variable warnings in glib/tests/autoptr.c
+ 752239 Missing dependency for python files in build file
+ 752240 Add DTLS support to GIO
+ 753459 GDateTime: Add conversion functions from/to ISO 8601 strings
+ 753521 g_subprocess_launcher_set_environ misses argument annotations
+ 754026 gfileutils: add some sanity checks
+ 756009 'const gchar* const *' gets incorrectly defaulted to utf8
+ 756103 Skip g_base64_decode_step() in introspection
+ 756128 Fix up annotations in gconvert
+ 756430 g_rw_lock_reader_lock() can return without locking, or error
+ 756470 Fix up annotations in gdataset.c
+ 756588 Fix up annotations on data/qdata API of GObject
+ 760022 Memory leak in gvariant-parser.c
+ 760109 [PATCH] Invalid GDate can't be g_boxed_copy()'d
+ 760716 Fix documentation regarding <glib/gprintf.h>
+ 765063 Update annotations for gio
+ 765552 Please set serial in .m4 files to prevent autoreconf failure on up...
+ 767215 GCC version number is interpreted as start of a list in docs for g...
+ 767239 Tautological comparisons in convert tests
+ 769674 some GIO tests' arbitrary timeouts are too short
+ 769846 gmessages: Add timestamp to g_log_writer_format_fields()
+ 770459 Tutorial article is slightly wrong
+ 773355 Incorrect documentation about stopping a signal emission from a hook
+ 774083 spelling mistakes in glib: charater
+ 776562 Add Intel C Compiler support for G_GNUC_BEGIN/END_IGNORE_DEPRECATI...
+ 777308 GModule win32: disable error dialog popup
+ 777310 gio/gasynchelper.c: fix cast from pointer to smaller int type on w...
+ 777956 gmessages: Update advice for G_LOG_DOMAIN
+ 779182 xdg-open fails with gio open for some uris
+ 779501 Type of GIConv given wrongly on web
+ 780202 introspection: Don't expose GValueArray.free
+ 780296 xdg-open/gnome-open doesn't work if service isn't started
+ 781598 gstdio.h should #include what it needs to work
+ 781867 various gvfsd-* wants to look in /boot/efi, causes unnecessary/ina...
+ 783210 build: Switch to sassc for generating style
+ 783270 Improve Visual Studio support for Meson builds
+ 783825 Suggest that asynchronous operations should invoke the callback in...
+ 786737 No g_variant_get() example for dicts
+ 786785 Commit #fe2a9887a8 breaks gdbus-codegen, cannot find its module so...
+ 787271 Make GListModel usable from G-I bindings
+ 787485 g_tls_backend_supports_dtls () returns true when the backend doesn't
+ 787551 Factor out some duplicated code in GParamSpec validation
+ 787581 tests: Add tests for g_slist_copy() and g_slist_copy_deep()
+ 787671 meson: Fix permissions of installed scripts
+ 787731 g_file_query_filesystem_info() wrongly reports "filesystem::readon...
+ 788138 glib-compile-resources: Fix leak of a GHashTable
+ 788180 G_FILE_ATTRIBUTE_ID_FILE is useless on W32
+ 788270 gmodule - failed to load symbol on Android 64bit
+ 788368 Race condition in GDbusObjectManagerClient
+ 788384 gtypes: Fix signedness of __builtin_bswap() usage
+ 788385 gtestutils: Explicitly cast args to g_assertion_message_cmpnum()
+ 788401 PATCH: MacOS build cannot detect content type from content - xdgmi...
+ 788467 Fatal errors and warnings should be reported as TAP
+ 788488 GFile-based API for g_build_filename()
+ 788489 gmain: add g_clear_source API
+ 788561 Document how to integrate GTest into your project
+ 788594 gdbus-tool doesn’t handle non-message-bus connections correctly
+ 788705 Allow building GLib on older Linux platforms
+ 788766 fixed a doc-typo in socket_get_remote_address
+ 788772 meson installs gdb scripts incorrectly
+ 788863 Add more filename type annotations for strings which can contain f...
+ 788880 gunixmounts: Update list of virtual file systems to ignore
+ 788927 Expose better API for detecting ‘system’ mounts
+ 788936 Show mime type icons on OS X
+ 788948 Document Autotools best practices for genmarshal/mkenums
+ 788975 Meson + Visual Studio: Can't find zlib.h with subprojects/zlib
+ 788978 Document XML has a syntax error
+ 788989 Use subdir-objects with Autotools
+ 788990 Include licensing information in output from glib-mkenums, glib-ge...
+ 789087 gint and guint misrepresented as functions
+ 789170 GFormatSizeFlags should have a value for bits
+ 789245 g_settings_bind() not conforming to lifecycle specification
+ 789444 Fix handling of length in g_utf8_make_valid
+ 789637 glib-mkenums: Fails when --ouput file does not exist
+ 789681 meson: Libmount support not built
+ 789723 [PATCH] gdbus-codegen: Call abspath() earlier
+ 789755 g_get_host_name: ensure return value is always UTF8 encoded
+ 789820 GPollFileMonitor is not cleaning up correctly
+ 790015 docs: Various linking and syntax fixes
+ 790030 GResource/GVariant fails to load from non-pointer aligned memory
+ 790093 gio-tool: fix inverted logic in monitor tool
+ 790126 gengiotypefuncs.py is missing from tarballs
+ 790147 build: Drop data-to-c.pl in favour of data-to-c.py
+ 790157 gmessages: Give examples of G_DEBUG with gdb in the documentation
+ 790272 file: add g_file_load_bytes()
+ 790275 avoid temporary string allocations in g_resources_enumerate_children
+ 790310 speedup path canonicalization in GResourceFile
+
+* Translation updates:
+ Catalan (Valencian)
+ Czech
+ German
+ Nepali
+ Norwegian bokmål
+ Slovak
+ Slovenian
+ Spanish
+
+
+Overview of changes in GLib 2.54.0
+==================================
+
+* Bugs fixed:
+ 780861 Crash in GnomeWallClock
+ 786983 Please make the output of gio-querymodules deterministic
+ 787109 Valgrind false positive in ioctl() in btrfs file copy
+ 787123 glib: Slighty update GIOChannel documentation
+ 787146 GMainLoop: match of parameter pair of LOCK_CONTEXT/UNLOCK_CONTEXT
+
+* Translation updates:
+ Basque
+ Catalan
+ Romanian
+ Swedish
+
+
+Overview of changes in GLib 2.53.7
+==================================
+
+* Bugs fixed:
+ 736710 remove unnecessary executions of libtool from configure
+ 785260 gio/tests/appmonitor fails if local dir not writeable
+ 786456 g_subprocess_wait[_check]_async() breaks when cancelled...
+ 786555 g_array_free() is not thread safe w.r.t. g_array_unref()
+ 786580 gdesktopappinfo.c: Add Tilix as a fallback terminal
+ 786807 g_uuid_string_random undefined when built with meson
+
+* Translation updates:
+ Brazilian Portuguese
+ Catalan
+ Czech
+ Danish
+ Finnish
+ French
+ Friulian
+ German
+ Italian
+ Kazakh
+ Korean
+ Latvian
+ Nepali
+ Polish
+ Spanish
+ Turkish
+
+
+Overview of changes in GLib 2.53.6
+==================================
+
+* Bugs fixed:
+ 766358 glib doesn't respect XDG_* envvars on W32, ever
+ 783270 Improve Visual Studio support for Meson builds
+ 785955 pthread_setname_np misdetected with meson
+ 786060 Sequences documentation does not make it clear...
+ 786360 gobject: add autoptr support for GClosure
+ 786452 crash on Linux without stderr stream
+ 786460 gio-tool: Unify buffer sizes
+ 786462 Use g_output_stream_write_all instead of while
+ 786463 gio-tool-save: Prevent overwriting error
+
+* Translation updates:
+ Catalan
+ Galician
+ Hungarian
+ Indonesian
+ Lithuanian
+ Nepali
+ Serbian
+
+
+Overview of changes in GLib 2.53.5
+==================================
+
+* Bugs fixed:
+ 695573 Untranslatable strings in glib-compile-schemas
+ 725950 GApplication: call dbus_unregister only once, and before destruction
+ 731703 giomodule test misbuilds its test modules as libraries
+ 769135 External control for g_test_add/g_test_run
+ 779332 Rewrite mkenums in Python
+ 779607 Race between mounts-changed signal and g_unix_mounts_get() function
+ 784000 Improve strerror_r() detection
+ 784815 Map G_NOTIFICATION_PRIORITY_HIGH to NOTIFY_URGENCY_NORMAL
+ 784965 Use the glib preset for i18n in Meson
+ 784995 meson: some Windows improvements
+ 785113 glib-mkenums Python port fixes
+ 785130 G_LOG_DOMAIN shouldn't be left undefined for applications
+ 785438 Spurious -Wmaybe-uninitialized in gdatetime.c
+ 785468 glib/gpoll: Unnecessary if conditional included in the poll_rest() function
+ 785520 Replace advice to use removed gdk_spawn functions
+ 785577 clobbers errno while setting GError
+
+* Translation updates:
+ Slovenian
+ Spanish
+
+
+Overview of changes in GLib 2.53.4
+==================================
+
+* Unicode support has been updated to Unicode 10.0.0
+
+* glib-genmarshal and glib-mkenums have been rewritten in python.
+  Every effort has been made to keep compatibility. Please report
+  problems related to these tools
+
+* GLib can now be built with meson. autotools are still supported
+
+* Bugs fixed:
+ 722047 drop makefile.msc?
+ 733821 g_strerror() uses strerror(3) instead of strerror_r(3)
+ 773842 g_utf8_find_next_char() won't signal the end of a NUL-terminated string
+ 779332 Rewrite mkenums in Python
+ 780095 g_utf8_get_char_validated() stopping at nul byte even for length specified...
+ 780634 Remove remaining old codepage ABI comapt code
+ 783841 test_GDateTime_new_from_timeval_overflow fails on 32 bit systems
+ 784000 Improve strerror_r() detection
+ 784020 GKeyFile – Add array length annotations to to_data(), get_keys() and get_g...
+ 784037 gio: Mention the ALL_METADATA flag in g_file_copy()
+ 784433 gdbus-codegen with variant type parameters result in nested variant
+ 784456 Update to Unicode 10.0.0
+ 784528 Rewrite glib-genmarshal in Python
+ 784579 Calling g_dir_open on Missing Directory When Executable File Path Contains...
+ 784581 docs: Fix cut'n'paste error in g_resources_get_info() doc
+ 784739 Minor typo in configure error message
+ 784792 Just fixing a little typo in comments
+
+* Translation updates:
+ Hebrew
+
+
+Overview of changes in GLib 2.53.3
+==================================
+
+* Bugs fixed:
+ 658446 Add translation comment for wrong password notice string
+ 661926 Improve the default logging setup in GLib
+ 674885 type initialisation deadlock in GObject
+ 775593 GIO cannot write symlinks on FreeBSD and NetBSD
+ 776169 Various gio-tool fixes
+ 776333 Fix annotation on g_file_copy_async()
+ 776504 Upgrade license from LGPLv2+ to LGPLv2.1+
+ 777307 race condition between gdbus signal callback and g_bus_unwatch_name...
+ 778422 gsubprocesslauncher: Clarify the behavior of set_environ()
+ 781301 Stack pointer corrupted by incorrect call of NtNotifyChangeMultipleKeys
+ 782336 Add additional documentation of the GResource XML format
+ 782996 build: Use AM_TESTS_ENVIRONMENT rather than TESTS_ENVIRONMENT
+ 783061 GApplication: Remove some unused members
+ 783130 Make dbus activation sandbox-aware
+ 783193 Adapt to OpenURI api change
+ 783201 gdbus-codegen: Apply --output-directory to generated docs as well
+ 783340 win32: port monotonic times to use QPC
+ 783350 length parameter can be NULL g_data_input_stream_read_line
+ 783392 incorrect (out) annotation for g_dbus_interface_info_generate_xml
+ 783593 GGtkNotificationBackend should use /org/freedesktop/DBus to call Ge...
+
+* Translation updates:
+ Esperanto
+ German
+ Indonesian
+ Kazakh
+ Spanish
+
+
+Overview of changes in GLib 2.53.2
+==================================
+
+* A few new number parsing functions have been added:
+  - g_ascii_string_to_signed
+  - g_ascii_string_to_unsigned
+  These have better error handling than the existing ones.
+
+* glib-mkenums now supports /*< private >*/ and /*< public >*/
+
+* GSettings now consider XDG_DATA_HOME in addition to XDG_DATA_DIRS.
+
+* Bugs fixed:
+ 674885 type initialisation deadlock in GObject
+ 698064 Add g_ptr_array_contains()
+ 732000 gdatetime: Remove an unnecessary NULL pointer check
+ 734946 Implement GContentType on OSX
+ 741335 Possible differences in use of XDG_DATA_DIRS versus XDG base directory specification
+ 748263 Use-after-free in g_dbus_connection_call_internal()
+ 776876 gmodule – Various Android bug-fixes
+ 777030 build error where minor() and major() cant be resolved in gio/gdbusmessage.c
+ 780300 gio/gosxappinfo.c uses deprecated LSFindApplicationForInfo
+ 780309 gio/tests/appinfo build fails: gdesktopappinfo.c skipped on OS X
+ 781755 Avoid compiler warnings in generated marshallers code
+ 781826 portal support: Read /.flatpak-info
+ 781830 Fix some typos and errors in GVariant documentation
+ 781847 Use-after-free under send_message_with_reply_cleanup():gdbusconnection.c:1792
+ 781867 various gvfsd-* wants to look in /boot/efi, causes unnecessary/inappropriate auto...
+ 782068 doc: Trivial typo fixes
+ 782075 gtimer: Handle gmtime() failure in g_time_val_to_iso8601()
+ 782089 gdatetime: Fix overflow checks when constructing from timestamps
+ 782162 Support public/private trigraph in glib-mkenums
+ 782237 make check error
+ 782311 inode/directory is treated as a subclass of application/octet-stream
+ 782628 libmount build dependency check not requiring the right version?
+
+* Translation updates:
+ Hungarian
+ Indonesian
+ Spanish
+
+
+Overview of changes in GLib 2.53.1
+==================================
+
+* The gdbus tool gained a wait command
+
+* g_unix_signal_source_new support SIGWINCH now
+
+* There are now g_enum_to_string and g_flags_to_string functions
+
+* A new function to instantiate objects: g_objet_new_with_properties
+
+* GParameter and related APIs have been deprecated
+
+* Bug fixes
+ 447907 enum/flags from string + type transform + tests
+ 668962 GUnixMountPoint/GUnixMountEntry not usable through gobject-introspection
+ 669355 gdbus-codegen output contains stray semicolons at file scope (forbidden in C99)
+ 674885 type initialisation deadlock in GObject
+ 698064 Add g_ptr_array_contains()
+ 709865 Add boxing to GParameter
+ 725894 build: Include gettext libraries for static compilation on Mac OS X
+ 734946 Implement GContentType on OSX
+ 741229 gio: Handle NULL cached properties in NetworkManager monitor
+ 745971 gdbus-tool: Add a command to wait for a well-known name on the bus
+ 755046 gfileutils: Add precondition checks to g_file_test()
+ 761102 Increase performance for main loop
+ 761889 GDateTime: %p does not always print AM/PM string
+ 766660 Please clarify the extent to which GInitable, GAsyncInitable must be idempotent
+ 769534 g_unix_signal_source_new does not support SIGWINCH
+ 772221 Take advantage of Unicode
+ 775879 g_log_default_handler should not check G_MESSAGES_DEBUG
+ 776169 various gio-tool fixes
+ 777961 Documentation for g_app_info_equals() could be clearer
+ 778049 race in gsource detected by TSan
+ 778207 gio-querymodules: fix memory leak
+ 778287 G_MODULE_EXPORT and -fvisibility=hidden
+ 779409 Fix false positive g_warning() in remove_filter()
+ 780066 g_base64_encode_close() in glib/gbase64.c produces invalid base64 encoding
+ 780095 g_utf8_get_char_validated() stopping at nul byte even for length specified buffers
+ 780306 Unused function in gunicollate.c for CARBON
+ 780310 g_tls_database_verify_chain doesn't set the GError for failures other than cancell...
+ 780384 gio/tests/contenttype fails on OS X: "public.directory" != "public.folder"
+ 780441 Make the portal implementation of g_app_info_launch() synchronous
+ 780634 Remove remaining old codepage ABI comapt code
+ 780908 gobject: remove duplicate GType sanity check
+ 780924 Memory leak in gdbusmethodinvocation.c
+ 781125 gio-tool: Fix errors format string
+ 781234 the buffer written to by g_input_stream_read is not marked as an out parameter
+ 781298 gfileutils.c:330:3: error: ISO C90 forbids mixed declarations and code
+
+* Translation updates
+ Catalan
+ Friulian
+ German
+ Hebrew
+ Indonesian
+ Polish
+ Russian
+
+
+Overview of changes in GLib 2.52.0
+==================================
+
+* Bug fixes:
+ 779799 gdatetime test fails with tzdata 2017a
+ 780032 Add missing attributes to two functions
+ 780144 gio/fam: Remove leftover debug print
+
+* Translation updates:
+ French
+ Friulian
+ Latvian
+
+
+Overview of changes in GLib 2.51.5
+==================================
+
+* OS X implementations of GContentType and GAppInfo
+  have been added
+
+* Bugs fixed:
+ 673047 gunicollate is broken on OS X (patch included!)
+ 734946 Implement GContentType on OSX
+ 747146 Implement GNotification on OSX
+ 769983 glib-mkenums generates non-reproducible Makefile snippets
+ 777203 gnulib license information is not correct in glib2.0
+ 778515 Crash in the gio kqueue backend
+ 779456 Make g_utf8_make_valid optionally take a length
+
+* Translation updates:
+ Danish
+ Friulian
+ German
+ Hungarian
+ Korean
+ Lithuanian
+
+
+Overview of changes in GLib 2.51.4
+==================================
+
+* Memory leak fixes
+* Fix the released tarball
+
+
+Overview of changes in GLib 2.51.3
+==================================
+
+* Bugs fixed:
+ 771997 gchecksum: Add SHA-384 support
+ 778422 gsubprocesslauncher: Clarify the behavior of set_environ()
+ 778581 gdbus-codegen: Fix -Wconversion warning
+ 778801 gdbus-codegen: Add --outdir flag
+ 778991 Plug a mem leak in gdbusauth
+ 779183 g_io_extension_point_get_extensions should check for NULL pointer
+
+* Translation updates:
+ Basque
+ Chinese (Taiwan)
+ Danish
+ Indonesian
+ Italian
+ Serbian
+
+
+Overview of changes in GLib 2.51.2
+==================================
+
+* Minimal support for UUIDs has been added
+
+* A new file attribute, G_FILE_ATTRIBUTE_RECENT_MODIFIED has been added
+  to improve sorting of recent files
+
+* Bugs fixed:
+ 639078 UUID support feature request
+ 777135 gkeyfile: Be more specific about error codes in documentation
+ 777307 race condition between gdbus signal callback and g_bus_unwatch_name...
+ 777481 goutputstream: docs: fix typos
+ 777493 g_mkdtemp() not introspectable
+ 777507 Recent view sorting incorrectly
+ 777592 Add minor examples to GDBus and GVariant documentation
+ 778002 race in gdbusprivate.c detected by the ThreadSanitizer
+ 778096 race in gdbusconnection reported by TSan
+
+* Translation updates:
+ Norwegian bokmål
+ Polish
+ Simplified Chinese
+ Slovak
+ Spanish
+ Swedish
+
+
+Overview of changes in GLib 2.51.1
+==================================
+
+* glib-compile-resources grew a --generate-phony-targets flag
+
+* GLib now installs a valgrind suppressions file for GLib and GIO
+
+* Bugs fixed:
+ 666114 should have infrastructure to run its tests under valgrind
+ 729730 GDBusMessage: Fix segfault if DEBUG_SERIALIZER is enabled
+ 730932 statically assert that reasonable assumptions about enums are true
+ 735731 gobject: Document behaviour of GType checking macros on NULL
+ 736810 gdbus: Fix leak in g_dbus_message_print()
+ 762283 GSocket – Fix race conditions on Win32 if multiple threads are waiting on cond...
+ 767609 Test suite problems
+ 767952 g_dbus_method_invocation_return_*, g_dbus_method_invocation_take_error: They d...
+ 769672 Assert threads for testcase 642026 are sucessfully created
+ 769745 gtask: Add guards for public functions
+ 770175 Add command line argument to mkenums and genmarshal to write output to a file
+ 770646 glib: Namespace global tapset variables by soname
+ 772160 Add g_unix_mount_for() support
+ 772989 Totem allows invalid urls that might cause segfault that's irrecoverable
+ 773823 gio: Bump copy buffer size to 256k by default
+ 774086 fix g_main_context_check declaration
+ 774368 Dependency file output of resource scanner breaks Ninja
+ 774421 Two minor patches
+ 774520 GSocket allocates and processes control messages even if not requested
+ 775309 Crash in gdbusauth
+ 775468 Improve log write supports color method on windows
+ 775510 testing with -fsanitize=undefined reports various undefined behaviour
+ 775517 Password input is echoed in the terminal
+ 775621 gmessages: Fix compilation on Android
+ 775765 FDO notification withdrawal backend sends wrong ID to the server
+ 775913 subprocesslauncher: potential infinite loop in verify_disposition()
+ 776198 Stray semicolon after g_variant_print() function in gvariant.c
+ 776586 License headers cleanup
+ 777077 Use of memory after it is freed
+
+* Translation updates:
+ Brazilian Portuguese
+ Czech
+ Galician
+ German
+ Hebrew
+ Kazakh
+ Lithuanian
+ Spanish
+ Swedish
+
+
+Overview of changes in GLib 2.51.0
+==================================
+
+* glib-genmarshal and glib-mkenums have gained --output options
+  for better build system integration
+
+* New API: g_utf8_make_valid
+
+* Bugs fixed:
+ 591603 Make _g_utf8_make_valid public
+ 610969 Nice to have g_utf8_make_valid as public
+ 767882 Bit shift overflow (-Wshift-overflow) warning in gparam.h
+ 769135 External control for g_test_add/g_test_run
+ 769630 gfile: G_FILE_MONITOR_WATCH_MOVES was actually introduced in 2.46
+ 772160 Add g_unix_mount_for() support
+ 772221 Take advantage of Unicode
+ 773303 GApplication leaks option_strings 
+
+* Translation updates:
+ French
+ Galician
+ German
+ Hungarian
+ Lithuanian
+ Norwegian bokmål
+ Occitan
+ Polish
+ Slovak
+ Turkish
+
+
+Overview of changes in GLib 2.50.1
+==================================
+
+* Update Unicode support to Unicode 9.0.0
+
+* Bugs fixed:
+ 662946 gunixmounts monitoring doesn't work correctly with libmount
+ 771591 Update to Unicode 9.0.0
+ 772054 glib/gspawn-win32-helper.c: unexpected behavior re CommandLineToArgvW()
+ 772255 gresolver: Mark GResolver as an abstract class
+ 772269 Add --version options to glib-compile-resources and glib-compile-schemas
+ 772297 completion: Complete gsettings describe
+ 772511 g_log_default_handler crashes windows apps with "Unspecified fatal err...
+
+* Translation updates:
+ Brazilian Portuguese
+ Catalan
+ Croatian
+ Czech
+ Danish
+ Hungarian
+ Italian
+ Latvian
+ Polish
+ Swedish
+
+
+Overview of changes in GLib 2.50.0
+==================================
+
+* Bugs fixed:
+ 771438 Turn on libmount by default on linux
+        Fix the annotation for g_log_variant
+
+* Translation updates:
+ British English
+ French
+
+
+Overview of changes in GLib 2.49.7
+==================================
+
+* Add g_log_variant, binding-friendly api for structured logging
+
+Bugs fixed:
+ 646926 arg_data invalid after g_option_context_parse() fails
+
+* Translation updates:
+ Danish
+ Finnish
+ Galician
+ German
+ Hebrew
+ Kazakh
+ Korean
+ Latvian
+ Lithuanian
+ Polish
+ Portuguese
+ Serbian
+ Slovak
+ Spanish
+ Swedish
+ Thai
+
+
+Overview of changes in GLib 2.49.6
+==================================
+
+* The gsettings commandline tool now has a describe command
+
+Bugs fixed:
+ 745754 Add gcc-style dependency output to glib-compile-resources
+ 769076 Fix warning: attempt to override closure->va_marshal with new marshal
+ 770372 gdbus-codegen: Strip @since parameters before comparison
+
+Translation updates:
+ Brazilian Portuguese
+ Czech
+ German
+ Hungarian
+ Polish
+ Portuguese
+ Spanish
+
+
+Overview of changes in GLib 2.49.5
+==================================
+
+* Structured logging:
+ - drop libsystemd dependency
+ - document that g_test_expect_message does not work with structured logs
+
+* Use libmount for unix mount support
+
+* Add an async variant of g_app_info_launch_default_for_uri
+
+Bugs fixed:
+ 522053 GUnixMountMonitor needs to use /proc/self/mountinfo on recent Linux
+ 682794 Add usage guidance to logging documentation
+ 744456 Structured logging API
+ 766370 Add a macro for initializing g_auto(GVariantBuilder)
+ 767240 Regex failures with pcre 8.38
+ 768198 Can't build glib with systemtap enabled
+ 768453 Gdbus test: compilation fails due to -Werror=format-y2k errors
+ 768752 Add async variant of g_app_info_launch_default_for_uri
+ 769027 Docs misleadingly imply G_CHECKSUM_SHA512 is available since 2.16
+ 769029 gmessage: compiler complains about -Wformat-nonliteral
+ 769042 'O_CLOEXEC' undeclared (first use in this function)
+ 769087 gmessages: support NULL log domain
+ 769089 Fix gsettings uint64 testcase
+ 769104 Build failure when using _GLIB_CHECKED_ADD_U32 with the Intel compiler
+ 769139 g_log_writer_journald uses non-standard 'htole64' function
+ 769238 memory increases every time I umount and mount my secondary hard disk.
+ 769245 is_valid_heap_iter define misses NULL pointer check
+ 769507 gmessages: Don’t require is_journald() call before writer_journald()
+ 769785 gmessages: Expand documentation further for structured logging
+ 769995 gdbus-codegen: Allow '@since: UNRELEASED' in documentation comments
+
+Translation updates:
+ Catalan
+ Hebrew
+ Lithuanian
+ Slovak
+ Spanish
+
+
+Overview of changes in GLib 2.49.4
+==================================
+
+* Change the just-introduced structured logging API. The arguments
+  of g_log_structured() had to be reordered to enable an implementation
+  within the limits of what the standards guarantee about var args.
+
+Bugs fixed:
+ 744456 Structured logging API
+ 768936 gio doc build fails because of missing gio.xml in the tarballs
+ 768963 improper va_list use in g_log_structured()
+ 768968 gio/tests/socket-listener hangs since e4ee307
+
+Translation updates:
+ Spanish
+
+
+Overview of changes in GLib 2.49.3
+==================================
+
+* GLib has a structured logging API, g_log_structured, with support
+  for writing to the systemd journal. It also supports colored output
+  in terminals
+
+* Some new GBytes API has been added:
+ - g_key_file_load_from_bytes
+ - g_compute_hmac_for_bytes
+
+* Stack-allocated GVariantBuilder and GVariantDict objects can now be
+  initialized with G_VARIANT_BUILDER_INIT and G_VARIANT_DICT_INIT
+
+* gio:
+ - Add a way to register handlers for custom uri schemes
+ - Add a G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE attribute to
+   have these heuristics in a single place
+ - Include a gio tool that makes the functionality of the
+   various gvfs commandline tools available in a single place
+ - Add portal support to g_app_info_launch_default_for_uri
+ - Add portal support to GNetworkMonitor
+ - Add portal support to GProxyResolver
+ - Add portal support to g_application_send_notification
+
+Bugs fixed:
+ 547200 g_utf8_find_next_char() issues
+ 662802 systemtap multiarch issue
+ 723506 fork/exec from non-main thread when autolaunching could be avoided...
+ 725902 build: simplify dtrace configuration
+ 728207 gsocketservice: Documentation does not mention that is already act...
+ 729914 instead of DEBUG_CODE and IF_DEBUG, provide a common macro to supp...
+ 744456 Structured logging API
+ 744678 Unable to delete relocatable schemas
+ 746685 clarify that g_variant_get_data() can be used instead of g_variant...
+ 747134 glib-compile-resources --generate should detect common C++ file ex...
+ 750257 GSettings changed signal should clearly state the order required
+ 753231 Memory is potentially used after free
+ 754012 missing filename in "Error loading css: Failed to import: Error op...
+ 760115 gtestutils: add missing dash in seed argument's --help documentation
+ 760423 gio-querymodules prints error messages as question marks on some l...
+ 761102 Increase performance for main loop
+ 765338 GLib.compute_hmac_for_data throws every time
+ 766370 Add a macro for initializing g_auto(GVariantBuilder)
+ 766899 Superflous HTML/XML comments in GDBusProxyTypeFunc documentation s...
+ 766933 GSocketAddress leaks in gnetworkmonitornetlink.c:read_netlink_mess...
+ 767765 Add names and tags to various GSources and GTasks constructed in GLib
+ 767880 gkeyfile: add g_key_file_load_from_bytes() API
+ 767887 vfs: add g_vfs_register_uri_scheme()
+ 767949 [patch] Typos in glib docs
+ 768029 infinite loop in parse_name_internal()
+ 768119 Fix fallout from get_supported_schemes() changes
+ 768357 Build the gio tool on Windows/MSVC
+ 768498 portal support for glib
+ 768504 keyfile: g_key_file_get_double behavior doesn't follow documentation
+ 768549 Test failure: test_ip_sync_dgram
+ 768551 Test failure: test_socket_address_to_string
+ 768560 gio/tests/gsettings: fix GSettings reference leaks in some tests
+ 768780 O_PATH is a non-standard flag which may be unavailable on non-Lin...
+ 768806 gdbus tool must swallow -- argument
+
+Translation updates:
+ Chinese (Taiwan)
+ French
+ Hebrew
+ Indonesian
+ Lithuanian
+ Portuguese
+ Spanish
+
+
+Overview of changes in GLib 2.49.2
+==================================
+
+ * GMainContext and GTask have gained more systemtap probes
+
+Bugs fixed:
+ 673101 resource compiler dependency generation not working for gen...
+ 700756 GFile.new_for_path arguments misses (type filename) annotation
+ 730187 glocalfileoutputstream: Fix an FD leak in an error path
+ 755439 Memory leak in gdbusproxy.c
+ 759813 Add more SystemTap/DTrace probes for main context and GTask
+ 761810 gio: Support using GDBusObjectManagerServer at path ‘/’
+ 767172 docs: Move GIO_USE_VFS to "okay for production" section
+ 767218 Remove a UTF-8 ellipsis from gsignal.h
+ 767245 Add filename type annotations
+ 767824 Some UTC timezones incorrectly recognized on Windows 7
+
+Translation updates:
+ Occitan
+
+
+Overview of changes in GLib 2.49.1
+==================================
+
+ * GDesktopAppInfo now allows bus activation with dashes. This is
+   not technically allowed per the Desktop Entry specification, but
+   it happens in the wild. Rather than forcing people to go through
+   another traumatic desktop file rename, accept it and translate - to _.
+
+ * The support for giving names to threads has been improved. Thread names
+   are now supported on Solaris as well, and the Linux support no longer
+   uses prctl() but the pthread api.
+
+ * GIO resources can now be overridden at runtime, using the G_RESOURCE_OVERLAYS
+   environment variable.
+
+ * gdbus-codegen can now generate autocleanup definitions for the types
+   it generates. Use the --c-generate-autocleanup option to control this
+
+Bugs fixed:
+ 665446 Use g_abort() instead of abort()
+ 731988 glocalfile: Avoid a potential NULL pointer dereference
+ 742898 g_value_type_transformable() description differs from the code
+ 747107 GVariant varargs documentation: g_variant_get() example
+ 747478 g_system_thread_set_name() is not implemented for gthread-win32
+ 748474 g_get_language_names() is not thread-safe
+ 748530 gthread: W32 implementation of g_get_num_processors() has lame fallback
+ 748806 GVariant: Better introduction to the concepts and its uses
+ 749583 GSequence performance improvements
+ 749606 tests: always remove app.desktop
+ 755898 [PATCH] settings: add get/set uint64
+ 758174 Fix documentation typos
+ 758738 Usage of GType properties causes crashes due to gulong/gpointer mismatch
+ 760186 namespace clash with gdb pretty-printing code
+ 762994 Race condition in GIO/AppFileChooser crashes Firefox/Gtk3
+ 763379 codegen: Add support for g_autoptr to gdbus-codegen–generated objects
+ 763821 build: Also dist Systemtap files always for gobject/
+ 764092 gstrfuncs: Document the behaviour of g_strjoinv()
+ 764163 g_task_had_error doesn't remember the error after g_task_propagate_*
+ 764415 Very High CPU usage in g_poll() Windows implementation
+ 764574 build: Fix all statfs() tests failing
+ 764575 tests: Fix compilation errors due to Y2K format problems
+ 764685 GApplication documentation about handling command-line options is confusing
+ 764754 '-' in application id: unbreak bus activation and notifications
+ 765173 documentation of g_main_context_push_thread_default() regarding GIO...
+ 765668 GResources: add support for resource overlays
+ 765710 gdbus-tool: only print note about expected argument types if that...
+ 765712 tests: Fix compilation
+ 765861 task: avoid context lock when setting source name
+ 765900 Add g_drive_is_removable() support
+ 765924 Improve external drives detection
+ 765959 socket: set fd field to -1 after closing socket
+ 765990 Visual Studio: Define inline only when necessary
+ 765991 Compilation of gresource.c is broken due to S_ISDIR
+ 766092 Incorrect locale handling in g_date_time_format_locale()
+ 766211 Fix the upper bound in g_unichar_iswide_bsearch
+ 766407 Some build-related defects in glib testsuite
+ 766570 build: Fix a misnamed variable in glib-tap.mk
+
+Translation updates:
+ Basque
+ Catalan
+ Chinese
+ Occitan
+ Portuguese
+ Turkish
+ Vietnamese
+
+
+Overview of changes in GLib 2.48.0
+==================================
+
+ * a minor build fix in the name of determinism
+
+ * a few coverity fixes
+
+Bugs fixed:
+ 763617 giotypefuncs.c: Sort _get_type functions in the 'C' locale
+
+Translations updated:
+ Danish
+ Italian
+
+Overview of changes in GLib 2.47.92
+===================================
+
+ * gdbus-codegen now supports g_autoptr()
+
+ * g_get_user_runtime_dir() now reliably returns an existing directory
+
+ * g_array_remove_range() can now remove 0 items from the end of an array
+
+ * Many fixes for Windows
+   * build fixes
+   * file monitoring
+   * gsettings backend
+   * streams
+   * random numbers
+   * wide character support
+
+ * documentation improvements
+
+ * other small bugfixes
+
+Bugs fixed:
+ 724847 Segmentation fault on "gsettings list-recursively"
+ 743933 gapplication: add --app-id command line option
+ 756706 [PATCH] gio/gtestdbus.c: don't use non-standard %m printf modifier
+ 757506 gsettings: schema_list should use the passed schema's source
+ 760694 W32: Apps linked with -mwindows make cursor busy sometimes
+ 762202 g_win32_error_message improvements
+ 762637 build: Unconditionally dist tapset files
+ 762748 Undefined behavior
+ 762937 Mention that g_clear_error can be used with an "empty" GError
+ 763339 array: Support clearing an empty array with g_array_remove_range()
+ 763344 g_get_user_runtime_dir(): ensure directory exists
+ 763379 codegen: Add support for g_autoptr to gdbus-codegen–generated objects
+
+Translations updated:
+ Brazilian Portuguese
+ Czech
+ Finnish
+ French
+ Galician s
+ German
+ Greek
+ Hebrew
+ Hungarian
+ Italian
+ Kazakh
+ Korean
+ Latvian
+ Lithuanian
+ Occitan
+ Polish
+ Russian
+ Serbian
+ Slovak
+ Slovenian
+ Spanish
+ Swedish
+
+Overview of changes in GLib 2.47.6
+==================================
+
+* Windows usupport:
+ - Fixes and improvements to the GSettings registry backend
+ - Handle readability and writability of registry keys
+ - Use Unicode registry APIs
+
+* Bugs fixed:
+760852 744772 761126 747927 761337 744570 761504 761550 761843
+ 744570 GString is missing (transfer none) annotations on many of its methods
+ 744772 systemtap and gdb scripts install in wrong place
+ 747927 Documentation: various small improvements
+ 760852 gdbusobjectmanagerserver: Clarify recommended ObjectManager paths
+ 761126 winiconv: update to upstream version
+ 761337 Fix some annotations
+ 761504 W32 registry GSettings backend does not use Unicode
+ 761550 Cannot build with default flags under Fedora rawhide (-Werror=format-...
+ 761843 gmacros.h is testing attributes with __has_feature (when compiling wi...
+
+* Translation updates:
+ Brazilian Portuguese
+ Bulagarian
+ Chinese (Taiwan)
+ Hungarian
+ Polish
+ Slovak
+ Slovenian
+ Spanish
+ Swedish
+
+
+Overview of changes in GLib 2.47.5
+==================================
+
+* the system copy of PCRE is now used by default to implement GRegex.
+  Configure with --with-pcre=internal if a system PCRE version
+  is unavailable or undesired.
+
+* interfaces for DTLS support have been added.  A new version of
+  glib-networking will also be required.
+
+* GDBusMethodInvocation now drops replies if the sender set the
+  NO_REPLY_EXPECTED flag
+
+* several GApplication fixes, including fixes for commandline arguments
+  in interpreted languages on Windows
+
+Bugs fixed:
+ 624186 Deprecate glib-gettext macros
+ 734095 gtk-demo.py of PyGObject fails to run on Windows (and likely other binding scripts using g_application_run())
+ 735754 Implement close on TLS GOutputStream
+ 748064 gnulib vfprintf returns desired (not actual) number of bytes, ignores errors
+ 752240 Add DTLS support to GIO
+ 755421 GDBus ignores NO_REPLY_EXPECTED flag in messages, leading to warnings on system bus
+ 756875 Include ntdef.h for NTSTATUS
+ 759554 g_application_run() calls g_main_context_default() repeatidly
+ 760199 gsettings: Install gettext ITS rules
+ 760215 G_LIKELY/_UNLIKELY macros need more parentheses
+ 760683 regex test: Check the expected PCRE exceptions at runtime
+
+Translations updated:
+ Brazilian Portuguese
+ Czech
+ German
+ Lithuanian
+ Swedish
+
+Overview of changes in GLib 2.47.4
+==================================
+
+* The GApplication documentation has been improved in several areas.
+
+* Bugs fixed:
+ 749092 gdb pretty-printers fail on Python 3 with a TypeError...
+ 757374 macros: clean up "inline" mess
+ 758641 Memory leak in g_dbus_proxy_new_for_bus_sync()
+ 759134 Add missing checks for gnulib vasnprintf()
+ 759408 Do not use uninitialized var 
+ 756475 Stop supporting non-POSIX getpwuid_r, getgrgid_r
+ 757372 GApplication: destroy the impl on shutdown
+ 728099 macros: add G_GNUC_CHECK_VERSION() for compiler checks
+ 757299 glib-compile-resources: do not leak c_name
+ 758553 Fix gettext use
+ 758823 file monitors: reorder some code to avoid segfault
+ 756214 gsettings: Don't translate ""
+ 710243 Add GParamSpec object ref management annotations
+ 735696 xdgmime: Finer handling for cases where mmap() is not available
+ 752983 gapplication: Acquire the main context before running
+
+* Translation updates:
+ Swedish
+
+
+Overview of changes in GLib 2.47.3
+==================================
+
+The inline cleanup in the last release accidentally removed three
+symbols from libglib-2.0.so.  It is unlikely that this will have caused
+any problems because these symbols were only backup symbols for
+definitions exported as inlines in the header files, but ABI is ABI.
+
+This release corrects only this problem.
+
+Overview of changes in GLib 2.47.2
+==================================
+
+* We have formalised the assumption that all compilers that are
+  interested in support 'static inline' and simplified the macros around
+  this considerably.  Please watch for and report unintentional fallout.
+
+* New API: hardware-assisted helpers for overflow-checked integer math.
+
+* other fixes
+
+Bugs fixed:
+ 696324 gtester-report doesn't work with Python 3.x
+ 719966 glib: Add missing (nullable) and (optional) annotations
+ 752837 gobject and glib-compile-resources rely on .CRT$XCU section, no longer works with Win 10 UCRT (VS 2015)
+ 755364 make gtkdoc-check happy again
+ 756134 Segmentation fault on calling g_simple_action_group_add_action with bad action constructor call
+ 756179 gwin32.c: Replace VerifyVersionInfoW() with RtlGetVersion() due to API deprecation
+ 756988 GSequence should document each function's complexity
+ 757294 Move G_POLLFD_FORMAT to glibconfig.h
+ 757374 macros: clean up "inline" mess
+ 757451 doc: fix g_task_attach_source() example
+ 757628 gio tests fail to build when cross compiling 2.46.1
+ 757693 Invalid free in g_local_file_trash()
+ 757742 Fix up annotations in ghash.c
+ 758181 GTask: fix wrong example code
+
+Translations updated:
+ Greek
+ Hebrew
+ Hungarian
+ Norwegian bokmål
+ Portuguese
+ Scottish Gaelic
+ Simplified Chinese
+ Spanish
+
+Overview of changes in GLib 2.47.1
+==================================
+
+* The Unicode support has been updated to version 8.0 of the Unicode standard
+
+* GDesktopAppInfo no longer sets the DISPLAY environment variable when
+  launching apps. This is now done in the GAppLaunchContext implementations
+  when appropriate
+
+* Bug fixes:
+ 664740 Key-value file parser, space after integer
+ 687223 cleverer GThreadPool management
+ 692085 stderr and stdout are not always file descriptors 1 and 2
+ 697907 Add interface for socket-like things (GSocket, DTLS, etc)
+ 735754 Implement close on TLS GOutputStream
+ 737116 Add functions to print GSocketConnectables and addresses as strings
+ 743011 Minor additions to GError documentation
+ 749161 undefined reference to `__imp__stat32i64'
+ 749314 Cannot restore a just-trashed file
+ 751924 Add recvmmsg()-like API on GSocket
+ 752240 Add DTLS support to GIO
+ 752837 gobject and glib-compile-resources rely on .CRT$XCU section, no longer...
+ 753310 Remove `#pragma GCC system_header` from gmessages.h
+ 753935 Update example namespace and class names in GObject tutorial
+ 754855 Object instantiation documentation refers to example that no longer ex...
+ 754983 Wayland: g_desktop_app_info_launch_uris_with_spawn() forces DISPLAY va...
+ 754994 g_date_time_get_second () sometimes returns an off-by-one result
+ 755083 Clarify in G_ADD_PRIVATE that it is safe to call _get_instance_private...
+ 755351 Example still contains g_autoptr(gchar)
+ 755355 Move GStrv to glib.h so it can be used with g_auto()
+ 755374 g_variant_get_child(): flatten-first logic on '&'
+ 755496 glib 2.46 fails GStreamer test suite
+ 755609 glib 2.46.0 breaks Sun Java JVM 1.8.0.60
+ 755766 gvalue: The g_auto cleanup function assert if value is G_VALUE_INIT
+ 755795 2.46 considers empty files as octet-stream rather than text (leads to...
+ 755961 Fix up annotations in gbytes.c
+ 756053 MSVC doesn't understand the symbol 'msghdr'
+ 756054 MSVC linker error due to 'g_socket_send_message_with_timeout()'
+ 756077 testutils: remove internal ABI comment
+ 756099 g_main_context_query(): Annotate @n_fds as (in) parameter
+ 756139 musl: ctors called in the wrong order
+ 756179 gwin32.c: Replace VerifyVersionInfoW() with RtlGetVersion() due to AP...
+ 756251 The documentation of G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is confusing
+ 756255 GOutputStream swallowing errors in splice with G_OUTPUT_STREAM_SPLICE...
+ 756316 GSequence should provide fast api to check if empty
+ 756382 snprintf used on Windows with VS2015 doesn't support %n
+ 756477 gio/gthreadedresolver.c has outdated copy of bionic headers (for android)
+ 756550 gtypes.h: Make G_MININTn literals negative
+ 756875 Include ntdef.h for NTSTATUS
+ 756952 giomodule: return a copy of module name
+
+* Translation updates:
+ Basque
+ Czech
+ Serbian
+ Serbian Latin
+ Vietnamese
+
+
+Overview of changes in GLib 2.46.0
+==================================
+
+* Disable runtime-deprecation warnings
+
+* Fix marshalling of flags on bigendian 64bit architectures
+
+* Translation updates
+ Brazilian Portuguese
+ Danish
+ German
+ Latvian
+ Russian
+ Turkish
+
+
+Overview of changes in GLib 2.45.8
+==================================
+
+* utf8 validation and utf8-to-ucs4 conversion are faster
+
+* Small speedups to property change notification
+
+* Various other small optimizations for GQuark, GData
+
+* Bugs fixed:
+ 696426 GParamSpecTypeInfo do not need to be static
+ 735429 Cleanup MSVC Project Files Generation
+ 738504 Optimize UTF-8 decoding by unrolling branches and expressions
+ 742903 Add missing (transfer) annotation to GString
+ 748633 g_set_object order of operations
+ 754431 Fix build of glib/gstrfuncs.c on Windows
+ 754560 gioerror: Add more mappings for WinSock error codes
+ 754582 Glib cannot compile
+ 754601 Make g_strerror work with non-glibc POSIX systems
+ 754636 tests/unicode-encoding test fails for glib 2.45.7 on x86-64
+ 754788 more g_strerror stuff
+ 754831 autocleanups: Add GString type
+ 754924 Improve test coverage of g_utf8_validate() by added known-...
+ 754986 Avoid unnecessary signal emission during draw
+
+* Translation updates:
+ Italian
+ Kazakh
+ Korean
+ Lithuanian
+ Slovenian
+ Swedish
+
+
+Overview of changes in GLib 2.45.7
+==================================
+
+* Add G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE for use by non-POSIX-like
+  backends (e.g. cloud storage).
+
+* GFileMonitor: Make the inotify backend work with atomic renames again
+
+* GSettings: change notification is again working unconditionally
+
+* GListStore has a sort function now
+
+* Test infrastructure:
+ - Tests are now required to have unique names
+ - TAP support has been improved
+ - A macro for asserting that two memory regions have identical content
+   has been added
+
+* Bugs fixed:
+ 708525 A "g_file_query_info" on the file path "/sys/kernel/debug/hid"...
+ 742849 inotify: send paired events to both sides
+ 744060 Update GObject tutorial documentation to use G_DECLARE_FINAL_T...
+ 747364 Fix GError leak in g_file_query_writable_namespaces()
+ 749492 Support file creation time on FreeBSD and NetBSD
+ 752769 (g_socket_receive_message | g_socket_send_message) performance
+ 753745 glib-genmarshal still needed for cross-compilation
+ 754152 Add g_list_store_sort
+ 754211 Memory leak in g_file_enumerator_iterate ()
+ 754264 GLib 2.44 certificate chain construction fails if the PEM incl...
+ 754283 gtestutils: add g_assert_cmpmem()
+ 754284 gtestutils: print the TAP test plan first, not last
+ 754286 misc gtestutils fixes
+ 754307 size of array '_GStaticAssertCompileTimeAssertion_3387' is neg...
+
+
+* Translation updates:
+ Chinese (Taiwan)
+ French
+ Galician
+ Greek
+ Hebrew
+ Hungarian
+ Indonesian
+ Polish
+ Portuguese
+
+
+Overview of changes in GLib 2.45.6
+==================================
+
+* Fix a test failure and a build failure
+
+Overview of changes in GLib 2.45.5
+==================================
+
+* GNetworkMonitor now provides information about metered networks
+
+* g_mem_set_vtable has been deprecated; it has not been working for
+  quite a while. The recommendation is to use valgrind, or replace
+  malloc itself.
+
+* Bugs fixed:
+ 656325 Make GDBusInterfaceVTable binding friendly
+ 741779 Documentation tweaks addressing real-world API misuses
+ 741822 Fails to build with VS 2015
+ 742386 gdbusconnection: Don't g_printerr() when exiting
+ 743018 gobject: Add more cross-links between documentation pages
+ 750282 Add g_network_monitor_get_network_metered() to get if the connection...
+ 751358 GFileMonitor doesn't react to "mv some-file watched-file"
+ 751592 Stop using GMemVtable
+ 751598 Stop 'handle-local-options' propagation when callback reports an err...
+ 751610 g_str_hash produces collisions with strings of length 2
+ 751751 Wrong docs of g_async_queue_remove
+ 752210 gdbus command crashes with SIGSEGV
+ 752656 gdbusconnection: Fix signal subscription documentation
+ 752767 Fix typo in g_hash_table_replace() documentation
+ 753278 gdbus: Don't use g_assert_no_error() GDBusObjectManagerServer
+ 753285 g_menu_item_set_icon fails if called with NULL icon
+
+* Translation updates:
+ Catalan
+ Czech
+ French
+ Indonesian
+ Lithuanian
+ Norwegian bokmål
+ Slovak
+ Spanish
+ Thai
+ Turkish
+
+
+Overview of changes in GLib 2.45.4
+==================================
+
+* Bugs fixed:
+ 727829 win32: glibconfig.h.win32 updates
+ 741901 Clang cannot know that g_error don't return
+ 746339 GSocket kills process when fd is not a socket
+ 747676 gio/tests/socket fails: test_fd_roundtrip
+ 748610 Some tests fail with non-English locales
+ 749911 g_inet_address_to_string broken on XP/2003
+ 749912 g_inet_address_new_from_string broken on XP/2003
+ 750625 Should dismiss Software Updates Available notification after...
+ 750807 G_BREAKPOINT doesn't work as intended on Darwin
+ 751160 gtask does unnecessary work
+ 751672 -Wduplicate-decl-specifier in glib/tests/keyfile.c
+ 751731 GFile/DirectoryMonitor emit move events with other_file=NULL
+ 751737 gio/tests/appmonitor test fails in 2.45.3
+ 751798 Wrong enum type used in some test-cases
+ 752089 make gsocketservice::active a property
+ 752293 small cleanup: use list_free_full
+
+* Translation updates:
+ Greek
+ Hebrew
+ Portuguese
+
+
+Overview of changes in GLib 2.45.3
+==================================
+
+* Improve performance of g_signal_handler_disconnect for signals
+  with many handlers
+
+* GDBus has gained a new call flag to allow interactive authorization
+
+* GSettings:
+ - New API: g_settings_schema_list_keys
+ - Deprecated: g_settings_list_keys
+
+* OS X:
+ - Implement GNotification
+ - Bump the OS X requirement to 10.9
+
+* Windows:
+ - Add registry reading API
+ - Reimplement GAppInfo using registry information
+
+* Bugs fixed:
+ 666831 Support URI opening on W32
+ 728489 property action with inverted boolean state
+ 730168 Incorrect annotation on g_action_group_get_action_state_type return...
+ 733325 Several regex tests fail with pcre3 8.35
+ 734888 GLib has no helper functions to work with W32 Registry
+ 737009 signal handler lookup doesn't scale
+ 738185 Misleading language about "file name encoding" in the docs on g_env...
+ 738504 Optimize UTF-8 decoding by unrolling branches and expressions
+ 739122 glib not handling -1 return ("no limit") from sysconf (_SC_THREAD_S...
+ 739424 gnome-shell crashes when files are added, deleted, or modified in $...
+ 739616 DBus; Add new call flag to allow interactive authorization
+ 740308 Add g_settings_schema_list_keys() method
+ 740516 RFE: please provide an introspectible version of g_log_set_handler
+ 741788 Document GSettings build system integration
+ 745013 GBinding not thread safe
+ 747146 Implement GNotification on OSX
+ 747941 try XDG_RUNTIME_DIR/bus before falling back to X11 autolaunch (dbus...
+ 748727 Filechooser dialog shows no icons for directories on W32
+ 749693 GActionGroupExporter: flush queue on requests
+ 750203 GNetworkMonitorNetlink hangs in user namespace
+ 750322 gapplication: Make sure --help output is translated
+ 750344 GTlsInteractionClass is missing from doc
+ 750369 Various GBinding cleanups
+ 750386 Race condition in g_io_condition_get_type
+ 750399 Typo "equilalent" in glib documentation's glib-Error-Reporting.html...
+ 750573 GTlsDatabaseClass is not documented
+ 750918 genmarshal: silence register storage class warnings
+ 751122 gsocket: avoid unnecessary g_socket_cond_wait() in _send_messages()
+ 479730 The "g_key_file_set_comment" interface prepends '#' character to...
+
+* Translation updates:
+ Hungarian
+ Spanish
+
+
+Overview of changes in GLib 2.45.2
+==================================
+
+* Improve error reporting in glib-compile-schemas.
+
+* Add introspection annotations to GListStore.
+
+* Bugs fixed:
+ 696749 win32 : failed to compile because of careless mistake in the code
+ 723394 const parameter to GtkPopover gtk_popover_set_pointing_to
+ 724113 gdbus-connection-loss test can fail on slow machines
+ 725981 tap-driver.sh: internal error getting exit status
+ 733325 Several regex tests fail with pcre3 8.35
+ 744895 Unknown or unsupported transport 'this-should-not-be-used-and-will...
+ 747882 gtype: Bump allowed number of children
+ 748534 gtest: if a subprocess assertion fails, print its stdout and stderr
+ 748612 de_DE locale used in option-context test is not supported by FreeBSD
+ 748614 Double unref in g_socket_listener_add_inet_port
+ 748834 glocalfilemonitor: Emit notification on rate limit change
+ 749079 gdbus-peer test: TCP tests can fail with ECONNRESET due to a race...
+ 749080 gdatetime test: fails if close to rollover between seconds
+ 749180 gnetworkaddress: add return type annotation to parse methods
+ 749352 g_binding_unbind() fails when source is also the target
+ 749353 GBinding does not connect to the detailed notify signal
+
+* Translation updates:
+ Catalan
+ French
+ Slovak
+ Thai
+
+
+Overview of changes in GLib 2.45.1
+==================================
+
+* The GSettings schema compiler, glib-compile-schemas has been changed
+  to reject schema xml that has duplicate <summary> or <description>
+  elements. Such elements typically occur when translations are merged
+  into the schema, with xml:lang attributes. This is not the correct
+  way to translate schemas. Instead keep the translations in the .mo
+  file and set the gettext-domain attribute on the <schemalist> element.
+
+* The file monitoring infrastructure has been rewritten, and all backends
+  have seen major improvements.
+
+  The inotify backend is reporting events with less delay (no event will
+  be delayed more than 10ms) and wakeups due to file monitoring have been
+  significantly reduced. A CHANGES_DONE event will also be sent when new
+  files appear.
+
+  The poll implementation is now using the thread default main context.
+
+  The fam implmentation is now running in the worker thread.
+
+  The fen implementation has been removed, since it was unmaintained.
+
+* The GSettings schema compiler, glib-compile-schemas, is more strict
+  about rejecting schemas with xml:lang style merged translations.
+  Schema translations should be done by specifying the gettext domain
+  in the xml, and keeping the translations in gettext. To avoid breaking
+  already-installed schemas, this change is only taking effect when
+  you use the --strict option.
+
+* The hardcoded 10-thread limit of GTask's thread pool has been removed,
+  since it was prone to causing deadlocks. The thread pool is now allowed
+  to grow dynamically and will shrink back over time.
+
+* GSimpleAsyncResult has been deprecated in favor of GTask.
+
+* The algorithm used by GAppInfo to find default handlers for mime types
+  has been tweaked to prefer apps that handle the specific subtype over
+  default handlers for a generic supertype.
+
+* Bug fixes:
+ 627285 inotify file monitor hardwired delay
+ 631597 Segmentation fault in append_escaped_text
+ 661767 merge/improve various bits of run-in-thread functionality
+ 687223 cleverer GThreadPool management
+ 711547 win32: silence some build warnings
+ 719966 glib: Add missing (nullable) and (optional) annotations
+ 726447 Possibly an error in text string
+ 728663 W32: wrong stat struct is used when built with MinGW-w64
+ 728669 W32: GLocalFile can't measure size of files larger than 2^32...
+ 730188 gsocket: Document FD ownership with g_socket_new_from_fd()
+ 733325 Several regex tests fail with pcre3 8.35
+ 738207 Add a way to set SO_SENDBUF and SO_RECVBUF on listener (and...
+ 739850 GClosure: add valgrind hints
+ 741791 gmain: Save errno when handling unix signals
+ 744282 gvfs-open for application/x-virt-viewer changed behaviour bet...
+ 745255 Add support for copying sessions between GTlsClientConnections
+ 745745 gdbus: fix out-of-bound array access
+ 745821 Don't use __alloc_size__ attribute with clang
+ 746749 GLib-GIO:ERROR:inotify-kernel.c:327:ik_source_dispatch: ass...
+ 746753 Glib-compile-resources --generate-header not using ".h" as ...
+ 747209 glib-compile-schemas ought to reject repeated <summary> and...
+ 747349 Conversion of gdbus to use GTask causes deadlocks
+ 747363 gatomic: Add missing new line in API doc comment
+ 747472 Don't ignore already-installed schemas with multiple <summa...
+ 747541 gdbus segfaults with invalid --dest
+ 747772 Having hardcoded utf8 strings in the source code does not p...
+ 748019 gsocketconnection: Fix copy-pasto in documentation
+ 748177 not all test schemas are distributed, "make distcheck" fails
+
+* Translation updates:
+ Basque
+ Czech
+ Danish
+ Finnish
+ German
+ Hebrew
+ Icelandic
+ Norwegian bokmål
+ Russian
+ Turkish
+
+
+Overview of changes in GLib 2.43.92
+===================================
+
+GLib is now considered frozen.  We do not expect any major changes
+before the release of 2.44.0.
+
+ * GUnixMountMonitor now properly supports multiple main contexts
+
+ * many documentation improvements and cleanups.  We are now
+   approaching a point where the documentation is 100% complete and the
+   xml will build without warnings.  This will probably be enabled by
+   default in the next cycle.
+
+ * new support for HTTP proxies in GIO
+
+ * new GTask:completed property
+
+ * use "private" futexes in order to further improve the performance of
+   the contended case of GMutex and g_bit_lock()
+
+Bugs fixed:
+ 614684 Make various parts of GObject const-correct
+ 730352 Use inet_pton(), if_nametoindex() and if_indextoname() for newer versions of Windows
+ 733876 Proxy protocol 'http' is not supported.
+ 741442 threads: use FUTEX_WAIT_PRIVATE and FUTEX_WAKE_PRIVATE if possible
+ 742599 Clean up GUnixMountMonitor
+ 743636 gtask: Add a GTask:completed property
+ 743661 g_win32_check_windows_version() is missing from doc
+ 744722 docs: Expand introduction to mention using async calls over sync ones
+ 745589 [Patch] gio: add some missing autocleanup
+ 745634 [GNotifications] Use themed icon as icon-name
+
+Translations updated:
+ Bosnian
+ Bulgarian
+ Catalan
+ Czech
+ French
+ German
+ Greek
+ Hungarian
+ Italian
+ Kazakh
+ Korean
+ Latvian
+ Lithuanian
+ POTFILESin
+ Polish
+ Russian
+ Serbian
+ Slovak
+ Slovenian
+ Spanish
+ Swedish
+ Vietnamese
+ pa  for Gnome
+
+Overview of changes in GLib 2.43.91
+===================================
+
+We have now added 'g_autofree' as a libgsystem-style autocleanup macro
+that calls g_free() on the content of a local variable when it leaves
+scope (working only on GCC and clang).
+
+GApplication now has an "is-busy" property, allowing one to query the
+effective busy state.
+
+There have been various other bugfixes and cleanups.
+
+Bugs fixed:
+ 661554 GIO's use of GError is wrong
+ 744263 Fix format specifier for __LINE__ in G_OBJECT_WARN_INVALID_PSPEC
+ 744565 gapplication: add bind_busy_property()
+ 744747 Add g_autofree
+ 744756 Can't find out if gapplication is marked as busy
+ 744830 autocleanups: Add GArray and GPtrArray
+ 744876 Unclean exit from from g_application_run
+ 745239 g_property_action_new missing type annotation
+
+Translations updated:
+ Chinese (Taiwan)
+ French
+ Galician
+ Lithuanian
+ Slovak
+
+Overview of changes in GLib 2.43.90
+===================================
+
+* new GSimpleIOStream class to construct a GIOStream from an arbitrary
+  GInputStream and GOutputStream
+
+* GApplication: new API for marking 'busy' state according to the value
+  of a boolean property on another object
+
+* GOptionGroup: add binding support (boxed type, annotation fixes, etc.)
+
+Bugs fixed:
+ 739724 Test functions should have async scope
+ 741024 glist: Mention that g_list_length() is bad for checking list emptiness
+ 741630 Add GSimpleIOStream class
+ 743349 goption: Add boxed type for GOptionGroup
+ 743990 GDBus connection closing is broken
+ 744565 gapplication: add bind_busy_property()
+
+Translations updated:
+ Greek
+ Italian
+ Norwegian bokmål
+ Russian
+ Slovenian
+ Swedish
+
+Overview of changes in GLib 2.43.4
+==================================
+
+* GType now has type declaration macros G_DECLARE_DERIVABLE_TYPE,
+  G_DECLARE_FINAL_TYPE and G_DECLARE_INTERFACE, which significantly reduce
+  the boilerplate needed for GObject types and interfaces.
+
+* g_autoptr and g_auto are macros for declaring variables with automatic
+  cleanup. They only work with gcc and clang.
+
+* GListModel is a new interface that represents a dynamic list of GObjects.
+
+* GListStore is a GSequence-based implementation of GListModel.
+
+* Support thread names on OS X
+
+* g_simple_action_set_state_hint: New function to set the state hint
+  of GSimpleActions
+
+* g_win32_check_windows_version: New function to check Windows version
+
+* g_settings_schema_list_children and g_settings_schema_key_get_name
+  are new functions to complete the GSettingsSchema API.
+
+* Bugs fixed:
+ 389585 G_DEFINE_TYPE hack for header files
+ 729351 Add GListModel
+ 736914 Docs: various fixes and improvements
+ 741807 Add thread name support on OS X and iOS
+ 741895 gwin32: Add Simple API to check whether we are on at least a v...
+ 742456 object: Add g_steal_pointer() convenience function to mark own...
+ 743508 polkitd fails to start: patch for gio/gcredentialsprivate.h
+ 743517 GSettings API is missing some introspection functions
+ 743521 GSimpleAction: add g_simple_action_set_state_hint
+ 743596 G_DECLARE_DERIVABLE_TYPE() should allow additional typedef for...
+ 743640 add __attribute__((cleanup)) support
+ 743827 Fix build of GListModel (on Visual Studio)
+ 743927 GListStore: add sorted insert function
+ 743936 glib: handle unsigned modifier for long long in internal printf
+ 744012 Add GMutexLocker
+ 744190 Fix build on Compilers That Do Not Use inline for Plain C Code
+
+
+Overview of changes in GLib 2.43.3
+==================================
+
+* add g_set_object() convenience function
+
+* GNetworkMonitor: check if NM is not running and don't crash
+
+* fix some races with g_mkdir_with_parents
+
+* fix some warnings in MSVC
+
+* avoid use of G_STRLOC in G_OBJECT_WARN_INVALID_PSPEC in order to save
+  on static strings
+
+* fix some content type vs. mime issues
+
+* documentation improvements
+
+* Bugs fixed:
+ 719455  g_file_make_directory_with_parents() can erroneously throw G_IO_ERROR_EXISTS
+ 732439  GSocket: avoid unnecessary g_socket_wait_condition() for blocking sockets
+ 734946  Implement GContentType on OSX
+ 741589  gobject: Add g_set_object() convenience function to set GObject pointers
+ 741653  gnetworkmonitornm: Check if network-manager is running
+ 741654  [patch] gobject: don't use G_STRLOC in G_OBJECT_WARN_INVALID_PSPEC() macro
+ 741707  Gsocket blocks trying to send data
+ 741788  Document GSettings build system integration
+ 742548  configure.ac: stay out of autoconf's namespace
+ 742851  avoid MSVC warnings in G_STMT_END
+ 742972  ggettext: Include an example of setlocale() and friends in the i18n docs
+ 743014  gtestutils: Add an example of using test fixtures 
+
+* Translations updated:
+ Basque
+ Brazilian Portuguese
+ Spanish
+
+Overview of changes in GLib 2.43.2
+==================================
+
+* New function: g_strv_contains
+
+* New function: g_network_address_new_loopback
+
+* New function: g_socket_send_messages
+
+* A new GNetworkMonitor implementation using NetworkManager provides
+  more detailed connectivity information
+
+* Bugs fixed:
+  11059 Linux poll issue
+ 664562 captive wifi portal support for GNetworkMonitor
+ 685880 Add g_strv_contains()
+ 712570 Hang in g_threaded_socket_service_func
+ 719646 GSocket: add g_socket_send_messages() to send multiple messages...
+ 728928 Provide separate error code for "Connection reset by peer"
+ 732317 Support GSocketConnectable for loopback addresses
+ 740814 "make check" should ensure that every symbol is documented
+ 740848 Backend subscription fails when connecting to a signal with a d...
+ 741016 gio: add G_IO_ERROR_NOT_CONNECTED
+ 741226 keyfile: Add "in group" to GError message consistently
+
+* Translation updates:
+ Gujarati
+ Hebrew
+ Hungarian
+ Kannada
+ Turkish
+ Vietnamese
+
+
+Overview of changes in GLib 2.43.1
+==================================
+
+* GQueue now accepts NULL as a sibling in g_queue_insert_before() and
+  g_queue_insert_after()
+
+* Bugs fixed:
+  11059 Linux poll issue
+ 726037 Add G_PARAM_READWRITE value to the GParamFlags enumeration
+ 727988 GMemoryOutputStream hangs when writing more than 1GiB
+ 729739 tlscertificate: add support for loading certificate chains
+ 733791 GSettings: delay backend subscription
+ 736286 Clarify g_file_replace behavior with etags
+ 736620 GQueue: accept NULL sibling for insert_before() and insert_after()
+ 737150 GLib-GIO-WARNING **: Failed to parse translated string 'visible-name...
+ 737160 unhelpful error message
+ 738259 GDBusInterfaceVTable: clarify memory handling for the method() virt...
+ 738551 'interface' variable conflicts with Windows defines
+ 738633 Need to disable SSLv3 in glib-networking
+ 740157 <app> --help doesn't work even when options were added
+ 740309 Fix docs in g_strfreev
+ 740413 Fix the GSettings Registry Backend 
+
+* Translation updates:
+ Norwegian bokmål
+
+
+Overview of changes in GLib 2.43.0
+==================================
+
+* GObject gained a debug option to provide instance counts. To use it,
+  set GOBJECT_DEBUG=instance-count and call g_type_get_instance_count().
+
+* GOption now has a strict POSIX mode in which it stops parsing arguments
+  as soon as a non-option argument is encountered.
+
+* Bugs fixed:
+ 354457 Feature Proposal: Per-Type Statistics for Instantiable GTypes
+ 695082 g_hash_table_remove_all is not save against a call to g_hash_table_remove
+ 723160 GOption: add strict posix mode
+ 728256 gcredentials: add NetBSD support
+ 729739 tlscertificate: add support for loading certificate chains
+ 733338 Don't segfault in GNetworkMonitor when IPv6 support is unavailable
+ 736273 gdesktopappinfo: Use symbolic names in the code
+ 736284 Keep only one list of signal emissions
+ 736806 gtask: Fix reference count loop causing leaks
+ 736914 Docs: various fixes and improvements
+ 737143 Include <stdint.h> in glib/valgrind.h
+ 737259 gcancellable: Clarify that GSources hold references to GCancellables
+ 737338 gmain: Unref child sources when finalising a GSource
+ 737446 tests: Fix some minor leaks in the unit tests
+ 737451 Provide api to read_all_async
+ 737741 g_datalist_id_get_data assertion fails for non-existant keys
+ 737869 GApplication command line handling breaks --help
+ 738170 g_byte_array_new_take() doesn't initialize array->alloc
+ 738197 g_cond_timed_wait() doesn't time out on Mac OS X
+ 738374 gfile: g_file_equal (x, x) is TRUE
+ 738675 GSubprocessLauncher is missing some data on the docs 
+
+* Translation updates:
+ Bengali (India)
+ Bulgarian
+ Gujarati
+ Italian
+ Telugu
+
+
+Overview of changes in GLib 2.42.0
+===================================
+
+All changes in this release are trivial in nature.
+
+ - introspection warning fixes
+
+ - g_application_add_main_option now uses an enum instead of an 'int'
+   for the type of a parameter
+
+ - added a G_OPTION_FLAG_NONE so that people don't need to use 0
+
+ - gresource: Use GError in more places
+
+ - gresource commandline tool: improve extraction from multiple sections
+
+ - GSource now takes the context lock (if any) in g_source_set_name()
+
+ - new documentation to clarify the use of some APIs related to
+   GVariant, GSource, GApplication
+
+ - other minor updates to docs
+
+* Bugs fixed
+ 736683 Thread safety issues with g_main_context_find_source_by_id
+ 736975 [patch] please document that GVariant serialization needs an
+        out-of-band length field
+
+* Translation updates
+ Danish
+ Hindi
+ Marathi
+ Punjabi
+ Serbian
+ Simplified Chinese
+
+Overview of changes in GLib 2.41.5
+==================================
+
+* Bug fixes:
+ 735819 single native credential struct used for two purposes
+ 735915 glib-building.html uses --enable-gcov instead of --enable-coverage
+ 736350 GDesktopAppInfo: avoid polling on missing desktop dirs
+ 736351 Don't use issetugid() on Android
+        Fix the default application logic in GDesktopAppInfo
+ 736458 Only use rand_s() when targetting Visual Studio >= 2005
+
+* Translation updates
+ Galician
+ Hungarian
+ Indonesian
+ Kannada
+ Latvian
+ Polish
+ Russian
+ Slovenian
+ Tamil
+
+
+Overview of changes in GLib 2.41.4
+==================================
+
+* GApplication now has binding-friendly API to handle
+  commandline options: g_application_add_main_option
+
+* G_GNUC_BEGIN_IGNORE_DEPRECATIONS works with clang
+
+* Bugs fixed:
+ 583330 poll list of mounted file systems (no mtab support)
+ 727455 Command line option parsing from bindings
+ 734126 add G_GNUC_BEGIN_IGNORE_DEPRECATIONS macro for clang
+ 735179 gsocketclient: Handle cancellation between CONNECTING...
+ 735297 Docs claim that GThread struct is deprecated 
+
+* Translation updates:
+  Assamese
+  Catalan
+  Catalan (Valencian)
+  Czech
+  French
+  German
+  Greek
+  Hebrew
+  Korean
+  Oriya
+  Traditional Chinese
+
+
+Overview of changes in GLib 2.41.3
+==================================
+
+* g_clear_pointer and g_clear_object no longer use atomics
+
+* Bugs fixed:
+ 711547 win32: silence some build warnings
+ 725511 Compiled resource files should have the same /-separators everywhere
+ 725513 Some tests fail to build on W32
+ 725514 W32: gfileutils does not preserve errno correctly
+ 725515 test-printf fails on W32
+ 728730 gsocket: Set SO_NOSIGPIPE on sockets on Darwin
+ 729703 Leaks a GError in g_file_move
+ 730932 statically assert that reasonable assumptions about enums are true
+ 732085 gtype: Fast-path for g_type_is_a
+ 732754 GDBusMessage: optimise (de)serialisation of fixed arrays
+ 733345 ginetaddress: Add a precondition to g_inet_address_new_from_string()
+ 733576 Patches from static analysis run on 2.40
+ 733715 glib's configure.ac makes accidentally use of nested function
+ 733934 win32: improve the package installation dir lookup
+ 733960 W32: spawning a console process creates a new window when stdout...
+ 733969 Remove atomic aspects of g_clear_pointer/object
+ 733982 Do not crash when checking whether an instance type is of a given...
+ 734035 gedit hangs up when there's no GSettings key in the registry 
+
+* Translation updates:
+ Basque
+ Brazilian Portuguese
+ Lithuanian
+ Slovenian
+ Spanish
+
+
+Overview of changes in GLib 2.41.2
+==================================
+
+* The Unicode support has been updated to version 7.0
+  of the Unicode standard
+
+* GNotification now supports priorities for notifications
+
+* GCredentials has gained NetBSD support
+
+* GMutex now uses a faster, native implementation on Linux
+
+* Bugs fixed:
+ 699132 Pluggable event loop backends
+ 720708 g_assert_warning(): number of arguments doesn't match for...
+ 722092 Add GtkApplication resources support
+ 724986 Change gio/data-to-c.pl to /usr/bin/env perl.
+ 727974 Fix up failure-to-see-expected-message logging
+ 728256 gcredentials: add NetBSD support
+ 728401 GDateTime: Add guards to g_date_time_new()
+ 729825 Formatting of g_alloca documentation
+ 729914 instead of DEBUG_CODE and IF_DEBUG, provide a common macro...
+ 730293 clang++-3.4: error: 'register' storage class specifier is ...
+ 731339 giochannel: avoid setting uninitialised length
+ 731424 #ifdef spaghetti for load_user_special_dirs() implementations
+ 731623 GNotification: add support for a priority setting
+ 731929 update tables to unicode 7.0.0
+ 731950 gvalue: New g_value_from_instance
+ 731986 GLib: implement GMutex natively on Linux
+ 732184 GObject: warn on use of deprecated properties
+ 732357 Docs: various fixes and improvements
+ 732429 GActionEntry: improve documentation
+ 732465 Fix build on x64 Visual C++ builds
+ 732704 Docs: various fixes and improvements
+ 732739 ginetsocketaddress: Explicitly initialise flags for getaddr...
+ 732754 GDBusMessage: optimise (de)serialisation of fixed arrays
+ 732984 g_object_ref(NULL) in g_dbus_object_manager_client_finalize
+ 733084 Typos in g_bytes_hash() and g_time_zone_find_interval() docs
+ 733146 spawn helper does not use correctly the parameters 
+
+* Translation updates:
+ Lithuanian
+
+
+Overview of changes in GLib 2.41.1
+==================================
+
+* Bug fixes:
+ 697229 Custom Interface implementations will be broken with glib 2.37/38
+ 698614 GObject: prevent installing properties after init
+ 729269 gvariant: Fix confusion between type and format strings in the docs
+ 730198 broken valgrind.h leads to crashes in g_type_free_instance on mingw64
+ 730807 GMutex performance regression
+ 730963 gconvert: mention that the g_convert len should be in bytes
+ 730984 Faster instance type check for fundamentals
+ 731050 <structname> tags appear in documentation
+ 731200 unconditional 'notify' during g_object_set() is problematic
+ 731335 gtype: guard uses of new fundamental type check
+ 731341 gparam: change value of G_PARAM_EXPLICIT_NOTIFY
+ 731366 run-assert-msg-test.sh gdb leaves assert-msg-test zombie
+ 731425 giomodule protects function-call with different token than function...
+ 731513 clang: build failure: implicit declaration of function '__atomic_load_4'
+ 731584 gbookmarkfile: Cleaner error handling code to pacify static analysis
+ 731657 Prevent an invalid @CARBON_LIBS@ from appearing in the .pc files
+ 731979 docs: Correct param to interface's default_init()
+ 731996 Return folder as icon for directories
+ 732002 gwakeup: Clarify buffer sizing in g_wakeup_signal()
+ 732005 Remove unused assignments
+ 732019 gtestdbus: Don’t close stdout for dbus-daemon
+ 732068 gsignal: Add an example to the g_signal_connect_swapped() documentation
+ 732081 gsocket: Document that g_socket_create_source() holds a socket ref
+ 732107 gsocketlistener: Reconsider closing sockets on listener finalisation
+
+
+Overview of changes in GLib 2.41.0
+===================================
+
+* Many bugfixes found by static analysis, including potential fd leaks
+  and NULL pointer dereferences.
+
+* Increased use of (nullable) attribute on out values and return types
+  now that it is supported (mostly from porting Vala metadata).
+
+* use XDG_CURRENT_DESKTOP for OnlyShowIn/NotShowIn handling of desktop
+  files, deprecating g_desktop_app_info_set_desktop_env()
+
+* add support for g_desktop_app_info_get_implementations() to find
+  desktop files that have an Implements= line for a given interface
+
+* GHmac has gained SHA-512 support
+
+* support the new mimeapps specification (most notably, moving the
+  assoications/defaults configuration to ~/.config/mimeapps.list).
+
+* libgobject is now linked -Wl,-z,nodelete when possible to avoid errors
+  when gobject is used from a module for a program that does not itself
+  use gobject and that module is unloaded/reloaded
+
+* ... and many other bug fixes.
+
+ 623552 glib warns if backtrace.py is not present
+ 667468 glib-2.30.2: ipv6 tests fail when no ipv6 support is available
+ 668152 -framework Carbon linker flag not passed to pkg-config .pc files
+ 707298 libgobject should be linked with -Wl,-z,nodelete
+ 712391 Add g_desktop_app_info_get_implementors()
+ 722723 Infinite recursion when calling g_io_stream_close_async() from libsoup
+ 724741 hmac: Fix support for SHA-512 in GHmac
+ 726040 networkaddress: fix parsing of uri with @ after authority
+ 726318 gio: Document that GSocket is not thread safe
+ 726611 socketclient: Leak on cancellation
+ 726872 gio: Add names to idles and timeouts
+ 727119 wrong IN6_IS_ADDR_MC_LINKLOCAL usage break android build
+ 727123 GNotification: Some small documentation fixes
+ 727320 docs: Remove escaping '\' from literals
+ 727551 Check use_count of GApplication in g_application_release()
+ 727559 g_file_copy: Don't set GError when we intend to ignore errors
+ 727692 gio/gtlscertificate.c -- broken PEM-file processing (affects local CA root stores, for starters)
+ 727890 soup_content_sniffer_real_sniff segfault
+ 727900 gio: Add newer dbus UnknownXxxx and PropertyReadOnly errors
+ 727928 gapplication-tool fixes
+ 727939 INTLLIBS are always appended in configure checks
+ 727964 g_io_extension_point_get_extension_by_name: Warn, but don't crash, for NULL inputs
+ 728040 Implement new mimeapps spec
+ 728066 Deal with startup notify id being NULL
+ 728280 platform_get_argv0: fix sysctl(3) use on OpenBSD
+ 728285 docs: Use markdown links in .h files, too
+ 728350 gaction: Minor clarifications in the GAction documentation
+ 728380 docs: Remove <!-- --> comment before plural s
+ 728565 gfile: More explicitly document the context for GFileProgressCallback
+ 728983 Docs: various fixes and improvements
+ 729167 gobject: Document that classes/objects/interfaces are zero-filled
+ 729563 GOption: A short option's value is included in G_OPTION_REMAINING
+ 729813 AppInfo: use XDG_CURRENT_DESKTOP for OnlyShowIn
+ 729875 gio: cleanup gdbusmessage.c file
+ 730045 Avoid overeager warning about deprecated properties
+ 730189 gtestutils: Fix a very unlikely FD leak in test fork handling
+ 730190 gsocket: Add missing preconditions to g_socket_send_message()
+ 730277 gthread: Fix use of a local variable after it went out of scope
+ 730278 gsubprocess: Add a missing va_end() call
+ 730295 gdbus-tool: Remove dead variables
+ 730493 Port annotations from Vala metadata
+
+Translations updated:
+ Basque
+ Brazilian Portuguese
+ Catalan
+ Czech
+ Danish
+ Greek
+ Hebrew
+ Hungarian
+ Punjabi
+ Serbian
+ Slovenian
+ Spanish
+ Ukrainian
+
+Overview of changes from GLib 2.39.91 to GLib 2.39.92
+=====================================================
+
+This is a release candidate for 2.40.0.
+
+There are no major changes in this release, but a few serious bugs have
+been fixed.
+
+* Bugs fixed:
+ 710367 Crash in g_settings_backend_dispatch_signal()
+ 723899 G_DEFINE_TYPE() causes compiler warnings with clang due to foo_get_instance_private
+ 724859 Let the test_wait_until() test also run on non-*nix
+ 724916 gio unmount code makes XFCE's Thunar crash
+ 725651 GSubprocessLauncher: Does not copy the calling process environment.
+ 725656 Unskip GVariantDict
+ 725891 gio tests: add codegen to BUILT_SOURCES
+ 726046 Recent commit created symbolic icons issues
+
+* Translations:
+ Chinese
+ French
+ Korean
+ Latvian
+ Norwegian bokmål
+ Portuguese
+ Russian
+ Traditional Chinese
+
+Overview of changes from GLib 2.39.90 to GLib 2.39.91
+=====================================================
+
+This release introduces a hard dependency on present and functioning
+clock_gettime() and CLOCK_MONOTONIC.  It also introduces a dependency on
+pthread_condattr_setclock() unless your system happens to have
+pthread_cond_timedwait_relative_np() (as do Mac OS and Android).  This
+release is known to be broken with at least GNU/Hurd, pending addition
+of working pthread_condattr_setclock(CLOCK_MONOTONIC) there.
+
+New API: g_str_to_ascii()
+
+* Fixed bugs:
+ 670144 unconditional use of CLOCK_MONOTONIC is broken
+ 673607 invalid assumption in g_cond_wait_until() / g_get_monotonic_time() API
+ 710142 Add more impressive transliteration to GLib
+ 722360 make check fails
+ 722604 (partial) Various tests are failing with 2.39.3
+ 723316 g_hash_table_iter_remove() should be explicit whether or not it is safe while iterating the table
+ 724609 Fix build of GIO on Windows
+ 724687 gmain: make monotonic time really monotonic, everywhere
+ 724706 gsource: document priority of child sources
+ 724707 some GSocket source improvements
+ 724839 GMainContext: some source ID cleanups
+ 724858 Dist gtranslit-data.h
+ 724994 Missing icons for bookmarks in file chooser
+ 725023 Can no longer find apps by executable/desktop file name
+
+* Translations:
+ Lithuanian
+ Polish
+ Thai
+
+Overview of changes from GLib 2.39.4 to GLib 2.39.90
+====================================================
+
+* Fixed bugs:
+ 625408 make GVariant dictionaries more useful
+ 660809 document that if you fail a precondition check, documented guarantees do not apply
+ 661576 fix handling of constructors that destroy half-constructed objects
+ 679957 g_inet_address_new_from_string is not able to handle dots and numbers IPv4 addresses
+ 712837 gvariant: Document the need to cast varargs when constructing GVariants
+ 721458 g_simple_async_result_is_valid has a NULL check for the wrong source_tag
+ 721977 improve split handling of command line arguments
+ 722033 win32: fixup lib.exe invocation
+ 723422 Fix g_socket_get_available() with TCP on Windows
+ 723616 gio/tests: fix race when generating code
+ 724001 gsubprocess: Fix a broken link in the documentation
+ 724124 glib/tests/collate.c fails if no en_US locale
+ 724126 intermittent GApplication test failure: /gapplication/local-actions: lines of output permuted
+ 724233 gsocketservice: Note g_socket_listener_close() for closing open sockets
+ 724239 soup_session_queue_message - Connection terminated unexpectedly
+ 724278 gsocketconnection: Document closing connections with g_io_stream_close()
+ 724330 configure.ac: tweak inotify check
+ 724385 gtestutils: make the new assert messages more detailed
+ 724401 gsubprocess: Mutex leak
+ 724417 glib master build broken on OpenBSD
+ 724434 Build failure in gio/gresolver.c
+
+* Updated translations:
+ Brazilian Portuguese
+ Galician
+ Indonesian
+ Italian
+ Kannada
+ Norwegian bokmål
+ Spanish
+ Thai
+
+Overview of changes from GLib 2.39.3 to GLib 2.39.4
+===================================================
+
+* Fixed Bugs:
+ 139699 Correction for g_main_context_unref()
+ 583036 g_strchomp and g_strchug are not declared const
+ 683388 improve documentation for application developers
+ 685204 ./configure fails to add the '-g' flag to CFLAGS
+ 688406 GStaticMutex broke ABI on at least ARM EABI during 2.31.x
+ 693299 cannot compile on Solaris: error in gbitlock.c
+ 707111 Clarify type transformability and compatibility
+ 711547 win32: silence some build warnings
+ 719344 Fix the various test programs (or GLib itself) on Windows
+ 722025 cleanup/clarify command line argument encoding on Windows
+ 722323 remove unused include 'gslist.h' in 'gbookmarkfile.c'
+ 722326 gstringchunk: Use g_slist_free_full() where possible
+ 722357 gio: fix small memory leak on local xattr
+ 722436 Adjust doc to Makefile.decl renaming
+ 722503 GSimpleAction: add default activate handler
+ 722526 glib/deprecated/gthread.h error on FreeBSD
+ 722591 [documentation] broken link to GtkAction from GAction.html
+ 722973 Broken example in GApplication reference
+ 723048 'network-access' test can fail to guess interface index
+ 723360 gmain: Note that g_source_destroy() can be called multiple times 
+
+* Updated Translations:
+ Assamese
+ Tamil
+ Traditional Chinese
+
+
+Overview of changes from GLib 2.39.2 to GLib 2.39.3
+===================================================
+
+No major changes this release -- mostly lots of small fixes and
+improvements in test coverage.
+
+ * fix a crasher in code from gdbus-codegen
+
+ * improvements to gobject gdb helper script
+
+ * portability:
+
+   - fix a deadlock issue with kqueue on FreeBSD
+
+   - work around a quirk in the sunstudio compiler
+
+   - rename a variable to avoid clashing with a macro definition of
+     'environ' on some platforms (like mingw)
+
+   - use POSIX-specified <poll.h> over <sys/poll.h>
+
+   - many improvements to Visual Studio projects and and some build
+     fixes for Windows
+
+ * tests
+   - a very large number of improvements in test coverage
+
+   - don't report skipped tests as failures
+
+   - return 77 if we skip all tests in an executable
+
+   - improve gtest documentation and fix some minor issues
+
+   - fix g_test_trap_reached_timeout() return value
+
+   - remove some dead code uncovered during test coverage expansion
+
+   - Use tap mode for installed tests too, when using tap
+
+ * fix races in unix signal handling
+
+ * make our GVariant-based commandline tools (glib-compile-schemas,
+   gdbus, gapplication) print out GVariant parse errors in context
+
+ * GApplication now has a --gapplication-service command line switch to
+   turn any GApplication into a service
+
+ * improve compatibility of GApplication and GOptionContext
+
+ * fix gsettings.m4 wrt. builddir != srcdir with non-recursive make
+
+ * use a directory monitor in GKeyfileSettingsBackend
+
+ * improve robustness of some GIcon classes
+
+Bugs fixed
+ 141251  poll(2) is in <poll.h>, not <sys/poll.h> per SUS standard
+ 613732  [PATCH] gobject.py: Don't install frame filters when GDB does not support them
+ 708212  g_variant_parser_error_get_quark() has unexpected name.
+ 710965  GApplication: add --gapplication-service switch
+ 711090  periodic failure of spawn-multithreaded async testcase
+ 712171  gsettings.m4: @GSETTINGS_RULES@: Support srcdir != builddir with nonrecursive make
+ 712630  Revert "gsettings m4: check for .xml in src/builddir"
+ 715028  GVariant: add way to print context of parse errors
+ 719344  Fix the various test programs (or GLib itself) on Windows
+ 720263  gtestutils: skipping a test should count as success, not failure
+ 720539  gdbus-codegen: Fix crasher in goa-using apps
+ 720635  Make gdb pretty-printers compatible with Python3
+ 720891  g_settings_get_child does not inherit the backend
+ 721034  glib 2.38.2 cannot be compiled with SunStudio Compiler under Solaris
+ 721059  g_subprocess_launcher_set_environ vs "environ"
+ 721074  kqueue: deadlock
+ 721087  Missing -lselinux in pkg-config --libs --static gio-2.0
+ 721324  Error message is printed to stdout
+ 721624  Regression in GTest framework reorders existing test cases
+ 721625  backwards NEWS entry about g_source_remove change
+ 721796  insufficient escaping in g_dbus_annotation_info_generate_xml()
+ 721947  Improve GApplication ⇔ GOptionContext compatibility 
+
+Translations updated:
+ Brazilian Portuguese
+ Galician
+ Greek
+ Hebrew
+
+Overview of changes from GLib 2.39.1 to GLib 2.39.2
+===================================================
+
+* Portability
+
+  - Remove alleged support for OS/2
+
+  - Remove alleged support for BeOS
+
+  - Remove alleged support for last-millennium Unixes
+
+  - Require C90 compliance
+
+  - Require POSIX.1 (1990) compliance on Unix
+
+  - Require GNU make
+
+* Bugs fixed:
+ 113075 support "nonnull" attribute
+ 159528 g_ptr_array_remove_range()
+ 307947 The check for growing stack pointer in configure can fail
+ 607016 docs should mention property notification order
+ 671557 Fun with integers and g_key_file_load_from_data()
+ 676761 don't use g_critical for a runtime error
+ 690525 g_file_replace_contents_async doesn't copy its @conten...
+ 691608 Support compilation with clang 3.2
+ 697585 g_variant_builder_add's doc example is leaking
+ 697828 g_hash_table_add() should return a boolean
+ 702862 gdbus-codegen : look for deps in default install path
+ 703522 Reference leak in GvariantBuilder documentation
+ 705902 g_get_current_dir() should check PWD env var and retur...
+ 708274 Added GObject Introspection annotations to genums.c
+ 710519 Portability schmortability
+ 710741 some mainloop instrumentation
+ 710983 Test failures on powerpc
+ 711047 Enable the build of the various test programs on Windo...
+ 711051 Add basic test for the GNotification gtk backend
+ 711088 gbacktrace: Don't close stderr when running gdb
+ 711103 gmessages: Add g_info macro for G_LOG_LEVEL_INFO
+ 711178 appinfo test problems
+ 711546 utf8: report allocation error
+ 711640 gdesktopappinfo: Rank Keywords matches higher than Gen...
+ 711751 Fix memory leaks in libglib tests
+ 711753 gthread-posix: Don't use gslice allocated GRecMutex
+ 711796 glib-tap.mk: fix to actually use the TAP driver
+ 711800 fix g_test_set_nonfatal_assertions()
+ 711801 giomodule: Allow overriding source directory gio modul...
+ 711805 gdbus-connection: Fix race condition in test
+ 711806 gtestdbus: Don't destroy GSource twice
+ 711807 gtestdbus: Properly close server connections
+ 711871 Broken and misleading configure check for growing stack
+ 712136 'O_CLOEXEC' undeclared (first use in this function)
+ 712148 Add system bus support to GTestDBus
+ 712171 gsettings.m4: @GSETTINGS_RULES@: Support srcdir != bui...
+ 712314 AIX port: splice(); major()/minor(); libtool library order
+ 712315 GSettings: More docs for deprecated _list_schemas()
+ 712393 gobject: Box GMappedFile
+ 712547 GSocketClient "event" not useful for determining resol...
+ 715164 Clang static analysis fixes
+ 719395 GPtrArray add g_ptr_array_insert
+ 719402 Crashes when startup
+ 719472 leak in generated proxy-side property-setter
+ 719687 fix or remove g_trap_object_ref
+ 719809 Signal connection ids are always > 0 if successful
+ 719837 gdbus-connection: Work around race in connection tests
+ 719884 Fix documentation typos in GTask and GCancellable examples
+ 719979 g_settings_get: check validity of format string
+ 720080 Truncating a GMemoryOutputStream to a larger size cause...
+ 720210 gdataset: Remove unused define
+ 720236 Allow clean simple use of g_test_trap_subprocess() 
+
+* Translations updates:
+ Italian
+ Lithuanian
+ Simplified Chinese
+ Spanish
+
+
+Overview of changes from GLib 2.39.0 to GLib 2.39.1
+====================================================
+
+ * GSettings fixes/improvements
+
+   - GSettingsSchema API is now more powerful and consistent
+
+   - new GSettingsSchemaKey API allows accessing metadata for keys:
+     type, default value, range and the long-awaited support for summary
+     and description
+
+   - GSettingsSchemaSource gains support for listing schemas within a
+     source.  Deprecate the global API that did this for the default
+     source.
+
+   - 'gsettings list-schemas' now works properly with --schemadir
+
+   - deprecate a bunch of now-redundant functionality on GSettings
+
+   - add API to GSettings for getting the default value of a key (as set
+     by the sysadmin)
+
+   - add API to GSettings for determining if the user has assigned a
+     particular value to a key (ie: we are not just reading the default)
+
+   - ignore qualified tags and attributes appearing in schema files
+
+ * Applications/Actions
+
+   - make GSimpleAction a bit more strict with respect to state changes
+     that would violate the interface (ie: by changing the state type
+     after construction)
+
+   - throw an error when attempting to 'Describe' a non-existent action
+     via D-Bus instead of returning a bogus description
+
+   - throw an error when attempting to invoke unsupported methods on an
+     Application (eg: 'Open' on an app that doesn't HANDLES_OPEN)
+     instead of emitting a g_critical() in context of the app (which is
+     not itself at fault for the errant call)
+
+ * Appinfo
+
+   - substantially rework GDesktopAppInfo to reduce the amount of disk
+     accesses that are performed in common situations
+
+   - add a new class: GAppInfoMonitor for discovering when applications
+     are installed/removed
+
+   - add a new g_desktop_app_info_search() API for searching for
+     installed applications by name, keywords, etc.
+
+ * GMarkup: add new G_MARKUP_IGNORE_QUALIFIED flag for skipping over
+   "qualified" tags and attributes (those with a colon in the name, such
+   as 'my:tag')
+
+ * GDBus
+
+   - ignore qualified tags, as above
+
+   - GTestDBus: unset all D-Bus addresses (such as STARTER) to ensure
+     that test programs don't pick them up
+
+   - add new session_bus_run() convenience in the tests and use it
+
+ * GRand: use real random data as a seed on win32 and use the
+   timestamp/pid/uid fallback only on UNIX machines where we can't open
+   '/dev/urandom'.  This may cause issues with older mingw32 releases
+   due to a missing prototype for the rand_s() API.
+
+ * Many win32 (and particularly MSVC) portability fixes.  Many
+   additional tests are now runnable when building with MSVC.
+
+ * Due to early testing of the (soon to land) GCleanup framework, a very
+   large number of memory errors have been found and fixed (mostly in
+   the testcases, but some in glib itself).
+
+ * GIO:
+
+   - some more seeking cleanups: particularly on GLocalFileInputStream
+
+   - don't leave a .trashinfo file around if trashing a file fails
+
+   - Add a request_certificate virtual method to GTlsInteraction
+
+Translations updated:
+ Assamese
+ Galician
+ Greek
+ Spanish
+ Tamil
+
+Bugs fixed:
+ 635641 schema compiler should ignore unknown attributes
+ 637257 g_tls_client_connection_gnutls_retrieve_function needs to be able to block
+ 637956 GKeyfileSettingsBackend should ignore file deletions
+ 645453 keys from base schema missing from extended schema
+ 665634 g_dbus_node_info_new_for_xml() errors on unknown attributes in XML files
+ 668232 Unable to get description and summary for a key
+ 668233 Unable to determine if a key is set to the default / what the default value is
+ 680838 Need g_settings_schema_source_get_schemas()
+ 683017 API for accessing GSettings Schema metadata
+ 687185 org.gtk.Actions.Describe doesn't return an error for non-existing action names
+ 687202 If trashing fails, the ".trashinfo" file is not removed
+ 695558 The --schemadir option has no effect
+ 696424 GSimpleAction.state property is not right
+ 697348 GTestDBus should unset DBUS_STARTER_ADDRESS, DBUS_STARTER_BUS_TYPE
+ 710133 Emit backward compatible code with gdbus-codegen
+ 710691 glib-networking: locking during implicit handshake
+ 710738 GRand has lame fallback for Windows
+ 710859 Typo in gio docs
+ 710885 Two fixes for GApplication
+ 710962 error: 'F_DUPFD_CLOEXEC' undeclared (first use in this function)
+ 710964 Add g_hash_table_get_key_array()
+ 710991 test: g_debug messages shouldn't affect g_assert_expected_messages
+ 711016 g_settings_list_keys () segfaults for empty schemas
+ 711048 glocalfileinputstream.c allows skip past end of file
+ 711049 Fix build of GLib-GIO 2.39.x on Windows/MSVC
+ 711064 Adding child source to blocked source can cause a segfault
+ 711070 Copying a symlink over another one segfaults
+ 711099 gapplication test failure
+ 711520 GDesktopAppInfo: allow more than one level of legacy folder prefixes
+ 711556 Add GAppInfoMonitor
+ 711557 Add g_desktop_app_info_search()
+ 711600 trivial portability fix
+ 711632 The desktop-app-info test fails during make check
+ 711754 gmain: Fix use of uninitialized memory in sigaction structure
+ 711755 private: Use threading primitives correctly in private test
+ 711756 gthreadpool: Don't pass bad data to GThreadPool sorter
+ 711768 Fix memory leaks in libgmodule tests
+ 711775 utils: Don't free memory owned by glib in test
+ 711782 boxed: Fix double free in boxed unit tests
+ 711803 gsubprocess: Fix a number of leaks and a segfault
+ 711808 gtestdbus: Fix leak of GMainLoop 
+
+Overview of changes from GLib 2.38.0 to GLib 2.39.0
+====================================================
+
+ * prep for the 2.40 series (version macros, docs index, etc.)
+
+ * GNotification
+
+   - new API for sending persistent notifications via the desktop shell
+
+   - notifications persist when the application has quit and clicking on
+     them can restart the application with an action (via
+     DBusActivatable)
+
+ * GSubprocess
+
+   - new API for launching subprocesses
+
+   - nice GIO integration like async functions, cancellability, etc.
+
+   - a convenient communicate() API inspired by the same API in Python
+
+   - related: the gspawn API now has a CLOEXEC flag for the created
+     pipes for stdin/stdout/stderr
+
+ * New gapplication(1) commandline tool
+
+   - intended to be used with DBusActivatable apps
+
+   - can be used for launching apps, opening files, invoking application
+     actions and listing apps and actions
+
+   - bash tab completion is supported
+
+ * GDesktopAppInfo changes:
+
+   - g_file_get_path() can implicitly cause a FUSE mount so don't call
+     it until we know we need it (for an app that doesn't support URIs)
+
+   - don't crash when trying to load from a keyfile with
+     DBusActivatable=true
+
+   - remove some dead code, refactor the search path handling a bit and
+     do a large-scale whitespace cleanup (prep work for the pending
+     desktop file index)
+
+ * File monitors
+
+   - fix broken handling of mount point monitoring
+
+   - remove some strange use of GObject::constructor() from the base
+     class and inotify backend
+
+   - fix GFileMonitor to work in the non-default main context even when
+     the main context is not running (or is blocked)
+
+   - add internal private API for easily creating a file monitor in the
+     GLib worker thread
+
+ * GSettings
+
+   - g_settings_list_children: only list viable schemas.  This fixes a
+     longstanding issue where 'gsettings list-recursively' will crash
+     when there are invalid schemas installed
+
+   - don't accept invalid paths on g_settings_new_with_path, etc.
+
+ * GIO
+
+   - GFile now has a thumbnail::is-valid attribute to check if the
+     thumbnail in thumbnail::path needs to be regenerated
+
+   - GDBusProxy now has a flag to control autostarting of services at
+     construction time
+
+   - for GSeekable, properly introduce the concept of "resizable" vs.
+     "fixed-sized" streams in the docs, explaining the expected
+     semantics of the interface in each case
+
+   - fix some cases in GMemoryOutputStream that were violating the above
+     expectations (which may cause a slight API incompatibility)
+
+   - clean up GCredentials code and add support for Hurd and Solaris
+
+   - improve splicing by using different codepaths for the case where we
+     have real _read_async() and _write_async() implementations on the
+     stream vs. the case where they are internally emulated (via
+     dispatching the sync variant of the call in a thread)
+
+ * GKeyFile
+
+   - fix a leak in g_key_file_get_(u)int64 when we fail to parse the
+     value as an integer
+
+   - add long-requested API g_key_file_save_to_file()
+
+ * Portability improvements
+
+   - avoid using O_DIRECTORY on platforms that don't have it
+
+   - be careful about systems that define SOCK_CLOEXEC but don't
+     actually support it (like Hurd)
+
+   - only use SA_RESTART if it exists
+
+ * Other small API changes/additions
+
+   - a pair of functions to support matching strings for the type of
+     search functionality that you'd expect to have with things like
+     GtkSearchBar.  This will also be used by the desktop file index.
+
+   - g_str_is_ascii() with obvious purpose
+
+   - g_test_expect_message() no longer appears to allow you to catch
+     G_LOG_ERROR messages
+
+ * GMainContext/GSource
+
+   - fix handling of overflowing the 'next source id' counter
+
+   - g_source_remove() will now throw a critical in the case that you
+     try to remove a non-existent source.  We expect that there is some
+     code in the wild that will fall afoul of this new critical but
+     considering that we now reuse source IDs, this code is already
+     broken and should probably be fixed.
+
+   - simplify handling of the 'current dispatching source' to not
+     require use of a linked list
+
+ * GObject
+
+   - the long-broken (and leaky) pattern of destroying a just-allocated
+     object from inside of a custom GObject::constructor is now
+     officially completely illegal and will abort the program
+
+ * Unicode: update to 6.3.0
+
+ * Bug fixes
+
+   - g_file_copy() now falls back to pathname queryinfo.  This should
+     clear up the bugs with copying from some GVfs backends (afp,
+     gphoto, archive, at least).
+
+   - fix an out-of-bounds read in the xdgmime code
+
+   - fix a typo in the /org/freedesktop/DBus path on the object manager
+     client
+
+   - skip emitting path_namespace='/' in match rules in order to
+     workaround a bug in the D-Bus daemon and fix our own implementation
+     (which shared exactly the same bug)
+
+   - fix crashes on precondition violations for GParamSpec constructors
+
+   - many other small fixups (see bug list)
+
+  * Many documentation improvements
+
+Bugs fixed:
+ 309224 g_key_file_save_to_file missing
+ 583321 QNX: no SA_RESTART
+ 661576 fix handling of constructors that destroy half-constructed objects
+ 672102 GSubprocess class
+ 684842 Seeks on GMemoryOutputStream don't have opaque semantics
+ 688492 Add a notification API
+ 691581 g_output_stream_real_splice_async doesn't use overriden read/write_async functions
+ 702516 gfileutils: Make -Werror=format-nonliteral happy
+ 704218 New gapplication(1) tool
+ 704593 g_setenv: on some systems (BSD, OSX…), setting a variable to NULL crashes the system
+ 704882 GLocalDirectoryMonitorClass mount_notify field is useless
+ 704887 file monitoring improvements
+ 705029 Support for Solaris credentials
+ 705688 g_settings_list_children: only list viable schemas
+ 706254 Afp backend cannot copy files
+ 707887 Attempting to create GObject Property with underscore prefix segfaults
+ 708042 gapplication: don't rely on cmdline being finalized immediately
+ 708265 add support for GNU/Hurd in GLib D-Bus Library
+ 708266 fix error code checks when SOCK_CLOEXEC is defined but not supported
+ 708529 xdgmime: valgrind warns about invalid reads
+ 708677 incorrect object path 'deskop' used in gio/gdbusobjectmanagerclient.c
+ 708714 Typo in docs of GLIB_VERSION_2_40 macro.
+ 708753 gdesktopappinfo: Call g_file_get_path() on demand
+ 708793 glib build fails with clang < 3.1: error: expected ';' after top level declarator
+ 708828 GDBusProxy: add the ability to call methods on non autostarted proxies
+ 708860 glib-2.38.0 doesn't build on Solaris 10
+ 708972 gnetworking.h in tarball screws up out-of-source builds
+ 709113 [PATCH] Main loop dispatch path has needless linked list
+ 709227 Update to unicode 6.3.0
+ 709301 goutputstream: Add clear warning about short writes to _write_bytes() and async version
+ 709326 GDesktopAppInfo crashes creating a DBusActivatable app without a filename
+ 709440 Fix overloading of "source" and "target" terminology in GBinding
+ 709615 Cannot use g_test_expect_message with g_error
+ 709753 Add helpers for string matches when using GtkSearchBar-like widget
+ 709898 Expose thumbnail validity in GFile attributes
+ 709966 Remove outdated documentation
+ 709994 Minor fix for HACKERS doc to direct hackers to proper help file
+ 709995 Obsolete makefile rules
+ 710002 G_MAXUINT may be assigned as duplicate source id
+ 710313 Memory leak in g_key_file_get_(u)int64 with invalid integer values
+ 710345 [Patches] Fix some redundant-decls
+ 710496 g_locale_to/from_utf8() doc updated.
+ 710625 g_file_error_from_errno: Remove unneeded breaks
+ 710666 Frame clock related bug fixes
+ 710724 gmain: Warn when g_source_remove() fails
+ 710726 Work around D-Bus bug with path_namespace='/' match rules
+
+Translations:
+ Assamese
+ Brazilian Portuguese
+ Indonesian
+ Russian
+ Tamil
+ Traditional Chinese
+
+What's new in Glib 2.38
+========================
+
+ * Application support
+
+  - GIO now provides an implementation of Desktop Actions from the
+    desktop entry specification
+
+  - GApplication now implements the org.freedesktop.Application
+    interface as per the desktop entry specification, allowing for
+    standards-based D-Bus launching of GLib-based applications
+
+  - GDesktopAppInfo now supports DBusActivatable as per the desktop
+    entry specification, allowing GLib-based applications to use D-Bus
+    to launch other applications
+
+  - GApplication now has a "busy" flag that can be set on an application
+    to allow the shell to show that it is busy
+
+ * GObject
+
+  - the private offset for a given class type is now always constant.
+    This was done by reorganising the memory layout of instances so that
+    the private data comes before the "official" pointer for the object
+    (ie: at a negative offset).  Valgrind macros were added to mitigate
+    any problems that this may have caused.
+
+  - a new G_DEFINE_TYPE_WITH_PRIVATE has been added along with a
+    generated function *_get_instance_private() that can now serve as an
+    equally-performing alternative to ->priv pointers in instances
+    (allowing memory savings)
+
+  - new G_PRIVATE_FIELD, G_PRIVATE_FIELD_P and G_PRIVATE_OFFSET macros
+    provide a convenient method of converting between named variables in
+    private structures and their (now constant) offsets
+
+  - installing properties on a GObjectClass must now be done from
+    class_init.  It is no longer valid to install them after class_init
+    has returned.
+
+  - it is now possible to manually break a GObject property binding
+    without destroying one of the objects involved
+
+ * Icons
+
+  - the requirements for implementing the GIcon interface have changed
+    in order to make it possible to consume all implementations of GIcon
+    with a finite number of cases
+
+  - a new GBytesIcon type was added for an icon represented by an
+    in-memory binary blob in a known image format (ideally png).
+
+  - new APIs g_icon_serialize() and g_icon_deserialize() replace the old
+    to/from_string APIs and will always work, irrespective of which
+    types have been initialised in the calling process, allowing for a
+    serialised GdkPixbuf to be deserialised in a process that doesn't
+    have GdkPixbuf
+
+  - support for icons has been added to GMenuModel using the new APIs
+
+ * Actions and menus
+
+  - GPropertyAction provides a convenient way of creating a stateful
+    property corresponding to a property on a GObject, such as the
+    "visible-child-name" property of a GtkStack
+
+  - new API g_menu_remove_all()
+
+  - we now have established rules about what is a "valid" action name
+    and an API to check them
+
+  - a new API for converting detailed action names to and from the
+    split-out name and parameter value (as GVariant)
+
+  - for backwards compatibility, invalid action names can still be used
+    with most functions, but this is not recommended
+
+ * Other GIO
+
+  - GDBus now supports services that wish to handle some of all
+    properties on an interface asynchronously, without requiring the
+    service to reimplement the entire org.freedesktop.DBus.Properties
+    interface
+
+  - GFile now has a new _measure_disk_usage() (and async) API for
+    recursively determining the amount of disk space used by a
+    particular directory (akin to 'du').
+
+  - asynchronous version of g_file_trash() and g_file_make_directory()
+    have been added
+
+ * Other new API
+
+  - GRegex has a new function to query the maximum lookbehind length to
+    allow for regexp matching on streams
+
+  - GVariant has two new APIs for constructing strings that allow
+    avoiding copies in some cases: g_variant_new_take_string() and
+    g_variant_new_printf()
+
+ * Testing
+
+  - we can now generate TAP output
+
+  - new support functions for simplifying the process of dealing with
+    data files for srcdir != builddir and installed test cases
+
+  - g_test_trap_subprocess() provides a portable alternative to
+    g_test_trap_fork()
+
+ * Other
+
+  - GLib now builds on Android against the bionic C library
+
+Overview of changes from GLib 2.37.93 to 2.38.0
+================================================
+
+* fix the documentation for GSourceFuncs
+
+* fix compilation on OS X/ppc64
+
+Bugs fixed: 708445, 647145
+
+Translations updated:
+ Danish
+ French
+ Portuguese
+ Punjabi
+
+Overview of changes from GLib 2.37.92 to 2.37.93
+================================================
+
+* a couple of bugfixes in the new g_file_measure_disk_usage() API
+
+* updated Traditional Chinese translation
+
+Overview of changes from GLib 2.37.7 to 2.37.92
+===============================================
+
+* new API g_file_measure_disk_usage() similar to du(1)
+
+* minor fixes
+
+* Translation updates:
+ Assamese
+ Belarusian
+ Brazilian Portuguese
+ Catalan
+ Czech
+ Galician
+ German
+ Hungarian
+ Indonesian
+ Italian
+ Korean
+ Korean
+ Latvian
+ Lithuanian
+ Polish
+ Serbian
+ Slovenian
+ Spanish
+
+Overview of changes from GLib 2.37.6 to 2.37.7
+==============================================
+
+* GDateTime now supports %:z formatting variations
+  for timezones. This is a GNU date extension.
+
+* Bugs fixed:
+ 685387 Segfault with GObject.signal_handler_is_connected()...
+ 686786 g_socket_get_available_bytes() returns wrong value ...
+ 705027 GSocket GSource not threadsafe on Windows
+ 706469 Fix G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE documentation
+ 706706 Fix Gir annotations on g_loadable_icon_load_finish
+ 706888 gtype: fix a no-op assertion
+ 706958 configure.ac: fix atomic opts detection
+ 707092 "File Utilities" page for GLib documentation doesn'...
+ 707151 gdatetime: Extend the '%z' timezone format
+
+* Translation updates:
+ Catalan
+ Hungarian
+ Japanese
+ Polish
+ Slovak
+ Tamil
+
+
+Overview of changes from GLib 2.37.5 to 2.37.6
+==============================================
+
+* Tests using the g_test facilities can now generate TAP output
+
+* Bugs fixed:
+ 680926 generic type fallback logic is broken for -symbolic
+ 684327 setting null icon to icon list
+ 689245 GSocket unable to reuse (address,port) on Mac OS X
+ 692125 Support TAP as GTest output format
+ 693335 build: fix dtrace-related warnings
+ 696633 gdbus-codegen trips over unicode chars when using python 3.x
+ 696970 Compiling 2.36.0 for win64 fails
+ 697185 GSocket – Allow specifying the multicast interface from...
+ 700268 Add support for using the clang analyzer
+ 701318 Add G_SPAWN_DEFAULT to GSpawnFlags
+ 701529 glib/tests/gdatetime: use UTC time in test_GDateTime_diff()
+ 701800 a new approach to reporting critical errors
+ 702674 g_date_time_new_utc crash
+ 704165 GLib.IOChannel read_unichar() fails
+ 705075 Simplify g_get_tmp_dir()
+ 705152 Race in glib/task.test
+ 705398 gtype: Fix typo in g_type_class_add_private() error message
+ 705570 Check ref_count in g_object_notify_by_pspec
+ 705600 Deprecate GSimpleActionGroup functions?
+
+* Updated translations:
+ Assamese
+ Brazilian Portuguese
+ Czech
+ Dutch
+ Galician
+ Gujarati
+ Hebrew
+ Italian
+ Lithuanian
+ Marathi
+ Norwegian bokmål
+ Russian
+ Slovenian
+ Spanish
+ Thai
+ Traditional Chinese
+
+
+Overview of changes from GLib 2.37.4 to 2.37.5
+==============================================
+
+* Implement the Desktop Action specification: In the case that the
+  application is a GApplication and DBusActivatable, actions from the
+  desktop file are translated into GActions that have been added to
+  the  application with g_action_map_add_action().
+
+* GPropertyAction is a new type of GAction that represents the value
+  of a property on an object, and allows to change the value when
+  activated.
+
+* GNetworkMonitorNetlink can now handle default routes via a device.
+
+* The gsettings tool now reports failure to write a key (e.g. because
+  the key was locked down)
+
+* Miscellaneous new api:
+ - g_variant_new_printf
+ - g_action_print_detailed_name
+ - g_regex_get_max_lookbehind
+
+* Bugs fixed:
+ 664444 Support additional application actions in .desktop files
+ 684123 glib build only tries -D_GNU_SOURCE if glibc is detected
+ 689794 support incremental matching
+ 699259 add org.freedesktop.Application support to GIO
+ 700460 rewrite tests to not rely on precise timing of timeouts
+ 701511 updates to various GSource types
+ 701609 gnetworkmonitornetlink: handle default route via device
+ 703270 add GPropertyAction
+ 704157 GAction: add function for printing detailed names
+ 704250 Doc: various fixes
+ 704267 regression gsourceclosure: segfault in gedit file chooser
+ 704322 glib-unix: fix handling of multiple signal source for the...
+ 704424 No error when failing to override a locked key
+ 704447 Fix build/use of g_child_watch_closure_callback on Windows
+ 704523 g_thread_create_full() can dereference NULL pointer
+ 704543 Add implementations for G_GNUC_*_IGNORE_DEPRECATIONS for ...
+ 704567 gdbusnameowning: Don't spew an error if we're releasing a...
+ 704585 libc printf can give mixed-case strings for NaN and Inf
+ 704587 FTBFS: statfs_result is undeclared for statvfs()
+ 704699 gmain: Reset signal handlers to default when source is
+ 704704 AI_NUMERICSERV cannot be used with ai_socktype = 0
+ 704873 inotify: don't assume mainloop is running
+ 704999 glib/convert.test crashing due to lack of iconv cache
+ 704931 GMenuModel: add annotations to virtual functions
+
+* Translation updates:
+ Assamese
+ Czech
+ German
+ Gujarati
+ Spanish
+ Tamil
+
+
+Overview of changes from GLib 2.37.3 to 2.37.4
+==============================================
+
+* Bugs fixed:
+ 701283 g_source_add_child_source() segfault
+ 702147 inconsistency of G_STRFUNC
+ 703191 new private macros interact poorly with versioning macros
+ 703254 Doc: various fixes
+ 703407 g_spawn_async() keeps child_pid_report_pipe open in child process
+ 703437 GDBusConnection: be more careful with async GetAll
+ 703478 Missing G_BEGIN/END_DECLS in gsettingsschema.h
+
+* Translation updates:
+ Catalan
+
+Overview of changes from GLib 2.37.2 to 2.37.3
+==============================================
+
+* add a new API for instance private data: G_DEFINE_TYPE_WITH_PRIVATE
+
+* fix timestamps in tarball to prevent automake from being required to
+  build the unmodified source
+
+* add new D-Bus API for async property handling
+
+* add back fsync() on ext4 for g_file_set_contents() after it was
+  discovered that despite statements in the ext4 documentation
+  suggesting that this is safe, it is not safe.
+
+* Translations:
+ Italian
+ Norwegian bokmål
+
+* Bugs fixed:
+ 698375 - D-Bus async properties
+ 700350 - timestamp issue
+ 701560 - fsync issue (fixed again)
+ 700035 - new API for instance private data
+
+Overview of changes from GLib 2.37.1 to 2.37.2
+==============================================
+
+* The GLib test utilities have grown some file-related APIs
+  to support tests that can be used installed and uninstalled.
+
+* Installing properties after class initialization is deprecated,
+  and will trigger a warning.
+
+* GApplication:
+ - Support org.freedesktop.Application, including D-Bus activation
+   from desktop files
+ - Set prgname to appid for services
+
+* Bugs fixed:
+ 549783 gtester lacks framework for tests with data files
+ 692848 Fix property example in gobject tutorial
+ 698018 Add an explicit g_binding_release()
+ 698614 GObject: prevent installing properties after init
+ 699259 add org.freedesktop.Application support to GIO
+ 699959 g_file_copy(): Ensure we create private files by default
+ 700123 Test failure: g_inet_socket_address_get_scope_id
+ 700725 GIcon: NULLify the `type' out param in the sync methods too
+ 701401 gtest: add function for testing for WINE
+ 701456 Error in gnome/glib/gio/tests/file.c
+ 701474 Error building glibmm due to extra comma in glib/gtestutils.h
+ 701560 various improvements for g_file_set_contents()
+ 701680 GFileEnumerator: Add some documentation about ordering
+ 701878 Check wakeup() before iteration(TRUE) doesn't block
+
+* Translations:
+ Assamese
+ Czech
+ Galician
+ Gujarati
+ Kannada
+ Marathi
+ Odia
+ Polish
+ Slovenian
+ Spanish
+ Telugu
+
+
+Overview of changes from GLib 2.37.0 to 2.37.1
+==============================================
+
+ * add support for installed tests:
+   https://live.gnome.org/GnomeGoals/InstalledTests
+
+ * add a new g_test_trap_subprocess() that works on Windows as a
+   replacement for the (now deprecated) g_test_trap_fork()
+
+ * support for explicitly cancelling a gobject property binding
+
+ * performance improvements for signal argument handling
+
+ * stop using `quotes' in very many log messages generated by GLib, for
+   favour of 'this style'.  This may cause testcases in other packages
+   to fail if they were matching on the previous text.
+
+ * improve manpages: add missing arguments and flags
+
+Translations: 
+ Aragonese
+ Assamese
+ Gujarati
+ Hindi
+ Kannada
+ Norwegian bokmål
+ Odia
+ Slovenian
+ Spanish
+ Tamil
+ Telugu
+
+Bugs fixed:
+ 679683 replace g_test_trap_fork()
+ 694380 Improve signal argument collection performance
+ 695233 Strings require plural forms
+ 697849 spelling fixes in cross.xml and running.xml
+ 698877 GProxyAddressEnumerator calls g_network_address_parse_uri without port
+ 698981 [PATCH] test /gdbus/connection/large_message could hang forever
+ 699079 Prototype support for installed tests
+ 699485 [PATCH] tests/mappedfile: Also handle ENOMEM
+ 699493 SOCKS5 proxy code crashes if it cannot authenticate
+ 699500 gbitlock: fix this to not unconditionally use futex emulation
+ 699779 [PATCH] G_GNUC_FORMAT: documentation error
+ 700263 m4macros/glib-gettext.m4: Don't use AC_HEADER_STDC
+ 700714 [PATCH] gtestutils: Ensure test subprocesses don't dump core
+ 700746 Use 'dumb quotes' rather than `really dumb quotes'
+
+Overview of changes fron GLib 2.36.0 to 2.37.0
+==============================================
+
+* The syntax for detailed action names has been documented,
+  and a parser API for them is now provided
+
+* GApplication has gained a busy state. This feature is intended for
+  clients that want to signal a desktop shell their busy state, for
+  instance because a long-running operation is pending.
+
+* GLib can now be built with the bionic C library
+
+* GIcon can now be serialized to a GVariant
+
+* Bugs fixed:
+ 548353 Finish implementing GFile interface (mostly asynchron...
+ 645881 Full port of glib-2.28.1 onto Android-ARM
+ 665445 Glib mistakes nl_langinfo() from plibc for the real t...
+ 672018 Need API to set global application state (busy, count...
+ 687659 drop support for adding interfaces after class_init
+ 688820 GIcon is a bad interface
+ 688954 extend 'detailed action' syntax, provide parser
+ 689223 Fix compilation on Android with the bionic C library
+ 695156 Add support for arg0namespace matching in signal_subs...
+ 696108 gdbus-codegen: avoid warnings in generated code
+ 696629 fix sed(1) usage
+ 696652 GTask won't free its error member variable on finalize
+ 696857 GThreadedResolver: set an error if no records could b...
+ 696973 Compiling 2.36.0 for win64 fails in gdbusmessage.c
+ 697131 No --version
+ 697160 [PATCH] gmacros: Mark G_UNAVAILABLE() functions as de...
+ 697229 Custom Interface implementations will be broken with ...
+ 697250 Documentation glitch of G_DEFINE_TYPE_EXTENDED causes...
+ 697365 Fix usage of hasmntopt in gunixmounts.c
+ 697367 Remove warning on gio/gunixmounts.c
+ 697386 Except const argument with atomic is not lock free
+ 697595 g_main_context_unref unlocks a mutex twice
+ 697601 reduce GMenuModel D-Bus traffic
+ 697626 Allow posix threads to be used on w32
+ 697652 Help options generated even when help disabled
+ 697771 fix a typo of "fo" to "of" in building.xml
+ 697887 GVariant: fix transfer annotation
+ 697942 abicheck.sh fails on mips
+ 698056 rewrite g_object_new()
+ 698081 Pidgin hangs in g_spawn_command_line_sync
+ 698455 GVariant: add new g_variant_new_take_string() API
+ 698457 g_variant_get_data_as_bytes() always returns toplevel...
+ 698478 gactionmap: don't require GActionGroup
+ 698595 the valgrind/priv-before-instance bug
+ 698655 desktop-app-info test relies on true being in /usr/bin/
+ 698686 GUnixSocketAddress: fix construct parameter issue
+ 698716 Use of g_mem_set_vtable() breaks after gobject automa...
+ 698999 bytesicon: fix a memory leak
+ 699001 bytesicon: don't use g_object_unref() on GBytes
+ 699361 gio: fix small leak
+
+* Translation updates:
+ Assamese
+ Gujarati
+ Hungarian
+ Italian
+ Kannada
+ Norwegian bokmål
+ Polish
+ Spanish
+ Tamil
+
+
+Overview of changes fron GLib 2.35.9 to 2.36.0
+==============================================
+
+This release contains only small bugfixes and translations updates.
+
+ - g_file_copy(): fix bug where attributes were not applied properly to
+   the destination file
+
+ - fix some 'available since' annotations
+
+ - fix gdbus-codegen to produce more pedantically-correct code
+
+* Bugs fixed:
+ 696108 gdbus-codegen: avoid warnings in generated code
+ 696014 g_file_copy(): Ensure G_FILE_COPY_OVERWRITE preserves permissions
+
+* Translations updated:
+ Basque
+ Czech
+ Gujarati
+ Hindi
+ Hungarian
+ Japanese
+ Malayalam
+ Marathi
+ Odia
+ Punjabi
+ Russian
+ Tadjik
+ Tamil
+ Telugu
+
+Overview of changes from GLib 2.35.8 to 2.35.9
+==============================================
+
+This release drops the old codepage ABI from gutils.c. This is a
+source-compatible change and only breaks ABI with respect to truly
+ancient binaries (and those binaries are already broken for other
+reasons).  This change only affects Windows.
+
+* Bugs fixed:
+ 682896 glib doesn't build on mingw32
+ 693204 split up g_get_{hostname,username,realname,home_dir} etc.
+ 694181 Handle GNetworkAddress better in g_network_monitor_base_...
+ 694253 occasional /gdbus/unref-pending test failure
+ 694350 Add type names to gsignal warnings
+ 694757 Use separate GLIB_WARN_CFLAGS that can be overridden ext...
+ 568405 Which is the correct replacement for g_strncasecmp, if...
+ 630284 g_hash_table_get_keys docs
+ 659428 docs: Small clean-up of howto subsection headers
+ 675333 Cannot forget association in Open With dialog: program...
+ 694669 consider unicode corrigendum #9
+ 694843 g_base64_decode_step () produces invalid data
+ 695147 Don't use PATH_MAX as it's not guaranteed to be defined
+ 695191 Commit f641699 broke /appinfo/mime/api test case
+ 695339 Swapped msgid plural forms for translation
+ 695376 GDBusMethodInvocation leak and potential crash
+ 695425 Untranslatable message in gsettings-tool
+ 695887 Improvements to GObject API documentation
+ 695925 GUINT32/64_SWAP_LE_BE macros do not enclose val argume...
+ 696015 PATCH Add doc warning to g_base64_decode()
+
+* Translation updates:
+ Assamese
+ Belarusian
+ Brazilian Portuguese
+ Catalan
+ Catalan (Valencian)
+ Danish
+ French
+ Galician
+ German
+ Greek
+ Gujarati
+ Italian
+ Korean
+ Latvian
+ Lithuanian
+ Polish
+ Portuguese
+ Punjabi
+ Serbian
+ Simplified Chinese
+ Slovak
+ Slovenian
+ Spanish
+ Thai
+ Traditional Chinese
+ Uyghur
+ Vietnamese
+
+
+Overview of changes from GLib 2.35.7 to 2.35.8
+==============================================
+
+This release contains one major change that may cause problems: type
+modules are now never unloaded.  This is implemented by (effectively)
+leaking the last reference on dynamic types.  Some testcases that check
+for unloading of types have been observed to be broken by this change,
+but we know of no actual cases of "real code" breaking.  Please report
+any problems.
+
+Other changes:
+ * A couple of build fixes for Solaris
+ * Fix signal emission for GDBusObjectManagerClient
+ * annotations fixes
+ * new API: g_dbus_address_escape_value()
+ * GSocketClient: add proxy-resolver property
+ * GSimpleProxyResolver: new simple GProxyResolver class
+ * documentation fixes
+ * gnetworkaddress: preserve IPv6 scope ID in IP literals
+
+Bugs fixed:
+ 691105 Allow GSocketClient to override GProxyResolver for per client proxy settings.
+ 692827 configure test fails for arpa_nameser.h
+ 692829 new Btrfs support causes build failure on Solaris
+ 693285 GDBusObjectManagerClient: won't emit object-added|removed if name-owner arrives later
+ 693502 Cross-compiling documentation: typo (np -> no)
+ 693673 add g_dbus_address_escape_value()
+ 693694 gio: Fix annotations on g_[async_]initable_new() and friends 
+
+Translations:
+ Dutch
+ Galician
+ Polish
+ Serbian
+
+Overview of changes from GLib 2.35.6 to 2.35.7
+==============================================
+
+This is a quick follow-up release with a few bug fixes.
+
+* Fix the build on systems with strict linkers by adding -pthread back
+  to the LDFLAGS for a testcase.
+
+* Re-enable native atomic operations on some buggy versions of clang
+  that ship as part of the MacOS X SDK.
+
+* Make G_IO_FLAG_IS_WRITEABLE an enum again (the #define broke bindings)
+
+* a small docs fix
+
+* Bugs fixed:
+ 657045
+ 636683
+ 682818
+ 693105
+
+* Translations:
+ Italian
+
+Overview of changes from GLib 2.35.4 to 2.35.6
+==============================================
+
+* GUnixFdSource is a new way to add file descriptors
+  to the mainloop
+
+* g_source_set_ready_time lets you mark a source to become
+  ready at a specified monotonic time
+
+* The internal visibility handling of GLib has been reworked
+
+* GFileMonitor will now automatically use fam instead of inotify
+  if $HOME is on NFS
+
+* The file monitor implementation can now be overridden with
+  the GIO_USE_FILE_MONITOR environment variable
+
+* Bugs fixed:
+ 570572 2 make check errors on
+ 592211 No monitoring over NFS mounts
+ 625552 wrong behaviour of GVolume GVolumeMonitor related func...
+ 657729 modernise GMainLoop
+ 658020 GSource for a single GPollFD
+ 678223 g_mutex_free
+ 682560 leak fixes
+ 682819 EINTR-harden all the things
+ 684404 When using g_network_address_address_enumerator_next()...
+ 686853 new GSource fd API
+ 688169 G_DISABLE_DEPRECATED doesn't cover deprecated/gthread....
+ 688681 build: Make .symbols file canonical on all platforms
+ 690118 Crash when closing last tab of a window using Ctrl-w
+ 691624 glib/gtester.c: missing include
+ 691812 gioinputstream - give task as callback_data not task_data
+ 691866 fails out of source build directory - gnetwork.h not f...
+ 692029 Add new API checking utility
+ 692034 Install an invalidation notifier for GClosure in g_sou...
+ 692058 Broken makefile for gio tests
+ 692079 build failure in gmarkup.c when using gcc 4.8 and buil...
+ 692201 inotify: fix a memleak
+ 692202 gfile: don't report completion twice on g_file_load_co...
+ 692229 Incorrect string formatters in a translation string
+ 692332 GNetworkMonitorNetlink: make the netlink socket cloexec
+ 692360 possibly non-threadsafe code in g_content_type_guess()?
+ 692404 tester: Use FD_CLOEXEC when creating pipes
+ 692408 nautilus SIGSEGV in g_file_info_get_size()
+ 692544 [PATCH] gfile: Ensure we create internal pipe with FD_C...
+ 692583 atomic get doesn't accept a const argument on architect...
+ 692618 Use g_timeout_add_seconds
+ 692815 Using g_hash_table_insert() when using a hash table as ...
+ 692865 Invalid docbook generated by gdbus-codegen
+ 692928 Document G_MENU_{ATTRIBUTE,LINK}_*
+
+* Translation updates:
+ Hebrew
+ Kannada
+ Lithuanian
+ Norwegian bokmål
+ Polish
+ Serbian
+ Slovenian
+ Spanish
+ Uyghur
+
+
+Overview of changes from GLib 2.35.3 to 2.35.4
+==============================================
+
+* New features:
+ - New API: g_get_num_processors
+ - New API: g_application_command_line_get_stdin
+ - New GFileMonitor flag: G_FILE_MONITOR_WATCH_HARD_LINKS
+ - Parse more timezone offset formats
+ - Better timezone support on Windows
+ - Make GParamSpec constructors introspectable
+
+* Removed or deprecated features:
+ - Disallow adding interfaces after class_init
+
+* Bug fixes:
+ 532815 gio + inotify support for hardlinks
+ 614930 add g_get_num_processors (), return the max concurrent...
+ 626497 Btrfs clone/reflink ioctl support in g_local_file_copy
+ 633117 glib fails stests if /etc/localtime is not properly set
+ 661767 merge/improve various bits of run-in-thread functionality
+ 668210 Add g_application_command_line_get_stdin()
+ 675856 Use GDbus via gobject-introspection instead dbus-python
+ 684103 make glib work with python3
+ 684723 run-assert-msg-test.sh fails
+ 686058 OpenBSD: disable ipv6_v4mapped test
+ 686128 GTimeZone should be able to parse POSIX format for...
+ 687223 cleverer GThreadPool management
+ 687659 drop support for adding interfaces after class_init
+ 687920 GCredentials should have an accessor for the process ID
+ 688681 build: Make .symbols file canonical on all platforms
+ 688829 Variable overflow in utils.c test on 32-bit machine
+ 689324 Variable scoping in gunixmounts.c
+ 689810 Include guard optimization
+ 690043 Broken link for gsettings tutorial: gnome-utils in...
+ 690084 gmarkup: Make GMarkupParseContext a boxed type
+ 690388 Check if CMSG_FIRSTHDR() returns NULL when there is...
+ 690538 gschema DTD is invalid
+ 690543 Add test coverage for testing in-tree DBus services...
+ 690670 local_command_line not introspectable/annotated
+ 690902 G_END_DECLS needs to be at the end of gutils.h
+ 690970 Unhelpful deprecation message for g_value_array_get_nth
+ 691001 building docs is broken on master branch
+ 691011 Automake-1.13 errors on obsolete AM_PROG_CC_STDC
+ 691077 gio-querymodules crashes with SIGSEGV
+ 691110 g_cond_wait() docs incomplete
+ 691489 Crash in Oscars 2013 page
+ 691558 Only check for .hidden files if standard::is-hidden...
+ 691608 Support compilation with clang 3.2
+
+* Translation updates:
+ Assamese
+ Bulgarian
+ Estonian
+ Galician
+ Greek
+ Hebrew
+ Norwegian bokmål
+ Polish
+ Slovak
+ Slovenian
+ Spanish
+ Tamil
+
+
+Overview of changes from GLib 2.35.2 to 2.35.3
+==============================================
+
+* This release contains an incompatible change to the g_get_home_dir()
+ function. Previously, this function would effectively ignore the HOME
+ environment variable and always return the value from /etc/password.
+ As of this version, the HOME variable is used if it is set and the
+ value from /etc/passwd is only used as a fallback.
+
+* We now install a public "gnetworking.h" header that can be used to
+ include the relevant OS-dependent networking headers. This does not
+ really abstract away unix-vs-windows however; error codes, in
+ particular, are incompatible.
+
+* Bugs fixed in this release:
+ 142568 Allow $HOME to override passwd entry if the user really wants
+ 587806 The file selector should honor .hidden files
+ 602715 [GChecksum] Please add support for SHA512
+ 623187 provide some support for arbitrary setsockopt()s?
+ 629301 .goutputstream files left behind when cancelling I/O
+ 652650 Optimize GDBusMessage serialization
+ 664627 /gapplication/basic test intermittently fails: cmdline re-or...
+ 675516 Win32: Don't start a DBus server when built as static library
+ 679683 replace g_test_trap_fork()
+ 684145 Current Git sources fails to cross-compile for Windows in Li...
+ 686895 file-info: catch thumbnail files in large directory as well
+ 687092 IPv6 <-> IPv4 mismatch when subscribing to multicast (send)
+ 688180 GObject: Minor error in description of floating reference
+ 688319 gthread: add missing AVAILABLE_IN_2_32 annotations
+ 688377 configure: add missing square bracket in AS_IF for memmove
+ 688419 gtask: source_object arguments and return values not annota...
+ 688497 AppInfo: Add sufficient api to port gnome-session from Egg...
+ 688681 build: Make .symbols file canonical on all platforms
+ 688704 Add boxed GType for GThread
+ 688886 Improve the i18n documentation
+ 688931 GMemoryOutputStream: Add new _resizable() constructor usab...
+ 689037 need helper for creating a GFile from a remote commandline...
+ 689377 Fix a compiler warning in GDBus
+ 689538 Source object tag set too late in gsocketlistener
+ 689800 Treat lost+found directory as a hidden file
+ 689847 Add fast repeated typename -> GType resolver
+ 689982 Make GChecksum more fully introspectable
+ 690069 g_unix_open_pipe: Add missing F_SETFD
+ 690083 gfileenumerator: Add a g_file_enumerator_get_child method
+ 690163 Add a pre-configured gio/gnetworking.h for Visual C++ builds
+ 690346 Remove an unneeded escaping in NAMESER_COMPAT_INCLUDE
+ 690348 Fix g_type_add_class_private() name in g_warning
+
+* Translation updates:
+ Assamese
+ Galician
+ Hebrew
+ Hindi
+ Kannada
+ Odia
+ Polish
+ Spanish
+
+
+Overview of changes from GLib 2.35.1 to 2.35.2
+==============================================
+
+Note that the incompatible change to the ->constructed() vfunc that was
+made in the last unstable release (2.35.1) has been reverted due to
+causing regressions in applications.
+
+A new incompatible change has been introduced in this version: it is no
+longer permitted to add interfaces to a class after the first
+instantiation (or more strictly: after g_type_class_ref()).  Bug #687659
+is tracking this.
+
+Two private symbols (g_menu_{attribute,link}_hash_iter_get_type) which
+were accidentally exported have also been properly hidden.  This may
+cause some tools to issue warnings about ABI mismatch.
+
+The remaining changes should be relatively harmless: 
+
+ * GIO now has kqueue support for GFileMonitor (BSDs, Mac OS)
+
+ * New g_variant_new_from_bytes() API
+
+ * UNIX signal sources now allow watching SIGUSR1 and SIGUSR2
+
+ * Many pedantic cleanups to adhere to a higher level of -W use
+
+ * GTask changes to avoid a deadlock
+
+ * many cleanups/fixes for Windows
+
+ * Boxing for GPollFD, GIOChannel, GBytes, GByteArray
+
+ * Fix URL-encoding of trashed files
+
+ * Many other docs and annotations fixes
+
+Translations:
+
+ Galician
+ Gujarati
+ Lithuanian
+ Serbian
+ Slovak
+ Slovenian
+
+Bugs closed:
+
+ 649302 Add support for GNU/FreeBSD
+ 668842 [GSocket] Add caching for the sender address in g_socket_receive_from()
+ 672924 Add annotations for g_filename_from_uri()
+ 673229 glib: Use Returns:, not @returns
+ 677062 (partial) GVariant: Make g_variant_new_from_bytes() public, add more GBytes API
+ 686185 g_date_time_format Transcoding Fails on OSX      
+ 686191 g_mutex_get_impl() should use g_atomic_pointer_get()
+ 686797 Box GPollFD to make it introspectable
+ 686810 [regression] Infinite wait in g_task_run_in_thread_sync()
+ 686822 possible dlopen()/dlclose() issue with automatic g_type_init()
+ 686839 mkinstalldirs: Move to glib-mkinstalldirs
+ 686895 file-info: catch thumbnail files in large directory as well
+ 686898 g_unix_signal_source_new: Allow SIGUSR1 and SIGUSR2
+ 686920 gdbus: Allow GDBusObjectManagerClient to work on peer connections
+ 686921 Remove some of the repetition from gio/tests/Makefile.am
+ 687075 g_spawn_sync diagnostic incorrectly complains about SIGCHLD
+ 687089 g_dbus_connection_export_menu_model(): fix a crash
+ 687098 Repeated g_timeout_add* use can lead to guint overflow
+ 687385 Add some stricter CFLAGS, fix up the code
+ 687441 ABI break in master: g_menu_attribute_hash_iter_get_type, g_menu_link_hash_iter_get_type removed
+ 687516 typo in string: KB should be kB
+ 687540 In Trash folder, Nautilus misinterprets "\n" in filename as a line break
+ 687541 GSignalQuery param_types field needs array annotation
+ 687600 gfileutils.c performs invalid cast of (varargs) open to non-vararg type
+ 687698 plural forms needed
+ 687700 ending spaces
+ 687742 Add support for internal linkage to glib-compile-resources
+ 687801 tests/buffered-input-stream: Fix size of parameter passed
+ 688109 win32 warning/error fixes
+ 688255 'make check' regressed in 138f4c1 because GMarkup error messages changed
+ 688338 [PATCH] gobject/gtype.c: Fix spelling of »exceed«
+ 688370 GDBusError documentation improvement for client-side
+ 688378 g_socket_join_multicast_group not working
+ 688518 gio-kqueue: use O_EVTONLY on MacOS
+
+
+
+Overview of changes from GLib 2.34.0 to 2.35.1
+==============================================
+
+These two changes in particular may be slightly incompatible.  Please
+give feedback if they cause trouble:
+
+  * Signal handlers connected with g_signal_connect_object() are now
+    automatically disconnected on target object destruction
+
+  * The ->constructed vfunc is now called after all properties are set
+
+The remaining changes should not cause problems.
+
+  * g_type_init() is no longer necessary and has been deprecated
+
+  * GTask (the new GAsyncResult implementation) has landed 
+
+  * GLib version macros updated
+
+  * Update to Unicode 6.2
+
+  * Thread safety fixes for GFileMonitor in non-default main contexts
+
+  * GTimeZone support for old-format zoneinfo database (as on Mac OS)
+
+  * g_settings_bind() now works with non-canonical property names
+
+  * Fix crashes related to NULL connection passed to
+    GBusNameVanishedCallback and document this situation
+
+* Bugs fixed:
+ 118536 Make g_signal_connect_object'ed handlers disconnect when the data object is destroyed
+ 661767 merge/improve various bits of run-in-thread functionality
+ 682950 GFileMonitor crashing on high event count when running in different thread
+ 683642 Missing g_content_type_get_symbolic_icon
+ 684882 Gsettings should spaw a warning when binding against a low_underscored_property
+ 684909 codegen: Explicitly close output
+ 684912 Update to Unicode 6.2
+ 685037 g_strcmp0: Returns shall include values less and greater than zero
+ 685069 Leak in glib-compile-resources
+ 685208 missing g_return_if_fail
+ 685608 [Patch] Port gio tests from pygobject to pygi
+ 685697 Documentation typo in g_dbus_interface_skeleton_has_connection()
+ 685733 Call ->constructed() after all properties are set
+ 685787 gtestdbus: correct documentation typos
+ 685995 Crash in g_menu_exporter_name_vanished
+ 686091 Invalid reads in g_bytes_unref_to_data
+ 686119 dtrace, gobject_probes.d, the last three probes - semicolon missing
+ 686161 Deprecate g_type_init()
+ 686231 GBusNameVanishedCallback: document NULL connection
+ 686458 slightly increase poll duration in test_timed_wait 
+
+* Translations updated
+  Catalan (Valencian)
+  Czech
+  Danish
+  Italian
+  Lithuanian
+  Norwegian bokmål
+  Slovenian
+
+Overview of changes from GLib 2.33.14 to 2.34.0
+===============================================
+
+* Bug fixes:
+ 654239 g_type_init()'s docs have no statement about how to...
+ 674620 Update GSettings migration guide for intltool updates
+ 676034 Fix doc annotation for g_ptr_array_ref()
+ 684278 Fix GIO build on Windows
+
+* Translation updates:
+ Brazilian Portuguese
+ British English
+ Bulgarian
+ Catalan
+ Galician
+ German
+ Hebrew
+ Hindi
+ Hungarian
+ Kannada
+ Latvian
+ Marathi
+ Spanish
+ Telugu
+
+
+Overview of changes from GLib 2.33.12 to 2.33.14
+================================================
+
+ * CVE-2012-3524: don't run dbus-launch from setuid binaries
+
+ * g_content_type_get_generic_icon_name():
+     new API for getting the icon name for a mime type
+
+ * Introspection fixes:
+  - GDBusConnection nullability fixes
+  - give a box type to GTimeZone
+
+ * Drop GVFS_INOTIFY_DIAG
+
+ * Add a new "Writing GLib Applications" section to the reference
+   documentation with general info on security, threads, etc.
+
+ * gwin32mount.c: Fix syntax error
+
+ * gresource tests: srcdir != builddir fixes
+
+ * tests/gvariant: Fix test on big endian architectures
+
+ * Fix regression in g_shell_parse_argv()
+
+Bugs fixed:
+ 562907 g_shell_parse_argv() mishandles # (hash)
+ 683167 g_time_zone_new not introspectable
+ 683384 /gvariant/checksum-basic failure on big endian machines
+ 683641 Typo in gwin32mount.c
+ 683744 have a way to get the generic icon name for a mime type
+
+Translation updates:
+ Assamese
+ Belarusian
+ British English
+ Czech
+ Danish
+ French
+ Galician
+ German
+ Greek
+ Hebrew
+ Indonesian
+ Indonesian
+ Korean
+ Lithuanian
+ Marathi
+ Marathi
+ Polish
+ Portuguese
+ Punjabi
+ Russian
+ Serbian
+ Slovenian
+ Traditional Chinese
+
+Overview of changes from GLib 2.33.10 to 2.33.12
+================================================
+
+* Add a G_DEFINE_QUARK macro
+
+* Add symbolic icon support to drive, volume, and mount, file
+  and content types
+
+* Add API to allow thread-safe access to the same qdata item
+
+* Bugs fixed:
+ 562907 g_shell_parse_argv() mishandles # (hash)
+ 627240 add G_DEFINE_QUARK
+ 672329 memory leaks in gutils.c and glib tests
+ 673012 Stable byte-level specification for normal form
+ 674805 gdbusproxy async test is broken
+ 679835 gvariant format string parsing (and assertions)...
+ 682075 gdbus: Fix double free and use after free of ob...
+ 682101 Provide a way to get a symbolic icon for a device
+ 682222 test_method_calls_on_proxy: assertion failed (e...
+ 682284 mount-op: use gint64 instead of guint64 for tim...
+ 682386 "make check" fails due to sys/resource.h not be...
+ 682560 leak fixes
+ 682586 gsettings-tool: make list-recursively really re...
+ 682819 EINTR-harden all the things
+ 682833 Handle EINTR for open()
+ 682849 drop the global lock for g_object_weak_ref
+ 682965 gdbus-tool: Check return value of strrchr()
+ 683088 gdbus-codegen: fix error when wrong interface n...
+        Fix the build with gtk-doc-stub
+        Don't crash if set_app_info is called before ad...
+
+* Translation updates
+ Assamese
+ Galician
+ Greek
+ Indonesian
+ Japanese
+ Latvian
+ Lithuanian
+ Norwegian bokmål
+ Polish
+ Portuguese
+ Punjabi
+ Russian
+ Spanish
+ Traditional Chinese
+ Vietnamese
+
+
+Overview of changes from GLib 2.33.8 to 2.33.10
+===============================================
+
+* New GTest API for testcases where log output is expected:
+  g_test_expect_message()
+
+* GMenuItem now has 'get' accessors and a construct-from-GMenuModel API
+
+* GVariant now has a function to check a format-string for type
+  compatibility
+
+* win32: We now use overlapped IO to support multiple asynchronous
+  operations (ie: reading and writing) at the same time.
+
+* GMappedFile: Add g_mapped_file_get_bytes()
+
+* The problems with g_file_make_directory_with_parents() should be
+  resolved.
+
+* The long-standing issues with placeholder generation of manpages are
+  now resolved.
+
+* gtlscertificate: Add GBytes based certificate and private-key props
+
+* build: Switch back to using AS_IF for conditionals
+
+* test coverage improvements, documentation improvements, leak fixes
+
+* Bugs fixed
+ 326931 Better docs for G_GNUC_*
+ 550433 g_test_init doesn't recognize --help
+ 600751 GCompletion should better document if and how items memory is managed
+ 628193 Miscellaneous string fixes
+ 637460 man glib-genmarshal is hard to use
+ 674483 broken configure results when cross-compiling with gcc >= 4.5
+ 677065 GMappedFile: Add g_mapped_file_get_bytes()
+ 679288 win32: use overlapped events for streams
+ 679556 it's hard to use gtest when g_warning() is expected
+ 680823 g_file_make_directory_with_parents: Fix error propagation
+ 681319 gtlscertificate: Add certificate-bytes and private-key-bytes props
+ 681336 man pages not built if --enable-gtk-doc not specified
+ 681413 build: Switch back to using AS_IF for conditionals
+ 681501 gmem: array only partially filled with memcpy
+ 681854 Documentation fix for Howto compile a program with glib
+ 682025 Documentation correction
+ 682067 Fix problems with CLEANFILES and automake-1.11.1 
+
+* Translations updated:
+ Lithuanian
+ Spanish
+ Galician
+ Telugu
+ Serbian
+ Assamese
+ Marathi
+ Indonesian
+ Traditional Chinese
+
+Overview of changes from GLib 2.33.6 to 2.33.8
+==============================================
+
+* GIO now has a g_file_delete_async function
+
+* The defaults for GThreadPools max_unused_threads
+  and max_idle_time values have been changed to
+  2 and 15*1000, respectively.
+
+* Bugs fixed:
+ 661767 merge/improve various bits of run-in-thread functionality
+ 680074 undefined symbol "get_C_locale"
+ 680121 g_cancellable_source_new: don't use a file descriptor
+ 680148 gthread: check for definition of PR_SET_NAME
+ 680310 Sorting of access points by strengh not working
+ 680704 g_utf8_strup() crash
+ 68076a0 GFile: Add g_file_delete_async()
+ 680787 Add .dir-locals.el to tell Emacs users not to use tabs...
+ 680823 g_file_make_directory_with_parents: Fix error propagation
+ 680994 STATIC_ASSERT in GDBusError docs don't have much utility
+ 681116 gtlscertificate: Add g_tls_certificate_equal() function
+ 681118 gtlsdatabase: Don't complain if no callbacks for async...
+ 669331 try to get gio tests working a little better on win32
+ 674314 Make gtk-doc not a hard dependency of GLib
+ 674800 gclosure: generic marshaller leaks return value
+ 675524 gsocket: FIONREAD undeclared (needs sys/filio.h)
+ 679509 use after free in g_dbus_action_group_describe_all_done()
+ 679996 gobject docs minor cleanup
+ 680459 Extra newline char in local implementation of g_applic...
+ 680505 object_path memory leak in gdbusobjectproxy.c
+ 680831 Deprecate and remove g_slice_[sg]et_config.*
+ 680912 gchecksum: Add g_compute_checksum_for_bytes()
+ 681151 checksum: Use functions instead of macros when buildin...
+ 681158 gtlscertificate: Don't confuse certificate and public ...
+
+* Translation updates:
+ Galician
+ German
+ Gujarati
+ Hebrew
+ Norwegian bokmål
+ Serbian
+ Slovenian
+
+
+Overview of changes from GLib 2.33.4 to 2.33.6
+==============================================
+
+* GAsyncInitable: partially revert the init_finish changes,
+  some applications were found to rely on behaviour that
+  was broken by these changes
+
+* Bugs fixed:
+ 679617 win32: fix g_get_environ()
+ 679968 Add some annotations to GBytes, GVariantType...
+ 680111 GIOScheduler assumes GCancellable "cancelled...
+
+* Translation updates:
+ Spanish
+
+Overview of changes from GLib 2.33.3 to 2.33.4
+==============================================
+
+* GMainContext: the source list has been reorganzied to
+  avoid O(n) behaviour
+
+* GRegex: Update included PCRE to 8.31 and expose new
+  functionality in 8.x versions of PCRE
+
+* GMountOperation gained a ::show-unmount-progress signal
+  which provides information about slow unmount operations
+
+* Bugs fixed:
+ 616892 gio: Add a boxed type for GFileAttributeMatcher
+ 619329 g_source_attach() O(n) in number of sources
+ 639771 g_dir_read_name() can also return NULL on error
+ 661767 merge/improve various bits of run-in-thread fun...
+ 667375 GAsyncInitable subclassing (and async subclassi...
+ 671545 Constify collect and lcopy strings in GTypeValu...
+ 674452 SEGFAULT in gio contenttype test
+ 674898 Deal with GLIB_VERSION_MIN_REQUIRED/MAX_ALLOWED...
+ 675504 Fix up GObject interface documentation
+ 677064 GString: Tweak documentation, add g_string_free...
+ 677578 error in PCRE error code conversion
+ 677579 update GRegexError for newer PCRE error codes
+ 678066 gdbus codegen does not work with python3
+ 678273 unicode othercasing is wrong in gregex
+ 678576 GIOScheduler performance enhancements
+ 678758 GTlsInteraction unlocks an unlocked mutex
+ 678808 GTestDBus issues
+ 678881 Test failures in /socket/timed_wait in some cas...
+ 678941 /contenttype/guess test case failure
+ 678944 gio returns the wrong default applications for ...
+ 678949 wrong definition of ulong_bool for 64 bit big e...
+ 678959 /mainloop/timeouts race condition: assertion fa...
+ 679193 update included pcre to 8.31
+ 679258 The 'Since' tag for G_SOURCE_CONTINUE and G_SOU...
+ 679473 Don't generate invalid property names
+ 679691 Add g_spawn_check_exit_status()
+ 679671 GDBusNodeInfo: the XML string must contain exac...
+ 676111 mount-operation: add show-unmount-progress signal
+ 679691 win32: fix build g_spawn_check_exit_status() wi...
+ 679813 Documentation bug on http://developer.gnome.org...
+
+* Translation updates:
+ Assamese
+ Belarusian
+ Bulgarian
+ Galician
+ Greek
+ Norwegian bokmål
+ Polish
+ Spanish
+ Traditional Chinese
+ Vietnamese
+
+
+Overview of changes from GLib 2.33.2 to 2.33.3
+==============================================
+
+This release contains mostly bugfixes, cleanups and performance
+improvements (including many fixes contributed by Colin on the advice of
+Coverity).  There are a few notable externally-visible changes:
+
+* Thumbnails are now in XDG_CACHE_HOME
+
+* new GDBus API: per-thread g_dbus_connection_get_last_serial()
+
+* GUnixOutputStream now has a can_poll() implementation
+
+* New deep copy APIs for G(S)List: g_(s)list_copy_deep
+
+* Bugs fixed:
+ 518309 Incorrect data*dir path in glib-gettextize output
+ 566994 Safer passing of -framework flag
+ 672889 GLib.utf8_validate does segfault
+ 673253 Not strict enough autconf test for libelf
+ 675024 adds g_list_copy_deep() and g_slist_copy_deep
+ 675168 prepare for thumbnails to move to XDG_CACHE_HOME
+ 675966 gresolver: More robust parsing of DNS responses
+ 676594 [Patch] fix g_reload_user_special_dirs_cache
+ 676825 Implement g_dbus_connection_get_last_serial ()
+ 677235 Clarify the comment at the top of gmarshal.list
+ 677527 OS X: gthread/spawn-async selftest failure
+ 677718 GDBusProxy: treat org.freedesktop.systemd1.Masked error as non-fatal
+ 677770 GUnixOutputStream does not implement can_poll
+ 677782 Install bash completion files in /usr/share
+ 677817 g_key_file_to_data adds extra blank lines in some cases
+ 677952 Missing annotation for GDBusConnection signal "closed"
+ 678052 g_wakeup_acknowledge is called too often.
+ 678273 unicode othercasing is wrong in gregex
+ 678333 gdbus-codegen code causes warnings under -Wfloat-equal
+
+* Translations updated:
+ Arabic
+ Assamese
+ Galecian
+ Greek
+ Spanish
+ Telugu
+
+Overview of changes from GLib 2.33.1 to 2.33.2
+==============================================
+
+* GLIB_VERSION_MIN_REQUIRED now defaults to the current stable version
+
+* GIO input and output stream classes have grown GBytes-based methods
+
+* GApplication now has hooks to register D-Bus objects before the bus
+  name is taken
+
+* Bugs fixed:
+ 605976 add g_type_ensure(), to ensure that a type has...
+ 660851 Breakage of code due to changes in the GThread...
+ 666386 Empathy doesn't open Redirect URI with particu...
+ 671139 need (transfer async) for io stream buffers
+ 672329 memory leaks in gutils.c and glib tests
+ 672548 g_utf8_validate: @str shouldn't end up annotat...
+ 674111 Provide an accessor for MimeType desktop entry...
+ 674483 broken configure results when cross-compiling ...
+ 674634 Add g_clear_pointer()
+ 674777 What's the (transfer) of g_variant_lookup()?
+ 675309 gkeyfile: Fix annotations for g_key_file_load_...
+ 675446 gfile: Plug memory leak in g_file_make_directo...
+ 675509 add extra dbus hooks
+ 675832 Incomplete gsettings bash auto-completion
+ 676208 The tmpl parameter to g_file_new_tmp can be NULL
+ 676265 GNetworkMonitor leaks a lot of memory
+ 676277 Document that g_app_info_create_from_commandli...
+ 676397 g_environ_* should work with NULL envp
+ 676398 g_spawn_* should take PATH from the passed env...
+ 676478 Broken gzip decoding
+ 676594 [Patch] fix g_reload_user_special_dirs_cache
+ 676816 Add more GLIB_AVAILABLE_IN_*
+ 676937 Document notify signal deduplication with free...
+
+* Translation updates:
+ Czech
+ French
+ German
+ Greek
+ Japanese
+ Russian
+ Slovenian
+ Spanish
+
+
+Overview of changes from GLib 2.32.1 to 2.33.1
+==============================================
+
+* GApplication
+ - can now have a NULL application ID
+ - add accessors for determining dbus connection and object path
+
+* g_clear_object: fix warnings when using it on C++ (due to lack of
+  ability to implicitly cast void*)
+* add g_clear_pointer as a generic form of g_clear_object
+
+* GDBus:
+ - add our own implementation of the message bus for use on Windows only
+ - fix up a few bugs that use of this bus uncovered in GDBus
+ - escape nonce files in dbus addressess (think 'c:\')
+ - support initial underscores in dbus codegen namespace (for private)
+ - add GTestDBus for bringing up a session bus for testing purposes
+ - gdbus-codegen: Avoid warnings in generated code
+ - GDBusAuthObserver: Add a way to control what authentication mechanisms to use
+ - 
+
+* Fix misdetection of GNUstep as Cocoa (for the MacOS GSettings backend)
+
+* make sure configure fails if AC_CHECK_ALIGNOF cannot detect the alignment
+
+* GAppInfo
+ - overwrite the DISPLAY only if it is set in the launch context
+ - add accessor for StartupWMClass
+
+* glib/tests/date: force US locale running the GDateTime tests
+
+* Resources:
+ - fix broken use of GVDB on big endian machines
+ - set a 'display name' so that pretty file names appear in Gtk CSS
+   warning messages
+
+* GMainContext:
+ - block child sources when blocking the parent
+ - introduce more testcases for child sources
+
+* GResolver: add support for MX, TXT, NS and SOA records
+
+* GSocketControlMessage: Don't warn about unknown messages
+
+* GIO:
+ - implement GSeekable for the data and buffered stream classes
+ - implement GPollable for many more classes as well
+ - fix GConverterInputStream infinite loop when fill_buffer returns an error
+ - fileinfo: document the correct type for trash::orig-path
+
+* test coverage improvements and general fixes
+
+* new 2.34 stuff: version macros, docs index section, etc.
+
+* Build:
+ - add --disable-modular-tests build option
+ - don't require host binaries if tests are not enabled for cross-builds
+
+* Translations updated
+ Brazilian Portuguese
+ Bulgarian
+ Czech
+ French
+ Galician
+ German
+ Hebrew
+ Hindi
+ Italian
+ Norwegian bokmål
+ Polish
+ Russian
+ Russian
+ Serbian
+ Simplified Chinese
+ Slovenian
+ Spanish
+ Telugu
+
+Overview of changes from GLib 2.32.0 to 2.32.1
+==============================================
+
+* Bugs fixed:
+ 670254 glib-2.30.2: Fails /GDateTime/new_from_unix test
+ 672541 glib-compile-resources prepends --sourcedir to absolute paths
+ 673139 URL to mailing lists in README incorrect
+ 673174 g_input_stream_read[_finish]: document returning 0 on EOF
+ 673191 glib/gchecksum.c warning: dereferencing type-punned pointer...
+ 673216 [W32] gtestutils does not use path separators consistently
+ 673439 Properly deprecate g_value_{set,get}_char
+ 673612 Fails to decode dictionaries wrapped in two layers of array
+ 673803 gclosure: Support return values of GVariants
+ 669285 glib/tests/markup-parse fails under non-english locale
+ 673911 gio-2.0.pc lists full path to executables, breaking cross com..
+ 673762 gnextstepsettingsbackend.c:343: error: parse error before 'in'
+
+* Updated translations:
+ Belarusian
+ British English
+ Bulgarian
+ Catalan
+ Czech
+ French
+ German
+ Hebrew
+ Hindi
+ Hungarian
+ Italian
+ Japanese
+ Kannada
+ Latvian
+ Lithuanian
+ Marathi
+ Norwegian bokmål
+ Odia
+ Polish
+ Serbian
+ Slovenian
+ Spanish
+ Swedish
+ Telugu
+
+
+Overview of changes from GLib 2.31.22 to 2.32.0
+===============================================
+
+* Bugs fixed:
+ 671988 Quickly registering / unregistering objects on bus...
+ 672095 glib needs stable sort function
+ 672406 glib/tests/include.c fails to build on FreeBSD
+
+* Updated translations:
+ Telugu
+
+
+Overview of changes from GLib 2.31.20 to 2.31.22
+================================================
+
+* Bugs fixed:
+ 531901 Use __builtin_bswap* for GUINT*_SWAP_LE_BE if building...
+ 653167 Out of tree build is broken on windows
+ 668973 Test /gvariant/parser fails on Solaris 10
+ 669797 gvfs now lists its fuse mounts
+ 670846 deadlock: GStreamer-WARNING **: wrong STREAM_LOCK count 0
+ 671664 gio-querymodules: unlink instead of writing empty cache
+ 671676 Glib can't be cross-compiled any more after merge of...
+ 671918 gnome-shell is inaccessible unless started while an AT...
+ 671942 GSocketMsgFlags: annotate as a flags
+ 671997 Unix signal handling assumes that volatile 1-byte writes...
+ 672013 GSimpleAsyncResult: support reliable cancellation
+ 672026 default log output should include pid and/or prgname
+ 672095 glib needs stable sort function
+ 672201 G_SPAWN_SEARCH_PATH should continue on ENODEV and ETIMEDOUT
+ 672239 request NO_REPLY from g_dbus_connection_call() with no as...
+ 672249 gdbusproxy leaks asyncresult in an error case instead of...
+
+* Translation updates:
+ Assamese
+ British English
+ Catalan
+ Catalan (Valencian)
+ Danish
+ Esperanto
+ Finnish
+ French
+ German
+ Hungarian
+ Korean
+ Lithuanian
+ Norwegian bokmål
+ Polish
+ Portuguese
+ Russian
+ Traditional Chinese
+
+
+Overview of changes from GLib 2.31.18 to 2.31.20
+================================================
+
+* Update to Unicode 6.1
+
+* Update PCRE to 8.30
+
+* Deprecations are now versioned, and new API is
+  marked with the version it was introduced.
+  Use these with GLIB_VERSION_{MIN,MAX}_REQUIRED
+
+* The performance of signal emissions has been
+  improved for simple cases
+
+* Bugs fixed:
+ 529806 Cannot build in 64-bit Mac OS X due to libiconv
+ 580873 Documentation of register type functions incomplete
+ 592666 Document how to unset an attribute
+ 597785 g_type_class_add_private code snippet is a bad example
+ 621368 glib-2.24.1: FAIL: run-assert-msg-test.sh when updating...
+ 622149 --disable-regex breaks glib2 build
+ 639873 GBinding: Crash when binding two properties on the same...
+ 640202 For GLIB v. 2.23.6 and above: impossibility to build mu...
+ 668295 Need a way to classify GVolume instances
+ 669670 gasyncqueue: don't use deprecated g_cond_timed_wait()
+ 670542 Add version information for deprecations
+ 670557 gvaluetransform: Fix an infinite loop with GFlagsValue...
+ 670721 global variable for signal ID should be hidden
+ 670751 IceWM build fails due to the G_DEPRECATED_FOR macro
+ 670909 g_dbus_connection_call leaks when it receives an error...
+ 670922 Include path to gdbus-codegen in the pkgconfig file
+ 670969 GSequence lookup may fail if there was no sort prior to...
+ 671025 Constants and identifiers starting with a number are no...
+ 671270 make distclean failures
+ 671281 glib-compile-resources.xml is missing from the dist tar...
+
+* Translation updates:
+ Basque
+ Belarusian
+ Brazilian Portuguese
+ Bulgarian
+ Galician
+ Hebrew
+ Lithuanian
+ Persian
+ Punjabi
+ Serbian
+ Simplified Chinese
+ Slovenian
+ Telugu
+ Traditional Chinese
+ Uyghur
+ Vietnamese
+
+
+Overview of changes from GLib 2.31.16 to 2.31.18
+================================================
+
+* GDBusProxy has now a flag, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
+  which can be set to make GDBus automatically reload
+  changed properties even if the propertychanged signal
+  does not contain the new values.
+
+* GApplication puts non-unique applications on the bus
+
+* GApplication now has g_application_quit()
+
+* g_async_queue_timed_pop has been deprecated in favor of
+  the new g_async_queue_timeout_pop, which uses relative
+  delays in microseconds instead of a GTimeVal.
+
+* a huge number of API documentation fixes
+
+* Bugs fixed:
+ 647986 put non-unique apps on D-Bus
+ 658484 vpn connection vs NetworkSecretDialog
+ 664237 GDateTime falls back to UTC if TZ is set
+ 669329 gthread-win32: update for g_get_monotonic_time() changes
+ 669330 glocalfile: fix error code when opening a directory on win32
+ 669372 glib/tests memory leaks.
+ 669412 mem leak in g_environ_unsetenv
+ 669538 Fix compilation of glib-compile-resources.c on Windows
+ 669544 gdbus-codegen example introspection XML is not complete
+ 669595 glib-mkenums: fix handling of forward enum declarations
+ 669670 gasyncqueue: don't use deprecated g_cond_timed_wait()
+ 669671 gobject: use #pragmas to avoid deprecated function warnings
+ 669689 Retrieve cwd and environ in local GApplicationCommandLine
+ 669810 socket/win32: flush pending read before signaling HUP
+ 669865 g_regex_fetch()
+ 670085 memory leak in g_output_stream_write_async
+ 670138 gbytes.h is missing the G_BEGIN/END_DECL guards
+ 670485 Simplify session API (shared bug with gtk+)
+
+* Updated translations:
+ Belarusian
+ Danish
+ Galician
+ Serbian
+ Telugu
+ Hebrew
+
+
+Overview of changes from GLib 2.31.14 to 2.31.16
+================================================
+
+* GResource:
+ - The resource compiler can now convert pngs into
+   pixel data that can be used without parsing at runtime
+   (requires gdk-pixbuf-pixdata to be present)
+
+* Bugs fixed:
+ 669123 resource compiler: failing to-pixdata should...
+ 669173 resource: fix xml preprocess entity handling
+ 669224 Cross-compilation broken by data-to-c
+ 669253 gsettings set buggy on array values
+ 669334 fix memory leak in bookmark file parser
+
+* Translation updates:
+ Norwegian bokmål
+ Spanish
+
+
+Overview of changes from GLib 2.31.12 to 2.31.14
+================================================
+
+* GResource:
+ - GLib now includes a commandline utility, gresource,
+   to explore resources in ELF files
+ - The resource compiler can now optionally strip
+   ignorable whitespace from XML resources
+ - The resource compiler can now generate build dependencies
+ - The resource compiler will now autoselect output formats
+
+* GApplication:
+ - The menu markup parser API has been dropped, the
+   menu XML support lives in GTK+ now
+
+* GValueArray has been deprecated
+
+* Bugs fixed:
+ 626258 N-ary Trees - 'nodes' can be inserted before and after...
+ 634232 Core Dump / Aborted using g_key_file_to_data
+ 639099 schema compiler chokes on valid schema
+ 667228 Deprecate GValueArray
+ 667243 Add an element clear function to GArray
+ 667929 glib-compile-resources: xml resources doesn't need to...
+ 668250 g_date_time_format() produces a non-UTF8 string
+ 668468 'IP_ADD_SOURCE_MEMBERSHIP' undeclared
+ 668532 resources: add dependency generator to the resource compiler
+ 668539 resources: compiler should autoselect output format...
+ 668561 gresource-tool not internationalized
+ 668572 glib_cv_g_atomic_lock_free config.cache setting not honored...
+ 668650 GRealArray->clear_func should be initialized
+ 668756 GKeyFile: allow loading from empty strings
+ 668857 fix couple of typos in comments
+ 669024 goption: implement platform_get_argv0() for OpenBSD
+
+* Updated translations:
+ Galician
+ Norwegian bokmål
+ Spanish
+ Traditional Chinese
+
+Overview of changes from GLib 2.31.10 to 2.31.12
+================================================
+
+* GApplication:
+ - Drop support for exporting menus - this functionality
+   will be provided in GtkApplication
+ - Add a way to create actions that change settings
+
+* Bugs fixed:
+ 629503 Add async versions of g_unix_connection_{receive,send}_credentials
+ 656301 glib-compile-schemas should not create an empty file
+ 668071 mingw-gcc build fails on gio/gsocket.[c|h]
+ 668118 the big appmenu switcheroo
+ 668158 base64 encode and line termination
+ 668163 GDBusConnection: note that exit-on-close is sometimes TRUE
+ 668269 gsignal: add g_signal_handlers_disconnect_by_data
+ 668279 create GAction from GSettings
+
+* Translation updates:
+ Norwegian bokmål
+
+
+Overview of changes from GLib 2.31.8 to 2.31.10
+===============================================
+
+* GResource:
+ - A new facility to allow linking data files into binaries
+   and make them available as resources
+ - Resources are compiled using glib-compile-resources
+ - GIO supports resource:/// uris to access resources
+
+* Bugs fixed:
+ 619126 Missing dependency libs
+ 658315 g_key_file_get_keys() should set length to 0...
+ 660371 is it ever valid to have 0 as a GError domain?
+ 666700 Add some missing (allow-none) annotations
+ 667375 GAsyncInitable subclassing (and async subclassing...
+ 667447 Missing many introspection annotations
+ 667790 Protect call to pthread_condattr_setclock with define
+ 667938 wrong gtypes generated for empty flags enums
+
+* Translation updates:
+ Hebrew
+ Spanish
+
+
+Overview of changes from GLib 2.31.6 to 2.31.8
+==============================================
+
+* GObject:
+ - The type checks for overriding properties have been loosened.
+   In particular, it is now possible to add the CONSTRUCT flag
+   to an overridden property
+ - GWeakRef is a new API for weak references; unlike g_object_weak_ref
+   and g_object_add_weak_pointer, it is thread-safe.
+
+* GHashTable has grown new convenience api for use as a set:
+  g_hash_table_add, g_hash_table_contains
+
+* GSocketConnection has gained API for managing connection status
+
+* GSettings: a native OS X backend has been added, under the
+  name 'nexstep'
+
+* Bugs fixed
+ 455640 Something fishy with GRegex and unicode
+ 548954 weak references are not threadsafe
+ 625751 Add G_FILE_ATTRIBUTE_FILESYSTEM_USED
+ 658871 gbacktrace: g_get_prgname () isn't called for a NULL argu...
+ 664069 gvariant: Never break out of g_variant_iter_loop
+ 664830 g_strescape doesn't natively handle \v (vertical tab)
+ 665211 GDBusConnection singleton access can race with disposal
+ 665805 Add GSocketClient::action, for tracking socket client status
+ 666116 some tests provoke undefined behaviour, which is undesira...
+ 666422 Unreachable code in gio gnetworkmonitornetlink.c
+ 666551 Crash in g_thread_xp_SleepConditionVariableSRW
+ 666595 menu parser disallows id='' on submenu and section
+ 666615 loosen property override flag restrictions
+ 666616 gobject: fix property override type checks
+ 666803 g_utf8_validate() fails to validate strings with known size
+ 666804 g_ateaxit deprecation warning in devhelp points in wrong ...
+ 666951 g_mkdtemp: Since version incorrect in docs
+ 666978 Fails to compile glib applications with ISO C90 compiler
+ 667098 ginetaddressmask leaks its address property
+ 667225 GSocket: add missing type checks to public methods
+ 667226 GSocket: fix an error return value
+ 667279 Sometimes crashes when launching commandline-crea...
+ 667285 Wrong keyname listed in documentation for g_deskt...
+ 667331 Use g_queue_free_full() convenience function
+ 667420 GHashTable GDB pretty printing is broken
+
+* Updated translations
+ Belarusian
+ Bulgarian
+ Hebrew
+ Norwegian bokmål
+ Norwegian Nynorsk
+ Spanish
+ Vietnamese
+
+
+Overview of changes from GLib 2.31.4 to 2.31.6
+==============================================
+
+* GApplication no longer has APIs for setting menus.  Those have been
+  moved to GtkApplication.
+
+* the GActionGroup import/export functionality has been decoupled from
+  GApplication by the introduction of a new interface for the purpose of
+  handling platform data: GRemoteActionGroup.  This allows Gtk to
+  properly deal with platform data (and gdk threads) on window actions.
+
+* lots of documentation improvements
+
+* bug fixes and a huge number of memory leak fixes
+
+* the test suite now passes on ARM and some of the GDBus testcase hangs
+  we've been seeing have been resolved (although others could remain)
+
+* g_bytes_get_data() API changed: now includes 'size' out parameter
+
+* new g_queue_free_full() API similar to g_[s]list_free_full()
+
+* desktop files: use standard "Keywords" now, not "X-GNOME-Keywords"
+
+* gsettings commandline tool now has --schemadir option for schemas not
+  installed in the usual place (ie: as part of plugins)
+
+* Bugs fixed:
+ 643736 GApplication doesn't emit dbus signals on action updates
+ 657433 g_queue_free_full() missing
+ 664699 glib: documentation fixes
+ 665737 acquire/release gdk threads lock on incoming dbus
+ 665879 GBytes: add a size argument to g_bytes_get_data
+ 666113 various leaks in GLib, GIO are visible in the regression tests
+ 666115 various tests leak memory, obscuring real leaks in the library
+ 666145 Doc could be more explicite that g_thread_init calls can be droped
+ 666173 Configure warning - linux/netlink.h usability... no
+ 666296 Race condition in g_thread_xp_get_srwlock
+ 666415 Settings tools should allow specifying a schema directory 
+
+* Translations updated:
+ French
+ Spanish
+
+Overview of changes from GLib 2.31.2 to 2.31.4
+==============================================
+
+* EXPERIMENTAL: Menu support has been added to GApplication.  Menus
+  are exported on the bus, alongside the actions that are already there.
+  There have also been many related improvements to action group
+  functionality.
+
+  These new APIs are subject to changes in the coming releases.  In
+  particular, it seems somewhat likely that the APIs for registering
+  menubars may change in order to accommodate windows with different
+  types of menubars.
+
+* GDBusConnection previously directly dispatched destroy notifies when
+  unregistering objects if the current main context was the same context
+  the object was exported on.  It now unconditionally dispatches these
+  through an idle on the context.
+
+* Clean up Requires in pc files. Linking against GIO no
+  longer drags in gmodule. This may require dependency
+  fixes here and there.
+
+* Introduce GBytes, a data type for immutable, fixed-size
+  byte sequences. This makes the pre-existing GBuffer
+  API available outside GLib
+
+* GDBusInterfaceSkeleton can now be exported on multiple
+  connections
+
+* Bugs fixed:
+ 600161 Do not use static GTypeInfo and GInterfaceInfo
+ 640077 GFileMonitor: Always send CHANGES_DONE_HINT after a move...
+ 641720 Misleading definition for local_command_line() in GApplic...
+ 648516 Little comment error and 2 useless lines of code
+ 651997 Dummy backend for gapplication
+ 652560 Test for g_ascii_strtod is failing
+ 662208 failure to initialize a GInitable should be considered...
+ 662718 GDBusInterfaceSkeleton should be able to export on multi...
+ 663291 GBytes: Immutable, refcounted sequence of bytes
+ 664406 Need context for a proper translation
+ 664455 Build fixes for GLib GIT master (2.31.x)
+ 664558 GDBusWorker.frozen has a value > 1 in a gboolean
+ 664559 sys/wait.h not available on windows
+ 664617 gdbus segfault error 4 in libgio-2.0.so.0.3102.0
+ 664635 GMemory{Out,In}putStream _async functions break sub-class...
+ 664809 Add command line option to gtester to allow skipping tests
+ 665067 cryptic assertion failure if nonsensical flag combinations...
+ 665184 Check ref. count before reffing/unreffing
+ 665298 Add 'Requires.private: libpcre' to glib-2.0.pc
+ 665391 update documentation around mainloops
+ 665607 ./configure is there for fiddling with cross-compile enviro...
+ 665634 g_dbus_node_info_new_for_xml() errors on unknown attributes...
+ 665685 Add a #define for the max length of a Unicode decomposition
+ 665733 GDBusConnection holds lock while calling destroynotify
+
+* Translation updates:
+ Norwegian bokmål
+ Spanish
+
+
+Overview of changes from GLib 2.31.0 to 2.31.2
+==============================================
+
+* Monotonic time is now properly supported on Windows
+
+* glib-mkenums: fix @ENUMPREFIX@ with /*< underscore_name=... >*/
+
+* EXPERIMENTAL: introduce new GSettingsSchema and GSettingsSchemaSource
+  APIs for the convenience of plugin system authors and those who wish
+  to introspect the contents of schemas.  This API may change.
+
+* Improve the performance of GObject property notifies.
+
+* GDBus:
+ - fix a race when unowning a name immediately after owning it
+ - thread safety improvements on GDBusConnection
+ - fixes for exit-on-close functionality
+
+* Deprecations:
+ - add G_SIGNAL_DEPRECATED
+ - don't use G_DISABLE_DEPRECATED masking for functions anymore
+
+* docs
+ - tmpl/ is finally dead for glib
+
+* GIO:
+ - GInetAddressMask: new type for internet address range matching
+ - various GIO file and stream fixes
+ - improvements to attribute and fileinfo handling
+
+Overview of changes from GLib 2.29/2.30 to 2.31.0
+=================================================
+
+This release contains a huge number of changes (500 commits worth).  The
+list below attempts to summarise, but not every change is listed.
+
+* Major changes to threading and synchronisation
+ - threading is now always enabled in GLib
+ - support for custom thread implementations (including our own internal
+   support for errorcheck mutexes) has been removed
+ - a whole lot of dead code (to deal with the non-threaded case) has
+   been ripped out.  This includes the racy path of GMainContext that
+   caused deadlocks with respect to child process exits in
+   single-threaded programs (such as gtester).
+ - libgthread is now an empty shell and g_thread_init() is no longer
+   required (and has been deprecated)
+ - GMutex and GCond can now be statically allocated without explicit
+   initialisation.  Dynamic allocation for these types is deprecated.
+ - new types GRecMutex and GRWLock can also be statically allocated
+   without explicit initialisation.
+ - GPrivate can now be statically allocated and has an improved API.
+   Dynamic allocation of GPrivate is deprecated.
+ - GStaticMutex, GStaticRecMutex, GStaticRwLock, GStaticPrivate are
+   deprecated.
+ - GCond now uses monotonic time internally and a new API takes
+   monotonic time for timed waits, deprecating the wallclock API
+ - removal of the insane macro indirection used in the previous
+   implementation of threading and synchronisation APIs
+ - use SRWLock and CONDITION_VARIABLE APIs when available on Windows
+   (Vista and later) and emulate them on XP
+ - leaks of G(Static)Private-allocated data on some cases of thread exit
+   have been fixed
+ - simplified new thread creation API with the old API deprecated.  The
+   concept of joinability has disappeared (all threads are joinable) as
+   have priority levels, 'bound'ness (ie: kernel vs. userspace threads)
+   and ability to manipulate the stack size.
+ - GThread is now a refcounted type
+ - other implementation details changed
+
+* Move headers for some deprecated functionality to a separate
+  deprecated/ directory.
+
+* New support for attribute-based deprecations to issue compiler
+  warnings instead of breaking the build and/or giving warnings about
+  implicit declarations (and possibly miscompiling).
+
+* GCache has been deprecated (after its last use was removed from our
+  platform over a year ago).
+
+* It is no longer possible to include individual headers (like
+  "ghash.h") -- you must #include <glib.h>.
+
+* The misguided experiment of allowing the program to stumble along with
+  missing GSettings schemas is now over -- the abort is back.
+
+* Clarify that fork() is not valid while using GMainContext.  This is
+  because the internal resources of the GMainContext end up being shared
+  by both processes.  We had an assert here but it was breaking existing
+  (valid) use cases as well, so it has been removed for now.
+
+* GApplication
+  - add ::shutdown signal as logical dual to ::startup
+  - don't use a GMainLoop: iterate the GMainContext directly (improves
+    quit logic)
+
+* Several portability fixes for Windows, OpenBSD, Solaris
+
+* Add new GValue API to specifically deal in signed chars (in case the
+  platform defines 'char' as unsigned)
+
+* some new API to mitigate the problems associated with calling setenv()
+  in a multi-threaded program
+
+* Use CLOCK_MONOTONIC unconditionally if the libc has support at compile
+  time (ie: stop checking for kernel support at runtime).
+
+* pkg-config files:
+  - drop -uninstalled variants
+  - remove gobject dependency on gthread
+
+* New macro G_ATOMIC_LOCK_FREE is defined if the atomic operations are
+  implemented without use of a mutex.  Cleaned up atomic-related
+  compilation issues with mingw compilers on win32 systems.
+
+* SOCKS proxy and resolver improvements
+
+* Fix the spelling of G_IO_FLAG_IS_WRITABLE (was WRITEABLE) and
+  introduce a macro for backwards compatibility.
+
+* GDBus:
+  - many code generation updates and improvements
+  - some race condition fixes, including testcase hangs
+
+* GVariant:
+  - new g_variant_new_from_fixed_array() API
+  - substantial docs improvements/clarifications
+
+* GKeyFile is now refcounted and boxed
+
+* mount monitoring is now based on /proc/mounts (where available)
+  instead of mtab
+
+* new macros G_SOURCE_CONTINUE and G_SOURCE_REMOVE for returning from
+  GSourceFunc (so you don't have to remember what TRUE and FALSE mean)
+
+* use xlocale functions where available to avoid too much heavy lifting
+  in functions like g_ascii_strtod()
+
+* GMappedFile can now be created from an fd
+
+* error message strings grammar/i18n fixes
+
+* many docs updates
+
+* Partial list of bugs closed:
+ 70598  Unify GStaticMutex and GMutex.
+ 320888 optimization for g_main_context_wakeup
+ 398418 GChildWatch race condition?
+ 527214 g_timer_elapsed() returns random values
+ 580505 add a way to set/get name for a thread
+ 583511 race condition means g_main_loop_quit() does not work
+ 590808 GKeyFile should have a refcount and a boxed type in GObject
+ 592715 Document that g_str_hash() and g_int_hash() are not NULL safe
+ 631413 Add macros for GSourceFunc return values
+ 632049 not immediately clear what g_variant_get_fixed_array expects
+ 640212 "Error stating file" is not a friendly message
+ 640293 Use xlocale functions to implement g_ascii_strtod()
+ 640975 Check that error exists before trying to set it
+ 643934 GApplication lacking a logical dual for the ::startup signal
+ 651268 assertion failed in GDBus worker thread
+ 653987 g_key_file_get_integer cannot interpret trailing spaces
+ 654412 Documentation for g_variant_get_child_value unclear
+ 654563 info capplet: Failed to calculate disk space
+ 655366 missing GSettings schemas lead to obscure crashes
+ 656621 g_spawn_*() calls executables in current directory
+ 656679 [gi] Add two annotations to gio
+ 657992 Add glib__private__() API to share between glib,gio
+ 658188 _set_as_last_used_for_type generates a broken mimeapps.list
+ 658206 gsocks5proxy.c has invalid gettext use
+ 658207 glib-compile-schemas says "can not"
+ 658558 simpleaction: Fix documentation of :enabled
+ 658683 clean up charset/language threading issues
+ 658692 add introspection annotations to g_time_val_from_iso8601()
+ 658715 Duplicite strings
+ 658769 Invalid reuse of GError in GThreadedResolver
+ 658806 sign error in string hash implementation
+ 658976 gdbus-codegen's C namespace option needs to support Ugly_Case
+ 659070 gdbus-codegen generated code segfaults when property changes
+ 659082 gdbus-codegen: Single letter namespaces get dropped from names
+ 659212 GMappedFile should fail on non-regular files
+ 659324 _SPLICE_CLOSE_TARGET doesn't mark the output stream as closed
+ 659423 Use adaptive mutexes when available
+ 659427 Move deprecated code to a separate directory
+ 659646 gdbus-codegen produce code that warnings at build
+ 659690 Possible build warning in code generated by gdbus-codegen
+ 659699 property name collision when generating code for "Connection"
+ 659754 Add API to GMappedFile that allows to pass FD
+ 659838 incorrect types in introspection for g_object_bind_property
+ 659866 pthread_rwlock_t requires defined __USE_UNIX98
+ 659870 gvalue: Fix signedness of g_value_get_char()
+ 659889 glib-2.29.92/gio-2.0.pc.in has a wrong line.
+ 659916 GObject size of 64K is not actively enforced
+ 659920 Missing setter for read/write property 'closed' of GIOStream
+ 659923 Add g_variant_new_fixed_array() function
+ 660013 Remove old g_atomic configure cruft
+ 660096 glib/rwlock tests failure (tests asserted)
+ 660130 Possible loss of user data when updating mimeapps.list
+ 660147 tracker causes g_critical in "gsettings list-recursively"
+ 660413 Make G_ASSERT_STATIC work with clang
+ 660498 Generated test code fails when the codegen changes
+ 660511 Use /proc/mounts for monitoring mounts, not /etc/mtab
+ 660536 Expose options for /etc/fstab entries
+ 660635 Deprecate g_thread_foreach
+ 660637 Pending dbus method calls not canceled on connection loss
+ 660739 kill off g_{mutex,cond}_{new,free}()
+ 660740 make GThread more standard
+ 660741 g_cond_timedwait is a disaster
+ 660743 macro wrappers for g_once_init_enter/leave
+ 660744 finish killing g_thread_init()
+ 660745 GPrivate leaks on Windows
+ 660791 [gio] Improve doc for g_file_make_directory_with_parents()
+ 660843 asyncqueue-test is broken
+ 660849 Remove cruft from g_strerror and g_strsignal
+ 660886 GDBusProxy: don't drop/complain about unknown props/signals
+ 660887 g_slice_set_config() is broken
+ 660994 Add g_main_context_ref_thread_default()
+ 661255 gio: enable test_peer regression test for OpenBSD
+ 661257 giomodules.c uses ":" instead of G_SEARCHPATH_SEPARATOR_S
+ 661318 tests use pthread without appropriate compiler/linker flags
+ 661421 Applications fail to initialize on GNU Hurd - commit
+ 661438 Implement G_GNUC_DEPRECATED/G_GNUC_DEPRECATED_FOR on Visual C++
+ 661711 Sorting keys for GDrive, GVolume and GMount instances
+ 661763 desktop-app-info: Add support for X-GNOME-Keywords
+ 661896 /gdbus/connection/life-cycle is racy
+ 661914 Gstreamer/Totem locks up
+ 662100 regression: g_dbus_connection_close() triggers exit-on-close logic
+
+* Translations updates:
+ Belarusian 
+ Brazilian Portuguese
+ British English 
+ Bulgarian 
+ Catalan 
+ Catalan (Valencian)
+ Czech 
+ Danish 
+ Esperanto
+ French 
+ Gujarati
+ Hebrew 
+ Hungarian 
+ Italian 
+ Japanese
+ Lithuanian
+ Norwegian bokmål
+ Oriya
+ Polish 
+ Russian 
+ Serbian
+ Simplified Chinese
+ Slovak 
+ Slovenian
+ Spanish 
+ Tamil
+ Vietnamese
+
+Overview of changes from GLib 2.29.18 to 2.29.90
+================================================
+
+* API/ABI changes:
+ - unix signal watches now match the API of all of the other sources
+ - revert the addition of g_date_time_source_new () from last release
+
+* networking and other fixes for Solaris
+ - we no longer support symbolic port names (ie: from /etc/services)
+ - check if -lsocket is needed
+ - fix g_socket_details_from_fd()
+ - avoid getmntinfo
+ - fix some harmless warnings
+
+* GDateTime improvements:
+ - generally improved standards compliance (with C99)
+ - support C99-specified format strings: %g, %G, %V, %c, %C, %w
+ - consult the locale for the preferred 12-hour time format (%r)
+ - drop support for non-standard %N and broken %W
+ - better support for formatting non-POSIX (eg: Arabic) numerals
+ - locale-related test case fixups, and fix some leaks
+
+* GTlsInteraction: add interaction method invocation guarantees
+
+* gdbus-codegen: post-process all interfaces when parsing >1 file
+
+* make GMainLoop, GMainContext and GSource boxed types
+
+* fix a race condition in the first use of g_get_monotonic_time()
+
+* lots gtk-doc cleanups
+
+* better intltool compatibility when generating pot file
+
+* avoid GCC-specific compiler options when not using GCC
+
+* Translation updates:
+ Belarusian
+ Brazilian Portuguese
+ Canadian English
+ Galician
+ Indonesian
+ Korean
+ Lithuanian
+ Norwegian bokmål
+ Portuguese
+ Spanish
+ Swedish
+
+Overview of changes from GLib 2.29.16 to 2.29.18
+================================================
+
+* GDateTime is now respecting LC_TIME when formatting
+
+* GTimeZoneMonitor has been removed again
+
+* A new API for wallclock functionality has been added:
+  g_date_time_source_new(). This API is still experimental
+  and may be changed or removed before 2.30.
+
+* Bugs fixed:
+ 628904 Add credential support for FreeBSD and fix a socket issue
+ 650763 gdbus-codegen is broken with python 2.7
+ 655129 GDateTime could provide api for implementing wall clocks
+ 656341 gtlsconsoleinteraction.c uses getpass() which isn't avail...
+ 656387 GCancellable can be used concurrently
+ 656443 Make GTlsInteraction ask_password cancellable
+ 656675 void functions should not return in glib 2.29.16
+ 656772 g_variant_compare for uint64 incorrect
+ 656914 Load GIO_EXTRA_MODULES first, and ignore duplicates
+ 657083 The header langinfo.h is not available on all systems
+ 657084 gfileutils: fix docs/annotations for temp file methods
+ 657138 Some files missing in POTFILES.in
+ 657206 GInputStream leaked in g_file_icon_load_async()
+ 657243 g_cancellable_set_error_if_cancelled() documentation
+ 657274 Use detected PYTHON variable as shebang for gdbus-codegen
+ 657336 Speling fixes for glib found with codespell
+ 657452 plural forms needed
+ 657454 Translation comment needed
+ 657540 Print out file:// URL to coverage HTML report after building
+ 657593 g_test_trap_fork calls close(-1)
+ 646082 Addresses from GSocket should be normalized before returning
+ 657517 fix gio/tests/gdbus-peer on bsd
+
+* Translation updates:
+ Brazilian Portuguese
+ Galician
+ Norwegian bokmål
+ Punjabi
+ Russian
+ Serbian
+ Spanish
+ Swedish
+ Traditional Chinese
+ Uighur
+
+
+Overview of changes from GLib 2.29.14 to 2.29.16
+================================================
+
+* GTlsDatabase: an abstract class that provides support
+  or certificate and key lookup. An implementation will
+  be provided in glib-networking
+
+* GHmac: Support or HMAC digests
+
+* Misc new API:
+ - g_ptr_array_add_full: creates a GPtrArray with
+   a preallocated size and a destroy function
+ - g_desktop_app_info_get_show_in: checks if a GDesktopAppInfo
+   should be shown in a given desktop environment
+ - g_mkdtemp, g_mkdtemp_full, g_dir_make_tmp: create
+   temporary directories
+
+* Unify thread wakeup implementations of GMainContext
+  and GCancellable, and use eventfd for it when available
+
+* Show mounts in $XDG_USER_DIR in addition to /media and $HOME
+
+* Bugs fixed:
+ 636572 GTlsCertificateDB
+ 644601 Some tests need a running dbus session
+ 652284 deal with small key lengths
+ 652827 glib-2.29.8 no longer builds with mingw.org's toolchain
+ 653063 PEM parser fails parsing private key when put first
+ 654078 Fail to static linking with Glib library
+ 654450 New functions: g_ptr_array_new_full()
+ 654793 Add G_VALUE_INIT
+ 655044 GDesktopAppInfo: Add g_desktop_app_info_get_show_in()
+ 655148 gdbusconnection is broken when compiling with mingw
+ 655241 glocalfile.c no longer compiles with MinGW GCC
+ 655598 g_cancellable_get_fd: silently return -1 for NULL cancellable
+ 655664 gdbus should not abort if no dbus session is available
+ 655769 Use ZLIB_CFLAGS when compiling gio
+ 656031 Improve GVariant annotations
+ 656048 glib-codegen requires Python >= 2.5
+ 656151 configure test logic inverted, doesn't match comments
+ 656152 GCC only syntax used, yet other compilers allowed by configure.
+ 656162 allow use of lcov 1.9 for coverage
+ 656282 GDBusProxy: uninitialized local variables can be freed
+ 656283 Failing tls connection cause assertion
+ 118563 Add g_mkdtemp in the spirit of g_mkstemp
+ 636405 Add g_return_if_fail() to g_settings_bind_with_mapping()
+ 656039 race condition between GDBusProxy signals and public API
+ 656492 g_io_channel_new_file failure (open(2) behavior wrt POSIX)
+
+* Translation updates:
+ Bulgarian
+ Esperanto
+ French
+ Galician
+ German
+ Hebrew
+ Indonesian
+ Italian
+ Norwegian bokmål
+ Russian
+ Spanish
+ Swedish
+
+
+Overview of changes from GLib 2.29.12 to 2.29.14
+================================================
+
+* Unicode improvements
+ - add g_unicode_script_{to,from}_iso15924
+ - add G_UNICODE_SPACING_MARK define
+ - more normalisation improvements
+ - stop using deprecated g_unicode_canonical_decomposition()
+
+* GParamSpec:
+ - mark the 'name' field as 'const' and add a comment to the header to
+   help avoid future problems caused by bad hacks
+
+* Merge some (modified) patches from Debian:
+ - 03_blacklist-directories.patch
+   - add some blacklisted mount directories
+ - 60_wait-longer-for-threads-to-die.patch
+   - sleep longer in a test case, if needed to avoid failing
+
+* Units policy change: prefer use of SI units
+ - deprecate g_format_size_for_display, add g_format_size(_full)
+
+* GSettings: don't call g_error() when the schema is missing
+
+* GVariant support for arrays of object paths:
+ - new g_variant_{new,get,dup}_objv API
+ - support for g_variant_{new,get} '^ao' and '^a&o' similar to '^as'
+
+* GDBus:
+ - use new improved array-of-objects support and pass 'ao' as char**
+   instead of GVariant*
+ - improve handling of 'h' type (Unix file descriptor index)
+
+* GIO:
+ - fix compilation without USE_STATFS and USE_STATVFS
+
+* Documentation fixes
+
+* Bugs fixed:
+ 622921 Migrate from dbus-glib to glib's GDBus
+ 648271 Add g_unicode_script_to_iso15924()
+ 654948 Stop using deprecated g_unicode_canonical_decomposition()
+ 654988 g_atomic_int_add should document behaviour change
+ 655025 #define G_UNICODE_SPACING_MARK G_UNICODE_COMBINING_MARK
+ 655076 normalization misses some Full_Composition_Exclusion=True. 
+
+* Translations updated:
+ Spanish
+
+Overview of changes from GLib 2.29.10 to 2.29.12
+================================================
+
+* Add new API to do Unicode (de-)composition in atomic steps,
+  for use in Harfbuzz.
+
+* Bugs fixed:
+ 615895 (indirectly) support non-NULL-terminated regexes in GRegex
+ 617949 glib trunk fails to compile on Solaris w/ Studio 12...
+ 620423 Document the possibility to unset attributes
+ 627974 Floating reference headaches
+ 644687 Not finding cross-links in current doc set
+ 649246 g_output_stream_splice() cannot be used on 32-bit machines...
+ 653841 a helper script to build glib from git master on win32
+ 653935 g_slist_free_full/g_list_free_full iterates twice in the list
+ 654017 tests: fix glib_translations_work() in gsettings unit test
+ 654085 Don't needlessly use "echo -e" when creating .def files
+ 654195 Add g_unichar_compose() and g_unichar_decompose()
+ 654232 GCancellable eventfd problems
+ 654394 suspicious use of floating references in GDBusInterfaceSkeleton
+ 654536 GSettings: lift key name length restriction to 64
+ 654627 GParamSpec: intern property names
+ 654651 Better g_unicode_canonical_decomposition()
+ 654917 Make g_cclosure_marshal_generic the default signal handler
+
+* Translation updates:
+ Belarusian
+ Finnish
+ Korean
+ Latvian
+ Lithuanian
+ Norwegian bokmål
+ Turkish
+
+
+Overview of changes from GLib 2.29.8 to 2.29.10
+===============================================
+
+* New features:
+ - g_desktop_app_info_get_nodisplay: a function that is required
+   to port gnome-menus to GDesktopAppInfo
+ - g_hash_Table_iter_replace: new function to replace a value
+   while iterating over a hash table
+ - g_utf8_substring: convenience API to extract substrings from
+   UTF-8 strings
+ - g_action_group_add_entries: convenience API for creating lots
+   of actions quickly
+ - Use eventfd instead of pipes for waking up main contexts and
+   for cancellation when available
+ - GMatchInfo is now a refcounted boxed type
+
+* API changes in GAction:
+ - the 'set_state' entry in the GActionInterface vtable has been
+   renamed to 'change_state
+ - g_action_set_state has been renamed to g_action_change_state
+ - the 'state' property has been changed to read-only
+ - GSimpleAction can no longer be subclassed
+
+* Bug fixes
+ 647796 g_variant_new_variant is not marked as constructor
+ 652072 gmain: make use of signalfd()
+ 652168 Crosscompiling Fails if build<=2.24 and host >2.24
+ 652750 make dist fails
+ 652758 GDataInputStream: Clarify g_data_input_stream_read_line docs...
+ 652822 Add a g_hash_table_iter_replace
+ 652897 tiny docs clarification for g_utf8_to_ucs4_fast
+ 653140 gmain: use Linux eventfd() for main context wake up
+ 653429 drop AM_MAINTAINER_MODE or enable it by default
+ 653484 GAsyncCallbacks should default to allow-none
+        Add missing fundamental types to the generic marshaller
+
+* Translation updates
+ Belarusian
+ Galician
+ Russian
+
+Overview of changes from GLib 2.29.6 to 2.29.8
+==============================================
+
+* Bug fixes
+ 646608 export_symbols variable for gio dynamic library is wrong
+ 646635 Fix introspection of GLib
+ 647930 Documentation: GDataInputStream _read_upto() version
+ 651745 Switch to _ prefixing rather than G_GNUC_INTERNAL
+ 651920 Improve qsort_r detection
+ 651959 gbitlock: "asm goto" is not available in gcc < 4.5
+ 651998 gdbus-codegen: Use relative Python imports
+ 652000 Fix for gatomic.c on Windows/MSVC
+ 652002 Proposal to clean up gvaluetransform.c for MSVC
+ 652025 g_dbus_connection_register_object: error is not set...
+ 652081 Typos in a GBinding warning message
+ 652197 Improper handling of double values in GDBusMessage
+        Fix a deadlock in gobject finalization
+
+* Translation updates:
+ Czech
+ Galician
+ German
+ Hebrew
+ Norwegian bokmål
+ Spanish
+ Uighur
+
+
+Overview of changes from GLib 2.29.4 to 2.29.6
+==============================================
+
+* Atomic operations have been rewritten from scratch to make use
+  of gcc builtins where possible. As a side-effect of this, calls
+  to g_atomic_ API with explicit casts may now be problematic; if
+  that happens to you, try first to remove the casts. Another
+  side-effect of the rewrite is that g_atomic_int_exchange_and_add
+  has been deprecated in favor of g_atomic_int_add.
+
+* A full set of atomic operations on pointers has been added,
+  including bit locks in pointer-size locations.
+
+* Access to quarks is now lockless
+
+* GObject data scalability has been greatly improved
+
+* g_data_time_format now supports alternative digits and padding
+
+* Introspection improvements:
+ - Add a boxed type for GVariantBuilder
+ - Annotation fixes in GDBus, GVariant, g_base64_
+
+* Bugs fixed:
+ 502560 g_rand_double_range returns 'inf'
+ 612729 g_mkdir_with_parents can fail if the directory already exists
+ 617491 g_once() implementation is inefficient
+ 619418 Add a performance test for UTF-8 decoding functions
+ 619435 Make g_utf8_to_ucs4_fast() yet faster
+ 626549 G_STATIC_ASSERT_EXPR
+ 631231 bitlock: Fix detection and usage of futexes with Bionic
+ 632294 g_queue_remove() should return a boolean
+ 640518 GMainLoop has quadratic complexity when all pollfd's...
+ 642026 Race condition in g_static_private_free
+ 646635 Fix introspection of GLib
+ 648678 g_date_time_format(): support %O flags for localized numbers
+ 649480 Use MSG_CMSG_CLOEXEC in recvmsg in gio/gsocket.c
+ 649506 GTestFunc et al lacking Since tag
+ 649657 Don't return gboolean for functions that throw
+ 649775 glib-gio-gdbuscodegen-Makefile.patch
+ 649915 gsettings accepts unquoted strings longer than two characters
+ 649973 gthread: build unix tests only on unix
+ 649988 gdbus-codegen: Drop dependency on argparse
+ 650078 forkbomb building glib/tests/protocol
+ 650211 Optimization in key file parsing
+ 650236 Application over DBus implements action state incorrectly
+ 650345 g_key_file_has_key_full: New function to fix g_key_file_has_key...
+ 650458 reduce overhead in g_object_set/get_data
+ 650459 hash table consistency while calling destroy notify funcs
+ 650688 enforce rules about hash table modification
+ 650823 expand the set of atomic ops
+ 650874 codegen chokes on docs
+ 650882 use stdout instead of stderr for informational messages
+ 650884 fix compilation with gcc2
+ 650885 implement glib credentials on OpenBSD (hackish)
+ 650935 G_GNUC_MAY_ALIAS and atomic ops
+ 651009 minor documentation fix
+ 651034 Regarding g_cond_wait after g_thread_pool_push in gthreadedresolver
+ 651133 race condition in GDBusConnection's emit_signal_instance_in_idle_cb
+ 651141 hashtable infinite loop
+ 651219 fix path to true(1) on OpenBSD
+ 651223 Fix some compile warnings on OpenBSD
+ 651327 Minor fixes for the gsocket API
+ 651467 Add pointer sized bitlocks
+ 651650 gdbus: Avoid busy wait loop
+ 651725 gmain: Cleanups and a new test case
+ 651745 Switch to _ prefixing rather than G_GNUC_INTERNAL
+
+* Updated translations:
+ Catalan (Valencian)
+ Esperanto
+ Hebrew
+ Hungarian
+ Russian
+ Spanish
+
+
+Overview of changes from GLib 2.29.2 to 2.29.4
+==============================================
+
+* GDBus:
+ - Includes several new types to support modeling D-Bus
+   objects and interfaces more fully, and also introduces
+   an 'object manager' pattern:
+   GDBusInterface, GDBusObject, GDBusObjectManager
+   These interfaces have client-side implementations:
+   GDBusProxy, GDBusObjectProxy, GDBusObjectManagerClient
+   And server-side implementations:
+   GDBusInterfaceSkeleton, GDBusObjectSkeleton, GDBusObjectManagerServer
+ - The new gdbus-codegen utility uses these new classes
+   to generate C code and documentation from D-Bus interface
+   descriptions in XML
+
+* GTest:
+ - There is now a g_test_fail() function to mark
+   tests as failed
+
+* GDesktopAppInfo
+ - Now has a binding-friendly filename property
+ - Other new API to more fully expose desktop file contents:
+   g_desktop_app_info_get_categories(),
+   g_desktop_app_info_get_generic_name()
+
+* GHashTable:
+ - Several optimizations to reduce space consumption of
+   large hash tables, in particular tables that are used
+   to store sets.
+
+* Unix-specific APIs:
+  GLib now installs a separate header, glib-unix.h, that is
+  meant to collect Unix-specific APIs. For now, it contains
+  g_unix_open_pipe(), g_unix_set_fd_non_blocking() for dealing
+  with pipes and fds, as well as APIs to create mainloop
+  sources which can trigger callbacks on certain Unix
+  signals (SIGTERM, SIGHUP, SIGINT).
+
+* Bugs fixed:
+ 631379 GDBus nonce-tcp test failing
+ 632631 GLib-CRITICAL **: g_variant_new_string: assertion `g_utf8_validate (string, -1, NULL)' failed
+ 635694 gdbus aborting due to unauthorized socket in DBUS_SESSION_BUS_ADDRESS
+ 637561 Crash when using G_DBUS_SERVER_FLAGS_RUN_IN_THREAD
+ 642935 g_date_time_format() prints wrong value for %z and timezone -0800
+ 643134 g_dbus_message_copy
+ 644941 glib-unix: New Unix-specific API
+ 646013 g_hash_table_remove_all_nodes optimization
+ 646309 glib cannot be cross-compilled for mingw32
+ 646435 GTimeZone doesn't seem to be thread-safe
+ 646957 GIO chained calls don't work with a thread default context
+ 647594 README link to mailing list is broken
+ 647602 Cannot connect to remote message bus via TCP
+ 647746 The GSocketService documentation is incomplete.
+ 647826 API: gtester: Add g_test_fail()
+ 647903 GDesktopAppInfo: Add g_desktop_app_info_get_categories()
+ 648416 g_app_info_create_from_commandline ignores SUPPORTS_STARTUP_NOTIFICATION
+ 648423 Support G_DEBUG=trap-warnings
+ 648425 GDesktopAppInfo: Add "filename" property for bindings
+ 648966 Update g_unichar_iswide and g_unichar_iswide_cjk
+
+* Updated translations
+ Norwegian bokmål
+ Spanish
+ Turkish
+ Uighur
+
+
+Overview of Changes from GLib 2.28.0 to 2.29.2
+==============================================
+
+* GApplication
+ - The documentation has been enhanced and clarified
+ - An opt-out for uniqueness has been added: G_APPLICATION_NON_UNIQUE
+ - GApplication now syncs settings before g_application_run() returns
+
+* GDBus
+ - Interface lookups are now happening in constant time
+ - Signature checking and handling of various unexpected
+   situations has been improved
+
+* GVariant
+ - The format accepted by the GVariant parser has beend documented
+ - GVariant accepts G_VARIANT_TYPE_VARDICT for a{sv}
+
+* GDateTime:
+ - The return value of g_datetime_compare() has been fixed to
+   match strcmp() semantics
+ - In order to handle problems with changing timezones, a GTimeZoneMonitor
+   has been added to GIO, and g_time_zone_refresh_local() can be
+   called to update the cached information about the local timezone
+
+* GOption now uses /proc/self/cmdline to set the program name instead
+  and only falls back to "<unknown>" if that is unavailable
+
+* GSettings:
+ - The schema compiler now warns about references to non-existing schemas
+
+* Commandline utilities are now fully translated
+
+* Signals can now indicate that collecting their arguments must
+  always happen, even in the absence of connected signal handlers,
+  using the G_SIGNAL_MUST_COLLECT flag.
+
+* Bugs fixed:
+ 635099 Memory leak in gdbus introspection when parsing xml
+ 640489 $ and ^ do not match lines if G_REGEX_MULTILINE|G_R...
+ 642042 Overriding GDBus org.freedesktop.DBus.Properties im...
+ 642052 g_timeout_add(_seconds) cannot handle large intervals
+ 642490 notify_desktop_launch() "g_variant_new_bytestring:...
+ 613269 g_type_get_qdata() doesn't work as I expected on subtypes
+ 624943 G_VALUE_NOCOPY_CONTENTS is undocumented
+ 637738 object_interface_check_properties never actually executes
+ 638185 GIOCondition should be annotated as "flags"
+ 639478 GDBusServer's g_dbus_server_new_sync() function should just...
+ 641755 Add g_settings_get/set_uint() helpers
+ 641768 dconf gsettings backend silently drops writes if it can't...
+ 642797 g_app_info_get_default_for_type() broken for subtypes
+ 642825 Unnecessary assertion failure in g_option_context_parse()
+ 642944 NULL key lookup using g_hash_table_lookup_extended()
+ 643074 Incorrect documentation for g_socket_receive() and g_socket...
+ 643197 g_application_id_is_valid docs imply no valid ids
+ 643468 GApplication docs: Warn that handling "command-line" means...
+ 643478 GApplication::local_command_line vfunc documentation seems wrong
+ 643624 Can g_variant_unref() on an already free'd variant
+ 643649 g_application_run() should say that argc/argv can be NULL
+ 643780 shouldn't need to create an action group to use actions...
+ 643795 g_timeout_add_seconds fires with intervals 1 second longer...
+ 644309 Program name is not set when using GtkApplication
+ 644428 Crash in failure section of g_markup_collect_attributes()
+ 644465 undefined reference to `_usleep'
+ 644552 g_timeout_add_seconds(1, ...) may have a latency of up to 2...
+ 644607 Correct internal definition of C_()
+ 645789 annotations for g_file_*_contents
+ 646039 g_settings_list_children() returns child that cannot be opened
+ 646310 Accept range with only min or max
+ 646420 g_dbus_method_invocation_get_parameters() docs should say...
+ 646843 occasional abort on autologin
+ 646985 add G_APPLICATION_NON_UNIQUE flag
+ 647579 gsettings: Implement reset-recursively
+ 647600 gsettings description has typo
+
+* Translation updates
+ Afrikaans
+ Bulgarian
+ Bengali India
+ British English
+ Bulgarian
+ Catalan
+ Czech
+ Danish
+ French
+ Galician
+ German
+ Greek
+ Gujarati
+ Hebrew
+ Hungarian
+ Italian
+ Japanese
+ Korean
+ Lithuanian
+ Polish
+ Portuguese
+ Romanian
+ Serbian
+ Simplified Chinese
+ Spanish
+ Swedish
+ Traditional Chinese
+ Uighur
+ Vietnamese
+
+
+Overview of Changes from GLib 2.27.93 to 2.28.0
+===============================================
+
+* Bugs fixed:
+641363 GInitable documentation isn't clear about that finalize...
+641395 Add more data about the origin application to the "Lau...
+641411 gdesktopappinfo signals lost if it's the session bus...
+641477 glib-mkenums uses unportable #! line
+641572 Add @EXEEXT@ to pkgconfig binary name
+641688 glib installs GSettings.html and gsettings.html
+
+* Translation updates:
+ Galician
+ Italian
+ Korean
+ Punjabi
+
+
+Overview of Changes from GLib 2.27.92 to 2.27.93
+================================================
+
+* Bugs fixed:
+ 637013 gio/gdbusmessage.c fails to compile on Solaris
+ 640192 Error creating a Gio.Settings object through py...
+ 640261 Minimum version for external pcre needs to be..
+ 640262 GActionGroup contains redundant TYPE macros
+ 640436 Make load_user_special_dirs() resistant to non...
+ 640695 g_key_file_load_from_file() mishandles a CR-LF...
+ 640724 can't compile gio due to format string issues
+ 640725 can't compile tests due to format string issue
+ 640807 improve GVariant behaviour with invalid pointers
+ 640823 wrong documentation for g_source_add_child_source
+
+* Translation updates:
+ Bulgarian
+ Galician
+ Hebrew
+ Norwegian bokmål
+ Spanish
+ Traditional Chinese
+
+
+Overview of Changes from GLib 2.27.91 to 2.27.92
+================================================
+
+* Update to Unicode 6.0
+
+* Update PCRE to 8.12
+
+* Bugs fixed:
+ 637696 g_unix_connection_send_fd() doesn't work
+ 638872 null settings backend bug
+ 640042 GtkApplication's warning about not connecting...
+
+* Translation updates:
+ Arabic
+ Basque
+ Estonian
+ Greek
+
+Overview of Changes from GLib 2.27.90 to 2.27.91
+================================================
+
+* Bugs fixed:
+ 638838 gdesktopappinfo: Don't crash if we don't have a desktop filename
+ 638894 Splitting on \s* gives no result
+ 639064 Update gschema.dtd
+ 639084 Copy/paste error in GSettings::writable-changed signal
+ 639177 SIGSEGV for GApplications with G_APPLICATION_IS_SERVICE
+
+* Translation updates:
+ Estonian
+ Galician
+ Indonesian
+
+
+Overview of Changes from GLib 2.27.5 to 2.27.90
+===============================================
+
+* Test reports created by gtester-report can now
+  include revision information
+
+* The g_desktop_app_info_launch_* family of functions
+  now emit a DBus signal when an application is launched.
+  Additionally, there is a new variant
+  g_desktop_app_info_launch_uris_as_manager(), which
+  gives more control over the launched process.
+
+* The memory and null GSettings backends are now available
+  as public API
+
+* g_get_locale_variants() is a new function that returns a
+  list of variants of a locale identifier
+
+* Bugs fixed:
+ 587898 I/O timeouts for GSocket
+ 606960 gio: Add extension point for informing parties...
+ 631980 Handle an optional <revision> node in the report...
+ 634569 Document that g_variant_builder_add_value consumes...
+ 635998 Make _g_compute_locale_variants public
+ 636806 Add g_{memory,null}_settings_backend_get_default
+ 637262 Need a binary DER version of ::accepted-cas
+ 637544 Skip fsync() on btrfs
+ 637720 void functions should not return a value.
+ 637738 object_interface_check_properties never actually...
+ 637759 GIOChannel: fix a crash in g_io_channel_read_chars()
+ 637852 Updates to glib.vsprops file for MSVC 2008 builds...
+ 637858 Updates to test/testglib.c...
+ 638349 parameter name of g_variant_new_* may conflict...
+
+* Translation updates:
+ Hebrew
+ Norwegian bokmål
+ Simplified Chinese
+ Spanish
+ Swedish
+ Uyghur
+ Vietnamese
+
+
+Overview of Changes from GLib 2.27.4 to 2.27.5
+==============================================
+
+* Network support:
+ - Add g_tls_certificate_verify() to verify a certificate
+ - Add GTlsConnection:use-system-certdb
+ - Other TLS api additions
+
+* GIO:
+ - Add g_io_stream_splice_async()/_finish() to splice two iostreams
+ - Add g_emblemed_icon_clear_emblems() and make GEmblemedIcon derivable
+ - Remove GPeriodic; it did not receive the necessary review and
+   integration work to declare it stable
+
+* GSequence:
+ - New methods g_sequence_lookup() and g_sequence_lookup_iter()
+
+* Bugs fixed:
+ 617254 Missing g_sequence_lookup
+ 632544 g_dbus_connection_send_message can not send a locked message...
+ 633350 g_hostname_to_ascii() ignores non-ascii dots
+ 634583 Better error reporting for g_variant_parse()
+ 635007 gsetting enum rule don't work for out-of-srcdir builds
+ 635626 GDBus message idle can execute while flushes are pending
+ 636100 Can't read GSettings:backend property
+ 636305 Typo on g_queue_remove_all() function description
+ 636311 appinfo: tweak application positioning for content-types
+ 636351 g_simple_async_result_is_valid lacks a version tag
+ 636387 gdb autoload files shadow the "dir" builtin
+ 636673 g_simple_async_report_error_in_idle should allow object...
+ 637147 Add a "delay-apply" property to GSettings
+ 637171 emblemedicon: add g_emblemed_icon_clear_emblems()
+ 637237 gapplication: plug a memory leak
+
+* Translation updates:
+ Estonian
+ Galician
+ Hebrew
+ Norwegian bokmål
+ Simplified Chinese
+ Spanish
+ Traditional Chinese
+ Vietnamese
+
+
+Overview of Changes from GLib 2.27.3 to 2.27.4
+==============================================
+
+* GIO
+ - Mounts are treated as hidden if they have a path element
+   that starts with a dot
+ - GAppInfo gained API to differentiate between recommended
+   and fallback mime handlers
+ - g_cancellable_create_source: creates a GSource that triggers
+   when the GCancellable is canceled
+ - GPollableInput/OutputStream: Interfaces for pollable streams
+ - TLS support has landed, with an extension point that is
+   implemented in glib-networking
+
+* GLib
+ - Mainloop sources can now have 'child sources'
+ - g_get_runtime_dir: New function to return the XDG_RUNTIME_DIR
+
+* Bugs fixed:
+ 530786 GFileMonitor "changed" signal underdocumented
+ 588189 TLS support for GSocket*
+ 630357 g_object_new_valist uses uninitialized memory
+ 630559 typo in public string in gsocks: 'The SOCKSv5 require...
+ 632445 Documentation refers to removed GNOME 2.0 porting guide
+ 634239 Child GSources
+ 634241 Add pollable input/output streams
+ 634504 allow passing a NULL emblem to g_emblemed_icon_new()
+ 634613 unsufficient g_get_user_runtime_dir() documentation
+ 635640 schema should inherit gettext-domain from schemalist
+ 635768 Protect g_file_monitor_set_rate_limit() against negative...
+ 635882 Fix the wrong-category schema test
+ 635187 Wrong type of GVariant received in an action...
+
+* Updated translations:
+ Galician
+ Italian
+ Norwegian bokmål
+ Uyghur
+
+
+Overview of Changes from GLib 2.27.2 to 2.27.3
+==============================================
+
+* The GTimeSpec type that was introduced in the 2.27.2 has been
+  dropped again in favour of APIs that return microseconds as
+  64-bit integer.
+  Affected functions:
+  g_source_get_time
+  g_periodic_unblock
+  g_get_monotonic_time
+  g_get_real_time
+  The similar GTimeVal struct is still around, but its use is
+  discouraged.
+
+* GTimer is now using monotonic time unconditionally
+
+* There are some new functions to facilitate error reporting
+  in async GIO APIs:
+  g_simple_async_result_take_error
+  g_simple_async_result_new_take_error
+  g_simple_async_report_take_gerror_in_idle
+
+* There is new convenience API to us GVariant dictionaries:
+  g_variant_lookup
+
+* It is now possible to delay sending match rules to the
+  D-Bus daemon in GDBus:
+  G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE
+
+* Support has been added for XDG_RUNTIME_DIR:
+  g_get_user_runtime_dir
+
+* Various fixes for Win64/MSVC builds have been committed
+
+* Bugs fixed:
+ 620263 Add g_clear_object, g_clear_pointer, g_clear_boxed
+ 633075 update Project Files and sources for MSVC 2008/C89
+ 633381 gsettings Makefile rules should handle empty list...
+ 633685 Use g_simple_async_result_{new_,}take_error
+ 633686 Add g_simple_async_report_take_gerror_in_idle
+
+* Translation updates:
+  Belarusian
+  Galician
+  Hebrew
+  Punjabi
+  Spanish
+
+
+Overview of Changes from GLib 2.27.1 to 2.27.2
+==============================================
+
+* GApplication
+ - Export actions over DBus and support activating them from remote instances
+ - Support environment passing
+
+* GSettings
+ - The gsettings utility has a list-recursively command
+ - The gsettings utility has commandline completion for enum values
+
+* GLib is now linked against librt and uses monotonic time for
+  timeouts and GPeriod sources. GSource has a new g_source_get_time()
+  which returns monotonic time, and g_source_get_current_time() has
+  been deprecated
+
+* Bugs fixed:
+ 158725 free linked list with data
+ 626320 GVariant: Avoid locking in g_variant_get_child_value() if possible
+ 629247 add gsimpleasyncresult methods to take over a GError
+ 629274 GNetworkService does not do fallback when there is no SRV record
+ 631264 gsettings-tool choice/range support
+ 631482 g_date_time_from_instant: 1000000000000000000
+ 632169 docs for manual use of gsettings-data-convert
+ 632571 Add equivalent to gconftool-2's -R option
+ 633115 GSettings m4 doesn't fail the build for broken schemas
+ 633206 Default g_application_local_command_line() doesn't set exit_status...
+ 633339 support more complex gapplication setups
+ 633356 Make timeout G_MAXINT mean "no timeout"
+
+* Translation updates:
+ Catalan (Valencian)
+ Indonesian
+ Japanese
+
+
+Overview of Changes from GLib 2.27.0 to 2.27.1
+==============================================
+
+* GDateTime now has full week number support.
+  New API: g_date_time_get_week_numbering_year
+
+* The GSettings schema compiler will now skip over
+  broken .xml schema files instead of aborting altogether
+
+* GSettings now works properly on bigendian systems
+
+* GSettings has more complete support for ranges
+  New API:
+    g_settings_get_range
+    g_settings_range_check
+  The gsettings commandline tool supports ranges too.
+
+* GApplication has been rewritten; see the API docs for details
+  and examples. The action support is not complete yet.
+
+* The GLib mainloop has gained 'dispatch to context' functionality,
+  which can replace manually created idles in many cases.
+  New API:
+    g_main_context_invoke
+    g_main_context_invoke_full
+
+* The gio-desktop-app-info-lookup extension point has been
+  removed from GIO. GIO now uses x-scheme-handler mimetypes when
+  looking for default applications.
+
+* On win32, make g_get_user_data_dir() return the CSIDL_LOCAL_APPDATA
+  folder on Windows, and not CSIDL_PERSONAL. This matches what Qt does,
+  and has been widely requested. Also make g_get_user_config_dir() return
+  this and not the (roaming) CSIDL_APPDATA folder.
+
+* A periodic event clock has been added in GIO: GPeriodic. Note that this
+  API is still experimental and expected to undergo changes before it
+  will be incorporated into a stable GLib release. Use at your own risk.
+
+Bug fixes:
+ 613822 gobject signal connect/disconnect not thread safe
+ 618737 "dispatch to context" functionality
+ 620710 g_get_user_data_dir() uses CSIDL_PERSONAL and not CSIDL_APPDATA
+ 623400 acquire context before dispatching
+ 627126 gsettings schema files don't get installed on FreeBSD
+ 627171 g_socket_new_from_fd() doesn't set the right protocol
+ 628876 Wrong error description
+ 628937 gracefully handle broken schemas
+ 629274 GNetworkService doesn't fallback when there is no SRV record
+ 629289 g_error() used wrong, produces core dump
+ 629687 leaks class refcount in gsocketcontrolmessage
+ 629849 GLib-CRITICAL **: g_source_get_context: assertion `!SOURCE_...
+ 629945 GDBus deadlock in g_bus_get_sync()
+ 630000 g_date_time_difference
+ 630077 GDateTime week number support
+ 630185 Allow NULL strings in g_quark_try_string()
+ 630797 docs mention non-existent g_object_dispose()
+ 630968 gschema-compile problems on power g5
+ 631263 GSettings needs range/choice APIs
+ 631264 gsettings-tool choice/range support
+ 631379 GDBus nonce-tcp test failing
+ 631410 Port gapplookupgconf.c to using x-scheme-handler/
+ 632884 Possible deadlock in g_object_remove_toggle_ref()
+
+Transation updates:
+ Basque
+ Brazilian Portuguese
+ British English
+ Bulgarian
+ Czech
+ Dutch
+ Estonian
+ French
+ Galician
+ German
+ Greek
+ Hebrew
+ Hungarian
+ Japanese
+ Lithuanian
+ Polish
+ Portuguese
+ Romanian
+ Simplified Chinese
+ Slovenian
+ Spanish
+
+
+Overview of Changes from GLib 2.25.15 to GLib 2.27.0
+====================================================
+
+Build:
+  - massive restructuring to reduce #include abuse
+  - tweaks to silence some harmless compiler warnings
+  - rename gschema-compile.c to glib-compile-schemas.c
+  - Windows fixes
+  - fix building with zlib < 1.2.4 on win32
+
+GDateTime:
+  - better msgctxt for translating month and weekday names
+  - API is changed quite a lot, implementation is improved
+  - GTimeZone is now exposed
+
+GObject:
+  - make ordering for overridden interface properties consistent
+  - ->priv structures are limited to 64k but this was not documented,
+    and exceeding this limit produced bad results.  Add docs and enforce
+    the limit properly.
+  - add g_object_class_install_properties() to install multiple
+    properties in one go
+  - improve debugging output for GValue containing G_TYPE_STRV
+
+GIO:
+  - fix priority sorting of GIO extensions
+  - add GCredentials support on FreeBSD
+  - fix support for IPv6 addresses in URI parsing functions
+  - GSocketClient fixes for when g_socket_connect succeeds immediately
+  - clarify string encoding for GFile constructors in docs
+  - new functions g_data_input_stream_read_upto{,async,finish}
+  - tweak confusing documentation for g_output_stream_write()
+
+GDBus:
+  - GDBusMessage can now be locked and copied (like in libdbus)
+  - GDBusConnection filter function API has changed again
+  - GDBusServer: ::new-connection now declares if the connection was claimed
+  - add a partial workaround for GObject bug 627724.
+  - very many memory leaks fixed
+
+GVariant:
+  - check for size == 0 in g_variant_get_bytestring to avoid a crash
+    when attempting to get_bytestring() from an empty array
+  - improve gobject-introspection annotations
+
+GSettings:
+  - add GSettings Windows registry backend
+  - some internal tweaks to the backend API
+  - remove g_settings_list_items
+  - add g_settings_list_children and _list_keys to replace it
+  - add schema compiler restrictions for dealing with lists
+  - don't automatically emit value changed signals on writability
+    changes
+
+Other:
+  - constify the 'parser' vtable param to g_markup_parse_context_push()
+  - plug many memory leaks in test cases
+
+Bugs closed:
+  50076 Time API to go with date API
+ 584284 g_data_input_stream_read_until_async different from sync version
+ 624546 Modification of GDBusMessage in filter function
+ 626919 Let g_object_class_install_property() return the installed GParamSpec*
+ 628029 GDateTime missing get_week_of_year method
+ 628253 Interface properties not listed in a consistent order
+ 628331 Plug lots of mem leaks in gio test suite
+ 628345 Plug a mem leak
+ 628436 Plug a mem leak
+ 628505 Fix building with zlib < 1.2.4 on win32
+ 628839 [PATCH] datetime: Rename shadowing variables
+ 628904 [PATCH] Add credential support for FreeBSD and fix a socket issue
+ 628952 incorrect glib_major_version and other variables on cygwin.
+ 629192 g_strdup_value_contents(): dump GStrv more usefully
+ 629251 g_socket_client_async_connect_complete: assertion failed
+ 629259 Failed to connect to "::1"
+ 629328 g_markup_parse_context_push doesn't respect const structs
+ 629429 month "May" short and full form same with "GDateTime" msgctxt
+ 629689 GDBusConnection leaks its GCredentials
+ 629698 Segfault in g_variant_get_bytestring() 
+
+Updated translations:
+  Arabic
+  Armenian
+  Basque
+  British English
+  Czech
+  Finnish
+  Galician
+  German
+  Hungarian
+  Indonesian
+  Japanese
+  Lithuanian
+  Norwegian bokmål
+  Polish
+  Portuguese
+  Punjabi
+  Simplified Chinese
+  Slovenian
+  Spanish
+  Swedish
+  Swedish
+  Traditional Chinese
+
+Overview of Changes from GLib 2.25.14 to GLib 2.25.15
+=====================================================
+
+ * GIO
+  - Memory leak fixes
+  - The GZip(De}Compressor can now process header information
+  - Support for network proxies has been added, with the GProxy
+    interface and the gio-proxy-resolver extension point. GIO
+    includes SOCKSv4 and SOCKSv5 implementations, and libproxy
+    is also going to provide an implementation of this extension
+    point.
+  - There are GAction and GActionGroup interfaces now, which will
+    be used in GApplication in the near future.
+
+ * GObject
+  - There are now convenience macros for defining boxed and
+    pointer types
+
+ * GDBus
+  - Memory leak fixes
+  - GDBusProxy for well-known names can now auto-restart
+    the service if the name owner disapperas
+  - Filter functions are now allowed to modify messages
+
+ * GLib
+  - GDateTime is a replacement for GDate that supports time
+    and timezone information.
+
+ * Bugs fixed:
+  50076 Time API to go with date API
+ 449565 Add G_DEFINE_BOXED_TYPE()
+ 617691 Add GZIP header processing to GZlibCompressor/GZlibDecompressor
+ 622184 add g_memory_output_stream_steal_data
+ 624546 Modification of GDBusMessage in filter function
+ 627088 Build failure in gdbus-peer.c on FreeBSD
+ 627181 save a memdup
+ 627182 Plug a mem leak in the gdbus-connection test
+ 627187 Plug some gdbus mem leaks
+ 627188 gdbus-non-socket test occasionally fails
+ 627252 G_OPTION_FLAG_NO_ARG is only for callback options
+ 627392 gdbus commit 8a3a4596 breaks win32 compile
+ 627407 FTBFS on !linux UNIX platforms
+ 627604 String error: 'that' twice in a row
+ 627969 ABR in g_file_open_tmp
+ 628084 gdbus-peer fails with assertion
+ 628193 Miscellaneous string fixes
+ 628296 abort() in gsocketconnection.c
+ 628309 Plug a mem leak in GConverterOutputStream
+ 628317 GEmblemedIcon:equal implementation is buggy
+ 628323 Fix invalid reads
+ 628327 Plug a mem leak
+ 628328 Plug a mem leak
+ 628329 Don't leak the FD list
+ 628324 Invalid reads in gdbus-export test
+
+ * Updated translations:
+  British English
+  Danish
+  Galician
+  Hebrew
+  Punjabi
+  Serbian
+  Spanish
+  Traditional Chinese
+
+
+Overview of Changes from GLib 2.25.13 to GLib 2.25.14
+=====================================================
+
+* GDBus
+ - Make the closure variants of GDBus apis work
+ - Make error unregistration work
+ - Use async IO in the IO thread (626748)
+
+* GIO
+ - Make g_simple_async_result_is_valid work without source (626208)
+ - GSocketClient: add a timeout property
+ - Fix memory leaks in GSocketClient
+ - Handle async vs. sync correctly in GSocketConnection stream (616458)
+ - Declare stream base classes as abstract
+ - Clarify semantics of g_output_stream_write() (627071)
+
+* Other
+ - Improve test coverage for GDBus, GRegex, GAsyncResult
+ - Drop dead code in pcre, xdgmime
+ - Fix a race condition in gtester (578295)
+ - Avoid an extra allocation in GAsyncQueue (626704)
+ - Add test case for non-socket GIOStream (626841)
+ - More explicit GVariant docs (622770)
+ - Imroved docs for GAsyncInitable and GSimpleAsyncResult (602417)
+
+* Translation updates:
+ - Galician
+ - Norwegian bokmål
+ - Punjabi
+ - Simplified Chinese
+ - Swedish
+
+
+Overview of Changes from GLib 2.25.12 to GLib 2.25.13
+=====================================================
+
++-------------------------------------------------------------------+
+|   WARNING: There have been no breaks in API or ABI.  Weird, eh?   |
++-------------------------------------------------------------------+
+
+The primary purpose of this release is to fix a serious problem with
+glib 2.25.12: glibconfig.h (as generated on a Fedora amd64 system) was
+being distributed in the tarball.  It was being used to build some parts
+of glib on other systems (eg: 32bit ones).  This was causing some very
+serious problems.
+
+There have been many other improvements, however:
+
+ Build and testing:
+  - vastly improved test coverage
+  - old tests moved to the gtester framework
+  - gtester Makefile modified so that the tests only run once
+  - cleanup of how we handle includes while building glib
+
+ GVariant:
+  - add a g_return_if_fail (utf8) to g_variant_new_string()
+
+ GDBus:
+  - perform extra sanity checks when serialising messages
+  - add API to query and set the byteorder of a GDBusMessage
+  - improve debug output, add some extra options
+  - if exiting due to the bus disconnecting us, print an error message
+    explaining why
+  - sort property names correctly
+  - don't bother sending RemoveMatch when we will close the connection
+    anyway
+  - use effective uid/gid for credential passing
+
+ GSettings:
+  - add G_SETTINGS_BIND_INVERT_BOOLEAN for inverting boolean bindings
+    without mapping functions
+  - mark all strings in the schema compiler for translation
+
+ Binding:
+  - improve closure support for bindings
+  - copy GSettings INVERT_BOOLEAN flag
+
+ Other:
+  - fix another complicated GCancellable deadlock possibility
+
+Bugs closed:
+ 599590 glib build doesn't look for correct pkg-config
+ 619026 avoid warning in gutils.h when using gcc with -Wconversion
+ 624739 Please fix POTFILES.in
+ 625472 Valgrind claims uninitialized bytes used
+ 625500 g_date_set_time_val documentation doesn't mention local time
+ 625628 GDBusProxy: wrong property name sorting
+ 625753 Incorrect flags used in g_dbus_connection_call_sync()
+ 625827 Expand documentation about error quark naming
+ 625988 builddir != srcdir issues
+ 626107 glibconfig.h is being disted
+
+Updated translations:
+ French
+ Galician
+ Hebrew
+ Norwegian bokmål
+ Spanish
+
+
+Overview of Changes from GLib 2.25.11 to GLib 2.25.12
+=====================================================
+
++-------------------------------------------------------------------+
+| WARNING: There have been many API changes in GDBus -- sending     |
+| messages, subscribing to signals, closing connections and         |
+| registering subtrees are affected.  The ABI for GSettingsBackend  |
+| has also been changed.  For both reasons, a new dconf release is  |
+| required (and will be along soon).                                |
++-------------------------------------------------------------------+
+
+Build:
+  - cleanup automake setup
+  - rename configure.in to configure.ac
+  - various docs fixups
+  - move glibconfig.h to glib/
+  - disable dtrace support on Mac OS (which has incompatible 'dtrace')
+
+GSettings:
+  - add support for vendor override files (to change the default values
+    in a schema)
+  - change GSettingsBackend vtable
+  - add g_settings_reset()
+  - support binding to G_TYPE_STRV properties
+
+GDBus:
+  - many bug fixes, including a serialisation fix
+  - stop handling incoming connections as soon as stop() is called
+  - proper support for file descriptor passing
+  - new flags parameter for sending messages
+  - new flags parameter for subscribing to signals
+  - always reset the message serial when sending a message unless
+    G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL is given
+  - constness fixes for introspection structures
+  - clean ups to subtree registration API
+
+Other:
+  - fix divide by zero bug in g_malloc_n functions
+  - GIO: don't blindly assume that SOCK_CLOEXEC is supported
+  - make GObject property notify freezes threadsafe
+  - GIO: clean up credentials passing
+  - GApplication: make default-quit not apply if register=FALSE
+  - GIO: add annotations for gobject-introspection
+
+Bugs closed:
+ 166020 use GAtomic for refcounting
+ 617483 Credentials passing
+ 622005 [GApplication] no way to modify the "default-quit" property
+ 623293 vendor override files
+ 623810 Message serialization bug
+ 623815 Don't check sender for GDBusProxy objects where name is not set
+ 624473 GDBusSubtreeIntrospectFunc return type
+ 624483 GDBusSubtreeEnumerateFunc clarification
+ 624484 GDBusSubtreeDispatchFunc clarification
+ 624754 gdbusaddress.c missing sys/wait.h
+ 624968 div by zero in g_malloc_n family
+ 624991 GSettings mapping for G_TYPE_STRV 
+ 625383 Add missing GI annotations
+
+Updated Translations:
+ Armenian
+ Galician
+ German
+ Hebrew
+ Kazakh
+ Romanian
+ Simplified Chinese
+ Spanish
+
+Overview of Changes from GLib 2.25.10 to GLib 2.25.11
+=====================================================
+
++-------------------------------------------------------------------+
+| WARNING: There have been minor API changes in GDBus and GVariant. |
+| These API changes will not affect many users, but they do require |
+| a new version of GTK+ to be installed.                            |
++-------------------------------------------------------------------+
+
+Build:
+  - add a --disable-Bsymbolic configure flag to disable linking with
+    -Bsymbolic-functions
+  - this release sees the complete removal of the old 'g*alias' hacks
+  - honour the NOCONFIGURE environment variable from autogen.sh
+  - use proper feature test macros for isnan
+  - use pkg-config to check for zlib
+  - add ACLOCAL_AMFLAGS to Makefile.am
+
+GDBus:
+  - hide Class and instance structures for all GDBus types except
+    GDBusProxy.  This breaks API by preventing subclassing, but probably
+    nobody was doing that.
+  - add new GDBusConnection call to support flushing all pending
+    outgoing messages
+  - change the register_object API to add a reference to the
+    GDBusInterfaceInfo object so the caller need not keep it alive
+    themselves
+  - don't rewrite the serial number when sending messages that already
+    have a serial number
+  - better error checking for DBUS_SESSION_BUS_ADDRESS environment
+    variable
+  - switch to g_parse_debug_string for G_DBUS_DEBUG and add a lot of new
+    flags
+  - add support for temporarily freezing a freshly created
+    GDBusConnection.  Do this until after the ::new-connection signal
+    has finished running on GDBus services.
+  - never require non-closed connections (the user is incapable of doing
+    this due to the obvious race)
+  - remove weird/misleading redundant check on NameOwnerChanged signal
+  - emit GDBusProxy::g-properties-changed on NameOwnerChanged
+
+GVariant:
+  - the 'g_variant_{new,get}_byte_array' APIs have been removed
+  - g_variant_{new,get,dup}_bytestring has been added, with different
+    arguments and different behaviour
+  - g_variant_{new,get,dup}_bytestring_array has been added, doing
+    essentially the same thing as the 'strv' functions, but with byte
+    strings instead of utf8 strings
+  - G_VARIANT_TYPE_BYTESTRING ('ay'), BYTESTRING_ARRAY ('aay') and
+    STRING_ARRAY ('as') constants have been added
+  - the undocumented behaviour that g_variant_get_strv() deserialised
+    arrays of object paths or signature strings has been dropped
+  - additional varargs support for converting bytestrings or bytestring
+    arrays with ^ay ^aay ^&ay and ^a&ay
+  - improved gobject-introspection annotation
+  - fix a problem with GBuffer calling g_slice_free for the wrong type
+  - fix leaks in the type inferencing code of the parser
+
+GSettings:
+  - improved documentation
+  - updated schema XML DTD, now xincluded into the docs
+  - added support for schemas that extend other schemas (using the
+    'extends=' attribute).  Values of keys in the base schema can be
+    overridden using <override>.
+  - added theoretical support for lists (using the 'list-of=' attribute)
+  - lots of new tests
+  - add support for flags (implemented similarly to enums)
+  - add support for generating .enums.xml files to gsettings.m4:
+      gsettings_ENUM_NAMESPACE = org.example.myapp
+      gsettings_ENUM_FILES = ../path/to/*.h
+    will generate org.example.myapp.enums.xml with mappings for all
+    enums and flags in the specified .h files.
+  - warn with g_message() if the 'memory' backend is used by default
+    (ie: because no other GSettings backends are installed)
+  - fix get_property() for GSettings::schema
+  - command line tool: fix a bug that prevented non-basic values from
+    being set due to a premature free
+  - command line tool: bash completion support
+  - chain up in _finalize
+  - add a new g_settings_get_mapped API to read settings that require
+    post-processing
+  - retry with the translated or schema default value if the
+    GSettingsBindGetMapping function fails
+  - schema compiler: never fail due to empty schema directories (but
+    warn)
+  - peek rather than ref/unref the GEnumClass in the mapping function
+  - schema compiler: compile *.enums.xml before *.gschemas.xml to ensure
+    that we have all the enums that the schemas may reference
+  - schema compiler: improve accuracy of line numbers in error reports
+  - fix crashes in the keyfile backend caused by invalid group names in
+    the keyfile
+
+Other:
+  - always intern GBinding prop names
+  - base64: remove asserts preventing conversion of empty strings
+  - document NULL special-cases for GValueArray
+  - GNode docs improvements
+  - improve detection of 'system internal' mounts
+  - fix leaks in the inotify GFileMonitor implementation
+  - annotate all custom GIO GSources to improve debugging (e.g. using
+    SystemTap)
+
+Tests:
+  - Turn on glibc malloc checking features for make check
+  - improvements for GSettings tests, plus new tests
+  - improved tests for GKeyfile
+  - new tests for GDir, GSList, GSList, GAppLaunchContext,
+    CharsetConverter, GIcon, ...
+  - move some tests to GTester (tree tests, uri tests)
+  - generally, really an awful lot of new tests
+  - don't try to allocate 2gigs of memory anymore for the array test
+
+ 552363 g_value_array_{insert,prepend,append}'s special cases for NULL
+ 561248 Improve return value description from g_node_prev/next_sibling()
+ 570036 Add ACLOCAL_AMFLAGS to Makefile.am
+ 576833 g_sprintf add a reference to g_strdup_printf
+ 576854 g_strconcat() documentation should provide a hint about bad l10n
+ 582227 reference: add other URI functions to 'URI Functions' section
+ 599223 should provide g_spawn_* variants that take a GAppLaunchContext
+ 610784 array test failing
+ 613057 Leak in inotify GFileMonitor implementation
+ 620536 Annotate all custom GIO GSource using g_source_set_name
+ 620913 More control with G_DBUS_DEBUG
+ 622124 implement flags
+ 622127 GSettings extended key validation
+ 622128 retry with default value for failed mapping
+ 622294 More annotations for GVariant
+ 622565 glib-compile-schemas fails when no schemas
+ 622600 Fix missing prototype warning
+ 622813 gsettings mapping & enum buglet
+ 623142 Ensure ::new-connection runs before processing D-Bus messages
+ 623143 Never require non-closed connections
+ 623319 use g_parse_debug_string for dbus debug flags
+ 623401 process enums first
+ 623402 schema compiler reports wrong line numbers
+ 623407 g_keyfile_settings_backend_new crashes with the key "/"
+ 623473 zlib should be checked with pkg-config
+ 623537 GDBusProxy has weird checking on NameOwnerChanged
+ 623538 GDBusProxy::g-properties-changed emission for corner cases
+ 623692 directory with file at multiple MLS levels may display empty
+ 623720 gschema.dtd does not contain enum definitions
+ 623770 quoting of expand_macro in gdesktopappinfo.c
+ 623772 gdesktopappinfo.c, function child_setup
+ 623780 g_unix_is_mount_path_system_internal
+ 623954 g_settings_finalize
+ 623955 Dubious return values
+
+Updated translations:
+ Galician
+ Hebrew
+ Norwegian bokmål
+ Spanish
+
+Overview of Changes from GLib 2.25.9 to GLib 2.25.10
+====================================================
+
++----------------------------------------------------------------+
+| WARNING: There have been API changes in GDBus. Users of these  |
+| APIs will need to be adapted.  In particular, a new release of |
+| dconf is required to go along with this one.  There has also   |
+| been a change in the GSettings backend API used for keyfiles.  |
++----------------------------------------------------------------+
+
+* GDBus:
+ - add direction parameter to filter functions (API change)
+ - allow calling other interfaces with a GDBusProxy
+ - padding added to class struct fields (ABI change)
+ - fixes for closures-based functions
+
+* GVariant:
+ - new is_floating() call
+ - add g_value_take_variant() call (required for marshallers)
+
+* GSettings:
+ - support for binding GParamSpecEnum properties
+ - ifelse-style condition support for GLIB_GSETTINGS m4 macro
+ - remove gsettings-schema-convert tool (now in GConf)
+ - allow introspection of all installed schemas
+ - allow introspection of the keys in a schema
+ - rewrite keyfile backend (API change)
+
+* GNIO:
+ - don't implicitly close GSocket until it is destroyed
+ - windows fixups
+
+* Other:
+ - allow GChecksum to take (NULL, 0) for data/length
+ - GRelation and GCompletion are now deprecated
+ - introduce G_PARAM_DEPRECATED and G_ENABLE_DIAGNOSTIC
+ - add working directory to GApplication platform data
+ - lots of documentation cleanups
+ - PCRE updated to 8.02
+
+* Build:
+ - the IA__g_* style symbol aliasing has been disabled and replaced with
+   the -Bsymbolic-functions linker flag on platforms that support it.
+   Please be on the watch for portability issues and report them to us.
+ - many test cases have been moved to the GTester framework
+ - lcov support has been added for tests
+ - many windows fixes
+
+* Bugs fixed:
+ 501057  lcov coverage suite and GLib integration
+ 551271  deprecate GRelation
+ 601686  Implement diagnostic mode
+ 603309  GSocketOutputStream broken on Windows (?)
+ 616718  GLIB_GSETTINGS macro can't be used conditionally
+ 616855  GSocketConnection: don't close the socket if it's still reffed
+ 618866  g_ptr_array_remove_index_fast memory leak
+ 619878  keyfile backend calls keys_changed with invalid argument
+ 619879  keyfile backend doesn't make use of expected_type
+ 621092  Add with_closures() variants for bindings
+ 621172  Cross compiling fails
+ 621838  Actually add cwd to platform data
+ 621945  Filter outgoing messages in GDBusConnection
+ 621947  add g_value_take_variant
+ 622038  GSettings: "It is a programmer error" documentation is unclear
+ 622154  [patch] update documentation for g_application_new
+ 622281  binding: Add SYNC_CREATE to the flags
+ 622480  Improve documentation for g_strcmp0()
+ 622554  g_error called if schema not installed
+ 622601  Return interned strings from g_settings_list_keys
+
+* Translation updates:
+ - Galician
+
+Overview of Changes from GLib 2.25.8 to GLib 2.25.9
+===================================================
+
++----------------------------------------------------------------+
+| WARNING: There have been API changes in GDBus, GSettings and   |
+| GApplication. Users of these APIs will need to be adapted. In  |
+| particular, a new release of GTK+ is required to go along with |
+| this one.                                                      |
++----------------------------------------------------------------+
+
+* GDBus
+ - Use Gio's default async implementation
+ - Fix proxy construction for objects with no properties
+ - Fix error handling in synchronous initialization
+ - Do not dispatch calls to unregistered objects
+ - Add _with_closures alternative functions
+ - Allow constructing GDBusProxy with well-known names
+ - Remove GType parameters from GDBusProxy constructors
+ - Nuke g_bus_watch_proxy API
+ - Add --xml to gdbus-tool to print raw introspected XML
+
+* GSettings
+ - schema file format change: store (default, options) in gvdb
+ - Add g_settings_sync()
+ - Add support for enums and ranges
+ - 'context' support has been replaced by direct use of
+   GSettingsBackend
+
+* GApplication
+ - Switch to using variants for timestamps
+ - Use GInitable
+
+* GObject
+ - Introduce g_object_notify_by_pspec
+ - Add GBinding
+ - The GVariant gtype G_TYPE_VARIANT was changed from boxed
+   to fundamental. We believe there were no existing users
+   of the boxed type, so this should not cause any applications
+   to break.
+
+* Test framework
+ - Add package and version to the test report XML
+ - Use optparse to parse gtester-report commandline
+ - Add subunit support to gtester-report
+ - Prevent division by zero if no tests
+
+* Bugs fixed:
+ 621782 Crash using gbinding
+ 619945 GConverterOutputStream triggers assertion and corrupts data
+ 621319 more leaked GVariants in GSettings
+ 621168 GKeyFile memory leak on Windows platform
+ 621002 Switch to using variants for timestamps, split out signals
+ 620953 tiny docs addition
+ 618904 Lies in gunixmounts documentation
+ 621702 Correctly initialize GError
+ 611778 minor cleanup of gtester-report
+ 621213 GDBusProxy and well-known names
+ 621034 Rewrite apps test to ensure children are killed
+ 620954 gapplication gvariant simplifications
+ 611869 add subunit out feature to gtester-report
+ 621119 GDBusProxy and objects with no properties
+ 620990 Use Gio's default async implementation again
+ 620952 g_application_register_with_data is an ugly API
+ 621252 GSettings leaks context
+ 618715 fork() in GSettings test cases is problematic 618715
+ 621905 Assume a ref when doing async work
+ 621266 GSettings "context" clarification
+
+* Translation updates:
+ Chinese
+
+
+Overview of Changes from GLib 2.25.7 to GLib 2.25.8
+===================================================
+
+* Initial support for dtrace and systemtap profiling:
+ - mainloop sources can be named
+ - probes for memory allocation with g_malloc and gslice
+ - gquark name tracking
+ - type creation
+ - object life-cyle (creation, finalization, ref, unref)
+ - signal creation and emission
+
+* GVariant
+ - has been fixed to work with the FreeBSD malloc
+ - added introspection annotations
+ - new function: g_variant_builder_add_parsed
+
+* GSettings:
+ - g_settings_set/get_strv functions have lost their length parameter
+ - g_settings_set_strv accepts NULL
+ - added introspection annotiations
+
+* GPermission: an abstract interface for representing permissions,
+  with a minimal implementation named GSimplePermission
+
+* GApplication: a basic application support class, with a D-Bus based
+  implementation
+
+* Bugs fixed:
+ 619585 glib-compile-schemas asserts on FreeBSD
+ 620384 Annotate GVariant and GSettings _strv() functions
+ 606044 Add support for dtrace/systemtap static markers
+ 620350 add g_variant_builder_add_parsed() API
+ 620349 utf8ify GVariant printer
+ 620767 Typo in GSettings documentation: "INTLTOOL_NOMERGE_RULE"
+ 620312 Fix g_settings_[gs]et_strv() API
+ 620519 GPermission
+ 620582 GPermission needs a simple implementation
+ 620496 GSettings schema compiler should reject invalid paths
+ 620173 missing single header inclusion guards
+ 620265 g_assertion_message_error should take const GError *
+
+* Translation updates:
+ Esperanto
+ Galician
+ Hebrew
+ Indonesian
+ Norwegian bokmål
+ Slovenian
+ Spanish
+
+
+Overview of Changes from GLib 2.25.6 to GLib 2.25.7
+===================================================
+
+* NOTE: API/ABI breaks since 2.25.6 release:
+  - g_dbus_connection_sync{,_sync} takes a new 'reply_type' argument
+  - GSettingsBackendClass 'list' virtual function changed
+
+  GSettings backends and things using GDBus may need to be rebuilt.
+
+* GDBus: many build-related fixes
+
+* GDBus (service): return a DBus error when receiving a method call for
+  an unknown interface.
+
+* GSettings: fix 'make install' bug in gsettings.m4 for generated schema
+  files
+
+* GSettings: avoid non-portable use of LC_MESSAGES
+
+* better approach to handling man pages
+
+
+* Bugs fixed:
+ 619527 please improve docs on g_file_make_symlink
+ 619391 send-with-reply should have expected result signature
+ 618616 Use stack-allocated GVariantBuilders
+ 617004 Build with "--disable-nls" fails under MinGW/Win32
+ 619142 Build fixes (GDBus)
+
+* Updated translations:
+ Estonian
+ Galician
+ Norwegian bokmål
+
+Overview of Changes from GLib 2.25.5 to GLib 2.25.6
+===================================================
+
+* GDBus: introspection improvements
+* GDBus: build fixes
+
+* GSettings: GSettingsBackend ABI changed               **** NOTE ****
+* GSettings: --uninstall option for schema compiler
+* GSettings: new m4 macro with more power
+* GSettings: thread support
+
+* rework of file notification on Solaris
+* fixes for gold linker
+
+* Bugs fixed:
+ 619038 increase gsettings.m4 power
+ 619031 method-calls-in-thread test failing
+ 618839 Typo at translation message
+ 616864 GSETTINGS_CHECK_RULE doesn't work with multiple files
+ 618730 gunixcredentialsmessage.c doesn't compile on GNU/kfreebsd
+ 616314 Make GSettings (partially) threadsafe
+
+* Updated Translations:
+ Indonesian
+ Galician
+ Spanish
+
+Overview of Changes from GLib 2.25.4 to GLib 2.25.5
+===================================================
+
+* GDBus: Fix serialization of empty arrays
+
+* GDBus: Plug various memory leaks
+
+* GSettings: Fix problems with GSETTINGS_CHECK_RULE
+
+* Bugs fixed:
+ 616731 GSETTINGS_CHECK_RULE doesn't work in non-srcdir builds
+ 616864 GSETTINGS_CHECK_RULE doesn't work with multiple files
+ 618615 mem leaks in parse_value_from_blob
+ 618622 Plug some mem leaks in gdbus
+ 618650 Plug a mem leak in gdbusauth
+ 618663 Plug mem leaks in gdbus tests & examples
+
+* Updated translations:
+ Spanish
+
+
+Overview of Changes from GLib 2.25.3 to GLib 2.25.4
+===================================================
+
+* GDBus D-Bus support has been merged. This provides an API
+  to replace dbus-glib
+
+* GVariant no requires strings to be UTF-8. You can use byte
+  arrays for non-UTF-8 strings.
+
+* GSettings allows to bind string properties to byte arrays
+
+* The schema compiler supports range restrictions
+
+* Bugs fixed:
+ 618051 socket-server|client.c fail to compile under AIX...
+ 616102 GSettings ignores <choice> and <range>
+ 616720 Chunked quark allocation
+ 616877 Several issues with g_socket_receive_message
+ 616892 gio: Add a boxed type for GFileAttributeMatcher
+ 616967 Add g_regex_get_compile_flags() and g_regex_get_match_flags()
+ 617767 g_settings_[gs]et_strv() 'length' argument has missing docs...
+ 617914 gtester-report: cope with binaries with no test cases
+ 617937 output_stream_close vs output_stream_close_async semantics
+ 615494 Connction timeouts produce partially invalid error messages
+ 617823 glib-compile-schemas problems with an out of source build
+ 617947 glib-mkenums: add @valuenum@ support
+
+* Translation updates:
+ Galicaian
+ Norwegian bokmål
+ Shavian
+ Spanish
+
+
+Overview of Changes from GLib 2.25.2 to GLib 2.25.3
+===================================================
+
+* New macro: G_GNUC_DEPRECATED_FOR, a variant of G_GNUC_DEPRECATED
+  that lets you add replacement information (requires gcc 4.5)
+
+* Rename AM_GSETTINGS autoconf macro to GLIB_GSETTINGS
+
+* Rename gschema-compile utility to glib-compile-schemas
+
+* Add support for timeouts in GSocket
+
+* Bugs fixed:
+ 589989 Compilation error on Solaris 9
+ 616648 Change AM_GSETTINGS macro to GLIB_GSETTINGS
+ 587898 I/O timeouts for GSocket
+ 614541 Add G_TYPE_ERROR boxed type for GError
+
+
+Overview of Changes from GLib 2.25.0 to GLib 2.25.2
+===================================================
+
+* Include a 'gsettings' utility, for commandline access to GSettings
+
+* Install a AM_GSETTINGS autoconf macro similar to AM_GCONF
+
+* GSettings can bind the writability of a key explicitly
+
+* There is now a predefined boxed type for GError
+
+* Bugs fixed:
+ 615379 g_new macros crash if sizeof(struct_type) == 0
+ 616312 Add m4 rule equivalent to GCONF_SCHEMAS_INSTALL
+ 616295 mapping bug for uint64
+ 616216 glib compile from remote directory fails
+ 615960 Fix size passed to connect() for abstract sockets
+ 616432 Crash in gschema-compile
+ 616331 gsettings-schema-convert uses imaginary types
+ 616309 gsettings-schema-convert should output gettext-domain
+ 616384 Add mention of GConfBridge in conversion docs
+ 616311 gschema-compile outputs in current directory
+ 616276 simplify gschema-compile test setup
+ 616156 keys with unnecessary empty options arrays
+ 616405 gsettings missing g_return_if_fail's
+ 616245 Use G_DEFINE_INTERFACE macro
+ 614541 Add G_TYPE_ERROR boxed type for GError
+
+* Updated translations:
+ Catalan (Valencian)
+ Galician
+ Kannada
+ Spanish
+
+
+Overview of Changes from GLib 2.24.0 to GLib 2.25.0
+===================================================
+
+* The GSettings framework has been merged. This provides the API to
+  replace GConf. DConf will provide a backend implementation for it.
+  GConf will also provide a backend implementation to ease the
+  transition. We provide utilities to assist with schema conversion
+  and data migration, as well as a porting guide.
+
+* Translation updates:
+ Bengali
+ Catalan
+ Danish
+ Gujarati
+ Marathi
+ Thai
+ Traditional Chinese
+
+
+Overview of Changes from GLib 2.23.6 to GLib 2.24.0
+===================================================
+
+* Bug fixes:
+ 613601 buglet in dup_close_on_exec_fd
+ 584284 g_data_input_stream_read_until_async behaves confusingly
+ 613748 Write errors in middle of copy cause hang
+ 613923 splice_stream_with_progress: wrong error handling
+ 613667 Typo in GObject documentation
+ 613618 gvariant format string docs unclear
+
+* Translation updates:
+ Basque
+ Ukrainian
+ Vietnamese
+
+
+Overview of Changes from GLib 2.23.5 to GLib 2.23.6
+===================================================
+
+* Class private data:
+  - support for private data associated with a GTypeClass
+
+* GVariant merge is now complete:
+  - loading functions and parser merged
+
+* Windows improvements:
+  - socket fixes
+  - various build improvements
+  - removal of GCC/C99isms in favour of portable code
+  - drop unmaintained Visual Studio 8 support
+
+* Minor API addition:
+  - g_desktop_app_info_get_filename()
+
+* Bugs fixed:
+ 521707 Class private data
+ 612502 build fails on glib/tests/gvariant.c
+ 612832 [GDesktopAppInfo] New function g_desktop_app_info_get_filename
+ 612702 [PATCH] Fix GSocket-related crash on Windows
+ 612736 Improve the documentation about single include
+ 610858 gvariant test fails sometimes
+ 612327 uninitialized variable
+
+* New translations:
+ Afrikaans
+ LowGerman
+
+* Updated translations:
+ Czech
+ Finnish
+ Galician
+ Greek
+ Punjabi
+ Romanian
+ Serbian
+
+
+Overview of Changes from GLib 2.23.4 to GLib 2.23.5
+===================================================
+
+* New API addition: g_malloc_n() and friends used to implement an
+  overflow-safe family of g_new() macros.
+
+* GVariant:
+ - GVariantBuilder and GVariantIter are now merged.
+ - The variable arguments API is now merged.
+ - The parser will be in a future release.
+
+* GIO:
+ - Remove GUtf8InputStream (which never appeared in a stable release)
+   for now since it doesn't satisfy the needs of its main intended use
+   case.  We hope to reimplement this feature in a better form in a
+   future release.
+
+* Bugs fixed:
+ 609531 missing licence headers
+ 612107 Missing G_FILE_ATTRIBUTE_TRASH_ORIG_PATH
+ 611897 g_io_modules_scan_all_in_directory leaks
+ 608196 Overflow-safe g_new family
+ 611696 gio uses GetAddrInfo which requires special handing on windows 2k
+ 605667 Don't use G_PARAM_SPEC_VALUE_TYPE when we know the pspec is valid
+ 610860 test_g_file_open_readwrite fails if $HOME is unwritable
+ 552912 glib-2.18 /live-g-file/test_copy_move failed when run as root
+ 609813 Renaming a file discards file notes
+
+* Updated translations:
+ Basque
+ Brazilian Portuguese
+ British English
+ Bulgarian
+ Catalan
+ Danish
+ Estonian
+ French
+ German
+ Hungarian
+ Italian
+ Lithuanian
+ Norwegian bokmål
+ Portuguese
+ Russian
+ Slovenian
+ Spanish
+ Swedish
+ Traditional Chinese
+
+
+Overview of Changes from GLib 2.23.3 to GLib 2.23.4
+===================================================
+
+* GVariant: The core of GVariant has been merged now, with some
+ API still to follow.
+
+* GIO:
+ - There is a new interface GFileDescriptorBased for file descriptor
+   based IO. GLocalFile{Input,Output}Stream implement it
+ - Use splice(2) to transfer data between file descriptors without
+   extraneous copies
+ - Add a way to request move events from file monitors
+
+* Bugs fixed:
+ 609143 *result_uncertain is never assigned in g_content_type_guess
+ 604086 Use splice(2) when doing local file copies
+ 547890 No move events for GFileMonitorEvent?
+ 568760 nautilus freezes due to a bug in garray.c:322
+ 609962 Add info about the use of G_DEFINE_INTERFACE
+ 609564 g_base64_encode_close docs should mention outbuf size...
+ 610484 g_variant_equal bug
+ 610131 libasyncns does not compile on Solaris 8
+ 609530 missing single header include guards
+
+* Updated translations:
+ Czech
+ Estonian
+ Galician
+ German
+ Korean
+ Polish
+ Slovenian
+ Spanish
+ Traditional Chinese
+
+
+Overview of Changes from GLib 2.23.2 to GLib 2.23.3
+===================================================
+
+* GLib now has a facility for locks that consume only one bit of
+  storage inside an integer: g_bit_lock()
+
+* GVariant: The serializer has been merged, with more API to follow
+
+* Bugs fixed
+ 548967 1 bit mutex lock
+ 604967 2.22.3 libasyncns build fails on HP-UX 11.11
+ 608602 G_VALUE_COLLECT_INIT variables shadow those in G_VALUE_COLLECT
+ 608743 Crash in g_hostname_to_ascii visiting certain website in epiphany
+ 599197 array ref and unref functions crash on NULL array.
+ 608159 mem leak in g_io_modules_scan_all_in_directory
+
+* Translation updates
+ Brazilian Portuguese
+ Czech
+ French
+ Norwegian bokmål
+ Slovenian
+ Spanish
+ Thai
+
+
+Overview of Changes from GLib 2.23.1 to GLib 2.23.2
+===================================================
+
+* We are now using gcc builtins for atomic operations when available
+
+* g_assert() grew the ability to store assertions in core dumps
+
+* GIO supports lazy loading of GIO modules, and there is a new
+  gio-querymodule utility that goes along with this.
+  Packagers will need to adapt to this.
+
+* Threading changes:
+ - The requirements for g_thread_init() have been relaxed slightly,
+   it can be called multiple times, and does not have to be the first
+   call.
+ - GObject now links to GThread and threads are enabled automatically
+   when g_type_init() is called.
+ - Thread-safety issues with boxed types in GObject have been fixed.
+
+* GObject:
+ - Another bunch of performance work has landed
+
+* GVariant:
+ - GVariantType has been merged, with the rest of the GVariant
+   API to follow.
+
+* Bugs fixed:
+ 568760 nautilus freezes due to a bug in garray.c:322
+ 602417 Document lifecycles of GSimpleAsyncResult and friends
+ 604824 crash in Epiphany: Selecting my Slashdot bo...
+ 448888 don't init g_slice for always-malloc
+ 531902 Use GCC atomic buildins for g_atomic*
+ 554887 boxed type registration is not thread safe
+ 586150 unresolved symbols when building glib 2.21.2 on OS X Tiger
+ 589176 row gvalue transform array exponentially
+ 594872 Support storing assertion messages into core dump
+ 602240 Upgrade libasyncns to 0.8
+ 603590 Speed up G_VALUE_COLLECT
+ 604457 gutf8inputstream.c: increasing unknown size pointer
+ 605686 GCharsetConverter doesn't flush
+ 605733 g_memory_output_stream_new violates GObject standards
+ 605883 g_object_new() processes varargs even when there are none
+ 605977 invalid utf-8 conversion in g_local_file_get_parse_name(...
+ 606775 Enable threads by default in gobject
+
+* Translation updates:
+ Asturian
+ Basque
+ Bengali
+ Bulgarian
+ Estonian
+ Norwegian bokmål
+ Spanish
+ Thai
+ Ukrainian
+
+
+Overview of Changes from GLib 2.23.0 to GLib 2.23.1
+===================================================
+
+* GObject performance work has landed:
+ - Construction of simple objects is much faster
+ - Interface lookup is lock-free and constant-time now
+ - Reduced locking overhead when dealing with types
+
+* GType now has a G_DEFINE_INTERFACE convenience macro
+
+* GIO gained GUtf8InputStream, an input stream that
+  performs utf-8 validation
+
+* GLib now has byte-swap macros for gsize and gssize
+
+* Bugs fixed:
+557151 Determining the newly_constructed boolean in gobject.c...
+557100 Performance improvements for GObjectClasses that don't...
+501166 Warning message says IA__g_type_init instead of g_type_init
+585375 Performance and Contention problems with g_type_class_ref...
+587892 Race in GType when instantiating the same class for the...
+603270 Input Stream validating utf8
+603476 gioenums.h:62: error: comma at end of enumerator list
+603540 g_time_val_from_iso8601 uses uninitialised variable
+603982 Stack overflow when reading file async with filter
+604645 G_DEFINE_INTERFACE_* documentation is not generated
+604875 Use of sa_len conflicts with system header
+320482 provide G_DEFINE_TYPE like macros for interfaces
+
+* Updated translations:
+ Estonian
+ Hebrew
+ Norwegian bokmål
+ Vietnamese
+ Welsh
+
+
+Overview of Changes from GLib 2.22.x to GLib 2.23.0
+===================================================
+
+* GIO:
+ - GConverter: a generic interface for stateful conversions of data,
+   suitable for charset conversion, compression, decompression, regexp
+   replacement. Concrete implementations are GCharsetConverter,
+   GZlibCompressor and GZlibDecompressor. GConverterInputStream,
+   GConverterOutputStream are stream implementations that convert data
+   while loading or saving it.
+ - GMounts can now have a 'default location': a path that reflects
+   the main entry point for the user (e.g. the home directory).
+ - As a consequence of the compression support, GIO depends on zlib now.
+
+* GObject:
+ - G_IMPLEMENT_INTERFACE_DYNAMIC: a convenience macro for adding
+   interfaces to dynamic types.
+
+* GModule:
+ - The -pthread flag has been added to all gmodule .pc files, because
+   it is not generally permissible to load modules that are linked
+   against libpthread if the program has not been compiled with threading
+   support.
+
+* Bugs fixed:
+ 601637 GUnixFDMessage should contain a GUnixFDList
+ 585566 GSocketListener API issues
+ 572252 Bug in g_file_test() function.
+ 600550 g_app_info_create_from_commandline doesn't treat arguments properly
+ 541236 not detecting exact content type
+ 350200 [PATCH] GTypeModule derived class unref does not unload plugin
+ 589631 Please enclose literal values with double quotes
+ 577711 cross compile check for g++ broken
+ 600620 Support X-GNOME-FullName in GAppInfo
+ 598899 GWin32DirectoryMonitor is broken
+ 593809 Nautilus does not restore the position of the icons on the desktop...
+ 563627 g_get_prgname() threadsafety
+ 600141 Add -pthread to gmodule pkg-config
+ 593856 file and directory monitors don't work when glib is compiled...
+ 324930 Nautilus should disallow copying of symlink to FAT drive early
+ 587300 Deadlock when calling g_cancellable_disconnect in a...
+ 595138 GFile not robust with invalid input
+ 591216 Warning building resolver.o
+ 590016 Does not compile under MinGW32 + Wine
+ 591214 Warnings building gcancellable.o
+ 561998 Have specific entry points (paths) for mounts...
+ 508157 Add G_IMPLEMENT_INTERFACE_DYNAMIC
+ 535159 g_file_has_parent
+
+* Updated translations:
+ Brazilian Portuguese
+ Catalan
+ Estonian
+ Galician
+ Norwegian bokmål
+ Shavian
+ Slovenian
+ Spanish
+ Swedish
+
+
+Overview of Changes from GLib 2.22.1 to GLib 2.22.2
+===================================================
+
+* GIO:
+ - Support case-sensitive globs in the shared mime database,
+   including support for the newer cache format that allows these.
+   Case-sensitive globs have been introduced in shared-mime-info
+   version 0.70
+
+* GObject:
+ - Speed up creation of simple objects
+
+* Bugs fixed:
+ 597194 Typo in _G_TYPE_CVH macro
+
+* Updated translations:
+ Russian
+
+
+Overview of Changes from GLib 2.22.0 to GLib 2.22.1
+===================================================
+
+* Bugs fixed:
+ 596064 Test file marked for translation
+ 595972 possibly invalid search in mime_info_cache_dir_add_...
+ 596561 C99 style of declaration of variable in gmessages.c
+ 596314 g_utf16_to_utf8 returns an invalid UTF8 string
+ 596748 g_async_result_get_source_object returns a new ref
+ 593809 Nautilus does not restore the position of the icons...
+ 593775 uses inotify_init1 unconditionally
+
+* Updated translations:
+ Bengali
+ Hebrew
+
+
+Overview of Changes from GLib 2.21.6 to GLib 2.22.0
+===================================================
+
+* Add gdb python macros to make gobject debugging more pleasant
+
+* Bugs fixed:
+ 579050 Allow making selected critical and warning messages non-fatal
+ 594759 g_socket_send_message fails due to invalid sendmsg params
+ 593941 GNetworkAddress skipping addresses when enumerating
+ 594597 Fix build with srcdir != builddir
+ 595619 Include gdb pretty printers
+
+* Changes that might affect bindings:
+ - The error parameter of g_simple_async_result_set_from_error has been
+   made const.
+
+* Updated translations:
+ Assamese
+ Bengali India
+ British English
+ Bulgarian
+ Catalan
+ Czech
+ Danish
+ Finnish
+ Galician
+ Greek
+ Gujarati
+ Hindi
+ Japanese
+ Kannada
+ Malayalam
+ Marathi
+ Norwegian bokmål
+ Oriya
+ Polish
+ Punjabi
+ Romanian
+ Serbian
+ Simplified Chinese
+ Slovenian
+ Spanish
+ Tamil
+ Telugu
+ Thai
+ Traditional Chinese
+ Ukrainian
+ Vietnamese
+
+
+Overview of Changes from GLib 2.21.5 to GLib 2.21.6
+===================================================
+
+* Minor API additions:
+  g_mkstemp_full is a variant of g_mkstemp that allows to specify flags
+  and permissions
+
+* Bugs fixed:
+ 593232 g_rand_new: read no more than requested from /dev/urandom
+ 591995 use saved errno
+ 589491 g_time_val_from_iso8601 doesn't handle some cases
+ 593406 Permissions set to 777 after copying via Nautilus
+ 594034 Add g_mkstemp_full()
+
+* Updated translations:
+ Assamese
+ Basque
+ Brazilian Portuguese
+ Czech
+ Estonian
+ French
+ German
+ Hungarian
+ Italian
+ Kannada
+ Malayalam
+ Marathi
+ Norwegian bokmål
+ Oriya
+ Portuguese
+ Swedish
+ Tamil
+ Turkish
+
+
+Overview of Changes from GLib 2.21.4 to GLib 2.21.5
+===================================================
+
+* A performance problem with trashing of many files has been fixed
+
+* GResolver now invalidates the libc resolv.conf cache as needed
+
+* Minor api additions:
+ - g_cancellable_make_pollfd returns a boolean now. And there is a
+   new function g_cancellable_release_fd that can be used to released
+   the resources used by a GCancellable.
+
+* Bugs fixed:
+ 589988 Compilation error on Solaris 9 (missing stdint.h)
+ 588901 gtcpconnection.c won't compile
+ 584246 GResolver needs to call res_init() when network state changes
+ 591714 Figure out failure handling for g_cancellable_make_pollfd()
+ 591532 redundent '/' returned from g_file_resolve_relative_path
+ 591378 Use MSG_NOSIGNAL in GSocket if it's available
+ 589649 API documentation migration for Base64 Encoding
+ 591840 configure fails with autoconf 2.64
+
+* Updated translations:
+ Basque
+ Brazilian Portuguese
+ Bulgarian
+ Danish
+ Estonian
+ Finnish
+ Galician
+ Gujarati
+ Hndi
+ Irish
+ Japanese
+ Korean
+ Norwegian bokmål
+ Polish
+ Portuguese
+ Punjabi
+ Spanish
+ Swedish
+ Telugu
+ Traditional Chinese
+ Thai
+
+
+Overview of Changes from GLib 2.21.3 to GLib 2.21.4
+===================================================
+
+* GTree is now refcounted
+
+* Bugs fixed:
+ 587938 Undocumented limitation for g_str_equal
+ 587773 refcounts for GTree
+
+* Updated translations:
+ French
+ Hebrew
+ Norwegian bokmål
+ Spanish
+ Swedish
+ Traditional Chinese
+ Ukrainian
+
+
+Overview of Changes from GLib 2.21.2 to GLib 2.21.3
+===================================================
+
+* GMappedFile is refcounted now
+
+* Mainloop: It is now possible to set per-thread default contexts,
+  with g_main_context_push_thread_default.
+
+* glib-mkenums supports a @basename@ substitution, in addition
+  to @filename@.
+
+* GIO:
+ - Vfs implementations can support storing of per-file metadata.
+ - GCancellable can now be subclassed.
+ - Unmount and eject methods now optionally allow interaction, via
+   variants that take a GMountOperation object.
+
+* Bugs fixed:
+ 556706 Inconsistent help arguments -h, -?
+ 579449 FileChoosers no longer work if an idle handler is active
+ 579933 mainloop FD_CLOEXEC has a race condition
+ 579984 alternate GMainContext support
+ 585937 gio/gsocket.c (glib 2.21.2) does not compile (Windows/mingw)
+ 586675 Runtime library location
+ 586797 Add GCancellables to GSocket ops
+ 586868 g_filename_complete_get_completions doesn't always return...
+ 587415 g_resolver_lookup_by_name_finish returns a freed list
+ 587434 regression tests fail, at least on x86_64
+ 586928 Avoid g++ warning in g_error()
+
+* Updated translations:
+ Estonian
+ Hebrew
+
+
+Overview of Changes from GLib 2.21.1 to GLib 2.21.2
+===================================================
+
+* GIO:
+  - g_socket_speaks_ipv4 is a new function to check if a socket can
+    speak IPv4.
+  - g_socket_listener_add_address gained a new effective_address out
+    parameter.
+  - GIO now returns special icons for XDG user directories, by the
+    name folder-music, folder-documents, etc.
+  - GIO gained support for starting/stopping of drives, which can be used
+    in connection with external hard disk enclosures, disk arrays, iSCSI
+    devices, etc. See g_file_start/stop_mountable.
+
+* GLib:
+ - g_reload_user_special_dirs_cache is a new function to force GLib to
+   reload the XDG user directory mapping from disk.
+
+* Bug fixes:
+ 584574 glib compile failure on Mac OS X with gunixresolver.c and...
+ 585566	GSocketListener API issues
+ 584255	Incorrect freeing of thread pool in GThreadedSocketService
+ 585088	g_string_chunk_insert_len stops at nul bytes
+ 585360	Monitor fontconfig configuration files using gio causes m...
+ 580103	Terminal starts on Display :0.0 when started on :0.1 in D...
+ 580301	network: a few issues on old darwin
+ 583398	SRV weight sorting is incorrect
+ 584176	build fixes on FreeBSD
+ 585189	g_cancellable_reset() must be called in same thread as g_...
+ 585280	compilation dies on gio/gsocket.c, needs sys/uio.h to con...
+ 585281	gio/gunixfdmessage.c needs sys/types.h for platforms that...
+ 585478	don't leak the inotify fd
+ 585575	g_socket_listener_add_inet_port() doesn't do the right thing
+ 585599	g_socket_listener_add_socket() consumes the socket
+ 585676	GEmblem doesn't reference its 'icon' if that is set as a ...
+ 585717	"bytes" nautilus translation to french is not shown in th...
+ 541276	XDG directories should have their own icons
+ 585726	Grammatical error in GList documentation
+ 585520	Wrong warning option in documentation
+ 585673	GNOME Goal: Remove deprecated glib symbols
+ 585591	Starting/stopping drives
+
+* Updated translations:
+ Bengali India
+ Norwegian bokmål
+
+
+Overview of Changes from GLib 2.21.0 to GLib 2.21.1
+===================================================
+
+* GIO:
+ - Support for network IO has been added, including a low-level
+   socket API and a high-level API for network connections and
+   services.
+ - Support for read-write access with GIOStream and its subclasses.
+ - GMount gained a pre-unmount signal.
+
+* Bug fixes:
+ 576104Implement GMount::pre-unmount
+ 578769 implement GWinHttpFileInputStream::close_fn
+ 582856	gsocket.c doesn't compile on Solaris
+ 569375	g[u]intptr undocumented
+ 573246	[FIX] g_desktop_app_info_dup() can access NULL pointer
+ 575013	g_cancellable_push_current() does not allow NULL
+ 577884	live-g-file.c:461: error: format ‘%d’ expects type ...
+ 578499	g_output_stream_splice and stream closing with gnio strea...
+ 579558	Application employing gvfs crashes with only libgvfscommo...
+ 583001	SIGPIPE (grr!)
+ 583061	Please add convenience function to connect to machines by...
+ 583198	typo in error message
+ 583206	use g_set_error_literal where appropriate
+ 583229	void function g_async_initable_init_async returns value
+ 583324	locking problem in g_main_context_iterate()
+ 583408	void function g_socket_control_message_serialize returns ...
+ 578786	wrong and confusing error message
+ 583205	g_inet_address_to_bytes has no length outparam
+ 583196	mem leak in keyfile test
+ 583663	GSocketType enum ends with a comma
+ 569024	Make g_error_new_valist public
+ 569376	missing G_G[U]INTPTR_FORMAT
+ 580347 off-by-1 bug in GWinHttpFile
+
+* Updated translations:
+ Oriya
+ Spanish
+ Valencian-Catalan
+
+
+Overview of Changes from GLib 2.20.x to GLib 2.21.0
+===================================================
+
+* GIO:
+ - New helper functions g_cancellable_connect/disconnect to avoid
+   race conditions when connecting to the "cancelled" signal on
+   GCancellable.
+ - New types and methods for dealing with IPv4 and IPv6 addresses (and
+   UNIX domain socket addresses under UNIX). This does not include code
+   for actual socket I/O.
+ - GResolver provides asynchronous and cancellable APIs for resolving
+   hostnames, reverse lookup of IP addresses and resolving SRV records.
+
+* Glib now provides hash and comparison functions for int64 and double
+  types, suitable for use with GHashTable.
+
+* GArray, GPtrArray and GByteArray can be ref counted now, and have
+  boxed types.
+
+* Bugs fixed:
+ 572844 Helper for GCancellable::cancelled connect/disconnect
+ 578363 goption docs should be improved
+ 548466 async/cancellable DNS resolver
+ 579830 param spec strings should use P_()
+ 579862 requesting xattr::foo ends up calling getxattr(..., user...
+ 580453 Hash and equal functions for gint64 and gdouble
+ 580450 Reference counting and boxed types for arrays
+ 580194 gresolver doesn't build on Solaris
+ 580301 network: a few issues on old darwin
+ 580299 network: include sys/types.h before sys/socket.h to insur...
+ 572508 gmarkup speedup
+ 580546 g_strtoull() referenced in documentation...
+ 580656 g_key_file_set_string_list erroneously asserts list != NULL
+ 579272 leaks in g_simple_async_result_set_op_res_gpointer
+
+
+* Updated translations:
+ Catalan (ca)
+ Pashto (ps)
+ Spanish (es)
+
+
+Overview of Changes from GLib 2.20.0 to GLib 2.20.1
+===================================================
+
+* Bug fixes:
+ 575555 Use fsync() when replacing files to avoid data loss on
+ 575708 runaway inotify madness
+ 575270 GVolumeMonitor::mount-pre-unmount not being emitted
+ 577128 glib make check Failed to execute child process...
+ 573673 Always show "backup" directories
+ 578369 g_time_val_from_iso8601() parses timezones incorrectly
+ 578002 Fix a small typo in GFile docs
+ 578017 G_DEFINE_TYPE_EXTENDED docs
+
+* Updated translations:
+ Arabic
+ Assamese
+ Basque
+ Bularian
+ Brazilian Portuguese
+ British English
+ Catalan
+ Danish
+ French
+ Galician
+ German
+ Greek
+ Hungarian
+ Italian
+ Japanese
+ Kannada
+ Lithuanian
+ Malayalam
+ Norwegian bokmål
+ Oriya
+ Polish
+ Punjabi
+ Russian
+ Simplified Chinese
+ Slovenian
+ Spanish
+ Swedish
+ Tamil
+
+
+Overview of Changes from GLib 2.19.9 to GLib 2.20.0
+===================================================
+
+* Base64 support: Avoid integer overflows. CVE-2008-4316
+
+* Bugs fixed:
+ 574019 GChecksum: document and guarantee hex characters in lower case
+ 573454 Unable copy/move files to directories symlinked to gvfs share
+ 561172 gnome-open fails on local URIs with anchors
+ 573970 crash in gunixvolumemonitor:update_mounts when unmounting
+ 573843 g_get_current_dir returns non-absolute path
+
+* Updated translations:
+ Assamese (as)
+ Bengali (bn_IN)
+ Czech (cs)
+ Hindi (hi)
+ Italian (it)
+ Japanese (ja)
+ Lithuanian (lt)
+ Malayalam (ml)
+ Marathi (mr)
+ Oriya (or)
+ Polish (pl)
+ Romanian (ro)
+ Telugu (te)
+
+
+Overview of Changes from GLib 2.19.8 to GLib 2.19.9
+===================================================
+
+* GMarkup:
+ - Considerable speedup
+
+* GIO
+ - Add G_FILE_CREATE_REPLACE_DESTINATION flag to allow replacing
+   the destination of a copying operation as if it did not exit before.
+ - Be more careful when classifying files as desktop files
+ - Support desktop file key X-GIO-NoFuse which disables the use
+   of fuse pathnames for %u and %U arguments
+
+* Bugs fixed:
+ 572672 glib/gthread.c: argument is different type
+ 572464 Doc for g_file_get_contents
+ 572151 “it's” and “its” confused in docs and comments
+ 570501 g_win32_get_system_data_dirs uses invalid conversion...
+ 167569 g_string_append_printf crashes on win32 when used...
+ 572508 gmarkup speedup
+ 560564 Replacing a symlink with its linked file truncates... 
+ 549298 impossible to copy files with p (pipe) flag
+ 543183 Clarify docs for g_file_has_prefix
+ 540461 g_memory_output_stream_get_data_size() doesn't behave...
+ 573462 GEmblemedIcon leak
+ 573421 Clarify message format in GMountOperation
+ 573658 Deadlock in giomodule.c
+ 556706 Inconsistent help arguments -h, -?
+ 573527 Wrong shell to run config.status in Makefile.in.in
+ 573128 A couple of typos in GObject documentation
+
+* Updated translations:
+ Catalan (ca)
+ British English (en_GB)
+ Spanish (es)
+ Basque (eu)
+ Finnish (fi)
+ French (fr)
+ Gujarati (gu)
+ Hebrew (he)
+ Hungarian (hu)
+ Korean (ko)
+ Maithili (mai)
+ Norwegian bokmål (nb)
+ Dutch (nl)
+ Portugese (pt)
+ Swedish (sv)
+ Thai (th)
+ Traditional Chinese (zh_HK)
+ Traditional Chinese (zh_TW)
+
+
+Overview of Changes from GLib 2.19.7 to GLib 2.19.8
+===================================================
+
+* GIO: Fix missing exports of new API
+
+* Fix strict aliasing warnings and violations to make Glib work
+  with gcc 4.4
+
+
+Overview of Changes from GLib 2.19.6 to GLib 2.19.7
+===================================================
+
+* GIO
+ - GFile gained an attribute for the actual file size in bytes
+ - GMountOperation gained an "aborted' signal that allows to abort
+   a mount operation from the backend side
+
+* Bugs fixed:
+ 523742 Use noinst for non-installable libraries
+ 566747 URIs opened with firefox %u load as local files
+ 541225 Can't compile gio on AIX duplicate case value in gioerror.c
+ 571598 GAsyncResult with NULL gobject
+ 505042 add file attribute for actually used file size in bytes
+
+* Updates translations:
+ Basque (eu)
+ Gujarati (gu)
+ Italian (it)
+ Japanese (ja)
+ Norwegian bokmål (nb)
+ Dutch (nl)
+ Portugese (pt)
+ Thai (th)
+ Vietnamese (vi)
+
+
+Overview of Changes from GLib 2.19.5 to GLib 2.19.6
+===================================================
+
+* New format macro to print goffset data: G_OFFSET_FORMAT
+
+* GIO: 
+ - Add a GFilter{Input,Output}Stream::close-base-stream properties which
+   determine whether the base stream will be closed when the filter stream
+   is finalized.
+ - g_data_input_stream_read_line and ..._read_until have asynchronous
+   variants now.
+
+* Bugs fixed:
+ 568294 A wrong reference in the description of g_bookmark_file_...
+ 563141 RFE: define G_OFFSET_FORMAT
+ 569105 g_time_val_to_iso8601() assumes time_t==long
+ 568394 dropping the last reference to a stream filter closes...
+ 568741 g_buffered_input_stream_fill_async doesn't work
+ 568723 g_buffered_input_stream_fill_async doesn't take count == -1
+ 568575 _async functions for GDataInputStream
+
+* Updated translations:
+ Bulgarian (bg)
+ Finnish (fi)
+ Hungarian (hu)
+ Oriya (or)
+ Swedish (sv)
+ Traditional Chinese (zh_HK)
+ Traditional Chinese (zy_TW)
+
+
+Overview of Changes from GLib 2.19.4 to GLib 2.19.5
+===================================================
+
+* Update included PCRE to 7.8
+
+* g_base64_decode_inplace: New function to do base64 decoding in place
+
+* Bugs fixed:
+ 567138 get_package_directory_from_module() does not free ...
+ 566569 gregex docs clarification
+ 566573 g_match_info_fetch_pos docs
+ 564728 Add function to decode base64 encoded data in place
+ 567838 G_STRUCT_OFFSETOF fails to compile under icc 9.1
+ 567977 textdomain() macro should not return NULL ...
+ 512779 --disable-regex breaks compilation
+ 566770 error code 0 for Too many open files is useless
+ 565484 g_content_type_guess passes non-UTF8 text to XDG ...
+
+* Updated translations:
+ Catalan (ca)
+ Spanish (es)
+ Italian (it)
+ Swedish (sv)
+
+ 
+Overview of Changes from GLib 2.19.3 to GLib 2.19.4
+===================================================
+
+* GIO:
+  - Use O_NOATIME when sniffing mimetypes
+  - Add a convenience method to check if a GSimpleAsyncResult
+    is valid
+
+* Bugs fixed:
+ 560676 function access for g_threads_supported
+ 565905 There is no g_context_group_set_translation_domain
+ 564210 SUN Studio 12 has supported visibility attribute
+ 565136 GObject's "notify" signal parameters are wrong in gtk-doc
+ 565831 error in interface creation sample
+ 566348 g_file_open_tmp uses the wrong g_mkstemp on win32
+ 566064 Add NOATIME flag to query_info_flags
+ 566170 g_async_result_verify_source_object
+
+* Updated translations:
+ Spanish (es)
+ Norwegian bokmål (nb)
+ Brazilian Portugese (pt_BR)
+ Simplified Chinese (zh_CN)
+
+
+Overview of Changes from GLib 2.19.1 to GLib 2.19.3
+===================================================
+
+* Bugs fixed:
+ 508021 Add support for the CRIS and CRISv32 architectures
+ 526320 should not list mounts that the user doesn't have permission to use
+ 558458 Cannot build gio tests on Solaris using SUN cc
+ 555465 GUnix{Input,Output}Stream lacks fd/close_fd_at_close property
+ 558298 Hide ecryptfs mounts
+ 515777 incorrect date&time on copy
+ 562452 Ensure we return G_IO_ERROR_CANCELLED if cancelling
+        g_simple_async_result_run_in_thread
+ 473150 g_type_module_use inconsistently increases the use
+        counter in case of error
+ 563150 G_GU?INT*_MODIFIER/FORMAT docs
+ 563156 Document printing and scanning gunichar values
+
+* Updated translations:
+ Hebrew (he)
+ Italian (it)
+ 
+
+Overview of Changes from GLib 2.19.0 to GLib 2.19.1
+===================================================
+
+* GIO: 
+  - g_icon_to_string, g_icon_new_for_string: GIcon serialization support
+  - G_FILE_ATTRIBUTE_PREVIEW_ICON: new file attribute for preview images
+  - g_app_info_get_commandline: new function to get the full commandline
+  - g_mount_shadow, g_mount_unshadow, g_mount_is_shadowed: New functions 
+    to 'shadow' mounts (i.e. hide them from the UI when they already
+    have a different representation, like a bookmark) 
+
+* Bugs fixed:
+ 556186 gpoll.h breaks gmain.h inclusion
+ 557087 mem leak in g_content_types_get_registered
+ 556921 gpoll.h breaks hal compilation
+ 557210 g_compute_checksum_for_* asserts with less than 2 bytes
+ 558381 Add support for compile time assertions
+ 558185 'parent' variable in g_local_file_get_child_for_display_name()
+        hits g_object_unref(NULL) assertion
+ 558513 g_warn_if_fail FIXME in gtestutils
+ 558672 NULL key lookup using g_hash_table_lookup_extended() 
+ 555740 gicon serialization
+ 557182 preview functionality
+ 528320 Incorrect icons displayed for files with custom mimetype icons
+ 556910 Memory leak: sub
+ 557592 Missing include in gwinhttpfile.c
+ 556415 Crash on Windows 2000 in g_winhttp_vfs_init()
+ 555935 Clarify the mechanism of overwriting properties
+ 552776 ac_cv_func_posix_getgrgid_r not mentioned
+ 559448 GObject Reference Manual (typo)
+ 561212 GFileReadMoreCallback API doc refers to non-existant function
+ 560569 gkeyfile doesn't use the set list_separator in some cases
+ 560568 gkeyfile docs buglet
+ 559413 g_option_group_set_error_hook docs buglet
+ 562378 callback return value not respected for callback option
+        with no arg
+ 559110 Do not include libintl.h after glibintl.h
+ 557603 carbon check output misplaced
+ 562544 g_key_file_get_string and g_key_file_get_value
+        documentation does not explain the difference
+ 547264 Missing "no flags" flag
+ 562638 GDebugKey key member should be const
+ 562639 g_parse_debug_flags() parsing "help"
+ 562549 g_byte_array_free should tell how free data
+ 559452 GObject Reference Manual (typo)
+ 559462 GObject Reference Manual (typo)
+ 559517 GObject Reference Manual (typo)
+ 562538 GObject interface tutorial shouldn't finalise with
+        "Please forget everything"
+ 561352 Leak of icon description
+ 561375 Leaks mountpoint description
+ 561807 inotify_sub.c: dup_dirname() fails to remove trailing '/'
+ 562393 g_buffered_input_stream_read_byte broken if data available
+ 541715 win32 : patch for warnings and signature problems in recent code
+ 547481 g_data_input_stream_read_line behaves not as stated in the docs
+ 548163 Nautilus displays wrong error message for too long file names
+ 559633 gtk_image_new_from_gicon does not always work for .desktop files
+ 555486 – No way to recover command line from GAppInfo
+
+* Translation updates:
+ Spanish (es)
+ Ukrainian (uk)
+
+
+Overview of Changes from GLib 2.18.1 to GLib 2.19.0
+===================================================
+
+* Rewrite GHashTable to use open addressing with quadratic probing instead 
+  of chaining. This has the potential to reduce memory fragmentation 
+  significantly, while being slightly faster due to better locality and 
+  no need to call alloc/free functions for nodes. Benchmarks suggest it 
+  also uses less memory overall.
+
+* Make g_poll available as public api
+
+* New macros g_assert_error and g_assert_no_error to assert 
+  that a GError is set or unset
+
+* g_cancellable_make_pollfd: New method to make a GPollFD for a cancellable
+
+* g_app_info_can_delete, g_app_info_delete, g_app_info_reset_type_associations:
+  New functions to clean up app infos and content types
+
+* When launching applications, always pass fuse file:// uris when possible,
+  and let gio convert such uris back to gio uris.
+
+* Bugs fixed:
+ 505361 gunixinputstream.c assumes poll() available
+ 509446 portable blocking gio cancellation
+ 553820 gpoll.c: undeclared identifier
+ 553724 python interpretter path not patched in correctly
+ 553857 gbacktrace.h requires signal.h
+ 553447 g_assert_no_error()
+ 554092 glib doesn't return G_FILE_ERROR_NOENT et al on OS X
+ 528670 Always pass file:/// uri's in GAppLaunchContext
+ 555224 Improve g_format_size_for_display doc
+ 555309 giochannel breaks on error
+ 554790 g_convert() misbehaves with winiconv versions
+ 555314 mem leak in gmarkup
+ 555313 GFileAttribute boxed type get_type function should...
+ 552861 glib-2.0.m4 calls system(3) without storing its result
+ 554557 Patch to fix gcc warnings about missing format specifiers
+ 552107 Small libtool fixes
+ 551355 Make glib build with libtool 2.2
+ 555311 format not a string literal and no format arguments
+ 556101 static mutex yields warnings with g++
+ 556186 gpoll.h breaks gmain.h inclusion
+ 526456 Open addressing in GHashTable
+ 553426 cancellable clarifications
+ 545350 GAppInfo deletion
+ 545351 Reset associations for content type
+ 552168 volume's mount not mounted after g_volume_mount_finish
+ 554970 segfault when update-desktop-database is not available...
+ 554745 GFileAttributeInfoList should be boxed
+ 555121 Improved build-time handling of gio module-dir
+ 555711 Wrong fallback order of mimetype icons
+ 555331 Deprecate adoption of mounts
+ 556335 make check fails in abicheck.sh
+ 556334 Warning when building without selinux support
+ 556422 g_file_enumerator_next_file: unclear...
+
+* Updated translations:
+ Arabic (ar)
+ Danish (da)
+ Polish (pl)
+ Brazilian Portugese (pt_BR)
+ Romanian (ro)
+ Russian (ru)
+
+
+Overview of Changes from GLib 2.18.0 to GLib 2.18.1
+===================================================
+
+* Bugs fixed:
+ 550433 g_test_init doesn't recognize --help
+ 523463 Core dump in gmain.c:2482:IA__g_main_context_check
+ 551228 G_STRFUNC on recent Sun compiler should be expanded...
+ 551410 gtestutils.c: using printf without prototype
+ 551731 g_date_set_time[_t] docs should mention what timezone
+ 548321 <string.h> is not included in gi18n-lib.h
+ 551149 xdgmime mem leak
+ 550647 synchronous pipe I/O when reading mount reply
+ 551887 Docs for g_desktop_app_info_new_from_filename aren't...
+ 551681 g_content_type_guess() too naive with filenames
+ 552352 g_app_info_launch doesn't work if "Path" key...
+ 551408 gmodule.def generated to builddir...
+ 552359 g_file_info_get_icon should return GThemedIcon, and...
+
+* Updated translations:
+ Arabic (ar)
+ Bengali India (bn_IN)
+ British English (en_GB)
+ Hindi (hi)
+ Croatian (hr)
+ Korean (ko)
+ Oriya (or)
+ Turkish (tr)
+ Telugu (te)
+
+
+Overview of Changes from GLib 2.17.7 to GLib 2.18.0
+===================================================
+
+* Win32:
+  - rework the g_poll() implementation to match poll() semantics more closely
+
+* Bugs fixed:
+ 324234 Using g_io_add_watch_full() to wait for connect() to return...
+ 548278 Async GETs connections are always terminated unexpectedly...
+ 500246 Bug fixes for giowin32
+ 523939 Example program for GValue
+ 550096 GBookmarkFile parser is not forward compatible
+ 550040 Move GString, rand and printf tests to the unit test framework
+ 550104 trivial documentation fix for g_get_home_dir
+ 548988 g_file_replace fails on Windows when the target file exists
+ 550059 Wrong docs for g_emblemed_icon_add_emblem
+ 548800 Missing a g_object_get_type function
+ 550056 Missing documentation for g_emblemed_icon_get_emblems
+
+* Updated translations:
+ Bulgarian (bg)
+ Czech (cs)
+ German (de)
+ Estonian (et)
+ Basque (eu)
+ French (fr)
+ Hebrew (he)
+ Hungarian (hu)
+ Italian (it)
+ Japanese (ja)
+ Lithuanian (lt)
+ Maithili (mai)
+ Dutch (nl)
+ Swedish (sv)
+ Thai (th)
+ Ukrainian (uk)
+ Vietnamese (vi)
+
+
+Overview of Changes from GLib 2.17.6 to GLib 2.17.7
+===================================================
+
+* More fixes for 64-bit Windows
+
+* GIO
+ - Add a vfs implementation for HTTP and HTTPS URIs on Windows
+
+* Bugs fixed:
+ 546329 API docs for g_utf8_normalize() are incorrect
+ 546876 Modify GMarkup parser to accept &#x1; .. &#x1f;
+ 547200 g_utf8_find_next_char() issues
+ 547637 unconditional #include of sys/statfs.h in configure
+ 547337 G_DISABLE_DEPRECATED breaks tests build
+ 547832 gtk+-2.12.11 fails to build - AC_PROG_MMAP too strict
+ 502498 Test framework assertion failures should follow gcc
+ 546371 Improve docs re g_file_monitor
+ 546483 GThemedIcon:use-default-fallbacks is not readable without...
+ 546132 GFileIcon is bindings-unfriendly
+ 542156 zfs mount in home directory shown on nautilus desktop 
+ 535124 umask 002 not being applied for new directories...
+ 547080 g_file_copy leaks expected errors
+ 546582 Callbacks from GFileMonitor present a GFile...
+ 547262 Missing link in the docs
+
+* Updated translations:
+ Arabic (ar)
+ Catalan (ca)
+ Spanish (es)
+ Basque (eu)
+ Finnish (fi)
+ Galician (gl)
+ Hebrew (he)
+ Marathi (mr)
+ Norwegian bokmål (nb)
+ Portugese (pt)
+ Brazilian Portugese (pt_BR)
+ Swedish (sv)
+ Thai (th)
+
+
+Overview of Changes from GLib 2.17.4 to GLib 2.17.6
+===================================================
+
+* Fix problems on 64-bit Windows
+
+* g_markup_context_get_user_data: New function to access
+  the user_data outside of callbacks
+
+* GIO
+ - g_mount_guess_content_type_sync: synchronous version of
+   g_mount_guess_content_type
+ - GEmblem: A GIcon implementation that adds emblem-related
+   metadata to icons
+ - GEmblemedIcon: A GIcon implementation that can add emblems
+   to icons
+
+* Bugs fixed:
+ 544088 option_test_LDADD is left in tests/Makefile.am
+ 544465 gmarkup makes it hard to use pre-rolled parsers
+ 545485 Implicit declaration of utime()
+ 545798 "Since: 2.18" mark is missing in g_set_error_literal...
+ 544140 fam-helper 64-bit issue
+ 529694 SELinux context setting support
+ 545157 wrong/no list of "open with" applications for .cc...
+ 545203 gfile.c: argument is different type
+ 545457 gdmsetup crashed with SIGSEGV in g_unix_mount_guess...
+ 544177 Fix trivial cut and paste error in documentation
+ 545395 Language tweak for g_value_set_string* docs
+ 541036 Gnumeric crashes when trying to open Desktop...
+ 546079 leak in xdgmime
+ 545395 Language tweak for g_value_set_string* docs
+ 546017 Don't copy attributes when copying a symlink
+
+* Updated translations:
+ Arabic (ar)
+ Estonian (et)
+ Galician (gl)
+ Italian (it)
+ Japanese (ja)
+ Korean (ko)
+ Norwegian bokmål (nb)
+ Pashto (ps)
+ Portugese (pt)
+
+
+Overview of Changes from GLib 2.17.3 to GLib 2.17.4
+===================================================
+
+* GIO:
+ - New API to handle content types: g_mount_guess_content_type,
+   g_content_type_guess_for_tree.
+ - Export the eject-button signal on the volume monitor class
+ - New API to enable out-of-process volume monitors: 
+   g_volume_get_activation_root
+
+* GObject:
+ - New API to handle signals without slots in the class structure:
+   g_signal_new_class_handler, g_signal_override_class_handler   
+
+* Internationalization:
+ - Add an NC_ macro that is a no-op equivalent of C_
+
+* GMarkup:
+ - Add two new functions g_markup_parse_context_push,
+   g_markup_parse_context_pop to support "subparsers"
+
+* Bugs fixed:
+ 541208 Functions to easily install and use signals without...
+ 541507 Ambiguous description of assigned characters in the...
+ 543040 async reading on dummy file will crash on GIO_USE_VFS=local
+ 543560 enable gio-FEN back-end warnings on Solaris will crash...
+ 528317 GRegex does not allow recursion limit
+ 337518 GMarkup: Subparser support
+ 541794 drive-eject-button signal
+ 541793 activation root for volumes
+ 467707 test_iconv_state() in tests/convert-test.c fails on AIX 5.3
+ 428048 2 of 51 tests fail on Solaris
+ 542332 small fix for error message in GMarkup
+ 482413 get_contents_stdio -- overflow and memory corruption
+ 406120 g_ascii_strtod
+ 334234 "printf" format error
+ 536996 Missing noop i18n macro equivalent to C_
+ 540616 mem leak in filechooser button
+ 539229 gobject-query calls itself query
+ 521589 [RFC] gobject documentation should mention Vala
+ 543168 Description of G_SLICE=debug-blocks discourages its use
+ 543220 Case collision on gio-extension-points.html
+ 530759 update the gobject tutorial to the XXI century
+ 535223 gbookmark file inefficiency ...
+ 543504 crash in Epiphany Web Browser: Opening local file
+
+* Updated translation:
+ German (de)
+ Estonian (et)
+ Pashto (ps)
+ Albanian (sq)
+ Thai (th)
+ Traditional Chinese (zh_HK)
+ Traditional Chinese (zh_TW)
+
+
+Overview of Changes from GLib 2.17.1 to GLib 2.17.3
+===================================================
+
+* PCRE
+ - fix for CVE-2008-2371 
+
+* Bugs fixed:
+ 538119 glib's mainloop leaks a pipe to sub-processes
+ 537635 Corrections and improvements to g_time_val_{to,from}_iso8601
+ 539067 The document g_io_channel_win32_new_fd() says...
+ 535949 annotate g_strip_context and g_dpgettext with G_GNUC_FORMAT
+ 539123 annotate g_d[n]gettext with G_GNUC_FORMAT
+ 539074 Cannot get exit status with g_spawn_command_line_sync
+ 316221 G_LOCK warns about breaking strict-aliasing rules
+ 539770 migrate gstrfunc unit tests to gtest
+ 539626 Update docstrings for g_object_freeze_notify and g_object_thaw_notify
+ 538044 unconditional use of LC_MESSAGES
+ 540545 Monotonic time and timer offset
+ 535947 want g_set_error_literal
+ 539999 glibconfig.h: add GLIB_USING_SYSTEM_PRINTF 
+ 536252 GFileEnumerator should allow access to the containing GFile
+ 538362 Get Win32 icons back in the file chooser
+ 540802 g_list_prepend doesn't concat lists
+ 540423 unrecoverable error after g_seekable_truncate
+ 538836 make check failure on PPC and ALPHA: pltcheck.sh on g_atomic_pointer_get
+ 539090 g_content_type_from_mime_type() should unalias
+ 540331 g_file_append_to () documentation: can return NULL
+ 534639 add g_desktop_app_info_new_from_keyfile
+ 536733 gio build failure on Irix
+ 536160 Add g_file_monitor()
+ 538127 FileChooser broken on win32
+ 531476 /live-g-file/test_traverse_structure test fails on Mac HFS+
+ 538564 gio should have gio-types.h
+ 540047 glib-genmarshal.c: '#include <io.h>' is too before
+
+Updated translations:
+ Korean (ko)
+ Occitan (oc)
+
+
+Overview of Changes from GLib 2.17.0 to GLib 2.17.1
+===================================================
+
+* New function: g_utime(), a gstdio wrapper for utime()
+
+* New functions: g_dgettext() and g_dngettext(), wrappers
+  for corresponding gettext functions with added functionaliy
+
+* Support the latest version of the shared-mime spec, including
+  icons for mime types 
+
+* New function: g_themed_icon_prepend_name()
+
+* Bugs fixed: 
+ 535418 Please document which glib version defines goffset
+ 528715 Misprint in the description of the interface g_type_class_add_private
+ 528714 Misprint in the description of the interface g_param_spec_flags
+ 537260 Doc bug in G_TYPE_INSTANCE_GET_CLASS()
+ 530527 Misprint in the description of the interface 
+        g_cclosure_marshal_VOID__FLAGS
+ 530526 Misprint in the description of the fields 'class_init' and 
+        'class_finalize' of the structure GTypeInfo
+ 528719 Improvement to the documentation of the "g_object_connect" interface
+ 528172 gtk_signal_handlers_unblock_* functions return value
+        amount of matched signals, not amount of actually unblocked
+ 528717 Misprint in the description of the parameter 'type_id' for 
+        the interface g_type_register_fundamental
+ 528716 Misprint in the description of the parameter 'iface_data' for 
+        the callback types GInterfaceInitFunc and GInterfaceFinalizeFunc 
+ 537555 GObject instantiation not thread safe
+ 537546 'desktop' shortcut in file chooser looks like a generic folder
+ 537392 Additional colon in xattr name
+ 536641 Filesystem querying in gio does not list AFS and autofs file systems
+ 528600 g_dummy_file_get_parent("scheme://example.com/")
+ 503071 Application direction changes to right to left even if theres no 
+        translation
+ 502511 g_assert_cmphex prints invalid message
+ 338162 Use po/LINGUAS
+ 314453 Nautilus crashes in Solaris when browsing the attached file
+ 529321 make check fails in glib/pcre
+ 455215 g_get_user_special_dir: no reference about G_USER_DIRECTORY_DOWNLOAD 
+        fallback to $HOME/Desktop if xdg-user-dirs is not in use
+ 498732 g_key_file_to_data cannot fail
+ 511367 add g_file_make_directory_with_parents
+ 531900 Use __builtin_offsetof for G_STRUCT_OFFSET if building with 
+        gcc 4.0 or newer
+ 536158 also bump GHashTable version when a node is removed via
+        g_hash_table_iter_remove()/g_hash_table_iter_steal()
+ 531403 g_utf8_collate broken on Mac
+ 535628 test/patterntest.c still includes gpattern.h directly
+ 535625 alias.h:2648: error: 'utime' undeclared here (not in a function)
+
+* Translation updates:
+ Arabic (ar)
+ German (de)
+ Italian (it)
+ Norwegian bokmål (nb)
+ Thai (th)
+
+
+Overview of Changes from GLib 2.16.x to GLib 2.17.0
+===================================================
+
+* Update to Unicode 5.1
+
+* Update included libcharset to the one shipped with libiconv 0.12
+
+* Update included PCRE to 7.7
+
+* Enforce that only toplevel headers are directly included.
+  This is turned on by default for GObject and GIO. To turn
+  it on for GLib, define G_DISABLE_SINGLE_INCLUDES.
+
+* Fix library version of GIO.  GLib 2.16 shipped with libgio-2.0.so.0.0.0
+
+* On Solaris, use FEN for file monitoring in GIO
+
+* Use the GIO_EXTRA_MODULES environment variable to find
+  additional GIO modules 
+
+* G_GNUC_ALLOC_SIZE: New macro that wraps the gcc alloc_size
+  function attribute
+
+* g_checksum_reset: New function to reset the state of a GChecksum 
+
+* g_unix_mount_monitor_set_rate_limit: New function to limit the 
+  rate at which events are reported
+
+* g_file_query_file_type: New utility function to query the type of
+  a file
+
+* g_memory_output_stream_get_data_size: New function to obtain the
+  size of the written data.
+
+* Bugs fixed:
+ 522292 Gives warnings in glib/gutils.h with GCC in C99 mode
+ 523298 win_iconv can't convert from UTF-8 to GB18030 (or vice versa)
+ 518160 replace two g_strdup_printf calls in GBookmarkFile
+ 523877 gbookmarkfile: avoid using g_string_append_printf() and
+        other optimizations 
+ 525192 100% CPU if run main loop with no IO sources
+ 315437 extern inline -> static inline
+ 524314 g_convert() on Win32 implicitly converts full width
+        alphanumerics into half width
+ 525732 Error in documentation for g_list_first
+ 525674 A typo in gmarkup.c
+ 448943 g_timeout_add_seconds() problems
+ 525972 UCS-4 not in the new win_iconv implementation
+ 526619 make test-report crash
+ 491554 Update to Unicode 5.1.0
+ 519137 g_slice_dup macro needs cast for 64-bit platform
+ 528752 Win32 build and SSL not working
+ 530457 G_USER_DIRECTORY_DOWNLOAD folder improperly mapped
+ 528667 Typos in testing module documentation
+ 459905 Bug in wcwidth data
+ 534085 g_unichar_iswide_cjk() has a totally wrong table
+ 501651 Update glib/libcharset
+ 519026 G_STMT_START/G_STMT_END test a non-existent preprocessor symbol
+ 534319 GLib's .pc files could use Libs.private
+ 534137 Typo in g_spawn_async_with_pipes doc
+ 517419 gio win32 directory monitor
+ 526796 Wrong order of arguments in g_file_copy's fallback
+ 530196 _g_local_file_has_trash_dir() doesn't handle st_dev == 0
+ 532965 Should not return filesystem::free for certain file systems
+ 525553 fix typo and nitpicking in GArray documentation
+ 526572 Missing * in declaration of parent_class in Object
+        Destruction section of GObject Reference Manual
+ 528648 Extra >s in Object Construction section
+ 535021 g_param_spec_internal documentation should
+        describe purpose of nick and blurb
+ 521513 Firefox crash when using file picker
+ 528433 gdesktopappinfo snafu ...
+ 533369 API g_file_info_get_attribute_string () unables to get "...
+ 521045 glib f_fstypename miscellany
+ 521672 compile error
+ 521946 control rate limit on GUnixMountMonitor
+ 522335 Fails to build: glib/gtester.c:276: error: 'ARG_MAX' unde...
+ 523015 Implement sliding window based upload operation
+ 523019 Use new GCC 4 feature
+ 523338 list nfs4 as a nfs mount type
+ 524350 Make glib build without NLS again
+ 524579 g_file_copy reports wrong total on progress callback for ...
+ 524742 A typo in gtestutils.c.
+ 524950 Minor documentation typos.
+ 525866 the user directory should not be considered as a mount to...
+ 526320 should not list mounts that the user doesn't have permiss...
+ 527132 nautilus crash when making ftp connection
+ 532852 CRITICAL **: totem_pl_parser_parse_with_base: assertion `...
+ 534759 Build failure in gio
+ 534764 Typo in error produced by g_file_make_directory
+ 521851 Redudant tests in gunixmounts.c
+ 524344 glib/gthread.h still use G_GNUC_PRETTY_FUNCTION
+ 525060 glib fails to build with -DG_DISABLE_ASSERT in CPPFLAGS o...
+ 534177 Invalid description of the interface g_cclosure_marshal_S...
+ 520715 Add GFile method g_file_query_file_type
+ 523039 nautilus can't access to trash/computer/network if gvfs i...
+ 
+* Updated translations:
+ Arabic (ar)
+ Bulgarian (bg)
+ Catalan (ca) 
+ Czech (cs)
+ Greek (el)
+ Candian English (en_CA)
+ British English (en_GB)
+ Spanish (es)
+ Estonian (et)
+ Basque (eu)
+ Galician (gl)
+ Hebrew (he)
+ Hungarian (hu)
+ Japanese (ja)
+ Lithuanian (lt)
+ Norwegian bokmål (nb)
+ Dutch (nl)
+ Occitan (oc)
+ Portugese (pt)
+ Russian (ru)
+ Slovak (sk)
+ Albanian (sq)
+ Swedish (sv)
+ Turkish (tr)
+ Vietnamese (vi)
+
+
+Overview of Changes from GLib 2.16.0 to GLib 2.16.1
+===================================================
+
+* Fix a crash in g_themed_icon_new
+
+* Update the included PCRE to 7.6
+
+
+Overview of Changes from GLib 2.15.6 to GLib 2.16.0
+===================================================
+
+* Fix the definition of G_INLINE_FUNC to work with gcc 4.3.0
+
+* GIO:
+ - Add missing GMountMountFlags argument to g_unix_volume_mount
+ - Fix the adopt_orphan_mount vfunc to take a volume monitor 
+   reference
+ - Add properties to GThemedIcon for bindings sake
+
+* Bugs fixed:
+ 520484 gvfsd-trash crashed with SIGSEGV in g_path_is_absolute()
+ 510855 g_checksum_update(): Take -1 for length.
+ 517676 g_themed_icon_new*() do more than call g_object_new().
+ 518816 should handle rmdir returning EEXIST correctly
+ 519352 g_[s]list_delete_link() docs
+ 519489 Fixes for sparse warnings in gio
+ 520169 add monitor argument to vfunc for GVolumeMonitor
+ 520700 Add type check in g_file_query_exists
+ 521145 FILE_READ_ONLY_VOLUME not present on Mingw32
+ 518720 No MIME type for empty files
+ 521013 in documentation, goffset doesn't say "Since 2.x"
+ 521028 Missleading error messages from g_io_channel_set_encoding()
+ 517484 GMainLoop could set the thread "Alertable" for APCs to be... 
+
+* Updated translations:
+ Assamese (as)
+ Bengali India (bn_IN)
+ Czech (cs)
+ German (de)
+ Spanish (es)
+ Estonian (et)
+ Finnish (fi)
+ French (fr)
+ Gujarati (gu)
+ Italian (it)
+ Lithuanian (lt)
+ Malayalam (ml)
+ Marathi (mr)
+ Norwegian bokmål (nb)
+ Romanian (ro)
+ Russian (ru)
+ Slovak (sk)
+ Ukrainian (uk)
+
+ 
+Overview of Changes from GLib 2.15.5 to GLib 2.15.6
+===================================================
+
+* GIO:
+ - New file attributes: trash::item-count, filesystem::use-preview
+ - Rename g_file_contains_file to g_file_has_prefix
+ - g_file_query_filesystem_info grew async variants
+ - g_themed_icon_append_name: new convenience function
+ - g_content_type_get_icon is implemented now
+ - Only show mounts in /media and ~
+ - g_file_contains_file has been renamed to g_file_has_prefix
+
+* Win32:
+ - g_win32_get_package_installation_directory_of_module: new function
+   which supersedes g_win32_get_package_installation_directory
+ - Use alertable wait functions so that I/O completion routines or 
+   user-mode Asynchronous Procedure Calls can be run
+ - Fix race conditions in g_spawn implementation on win32
+
+* Other:
+ - g_uri_get_scheme has been renamed go g_uri_parse_scheme
+
+* Updated translations:
+ Arabic (ar)
+ Belarusian Latin (be@latin)
+ Catalan (ca) 
+ British English (en_GB)
+ Finnish (fi)
+ Galician (gl)
+ Hebrew (he)
+ Italian (it)
+ Kannada (kn)
+ Norwegian bokmål (nb)
+ Dutch (nl)
+ Brazilian Portugese (pt_BR)
+ Vietnamese (vi)
+
+
+Overview of Changes from GLib 2.15.4 to GLib 2.15.5
+===================================================
+
+* Update the included PCRE to 7.6
+
+* GIO:
+ - g_volume_should_automount: new function to determine if a volume
+   should be mounted automatically
+ - g_file_query_default_handler: new convenience function to get
+   the default handler for a file
+ - g_app_info_launch_default_for_uri new convenience function to
+   launch the default handler for a URI
+ - Use mimeapps.list and defaults.list as discussed on xdg list
+   recently
+ - g_app_info_get_default_for_uri_scheme has a real implementation
+   now (gvfs provides a GConf-based implementation)
+ - There is the beginning of a test suite
+ - standard::description:  new file attribute
+ - GMountMountFlags flags argument added to mount calls
+
+* GObject:
+ - class initialization is now threadsafe
+
+* Updated translations:
+  Arabic (ar)
+  Catalan (ca)
+  Spanish (es)
+  Basque (eu)
+  Italian (it)
+  Japanese (ja)
+  Kannada (kn)
+  Korean (ko)
+  Macedonian (mk)
+  Occitan (oc)
+  Portugese (pt)
+  Brazilian Portugese (pt_BR)
+  Swedish (sv)
+  Thai (th)
+
+
+Overview of Changes from GLib 2.15.3 to GLib 2.15.4
+===================================================
+
+* G_GNUC_PRETTY_FUNCTION has been deprecated
+
+* GIO:
+ - g_file_copy has an async variant now
+ - Drives and volumes now have API to get identifiers
+   like Hal UDIs or UUIDs.
+ - There is now a registration API to let modules register
+   extensions they provide, such as volume monitor implementations
+
+* Bugs fixed:
+  511807 g_time_val_to_iso8601() uses MT-unsafe gmtime() function
+  316260 [patch] Doc patches for gnode (2.8.1)
+  385132 solaris gettext support fix
+  484261 ./configure check for system PCRE unicode support fails w...
+  510292 GOption main help not shown
+  511580 Implement g_file_copy_async
+  511654 Compile errors due to C99 constructs
+  487909 g_utf8_strreverse and combining marks
+  512381 unused variable 'is_main_group' 
+
+* Updated translations:
+  Arabic (ar)
+  Belarusian (be)
+  Czech (cz)
+  Spanish (es)
+  French (fr)
+  Galician (gl)
+  Portugese (pt)
+  Russian (ru)
+  Swedish (sv)
+  Thai (th)
+
+
+Overview of Changes from GLib 2.15.2 to GLib 2.15.3
+===================================================
+
+* GChecksum:
+ - g_checksum_update can accept nul-terminated strings
+ - The MD5 implementation works correctly on buffers 
+   that are longer than 64 bytes
+
+* GIO:
+ - Don't include a copy of the inotify headers, rely on system headers
+ - g_file_find_enclosing_mount has an async variant now
+ - Reduntant seek API on file streams has been removed
+
+* Bugs fixed:
+  508602 gmemory{in|out}putstream.c: unknown pointer size
+  508771 There is no g_file_test/exists() for GFile
+  508773 g_uri_escape_string() documentation unclear.
+  509465 AM_PATH_GLIB_2_0 doesn't support gio
+  509626 async functions: Document allowed NULL callback?
+  509990 GSeekable documentation unclear
+  510448 No inotify support on ARM or SH5
+  510855 g_checksum_update(): Take -1 for length. 
+
+* Updated translations:
+  Basque (eu)
+  Marathi (mr)
+  Swedish (sv)
+  Ukrainian (uk)
+
+
+Overview of Changes from GLib 2.15.1 to GLib 2.15.2
+===================================================
+
+* GIO:
+ - Mount operation API change: unhandled methods get reported via 
+   the reply, rather than by the signal emission return value
+ - File monitor API change: Add a GError argument to g_file_monitor_file
+ - g_unix_mount_guess_should_display(): new function
+
+* Bugs fixed:
+  508224 [PATCH] FAM backend crashes due to double free
+  508074 GAsyncResult documentation suggests g_freeing it.
+  508108 GFile documentation slightly unclear.
+  508309 rpc_pipefs mount points should be hidden
+  508378 GFileInfo documentation implies that it changes attribute...
+  508719 g_file_get_relative_path fails if parent is root
+  508773 g_uri_escape_string() documentation unclear.
+
+* Updated translations:
+  Arabic (ar)
+  Spanish (es)
+  Hebrew (he)
+  Italian (it)
+  Korean (ko)
+  Turkish (tr)
+
+
+Overview of Changes from GLib 2.15.0 to GLib 2.15.1
+===================================================
+
+ * Portability fixes:
+ - Assertion functions are marked as noreturn again
+ - Handling of inline functions has been fixed to work with gcc 4.3
+ - C99 comments have been removed from headers
+ - The nonportable sed -i option is no longer used
+
+ * GIO:
+  - Clarified the semantics of g_app_info_get_all()
+  - API for memory input and output streams has been changed a bit
+  - GDirectoryMonitor has been removed; GFileMonitor can monitor
+    files and directories now
+
+ * Bugs fixed:
+   504829 Invalid environment passed to g_spawn_async in g_desktop_...
+   505258 crash in Users and Groups: Adding a user
+   505815 g_content_types_get_registered should not g_free keys
+   491218 g_timer_new() doesn't initialize timer->end
+   315437 extern inline -> static inline
+   476856 Inconsistency between standard and implementation of the ...
+   480122 g_module_open fails to open modules with ".la" extension
+   495589 gspawn.c failing to set FD_CLOEXEC
+   500273 doesn't build with --disable-visibility
+   504142 Do not show empty groups in --help output
+   504879 giofam incorrectly linked
+   505042 add file attribute for actually used file size in bytes
+   505058 xattr namespace docs
+   505674 Misprint in the definition of the macro G_CCLOSURE_SWAP_DATA
+   505730 Fails to build on OSX 10.4: _NSGetEnviron not declared
+   505887 older darwin lacks lchown
+   506374 gmemoryinputstream api
+   506461 Conversion of g_assert_not_reached() and friends into fun...
+   503051 Small bug in glib interface
+   506395 Updates to GIO documentation
+   507628 Missing .pc entry for gio linking against glib
+   505195 [patch] typo in g_try_new0 docs 
+   507822 g{file,directory}monitor changes signal problem
+   506377 gmemoryoutputstream write implementation
+   507835 bug in gunixinputstream 
+
+ * Updated translations:
+   Arabic (ar)
+   Belarusian Latin (be@latin)
+   Spanish (es)
+   Basque (eu)
+   Irish (ga)
+   Hebrew (he)
+   Occitan (oc)
+   Vietnamese (vi)
+
+
+Overview of Changes from GLib 2.14.x to GLib 2.15.0
+===================================================
+
+Major new features:
+
+ * GIO: a VFS API, designed to replace GnomeVFS. The GIO implementation 
+   in GLib has support for local filesystems. The new, separate gvfs 
+   module contains various backend implementations (cifs, ftp, sftp,
+   http, ...)
+
+ * GChecksum: provides various hash algorithms, such as MD5, SHA-1
+   and SHA-256
+ 
+ * GTest: a test framework 
+ 
+Smaller additions:
+
+ * GHash:
+ - GHash has iterators, as an alternative to g_hash_table_foreach
+
+ * GMarkup: 
+ - g_markup_parse_context_get_element_stack: New function to
+   get the stack of open elements
+ - G_MARKUP_PREFIX_ERROR_POSITION: New flag to improve error
+   reporting
+ - g_markup_collect_attributes: Convenience function for handling
+   attributes
+
+* GKeyFile: 
+ - Functions that take a GError now return a boolean to indicate 
+   success, instead of void
+ - Various performance improvements
+
+* GAsyncQueue:
+ - g_async_queue_new_full: new function that allows to specify
+   a free function for leftover elements
+ 
+* GError:
+ - g_prefix_error and g_propagate_prefixed_error: New functions
+   to ease error propagation
+
+* Internationalization:
+ - C_: A new 2-argument variant of the Q_() macro 
+ - Use native character set conversion API on Windows
+
+* GLib builds with automake 1.10
+
+* Bugs fixed:
+ 455725 specific combination of g_utf8_strlen and g_pattern_match...
+ 467537 g_convert_with_iconv() not resetting iconv() state correc...
+ 497033 Commandline option parser should warn about missing optio...
+ 504527 gchecksum: Conditional jump or move depends on uninitiali...
+ 445362 Non-numeric local labels in gatomic.c are causing linker ...
+ 482313 gregex: no way to tell why compilation failed
+ 317775 main loops continues to run after g_main_loop_quit() has ...
+ 418778 Insufficient pkg-config version requirement
+ 436293 g_option_context_new() doc should mention that the string...
+ 466557 glib-mkenums shifts ARGV[0] to undefined
+ 468882 GKeyFile doesn't accept "True" as a true boolean value
+ 469551 application --help messages are garbaged on none UTF-8 lo...
+ 479724 Memory leak upon calling "g_main_loop_run" in the seconda...
+ 490061 outptrs uninitialized after g_parse_long_long
+ 490637 gobject documentation patch
+ 495294 glib-genmarshal prints warnings but returns 0
+ 496046 option to prefix location of errors for GMarkup
+ 498113 tests/regex-test fails on 64bit environment
+ 500506 Fails to build on OSX 10.4
+ 500638 gkeyfile speedup ...
+ 500875 Make check fails as there is no "test" target for "build"...
+ 502511 g_assert_cmphex prints invalid message
+ 502927 g_array_index triggers cast aligment warning
+ 503029 g_time_val_from_iso8601 parse non-ISO8601 dates
+ 503222 Need context to translate
+ 503420 gkeyfile leaks a hash table
+ 503470 Fix build when builddir != srcdir
+ 504227 Inverse variant for g_test_trap_assert_stdout, g_test_tra...
+ 71704 	file include order
+ 491957 Misprint in the specification of the interface "g_main_co...
+ 491959 Misprint in description of the structure "GThreadPool"
+ 491965 Mistype in the specification of the function "g_hook_list...
+ 491966 Misprint in the specification of the interface "g_main_co...
+ 491968 The documentation does not mention the restriction for th...
+ 491970 The documentation for the interface "g_date_clamp" is inc...
+ 491974 The documentation of the interface "g_main_context_iterat...
+ 491975 The documentation for the interfaces "g_io_channel_read_u...
+ 491979 Misprint in the description of the interfaces g_key_file_...
+ 491982 Misprint in the description of the interface "g_key_file_...
+ 501107 EXTRA_DIST automake warnings
+ 501997 g_utf8_normalize() returns NULL on invalid string
+ 502590 C_/g_dpgettext efficiency
+ 464259 g_set_application_name() docs should say "Since 2.2"
+ 496518 gbase64.c API doc clarification
+ 498728 g_key_file_get_*_list should set length to 0 when returni...
+ 500361 Improve docs for g_array_free() and g_ptr_array_free()
+ 501853 g_checksum_get_digest docs
+ 503862 Allow NULL strings in g_parse_debug_string()
+ 142676 Q_
+ 367550 Add g_async_queue_new_full() with GDestroyNotify function
+ 375651 Minor enhancements to GKeyFile API
+ 443648 MD5 digest support
+ 449937 Upgrade auto* sources to be clean under automake1.9
+ 452887 gmarkup context "get element" function is useless when ca...
+ 491549 [PATCH] Eliminate libiconv dependency on Windows
+ 500507 GHashTableIter API 
+
+* Translation updates
+ Belarusian Latin (be@latin)
+ Czech (cs)
+ German (de)
+ Spanish (es)
+ Esperanto (et)
+ French (fr)
+ Korean (ko)
+ Marathi (mr)
+ Norwegian bokmål (nb)
+ Brazilian Portugese (pt_BR)
+ Slovenian (sl)
+ Swedish (sv)
+
+
+Overview of Changes from GLib 2.14.2 to GLib 2.14.3
+===================================================
+
+* Update PCRE to 7.4
+
+* Bugs fixed:
+ 487491 Fix some warnings from sparse
+ 488068 Small (one-time) memory leak in glib_gettext initialization
+ 493688 TYPE macro "_get_type ()" is documented wrong
+
+* Updated translations:
+ Arabic (ar)
+ Belarusian Latin (be@latin)
+ Estonian (et)
+ Irish (ga)
+ Slovenian (sl)
+
+ 
+Overview of Changes from GLib 2.14.1 to GLib 2.14.2
+===================================================
+
+* Bugs fixed:
+ 476849 Invocation of the interface "g_hook_free" fails in certai...
+ 359165 marshallers can throw warnings with -Wunused
+ 477957 more discussion on g_value_set_object vs. g_value_take_ob...
+ 478459 G_DEFINE_DYNAMIC_TYPE_EXTENDED doesn't work with G_IMPLEM...
+ 483337 inline is disabled for MSVC when compiling C code
+ 478349 Broken link to gettext website
+ 469231 g_spawn optimization for setting all open fds to CLOEXEC 
+
+* Updated translations:
+Arabic (ar)
+Galician (gl)
+Hebrew (he)
+Korean (ko)
+
+
+Overview of Changes from GLib 2.14.0 to GLib 2.14.1
+===================================================
+
+* Bugs fixed:
+ 476840 Invocation of the interface "g_utf8_strreverse" crashes f...
+ 444765 Fix FIXME in gregex.c when new pcre is out
+ 464145 g_markup_escape_text Produces Invalid XML
+ 465625 g_type_default_interface_ref() does not ensure working g_...
+ 466768 Clearify that comments can be put anywhere in a Key-file.
+ 474229 The GError documentation should give convention for the G...
+ 474899 G_BREAKPOINT() docs inaccurate
+ 475854 Overuse of -lpcre when using system pcre
+ 473879 Incorrect includes in gregex.c
+ 468694 Typoes in documentation
+ 469051 g_snprintf () talks about characters where it probably me...
+ 457601 Missing arch specific atomic implementation
+ 475923 Missing pcre flags when static-linking against glib
+ 475619 glibthread-2.0.la does not list -lpthread
+
+* Updated translations:
+ Bulgarian (bg)
+ Catalan (ca)
+ Danish (da)
+ German (de)
+ Canadian English (en_CA)
+ British English (en_GB)
+ Spanish (es)
+ Estonian (et)
+ Finnish (fi)
+ French (fr)
+ Gujarati (gu)
+ Hungarian (hu)
+ Italian (it)
+ Georgian (ka)
+ Kannada (kn)
+ Lithuanian (lt)
+ Makedonian (mk)
+ Norwegian (nb)
+ Dutch (nl)
+ Polish (pl)
+ Portugese (pt)
+ Brazilian Portugese (pt_BR)
+ Romanian (ro)
+ Russian (ru)
+ Albanian (sq)
+ Serbian (sr, sr@Latn)
+ Swedish (sv)
+ Tamil (ta)
+ Thai (th)
+ Ukrainian (uk)
+ Vietnamese (vi)
+
+
+Overview of Changes from GLib 2.13.7 to GLib 2.14.0
+===================================================
+
+* Last-minute API additions:
+ - Make g_unichar_combining_class public
+ - Add goffset type, add G_MAXSSIZE and G_MINSSIZE
+
+* Update PCRE to 7.2
+
+* Bugs fixed:
+ 453998 Make _g_unichar_combining_class() public
+ 462549 gregex.c: variable is declared at middle of block
+ 417068 g_file_test doc inconsistency
+
+* Updated translations:
+ Assamese (as)
+ Basque (eu)
+ Kannada (kn)
+ Malayalam (ml)
+ Dutch (nl)
+ Polish (pl)
+ Brazilian Portugese (pt_BR)
+ Turkish (tr)
+
+
+Overview of Changes from GLib 2.13.6 to GLib 2.13.7
+===================================================
+
+* The memory corruption warning from the slice allocator that
+  occurred when threads were initialized after the slice allocator
+  has been removed, as the slice allocator now works fine
+  in this scenario.
+
+* New functions g_once_init_enter() and g_once_init_leave() make
+  it easier to write threadsafe one-time initialization functions 
+ 
+* Bugs fixed:
+ 454473 Simple XML Subset Parser terminates on invalid XML
+ 445813 g_module_open error, add file name
+ 453796 errno gets clobbered by g_filename_display_name
+ 341988 don't use "-c" with msgfmt in Makefile.in.in
+ 447048 Please produce slightly more output during long tests
+ 454785 GModule documentation lists same block of code twice.
+ 454786 GModule documentation lists same paragraph twice.
+ 383155 small docs quirks in gobject/closure API documentation
+ 65041  _get_type() functions aren't thread safe
+
+* Updated translations
+ Assamese (as)
+ Spanish (es)
+ Gujarati (gu)
+ Japanese (ja)
+ Korean (ko)
+ Macedonian (mk)
+
+
+Overview of Changes from GLib 2.13.5 to GLib 2.13.6
+===================================================
+
+* Reintroduce a GType typedef whose removal in 2.13.5
+  caused trouble for C++ bindings
+
+* Bugs fixed:
+ 450216 docs not explicit enough about g_free()
+ 451459 g_type_register_static_simple calls g_type_register_static
+
+* Updated translations
+ Norwegian bokmål (nb)
+ Sinhala (si)
+
+
+Overview of Changes from GLib 2.13.4 to GLib 2.13.5
+===================================================
+
+* xdg-user-dirs support: 
+ - the Desktop directory is guaranteed to be defined
+ - user-dirs.dirs is no longer reloaded on changes
+
+* Slice allocator: 
+ - new api to duplicate slices
+
+* Regular expression support:
+ - GRegex is a boxed type now
+
+* Bugs fixed:
+ 44793 make check failing in trunk
+ 354522 Small problem with PLT hiding 6 symbols
+ 363986 glib 2.12.4 does not compile with SGI IDO cc
+ 443869 g_type_class_add_private doesn't warn when adding 0-sized...
+ 446859 Legitimately return 0 for g_quark_from_string(NULL)
+ 447534 Small typo in g_timeout_add_seconds() doc
+ 447583 GStaticRWLock
+ 447935 g_get_current_dir SIGSEGV on long path
+ 448260 CLAMP has surprising result if low > high
+ 57693 	g_string_vprintf()
+ 442029 add g_slice_dup()
+ 445065 Add GRegex boxed type
+ 448819 Add full version of g_timeout_add_seconds()
+
+* Updated translations: 
+ Swedish (sv)
+ Oriya (or)
+ Hebrew (he)
+ Spanish (es)
+ Estonian (et)
+
+ 
+Overview of Changes from GLib 2.13.3 to GLib 2.13.4
+===================================================
+
+* Bugs fixed:
+ 444121 g_get_user_special_dir deadlocks
+ 444161 invalid UTF8 in key name shows up as valgrind error in g_...
+ 444130 g_option_context_get_help() is broken when there's a desc...
+
+
+Overview of Changes from GLib 2.13.2 to GLib 2.13.3
+===================================================
+
+* GKeyFile:
+ - Added defines for easier handling of desktop files
+
+* Unicode support:
+ - Update g_unichar_iswide_cjk for Unicode 5.0
+
+* Regular expression support:
+ - GRegex structs can now be ref-counted
+ - Some new functions for dealing with incremental 
+   replacement have been added
+ - The GRegexEvalCallback signature has been changed
+
+* g_get_user_special_dir() has been added to support
+  xdg-user-dirs
+
+* Bugs fixed:
+ 419376 Functions using named subpatterns behave inconsistently w...
+ 434358 g_regex_fetch_named() and g_regex_fetch_named_pos() are b...
+ 423708 typo in the README.win32 file see patch below
+ 339225 Add new defines for easier handling of .desktop files 
+ 442265 API additions/changes for GRegex
+ 432651 Add a glib-ish xdg_user_dir_lookup
+
+* Updated translations:
+ Estonian (et)
+ Norwegian bokmål (nb)
+
+
+Overview of Changes from GLib 2.13.1 to GLib 2.13.2
+===================================================
+
+* Unicode support:
+ - Add g_unichar_ismark()
+
+* GOption:
+ - Allow to use callbacks for remaining args
+
+* Updated translations:
+  Belarusian Latin (be@latin)
+  British English (en_GB)
+  Galician (gl)
+  Norwegian bokmål (nb)
+  Oriya (or)
+  Spanish (es)
+  Thai (th)
+
+
+Overview of Changes from GLib 2.13.0 to GLib 2.13.1
+===================================================
+
+* GRegex:
+ - Portability fixes
+ - Split into immutable GRegex and GMatchInfo
+ - Add g_regex_get_max_backref() and g_regex_get_capture_count()
+   to obtain information about the compiled regex
+
+* GKeyFile:
+ - Fix roundtrip problems
+ - Add g_key_file_load_from_dirs()
+
+* Unicode support:
+ - Fix corner cases in case conversion routines
+
+* GOption:
+  - Add a function to get the formatted help string
+
+* GHash:
+ - Add new functions g_hash_table_get_keys() and
+   g_hash_table_get_values() to retrieve the keys and
+   values in list form
+
+* Updated transations:
+  Simplified Chinese (zh_CN)
+  Arabic (ar)
+
+
+Overview of Changes from GLib 2.12 to GLib 2.13.0
+=================================================
+
+* Add GSequence, a list that is implemented using
+  a balanced binary tree.
+
+* Add GRegex, an implementation of Perl regular expressions,
+  based on PCRE.
+ 
+* Use Posix monotonic clocks instead of gettimeofday()
+  for GTimer when available.
+
+* Support static initialization of GQeues with G_QUEUE_INIT,
+  g_queue_init() and g_queue_clear().
+
+* Add g_string_chunk_clear() for clearing a 
+  GStringChunk.
+
+* Add g_unichar_get_script() to obtain Unicode
+  script information.
+
+* Add g_unichar_iszerowidth() to obtain information
+  about zero-width characters.
+
+* Add G_GNUC_MAY_ALIAS which wraps the gcc may_alias 
+  type attribute.
+
+* G_GNUC_INTERNAL has a working definition for the
+  Sun Studio compiler. This requires the macro to
+  be positioned before the function declaration.
+
+* The slice allocator can produce detailed debugging
+  information with G_SLICE=debug-blocks.
+
+* Modules support G_DEBUG flags resident-modules and
+  bind-now-modules.
+
+* Add G_DEFINE_DYNAMIC_TYPE() to make it easier
+  to define types in modules.
+
+* Bug fixes: too many to list them in detail here.
+
+* New and updated translations (be,bg,bn,ca,cs,de,
+  en_CA,en_GB,et,fa,fr,he,hu,it,ja,ku,lt,mg,mk,ml,
+  nb,ne,nn,pt,pt_BR,ro,sr,sr@Latn,sv,ta,uk,vi,zh_CN,
+  zh_HK,zh_TW)
+
+
+Overview of Changes from GLib 2.12.1 to GLib 2.12.2
+===================================================
+
+* Unicode updates:
+ - Normalization is following Unicode TR #29
+ - g_unichar_isxdigit() only accept characters
+   for which g_unichar_xdigit_value() returns a value
+ - g_unichar_toupper and g_unichar_tolower leave
+   unconvertable characters in place instead of
+   replacing them by NUL
+
+* Bugs fixed
+ 348491 g_utf8_strup() and g_utf8_strdown() returns 
+        string with NUL bytes
+ 349825	GKeyFile always inserts a newline before a group
+ 347842	g_unichar_isxdigit() is too general about what 
+        it considers a digit
+ 348694	g_utf8_normalize() hasn't been updated to PR #29
+ 348785	Hint about G_DEBUG in Message Logging docs
+ 349792	Wrong english string (UI)
+ 349952	gparamspecs.c uses gcc feature
+
+* Translation updates (ca,cs,de,dz,es,eu,fi,gu,ko,
+  nl,pl,tr,uk,zh_HK,zh_TW)
+
+
+Overview of Changes from GLib 2.12.0 to GLib 2.12.1
+===================================================
+
+* Update to final Unicode Character Database 5.0.0
+
+* Bugs fixed:
+ 346660 issues with base64 api documentation / g_base64_decode_cl...
+ 348136 Coverity reports allocation of wrong size CID #2839
+ 336281 Update to UCD 5.0
+ 346197 g_date_strftime %F option doesnt work for win32
+ 348011 Small optimization to real_toupper()
+ 246494 prototype mismatch in glib/gconvert.c
+
+* New and updated translations (bg,bn_IN,ca,dz,eu,fi,
+  fr,he,it,ja,mk,or,pt)
+
+
+Overview of Changes from GLib 2.11.4 to GLib 2.12
+=================================================
+
+* Bugs fixed:
+ 344905 leap-year bug in g_time_val_from_iso8601 w/o HAVE_TIMEGM
+
+* Updated translations (cy,nb,nl)
+
+
+Overview of Changes from GLib 2.11.3 to GLib 2.11.4
+===================================================
+
+* GBookmarkFile:
+ - g_bookmark_file_remove_item returns a boolean
+ 
+* g_mkstemp accepts the XXXXXX in the middle of
+  the template
+ 
+* Bugs fixed:
+ 344868 g_key_file_to_data should separate groups 
+
+* Updated translations (de,es,fr,gu,hi,ko,th)
+
+
+Overview of Changes from GLib 2.11.2 to GLib 2.11.3
+===================================================
+
+* GBookmarkFile:
+  - g_bookmark_file_move_item: Return TRUE in case of
+    an empty target
+
+* Bugs fixed: 
+ 343919 gunicollate.c: strxfrm bug on VC8
+
+* Updated translations (fi)
+
+Overview of Changes from GLib 2.11.1 to GLib 2.11.2
+===================================================
+
+* Add g_ascii_stroll to parse signed 64bit integers
+
+* GMarkup: add a flag to treat CDATA as text
+
+* GHashTable: add functions to remove all entries
+
+* GMainLoop: add functions to find the currently
+  running source, and determine if it is destroyed
+
+* Bug fixes:
+ 342563  g_atomic_thread_init() needs to be called before 
+         other _g_*_thread_init() functions
+ 343548  Potential use after free in callers of g_string_free() 
+ 168538  Wish: Clearing contents of GHashTables
+ 321886  GTK+ cannot be reliably used in multi-threaded 
+         applications
+ 341826  goption.c: 'strtoll' is C99's function
+ 343899  g_ascii_formatd dosn't work as expected for all 
+         format strings
+ 317793  Make GEnumValue strings const
+ 337129  Compile warnings in G_IMPLEMENT_INTERFACE
+ 303622  What is G_TYPE_CHAR?
+
+* Updated translations (bg,dz,eu,gl,ja,ko,nl,th,vi)
+ 
+
+Overview of Changes from GLib 2.11.0 to GLib 2.11.1
+===================================================
+
+* GOption  
+  - Support 64-bit integers 
+  - Allow optional text before and after the options
+    in help output
+
+* Bug fixes:
+ 340538 gbase64-test writes OOB 
+ 340816 GKeyFile set_string_list invalid memory reads 
+ 339105 g_key_file_parse_value_as_double
+ 340434 convert-test.c fails (function test_one_half)
+ 311043 Memory leaks (and potential infinite loops) 
+        when using G_ERRORCHECK_MUTEXES
+ 335198 Error checking mutexes are fubar  
+ 341237 Add a G_OPTION_ARG_INT64
+ 341192 g_io_channel_set_flags not implemented on win32
+ 336120 Allow adding description before/after GOption 
+        --help output body
+ 341191 misplaced check in g_relation_delete
+ 340530 mismatched calloc / g_free in win32 threads
+
+* Updated translation (es)
+
+Overview of Changes from GLib 2.10.x to GLib 2.11.0
+===================================================
+
+* GBookmarkFile: a parser for files containing bookmarks
+  stored using the Desktop Bookmark specification.
+
+* Base64 encoding support
+	
+* Unicode 5.0 support
+
+* GOption supports floating point numbers 
+
+* GKeyFile supports floating point numbers
+
+* Bug fixes:
+ 155884 gatomic.c should be based on new SDK
+ 157877 update-desktop-database doesn't handle duplicate entries
+ 164719 keyfile parser doesn't support floats
+ 327662 Import BookmarkFile from libegg
+ 329548 Add G_OPTION_ARG_DOUBLE
+ 329789 option-test.c type confusion
+ 332841 Segmentation Fault when %llu is passed to vasnprintf and 
+        HAVE_SNPRINTF is not defined
+ 333879 gthread/gthread-win32.c: IsDebuggerPresent needs '#define 
+        _WIN32_WINDOWS 0x0401'
+ 333916 g_timer_elapsed docs should mention that microseconds 
+        may be NULL
+ 334440 dlerror() portability issue causes crash on (old) a.out 
+        NetBSD platform
+ 334646 goption + error out params
+ 334799 g_remove() must check return value of remove()
+ 334943 make check FAIL: threadpool-test
+ 335215 Some breakages with GThreadPool
+ 336085 g_option_context_new parameter lacks better explanation
+ 336677 Documentation for g_object_ref_sink() is incorrect
+ 337027 gbookmarkfile.c: sys/time.h include error
+ 337553 Wrong escaping of URIs
+ 338572 Dereferencing NULL value in g_key_file_get_group_comment
+ 338845 g_completion_complete_utf8 crashes when NULL is passed to it
+ 339337 g_bookmark_file_set_description
+ 339338 gbookmarkfile.c, function expand_exec_line
+ 339340 gbookmarkfile.c, function bookmark_app_info_dump
+
+* Translation updates (bg,en_GB,et,gl,gu,he,hi,ka,nb,nl,nn,
+                       or,pt_BR,ro,tr,vi,zh_CN)
+
+
+Overview of Changes from GLib 2.10.0 to GLib 2.10.1
+===================================================
+
+* Bugs fixed:
+ 314794 Broken pthread detection on Darwin [Gregor Riepl]
+ 322476 Missing check for .dylib [Vladimir Panov]
+ 333651 Inconsistent _g_charset_get_aliases prototype [Julio 
+        M. Merino Vidal]
+ 333761 GInitiallyUnowned breaks application code [Sven Herzberg]
+
+* Win32 changes:
+ - Fix g_listenv() implementation.
+ - Allow up to 100 GPrivate structs
+
+* Translation updates (fr,hu,lt,pl,sv)
+
+
+Overview of Changes from GLib 2.9.6 to GLib 2.10.0
+==================================================
+
+* Bugs fixed:
+ 328997 64bit pointer trunction in glib slab-allocator
+        [Pascal Hofstee]
+ 331110 g_cond_broadcast(inform_cond) without holding 
+        inform_mutex [Chris Wilson, Sebastian Wilhelmi]
+ 332093 Fix some leaks in the tests [Kjartan Maraas]
+ 332435 g_utf8_strlen returns wrong value if a maximum 
+        number of bytes to check is specified 
+        [Matthias Clasen]
+ 331367 gslice requires more POSIX-like semantics for 
+        GPrivate destructors [Tor Lillqvist]
+
+* Documentation improvements [Matthias, Kang Jeong-Hee,
+  Tor Lillqvist, Stefan Kost]
+
+* Translation updates (el,eu,ka,uk)
+
+Overview of Changes from GLib 2.9.5 to GLib 2.9.6
+=================================================
+
+* Bugs fixed: 
+ 329124 distclean removes README [Kjartan Maraas, Tim Janik]
+ 317679 GRelation field type not documented [Behdad Esfahbod]
+ 329123 Typo in GTime docs [Kjartan Maraas]
+
+* Documentation improvements [Sven Herzberg, David
+  Schleef, Kjartan Maraas, Behdad Esfahbod]
+
+* Translation updates (cs,cy,it,ko,pt,sq,sr,sr@Latn,ru
+
+Overview of Changes from GLib 2.9.4 to GLib 2.9.5
+=================================================
+
+* Memory management: 
+  Runtime debugging support: The slice allocator
+  can be turned off by setting G_SLICE=always-malloc
+  in the environment. Zeroing of freed memory can
+  now be turned on at runtime by setting
+  G_DEBUG=gc-friendly in the environment. [Tim Janik]
+
+* Bugs fixed:
+ 328253 HP-UX/IA-64 uses ".so" as default shared library 
+        extension [Albert Chin]
+ 143380 unicode-encoding test fails converting to UTF-16 
+        with libiconv [Marc Moorcroft]
+ 328254 Build breakage (GSlice) [Jens Ganseuer]
+ 328705 C99ism in glib/gmem.c [Kazuki Iwamoto]
+
+* Translation updates (da,et,zh_CN)
+
+Overview of Changes from GLib 2.9.3 to GLib 2.9.4
+=================================================
+
+* Type system:
+  Fix a problem with g_object_compat_control() which 
+  can lead to segfaults in GTK+ applications on 64bit 
+  platforms. 
+
+* Thread suppport: 
+  Unused threads now fall back to the global pool after 
+  500 milliseconds, where they wait for another 
+  max-idle-time milliseconds. [Sebastian Wilhelmi]
+
+* Fix a memory allocation problem in GKeyFile. [Morten 
+  Welinder]
+
+
+Overview of Changes from GLib 2.9.2 to GLib 2.9.3
+=================================================
+
+* GTree:
+ - Replace the simple recursive implementation by
+   a nonrecursive, threaded one  [Maurizio Monge]
+
+* Change g_filename_display_name and
+  g_filename_display_basename to use the Unicode
+  replacement character U+FFFD instead of a question
+  mark, and don't append "(invalid encoding)"  [Matthias]
+
+* Documentation improvements [Sven Herzberg, Federico
+  Mena Quintero, Stefan Kost]
+
+* Bugs fixed:
+ 323937 gslice.c in glib 2.9.1 doesn't build on Mac OS X 
+        [Bogdan Nicula]
+ 326558 Some test failures on IRIX 6.5 [Daichi Kawahata]
+ 169285 "threaded" tree implementation for GTree 
+        [Maurizio Monge]
+ 326747 g_filename_display_basename adds (invalid encoding) 
+        [Alberto Ruiz]
+
+Other contributors: Christian Kellner, Murray Cumming
+
+New and updated translations (bg,ca,de,es,et,gu,ja,nl,th,vi)
+
+
+Overview of Changes from GLib 2.9.1 to GLib 2.9.2
+=================================================
+
+* Memory management:
+ - Add tests for cache colorization [Tim Janik]
+ - Minimize space consumption if small amounts of differently
+   sized slices are allocated, at a small performance cost.  [Tim]
+
+* Thread support:
+ - Add g_atomic_pointer_set() and g_atomic_int_set() [Tim Janik,
+   Sebastian Wilhelmi]
+ - Add g_thread_pool_set_sort_function() to allow sorting the 
+   tasks of a threadpool.  [Martyn Russell]
+ - Add g_thread_pool_set_idle_time() to allow unused threads
+   to exit after a certain time.  [Martyn]
+
+* Type system:
+ - introduce a new type GInitiallyUnowned, which has an initial
+   floating reference. [Tim]
+ - Add support for GType parameters. [Matthias]
+
+* Main loop:
+ - Add g_main_context_is_owner() to determine if the current
+   thread is the owner of the context.  [Michael Meeks]
+
+* Provide g_access(), g_chdir(), g_unlink(), g_rmdir() as 
+  wrapper functions instead of macros.  [Manish Singh]
+
+* Documentation improvements [Tim, Matthias, Federico Mena Quintero,
+  Stefan Kasal, Dan Williams]
+
+* New and updated translations (en_CA,fi,fr,gl,ml,nb,no,zh_HK,zh_TW)
+
+* Bugs fixed:
+ 324179 g_allocator_new() returns pointer to const dummy which Gtk+ 2.8 
+        tries to modify [J. Ali Harlow]
+ 324332 g_option_context_parse() returns false without setting error 
+        [Tim-Philipp Müller]
+ 324950 GLIB 2.9.1 testcase errors [Dan Yefimov]
+ 325015 gslice.c: process.h is needed on Windows [Kazuki Iwamoto]
+ 321978 G_DATALIST_GET_FLAGS() macro is not casting datalist to 
+        gpointer [Andrew Paprocki]
+ 316221 G_LOCK warns about breaking strict-aliasing [Michal Benes, 
+        Stanislav Brabec]
+ 325273 Error in documentation for glib_check_version () [Declan Naughton]
+ 325310 g_spawn_sync hangs when catching both stdout and 
+        stderr [Tor Lillqvist]
+ 325249 gcc warning when using g_rmdir from <glib/gstdio.h> [Jani Monoses]
+ 325864 glib/gthreadpool.c:"#define debug(...)" is C99 [Kazuki Iwamoto]
+ 325874 Should say somewhere that source IDs are > 0 [Dan Williams]
+ 325438 a typo (compatability) [Stefan Kasal]
+ 323937 gslice.c in glib 2.9.1 doesn't build on Mac OS X [Bogdan Nicula]
+
+
+Overview of Changes from GLib 2.9.0 to GLib 2.9.1
+=================================================
+
+* Memory management
+ - The slice allocator is implemented [Tim Janik]
+ - g_slice_free_chain() has been renamed to 
+   g_slice_free_chain_with_offset()  [Tim, Behdad Esfahbod]
+ - Mem chunks are deprecated [Matthias Clasen]
+
+* Data structures
+ - Hash tables are refcounted, and have a boxed type [Tim]
+
+* Thread support
+ - Support for Solaris threads has been removed 
+   [Sebastian Wilhelmi, Andrew Paprocki]
+ - g_async_queue_sort(), g_async_queue_push_sorted() have 
+   been added to allow GAsyncQueue to be used as a priority 
+   queue, together with the corresponding _unlocked 
+   variants  [Martyn Russell]
+
+* GObject:
+ - The concept of a floating initial reference has been
+   moved from GtkObject to GObject [Tim]
+
+* Win32 changes:
+ - Make g_rename() replace existing files [Tor Lillqvist]
+
+* Misc new API:
+ - G_GUINT64_CONSTANT macro to define guint64 
+   constants [Andrew Paprocki]
+ - G_GNUC_WARN_UNUSED_RESULT macro to instruct the 
+   compiler to emit a warning if the value returned
+   by a function is ignored. [Arjan van de Ven, Alex Larsson]
+ - GList and GSList now have sort functions which take an
+   extra user data argument [Martyn Russell]
+ - g_param_spec_ref_sink() has been added for consistency [Tim]
+
+* $LOGNAME is respected when determining user data. [Laszlo Peter]
+
+* Other changes and bug fixes [Tim, Matthias, Behdad, 
+  Christian Persch, Benedikt Meurer, Andrew Paprocki, 
+  Kazuki Iwamoto, Alexis S. L. Carvalho, Stanislav Brabec,
+  Andreas Schwab, Kalle Vahlman]
+
+* Documentation
+ - Deprecation warnings carry version information [Matthias]
+ - The slice allocator has been documented [Matthias, Tim]
+ - Other improvements [Morten Welinder]
+
+Overview of Changes from GLib 2.8.x to GLib 2.9.0
+=================================================
+* Unicode support:
+ - The Unicode tables have been updated to Unicode 4.1, 
+   adding several new values to the GUnicodeBreakType 
+   enumeration. This breaks Pango <= 1.10 
+   [Behdad Esfahbod]
+ - The various Unicode character predicate functions 
+   (g_unichar_isalpha, g_unichar_isdigit,...) have
+   been optimized
+   [Behdad]
+ - g_utf8_pointer_to_offset, g_utf8_offset_to_pointer:
+   These functions handle negative offsets now, and
+   going backwards in g_utf8_offset_to_pointer uses
+   "stutter stepping".
+   [Larry Ewing, Matthias Clasen]
+
+* Memory management:
+ - Mem chunks are no longer used internally in GLib and
+   GObject. GMemChunk will be deprecated in GLib 2.10
+ - All APIs based on GAllocator (g_list_push/pop_allocator,
+   and similar push/pop_allocator functions for other
+   data structures) have been deprecated, since they
+   never worked as intended.
+ - The g_slice_* functions have been added as a 
+   new API for fast allocation of small memory blocks. 
+   The implementation in GLib 2.9.0 is just a simple 
+   wrapper around malloc. GLib 2.10 will have an
+   efficient and scalable implementation. 
+   [Tim Janik, Matthias]
+
+* Pattern matching:
+ - g_pattern_match has been optimized to avoid
+   unnecessary recursion.
+   [Tim, Matthias]
+
+* g_intern_string, g_intern_static_string: 
+ - New functions to intern strings. These are now used 
+   by GObject to avoid duplicating static strings 
+   [Matthias]
+
+* g_thread_foreach: 
+ - New function to iterate over all GThreads 
+   [Tim, Matthias]
+
+* g_date_set_time_t, g_date_set_time_val:
+ - New functions to set a GDate from a time_t or
+   GTimeVal value. g_date_set_time has been deprecated 
+   in favor of these.
+   [Roger Leigh]
+
+* g_snprintf and g_vsnprintf:
+ - These functions are no longer declared in gprintf.h, 
+   since they are in glib.h
+   [Matthias]
+
+Overview of Changes from GLib 2.8.0 to GLib 2.8.1
+=================================================
+* Optimize single-character insertions in GString [Ross Burton]
+* Fix build problems on OS X
+* Fix build problems on Win32 [Tor Lillqvist, Hans Breuer]
+* Other bug fixes [Matthew F. Barnes, Stepan Kasal] 
+* Documentation improvements [Tristan van Berkom, Behnam
+  Esfahbod, Gustavo Carneiro, Stepan Kasal, Matthias]
+* New and updated translations (ca,cy,ko,ro,uk)
+
+Overview of Changes from GLib 2.7.7 to GLib 2.8.0
+=================================================
+* Make g_value_transform() handle enum values
+  correctly on ppc64.  [Michael Lorenz]
+  (Third-party code accessing enumeration values 
+  in GValues should also be changed to access 
+  v_long, not v_int, in order to work on bigendian 
+  64bit machines.)
+* Make g_flags_get_first_value() handle a value
+  of 0 meaningfully. [Tim-Philipp Müller] 
+
+Overview of Changes from GLib 2.7.6 to GLib 2.7.7
+=================================================
+* Make atomic operations on s390 work [Matthias]
+* Fix C++ guards in gstdio.h [Tor Lillqvist]
+
+Overview of Changes from GLib 2.7.5 to GLib 2.7.6
+=================================================
+* Add native implementations of atomic operations 
+  on s390 [Matthias]
+* Make atomic reference counting of closures
+  work on s390 [Matthias]
+* Avoid an infinite loop in g_convert_with_iconv().
+  [Sebastian Bacher]
+* Documentation improvements [Ross Burton]
+
+Overview of Changes from GLib 2.7.4 to GLib 2.7.5
+=================================================
+* Thread-related changes
+ - Fix build issues on HP-UX [Paul Cornett]
+ - Threadsafe access to flags stored in datasets [Tim Janik]
+ - Fix several issues with atomic refcounting for 
+   closures, objects and paramspecs [Tim]
+ - Improve tests for atomic refcounting changes [Tim]
+* Fix handling of stateful encodings in g_convert_* [Matthias]
+* Fix translation of GOption help output [Dan Winship]
+* Catch format errors in translations. This may cause 
+  "make check" to fail when using older versions
+  of gettext [Matthias]
+* Win32 bug fixes [Tor Lillqvist]
+* Documentation improvements [Ross Burton, Jochen Baier, 
+  Matthias, Tim]
+* New and updated translations (de,fi,gu,pl,pt,tr,zh_TW)
+
+Overview of Changes from GLib 2.7.3 to GLib 2.7.4
+=================================================
+* Fix g_atomic_pointer_compare_and_exchange 
+  on Sparc64 [Gert Doering]
+* Fix a hang in g_thread_pool_free. [Hong Jen Yee]
+* Win32 bug fixes [Tor Lillquist]
+* Other bug fixes [Benoit Dejean, Manish Singh]
+* Documentation improvements [Bryan Silverthorn,
+  Callum McKenzie] 
+* New and updated translations (de,lt,sq,zh_CN)
+
+Overview of Changes from GLib 2.7.2 to GLib 2.7.3
+=================================================
+* GOption
+ - Allow callbacks with optional arguments [Pawel Sliwowski]
+ - Allow to turn off the automatic long option name
+   disambiguation  [Adam McLaurin]
+ - Only allow printable ASCII as short option names [Matthias]
+* Win32
+ - Build fixes [Tor Lillqvist]
+ - Rewrite iochannel socket implementation [Tor]
+* GObject
+ - Threadsafety improvements; in particular, refcounting
+   of objects is done atomically now. [Wim Taymans, Tim Janik]
+* Bug fixes [Morten Welinder, Matthias, Wim Taymans]
+* Documentation improvements [Richard Laager, Matthias]
+* New and improved translations (bf,cs,hu,nb,nl,no)
+
+Overview of Changes from GLib 2.7.1 to GLib 2.7.2
+=================================================
+* Win32 build fixes [Hans Breuer]
+* Bug fixes [Mikael Magnusson]
+* Documentation improvements [Matthias Clasen]
+* New and updated translations (en_CA,es,et,ja,sr,sr@Latn,zh_TW)
+
+Overview of Changes from GLib 2.7.0 to GLib 2.7.1
+=================================================
+* GOption 
+ - Allow callback arguments without parameters [Dan Winship]
+* GMappedFile: an mmap wrapper [David Schleef, Behdad Esfahbod]
+* Misc new functions:
+ - g_get_host_name [Tor Lillqvist]
+ - g_mkdir_with_parents [Tor]
+ - g_build_pathv, g_build_filenamev [Todd A. Fisher, 
+   Matthias Clasen]
+* Bug fixes [Roger Leigh, Masatake YAMATO, Kjartan Maraas,
+  Manish Singh, Tor, Murray Cumming, Kian Duffy, Morten Welinder]
+* Documentation improvements [Hong Gang XU, Dan Winship, Matthias]
+* New and updated translations (bg,cs,da,en_CA,es,et,nb,nl,no,
+  sk,th,zh_TW)
+
+Overview of Changes from GLib 2.6.x to GLib 2.7.0
+=================================================
+* GKeyFile
+ - Add unit tests [Matthias Clasen, Suren A. Chilingaryan]
+ - Accept \r\n as line end [Bastian Nocera]
+ - Don't interpret leading zeros as octal numbers. [Matthias]
+ - Make key and group removal work [David Hoover, Matthias Hasselmann]
+* GOption
+ - Improve formatting of --help output [Matthias, Noah Levitt]
+ - Accept -? [Matthias]
+ - Warn about duplicate main groups [Jeff Franks]
+ - Treat '-' as non-option argument [Tim Musson, Thomas Leonard]
+ - Report missing arguments as errors [Björn Lindqvist]
+ - Add a boxed type for GDate [Tim-Philipp Müller]
+* GTree
+ - g_tree_remove() and g_tree_steal() return status information [Matthew F. Barnes]
+* Stdio wrappers
+ - Work regardless of large file support [Manish Singh]
+ - Add g_access(), g_chmod(), g_creat(), g_chdir [Tor Lillqvist]
+* GObject
+ - Implement "toggle references" to help language bindings [Owen Taylor]
+ - Allow to mark names, nicks and blurbs of pspecs as static [Ben Maurer, Matthias]
+ - Make pspec lookup a bit faster [Morten Welinder]
+* Add g_listenv() to list all set environment variables [Hans Petter Jansson]
+* Add g_file_set_contents() to atomically write a file.  [Søren Sandmann,
+  Sven Neumann, Manish, Alexis S. L. Carvalho]
+* Add g_try_malloc(), g_try_new(), g_try_new0() and g_try_renew() [Stefan Kost]
+* Add g_utf8_collate_key_for_filename() to sort filenames taking
+  extensions and numeric suffixes into account.  [Ole Laursen, Alex Larsson]
+* Add G_GNUC_NULL_TERMINATED to mark varargs function with 
+  NULL-terminated argument lists. [Marc Meissner]
+* Win32 changes
+ - Improved debugability [Ulf Lamping, Hans Breuer]
+ - Make filename handling more robust [Tor, Billy Skaggs]
+ - Improve g_get_system_data_dirs() [Tor]
+ - Use more precise timers [Tor]
+ - Build fixes [Kazuki Iwamoto, Hans, Tor, Robert Ögren]
+* Other bug fixes [Roger Leigh, Owen, Matthias, Morten, Kjartan Maraas, 
+  Pawel Sakowski, Tor, Simon Budig, Ed Avis, Manish, Nicolas Laurent, 
+  Bastien, Fabrício Barros Cabral, Michael Banck, Daniel Atallah, 
+  J. Ali Harlow, Tim Janik, Hazael Maldonado Torres, Sven, Jon-Kare Hellan,
+  Dave Benson, Tommi Komulainen, Benjamin Otte, Brian Cameron, Changwoo Ryu, 
+  Christian Biere, Noah, Benoît Carpentier]
+* Documentation improvements [Vincent Untz, Matthias, Tim-Philipp Müller,
+  Morten, Matthew, Federico Mena Quintero, Sebastian Bacher, Oliver Sessink, 
+  Stefan, Jared Lash, Tor, Owen, Daniel Vaillard, Mathieu Lacage]
+* New and updated translations (ca,cs,da,el,en_CA,en_GB,es,et,eu,fa,fr,gl,
+  hu,id,it,lt,mn,ne,nl,pl,pt,pt_BR,ro,rw,sk,sq,sr,sr@Latn,tl,uk,xh,zh_CN)
+
+Overview of Changes from GLib 2.6.0 to GLib 2.6.1
+=================================================
+* GOption
+ - Make gtk_init(NULL, NULL) work again [Marcin Krzyzanowski]
+ - Improve handling of -- [Matthias Clasen]
+ - Don't show G_OPTION_REMAINING in --help output [Matthew F. Barnes]
+* g_find_program_in_path() doesn't return directories [Tommi Komulainen]
+* Add gmodule-export-2.0.pc [Matthias]
+* Win32 changes
+ - Improve hangling of UNC paths [Tor Lillqvist]
+ - g_getenv(), g_setenv(), g_unsetenv(), g_find_program_in_path()
+   take and return UTF-8 now [Tor] 
+ - Make g_file_test() work more reliably, and use PATHEXT
+   when check for executables [Tor]
+ - Build and cross-compilation fixes [J. Ali Harlow]
+* Other bug fixes [Jens Hatlak, Morten Welinder, 
+  Tor, Kalpesh Shah, Adrian Bunk]
+* Documentation improvements [Marcin Krzyzanowski, Tor, Crispin
+  Flowerday, Mariano Suárez-Alvarez, Christian Biere, Danny Milo,
+  Vincent Untz, Bastien Nocera]
+* New and updated translations (cy,de,nl,ru,sq,sv)
+
+Overview of Changes from GLib 2.4.x to GLib 2.6.0
+=================================================
+
+* Major new APIs
+  - GOption, a commandline option parser
+  - GKeyFile, a parser/editor for the .ini like files 
+  - Functions to support the XDG basedir specification
+  - Wrappers for common POSIX pathname functions to handle filename
+    encodings consistently. On Windows, these use UTF-8.
+
+* Miscellaneous new functions
+  - g_filename_display_name() converts filenames in displayable UTF-8 strings
+  - g_uri_list_extract_uris() splits uri lists
+  - g_date_get_iso8601_week_of_year() gets ISO 8601 week numbers
+  - g_log_set_default_handler() installs an alternate default log handler
+  - g_get_language_names() obtains a list of applicable locale names
+  - g_strv_length() calculates the length of NULL-terminated string arrays
+  - g_win32_get_windows_version() determines the Windows version 
+  - G_GNUC_INTERNAL marks functions as non-exported
+  - glib_check_version() checks the GLib version at runtime
+  - g_debug() completes the family of logging functions
+
+* Performance improvements
+  - Optimize g_utf8_validate()
+  - Optimize g_markup_parse_context_parse()
+  - Reduce signal connection complexity from O(n) to O(1) 
+  - Get rid of many PLT entries for internally used exported symbols
+  - Reduce code size by removing literal strings from g_return_if_fail()
+
+* Other changes
+  - On Windows, GLib functions that take file name arguments now require
+    those to be in UTF-8. Functions that return file names return UTF-8.
+  - Use higher precision for mathematical constants
+  - Don't convert to/from UTF-8 in g_filename_to_uri/g_filename_from_uri
+  - Support ll as printf format modifier for long long on all platforms
+  - Clean up the ABI and enforce the list of exported symbols
+  - Add a .pc file for using gmodule in libraries
+  - Require ngettext
+
+Overview of Changes from GLib 2.5.7 to GLib 2.6.0
+=================================================
+* GOption: Don't list help options if group-specific
+  options have been requested [Glynn Foster]
+* Make g_get_language_names() track locale changes [Christian Persch]
+* Win32 bug fixes [Tor Lillqvist]
+* Bug fixes [Philippe Blain, Owen Taylor, Sebastian Wilhelmi]
+* New and updated translations (da,es,ja,lt,zh_CN)
+Bugs fixed: 159530,100697,160271,160645,157255
+
+Overview of Changes from GLib 2.5.6 to GLib 2.5.7
+=================================================
+* Optimize g_utf8_validate() [Owen Taylor, Matthias Clasen]
+* Optimize g_markup_parse_context_parse() [Havoc Pennington, 
+  Morten Welinder]
+* Reduce signal connection complexity from O(n) to O(1) 
+  [Sven Neumann]
+* Add a .pc file for using gmodule in libraries [Owen]
+* Add G_GNUC_MALLOC to mark functions returning newly 
+  allocated memory  [Matthias]
+* Win32 bug fixes [Hans Breuer, Tor Lillqvist, Robert Ögren,
+  Bruce Hochstetler]
+* Bug fixes [Kazuki IWAMOTO, Matthias, Manish Singh, Morten,
+  Frederic Crozat, Tor]
+* Documentation improvements [Matthias, Tor, Owen]
+* New and updated translations (cs,da,de,en_CA,en_GB,es,nb,nl,sq,zh_CN)
+
+Overview of Changes from GLib 2.5.5 to GLib 2.5.6
+=================================================
+* GOption
+  - Add G_OPTION_FLAG_REVERSE to allow options 
+    which unset a  boolean variable [Tor Lillqvist]
+* GChildWatch
+  - Use sigaction instead of signal [Jonas Jonnson, 
+  Archana Shah]
+  - Make the very first SIGCHLD work [Gustavo Carneiro]
+* Bug fixes [Morten Welinder, Tor, David MacLachlan,
+  Manish Singh, J. Ali Harlow]
+* Documentation improvements [Matthias Clasen, Tor]
+* Updated translations (da,ja,tr,zh_CN)
+
+Overview of Changes from GLib 2.5.4 to GLib 2.5.5
+=================================================
+* GKeyFile
+  - Cleanups, add more error checking [Ray Strode]
+  - Fall back to the untranslated string when getting 
+    locale strings [Mark McLoughlin]
+* GOption
+  - Document GOption [Matthias Clasen]
+  - Better support for rest arguments [Owen Taylor, Matthias]
+  - Handle conflicts between groups [Matthias]
+* Add g_lstat() to the stdio wrappers [Tor Lillqvist]
+* Add g_filename_display_name() to convert filenames
+  in displayable UTF-8 strings  [Alex Larsson, Matthias]
+* Win32 bug fixes [Kazuki IWAMOTO, Hans Breuer, Tor]
+* Bug fixes [Christophe Fergeau, Morten Welinder, 
+  Owen, Kjartan Maraas, Mark]
+* Documentation improvements [Matthias, Tor]
+
+Overview of Changes from GLib 2.5.3 to GLib 2.5.4
+=================================================
+Add GKeyFile, a parser/editor for the .ini like files used in various
+   freedesktop.org specifications. [Ray Strode]
+Make the handling of filename encodings consistent across all
+   GLib functions, introduce wrappers for common POSIX 
+   functions which accept the same filename encoding. [Tor Lillqvist, 
+   Owen Taylor]
+GOption
+ - Rename g_context_option_error_quark() to a more language-binding
+   friendly name [Murray Cumming]
+ - Accept backslashes in filenames on Win32 [Tor Lillqvist]
+* Strip the internal aliasing prefix IA__ from function names in 
+  assertions [Matthias Clasen]
+* Add a function to split uri lists. [Matthias]
+* Win32 bug fixes 
+ - Don't open console windows [Tor]
+* Other bug fixes [Philippe Blain, Robert Ögren, Hidetaka Iwai, Matthias,
+ Morten Welinder, Mats-Ola Persson, Tor, Nickolay V. Shmyrev, Kjartan Maraas,
+  Anders Carlsson, Tim-Philipp Müller, Lucas Rocha, Andrea Campi, Manish
+  Singh, Thomas Fitzsimmons, Kazuki IWAMOTO]
+* Documentation improvements [Matthias, Linus Walleij, Nickolay, Philippe, 
+ Adam Hooper, Gustavo Carneiro]
+* New and updated translations (cs,en_CA,en_GB,ja,nb,nl,or,sr,sr@Latn,sq)
+
+Overview of Changes from GLib 2.5.2 to GLib 2.5.3
+=================================================
+* GOption
+ - set the program name from argv[0] [Masatake YAMATO] 
+ - make contexts work without a main group [Anders Carlsson]
+* Performance 
+ - Get rid of many PLT entries for internally used exported symbols,
+   and clean up the ABI at the same time and make make check check the
+   list of exported symbols.  [Matthias Clasen]
+* Add API to get ISO 8601 week numbers [Niklas Lundell]
+* Add API to install an alternate default log handler [Darin Adler]
+* Add API to obtain a list of applicable locale names [Hidetoshi Tajima]
+* Reduce code size bloat by removing literal strings from
+ the g_return_if_fail() macros [Owen Taylor]
+* Add g_strv_length [Tim-Philipp Müller]
+* Win32 changes
+ - Add API to determine the Windows version [Tor Lillqvist]
+* Other bug fixes [Stepan Kasal, Anders, Tor, Kazuki Iwamoto,
+  Manish Singh]
+* Documentation improvements [Morten Welinder, Matthias]
+* New and updated translations (es,nn,ro)
+
+Overview of Changes from GLib 2.5.1 to GLib 2.5.2
+=================================================
+* Add G_GNUC_INTERNAL macro [Arjan van de Ven]
+* Add GOption, a commandline option parser [Anders Carlsson]
+* Add glib_check_version [Michael Natterer]
+* Add XDG basedir API [Ray Strode]
+* Require ngettext [Danilo Segan]
+* Bug fixes [Manish Singh, Ray Strode, Vincent Noel, 
+  Jon-Kare Hellan, Jody Goldberg]
+* Win32 bug fixes [Tor Lillqvist, Hans Breuer, Peter Zelezny]
+* Documentation improvements [Matthias Clasen, Vincent Untz, Christian Persch]
+* New and updated translations (bs,eu,fi,gu,ne,pa)
+
+Overview of Changes from GLib 2.5.0 to GLib 2.5.1
+=================================================
+
+* Bug fixes [Oliver Guntermann, Sven Neumann, James 
+  Henstridge, Hiroyuki Ikezoe, Matthias Clasen, Robert 
+  Ögren, Tommi Komulainen]
+* Documentation improvements [Soeren Sandmann, 
+  Christophe Fergeau, Danek Duvall]
+* New and updated translations (eu,hi)
+  
+Overview of Changes from GLib 2.4.1 to GLib 2.5.0
+=================================================
+
+* New functions g_debug [Sven Herzberg]
+* Use higher precision for mathematical constants [Morten 
+ Welinder]
+* Don't convert to/from UTF-8 in g_filename_{to,from}_uri 
+ [Federico Mena Quintero]
+* Win32
+ - Handle empty digit string in printf() functions 
+   correctly [Tor Lillqvist]
+ - Support ll as format modifier for long long [Tor]
+ - Be more careful about HOME [Tor, Ivan Wong]
+ - Bug fixes [John Ehresman]
+* Miscellaneous bug and portability fixes [Danilo Segan, 
+ Owen Taylor, Nikolai Weibull, Benoît Carpentier, Morten 
+ Welinder, Manish Singh, Sven Neumann, Julio M. Merino Vidal,
+ Kaz Sasayama, Murray Cumming, Federico, Mariano Suarez-Alvarez]
+* Documentation updates [Matthias Clasen, Crispin Flowerday,
+ Tommi Komulainen, Federico Mena Quintero, Ed Griffiths]
+* New and updated translations (ja,ne,no,wa)
+ 
+Overview of Changes from GLib 2.4.0 to GLib 2.4.1
+=================================================
+
+* Win32 bug fixes [Tor Lillqvist, Roger Leigh, John Ehresman]
+* Miscellaneous bug and portability fixes [Owen Taylor,
+  Matthias Clasen, Jonas Jonsson, Christian Krause,
+  Nickolay V. Shmyrev, Christophe Saout, Philippe Blain,
+  Piotr Klaban]
+* Documentation updates [Matthias]
+* New and updated translations (ca,cs,cy,el,en_CA,en_GB,es,eu,fi,
+  fr,gu,he,id,nl,pt,pl,ru,sr,sr@ije,sr@Latn,sv,uk)
+
+Overview of Changes from GLib 2.3.6 to GLib 2.4.0
+=================================================
+
+* Handle invalid-UTF-8 in g_log() properly [Matthias Clasen]
+* Win32 bug fixes [Tor Lillqvist, Bruce Hochstetler]
+* Miscellaneous bug and portability fixes [Olivier Biot, David L. Cooper II, 
+  Kjartan Maraas, Frédéric L. W. Meunier, Christof Petig, Manish Singh, 
+  Sebastian Wilhelmi]
+* Documentation updates [Owen]
+* Updated translations (hr,ro)
+
+Overview of Changes from GLib 2.3.5 to GLib 2.3.6
+=================================================
+
+* GAtomic bug fixes [Sebastian Wilhelmi, Mark McLoughlin]
+* GMain threading fixes and improvements [Sebastian]
+* Win32 [Tor Lillqvist]
+ - restore some symbols extraneously exported from gobject to maintain ABI compatibility
+ - Misc build improvements and fixes [Tor, Cedric Gustin, Hans Breuer]
+* Documentation updates [Sebastian, Takeshi AIHANA, Matthias, Sven Herzberg]
+* New and updated translations (be,es,fi,ga,pa,sr@ije,zh_CN)
+
+Overview of Changes from GLib 2.3.3 to GLib 2.3.5
+=================================================
+
+* Make glib-mkenums parse initializers with macros. [Matthias Clasen, muppet]
+* Respect locale era in g_date_set_parse(). [Theppitak Karoonboonyanan] 
+* Add atomic operations and use it for the async queue and
+  gonce implementation. [Sebastian Wilhelmi]
+* Documentation improvements [Sebastian, Matthias, Sven Herzberg]
+* Add g_main_depth() for finding the recursion depth of the main
+  loop [Owen Taylor, Tim Janik, Stefan Westerfeld]
+* Add g_spawn_close_pid(), needed on win32 [J. Ali]
+* Win32 fixes. [Hans Breuer, J. Ali Harlow]
+* Misc bugfixes [Sebastian, Matthias, Balazs Scheidler, Owen]
+* Updated translations (cy,et,ga,sq)
+
+Overview of Changes from GLib 2.3.2 to GLib 2.3.3
+=================================================
+
+* Add a native AIX gmodule implementation. [Laurent Vivier]
+* Add g_node_copy_deep().  [James M. Cape, Matthias Clasen]
+* Extend GQueue API to match the GList API. [Soeren Sandmann]
+* Add g_hash_table_find().  [Tim Janik]
+* Add a G_MODULE_BIND_LOCAL flag. [David Schleef]
+* Inline g_string_append_c() when possible. [Owen Taylor, Tim]
+* Wrap waitpid() as a GSource. [Jonathan R. Blandford]
+* Add g_completion_complete_utf8(). [Theppitak Karoonboonyanan, 
+  Matthias]
+* Add g_strsplit_set(). [Soeren]
+* Documentation improvements. [Vincent Untz, Sebastian Wilhelmi, 
+  Soeren, Matthias]
+* Win32 build fixes. [Tor Lillqvist]
+* Misc bugfixes [Manish Singh, Noah Levitt, Simon Josefsson, 
+  Morten Welinder, Damien Carbery, Julio M. Merino Vidal, Sebastian, 
+  Matthias]
+* Updated translations (nn,cs,it,ko,sq,ms,az,hr,uk,sr,sr@Latn,sq,ta)
+
+Overview of Changes from GLib 2.3.1 to GLib 2.3.2
+=================================================
+
+* Add G_MAXSIZE. [Manish Singh]
+* Add g_rand_new_with_seed_array(), g_rand_set_seed_array(),
+  implementing the init-by-array functionality of the 
+  original mersenne twister. Add g_rand_copy(). Improve seeding. 
+  [George Lebl]
+* Add a lowercase_name option to glib-mkenums. [Murray Cumming]
+* Add g_ptr_array_foreach(). [Matthias Clasen]
+* Add g_timer_continue(). [Tim-Philipp Müller]
+* Fix a threadsafety issue in mem chunks. [Matthias, Balazs Scheidler]
+* Fix g_filename_{to,from}_utf8() on Win32 and improve 
+  g_file_test() there too [Hans Breuer] 
+* Add a boxed type for NULL-terminated string arrays.  [Matthias]
+* Add G_DEFINE_TYPE() plus variants to ease the constuction
+  of GObject boilerplate code.  [Tim Janik]
+* Support & in password GECOS field [Matthias, Soeren Boll Overgaard]
+* Documentation improvements [Matthias, Manish]
+* Win32 build fixes [Hans]
+* Misc bug fixes [Damien Carbery, Matthias, Manish, Olivier Poncet, 
+  Zack Rusin]
+* Updated translations (ar,de,fa,ga,mn,nn,no,sq)
+
+Overview of Changes from GLib 2.3.0 to GLib-2.3.1
+=================================================
+
+* Add glib/gi18n.h and glib/gi18n-lib.h for common
+  gettext support, including a Q_() macro for translation
+  with context [Matthias Clasen]
+* Add a more flexible G_FILENAME_ENCODING variable
+  as a replacement for G_BROKEN_FILENAMES [Matthias]
+* Fix the return value g_main_context_iterate() for
+  newly ready sources [Padraig O'Briain]
+* Handle Hangul composition for normalization [Noah Levitt]
+* Add G_{MIN,MAX,MAXU}INT{8,16,32}. [Mark Jones, Matthias]
+* Add G_GSIZE_FORMAT/G_SSIZE_FORMAT [Manish Singh]
+* Add G_STRFUNC as a portable wrapper for __func__ [Tim Janik]
+* Documentation improvements [Matthias]
+* GObject [Tim Janik]
+ - Support '-' in g_signal_connect()/disconnect() names
+   like 'swapped-signal'.
+ - Add g_type_class_peek_static() and use to optimize
+   g_object_new() for static types [Tim]
+ - Allow setting construct-only properties from within
+   init() implementations
+ - Enforce readability/writeability in g_object_set/get()
+* Fix bug with g_ascii_strtod and multi-byte separator.
+  [Behdad Esfahbod, Roozbeh Pournader]  
+* Misc bug fixes [Matthias, John Ehresman, Andrew Lanoix,
+  Tor Lillqvist, Mark McLoughlin, Tim-Philipp Müller, Manish, 
+  Morten Welinder]
+* Updated translations (ca,cs,da,es,fr,ja,nn,no,pt,ru)
+
+Overview of Changes from GLib 2.2.x to GLib-2.3.0
+=================================================
+
+* Replace Trio printf by gnulib vasnprintf [Matthias Clasen]
+* Update Unicode data to Unicode 4.0 [Noah Levitt]
+* Support XML-safe formatted output with 
+  g_markup_[v]printf_escaped [Owen Taylor]
+* Add g_file_read_link to read symbolic links [Matthias]
+* Add g_unichar_get_mirror_char to obtain the 
+  mirrored variant of a character [Noah]
+* Support for one-time initialization functions. 
+  [Sebastian Wilhelmi]
+* Miscellaneous API additions: g_vasprintf
+  g_string_chunk_insert_len, g_setenv, g_unsetenv [Matthias]
+* Docs improvements [Matthias]
+* Add support instance-private data on classed types
+  [Mark McLoughlin, Tim Janik, Owen]
+* Optimize signal emissions [Soeren Sandmann, Tim]
+* Support a "default vtable" per interface [Tim]
+* Add support for properties on interfaces [Owen, Tim]
+* Miscellaneous API additions: g_value_take_string(),
+  g_value_take_param(), g_value_take_object(), 
+  g_value_take_boxed(). [Matthias]
+* Win32 build fixes [Tor Lillqvist]
+
+Overview of Changes from GLib 2.1.5 to GLib-2.2.0
+=================================================
+
+* Fix a problem with g_thread_init() on 64-bit problems
+  [Alceste Scalas, Sebastian Wilhelmi]
+* Add assembly implementations of byteswap macros
+  for ia64 and x86_64. [Manish Singh]
+* IOChannel fixes for Win32 [Tor Lillqvist, Thorsten Maerz]
+* Updated translations (bg,ca,es,da,fi,lv,ru,sk)
+
+Overview of Changes from GLib 2.1.4 to GLib-2.1.5
+=================================================
+
+* Win32 bug fixes [Tor Lillqvist]
+* Various post-rewrite fixes for glib-gettext.m4 [Owen Taylor,
+  Jody Goldberg, Kjartan Maraas, Johannes Stezenbach]
+* Ensure we have a GUINT64_FORMAT by pulling in Trio
+  if necessary [Manish Singh]
+* Further Trio build fixes [Matthias Clasen, Owen]
+* Hack around gcc, libtool issues with -pthread [Owen]
+* Docs improvements [Matthias]
+* Bug and portability fixes 
+* Updated and new translations (bg,de,fi,fr,sq,fr)
+
+Other contributors: Kai Poitschke, Morten Welinder
+
+Overview of Changes from GLib 2.1.3 to GLib-2.1.4
+=================================================
+
+* autoconf changes to make it possible to cross compile
+  GLib. [Owen Taylor, Dan Kegel, Amy Lin, Dimi Shahbaz, 
+  Johannes Stezenbach]
+* Use libintl when it has bind_textdomain_codeset() and
+  GLib doesn't. [Owen]
+* Improve generation of pseudo-random integers [Morten Welinder, 
+  Sebastian Wilhelmi]
+* Avoid literal UTF-8 in favor of octal escapes [Owen, Tomas Ogren]
+* Cleanup include order [Sven Neumann]
+* autoconf cleanups and bug fixes [Daniel, Matthias Clasen, Owen]
+* Doc fixes and additions [Matthias]
+
+Other contributors: James M. Cape, Frederic Crozat, Martin Gansser,
+  Phuc LeHong, Manish Singh, Joshua Weage, Morten Welinder
+
+Overview of Changes from GLib 2.0.x to GLib-2.1.x
+=================================================
+
+* Add copy of the Trio library to build and use for printf() when 
+  system printf isn't good enough. Add g_printf()/etc. [Matthias Clasen]
+* Add g_str_has_suffix()/g_str_has_prefix() [Alex Larsson]
+* Add g_markup_parse_context_get_element() [Matthias]
+* Add g_utf8_strreverse [Matthias]
+* Add g_ascii_strtoull() [Tim Janik]
+* Support scanning of 64-bit values with GScanner [Tim]
+* Add g_set/get_application_name() [Havoc Pennington]
+* Add G_LIKELY()/G_UNLIKELY() macros for hinting branch probabilities. 
+  Use for g_return_if_fail(). [Matthias Clasen]
+* Add G_GNUC_DEPRECATED macro [Tom Tromey]
+* Improve the seeding algorithm of GRandom to avoid problems
+  with certain pathological seeds. Support G_RANDOM_VERSION=2.0
+  environment variable. [Sebastian Wilhelmi]
+* Improve thread configure checks, use -pthread where applicable
+  [Sebastian]
+* Improve handlng of thread priorities [Sebastian]
+* Fix up parameter names that might shadow functions from
+  system headers [Soeren Sandmann]
+* Clean up usage of deprecated functions [Manish Singh]
+* Docs fixes and improvements. In particular, include "Since" information.
+  [Matthias, Soeren, Martin Schulze, Daryll Strauss, Bill Janssen, 
+  Owen Taylor, Morten Welinder]. 
+
+Overview of Changes in GLib 2.0.7
+=================================
+
+* Fix C++ warnings in gtype.h [Dom Lachowicz]
+* Fix g_type_fundamental_next() [Tim Janik]
+* Fix various missing includes of config.h [Morten Welinder]
+* Handle main loop initialization before g_thread_init [Sebastian Wilhelmi]
+* Various 64-bit fixes [Manish Singh]
+* Fix GPoll on Win32 [Tor Lillqvist, Herman Bloggs]
+* Fix bug with buffering on UTF-8 IOChannels [Daniel Elstner]
+* Misc bug and build fixes [Soren Andersen, Gustavo Carneiro, Tor,
+     Tim, Havoc Pennington,  Matthias Clasen, Sebastian Rittau,
+     Masahiro Sakai, Arvind Samptur, HideToshi Tajima, Owen Taylor]
+* Updated and new translations (be,cs,de,*fa,it,lv,pt_BR,tr)
+
+Overview of Changes in GLib 2.0.6
+=================================
+
+* Fix problem with interface prerequisites [Jon Trowbridge, Dave Camp]
+* Clean up debug spew from GObject [Anders Carlsson]
+* Compiler warning fixes [David L. Cooper II]
+* Fix some problems with g_build_path() [Guillaume Chazarain, Owen Taylor]
+* Fixes for --disable-debug [Sebastian Wilhelmi]
+* Threading fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, 
+  Rajkumar Sivasamy, Laurent Vivier]
+* Documentation fixes [Jacob Berkman, Manuel Clos, Jared Dukat, 
+  Sebastian Rittau, Linus Welleij]
+* Misc bug fixes [Anders Carlsson, Sam Couter, Morten Welinder, Owen]
+* Updated translations (bg,ko,vi)
+
+Overview of Changes in GLib 2.0.5
+=================================
+
+* Fix problem with interface prerequisites [Jon Trowbridge, Dave Camp]
+* Clean up debug spew from GObject [Anders Carlsson]
+* Compiler warning fixes [David L. Cooper II]
+* Fix some problems with g_build_path() [Guillaume Chazarain, Owen Taylor]
+* Fixes for --disable-debug [Sebastian Wilhelmi]
+* Threading fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, 
+  Rajkumar Sivasamy, Laurent Vivier]
+* Documentation fixes [Jacob Berkman, Manuel Clos, Jared Dukat, 
+  Sebastian Rittau, Linus Welleij]
+* Misc bug fixes [Anders Carlsson, Sam Couter, Morten Welinder, Owen]
+* Updated translations (bg,ko,vi)
+
+Overview of Changes in GLib 2.0.4
+=================================
+
+* Fix some 64-bit problems. (George Lebl, David L. Cooper II)
+* Add note about Tru64 iconv to INSTALL. (Manuel Op de Coul)
+* Fix problem with timouts > MAXINT. (Tim Janik, Owen Taylor)
+* Updated translations (ca,es,fr,ja,gl,ms,nl,pl,pt,ru)
+
+Overview of Changes in GLib 2.0.3
+=================================
+
+* Handle sorting 0-length arrays (Ron Arts)
+* Threading fixes (Sebastian Wilhelmi)
+* Portability fixes (Miroslaw Dobrzanski-Neumann, Jacob Berkman, Gareth Pierce, 
+  Sebastian, Qingjiang Yuan)
+* Various fixes for glib-2.0.m4. (Jim Gettys, others.)
+* Locate right glib-genmarshal when cross-compiling. (Mitch Natterer)
+* Win32 fixes (Tor Lillqvist)
+* Try to fix g_get_charset() related segfaults. (Owen)
+* Fixes for gettext detection. (Dan Winship, HideToshi Tajima, Boyd Lynn Gerber,
+  Andrew P. Lentvorski, Jr.)
+* Fix g_scanner_unexp_token() (Tim Janik, Sven Neumann)
+* g_markup fixes. (Matthias Clasen.)
+* Bug fixes and cleanups (Daniel Elstner, Matthias, Laszlo Peter, Morten Welinder,
+  Wayne Schuller)
+
+Overview of Changes in GLib 2.0.1
+=================================
+
+* Portability fixes for Sun's Forte compiler [Erwann Chenede]
+* Performance improvements for GObject parameter lookup, 
+  g_filename_to/from_utf8() [Alex Larsson]
+* Actually check interface prerequisites [Matthias Clasen,
+  Miroslaw Dobrzanski-Neumann]
+* Fix problem with glib-mkenums taking huge amounts of stack. [Owen Taylor]
+* Fix g_signal_handlers_disconnect_by_func() for C++ [Damien Sandras]
+* Fixes for g_log() and threading.
+  [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, Tim Janik]
+* Make g_print(), g_printerr(), g_warning(), etc, convert from
+  UTF-8 to the encoding of the locale [Sebastian Wilhelmi, Tim]
+* Fixes for GIOChannel on windows. [Tor Lillqvist]
+* Fix gsize/gint mismatches in giochannel.c [Miroslaw Dobrzanski-Neumann]
+* Fix file descriptor leak in g_file_get_contents() [Matthias]
+* Workaround iconv() problems on older Solaris [Lauri Alanko]
+* Fix warnings with gcc-3.1 about asm const [Cody Russel]
+* Minor bug fixes.
+
+Other contributors: Hans Breuer, LEE Sau Dan, Sven Neumann, Salmaso Raffaele,
+  Akira Tagoh, Morten Welinder
+
+
+Overview of Changes in GLib 2.0.0
+=================================
+
+* Thread portability fixes [Sebastian Wilhelmi]
+* Documentation updates [Owen Taylor]
+* Make g_strerror(), g_strsignal() properly return UTF-8,
+  call bind_text_domain_codeset() so that error strings
+  are in UTF-8 as well. [Owen, Tor Lillqvist]
+
+Overview of Changes in GLib 2.0.0 rc1:
+======================================
+
+* Win32 fixes [Tor Lillqvist]
+* Portability fixes [Finlay Dobbie, Miroslaw Dobrzanski-Neumann]
+* Fix up g_date_strftime [Daniel Elstner]
+* Add some structure padding [Tim Janik]
+* Make g_get_homedir() prefer the users home directory to $HOME
+
+Other contributors: Matthias Clasen, Paolo Maggi, Christian Rose
+
+Overview of Changes in GLib 1.3.15:
+===================================
+
+* Speed up marshalers by using private access to GValue 
+  [Anders Carlsson, Tim Janik]
+* Reduce GValue to 2 elements [Tim]
+* Add G_DEBUG environment variable, G_DEBUG=fatal_warnings [Matthias Clasen]
+* Fixes for AIX compilation [Miroslaw Dobrzanski-Neumann]
+* Add padding to various structures [Owen Taylor, Tim]
+* Win32 fixes [Tor Lillqvist]
+
+Other contributors: James Henstridge, Ryan Lovett, Morten Welinder,
+  Daniel Elstner
+
+Overview of Changes in GLib 1.3.14:
+===================================
+
+* Register value transformations for gint64, guint64 [Andy Wingo]
+* Build with large-file support [Sven Neumann, Owen Taylor]
+* Fix handling of hostnames in URI's [Darin Adler]
+* Main loop bug fixes [Havoc Pennington, Owen]
+* Doc fixes and improvements [Manish Singh, Tim Janik]
+* Support ' as attribute delimiters in GMarkup [Matthias Clasen]
+* Win32 fixes [Hans Breuer, Tor Lillqvist]
+* Threading bug and build fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann]
+* Miscellaneous bug fixes
+
+Other contributors: Matthias Clasen, James Henstridge, Mitch Natterer, 
+  Morten Welinder.
+
+Overview of Changes in GLib 1.3.13:
+===================================
+
+* Fix g_filename_to/from_uri for Win32 [Tor Lillqvist, Darin Adler]
+* Miscellaneous win32 fixes [Tor, Hans Breuer]
+* Fix thread options for gcc on AIX [Jerome Zago, Sebastian Wilhelmi]
+* Documentation improvements [Ron Steinke, Matthias, Sebastian]
+* Cache iconv converters as used by g_convert() [Jeffrey Stedfast]
+* Bug fixes [Sven Neumann, Owen Taylor, Matthias Clasen, Jeffrey,
+  Laszlo Peter, Havoc Pennington, Tim Janik]
+
+Overview of Changes in GLib 1.3.12:
+===================================
+
+* Implement closure chaining, fixing up API (Tim Janik)
+* Closure chaining test case (James Henstridge)
+* Make GType long not int where both are equal width (Tim)
+* Win32 fixes and improvements (Hans Breuer, Tor Lillqvist)
+* Fixes for NetBSD. (Dan Winship)
+* Use snprintf() for g_printf_string_upper_bound() where possible. (Matthias Clasen)
+* Save space for GBSearchArray (Tim Janik)
+* Documentation improvements. (Matthias, Sven Neumann, Havoc Pennington)
+
+Other contributors: Darin Adler, Chris Blizzard, Anders Carlson, Daniel Elstner, Michael Meeks, 
+  Mark McLoughlin, Dave Neary, Manish Singh, Owen Taylor, HideToshi Tajima, 
+  Sebastian Wilhelmi.
+
+
+Overview of Changes in GLib 1.3.11:
+===================================
+
+* Win32 fixes [Hans Breuer, Tor Lillqvist]
+* Documentation improvements [Matthias Clasen]
+* Portable directory handling API [Hans]
+* Threading fixes [Sebastian Wilhelmi, Havoc Pennington]
+* Fix excess relocations in Unicode tables [Andrew Taylor]
+* Fix gpattern for UTF-8 [Matthias Clasen]
+* Support overriding class closures [Tim Janik]
+* Support for derivation from G_TYPE_POINTER [Owen Taylor]
+* Hide pointers to type information inside GType to reduce locking
+  [Alex Larsson, Tim]
+* Adds check for direct inclusion of gobject/*.h [Owen]
+* GObject API cleanups [Tim]
+
+Other contributors: Darin Adler, Jacob Berkman, Daniel Egger, Eric Lemings, 
+  Michael Meeks, Mark McLoughlin, Arkadiusz Miskiewicz, Dan Winship
+
+
+Overview of Changes in GLib 1.3.10:
+===================================
+
+* Many Win32 fixes and improvements [Tor Lillqvist]
+* Documentation improvements [Matthias Clasen]
+* g_string_printfa() renamed to g_string_append_printf()
+* Use libcharset from libiconv to implement charset detection
+  more portably. [Owen Taylor, Hidetoshi Tajima]
+* Add 64 bit type support to GObject [Joshua Pritikin, Mathieu Lacage, Owen]
+* Make support for 64 bit integers a requirement [Joshua]
+* GPattern improvements [Tim Janik, Matthias]
+* Locale independent g_ascii_strtod / g_ascii_dtostr [Alex Larsson]
+* Many bug fixes and minor tweaks.
+
+Other Contributors: Darin Adler, Jakub Jelinek, James Antill, Andrew Taylor,
+  Ben Gertzfield, Elliot Lee, Manish Singh, Abel Cheung, Laszlo Peter,
+  Sven Neumann, George Lebl, Raja Harinath, Sebastian Wilhelmi,
+  Jacob Berkman
+
+
+Overview of Changes in GLib 1.3.9:
+==================================
+
+* Fixes for comparison of threads [Sebastian Wilhelmi]
+* Use vasprintf() when possible for g_strdup_printf [Matthias Clasen]
+* Win32 fixes [Tor Lillqvist, Hans Breuer]
+* Add a len argument to g_ascii_strup/strdown
+* Bug, portability fixes, cleanups.
+
+Other Contributors: Darin Adler, Katsuhiro Okuno, Joshua N. Pritikin
+
+
+Overview of Changes in GLib 1.3.8:
+==================================
+
+* Documentation updates [Owen]
+* Made GType interfaces overridable in derived types
+* Many win32 fixes [Tor Lillqvist]
+* Miscellaneous cleanups and fixes
+
+Other contributors:
+  Darin Adler, Matthias Clasen, Ron Steinke, Hans Breuer, Alex Larsson
+
+
+Overview of Changes in GLib 1.3.7:
+==================================
+
+* Integrate GClosure support into the main loop [Owen Taylor]
+* More GSignal convenience functions (macros) [Sven Neumann, Tim Janik]
+* Introduced weak references for GObject [James Henstridge, Sven, Tim] 
+* Minor hash table optimizations
+* Main loop and threading improvements [Sebastian Wilhelmi]
+* Added g_ascii_* functions to be used for locale insensitive UTF-8
+  compliant code instead of old string functions  [Darin Adler, Alex Larsson]
+* Add functions for Unicode case-conversion, normalization, and 
+  collation [Owen]* GString improvements [Owen]
+* Reworked the GIOChannel code [Hidetoshi Tajima, Ron Steinke]
+* Removed glib-config-2.0 in favour of pkgconfig [Sebastian]
+* Make code 64bit clean [Mark Murnane]
+* More G_CONST_RETURN fixes
+* Many improvements to the win32 code [Tor Lillqvist, Hans Breuer]
+* Miscellaneous bug and API fixes
+
+Other contributors:
+  Michael Natterer, Christopher James Lahey, Padraig O'Briain,
+  Matthias Clasen, Josh Pritikin, Steve Baker, Cesar Rincon, Garry R. Osgood,
+  Michael Meeks, Laszlo Peter,  Martin Baulig, Kjartan Maraas, Andrew Lanoix,
+  Peter Williams
+
+
+Overview of Changes in GLib 1.3.6:
+==================================
+
+* Threads have a "return value" from g_thread_join
+* Removed ability to adjust thread stack size
+* Prefix warnings with progname/PID by default, change toggle for this to 
+  be an env variable G_MESSAGES_PREFIXED not a compile-time option
+* GMarkup speedups
+* GDate const, convenience fixups
+* Include test cases that headers are compilable by C++ compiler
+* Add ability to spawn processes with argv[0] != executable path.
+* g_strstr_len, g_strrstr, g_strrstr_len
+* Add length argument to g_utf8_strchr and g_utf8_strrchr.
+* Misc bug fixes
+
+
+Overview of Changes in GLib 1.3.5:
+==================================
+
+* Added an installed glib-mkenums Perl program for parsing enumeration
+  declarations from header files.
+* Mark some additional deprecated functions.
+* Bug and Portability fixes
+
+
+Overview of Changes in GLib 1.3.4:
+==================================
+
+* Efficiency improvements for GThreadPool
+* A few bug fixes
+* Build fixes
+* Documentation improvements
+
+
+Overview of Changes in GLib 1.3.3:
+==================================
+
+GLib:
+
+* More user_data support in various functions.
+* Main loop API revamps to support per-thread main loops.
+* Unicode handling improvements.
+* Implemented debugging traps.
+* G_CONST_RETURN specification all over the place.
+* Various new small utility functions.
+* Random number generator precision improvements.
+* New configure option --disable-mem-pools.
+* Many Win32 improvements.
+* Added g_try_malloc() friends varinats.
+* Many documentation improvements.
+* Many threading improvements, support for dynamic allocation
+  of static mutexes.
+* GHookLIst API cleanups.
+* Improved format support of GDate parser.
+* String function speed improvements with new g_stpcpy().
+* Hashtable API additions.
+* New GPatternSpec for shell-style pattern matching (from GtkPatternSpec).
+* Optimizations, cleanups, bug fixes.
+
+GObject:
+
+* Added many convenience functions.
+* GClosure and GParamSpec use float/sink ref-counting scheme now.
+* Reworked property change notification.
+* Binary searchable array cleanups, so it's widely usable now.
+* Added static content keeping for some GValue types.
+* Support for statically scoped signal parameters.
+* Extinguished property trailer args in set/get interface.
+* Added support for abstract types.
+* G_CONST_RETURN specification all over the place.
+* Split parameter exchange functionality into value transforms
+  and parameter conversions.
+* Added signal emission hooks and signal accumulators.
+* Added interface prerequisites to support is_a (interface, object)
+  relations.
+* Implemented GValueArray.
+* New types, boxed: G_TYPE_VALUE, G_TYPE_CLOSURE, G_TYPE_GSTRING
+  GParamSpecs: G_TYPE_PARAM_PARAM, G_TYPE_PARAM_POINTER, G_TYPE_PARAM_CLOSURE,
+  G_TYPE_VALUE_ARRAY, G_TYPE_PARAM_UNICHAR, G_TYPE_PARAM_VALUE_ARRAY.
+* Varrags value collection improvements.
+* Implemented debugging traps.
+* Made things thread-safe.
+* Many documentation improvements.
+* Many cleanups, optimizations and bug fixes.
+
+
+Overview of Changes in GLib 1.3.2:
+==================================
+
+GLib:
+
+* Win32 build improvements  [Tor]
+* Improvements to error reporting  
+  (g_critical(), g_return_if_reached()) [Darin]
+* Add g_strlcpy/g_strlcat  [David Wheeler]
+* New IO channel implementation for Win32  [Tor] 
+* Make g_array_free, g_string_free return pointer to memory requested
+  not to be freed.  [Darin]
+* Added GError based error reporting for thread functions.  [Sebastian]
+* Moved reference docs into GLib distribution. [Owen]
+* Added g_convert() for doing convenient character set conversions based
+  on iconv. (GLib now requires libiconv or a native iconv.) [Havoc/Owen]
+* Various Unicode handling additions (g_ucs4_to_utf8, g_utf8_validate(),
+  g_{locale,filename}_{to,from}_utf8)  [Robert/Havoc/Owen]
+* Portability fixes for threading.  [Sebastian]
+* Added convenient functions for launching new processes (g_spawn_*),
+  and shell quoting/unquoting functions.  [Havoc]
+* Split glib.h into many headers.  [Sebastian]
+* Added a simple callback-based parser for XML-like files (GMarkup).  [Havoc]
+* Fixed confusions between comparison functions that return <0, 0, >0
+  and equaility functions that return FALSE,TRUE.  [Sebastian]
+* Added safe/portable temporary file manipulation functions.  [Tor]
+* autoconf improvements.  [Raja]
+* Many documentation improvements.
+* Bug fixes.
+
+GObject:
+
+* Added boxed and pointer types.  [Tim/Jonathan]
+* Added callback abstraction (GClosure)  [Tim]
+* Added signal system (GSignal)  [Tim]
+* Make GTypePlugin an interface  [Tim]
+* Added GTypeModule - a simple GTypePlugin instantiation  [Owen]
+* Bug fixes.
+
+
+What's new in GLib 1.3.1:
+=========================
+
+* New GObject library added including object system based on
+  the GTK+ object system. 
+* Functions for getting the properties of Unicode characters, 
+  computing the canonical decomposition and ordering combining
+  characters aand manipulating UTF-8 string manipulation based
+  on libunicode.
+* GString now properly handles embedded nuls.
+* Multiple fixes from the 1.2.x branch.
+* Upgrade to libtool 1.3.3
+* Full thread support (thread creation and destruction).
+* BeOS port, BeOS dynamic modules.
+* Many improvements to the Windows ports.
+* Improvements to the OS/2 port, OS/2 module support.
+* Double ended queue implementation.
+* GLib macros for printf() formatting, e.g. G_GULONG_FORMAT = "lu"
+* New configure option --enable-msg-prefix to prefix messages, warnings
+  et ceteri with the program name and the process id.
+* New thread-safe random number generator Mersenne Twister.
+* g_strcompress() added, g_strescape() had a slight API change, and
+  more tightly defined semantics.
+* the g_string(x) macro has been removed, #x may be used instead.
+                                
+
diff --git a/NEWS.pre-1-3 b/NEWS.pre-1-3
new file mode 100644
index 0000000..1aa4f4e
--- /dev/null
+++ b/NEWS.pre-1-3
@@ -0,0 +1,211 @@
+Overview of Changes in GLib 1.2.1:
+
+* g_realloc() fix for SunOS (please report further problems).
+* Continued the never ending fix vendetta regarding getpwuid(),
+  this time AIX has been the culprit.
+* Upgrade to libtool 1.2f
+* Miscellaneous other buglets fixed.
+
+What's new in GLib 1.2.0 (since GLib 1.0.x):
+
+* GLib is distributed seperatedly from Gtk+
+* Win32 Portability
+* Threading support
+* GModule mechanism (implemented in an extra library) which wraps dynamic
+  object code loading facilities in a portable manner
+* GIOChannel structure to encapsulate the IPC mechanism
+* GQuarks and datasets
+* GRelations for n-way mapping of certain data
+* An n-way tree implementation
+* GDate functionality for calendar date manipulations
+* GAllocator type and associated functions
+* Added generic callback maintenance functions (ghook)
+* Generic functions for TAB completions
+* Endian defines (G_*_ENDIAN)
+* g_log() mechanism for logging of messages at different log levels
+* Generic main-loop mechanism
+* New glib-config helper script
+* Many more API extensions
+
+Overview of Changes in GLib 1.1.16:
+
+* Allocate smaller pools of memory for glists, gslists, gnodes
+* Bug Fixes
+
+Overview of Changes in GLib 1.1.15:
+
+* HPUX 11 thread system detection should now work
+* Release the main loop lock around calls to prepare() and
+  check() so it is not held over user code
+* A few Win32 fixups
+
+Overview of Changes in GLib 1.1.14:
+
+* Check for dlsym() in system libraries and -dl
+* FreeBSD portability fixes
+* Random bug fixes and autoconf/automake changes
+
+Overview of Changes in GLib 1.1.13:
+
+* Removed alloca() based function and macro variants again.
+* Improved thread related configure tests.
+* GSource destruction fixups.
+* Fixed up idle function removal based on user_data pointer.
+* Advanced Win32 portability.
+* Enforced GSource's check(), prepare() and dispatch() constrains,
+  loop recursions may only happen from dispatch(), and check() as well
+  as prepare() are called while the main_loop lock is being held.
+* GLib development now requires GNU autoconf 2.13, GNU automake 1.4
+  and GNU libtool 1.2d.
+* Lots of random portability and bug fixes.
+
+Overview of Changes in GLib 1.1.12:
+
+* Added alloca functions/macros: g_strdup_a, g_strconcat3_a, g_alloca,
+  g_new_a, g_new0_a
+* New tests structure.  Type 'make check' on your system to run them.
+* Avoid unnecessary extra hook referencing in g_hook_list_marshal
+
+Overview of Changes in GLib 1.1.11:
+
+* provide defaults for POLL sysdefs
+* g_main_is_running: new function to check whether a main loop has been quitted
+* a few other enhancement/fixes
+
+Overview of Changes in GLib 1.1.9:
+
+* Check for pthread_attr_init in all cases, Digital Unix 4 requires this
+* For G_LOCK_DECLARE_*, if !G_THREADS_ENABLED, eat trailing semicolon better
+* Changed g_main_poll_(add|remove) to g_main_(add|remove)_poll
+
+Overview of Changes in GLib 1.1.8:
+
+* Added threading support
+  - The ability to specify a set of functions to be used for
+    locking at runtime.
+  - Default implementations of locking functions for pthreads,
+    Solaris threads, and (experimentally) NSPR.
+  - All static variables should now properly locked.
+  - Enhancements to the generic main-loop mechanism to be thread-safe.
+    (It is used for the main-loop in GTK+ as of GTK+-1.1.8)
+* Portability fixes.
+
+Overview of Changes in GLib 1.1.7:
+
+* Removed multiple define from glibconfig.h
+
+Overview of Changes in GLib 1.1.6:
+
+* New GDate functionality for calendar date manipulations (g_date_*)
+* New GAllocator type and associated functions
+* New functions g_slist_copy and g_list_copy to duplicate a list with all
+  its data pointers.
+* New function g_array_insert_vals and new macro g_array_insert_val to
+  insert elements at an arbitrary index
+* GAllocators used for glist, gslist, gnode node allocations
+* Incremental freezing in ghash
+* New function g_hook_list_marshal_check to eventually destroy hooks after
+  they got marshalled
+* Revised GIOChannel to provide generic virtual-function based interface
+* Added generic main-loop abstraction
+* Removed GListAllocator type and its g_*_allocator_*() function variants
+* Bug fixes
+
+Overview of Changes in GLib 1.1.5:
+
+* Win32 portability
+* GIOChannel structure to encapsulate the IPC mechanism 
+* Reimplemented endian stuff, using inline asm for x86
+* New functions:
+  - g_strescape: escapes backslashes
+  - g_path_is_absolute and g_path_skip_root
+  - g_getenv: expands environment variables that contain references 
+    to other environment variables
+  - g_scanner_sync_file_offset: rewind the filedescriptor to the current
+    buffer position and blow the file read ahead buffer
+  - g_array_remove_index: remove an entry, preserving the order
+  - g_array_remove_index_fast: remove an entry, order might be distorted
+  - g_ptr_array_remove: remove an entry, preserving the order 
+  - g_ptr_array_remove_fast: remove an entry, order might be distorted
+  - g_byte_array_remove_index: wrapper for g_array_remove_index
+  - g_byte_array_remove_index_fast: wrapper for g_array_remove_index_fast
+  - g_strncasecmp: modeled closely after g_strcasecmp
+  - g_list_sort, g_slist_sort: to merge sort GLists and GSLists
+* New macros:
+  - G_DIR_SEPARATOR, G_DIR_SEPARATOR_S: platform-dependant file name
+    syntax elements
+  - G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S: platform-dependant
+    search path syntax conventions
+  - G_STRUCT_OFFSET, G_STRUCT_MEMBER_P, G_STRUCT_MEMBER: for handling
+    structure fields through their offsets
+* Removed G_ENUM, G_FLAGS, G_NV, and G_SV macros
+* Bug fixes
+
+Overview of Changes in GLib 1.1.4:
+
+* Added generic callback maintenance functions (ghook)
+* New endian defines (G_*_ENDIAN)
+* New string join/split/free routines 
+* Fixes
+
+Overview of Changes in GLib 1.1.3:
+
+* New GModule mechanism (implemented in an extra library) which wraps dynamic
+  object code loading facilities in a portable manner.
+* glib-config features extra "glib" (old behaviour remains) and "gmodule"
+  (add libgmodule.so to the --libs output) arguments now. this can also
+  be specified as fourth argument to the AM_PATH_GLIB() macro.
+* Overhaul of the `inline' autoconfiguration stuff, so inlining should be
+  sufficiently supported on all systems that allow inlining now.
+* New g_log() mechanism for logging of messages at different log levels,
+  associated with certain log domains (define -DG_LOG_DOMAIN for your library).
+* New inline functions for bit masks tests.
+* GNode macros (and functions) now return the newly allocated node.
+* New macro G_VA_COPY() to work around va_list copying oddities on some
+  platforms. the non-static g_vsprintf() function vanished in favour of
+  a publically exported g_strdup_vprintf().
+  People that used the former g_vsprintf() would definitely want to read the
+  associated ChangeLog entries (grep for printf).
+* New utility functions:
+  g_strndup(), g_on_error_query(), g_on_error_stack_trace(), g_strdup_printf(),
+  g_strdup_vprintf(), g_printf_string_upper_bound(), g_spaced_primes_closest(),
+  g_strnfill(), g_memdup(). 
+* Overhaul of the array implementations, this contains some source incompatible
+  changes. Again, the ChangeLog is much more informative (grep for garray.c).
+* The internals of the g_dataset mechanism are now exported through the
+  new g_datalist_* API (this is also the underlying implementation for the
+  keyed data of GtkObjects).
+* New function g_atexit(), use of the ATEXIT() macro is discouraged.
+* Better configure checks for ansi compliance.
+* Libtool update to version 1.2b.
+* Lotsa bug fixes and cleanups as always ;)
+
+Overview of Changes in GLib 1.1.2:
+
+* Fixed packaging mistake which occured in 1.1.1
+* fix 64-bitness in g_prints in glibtest
+
+What is new in GLib 1.1.1:
+
+* An n-way tree implementation is provided now, based on the GNode structure.
+* Bugfix for pointer arrays.
+
+What is new in GLib 1.1.0:
+
+* GLib is distributed seperatedly from Gtk+ now and uses a sophisticated
+  shared library versioning scheme to deal with interface and binary
+  incompatibilities.
+* There is a glib-config helper script installed now.
+* Fixups all over the place.
+* gboolean is now a gint, not a gchar anymore.
+* API extensions for GList and GSList.
+* New g_str*() functions for simple string handling.
+* GScanner extensions for scope, warning and error handling.
+* Minor performance improvements for GMemChunks.
+* Implementations of GQuarks and datasets (similar to GtkObjects data
+  mechansim, but works for generic memory locations).
+* More convenience macros for GNU C function arguments.
+* Const correction all over the place, including a new pointer type
+  gconstpointer.
+* Generic functions for TAB completions.
+* GRelations for n-way mapping of certain data.
diff --git a/README b/README
new file mode 100644
index 0000000..96dc92f
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+See README.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4bc4113
--- /dev/null
+++ b/README.md
@@ -0,0 +1,333 @@
+# GLib
+
+GLib is the low-level core library that forms the basis for projects such
+as GTK and GNOME. It provides data structure handling for C, portability
+wrappers, and interfaces for such runtime functionality as an event loop,
+threads, dynamic loading, and an object system.
+
+The official download locations are:
+  <https://download.gnome.org/sources/glib>
+
+The official web site is:
+  <https://www.gtk.org/>
+
+## Installation
+
+See the file '[INSTALL.in](INSTALL.in)'
+
+## How to report bugs
+
+Bugs should be reported to the GNOME issue tracking system.
+(<https://gitlab.gnome.org/GNOME/glib/issues/new>). You will need
+to create an account for yourself.
+
+In the bug report please include:
+
+* Information about your system. For instance:
+  * What operating system and version
+  * For Linux, what version of the C library
+  * And anything else you think is relevant.
+* How to reproduce the bug.
+  * If you can reproduce it with one of the test programs that are built
+  in the tests/ subdirectory, that will be most convenient.  Otherwise,
+  please include a short test program that exhibits the behavior.
+  As a last resort, you can also provide a pointer to a larger piece
+  of software that can be downloaded.
+* If the bug was a crash, the exact text that was printed out
+  when the crash occurred.
+* Further information such as stack traces may be useful, but
+  is not necessary.
+
+## Patches
+
+Patches should also be submitted as merge requests to gitlab.gnome.org. If the
+patch fixes an existing issue, please refer to the issue in your commit message
+with the following notation (for issue 123):
+Closes: #123
+
+Otherwise, create a new merge request that introduces the change, filing a
+separate issue is not required.
+
+## Notes
+
+### Notes about GLib 2.48
+
+* The system copy of PCRE is now used by default to implement GRegex.
+  Configure with --with-pcre=internal if a system PCRE version
+  is unavailable or undesired.
+
+### Notes about GLib 2.46
+
+* GTask no longer imposes a fixed limit on the number of tasks that
+  can be run_in_thread() simultaneously, since doing this inevitably
+  results in deadlocks in some use cases. Instead, it now has a base
+  number of threads that can be used "for free", but will gradually
+  add more threads to the pool if too much time passes without any
+  tasks completing.
+
+  The exact behavior may continue to change in the future, and it's
+  possible that some future version of GLib may not do any
+  rate-limiting at all. As a result, you should no longer assume that
+  GTask will rate-limit tasks itself (or, by extension, that calls to
+  certain async gio methods will automatically be rate-limited for
+  you). If you have a very large number of tasks to run, and don't
+  want them to all run at once, you should rate-limit them yourself.
+
+### Notes about GLib 2.40
+
+* g_test_run() no longer runs tests in exactly the order they are
+  registered; instead, it groups them according to test suites (ie,
+  path components) like the documentation always claimed it did. In
+  some cases, this can result in a sub-optimal ordering of tests,
+  relative to the old behavior. The fix is to change the test paths to
+  properly group together the tests that should run together. (eg, if
+  you want to run test_foo_simple(), test_bar_simple(), and
+  test_foo_using_bar() in that order, they should have test paths like
+  "/simple/foo", "/simple/bar", "/complex/foo-using-bar", not
+  "/foo/simple", "/bar/simple", "/foo/using-bar" (which would result
+  in test_foo_using_bar() running before test_bar_simple()).
+
+  (The behavior actually changed in GLib 2.36, but it was not
+  documented at the time, since we didn't realize it mattered.)
+
+### Notes about GLib 2.36
+
+* It is no longer necessary to call g_type_init().  If you are
+  loading GLib as a dynamic module, you should be careful to avoid
+  unloading it, then subsequently loading it again.  This never
+  really worked before, but it is now explicitly undefined behavior.
+  Note that if g_type_init() was the only explicit use of a GObject
+  API and you are using linker flags such as --no-add-needed, then
+  you may have to artificially use some GObject call to keep the
+  linker from optimizing away -lgobject. We recommend to use
+  g_type_ensure (G_TYPE_OBJECT) for this purpose.
+
+* This release contains an incompatible change to the g_get_home_dir()
+  function.  Previously, this function would effectively ignore the HOME
+  environment variable and always return the value from /etc/password.
+  As of this version, the HOME variable is used if it is set and the
+  value from /etc/passwd is only used as a fallback.
+
+* The 'flowinfo' and 'scope_id' fields of GInetSocketAddress
+  (introduced in GLib 2.32) have been fixed to be in host byte order
+  rather than network byte order. This is an incompatible change, but
+  the previous behavior was clearly broken, so it seems unlikely that
+  anyone was using it.
+
+### Notes about GLib 2.34
+
+* GIO now looks for thumbnails in XDG_CACHE_HOME, following a
+  recent alignment of the thumbnail spec with the basedir spec.
+
+* The default values for GThreadPools max_unused_threads and
+  max_idle_time settings have been changed to 2 and 15*1000,
+  respectively.
+
+### Notes about GLib 2.32
+
+* It is no longer necessary to use g_thread_init() or to link against
+  libgthread.  libglib is now always thread-enabled. Custom thread
+  system implementations are no longer supported (including errorcheck
+  mutexes).
+
+* The thread and synchronisation APIs have been updated.
+  GMutex and GCond can be statically allocated without explicit
+  initialisation, as can new types GRWLock and GRecMutex.  The
+  GStatic_______ variants of these types have been deprecated.  GPrivate
+  can also be statically allocated and has a nicer API (deprecating
+  GStaticPrivate).  Finally, g_thread_create() has been replaced with a
+  substantially simplified g_thread_new().
+
+* The g_once_init_enter()/_leave() functions have been replaced with
+  macros that allow for a pointer to any gsize-sized object, not just a
+  gsize*.  The assertions to ensure that a pointer to a correctly-sized
+  object is being used will not work with generic pointers (ie: (void*)
+  and (gpointer) casts) which would have worked with the old version.
+
+* It is now mandatory to include glib.h instead of individual headers.
+
+* The -uninstalled variants of the pkg-config files have been dropped.
+
+* For a long time, gobject-2.0.pc mistakenly declared a public
+  dependency on gthread-2.0.pc (when the dependency should have been
+  private).  This means that programs got away with calling
+  g_thread_init() without explicitly listing gthread-2.0.pc among their
+  dependencies.
+
+  gthread has now been removed as a gobject dependency, which will cause
+  such programs to break.
+
+  The fix for this problem is either to declare an explicit dependency
+  on gthread-2.0.pc (if you care about compatibility with older GLib
+  versions) or to stop calling g_thread_init().
+
+* g_debug() output is no longer enabled by default.  It can be enabled
+  on a per-domain basis with the G_MESSAGES_DEBUG environment variable
+  like
+    G_MESSAGES_DEBUG=domain1,domain2
+  or
+    G_MESSAGES_DEBUG=all
+
+### Notes about GLib 2.30
+
+* GObject includes a generic marshaller, g_cclosure_marshal_generic.
+  To use it, simply specify NULL as the marshaller in g_signal_new().
+  The generic marshaller is implemented with libffi, and consequently
+  GObject depends on libffi now.
+
+### Notes about GLib 2.28
+
+* The GApplication API has changed compared to the version that was
+  included in the 2.25 development snapshots. Existing users will need
+  adjustments.
+
+### Notes about GLib 2.26
+
+* Nothing noteworthy.
+
+### Notes about GLib 2.24
+
+* It is now allowed to call g_thread_init(NULL) multiple times, and
+  to call glib functions before g_thread_init(NULL) is called
+  (although the later is mainly a change in docs as this worked before
+  too). See the GThread reference documentation for the details.
+
+* GObject now links to GThread and threads are enabled automatically
+  when g_type_init() is called.
+
+* GObject no longer allows to call g_object_set() on construct-only properties
+  while an object is being initialized. If this behavior is needed, setting a
+  custom constructor that just chains up will re-enable this functionality.
+
+* GMappedFile on an empty file now returns NULL for the contents instead of
+  returning an empty string. The documentation specifically states that code
+  may not rely on nul-termination here so any breakage caused by this change
+  is a bug in application code.
+
+### Notes about GLib 2.22
+
+* Repeated calls to g_simple_async_result_set_op_res_gpointer used
+  to leak the data. This has been fixed to always call the provided
+  destroy notify.
+
+### Notes about GLib 2.20
+
+* The functions for launching applications (e.g. g_app_info_launch() +
+  friends) now passes a FUSE file:// URI if possible (requires gvfs
+  with the FUSE daemon to be running and operational). With gvfs 2.26,
+  FUSE file:// URIs will be mapped back to gio URIs in the GFile
+  constructors. The intent of this change is to better integrate
+  POSIX-only applications, see bug #528670 for the rationale.  The
+  only user-visible change is when an application needs to examine an
+  URI passed to it (e.g. as a positional parameter). Instead of
+  looking at the given URI, the application will now need to look at
+  the result of g_file_get_uri() after having constructed a GFile
+  object with the given URI.
+
+### Notes about GLib 2.18
+
+* The recommended way of using GLib has always been to only include the
+  toplevel headers glib.h, glib-object.h and gio.h. GLib enforces this by
+  generating an error when individual headers are directly included.
+  To help with the transition, the enforcement is not turned on by
+  default for GLib headers (it is turned on for GObject and GIO).
+  To turn it on, define the preprocessor symbol G_DISABLE_SINGLE_INCLUDES.
+
+### Notes about GLib 2.16
+
+* GLib now includes GIO, which adds optional dependencies against libattr
+  and libselinux for extended attribute and SELinux support. Use
+  --disable-xattr and --disable-selinux to build without these.
+
+### Notes about GLib 2.10
+
+* The functions g_snprintf() and g_vsnprintf() have been removed from
+  the gprintf.h header, since they are already declared in glib.h. This
+  doesn't break documented use of gprintf.h, but people have been known
+  to include gprintf.h without including glib.h.
+
+* The Unicode support has been updated to Unicode 4.1. This adds several
+  new members to the GUnicodeBreakType enumeration.
+
+* The support for Solaris threads has been retired. Solaris has provided
+  POSIX threads for long enough now to have them available on every
+  Solaris platform.
+
+* 'make check' has been changed to validate translations by calling
+  msgfmt with the -c option. As a result, it may fail on systems with
+  older gettext implementations (GNU gettext < 0.14.1, or Solaris gettext).
+  'make check' will also fail on systems where the C compiler does not
+  support ELF visibility attributes.
+
+* The GMemChunk API has been deprecated in favour of a new 'slice
+  allocator'. See the g_slice documentation for more details.
+
+* A new type, GInitiallyUnowned, has been introduced, which is
+  intended to serve as a common implementation of the 'floating reference'
+  concept that is e.g. used by GtkObject. Note that changing the
+  inheritance hierarchy of a type can cause problems for language
+  bindings and other code which needs to work closely with the type
+  system. Therefore, switching to GInitiallyUnowned should be done
+  carefully. g_object_compat_control() has been added to GLib 2.8.5
+  to help with the transition.
+
+### Notes about GLib 2.6.0
+
+* GLib 2.6 introduces the concept of 'GLib filename encoding', which is the
+  on-disk encoding on Unix, but UTF-8 on Windows. All GLib functions
+  returning or accepting pathnames have been changed to expect
+  filenames in this encoding, and the common POSIX functions dealing
+  with pathnames have been wrapped. These wrappers are declared in the
+  header <glib/gstdio.h> which must be included explicitly; it is not
+  included through <glib.h>.
+
+  On current (NT-based) Windows versions, where the on-disk file names
+  are Unicode, these wrappers use the wide-character API in the C
+  library. Thus applications can handle file names containing any
+  Unicode characters through GLib's own API and its POSIX wrappers,
+  not just file names restricted to characters in the system codepage.
+
+  To keep binary compatibility with applications compiled against
+  older versions of GLib, the Windows DLL still provides entry points
+  with the old semantics using the old names, and applications
+  compiled against GLib 2.6 will actually use new names for the
+  functions. This is transparent to the programmer.
+
+  When compiling against GLib 2.6, applications intended to be
+  portable to Windows must take the UTF-8 file name encoding into
+  consideration, and use the gstdio wrappers to access files whose
+  names have been constructed from strings returned from GLib.
+
+* Likewise, g_get_user_name() and g_get_real_name() have been changed
+  to return UTF-8 on Windows, while keeping the old semantics for
+  applications compiled against older versions of GLib.
+
+* The GLib uses an '_' prefix to indicate private symbols that
+  must not be used by applications. On some platforms, symbols beginning
+  with prefixes such as _g will be exported from the library, on others not.
+  In no case can applications use these private symbols. In addition to that,
+  GLib+ 2.6 makes several symbols private which were not in any installed
+  header files and were never intended to be exported.
+
+* To reduce code size and improve efficiency, GLib, when compiled
+  with the GNU toolchain, has separate internal and external entry
+  points for exported functions. The internal names, which begin with
+  IA__, may be seen when debugging a GLib program.
+
+* On Windows, GLib no longer opens a console window when printing
+  warning messages if stdout or stderr are invalid, as they are in
+  "Windows subsystem" (GUI) applications. Simply redirect stdout or
+  stderr if you need to see them.
+
+* The child watch functionality tends to reveal a bug in many
+  thread implementations (in particular the older LinuxThreads
+  implementation on Linux) where it's not possible to call waitpid()
+  for a child created in a different thread. For this reason, for
+  maximum portability, you should structure your code to fork all
+  child processes that you want to wait for from the main thread.
+
+* A problem was recently discovered with g_signal_connect_object();
+  it doesn't actually disconnect the signal handler once the object being
+  connected to dies, just disables it. See the API docs for the function
+  for further details and the correct workaround that will continue to
+  work with future versions of GLib.
diff --git a/README.rationale b/README.rationale
new file mode 100644
index 0000000..85a3dfd
--- /dev/null
+++ b/README.rationale
@@ -0,0 +1,10 @@
+This file documents various major decisions which affect GLib development,
+giving a brief rationale of each decision, plus a link to further discussion.
+
+
+ * Compiler attributes: https://bugzilla.gnome.org/show_bug.cgi?id=113075#c46
+
+   GLib uses GIR annotations instead of compiler attributes. They are tidier,
+   already supported by GLib and GNOME tools, and accomplish the same task as
+   compiler attributes. GLib does not provide macros for attributes like
+   nonnull because it would not use them.
diff --git a/README.win32 b/README.win32
new file mode 100644
index 0000000..2a31029
--- /dev/null
+++ b/README.win32
@@ -0,0 +1 @@
+See README.win32.md
diff --git a/README.win32.md b/README.win32.md
new file mode 100644
index 0000000..2925d3d
--- /dev/null
+++ b/README.win32.md
@@ -0,0 +1,182 @@
+Chun-wei Fan `<fanc999@yahoo.com.tw>`
+Philip Withnall `<withnall@endlessm.com>`
+Nirbheek Chauhan `<nirbheek@centricular.com>`
+
+This document was last updated in 2019. You're reading this in the future, and
+lots of information might be misleading or outdated in your age. You have been
+warned.
+
+# General
+
+For prebuilt binaries (DLLs and EXEs) and developer packages (headers,
+import libraries) of GLib, Pango, GTK+ etc for Windows, go to
+https://www.gtk.org/download/windows.php . They are for "native"
+Windows meaning they use the Win32 API and Microsoft C runtime library
+only. No POSIX (Unix) emulation layer like Cygwin is involved.
+
+To build GLib on Win32, you can use either GCC ("MinGW") or the Microsoft
+Visual Studio toolchain. For the latter, Visual Studio 2015 and later are
+recommended. For older Visual Studio versions, see below.
+
+You can also cross-compile GLib for Windows from Linux using the
+cross-compiling mingw packages for your distro.
+
+Note that to just *use* GLib on Windows, there is no need to build it
+yourself.
+
+On Windows setting up a correct build environment is very similar to typing
+`meson; ninja` like on Linux.
+
+The following preprocessor macros are to be used for conditional
+compilation related to Win32 in GLib-using code:
+
+- `G_OS_WIN32` is defined when compiling for native Win32, without
+  any POSIX emulation, other than to the extent provided by the
+  bundled Microsoft C library.
+
+- `G_WITH_CYGWIN` is defined if compiling for the Cygwin
+  environment. Note that `G_OS_WIN32` is *not* defined in that case, as
+  Cygwin is supposed to behave like Unix. `G_OS_UNIX` *is* defined by a GLib
+  for Cygwin.
+
+- `G_PLATFORM_WIN32` is defined when either `G_OS_WIN32` or `G_WITH_CYGWIN`
+  is defined.
+
+These macros are defined in `glibconfig.h`, and are thus available in
+all source files that include `<glib.h>`.
+
+Additionally, there are the compiler-specific macros:
+- `__GNUC__` is defined when using GCC or Clang
+- `__clang__` is defined when using Clang or Clang-CL
+- `_MSC_VER` is defined when using MSVC or Clang-CL
+
+`G_OS_WIN32` implies using the Microsoft C runtime, which used to be
+`msvcrt.dll` and is now the [Universal CRT](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2015)
+when building with Visual Studio. When using the MinGW-GCC toolchain, the CRT
+in use depends on the settings used while the toolchain was built. We highly
+recommend [using the Universal CRT when building with
+MinGW](https://mingwpy.github.io/ucrt.html) too.
+
+GLib is not actively tested with the static versions of the UCRT, but if you
+need to use those, patches are welcome.
+
+# Building software that use GLib or GTK+
+
+Building software that just *uses* GLib or GTK+ also require to have
+the right compiler set up the right way. If you intend to use MinGW-GCC,
+follow the relevant instructions below in that case, too.
+
+You should link to GLib using the `-mms-bitfields` GCC flag. This flag means
+that the struct layout rules are identical to those used by MSVC. This is
+essential if the same DLLs are to be usable both from gcc- and MSVC-compiled
+code.
+
+## Cross-CRT issues
+
+You should take care that the DLLs that your code links to are using the same
+C runtime library. Not doing so can and likely will lead to panics and crashes
+**unless** you're very careful while passing objects allocated by a library
+linked with one CRT to a library linked to another CRT, or (more commonly) not
+doing that at all.
+
+If you *do* pass CRT objects across CRT boundaries, do not file any issues
+about whatever happens next.
+
+To give an example, opening a `FILE` handle created by one CRT cannot be
+understood by any other CRT, and will lead to an access violation. You also
+cannot allocate memory in one CRT and free it using another.
+
+There are [many other cases where you must not allow objects to cross CRT boundaries](https://docs.microsoft.com/en-us/cpp/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries?view=vs-2019),
+but in theory if you're **very very** careful, you can make things work. Again,
+please do not come to us for help if you choose to do this.
+
+# Building GLib
+
+You can build GLib with MinGW-GCC, MSVC, or (experimentally) with Clang-CL.
+
+For all compilers, you will need the following:
+
+- Install Python 3.6.x or newer, either 32-bit or 64-bit. We recommend enabling
+  the option to add it to your `PATH`.
+- [Install Meson](https://mesonbuild.com/Getting-meson.html)
+- Install the [Ninja build tool](https://github.com/ninja-build/ninja/releases), which can also be
+  installed with `pip3`. You can skip this step if you want to generate Visual
+  Studio project files.
+- [git for Windows](https://gitforwindows.org/) is required, since Meson makes
+  use of git to download dependencies using subprojects.
+
+## Building with MinGW-GCC
+
+Open your MSYS or [MSYS2](https://www.msys2.org/) shell where you have the
+MinGW-GCC toolchain installed, and build GLib [like any other Meson
+project](https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project).
+
+## Building with Visual Studio 2015 or newer
+
+Meson is now the only supported method of building GLib using Visual Studio.
+
+To do a build using Meson, do the following:
+
+- Open a Visual Studio (or SDK) command prompt that matches the Visual Studio
+  version and build platform (Win32/x86, x64, etc.) that will be used in all
+  the following steps.
+
+- Create an empty directory/folder for the build inside your GLib sources
+  directory, say, `_builddir`, and `cd` into it.
+
+- Set up the build using Meson:
+
+```cmd
+> meson .. --buildtype=<release|debug|debugoptimized> --prefix=<path> [--backend=vs]
+```
+
+ Please see [the Meson docs](https://mesonbuild.com/Builtin-options.html#core-options)
+ for an explanation for `--buildtype`.
+
+ The path passed for `--prefix` need not to be on the same drive as where the
+ build is carried out, but it is recommended to use forward slashes for this
+ path.  The `--backend=vs` option can be used if the Visual Studio project
+ generator is preferred over using Ninja.
+
+- Build, test and install the build:
+  Run `ninja` to build, `meson test` to test and `meson install` to install the
+  build. If you used `--backend=vs`, instead of running `ninja`, you need to
+  use `msbuild` or you can open the generated solution in Visual Studio.
+
+## Building with old versions of Visual Studio
+
+The steps are the same as above, with the following notes about issues that you might face.
+
+### C4819 build errors
+
+If you are building GLib-based libraries or applications, or GLib itself
+and you see a `C4819` error (or warning, before `C4819` is treated as an error
+in `msvc_recommended_pragmas.h`), please be advised that this error/warning should
+not be disregarded, as this likely means portions of the build are not being
+done correctly, as this is an issue of Visual Studio running on CJK (East Asian)
+locales.  This is an issue that also affects builds of other projects, such as
+QT, Firefox, LibreOffice/OpenOffice, Pango and GTK, along with many other projects.
+
+To overcome this problem, please set your system's locale setting for non-Unicode to
+English (United States), reboot, and restart the build, and the code should build
+normally.
+
+### Visual Studio 2008 hacks
+
+- You need to run the following lines from your build directory, to embed the
+  manifests that are generated during the build, assuming the built binaries
+  are installed to `$(PREFIX)`, after a successful build/installation:
+
+```cmd
+> for /r %f in (*.dll.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f $(PREFIX)\bin\%~nf;2
+> for /r %f in (*.exe.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f $(PREFIX)\bin\%~nf;1
+```
+
+
+- If building for amd64/x86_64/x64, sometimes the compilation of sources may seem to hang, which
+  is caused by an optimization issue in the 2008 x64 compiler.  You need to use Task Manager to
+  remove all running instances of `cl.exe`, which will cause the build process to terminate.  Update
+  the build flags of the sources that hang on compilation by changing its `"/O2"` flag to `"/O1"`
+  in `build.ninja`, and retry the build, where things should continue to build normally.  At the
+  time of writing, this is needed for compiling `glib/gtestutils.c`, `gio/gsettings.c`,
+  `gio/gsettingsschema.c` and `gio/tests/gsubprocess-testprog.c`
diff --git a/check-abis.sh b/check-abis.sh
new file mode 100755
index 0000000..a18103b
--- /dev/null
+++ b/check-abis.sh
@@ -0,0 +1,23 @@
+#!/bin/sh -e
+
+list_leaked_symbols () {
+	nm -D "$1" | grep ' T ' | cut -f 3 -d ' ' | egrep -v "$2"
+}
+
+check_symbols () {
+	if [ "`list_leaked_symbols "$1" "$2" | wc -l`" -ne 0 ]; then
+		echo File "$1" possibly leaking symbols:
+		list_leaked_symbols "$1" "$2"
+		exit 1
+	fi
+}
+
+allowed="^_init$|^_fini$|^_ftext$|^g_"
+allowed_in_libglib="${allowed}|^glib__private__$|^glib_gettext$|^glib_pgettext$|^glib_check_version$"
+allowed_in_libgthread='^_init$|^_fini$|^_ftext$|^g_thread_init$|^g_thread_init_with_errorcheck_mutexes$'
+
+check_symbols glib/.libs/libglib-2.0.so "$allowed_in_libglib"
+check_symbols gthread/.libs/libgthread-2.0.so "$allowed_in_libgthread"
+for file in gmodule/.libs/libgmodule-2.0.so gobject/.libs/libgobject-2.0.so gio/.libs/libgio-2.0.so; do
+	check_symbols "$file" "$allowed"
+done
diff --git a/clang-format-diff.py b/clang-format-diff.py
new file mode 100755
index 0000000..3fb776c
--- /dev/null
+++ b/clang-format-diff.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+#
+# === clang-format-diff.py - ClangFormat Diff Reformatter ---*- python -*-=== #
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===---------------------------------------------------------------------=== #
+
+"""
+This script reads input from a unified diff and reformats all the changed
+lines. This is useful to reformat all the lines touched by a specific patch.
+Example usage for git/svn users:
+
+  git diff -U0 --no-color HEAD^ | clang-format-diff.py -p1 -i
+  svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
+
+"""
+from __future__ import absolute_import, division, print_function
+
+import argparse
+import difflib
+import re
+import subprocess
+import sys
+
+if sys.version_info.major >= 3:
+    from io import StringIO
+else:
+    from io import BytesIO as StringIO
+
+
+def main():
+    parser = argparse.ArgumentParser(
+        description=__doc__,
+        formatter_class=argparse.RawDescriptionHelpFormatter)
+    parser.add_argument('-i', action='store_true', default=False,
+                        help='apply edits to files instead of displaying a '
+                             'diff')
+    parser.add_argument('-p', metavar='NUM', default=0,
+                        help='strip the smallest prefix containing P slashes')
+    parser.add_argument('-regex', metavar='PATTERN', default=None,
+                        help='custom pattern selecting file paths to reformat '
+                        '(case sensitive, overrides -iregex)')
+    parser.add_argument('-iregex', metavar='PATTERN',
+                        default=r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc'
+                                r'|js|ts|proto|protodevel|java|cs)',
+                        help='custom pattern selecting file paths to reformat '
+                             '(case insensitive, overridden by -regex)')
+    parser.add_argument('-sort-includes', action='store_true', default=False,
+                        help='let clang-format sort include blocks')
+    parser.add_argument('-v', '--verbose', action='store_true',
+                        help='be more verbose, ineffective without -i')
+    parser.add_argument('-style',
+                        help='formatting style to apply (LLVM, Google, '
+                        'Chromium, Mozilla, WebKit)')
+    parser.add_argument('-binary', default='clang-format',
+                        help='location of binary to use for clang-format')
+    args = parser.parse_args()
+
+    # Extract changed lines for each file.
+    filename = None
+    lines_by_file = {}
+    for line in sys.stdin:
+        match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
+        if match:
+            filename = match.group(2)
+        if filename is None:
+            continue
+
+        if args.regex is not None:
+            if not re.match('^%s$' % args.regex, filename):
+                continue
+        else:
+            if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
+                continue
+
+        match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
+        if match:
+            start_line = int(match.group(1))
+            line_count = 1
+            if match.group(3):
+                line_count = int(match.group(3))
+            if line_count == 0:
+                continue
+            end_line = start_line + line_count - 1
+            lines_by_file.setdefault(filename, []).extend(
+                ['-lines', str(start_line) + ':' + str(end_line)])
+
+    # Reformat files containing changes in place.
+    # We need to count amount of bytes generated in the output of
+    # clang-format-diff. If clang-format-diff doesn't generate any bytes it
+    # means there is nothing to format.
+    format_line_counter = 0
+    for filename, lines in lines_by_file.items():
+        if args.i and args.verbose:
+            print('Formatting {}'.format(filename))
+        command = [args.binary, filename]
+        if args.i:
+            command.append('-i')
+        if args.sort_includes:
+            command.append('-sort-includes')
+        command.extend(lines)
+        if args.style:
+            command.extend(['-style', args.style])
+        p = subprocess.Popen(command,
+                             stdout=subprocess.PIPE,
+                             stderr=None,
+                             stdin=subprocess.PIPE,
+                             universal_newlines=True)
+        stdout, _ = p.communicate()
+        if p.returncode != 0:
+            sys.exit(p.returncode)
+
+        if not args.i:
+            with open(filename) as f:
+                code = f.readlines()
+            formatted_code = StringIO(stdout).readlines()
+            diff = difflib.unified_diff(code, formatted_code,
+                                        filename, filename,
+                                        '(before formatting)',
+                                        '(after formatting)')
+            diff_string = ''.join(diff)
+            if diff_string:
+                format_line_counter += sys.stdout.write(diff_string)
+
+    if format_line_counter > 0:
+        sys.exit(1)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS
new file mode 100644
index 0000000..e1d6efe
--- /dev/null
+++ b/docs/CODEOWNERS
@@ -0,0 +1,83 @@
+# These are the people responsible for subsystems in GLib; if you're opening
+# a merge request for files listed here, please add the following people to
+# the list of reviewers
+
+# The syntax of this file is defined by GitLab:
+#   https://docs.gitlab.com/ee/user/project/code_owners.html
+# Which, in turn, is similar to the .gitignore and .gitattributes files:
+#
+#  - comments start with `#`
+#  - the first column contains paths and globs
+#  - the second column contains GitLab user names or email addresses,
+#    separated by spaces
+#
+# The last matching glob (rather than the union of *all* matching globs) gives
+# the owners of a piece of code.
+#
+# If you want to be responsible for code reviews in specific sections of
+# the GLib code base, add yourself here.
+
+# Overall maintainers
+*	@pwithnall @ebassi
+
+# Build system
+meson.build		@xclaesse @nirbheek @pwithnall
+meson_options.txt	@xclaesse @nirbheek @pwithnall
+subprojects/		@xclaesse @nirbheek @pwithnall
+
+# CI integration
+.gitlab-ci*	@pwithnall @xclaesse @creiter
+
+# macOS support
+*osx*	@jralls @pwithnall @sdroege
+*.m	@jralls @pwithnall @sdroege
+
+# Windows support
+*win32*	@lrn @creiter @fanc999 @pwithnall @sdroege @nirbheek
+
+# Windows support (MSVC-specific)
+*msvc*	@fanc999 @creiter @pwithnall @sdroege @nirbheek
+
+# Windows support (UWP-specific)
+*uwp*   @nirbheek
+
+# Android support
+*android*	@xclaesse @pwithnall @sdroege
+
+# BSD support
+*bsd*		@jmatthew @ajacoutot @lantw @pwithnall
+*kqueue*	@jmatthew @ajacoutot @lantw @pwithnall
+
+# flatpak portals
+gio/*portal*	@matthiasc @alexl @pwithnall
+
+# Networking
+gio/g*{tcp,udp,tls,socket,resolver,proxy,network,inet,datagram}*	@mcatanzaro @pgriffis @pwithnall @sdroege
+
+# D-Bus
+gio/g*bus*	@smcv @pwithnall
+
+# I/O
+gio/g*{file,vfs,mount,drive,volume}*	@oholy @alexl @pwithnall @sdroege
+gio/g*stream*				@alexl @pwithnall @sdroege
+gio/gio-tool*				@oholy @alexl @pwithnall
+
+# Generic bits of GLib
+glib/	@ebassi @pwithnall @sdroege
+
+# GObject type system
+gobject/	@ebassi @pwithnall @sdroege
+
+# GVariant
+glib/gvariant*	@pwithnall @sdroege
+
+# grefcount, GRcBox and GRefString
+glib/gref{count,string}.[ch]	@ebassi @pwithnall @sdroege
+glib/grc*.[ch]			@ebassi @pwithnall @sdroege
+glib/garc*.[ch]			@ebassi @pwithnall @sdroege
+
+# Logging
+glib/gmessages.[ch]	@pwithnall @sdroege
+
+# Google clusterfuzz support
+fuzzing/	@pwithnall
\ No newline at end of file
diff --git a/docs/debugging.txt b/docs/debugging.txt
new file mode 100644
index 0000000..2cc600a
--- /dev/null
+++ b/docs/debugging.txt
@@ -0,0 +1,38 @@
+
+Traps (G_BREAKPOINT) and traces for the debugging
+=================================================
+
+Some code portions contain trap variables that can be set during
+debugging time if G_ENABLE_DEBUG has been defined upon compilation
+(use the --buildtype=debug option to configure for this, macros.txt
+covers more details).
+Such traps lead to immediate code halts to examine the current
+program state and backtrace.
+Currently, the following trap variables exist:
+
+static volatile gulong g_trap_free_size;
+static volatile gulong g_trap_realloc_size;
+static volatile gulong g_trap_malloc_size;
+	If set to a size > 0, g_free(), g_realloc() and g_malloc()
+	respectively, will be intercepted if the size matches the
+	size of the corresponding memory block to free/reallocate/allocate.
+	This will only work with g_mem_set_vtable (glib_mem_profiler_table)
+	upon startup though, because memory profiling is required to match
+	on the memory block sizes.
+static volatile GObject *g_trap_object_ref;
+	If set to a valid object pointer, ref/unref will be intercepted
+	with G_BREAKPOINT ();
+static volatile gpointer *g_trap_instance_signals;
+static volatile gpointer *g_trace_instance_signals;
+       If set to a valid instance pointer, debugging messages
+       will be spewed about emissions of signals on this instance.
+       For g_trap_instance_signals matches, the emissions will
+       also be intercepted with G_BREAKPOINT ();
+
+Environment variables for debugging
+===================================
+When G_ENABLE_DEBUG was defined upon compilation, the GObject library 
+supports an environment variable GOBJECT_DEBUG that can be set to a
+combination of the flags passed in to g_type_init() (currently
+"objects" and "signals") to trigger debugging messages about
+object bookkeeping and signal emissions during runtime.
\ No newline at end of file
diff --git a/docs/macros.txt b/docs/macros.txt
new file mode 100644
index 0000000..aa326a4
--- /dev/null
+++ b/docs/macros.txt
@@ -0,0 +1,54 @@
+GLib's configure options and corresponding macros
+=================================================
+
+--buildtype={plain,release,minsize,custom}
+	none
+--buildtype={debug,debugoptimized}	[debugoptimized is the default]
+	-DG_ENABLE_DEBUG -g
+-Dglib_asserts=false
+	-DG_DISABLE_ASSERT
+-Dglib_checks=false
+	-DG_DISABLE_CHECKS
+
+Besides these, there are some local feature specific options, but my main
+focus here is to concentrate on macros that affect overall GLib behaviour
+and/or third party code.
+
+
+Notes on GLib's internal and global macros
+==========================================
+
+G_DISABLE_ASSERT
+	The g_assert() and g_assert_not_reached() become non-functional
+	with this define. The motivation is to speed up end-user apps by
+	avoiding expensive checks.
+	This macro can affect third-party code. Defining it when building GLib
+	will only disable the assertion macros for GLib itself, but third-party code
+	that passes -DG_DISABLE_ASSERT to the compiler upon its own build
+	will end up with the non-functional variants after including glib.h
+	as well.
+	NOTE: Code inside the assertion macros should not have side effects
+	that affect the operation of the program.
+G_DISABLE_CHECKS
+	This macro is similar to G_DISABLE_ASSERT, it affects third-party
+	code as mentioned above and the NOTE about G_DISABLE_ASSERT applies
+	too. The macros that become non-functional here are
+	g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached() and
+	g_return_val_if_reached().
+	Additionally the glib_mem_profiler_table and g_mem_profile() from
+	gmem.h become non-functional if this macro is supplied.
+	This macro also switches off certain checks in the GSignal code.
+G_ENABLE_DEBUG
+	Quite a bit of additional debugging code is compiled into GLib for this
+	macro, and since it is a globally visible define, third-party code may
+	be affected by it similar to G_DISABLE_ASSERT.
+	The additional code executed/compiled for this macro currently involve:
+	- extra validity checks for GDate
+	- memory profiling traps in gmem.c (consult debugging.txt for details)
+	- BREAKPOINT abortion for fatal log levels in gmessage.c instead of
+	  plain abort() to allow debuggers trapping and overriding them
+	- added verbosity of gscanner.c to catch deprecated code paths
+	- added verbosity of gutils.c to catch deprecated code paths
+	- object ref/unref traps (consult debugging.txt) and object bookkeeping
+	  in gobject.c
+	- extra validity checks in gsignal.c
\ No newline at end of file
diff --git a/docs/reference/.gitignore b/docs/reference/.gitignore
new file mode 100644
index 0000000..f9e370e
--- /dev/null
+++ b/docs/reference/.gitignore
@@ -0,0 +1,16 @@
+*-decl-list.txt
+*-decl.txt
+*-unused.txt
+*-undocumented.txt
+*-undeclared.txt
+*.args
+*.hierarchy
+*.interfaces
+*.prerequisites
+*.signals
+*.stamp
+html
+xml
+*.bak
+version.xml
+*.1
diff --git a/docs/reference/AUTHORS b/docs/reference/AUTHORS
new file mode 100644
index 0000000..64f46b7
--- /dev/null
+++ b/docs/reference/AUTHORS
@@ -0,0 +1,7 @@
+Damon Chaplin <damon@karuna.freeserve.co.uk> and others.
+
+See:
+
+ http://www.gtk.org/rdp/status.html
+
+for a complete list.
diff --git a/docs/reference/COPYING b/docs/reference/COPYING
new file mode 100644
index 0000000..df952d3
--- /dev/null
+++ b/docs/reference/COPYING
@@ -0,0 +1,30 @@
+This work may be reproduced and distributed in whole or in part, in
+any medium, physical or electronic, so as long as this copyright
+notice remains intact and unchanged on all copies.  Commercial
+redistribution is permitted and encouraged, but you may not
+redistribute, in whole or in part, under terms more restrictive than
+those under which you received it. If you redistribute a modified or
+translated version of this work, you must also make the source code to
+the modified or translated version available in electronic form
+without charge.  However, mere aggregation as part of a larger work
+shall not count as a modification for this purpose.
+
+All code examples in this work are placed into the public domain,
+and may be used, modified and redistributed without restriction.
+
+BECAUSE THIS WORK IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE WORK, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE WORK "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  SHOULD THE WORK PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY REPAIR OR CORRECTION.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE WORK AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+WORK, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/docs/reference/NEWS b/docs/reference/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/reference/NEWS
diff --git a/docs/reference/gio/.gitignore b/docs/reference/gio/.gitignore
new file mode 100644
index 0000000..e9e522e
--- /dev/null
+++ b/docs/reference/gio/.gitignore
@@ -0,0 +1,3 @@
+*.1
+gio-overrides.txt
+tmpl
diff --git a/docs/reference/gio/concat-files-helper.py b/docs/reference/gio/concat-files-helper.py
new file mode 100644
index 0000000..94d64c3
--- /dev/null
+++ b/docs/reference/gio/concat-files-helper.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2018 Collabora Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author: Xavier Claessens <xavier.claessens@collabora.com>
+
+import sys
+
+if len(sys.argv) < 3:
+  print('Usage: {} <output file> <input file 1> ...'.format(os.path.basename(sys.argv[0])))
+  sys.exit(1)
+
+with open(sys.argv[1], 'w') as outfile:
+    for fname in sys.argv[2:]:
+        with open(fname) as infile:
+            for line in infile:
+                outfile.write(line)
diff --git a/docs/reference/gio/gapplication.xml b/docs/reference/gio/gapplication.xml
new file mode 100644
index 0000000..13e3f23
--- /dev/null
+++ b/docs/reference/gio/gapplication.xml
@@ -0,0 +1,352 @@
+<refentry id="gapplication-tool" lang="en">
+  <refentryinfo>
+    <title>gapplication</title>
+    <productname>GIO</productname>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Ryan</firstname>
+        <surname>Lortie</surname>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>gapplication</refentrytitle>
+    <manvolnum>1</manvolnum>
+    <refmiscinfo class="manual">User Commands</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>gapplication</refname>
+    <refpurpose>D-Bus application launcher</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">help</arg>
+      <arg choice="opt"><replaceable>COMMAND</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">version</arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">list-apps</arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">launch</arg>
+      <arg choice="plain"><replaceable>APPID</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">launch</arg>
+      <arg choice="plain"><replaceable>APPID</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>FILE</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">list-actions</arg>
+      <arg choice="plain"><replaceable>APPID</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gapplication</command>
+      <arg choice="plain">action</arg>
+      <arg choice="plain"><replaceable>APPID</replaceable></arg>
+      <arg choice="plain"><replaceable>ACTION</replaceable></arg>
+      <arg choice="opt"><replaceable>PARAMETER</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      <command>gapplication</command> is a commandline implementation of the client-side of the
+      <interfacename>org.freedesktop.Application</interfacename> interface as specified by the freedesktop.org
+      Desktop Entry Specification.
+    </para>
+
+    <para>
+      <command>gapplication</command> can be used to start applications that have
+      <varname>DBusActivatable</varname> set to <literal>true</literal> in their <filename>.desktop</filename>
+      files and can be used to send messages to already-running instances of other applications.
+    </para>
+
+    <para>
+      It is possible for applications to refer to <command>gapplication</command> in the <varname>Exec</varname>
+      line of their <filename class='extension'>.desktop</filename> file to maintain backwards compatibility
+      with implementations that do not directly support <varname>DBusActivatable</varname>.
+    </para>
+
+    <para>
+      <command>gapplication</command> ships as part of <application>GLib</application>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Commands</title>
+
+    <refsect2>
+      <title>Global commands</title>
+
+      <variablelist>
+        <varlistentry>
+          <term>
+            <command>help</command>
+            <arg choice="opt"><replaceable>COMMAND</replaceable></arg>
+          </term>
+          <listitem>
+            <para>
+              Displays a short synopsis of the available commands or provides detailed help on a specific
+              command.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>
+            <command>version</command>
+          </term>
+          <listitem>
+            <para>
+              Prints the GLib version whence <command>gapplication</command> came.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>
+            <command>list-apps</command>
+          </term>
+          <listitem>
+            <para>
+              Prints a list of all application IDs that are known to support D-Bus activation.  This list is
+              generated by scanning <filename class='extension'>.desktop</filename> files as per the current
+              <envar>XDG_DATA_DIRS</envar>.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>
+            <command>launch</command>
+            <arg choice="plain"><replaceable>APPID</replaceable></arg>
+            <arg choice="opt" rep="repeat"><replaceable>FILE</replaceable></arg>
+          </term>
+          <listitem>
+            <para>
+              Launches an application.
+            </para>
+            <para> 
+              The first parameter is the application ID in the familiar "reverse DNS" style (eg:
+              '<literal>org.gnome.app</literal>') without the <filename class='extension'>.desktop</filename>
+              suffix.
+            </para>
+            <para>
+              Optionally, if additional parameters are given, they are treated as the names of files to open and
+              may be filenames or URIs.  If no files are given then the application is simply activated.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>
+            <command>list-actions</command>
+            <arg choice="plain"><replaceable>APPID</replaceable></arg>
+          </term>
+          <listitem>
+            <para>
+              List the actions declared in the application's <filename class='extension'>.desktop</filename>
+              file.  The parameter is the application ID, as above.
+            </para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>
+            <command>action</command>
+            <arg choice="plain"><replaceable>APPID</replaceable></arg>
+            <arg choice="plain"><replaceable>ACTION</replaceable></arg>
+            <arg choice="opt"><replaceable>PARAMETER</replaceable></arg>
+          </term>
+          <listitem>
+            <para>
+              Invokes the named action (in the same way as would occur when activating an action specified in
+              the <filename class='extension'>.desktop</filename> file).
+            </para>
+            <para>
+              The application ID (as above) is the first parameter.  The action name follows.
+            </para>
+            <para>
+              Optionally, following the action name can be one parameter, in GVariant format, given as a single
+              argument.  Make sure to use sufficient quoting.
+            </para>
+          </listitem>
+        </varlistentry>
+
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <refsect2>
+      <title>From the commandline</title>
+
+      <para>
+        Launching an application:
+      </para>
+
+      <programlisting>
+        gapplication launch org.example.fooview
+      </programlisting>
+
+      <para>
+        Opening a file with an application:
+      </para>
+
+      <programlisting>
+        gapplication launch org.example.fooview ~/file.foo
+      </programlisting>
+
+      <para>
+        Opening many files with an application:
+      </para>
+
+      <programlisting>
+        gapplication launch org.example.fooview ~/foos/*.foo
+      </programlisting>
+
+      <para>
+        Invoking an action on an application:
+      </para>
+
+      <programlisting>
+        gapplication action org.example.fooview create
+      </programlisting>
+
+      <para>
+        Invoking an action on an application, with an action:
+      </para>
+
+      <programlisting>
+        gapplication action org.example.fooview show-item '"item_id_828739"'
+      </programlisting>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        From the <varname>Exec</varname> lines of a <filename class='extension'>.desktop</filename> file
+      </title>
+
+      <para>
+        The commandline interface of <command>gapplication</command> was designed so that it could be used
+        directly from the <varname>Exec</varname> line of a <filename class='extension'>.desktop</filename>
+        file.
+      </para>
+
+      <para>
+        You might want to do this to allow for backwards compatibility with implementations of the specification
+        that do not understand how to do D-Bus activation, without having to install a separate utility program.
+      </para>
+
+      <para>
+        Consider the following example:
+      </para>
+
+      <programlisting>
+        [Desktop Entry]
+        Version=1.1
+        Type=Application
+        Name=Foo Viewer
+        DBusActivatable=true
+        MimeType=image/x-foo;
+        Exec=gapplication launch org.example.fooview %F
+        Actions=gallery;create;
+
+        [Desktop Action gallery]
+        Name=Browse Gallery
+        Exec=gapplication action org.example.fooview gallery
+
+        [Desktop Action create]
+        Name=Create a new Foo!
+        Exec=gapplication action org.example.fooview create
+      </programlisting>
+    </refsect2>
+
+    <refsect2>
+      <title>From a script</title>
+
+      <para>
+        If installing an application that supports D-Bus activation you may still want to put a file in
+        <filename class='directory'>/usr/bin</filename> so that your program can be started from a terminal.
+      </para>
+
+      <para>
+        It is possible for this file to be a shell script.  The script can handle arguments such as --help and
+        --version directly.  It can also parse other command line arguments and convert them to uses of
+        <command>gapplication</command> to activate the application, open files, or invoke actions.
+      </para>
+
+      <para>
+        Here is a simplified example, as may be installed in <filename>/usr/bin/fooview</filename>:
+      </para>
+
+      <programlisting>
+        #!/bin/sh
+
+        case "$1" in
+          --help)
+            echo "see 'man fooview' for more information"
+            ;;
+
+          --version)
+            echo "fooview 1.2"
+            ;;
+
+          --gallery)
+            gapplication action org.example.fooview gallery
+            ;;
+
+          --create)
+            gapplication action org.example.fooview create
+            ;;
+
+          -*)
+            echo "unrecognised commandline argument"
+            exit 1
+            ;;
+
+          *)
+            gapplication launch org.example.fooview "$@"
+            ;;
+        esac
+      </programlisting>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See also</title>
+    <para>
+      <ulink url='http://standards.freedesktop.org/desktop-entry-spec/latest/'>Desktop Entry Specification</ulink>,
+      <citerefentry>
+        <refentrytitle>gdbus</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>xdg-open</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>desktop-file-validate</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml
new file mode 100644
index 0000000..25210c3
--- /dev/null
+++ b/docs/reference/gio/gdbus-codegen.xml
@@ -0,0 +1,1165 @@
+<refentry id="gdbus-codegen" lang="en">
+
+<refentryinfo>
+  <title>gdbus</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>David</firstname>
+      <surname>Zeuthen</surname>
+      <email>zeuthen@gmail.com</email>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>gdbus-codegen</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>gdbus-codegen</refname>
+  <refpurpose>D-Bus code and documentation generator</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>gdbus-codegen</command>
+    <arg><option>-h</option>, <option>--help</option></arg>
+    <arg><option>--interface-prefix</option> <replaceable>org.project.Prefix</replaceable></arg>
+    <arg><option>--generate-c-code</option> <replaceable>OUTFILES</replaceable></arg>
+    <arg><option>--c-namespace</option> <replaceable>YourProject</replaceable></arg>
+    <arg><option>--c-generate-object-manager</option></arg>
+    <arg><option>--c-generate-autocleanup</option> none|objects|all</arg>
+    <arg><option>--output-directory</option> <replaceable>OUTDIR</replaceable></arg>
+    <arg><option>--generate-docbook</option> <replaceable>OUTFILES</replaceable></arg>
+    <arg><option>--pragma-once</option></arg>
+    <arg><option>--xml-files</option> <replaceable>FILE</replaceable></arg>
+    <arg><option>--header</option></arg>
+    <arg><option>--body</option></arg>
+    <arg><option>--interface-info-header</option></arg>
+    <arg><option>--interface-info-body</option></arg>
+    <arg><option>--symbol-decorator</option> <replaceable>DECORATOR</replaceable></arg>
+    <arg><option>--symbol-decorator-header</option> <replaceable>HEADER</replaceable></arg>
+    <arg><option>--symbol-decorator-define</option> <replaceable>DEFINE</replaceable></arg>
+    <arg><option>--output</option> <replaceable>OUTFILE</replaceable></arg>
+    <group choice="plain" rep="repeat">
+      <arg>
+        <option>--annotate</option>
+        <replaceable>ELEMENT</replaceable>
+        <replaceable>KEY</replaceable>
+        <replaceable>VALUE</replaceable>
+      </arg>
+    </group>
+    <arg><option>--glib-min-required</option> <replaceable>VERSION</replaceable></arg>
+    <arg><option>--glib-max-allowed</option> <replaceable>VERSION</replaceable></arg>
+    <arg choice="plain">FILE</arg>
+    <arg>
+      <arg choice="plain" rep="repeat">FILE</arg>
+    </arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+  <title>Description</title>
+  <para>
+    <command>gdbus-codegen</command> is used to generate code and/or
+    documentation for one or more D-Bus interfaces.
+  </para>
+  <para>
+    <command>gdbus-codegen</command> reads
+    <ulink
+    url="http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">D-Bus
+    Introspection XML</ulink> from files passed as additional
+    arguments on the command line and generates output files.
+    It currently supports generating C source code (via
+    <option>--body</option>) or header (via <option>--header</option>)
+    and Docbook XML (via <option>--generate-docbook</option>). Alternatively,
+    more restricted C source code and headers can be generated, which just
+    contain the interface information (as <type>GDBusInterfaceInfo</type>
+    structures) using <option>--interface-info-body</option> and
+    <option>--interface-info-header</option>.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Generating C code</title>
+  <para>
+    When generating C code, a
+    #GInterface<!-- -->-derived type is generated for each D-Bus
+    interface. Additionally, for every generated type,
+    <type>FooBar</type>, two concrete instantiable types,
+    <type>FooBarProxy</type> and <type>FooBarSkeleton</type>, implementing
+    said interface are also generated. The former is derived from
+    #GDBusProxy and intended for use on the client side
+    while the latter is derived from the
+    #GDBusInterfaceSkeleton type making it easy to export on a
+    #GDBusConnection either directly or via a
+    #GDBusObjectManagerServer instance.
+  </para>
+  <para>
+    For C code generation either <option>--body</option> that
+    generates source code, <option>--header</option> that
+    generates headers, <option>--interface-info-body</option> that generates
+    interface information source code, or
+    <option>--interface-info-header</option> that generates interface information
+    headers, can be used. These options must be used along with
+    <option>--output</option>, which is used to specify the file to output to.
+  </para>
+  <para>
+    Both files can be generated at the same time by using
+    <option>--generate-c-code</option>, but this option is deprecated.
+    In this case <option>--output</option> cannot be used due to the
+    generation of multiple files. Instead pass
+    <option>--output-directory</option> to specify the directory to put
+    the output files in. By default the current directory will be used.
+  </para>
+  <para>
+    The name of each generated C type is derived from the D-Bus
+    interface name stripped with the prefix given with
+    <option>--interface-prefix</option> and with the dots removed and
+    initial characters capitalized. For example, for the D-Bus
+    interface <literal>com.acme.Coyote</literal> the name used is
+    <literal>ComAcmeCoyote</literal>. For the D-Bus interface
+    <literal>org.project.Bar.Frobnicator</literal> with
+    <option>--interface-prefix</option>
+    <literal>org.project.</literal>, the name used is
+    <literal>BarFrobnicator</literal>.
+  </para>
+  <para>
+    For methods, signals and properties, if not specified, the name
+    defaults to the name of the method, signal or property.
+  </para>
+  <para>
+    Two forms of the name are used - the CamelCase form and the
+    lower-case form. The CamelCase form is used for the #GType and
+    struct name, while lower-case form is used in function names. The
+    lower-case form is calculated by converting from CamelCase to
+    lower-case and inserting underscores at word boundaries (using
+    certain heuristics).
+  </para>
+  <para>
+    If the value given by the <literal>org.gtk.GDBus.C.Name</literal>
+    annotation or the <option>--c-namespace</option> option contains
+    an underscore (sometimes called <emphasis>Ugly_Case</emphasis>),
+    then the camel-case name is derived by removing all underscores,
+    and the lower-case name is derived by lower-casing the
+    string. This is useful in some situations where abbreviations are
+    used. For example, if the annotation is used on the interface
+    <literal>net.MyCorp.MyApp.iSCSITarget</literal> with the value
+    <literal>iSCSI_Target</literal> the CamelCase form is
+    <literal>iSCSITarget</literal> while the lower-case form is
+    <literal>iscsi_target</literal>. If the annotation is used on the
+    method <literal>EjectTheiPod</literal> with the value
+    <literal>Eject_The_iPod</literal>, the lower-case form is
+    <literal>eject_the_ipod</literal>.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Generating Docbook documentation</title>
+  <para>
+    Each generated Docbook XML file (see the
+    <option>--generate-docbook</option> option for details) is a <ulink
+    url="http://www.docbook.org/tdg/en/html/refentry.html"><literal>RefEntry</literal></ulink>
+    article describing the D-Bus interface.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Options</title>
+  <para>
+    The following options are supported:
+  </para>
+  <variablelist>
+
+    <varlistentry>
+      <term><option>-h</option>, <option>--help</option></term>
+      <listitem>
+        <para>
+          Show help and exit.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--xml-files</option> <replaceable>FILE</replaceable></term>
+      <listitem>
+        <para>
+          This option is deprecated; use positional arguments instead.
+          The D-Bus introspection XML file.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--interface-prefix</option> <replaceable>org.project.Prefix.</replaceable></term>
+      <listitem>
+        <para>
+          A prefix to strip from all D-Bus interface names when
+          calculating the typename for the C binding and the Docbook
+          <ulink
+          url="http://www.docbook.org/tdg/en/html/primary.html">sortas
+          attribute</ulink>.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--generate-docbook</option> <replaceable>OUTFILES</replaceable></term>
+      <listitem>
+        <para>
+          Generate Docbook Documentation for each D-Bus interface and
+          put it in <filename>OUTFILES-NAME.xml</filename> where
+          <literal>NAME</literal> is a place-holder for the interface
+          name, e.g. <literal>net.Corp.FooBar</literal> and so on.
+        </para>
+        <para>
+          Pass <option>--output-directory</option> to specify the directory
+          to put the output files in. By default the current directory
+          will be used.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--generate-c-code</option> <replaceable>OUTFILES</replaceable></term>
+      <listitem>
+        <para>
+          Generate C code for all D-Bus interfaces and put it in
+          <filename>OUTFILES.c</filename> and
+          <filename>OUTFILES.h</filename> including any sub-directories. If you want the files to
+          be output in a different location use <option>--output-directory</option> as <filename>OUTFILES.h</filename>
+          including sub-directories will be referenced from <filename>OUTFILES.c</filename>.
+        </para>
+        <para>
+          The full paths would then be <literal>$(OUTDIR)/$(dirname $OUTFILES)/$(basename $OUTFILES).{c,h}</literal>.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--c-namespace</option> <replaceable>YourProject</replaceable></term>
+      <listitem>
+        <para>
+          The namespace to use for generated C code. This is expected
+          to be in <ulink
+          url="http://en.wikipedia.org/wiki/CamelCase">CamelCase</ulink>
+          or <emphasis>Ugly_Case</emphasis> (see above).
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--pragma-once</option></term>
+      <listitem>
+        <para>
+          If this option is passed, the
+          <ulink url="https://en.wikipedia.org/wiki/Pragma_once">&#35;pragma once</ulink>
+          preprocessor directive is used instead of include guards.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--c-generate-object-manager</option></term>
+      <listitem>
+        <para>
+          If this option is passed, suitable #GDBusObject,
+          #GDBusObjectProxy, #GDBusObjectSkeleton and
+          #GDBusObjectManagerClient subclasses are generated.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--c-generate-autocleanup</option> none|objects|all</term>
+      <listitem>
+        <para>
+          This option influences what types autocleanup functions are
+          generated for. 'none' means to not generate any autocleanup functions.
+          'objects' means to generate them for object types, and 'all' means to
+          generate them for object types and interfaces. The default is 'objects'
+          due to a corner case in backwards compatibility with a few projects,
+          but you should likely switch your project to use 'all'.
+          This option was added in GLib 2.50.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--output-directory</option> <replaceable>OUTDIR</replaceable></term>
+      <listitem>
+        <para>
+          Directory to output generated source to. Equivalent to changing directory before generation.
+        </para>
+        <para>
+          This option cannot be used with <option>--body</option>,
+          <option>--header</option>, <option>--interface-info-body</option> or
+          <option>--interface-info-header</option>; and
+          <option>--output</option> must be used.
+        </para>
+
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--header</option></term>
+      <listitem>
+        <para>
+          If this option is passed, it will generate the header code and write it to the disk by
+          using the path and file name provided by <option>--output</option>.
+        </para>
+        <para>
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
+          <option>--output-directory</option> are not allowed to be used along with
+          <option>--header</option> and <option>--body</option> options, because these options
+          are used to generate only one file.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--body</option></term>
+      <listitem>
+        <para>
+          If this option is passed, it will generate the source code and write it to the disk by
+          using the path and file name provided by <option>--output</option>.
+        </para>
+        <para>
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
+          <option>--output-directory</option> are not allowed to be used along with
+          <option>--header</option> and <option>--body</option> options, because these options
+          are used to generate only one file.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--interface-info-header</option></term>
+      <listitem>
+        <para>
+          If this option is passed, it will generate the header code for the
+          <type>GDBusInterfaceInfo</type> structures only and will write it to
+          the disk by using the path and file name provided by
+          <option>--output</option>.
+        </para>
+        <para>
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
+          <option>--output-directory</option> are not allowed to be used along with
+          the <option>--interface-info-header</option> and
+          <option>--interface-info-body</option> options, because these options
+          are used to generate only one file.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--interface-info-body</option></term>
+      <listitem>
+        <para>
+          If this option is passed, it will generate the source code for the
+          <type>GDBusInterfaceInfo</type> structures only and will write it to
+          the disk by using the path and file name provided by
+          <option>--output</option>.
+        </para>
+        <para>
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
+          <option>--output-directory</option> are not allowed to be used along with
+          the <option>--interface-info-header</option> and
+          <option>--interface-info-body</option> options, because these options
+          are used to generate only one file.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--symbol-decorator</option> <replaceable>DECORATOR</replaceable></term>
+      <listitem>
+        <para>
+          If a <literal>DECORATOR</literal> is passed in with this option, all the
+          generated function prototypes in the generated header will be marked with
+          <literal>DECORATOR</literal>. This can be used, for instance, to export
+          symbols from code generated with <command>gdbus-codegen</command>.
+          This option is added in GLib-2.66
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--symbol-decorator-header</option> <replaceable>HEADER</replaceable></term>
+      <listitem>
+        <para>
+          If a <literal>HEADER</literal> is passed in with this option, the
+          generated header will put a <literal>#include HEADER</literal> before the rest of the
+          items, except for the inclusion guards or <literal>#pragma once</literal>
+          (if <option>--pragma-once</option> is used).  This is used if using another header file is
+          needed for the decorator passed in via <option>--symbol-decorator</option> to be defined.
+          This option is added in GLib-2.66.
+        </para>
+        <para>
+          This option can only be used if <option>--symbol-decorator</option> is used.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--symbol-decorator-define</option> <replaceable>DEFINE</replaceable></term>
+      <listitem>
+        <para>
+          If a <literal>DEFINE</literal> is passed in with this option, the
+          generated source will add a <literal>#define DEFINE</literal> before the rest of the
+          items.  This is used if a particular macro is needed to ensure the decorator
+          passed in via <option>--symbol-decorator</option> uses the correct definition when the
+          generated source is being compiled. This option is added in GLib-2.66.
+        </para>
+        <para>
+          This option can only be used if <option>--symbol-decorator</option> is used.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--output</option> <replaceable>OUTFILE</replaceable></term>
+      <listitem>
+        <para>
+          The full path where the header (<option>--header</option>,
+          <option>--interface-info-header</option>) or the source code
+          (<option>--body</option>, <option>--interface-info-body</option>) will
+          be written, using the path and filename provided by
+          <option>--output</option>. The full path could be something like
+          <literal>$($OUTFILE).{c,h}</literal>.
+        </para>
+        <para>
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
+          <option>--output-directory</option> is not allowed along with
+          <option>--output</option>, because the latter is used to generate only one file.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--annotate</option> <replaceable>ELEMENT</replaceable> <replaceable>KEY</replaceable> <replaceable>VALUE</replaceable></term>
+      <listitem>
+        <para>
+          Used to inject D-Bus annotations into the given XML
+          files. It can be used with interfaces, methods, signals,
+          properties and arguments in the following way:
+        </para>
+<informalexample><programlisting><![CDATA[
+gdbus-codegen --c-namespace MyApp                           \
+  --generate-c-code myapp-generated                         \
+  --annotate "org.project.InterfaceName"                    \
+    org.gtk.GDBus.C.Name MyFrobnicator                      \
+  --annotate "org.project.InterfaceName:Property"           \
+    bar bat                                                 \
+  --annotate "org.project.InterfaceName.Method()"           \
+    org.freedesktop.DBus.Deprecated true                    \
+  --annotate "org.project.InterfaceName.Method()[arg_name]" \
+    snake hiss                                              \
+  --annotate "org.project.InterfaceName::Signal"            \
+    cat meow                                                \
+  --annotate "org.project.InterfaceName::Signal[arg_name]"  \
+    dog wuff                                                \
+  myapp-dbus-interfaces.xml
+]]></programlisting></informalexample>
+        <para>
+          Any UTF-8 string can be used for <replaceable>KEY</replaceable> and <replaceable>VALUE</replaceable>.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--glib-min-required</option> <replaceable>VERSION</replaceable></term>
+      <listitem>
+        <para>
+          Specifies the minimum version of GLib which the code generated by
+          <command>gdbus-codegen</command> can depend on. This may be used to
+          make backwards-incompatible changes in the output or behaviour of
+          <command>gdbus-codegen</command> in future, which users may opt in to
+          by increasing the value they pass for <option>--glib-min-required</option>.
+          If this option is not passed, the output from <command>gdbus-codegen</command>
+          is guaranteed to be compatible with all versions of GLib from 2.30
+          upwards, as that is when <command>gdbus-codegen</command> was first
+          released.
+        </para>
+        <para>
+          Note that some version parameters introduce incompatible changes: all callers
+          of the generated code might need to be updated, and if the generated code is part of
+          a library's API or ABI, then increasing the version parameter can result in an API
+          or ABI break.
+        </para>
+        <para>
+          The version number must be of the form
+          <literal><replaceable>MAJOR</replaceable>.<replaceable>MINOR</replaceable>.<replaceable>MICRO</replaceable></literal>,
+          where all parts are integers. <replaceable>MINOR</replaceable> and
+          <replaceable>MICRO</replaceable> are optional. The version number may not be smaller
+          than <literal>2.30</literal>.
+        </para>
+        <para>
+          If the version number is <literal>2.64</literal> or greater, the generated code will
+          have the following features: (1) If a method has <literal>h</literal> (file
+          descriptor) parameter(s), a <type>GUnixFDList</type> parameter will exist in the
+          generated code for it (whereas previously the annotation
+          <literal>org.gtk.GDBus.C.UnixFD</literal> was required), and (2) Method call functions will
+          have two additional arguments to allow the user to specify <type>GDBusCallFlags</type>
+          and a timeout value, as is possible when using <function>g_dbus_proxy_call()</function>.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><option>--glib-max-allowed</option> <replaceable>VERSION</replaceable></term>
+      <listitem>
+        <para>
+          Specifies the maximum version of GLib which the code generated by
+          <command>gdbus-codegen</command> can depend on. This may be used to
+          ensure that code generated by <command>gdbus-codegen</command> is
+          compilable with specific older versions of GLib that your software has
+          to support.
+        </para>
+        <para>
+          The version number must be of the form
+          <literal><replaceable>MAJOR</replaceable>.<replaceable>MINOR</replaceable>.<replaceable>MICRO</replaceable></literal>,
+          where all parts are integers. <replaceable>MINOR</replaceable> and
+          <replaceable>MICRO</replaceable> are optional. The version number must
+          be greater than or equal to that passed to <option>--glib-min-required</option>.
+          It defaults to the version of GLib which provides this <command>gdbus-codegen</command>.
+        </para>
+      </listitem>
+    </varlistentry>
+
+  </variablelist>
+</refsect1>
+
+<refsect1>
+  <title>Supported D-Bus Annotations</title>
+  <para>
+    The following D-Bus annotations are supported by
+    <command>gdbus-codegen</command>:
+  </para>
+
+  <variablelist>
+
+    <varlistentry>
+      <term><literal>org.freedesktop.DBus.Deprecated</literal></term>
+      <listitem>
+        <para>
+          Can be used on any <literal>&lt;interface&gt;</literal>,
+          <literal>&lt;method&gt;</literal>,
+          <literal>&lt;signal&gt;</literal> and
+          <literal>&lt;property&gt;</literal> element to specify that
+          the element is deprecated if its value is
+          <literal>true</literal>. Note that this annotation is
+          defined in the <ulink
+          url="http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">D-Bus
+          specification</ulink> and can only assume the values
+          <literal>true</literal> and <literal>false</literal>. In
+          particular, you cannot specify the version that the element
+          was deprecated in nor any helpful deprecation message. Such
+          information should be added to the element documentation
+          instead.
+        </para>
+        <para>
+          When generating C code, this annotation is used to add
+          #G_GNUC_DEPRECATED to generated functions for the element.
+        </para>
+        <para>
+          When generating Docbook XML, a deprecation warning will
+          appear along the documentation for the element.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><literal>org.gtk.GDBus.Since</literal></term>
+      <listitem>
+        <para>
+          Can be used on any <literal>&lt;interface&gt;</literal>,
+          <literal>&lt;method&gt;</literal>,
+          <literal>&lt;signal&gt;</literal> and
+          <literal>&lt;property&gt;</literal> element to specify the
+          version (any free-form string but compared using a
+          version-aware sort function) the element appeared in.
+        </para>
+        <para>
+          When generating C code, this field is used to ensure
+          function pointer order for preserving ABI/API, see <xref
+          linkend="gdbus-code-stability"/>.
+        </para>
+        <para>
+          When generating Docbook XML, the value of this tag appears
+          in the documentation.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><literal>org.gtk.GDBus.DocString</literal></term>
+      <listitem>
+        <para>
+          A string with Docbook content for documentation. This annotation can
+          be used on <literal>&lt;interface&gt;</literal>,
+          <literal>&lt;method&gt;</literal>,
+          <literal>&lt;signal&gt;</literal>,
+          <literal>&lt;property&gt;</literal> and
+          <literal>&lt;arg&gt;</literal> elements.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><literal>org.gtk.GDBus.DocString.Short</literal></term>
+      <listitem>
+        <para>
+          A string with Docbook content for short/brief
+          documentation. This annotation can only be used on
+          <literal>&lt;interface&gt;</literal> elements.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><literal>org.gtk.GDBus.C.Name</literal></term>
+      <listitem>
+        <para>
+          Can be used on any <literal>&lt;interface&gt;</literal>,
+          <literal>&lt;method&gt;</literal>,
+          <literal>&lt;signal&gt;</literal> and
+          <literal>&lt;property&gt;</literal> element to specify the
+          name to use when generating C code. The value is expected to
+          be in <ulink
+          url="http://en.wikipedia.org/wiki/CamelCase">CamelCase</ulink>
+          or <emphasis>Ugly_Case</emphasis> (see above).
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><literal>org.gtk.GDBus.C.ForceGVariant</literal></term>
+      <listitem>
+        <para>
+          If set to a non-empty string, a #GVariant instance will
+          be used instead of the natural C type. This annotation can
+          be used on any <literal>&lt;arg&gt;</literal> and
+          <literal>&lt;property&gt;</literal> element.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term><literal>org.gtk.GDBus.C.UnixFD</literal></term>
+      <listitem>
+        <para>
+          If set to a non-empty string, the generated code will
+          include parameters to exchange file descriptors using the
+          #GUnixFDList type. This annotation can be used on
+          <literal>&lt;method&gt;</literal> elements.
+        </para>
+      </listitem>
+    </varlistentry>
+
+  </variablelist>
+
+  <para>
+    As an easier alternative to using the
+    <literal>org.gtk.GDBus.DocString</literal> annotation, note that
+    parser used by <command>gdbus-codegen</command> parses XML
+    comments in a way similar to <ulink
+    url="http://www.gtk.org/gtk-doc/">gtk-doc</ulink>:
+<informalexample><programlisting><![CDATA[
+<!--
+  net.Corp.Bar:
+  @short_description: A short description
+
+  A <emphasis>longer</emphasis> description.
+
+  This is a new paragraph.
+-->
+<interface name="net.corp.Bar">
+  <!--
+    FooMethod:
+    @greeting: The docs for greeting parameter.
+    @response: The docs for response parameter.
+
+    The docs for the actual method.
+  -->
+  <method name="FooMethod">
+    <arg name="greeting" direction="in" type="s"/>
+    <arg name="response" direction="out" type="s"/>
+  </method>
+
+  <!--
+    BarSignal:
+    @blah: The docs for blah parameter.
+    @boo: The docs for boo parameter.
+    @since: 2.30
+
+    The docs for the actual signal.
+  -->
+  <signal name="BarSignal">
+    <arg name="blah" type="s"/>
+    <arg name="boo" type="s"/>
+  </signal>
+
+  <!-- BazProperty: The docs for the property. -->
+  <property name="BazProperty" type="s" access="read"/>
+</interface>
+]]></programlisting></informalexample>
+  </para>
+  <para>
+    Note that <literal><![CDATA[@since]]></literal> can be used in any inline
+    documentation bit (e.g. for interfaces, methods, signals and
+    properties) to set the <literal>org.gtk.GDBus.Since</literal>
+    annotation. For the <literal>org.gtk.GDBus.DocString</literal>
+    annotation (and inline comments), note that substrings of the form
+    <literal><![CDATA[#net.Corp.Bar]]></literal>,
+    <literal><![CDATA[net.Corp.Bar.FooMethod()]]></literal>,
+    <literal><![CDATA[#net.Corp.Bar::BarSignal]]></literal> and
+    <literal><![CDATA[#net.Corp.InlineDocs:BazProperty]]></literal> are all
+    expanded to links to the respective interface, method, signal and
+    property.
+    Additionally, substrings starting with <literal>@</literal> and <literal>%</literal> characters are rendered as
+    <ulink url="http://www.docbook.org/tdg/en/html/parameter.html">parameter</ulink> and
+    <ulink url="http://www.docbook.org/tdg/en/html/constant.html">constant</ulink> respectively.
+  </para>
+  <para>
+    If both XML comments and
+    <literal>org.gtk.GDBus.DocString</literal> or
+    <literal>org.gtk.GDBus.DocString.Short</literal> annotations are
+    present, the latter wins.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Example</title>
+  <para>
+    Consider the following D-Bus Introspection XML.
+  </para>
+  <informalexample><programlisting><![CDATA[
+<node>
+  <interface name="net.Corp.MyApp.Frobber">
+    <method name="HelloWorld">
+      <arg name="greeting" direction="in" type="s"/>
+      <arg name="response" direction="out" type="s"/>
+    </method>
+
+    <signal name="Notification">
+      <arg name="icon_blob" type="ay"/>
+      <arg name="height" type="i"/>
+      <arg name="messages" type="as"/>
+    </signal>
+
+    <property name="Verbose" type="b" access="readwrite"/>
+  </interface>
+</node>
+]]></programlisting>
+  </informalexample>
+  <para>
+    If <command>gdbus-codegen</command> is used on this file like this:
+  </para>
+<informalexample><programlisting><![CDATA[
+gdbus-codegen --generate-c-code myapp-generated       \
+              --c-namespace MyApp                     \
+              --interface-prefix net.corp.MyApp.      \
+              net.Corp.MyApp.Frobber.xml
+]]></programlisting></informalexample>
+  <para>
+    two files called
+    <filename>myapp-generated.[ch]</filename> are
+    generated. The files provide an abstract
+    #GTypeInterface<!-- -->-derived type called
+    <type>MyAppFrobber</type> as well as two instantiable types with
+    the same name but suffixed with <type>Proxy</type> and
+    <type>Skeleton</type>. The generated file, roughly, contains the
+    following facilities:
+  </para>
+<informalexample><programlisting><![CDATA[
+/* GType macros for the three generated types */
+#define MY_APP_TYPE_FROBBER (my_app_frobber_get_type ())
+#define MY_APP_TYPE_FROBBER_SKELETON (my_app_frobber_skeleton_get_type ())
+#define MY_APP_TYPE_FROBBER_PROXY (my_app_frobber_proxy_get_type ())
+
+typedef struct _MyAppFrobber MyAppFrobber; /* Dummy typedef */
+
+typedef struct
+{
+  GTypeInterface parent_iface;
+
+  /* Signal handler for the ::notification signal */
+  void (*notification) (MyAppFrobber *proxy,
+                        GVariant *icon_blob,
+                        gint height,
+                        const gchar* const *messages);
+
+  /* Signal handler for the ::handle-hello-world signal */
+  gboolean (*handle_hello_world) (MyAppFrobber *proxy,
+                                  GDBusMethodInvocation *invocation,
+                                  const gchar *greeting);
+} MyAppFrobberIface;
+
+/* Asynchronously calls HelloWorld() */
+void
+my_app_frobber_call_hello_world (MyAppFrobber *proxy,
+                                 const gchar *greeting,
+                                 GCancellable *cancellable,
+                                 GAsyncReadyCallback callback,
+                                 gpointer user_data);
+gboolean
+my_app_frobber_call_hello_world_finish (MyAppFrobber *proxy,
+                                        gchar **out_response,
+                                        GAsyncResult *res,
+                                        GError **error);
+
+/* Synchronously calls HelloWorld(). Blocks calling thread. */
+gboolean
+my_app_frobber_call_hello_world_sync (MyAppFrobber *proxy,
+                                      const gchar *greeting,
+                                      gchar **out_response,
+                                      GCancellable *cancellable,
+                                      GError **error);
+
+/* Completes handling the HelloWorld() method call */
+void
+my_app_frobber_complete_hello_world (MyAppFrobber *object,
+                                     GDBusMethodInvocation *invocation,
+                                     const gchar *response);
+
+/* Emits the ::notification signal / Notification() D-Bus signal */
+void
+my_app_frobber_emit_notification (MyAppFrobber *object,
+                                  GVariant *icon_blob,
+                                  gint height,
+                                  const gchar* const *messages);
+
+/* Gets the :verbose GObject property / Verbose D-Bus property.
+ * Does no blocking I/O.
+ */
+gboolean my_app_frobber_get_verbose (MyAppFrobber *object);
+
+/* Sets the :verbose GObject property / Verbose D-Bus property.
+ * Does no blocking I/O.
+ */
+void my_app_frobber_set_verbose (MyAppFrobber *object,
+                                 gboolean      value);
+
+/* Gets the interface info */
+GDBusInterfaceInfo *my_app_frobber_interface_info (void);
+
+/* Creates a new skeleton object, ready to be exported */
+MyAppFrobber *my_app_frobber_skeleton_new (void);
+
+/* Client-side proxy constructors.
+ *
+ * Additionally, _new_for_bus(), _new_for_bus_finish() and
+ * _new_for_bus_sync() proxy constructors are also generated.
+ */
+void
+my_app_frobber_proxy_new        (GDBusConnection     *connection,
+                                 GDBusProxyFlags      flags,
+                                 const gchar         *name,
+                                 const gchar         *object_path,
+                                 GCancellable        *cancellable,
+                                 GAsyncReadyCallback  callback,
+                                 gpointer             user_data);
+MyAppFrobber *
+my_app_frobber_proxy_new_finish (GAsyncResult        *res,
+                                 GError             **error);
+MyAppFrobber *
+my_app_frobber_proxy_new_sync   (GDBusConnection     *connection,
+                                 GDBusProxyFlags      flags,
+                                 const gchar         *name,
+                                 const gchar         *object_path,
+                                 GCancellable        *cancellable,
+                                 GError             **error);
+]]></programlisting></informalexample>
+  <para>
+    Thus, for every D-Bus method, there will be three C functions for
+    calling the method, one #GObject signal for handling an incoming
+    call and one C function for completing an incoming call. For every
+    D-Bus signal, there's one #GObject signal and one C function for
+    emitting it. For every D-Bus property, two C functions are
+    generated (one setter, one getter) and one #GObject property. The
+    following table summarizes the generated facilities and where they
+    are applicable:
+  </para>
+  <informaltable>
+    <tgroup cols="3">
+      <thead>
+        <row>
+          <entry></entry>
+          <entry>Client</entry>
+          <entry>Server</entry>
+        </row>
+      </thead>
+      <tbody>
+        <row>
+          <entry>Types</entry>
+          <entry>Use <type>MyAppFrobberProxy</type></entry>
+          <entry>Any type implementing the <type>MyAppFrobber</type> interface</entry>
+        </row>
+        <row>
+          <entry>Methods</entry>
+          <entry>Use <function>m_a_f_hello_world()</function> to call.</entry>
+          <entry>Receive via the <function>handle_hello_world()</function> signal handler. Complete the call with <function>m_a_f_complete_hello_world()</function></entry>
+        </row>
+        <row>
+          <entry>Signals</entry>
+          <entry>Connect to the <function>::notification</function> GObject signal.</entry>
+          <entry>Use <function>m_a_f_emit_notification()</function> to emit signal.</entry>
+        </row>
+        <row>
+          <entry>Properties (Reading)</entry>
+          <entry>Use <function>m_a_f_get_verbose()</function> or <parameter>:verbose</parameter>.</entry>
+          <entry>Implement #GObject<!-- -->'s <function>get_property()</function> vfunc.</entry>
+        </row>
+        <row>
+          <entry>Properties (writing)</entry>
+          <entry>Use <function>m_a_f_set_verbose()</function> or <parameter>:verbose</parameter>.</entry>
+          <entry>Implement #GObject<!-- -->'s <function>set_property()</function> vfunc.</entry>
+        </row>
+      </tbody>
+    </tgroup>
+  </informaltable>
+
+  <refsect2>
+    <title>Client-side usage</title>
+    <para>
+      You can use the generated proxy type with the generated
+      constructors:
+    </para>
+    <informalexample><programlisting><![CDATA[
+    MyAppFrobber *proxy;
+    GError *error;
+
+    error = NULL;
+    proxy = my_app_frobber_proxy_new_for_bus_sync (
+                G_BUS_TYPE_SESSION,
+                G_DBUS_PROXY_FLAGS_NONE,
+                "net.Corp.MyApp",              /* bus name */
+                "/net/Corp/MyApp/SomeFrobber", /* object */
+                NULL,                          /* GCancellable* */
+                &error);
+    /* do stuff with proxy */
+    g_object_unref (proxy);
+]]></programlisting></informalexample>
+    <para>
+      Instead of using the generic #GDBusProxy facilities, one can use
+      the generated methods such as
+      <function>my_app_frobber_call_hello_world()</function> to invoke
+      the <function>net.Corp.MyApp.Frobber.HelloWorld()</function>
+      D-Bus method, connect to the
+      <function>::notification</function> GObject signal to receive
+      the <function>net.Corp.MyApp.Frobber::Notification</function>
+      D-Bus signal and get/set the
+      <parameter>net.Corp.MyApp.Frobber:Verbose</parameter> D-Bus
+      Property using either the GObject property
+      <parameter>:verbose</parameter> or the
+      <function>my_app_get_verbose()</function> and
+      <function>my_app_set_verbose()</function> methods. Use the
+      standard #GObject::notify signal to listen to property changes.
+    </para>
+    <para>
+      Note that all property access is via #GDBusProxy<!-- -->'s
+      property cache so no I/O is ever done when reading properties.
+      Also note that setting a property will cause the
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties.Set</ulink> method to be
+      called on the remote object. This call, however, is asynchronous
+      so setting a property won't block. Further, the change is
+      delayed and no error checking is possible.
+    </para>
+  </refsect2>
+
+  <refsect2>
+    <title>Server-side usage</title>
+    <para>
+      The generated <type>MyAppFrobber</type> interface is designed so
+      it is easy to implement it in a #GObject
+      subclass. For example, to handle
+      <function>HelloWorld()</function> method invocations, set the
+      vfunc for <function>handle_hello_hello_world()</function> in the
+      <type>MyAppFrobberIface</type> structure. Similarly, to handle
+      the <parameter>net.Corp.MyApp.Frobber:Verbose</parameter>
+      property override the <parameter>:verbose</parameter> #GObject
+      property from the subclass. To emit a signal, use
+      e.g. <function>my_app_emit_signal()</function> or
+      g_signal_emit_by_name().
+    </para>
+    <para>
+      Instead of subclassing, it is often easier to use the generated
+      <type>MyAppFrobberSkeleton</type> subclass. To handle incoming
+      method calls, use <function>g_signal_connect()</function> with
+      the <function>::handle-*</function> signals and instead of
+      overriding #GObject<!-- -->'s
+      <function>get_property()</function> and
+      <function>set_property()</function> vfuncs, use
+      g_object_get() and
+      g_object_set() or the generated property
+      getters and setters (the generated class has an internal
+      property bag implementation).
+    </para>
+    <informalexample><programlisting><![CDATA[
+static gboolean
+on_handle_hello_world (MyAppFrobber           *interface,
+                       GDBusMethodInvocation  *invocation,
+                       const gchar            *greeting,
+                       gpointer                user_data)
+{
+  if (g_strcmp0 (greeting, "Boo") != 0)
+    {
+      gchar *response;
+      response = g_strdup_printf ("Word! You said `%s'.", greeting);
+      my_app_complete_hello_world (interface, invocation, response);
+      g_free (response);
+    }
+  else
+    {
+      g_dbus_method_invocation_return_error (invocation,
+                 MY_APP_ERROR,
+                 MY_APP_ERROR_NO_WHINING,
+                 "Hey, %s, there will be no whining!",
+                 g_dbus_method_invocation_get_sender (invocation));
+    }
+  return TRUE;
+}
+
+  [...]
+
+  interface = my_app_frobber_skeleton_new ();
+  my_app_frobber_set_verbose (interface, TRUE);
+
+  g_signal_connect (interface,
+                    "handle-hello-world",
+                    G_CALLBACK (on_handle_hello_world),
+                    some_user_data);
+
+  [...]
+
+  error = NULL;
+  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface),
+                                         connection,
+                                         "/path/of/dbus_object",
+                                         &error))
+    {
+      /* handle error */
+    }
+]]></programlisting></informalexample>
+    <para>
+      To facilitate atomic changesets (multiple properties changing at
+      the same time), #GObject::notify signals are queued up when
+      received. The queue is drained in an idle handler (which is called from the
+      <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+      of the thread where the skeleton object was
+      constructed) and will cause emissions of the <ulink
+      url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties::PropertiesChanged</ulink>
+      signal with all the properties that have changed. Use
+      g_dbus_interface_skeleton_flush() or
+      g_dbus_object_skeleton_flush() to empty the queue
+      immediately. Use g_object_freeze_notify() and
+      g_object_thaw_notify() for atomic changesets if on a different
+      thread.
+    </para>
+  </refsect2>
+</refsect1>
+
+<refsect1>
+  <title>C Type Mapping</title>
+  <para>
+    Scalar types
+    (type-strings
+    <link linkend="G-VARIANT-TYPE-BOOLEAN:CAPS">'b'</link>,
+    <link linkend="G-VARIANT-TYPE-BYTE:CAPS">'y'</link>,
+    <link linkend="G-VARIANT-TYPE-INT16:CAPS">'n'</link>,
+    <link linkend="G-VARIANT-TYPE-UINT16:CAPS">'q'</link>,
+    <link linkend="G-VARIANT-TYPE-INT32:CAPS">'i'</link>,
+    <link linkend="G-VARIANT-TYPE-UINT32:CAPS">'u'</link>,
+    <link linkend="G-VARIANT-TYPE-INT64:CAPS">'x'</link>,
+    <link linkend="G-VARIANT-TYPE-UINT64:CAPS">'t'</link> and
+    <link linkend="G-VARIANT-TYPE-DOUBLE:CAPS">'d'</link>)
+    ),
+    strings (type-strings
+    <link linkend="G-VARIANT-TYPE-STRING:CAPS">'s'</link>,
+    <link linkend="G-VARIANT-TYPE-BYTESTRING:CAPS">'ay'</link>,
+    <link linkend="G-VARIANT-TYPE-OBJECT-PATH:CAPS">'o'</link> and
+    <link linkend="G-VARIANT-TYPE-SIGNATURE:CAPS">'g'</link>) and
+    arrays of string (type-strings
+    <link linkend="G-VARIANT-TYPE-STRING-ARRAY:CAPS">'as'</link>,
+    <link linkend="G-VARIANT-TYPE-OBJECT-PATH-ARRAY:CAPS">'ao'</link> and
+    <link linkend="G-VARIANT-TYPE-BYTESTRING-ARRAY:CAPS">'aay'</link>)
+    are mapped to the natural types,
+    e.g. #gboolean, #gdouble, #gint, <link linkend="gchararray">gchar*</link>,
+    <link linkend="GStrv">gchar**</link> and
+    so on. Everything else is mapped to the #GVariant
+    type.
+  </para>
+  <para>
+    This automatic mapping can be turned off by using the annotation
+    <literal>org.gtk.GDBus.C.ForceGVariant</literal> - if used then a
+    #GVariant is always exchanged instead of the
+    corresponding native C type. This annotation may be convenient to
+    use when using
+    bytestrings (type-string <link linkend="G-VARIANT-TYPE-BYTESTRING:CAPS">'ay'</link>)
+    for data that could have embedded NUL bytes.
+  </para>
+</refsect1>
+
+<refsect1 id="gdbus-code-stability">
+  <title>Stability Guarantees</title>
+  <para>
+    The generated C functions are guaranteed to not change their ABI
+    that is, if a method, signal or property does not change its
+    signature in the introspection XML, the generated C functions will
+    not change its C ABI either. The ABI of the generated instance and
+    class structures will be preserved as well.
+  </para>
+  <para>
+    The ABI of the generated #GType<!-- -->s will be preserved only if
+    the <literal>org.gtk.GDBus.Since</literal> annotation is used
+    judiciously — this is because the VTable for the #GInterface
+    relies on functions pointers for signal handlers. Specifically, if
+    a D-Bus method, property or signal or is added to a D-Bus
+    interface, then ABI of the generated #GInterface type is preserved
+    if, and only if, each added method, property signal is annotated
+    with they <literal>org.gtk.GDBus.Since</literal> annotation using
+    a greater version number than previous versions.
+  </para>
+  <para>
+    The generated C code currently happens to be annotated with <ulink
+    url="http://www.gtk.org/gtk-doc/">gtk-doc</ulink> / <ulink
+    url="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject
+    Introspection</ulink> comments / annotations. The layout and
+    contents might change in the future so no guarantees about
+    e.g. <literal>SECTION</literal> usage etc. is given.
+  </para>
+  <para>
+    While the generated Docbook for D-Bus interfaces isn't expected to
+    change, no guarantees are given at this point.
+  </para>
+  <para>
+    It is important to note that the generated code should not be
+    checked into revision control systems, nor it should be included
+    in distributed source archives.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Bugs</title>
+  <para>
+    Please send bug reports to either the distribution bug tracker
+    or the upstream bug tracker at
+    <ulink url="https://gitlab.gnome.org/GNOME/glib/issues/new">https://gitlab.gnome.org/GNOME/glib/issues/new</ulink>.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>See also</title>
+  <para>
+    <citerefentry>
+      <refentrytitle>gdbus</refentrytitle><manvolnum>1</manvolnum>
+    </citerefentry>
+  </para>
+</refsect1>
+
+</refentry>
diff --git a/docs/reference/gio/gdbus-object-manager-example/.gitignore b/docs/reference/gio/gdbus-object-manager-example/.gitignore
new file mode 100644
index 0000000..cc8a11d
--- /dev/null
+++ b/docs/reference/gio/gdbus-object-manager-example/.gitignore
@@ -0,0 +1 @@
+gdbus-object-manager-example-overrides.txt
diff --git a/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml
new file mode 100644
index 0000000..7b0d1ca
--- /dev/null
+++ b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+]>
+<book lang="en" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <part>
+    <title>foo</title>
+    <chapter>
+      <title>bar</title>
+      <xi:include href="xml/ExampleAnimal.xml"/>
+      <xi:include href="xml/ExampleCat.xml"/>
+      <xi:include href="xml/ExampleObject.xml"/>
+      <xi:include href="xml/ExampleObjectManagerClient.xml"/>
+    </chapter>
+  </part>
+</book>
diff --git a/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt
new file mode 100644
index 0000000..1e3b8b8
--- /dev/null
+++ b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt
@@ -0,0 +1,161 @@
+<SECTION>
+<FILE>ExampleAnimal</FILE>
+<TITLE>ExampleAnimal</TITLE>
+ExampleAnimal
+ExampleAnimalIface
+example_animal_interface_info
+example_animal_override_properties
+example_animal_call_poke
+example_animal_call_poke_finish
+example_animal_call_poke_sync
+example_animal_complete_poke
+example_animal_emit_jumped
+example_animal_get_mood
+example_animal_get_foo
+example_animal_get_bar
+example_animal_dup_mood
+example_animal_dup_foo
+example_animal_dup_bar
+example_animal_set_mood
+example_animal_set_foo
+example_animal_set_bar
+ExampleAnimalProxy
+ExampleAnimalProxyClass
+example_animal_proxy_new
+example_animal_proxy_new_finish
+example_animal_proxy_new_sync
+example_animal_proxy_new_for_bus
+example_animal_proxy_new_for_bus_finish
+example_animal_proxy_new_for_bus_sync
+ExampleAnimalSkeleton
+ExampleAnimalSkeletonClass
+example_animal_skeleton_new
+<SUBSECTION Standard>
+example_animal_get_type
+example_animal_proxy_get_type
+example_animal_skeleton_get_type
+ExampleAnimalSkeletonPrivate
+ExampleAnimalProxyPrivate
+EXAMPLE_TYPE_ANIMAL
+EXAMPLE_TYPE_ANIMAL_PROXY
+EXAMPLE_TYPE_ANIMAL_SKELETON
+EXAMPLE_ANIMAL
+EXAMPLE_ANIMAL_GET_IFACE
+EXAMPLE_ANIMAL_PROXY
+EXAMPLE_ANIMAL_PROXY_CLASS
+EXAMPLE_ANIMAL_PROXY_GET_CLASS
+EXAMPLE_ANIMAL_SKELETON
+EXAMPLE_ANIMAL_SKELETON_CLASS
+EXAMPLE_ANIMAL_SKELETON_GET_CLASS
+EXAMPLE_IS_ANIMAL
+EXAMPLE_IS_ANIMAL_PROXY
+EXAMPLE_IS_ANIMAL_PROXY_CLASS
+EXAMPLE_IS_ANIMAL_SKELETON
+EXAMPLE_IS_ANIMAL_SKELETON_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>ExampleCat</FILE>
+<TITLE>ExampleCat</TITLE>
+ExampleCat
+ExampleCatIface
+example_cat_interface_info
+example_cat_override_properties
+ExampleCatProxy
+ExampleCatProxyClass
+example_cat_proxy_new
+example_cat_proxy_new_finish
+example_cat_proxy_new_sync
+example_cat_proxy_new_for_bus
+example_cat_proxy_new_for_bus_finish
+example_cat_proxy_new_for_bus_sync
+ExampleCatSkeleton
+ExampleCatSkeletonClass
+example_cat_skeleton_new
+<SUBSECTION Standard>
+example_cat_get_type
+example_cat_proxy_get_type
+example_cat_skeleton_get_type
+ExampleCatProxyPrivate
+ExampleCatSkeletonPrivate
+EXAMPLE_TYPE_CAT
+EXAMPLE_TYPE_CAT_PROXY
+EXAMPLE_TYPE_CAT_SKELETON
+EXAMPLE_CAT
+EXAMPLE_CAT_GET_IFACE
+EXAMPLE_CAT_PROXY
+EXAMPLE_CAT_PROXY_CLASS
+EXAMPLE_CAT_PROXY_GET_CLASS
+EXAMPLE_CAT_SKELETON
+EXAMPLE_CAT_SKELETON_CLASS
+EXAMPLE_CAT_SKELETON_GET_CLASS
+EXAMPLE_IS_CAT
+EXAMPLE_IS_CAT_PROXY
+EXAMPLE_IS_CAT_PROXY_CLASS
+EXAMPLE_IS_CAT_SKELETON
+EXAMPLE_IS_CAT_SKELETON_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>ExampleObject</FILE>
+<TITLE>ExampleObject</TITLE>
+ExampleObject
+ExampleObjectIface
+example_object_get_animal
+example_object_get_cat
+example_object_peek_animal
+example_object_peek_cat
+ExampleObjectProxy
+ExampleObjectProxyClass
+example_object_proxy_new
+ExampleObjectSkeleton
+ExampleObjectSkeletonClass
+example_object_skeleton_new
+example_object_skeleton_set_animal
+example_object_skeleton_set_cat
+<SUBSECTION Standard>
+example_object_get_type
+example_object_proxy_get_type
+example_object_skeleton_get_type
+ExampleObjectProxyPrivate
+ExampleObjectSkeletonPrivate
+EXAMPLE_IS_OBJECT
+EXAMPLE_IS_OBJECT_PROXY
+EXAMPLE_IS_OBJECT_PROXY_CLASS
+EXAMPLE_IS_OBJECT_SKELETON
+EXAMPLE_IS_OBJECT_SKELETON_CLASS
+EXAMPLE_OBJECT
+EXAMPLE_OBJECT_GET_IFACE
+EXAMPLE_OBJECT_PROXY
+EXAMPLE_OBJECT_PROXY_CLASS
+EXAMPLE_OBJECT_PROXY_GET_CLASS
+EXAMPLE_OBJECT_SKELETON
+EXAMPLE_OBJECT_SKELETON_CLASS
+EXAMPLE_OBJECT_SKELETON_GET_CLASS
+EXAMPLE_TYPE_OBJECT
+EXAMPLE_TYPE_OBJECT_PROXY
+EXAMPLE_TYPE_OBJECT_SKELETON
+</SECTION>
+
+<SECTION>
+<FILE>ExampleObjectManagerClient</FILE>
+<TITLE>ExampleObjectManagerClient</TITLE>
+ExampleObjectManagerClient
+ExampleObjectManagerClientClass
+example_object_manager_client_get_proxy_type
+example_object_manager_client_new
+example_object_manager_client_new_finish
+example_object_manager_client_new_sync
+example_object_manager_client_new_for_bus
+example_object_manager_client_new_for_bus_finish
+example_object_manager_client_new_for_bus_sync
+<SUBSECTION Standard>
+example_object_manager_client_get_type
+EXAMPLE_IS_OBJECT_MANAGER_CLIENT
+EXAMPLE_IS_OBJECT_MANAGER_CLIENT_CLASS
+EXAMPLE_OBJECT_MANAGER_CLIENT
+EXAMPLE_OBJECT_MANAGER_CLIENT_CLASS
+EXAMPLE_OBJECT_MANAGER_CLIENT_GET_CLASS
+EXAMPLE_TYPE_OBJECT_MANAGER_CLIENT
+ExampleObjectManagerClientPrivate
+</SECTION>
diff --git a/docs/reference/gio/gdbus-object-manager-example/meson.build b/docs/reference/gio/gdbus-object-manager-example/meson.build
new file mode 100644
index 0000000..13cae5b
--- /dev/null
+++ b/docs/reference/gio/gdbus-object-manager-example/meson.build
@@ -0,0 +1,11 @@
+gdbus_object_manager_example_doc = gnome.gtkdoc('gdbus-object-manager-example',
+  main_xml : 'gdbus-object-manager-example-docs.xml',
+  namespace : 'example',
+  dependencies : [libgdbus_example_objectmanager_dep],
+  src_dir : 'gio/tests/gdbus-object-manager-example',
+  scan_args : gtkdoc_common_scan_args + [
+    '--rebuild-types',
+  ],
+  install : false,
+)
+
diff --git a/docs/reference/gio/gdbus.xml b/docs/reference/gio/gdbus.xml
new file mode 100644
index 0000000..0e6c14d
--- /dev/null
+++ b/docs/reference/gio/gdbus.xml
@@ -0,0 +1,416 @@
+<refentry id="gdbus" lang="en">
+
+<refentryinfo>
+  <title>gdbus</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>David</firstname>
+      <surname>Zeuthen</surname>
+      <email>zeuthen@gmail.com</email>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>gdbus</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>gdbus</refname>
+  <refpurpose>Tool for working with D-Bus objects</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>gdbus</command>
+    <arg choice="plain">introspect</arg>
+    <group>
+      <arg choice="plain">--system</arg>
+      <arg choice="plain">--session</arg>
+      <arg choice="plain">--address <replaceable>address</replaceable></arg>
+    </group>
+    <arg choice="plain">--dest <replaceable>bus_name</replaceable></arg>
+    <arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
+    <group>
+      <arg choice="plain">--xml</arg>
+    </group>
+    <group>
+      <arg choice="plain">--recurse</arg>
+    </group>
+    <group>
+      <arg choice="plain">--only-properties</arg>
+    </group>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gdbus</command>
+    <arg choice="plain">monitor</arg>
+    <group>
+      <arg choice="plain">--system</arg>
+      <arg choice="plain">--session</arg>
+      <arg choice="plain">--address <replaceable>address</replaceable></arg>
+    </group>
+    <arg choice="plain">--dest <replaceable>bus_name</replaceable></arg>
+    <group>
+      <arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
+    </group>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gdbus</command>
+    <arg choice="plain">call</arg>
+    <group>
+      <arg choice="plain">--system</arg>
+      <arg choice="plain">--session</arg>
+      <arg choice="plain">--address <replaceable>address</replaceable></arg>
+    </group>
+    <arg choice="plain">--dest <replaceable>bus_name</replaceable></arg>
+    <arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
+    <arg choice="plain">--method <replaceable>org.project.InterfaceName.MethodName</replaceable></arg>
+    <group>
+      <arg choice="plain">--timeout <replaceable>seconds</replaceable></arg>
+    </group>
+    <arg choice="plain">ARG1</arg>
+    <arg choice="plain" rep="repeat">ARG2</arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gdbus</command>
+    <arg choice="plain">emit</arg>
+    <group>
+      <arg choice="plain">--system</arg>
+      <arg choice="plain">--session</arg>
+      <arg choice="plain">--address <replaceable>address</replaceable></arg>
+    </group>
+    <arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
+    <arg choice="plain">--signal <replaceable>org.project.InterfaceName.SignalName</replaceable></arg>
+    <group>
+      <arg choice="plain">--dest <replaceable>unique_bus_name</replaceable></arg>
+    </group>
+    <arg choice="plain">ARG1</arg>
+    <arg choice="plain" rep="repeat">ARG2</arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gdbus</command>
+    <arg choice="plain">wait</arg>
+    <group>
+      <arg choice="plain">--system</arg>
+      <arg choice="plain">--session</arg>
+      <arg choice="plain">--address <replaceable>address</replaceable></arg>
+    </group>
+    <arg choice="plain">--activate <replaceable>bus_name</replaceable></arg>
+    <group>
+      <arg choice="plain">--timeout <replaceable>seconds</replaceable></arg>
+    </group>
+    <arg choice="plain"><replaceable>bus_name</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gdbus</command>
+    <arg choice="plain">help</arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+  <title>Description</title>
+  <para>
+    <command>gdbus</command> is a simple tool for working with D-Bus objects.
+  </para>
+</refsect1>
+<refsect1>
+    <title>Commands</title>
+    <variablelist>
+      <varlistentry>
+        <term><option>introspect</option></term>
+        <listitem><para>
+          Prints out interfaces and property values for a remote object.
+          For this to work, the owner of the object needs to implement the
+          <literal>org.freedesktop.DBus.Introspectable</literal> interface.
+          If the <option>--xml</option> option is used, the returned
+          introspection XML is printed, otherwise a parsed pretty
+          representation is printed.
+          The <option>--recurse</option> option can be used to
+          introspect children (and their children and so on) and the
+          <option>--only-properties</option> option can be used to
+          only print the interfaces with properties.
+          </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>monitor</option></term>
+        <listitem><para>
+          Monitors one or all objects owned by the owner of
+          <replaceable>bus_name</replaceable>.
+        </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>call</option></term>
+        <listitem><para>
+          Invokes a method on a remote object.  Each argument to pass to the
+          method must be specified as a serialized
+          <link linkend="GVariant"><type>GVariant</type></link> except that strings do
+          not need explicit quotes. The return values are printed out as
+          serialized <link linkend="GVariant"><type>GVariant</type></link>
+          values.
+        </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>emit</option></term>
+        <listitem><para>
+          Emits a signal. Each argument to include in the signal must be specified as a serialized
+          <link linkend="GVariant"><type>GVariant</type></link> except that strings do
+          not need explicit quotes.
+        </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>wait</option></term>
+        <listitem><para>
+          Waits until <replaceable>bus_name</replaceable> is owned by some
+          process on the bus. If the <option>--activate</option> is specified,
+          that bus name will be auto-started first. It may be the same as the
+          bus name being waited for, or different.
+        </para></listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>help</option></term>
+        <listitem><para>
+          Prints help and exit.
+        </para></listitem>
+      </varlistentry>
+    </variablelist>
+</refsect1>
+
+<refsect1>
+  <title>Bash Completion</title>
+  <para>
+    <command>gdbus</command> ships with a bash completion script to
+    complete commands, destinations, bus names, object paths and
+    interface/method names.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Examples</title>
+  This shows how to introspect an object - note that the value of each
+  property is displayed:
+<programlisting>
+$ gdbus introspect --system \
+        --dest org.freedesktop.NetworkManager \
+        --object-path /org/freedesktop/NetworkManager/Devices/0
+node /org/freedesktop/NetworkManager/Devices/0 {
+  interface org.freedesktop.DBus.Introspectable {
+    methods:
+      Introspect(out s data);
+  };
+  interface org.freedesktop.DBus.Properties {
+    methods:
+      Get(in  s interface,
+          in  s propname,
+          out v value);
+      Set(in  s interface,
+          in  s propname,
+          in  v value);
+      GetAll(in  s interface,
+             out a{sv} props);
+  };
+  interface org.freedesktop.NetworkManager.Device.Wired {
+    signals:
+      PropertiesChanged(a{sv} arg_0);
+    properties:
+      readonly b Carrier = false;
+      readonly u Speed = 0;
+      readonly s HwAddress = '00:1D:72:88:BE:97';
+  };
+  interface org.freedesktop.NetworkManager.Device {
+    methods:
+      Disconnect();
+    signals:
+      StateChanged(u arg_0,
+                   u arg_1,
+                   u arg_2);
+    properties:
+      readonly u DeviceType = 1;
+      readonly b Managed = true;
+      readwrite o Ip6Config = '/';
+      readwrite o Dhcp4Config = '/';
+      readwrite o Ip4Config = '/';
+      readonly u State = 2;
+      readwrite u Ip4Address = 0;
+      readonly u Capabilities = 3;
+      readonly s Driver = 'e1000e';
+      readwrite s Interface = 'eth0';
+      readonly s Udi = '/sys/devices/pci0000:00/0000:00:19.0/net/eth0';
+  };
+};
+</programlisting>
+<para>
+  The <option>--recurse</option> and <option>--only-properties</option> options can be useful when wanting to inspect all objects owned by a particular process:
+</para>
+<programlisting>
+$ gdbus introspect --system --dest org.freedesktop.UPower --object-path / --recurse  --only-properties 
+node / {
+  node /org {
+    node /org/freedesktop {
+      node /org/freedesktop/UPower {
+        interface org.freedesktop.UPower {
+          properties:
+            readonly b IsDocked = true;
+            readonly b LidForceSleep = false;
+            readonly b LidIsPresent = false;
+            readonly b LidIsClosed = false;
+            readonly b OnLowBattery = false;
+            readonly b OnBattery = false;
+            readonly b CanHibernate = true;
+            readonly b CanSuspend = true;
+            readonly s DaemonVersion = '0.9.10';
+        };
+        node /org/freedesktop/UPower/Policy {
+        };
+        node /org/freedesktop/UPower/Wakeups {
+          interface org.freedesktop.UPower.Wakeups {
+            properties:
+              readonly b HasCapability = true;
+          };
+        };
+      };
+    };
+  };
+};
+</programlisting>
+<para>
+  In a similar fashion, the <option>introspect</option> command can be
+  used to learn details about the <literal>Notify</literal> method:
+</para>
+<programlisting>
+[...]
+  interface org.freedesktop.Notifications {
+    methods:
+      GetServerInformation(out s return_name,
+                           out s return_vendor,
+                           out s return_version,
+                           out s return_spec_version);
+      GetCapabilities(out as return_caps);
+      CloseNotification(in  u id);
+      Notify(in  s app_name,
+             in  u id,
+             in  s icon,
+             in  s summary,
+             in  s body,
+             in  as actions,
+             in  a{sv} hints,
+             in  i timeout,
+             out u return_id);
+  };
+[...]
+</programlisting>
+<para>
+  With this information, it's easy to use the <option>call</option>
+  command to display a notification
+</para>
+<programlisting>
+$ gdbus call --session \
+             --dest org.freedesktop.Notifications \
+             --object-path /org/freedesktop/Notifications \
+             --method org.freedesktop.Notifications.Notify \
+             my_app_name \
+             42 \
+             gtk-dialog-info \
+             "The Summary" \
+             "Here's the body of the notification" \
+             [] \
+             {} \
+             5000
+(uint32 12,)
+</programlisting>
+<para>
+  Monitoring all objects on a service:
+</para>
+<programlisting>
+$ gdbus monitor --system --dest org.freedesktop.ConsoleKit
+Monitoring signals from all objects owned by org.freedesktop.ConsoleKit
+The name org.freedesktop.ConsoleKit is owned by :1.15
+/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (false,)
+/org/freedesktop/ConsoleKit/Seat1: org.freedesktop.ConsoleKit.Seat.ActiveSessionChanged ('',)
+/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (true,)
+/org/freedesktop/ConsoleKit/Seat1: org.freedesktop.ConsoleKit.Seat.ActiveSessionChanged ('/org/freedesktop/ConsoleKit/Session2',)
+</programlisting>
+<para>
+  Monitoring a single object on a service:
+</para>
+<programlisting>
+$ gdbus monitor --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/AccessPoint/4141
+Monitoring signals on object /org/freedesktop/NetworkManager/AccessPoint/4141 owned by org.freedesktop.NetworkManager
+The name org.freedesktop.NetworkManager is owned by :1.5
+/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': &lt;byte 0x5c&gt;},)
+/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': &lt;byte 0x64&gt;},)
+/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': &lt;byte 0x5e&gt;},)
+/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': &lt;byte 0x64&gt;},)
+</programlisting>
+
+<para>
+  Emitting a signal:
+</para>
+<programlisting>
+$ gdbus emit --session --object-path /foo --signal org.bar.Foo "['foo', 'bar', 'baz']"
+</programlisting>
+
+<para>
+  Emitting a signal to a specific process:
+</para>
+<programlisting>
+$ gdbus emit --session --object-path /bar --signal org.bar.Bar someString --dest :1.42
+</programlisting>
+
+<para>
+  Waiting for a well-known name to be owned on the bus; this will
+  <emphasis>not</emphasis> auto-start the service:
+</para>
+<programlisting>
+$ gdbus wait --session org.bar.SomeName
+</programlisting>
+
+<para>
+  Auto-starting then waiting for a well-known name to be owned on the bus:
+</para>
+<programlisting>
+$ gdbus wait --session --activate org.bar.SomeName
+</programlisting>
+
+<para>
+  Auto-starting a different service, then waiting for a well-known name to be
+  owned on the bus. This is useful in situations where
+  <replaceable>SomeName</replaceable> is not directly activatable:
+</para>
+<programlisting>
+$ gdbus wait --session --activate org.bar.PrerequisiteName org.bar.SomeName
+</programlisting>
+
+<para>
+  Waiting for a well-known name and giving up after 30 seconds. By default,
+  the timeout is disabled; or set <option>--timeout</option> to 0 to disable it:
+</para>
+<programlisting>
+$ gdbus wait --session --timeout 30 org.bar.SomeName
+</programlisting>
+
+</refsect1>
+
+<refsect1>
+  <title>Bugs</title>
+  <para>
+    Please send bug reports to either the distribution bug tracker
+    or the upstream bug tracker at
+    <ulink url="https://gitlab.gnome.org/GNOME/glib/issues/new"/>.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>See Also</title>
+  <para>
+    <citerefentry>
+      <refentrytitle>dbus-send</refentrytitle><manvolnum>1</manvolnum>
+    </citerefentry>
+  </para>
+</refsect1>
+
+</refentry>
+
diff --git a/docs/reference/gio/gio-docs-unix.xml b/docs/reference/gio/gio-docs-unix.xml
new file mode 100644
index 0000000..b78edda
--- /dev/null
+++ b/docs/reference/gio/gio-docs-unix.xml
@@ -0,0 +1,3 @@
+<chapter id='unix-support'>
+<!--FIXME: fill this with unix APIs that cannot build on Windows -->
+</chapter>
diff --git a/docs/reference/gio/gio-docs-win32.xml b/docs/reference/gio/gio-docs-win32.xml
new file mode 100644
index 0000000..f34a6e6
--- /dev/null
+++ b/docs/reference/gio/gio-docs-win32.xml
@@ -0,0 +1,6 @@
+<chapter id='win32-support'>
+    <title>Win32 support</title>
+    <xi:include href="xml/gwin32registrykey.xml"/>
+    <xi:include href="xml/gwin32inputstream.xml"/>
+    <xi:include href="xml/gwin32outputstream.xml"/>
+</chapter>
diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
new file mode 100644
index 0000000..565c20c
--- /dev/null
+++ b/docs/reference/gio/gio-docs.xml
@@ -0,0 +1,391 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN'
+                      'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd' [
+<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book lang="en" id="gio" xmlns:xi="http://www.w3.org/2003/XInclude">
+<title>GIO Reference Manual</title>
+  <bookinfo>
+    <title>GIO Reference Manual</title>
+    <releaseinfo>
+      for GIO &version;
+      The latest version of this documentation can be found on-line at
+      <ulink role="online-location" url="https://developer.gnome.org/gio/unstable/">https://developer.gnome.org/gio/unstable/</ulink>.
+    </releaseinfo>
+  </bookinfo>
+
+  <xi:include href="xml/overview.xml"/>
+
+  <part>
+  <title>API Reference</title>
+    <chapter id="file_ops">
+        <title>File Operations</title>
+        <xi:include href="xml/gfile.xml"/>
+        <xi:include href="xml/gfileattribute.xml"/>
+        <xi:include href="xml/gfileinfo.xml"/>
+        <xi:include href="xml/gfileenumerator.xml"/>
+        <xi:include href="xml/gioerror.xml"/>
+        <xi:include href="xml/gmountoperation.xml"/>
+    </chapter>
+    <chapter id="file_mon">
+        <title>File System Monitoring</title>
+        <xi:include href="xml/gfilemonitor.xml"/>
+    </chapter>
+    <chapter id="utils">
+        <title>File-related Utilities</title>
+        <xi:include href="xml/gfilenamecompleter.xml"/>
+    </chapter>
+    <chapter id="async">
+        <title>Asynchronous I/O</title>
+        <xi:include href="xml/gcancellable.xml"/>
+        <xi:include href="xml/gasyncresult.xml"/>
+        <xi:include href="xml/gtask.xml"/>
+        <xi:include href="xml/gioscheduler.xml"/>
+        <xi:include href="xml/gsimpleasyncresult.xml"/>
+    </chapter>
+    <chapter id="conversion">
+        <title>Data conversion</title>
+        <xi:include href="xml/gconverter.xml"/>
+        <xi:include href="xml/gcharsetconverter.xml"/>
+        <xi:include href="xml/gzcompressor.xml"/>
+        <xi:include href="xml/gzdecompressor.xml"/>
+    </chapter>
+    <chapter id="streaming">
+        <title>Streaming I/O</title>
+        <xi:include href="xml/gseekable.xml"/>
+        <xi:include href="xml/ginputstream.xml"/>
+        <xi:include href="xml/goutputstream.xml"/>
+        <xi:include href="xml/giostream.xml"/>
+        <xi:include href="xml/gsimpleiostream.xml"/>
+        <xi:include href="xml/gfileinputstream.xml"/>
+        <xi:include href="xml/gfileoutputstream.xml"/>
+        <xi:include href="xml/gfileiostream.xml"/>
+        <xi:include href="xml/gfiledescriptorbased.xml"/>
+        <xi:include href="xml/gfilterinputstream.xml"/>
+        <xi:include href="xml/gfilteroutputstream.xml"/>
+        <xi:include href="xml/gmemoryinputstream.xml"/>
+        <xi:include href="xml/gmemoryoutputstream.xml"/>
+        <xi:include href="xml/gbufferedinputstream.xml"/>
+        <xi:include href="xml/gbufferedoutputstream.xml"/>
+        <xi:include href="xml/gdatainputstream.xml"/>
+        <xi:include href="xml/gdataoutputstream.xml"/>
+        <xi:include href="xml/gunixinputstream.xml"/>
+        <xi:include href="xml/gunixoutputstream.xml"/>
+        <xi:include href="xml/gconverterinputstream.xml"/>
+        <xi:include href="xml/gconverteroutputstream.xml"/>
+        <xi:include href="xml/gpollableinputstream.xml"/>
+        <xi:include href="xml/gpollableoutputstream.xml"/>
+        <xi:include href="xml/gpollableutils.xml"/>
+    </chapter>
+    <chapter id="types">
+        <title>File types and applications</title>
+        <xi:include href="xml/gcontenttype.xml"/>
+        <xi:include href="xml/gappinfo.xml"/>
+        <xi:include href="xml/gappinfomonitor.xml"/>
+        <xi:include href="xml/gdesktopappinfo.xml"/>
+    </chapter>
+    <chapter id="volume_mon">
+        <title>Volumes and Drives</title>
+        <xi:include href="xml/gvolumemonitor.xml"/>
+        <xi:include href="xml/gvolume.xml"/>
+        <xi:include href="xml/gmount.xml"/>
+        <xi:include href="xml/gdrive.xml"/>
+        <xi:include href="xml/gunixmounts.xml"/>
+    </chapter>
+    <chapter id="icons">
+        <title>Icons</title>
+        <xi:include href="xml/gicon.xml"/>
+        <xi:include href="xml/gfileicon.xml"/>
+        <xi:include href="xml/gbytesicon.xml"/>
+        <xi:include href="xml/gloadableicon.xml"/>
+        <xi:include href="xml/gthemedicon.xml"/>
+        <xi:include href="xml/gemblemedicon.xml"/>
+        <xi:include href="xml/gemblem.xml"/>
+    </chapter>
+    <chapter id="failable_initialization">
+        <title>Failable Initialization</title>
+        <xi:include href="xml/ginitable.xml"/>
+        <xi:include href="xml/gasyncinitable.xml"/>
+    </chapter>
+    <chapter id="subprocesses">
+      <title>Subprocesses</title>
+      <xi:include href="xml/gsubprocess.xml"/>
+      <xi:include href="xml/gsubprocesslauncher.xml"/>
+    </chapter>
+    <chapter id="networking">
+      <title>Low-level network support</title>
+      <xi:include href="xml/gsocket.xml"/>
+      <xi:include href="xml/gdatagrambased.xml"/>
+      <xi:include href="xml/ginetaddress.xml"/>
+      <xi:include href="xml/ginetaddressmask.xml"/>
+      <xi:include href="xml/gsocketaddress.xml"/>
+      <xi:include href="xml/ginetsocketaddress.xml"/>
+      <xi:include href="xml/gunixsocketaddress.xml"/>
+      <xi:include href="xml/gnativesocketaddress.xml"/>
+      <xi:include href="xml/gsocketcontrolmessage.xml"/>
+      <xi:include href="xml/gunixfdlist.xml"/>
+      <xi:include href="xml/gunixfdmessage.xml"/>
+      <xi:include href="xml/gcredentials.xml"/>
+      <xi:include href="xml/gunixcredentialsmessage.xml"/>
+      <xi:include href="xml/gproxy.xml"/>
+      <xi:include href="xml/gproxyaddress.xml"/>
+      <xi:include href="xml/gnetworking.xml"/>
+    </chapter>
+    <chapter id="highlevel-socket">
+      <title>High-level network functionality</title>
+      <xi:include href="xml/gsocketclient.xml"/>
+      <xi:include href="xml/gsocketconnection.xml"/>
+      <xi:include href="xml/gunixconnection.xml"/>
+      <xi:include href="xml/gtcpconnection.xml"/>
+      <xi:include href="xml/gtcpwrapperconnection.xml"/>
+      <xi:include href="xml/gsocketlistener.xml"/>
+      <xi:include href="xml/gsocketservice.xml"/>
+      <xi:include href="xml/gthreadedsocketservice.xml"/>
+      <xi:include href="xml/gnetworkmonitor.xml"/>
+    </chapter>
+    <chapter id="tls">
+      <title>TLS (SSL) support</title>
+      <xi:include href="xml/gtls.xml"/>
+      <xi:include href="xml/gtlscertificate.xml"/>
+      <xi:include href="xml/gtlsconnection.xml"/>
+      <xi:include href="xml/gtlsclientconnection.xml"/>
+      <xi:include href="xml/gtlsserverconnection.xml"/>
+      <xi:include href="xml/gdtlsconnection.xml"/>
+      <xi:include href="xml/gdtlsclientconnection.xml"/>
+      <xi:include href="xml/gdtlsserverconnection.xml"/>
+      <xi:include href="xml/gtlsbackend.xml"/>
+      <xi:include href="xml/gtlsdatabase.xml"/>
+      <xi:include href="xml/gtlsfiledatabase.xml"/>
+      <xi:include href="xml/gtlsinteraction.xml"/>
+      <xi:include href="xml/gtlspassword.xml"/>
+    </chapter>
+    <chapter id="resolver">
+      <title>DNS resolution</title>
+      <xi:include href="xml/gresolver.xml"/>
+      <xi:include href="xml/gproxyresolver.xml"/>
+      <xi:include href="xml/gsimpleproxyresolver.xml"/>
+      <xi:include href="xml/gsocketconnectable.xml"/>
+      <xi:include href="xml/gsocketaddressenumerator.xml"/>
+      <xi:include href="xml/gproxyaddressenumerator.xml"/>
+      <xi:include href="xml/gnetworkaddress.xml"/>
+      <xi:include href="xml/gnetworkservice.xml"/>
+      <xi:include href="xml/gsrvtarget.xml"/>
+    </chapter>
+    <chapter id="gdbus-lowlevel">
+      <title>Low-level D-Bus Support</title>
+      <xi:include href="xml/gdbusutils.xml"/>
+      <xi:include href="xml/gdbusaddress.xml"/>
+      <xi:include href="xml/gdbusintrospection.xml"/>
+      <xi:include href="xml/gdbuserror.xml"/>
+      <xi:include href="xml/gdbusmessage.xml"/>
+      <xi:include href="xml/gdbusconnection.xml"/>
+      <xi:include href="xml/gdbusmethodinvocation.xml"/>
+      <xi:include href="xml/gdbusserver.xml"/>
+      <xi:include href="xml/gdbusauthobserver.xml"/>
+    </chapter>
+    <chapter id="gdbus-convenience">
+      <title>High-level D-Bus Support</title>
+      <xi:include href="xml/gdbusnameowning.xml"/>
+      <xi:include href="xml/gdbusnamewatching.xml"/>
+      <xi:include href="xml/gdbusinterface.xml"/>
+      <xi:include href="xml/gdbusinterfaceskeleton.xml"/>
+      <xi:include href="xml/gdbusproxy.xml"/>
+      <xi:include href="xml/gdbusobject.xml"/>
+      <xi:include href="xml/gdbusobjectskeleton.xml"/>
+      <xi:include href="xml/gdbusobjectproxy.xml"/>
+      <xi:include href="xml/gdbusobjectmanager.xml"/>
+      <xi:include href="xml/gdbusobjectmanagerserver.xml"/>
+      <xi:include href="xml/gdbusobjectmanagerclient.xml"/>
+    </chapter>
+    <chapter id="settings">
+        <title>Settings</title>
+        <xi:include href="xml/gsettings.xml"/>
+        <xi:include href="xml/gsettingsbackend.xml"/>
+        <xi:include href="xml/gsettingsschema.xml"/>
+    </chapter>
+    <chapter id="resources">
+        <title>Resources</title>
+        <xi:include href="xml/gresource.xml"/>
+    </chapter>
+    <chapter id='permissions'>
+        <title>Permissions</title>
+        <xi:include href="xml/gpermission.xml"/>
+        <xi:include href="xml/gsimplepermission.xml"/>
+    </chapter>
+    <chapter id='data-models'>
+        <title>Data Models</title>
+        <xi:include href="xml/glistmodel.xml"/>
+        <xi:include href="xml/gliststore.xml"/>
+    </chapter>
+
+    <chapter id="application">
+        <title>Application support</title>
+        <xi:include href="xml/gapplication.xml"/>
+        <xi:include href="xml/gapplicationcommandline.xml"/>
+        <xi:include href="xml/gactiongroup.xml"/>
+        <xi:include href="xml/gactionmap.xml"/>
+        <xi:include href="xml/gsimpleactiongroup.xml"/>
+        <xi:include href="xml/gaction.xml"/>
+        <xi:include href="xml/gsimpleaction.xml"/>
+        <xi:include href="xml/gpropertyaction.xml"/>
+        <xi:include href="xml/gremoteactiongroup.xml"/>
+        <xi:include href="xml/gactiongroupexporter.xml"/>
+        <xi:include href="xml/gdbusactiongroup.xml"/>
+        <xi:include href="xml/gmemorymonitor.xml"/>
+        <xi:include href="xml/gmenumodel.xml"/>
+        <xi:include href="xml/gmenu.xml"/>
+        <xi:include href="xml/gmenuexporter.xml"/>
+        <xi:include href="xml/gdbusmenumodel.xml"/>
+        <xi:include href="xml/gnotification.xml"/>
+    </chapter>
+    <chapter id="extending">
+        <title>Extending GIO</title>
+        <xi:include href="xml/gvfs.xml"/>
+        <xi:include href="xml/giomodule.xml"/>
+        <xi:include href="xml/extensionpoints.xml"/>
+    </chapter>
+    <chapter id="tools">
+        <title>GIO Tools</title>
+        <xi:include href="gio-querymodules.xml"/>
+        <xi:include href="gsettings.xml"/>
+        <xi:include href="glib-compile-schemas.xml"/>
+        <xi:include href="glib-compile-resources.xml"/>
+        <xi:include href="gdbus.xml"/>
+        <xi:include href="xml/gdbus-codegen.xml"/>
+        <xi:include href="gresource.xml"/>
+        <xi:include href="gapplication.xml"/>
+        <xi:include href="gio.xml"/>
+    </chapter>
+    <chapter id="testing">
+        <title>GIO Testing</title>
+        <xi:include href="xml/gtestdbus.xml"/>
+    </chapter>
+    <xi:include href="gio-docs-platform.xml"/>
+  </part>
+
+  <part id="migrating">
+    <title>Migrating to GIO</title>
+    <xi:include href="xml/migrating-posix.xml"/>
+    <xi:include href="xml/migrating-gnome-vfs.xml"/>
+    <xi:include href="xml/migrating-gconf.xml"/>
+    <xi:include href="xml/migrating-gdbus.xml"/>
+  </part>
+
+  <chapter id="gio-hierarchy">
+    <title>Object Hierarchy</title>
+      <xi:include href="xml/tree_index.sgml"/>
+  </chapter>
+  
+  <index id="api-index-full">
+    <title id="index-all">Index</title>
+    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-deprecated" role="deprecated">
+    <title>Index of deprecated symbols</title>
+    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-18" role="2.18">
+    <title>Index of new symbols in 2.18</title>
+    <xi:include href="xml/api-index-2.18.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-20" role="2.20">
+    <title>Index of new symbols in 2.20</title>
+    <xi:include href="xml/api-index-2.20.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-22" role="2.22">
+    <title>Index of new symbols in 2.22</title>
+    <xi:include href="xml/api-index-2.22.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-24" role="2.24">
+    <title>Index of new symbols in 2.24</title>
+    <xi:include href="xml/api-index-2.24.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-26" role="2.26">
+    <title>Index of new symbols in 2.26</title>
+    <xi:include href="xml/api-index-2.26.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-28" role="2.28">
+    <title>Index of new symbols in 2.28</title>
+    <xi:include href="xml/api-index-2.28.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-30" role="2.30">
+    <title>Index of new symbols in 2.30</title>
+    <xi:include href="xml/api-index-2.30.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-32" role="2.32">
+    <title>Index of new symbols in 2.32</title>
+    <xi:include href="xml/api-index-2.32.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-34" role="2.34">
+    <title>Index of new symbols in 2.34</title>
+    <xi:include href="xml/api-index-2.34.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-36" role="2.36">
+    <title>Index of new symbols in 2.36</title>
+    <xi:include href="xml/api-index-2.36.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-38" role="2.38">
+    <title>Index of new symbols in 2.38</title>
+    <xi:include href="xml/api-index-2.38.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-40" role="2.40">
+    <title>Index of new symbols in 2.40</title>
+    <xi:include href="xml/api-index-2.40.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-42" role="2.42">
+    <title>Index of new symbols in 2.42</title>
+    <xi:include href="xml/api-index-2.42.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-44" role="2.44">
+    <title>Index of new symbols in 2.44</title>
+    <xi:include href="xml/api-index-2.44.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-46" role="2.46">
+    <title>Index of new symbols in 2.46</title>
+    <xi:include href="xml/api-index-2.46.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-48" role="2.48">
+    <title>Index of new symbols in 2.48</title>
+    <xi:include href="xml/api-index-2.48.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-50" role="2.50">
+    <title>Index of new symbols in 2.50</title>
+    <xi:include href="xml/api-index-2.50.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-52" role="2.52">
+    <title>Index of new symbols in 2.52</title>
+    <xi:include href="xml/api-index-2.52.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-54" role="2.54">
+    <title>Index of new symbols in 2.54</title>
+    <xi:include href="xml/api-index-2.54.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-56" role="2.56">
+    <title>Index of new symbols in 2.56</title>
+    <xi:include href="xml/api-index-2.56.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-58" role="2.58">
+    <title>Index of new symbols in 2.58</title>
+    <xi:include href="xml/api-index-2.58.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-60" role="2.60">
+    <title>Index of new symbols in 2.60</title>
+    <xi:include href="xml/api-index-2.60.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-62" role="2.62">
+    <title>Index of new symbols in 2.62</title>
+    <xi:include href="xml/api-index-2.62.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-64" role="2.64">
+    <title>Index of new symbols in 2.64</title>
+    <xi:include href="xml/api-index-2.64.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-66" role="2.66">
+    <title>Index of new symbols in 2.66</title>
+    <xi:include href="xml/api-index-2.66.xml"><xi:fallback /></xi:include>
+  </index>
+
+  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+
+</book>
diff --git a/docs/reference/gio/gio-querymodules.xml b/docs/reference/gio/gio-querymodules.xml
new file mode 100644
index 0000000..c9c5eec
--- /dev/null
+++ b/docs/reference/gio/gio-querymodules.xml
@@ -0,0 +1,45 @@
+<refentry id="gio-querymodules" lang="en">
+
+<refentryinfo>
+  <title>glib-compile-schemas</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Alexander</firstname>
+      <surname>Larsson</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>gio-querymodules</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>gio-querymodules</refname>
+  <refpurpose>GIO module cache creation</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>gio-querymodules</command>
+    <arg choice="req" rep="repeat">DIRECTORY</arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>gio-querymodules</command> creates a
+<filename>giomodule.cache</filename> file in the listed directories.
+This file lists the implemented extension points for each module
+that has been found. It is used by GIO at runtime to avoid opening
+all modules just to find out which extension points they are implementing.
+</para>
+<para>
+GIO modules are usually installed in the <filename>gio/modules</filename>
+subdirectory of libdir.
+</para>
+</refsect1>
+</refentry>
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
new file mode 100644
index 0000000..cd62b8a
--- /dev/null
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -0,0 +1,4683 @@
+<SECTION>
+<FILE>ginitable</FILE>
+<TITLE>GInitable</TITLE>
+GInitable
+GInitableIface
+g_initable_init
+g_initable_new
+g_initable_new_valist
+g_initable_newv
+<SUBSECTION Standard>
+G_INITABLE
+G_INITABLE_GET_IFACE
+G_IS_INITABLE
+G_TYPE_INITABLE
+G_TYPE_IS_INITABLE
+<SUBSECTION Private>
+g_initable_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gasyncinitable</FILE>
+<TITLE>GAsyncInitable</TITLE>
+GAsyncInitable
+GAsyncInitableIface
+g_async_initable_init_async
+g_async_initable_init_finish
+g_async_initable_new_async
+g_async_initable_new_finish
+g_async_initable_new_valist_async
+g_async_initable_newv_async
+<SUBSECTION Standard>
+G_ASYNC_INITABLE
+G_ASYNC_INITABLE_GET_IFACE
+G_IS_ASYNC_INITABLE
+G_TYPE_ASYNC_INITABLE
+G_TYPE_IS_ASYNC_INITABLE
+<SUBSECTION Private>
+g_async_initable_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gvfs</FILE>
+<TITLE>GVfs</TITLE>
+GVfs
+GVfsFileLookupFunc
+G_VFS_EXTENSION_POINT_NAME
+g_vfs_get_file_for_path
+g_vfs_get_file_for_uri
+g_vfs_parse_name
+g_vfs_get_default
+g_vfs_get_local
+g_vfs_is_active
+g_vfs_get_supported_uri_schemes
+g_vfs_register_uri_scheme
+g_vfs_unregister_uri_scheme
+<SUBSECTION Standard>
+GVfsClass
+G_VFS
+G_IS_VFS
+G_TYPE_VFS
+G_VFS_CLASS
+G_IS_VFS_CLASS
+G_VFS_GET_CLASS
+<SUBSECTION Private>
+g_vfs_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfile</FILE>
+<TITLE>GFile</TITLE>
+GFile
+GFileIface
+GFileQueryInfoFlags
+GFileCreateFlags
+GFileCopyFlags
+GFileMonitorFlags
+GFileMeasureFlags
+GFilesystemPreviewType
+GFileProgressCallback
+GFileReadMoreCallback
+GFileMeasureProgressCallback
+g_file_new_for_path
+g_file_new_for_uri
+g_file_new_for_commandline_arg
+g_file_new_for_commandline_arg_and_cwd
+g_file_new_tmp
+g_file_parse_name
+g_file_new_build_filename
+g_file_dup
+g_file_hash
+g_file_equal
+g_file_get_basename
+g_file_get_path
+g_file_peek_path
+g_file_get_uri
+g_file_get_parse_name
+g_file_get_parent
+g_file_has_parent
+g_file_get_child
+g_file_get_child_for_display_name
+g_file_has_prefix
+g_file_get_relative_path
+g_file_resolve_relative_path
+g_file_is_native
+g_file_has_uri_scheme
+g_file_get_uri_scheme
+g_file_read
+g_file_read_async
+g_file_read_finish
+g_file_append_to
+g_file_create
+g_file_replace
+g_file_append_to_async
+g_file_append_to_finish
+g_file_create_async
+g_file_create_finish
+g_file_replace_async
+g_file_replace_finish
+g_file_query_info
+g_file_query_info_async
+g_file_query_info_finish
+g_file_query_exists
+g_file_query_file_type
+g_file_query_filesystem_info
+g_file_query_filesystem_info_async
+g_file_query_filesystem_info_finish
+g_file_query_default_handler
+g_file_query_default_handler_async
+g_file_query_default_handler_finish
+g_file_measure_disk_usage
+g_file_measure_disk_usage_async
+g_file_measure_disk_usage_finish
+g_file_find_enclosing_mount
+g_file_find_enclosing_mount_async
+g_file_find_enclosing_mount_finish
+g_file_enumerate_children
+g_file_enumerate_children_async
+g_file_enumerate_children_finish
+g_file_set_display_name
+g_file_set_display_name_async
+g_file_set_display_name_finish
+g_file_delete
+g_file_delete_async
+g_file_delete_finish
+g_file_trash
+g_file_trash_async
+g_file_trash_finish
+g_file_copy
+g_file_copy_async
+g_file_copy_finish
+g_file_move
+g_file_make_directory
+g_file_make_directory_async
+g_file_make_directory_finish
+g_file_make_directory_with_parents
+g_file_make_symbolic_link
+g_file_query_settable_attributes
+g_file_query_writable_namespaces
+g_file_set_attribute
+g_file_set_attributes_from_info
+g_file_set_attributes_async
+g_file_set_attributes_finish
+g_file_set_attribute_string
+g_file_set_attribute_byte_string
+g_file_set_attribute_uint32
+g_file_set_attribute_int32
+g_file_set_attribute_uint64
+g_file_set_attribute_int64
+g_file_mount_mountable
+g_file_mount_mountable_finish
+g_file_unmount_mountable
+g_file_unmount_mountable_finish
+g_file_unmount_mountable_with_operation
+g_file_unmount_mountable_with_operation_finish
+g_file_eject_mountable
+g_file_eject_mountable_finish
+g_file_eject_mountable_with_operation
+g_file_eject_mountable_with_operation_finish
+g_file_start_mountable
+g_file_start_mountable_finish
+g_file_stop_mountable
+g_file_stop_mountable_finish
+g_file_poll_mountable
+g_file_poll_mountable_finish
+g_file_mount_enclosing_volume
+g_file_mount_enclosing_volume_finish
+g_file_monitor_directory
+g_file_monitor_file
+g_file_monitor
+g_file_load_bytes
+g_file_load_bytes_async
+g_file_load_bytes_finish
+g_file_load_contents
+g_file_load_contents_async
+g_file_load_contents_finish
+g_file_load_partial_contents_async
+g_file_load_partial_contents_finish
+g_file_replace_contents
+g_file_replace_contents_async
+g_file_replace_contents_bytes_async
+g_file_replace_contents_finish
+g_file_copy_attributes
+g_file_create_readwrite
+g_file_create_readwrite_async
+g_file_create_readwrite_finish
+g_file_open_readwrite
+g_file_open_readwrite_async
+g_file_open_readwrite_finish
+g_file_replace_readwrite
+g_file_replace_readwrite_async
+g_file_replace_readwrite_finish
+g_file_supports_thread_contexts
+<SUBSECTION Standard>
+G_FILE
+G_IS_FILE
+G_TYPE_FILE
+G_FILE_GET_IFACE
+G_TYPE_FILESYSTEM_PREVIEW_TYPE
+G_TYPE_FILE_COPY_FLAGS
+G_TYPE_FILE_CREATE_FLAGS
+G_TYPE_FILE_MEASURE_FLAGS
+G_TYPE_FILE_MONITOR_EVENT
+G_TYPE_FILE_MONITOR_FLAGS
+G_TYPE_FILE_QUERY_INFO_FLAGS
+<SUBSECTION Private>
+g_file_get_type
+g_file_copy_flags_get_type
+g_file_create_flags_get_type
+g_file_measure_flags_get_type
+g_file_monitor_event_get_type
+g_file_monitor_flags_get_type
+g_file_query_info_flags_get_type
+g_filesystem_preview_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfileenumerator</FILE>
+<TITLE>GFileEnumerator</TITLE>
+GFileEnumerator
+g_file_enumerator_iterate
+g_file_enumerator_next_file
+g_file_enumerator_close
+g_file_enumerator_next_files_async
+g_file_enumerator_next_files_finish
+g_file_enumerator_close_async
+g_file_enumerator_close_finish
+g_file_enumerator_is_closed
+g_file_enumerator_has_pending
+g_file_enumerator_set_pending
+g_file_enumerator_get_container
+g_file_enumerator_get_child
+<SUBSECTION Standard>
+GFileEnumeratorClass
+G_FILE_ENUMERATOR
+G_IS_FILE_ENUMERATOR
+G_TYPE_FILE_ENUMERATOR
+G_FILE_ENUMERATOR_CLASS
+G_IS_FILE_ENUMERATOR_CLASS
+G_FILE_ENUMERATOR_GET_CLASS
+<SUBSECTION Private>
+g_file_enumerator_get_type
+GFileEnumeratorPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gfileinfo</FILE>
+<TITLE>GFileInfo</TITLE>
+GFileAttributeMatcher
+GFileType
+GFileInfo
+G_FILE_ATTRIBUTE_STANDARD_TYPE
+G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN
+G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP
+G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK
+G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL
+G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE
+G_FILE_ATTRIBUTE_STANDARD_NAME
+G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
+G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME
+G_FILE_ATTRIBUTE_STANDARD_COPY_NAME
+G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION
+G_FILE_ATTRIBUTE_STANDARD_ICON
+G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON
+G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
+G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE
+G_FILE_ATTRIBUTE_STANDARD_SIZE
+G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE
+G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET
+G_FILE_ATTRIBUTE_STANDARD_TARGET_URI
+G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER
+G_FILE_ATTRIBUTE_ETAG_VALUE
+G_FILE_ATTRIBUTE_ID_FILE
+G_FILE_ATTRIBUTE_ID_FILESYSTEM
+G_FILE_ATTRIBUTE_ACCESS_CAN_READ
+G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
+G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE
+G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE
+G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH
+G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
+G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE
+G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE
+G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP
+G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL
+G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC
+G_FILE_ATTRIBUTE_TIME_MODIFIED
+G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC
+G_FILE_ATTRIBUTE_TIME_ACCESS
+G_FILE_ATTRIBUTE_TIME_ACCESS_USEC
+G_FILE_ATTRIBUTE_TIME_CHANGED
+G_FILE_ATTRIBUTE_TIME_CHANGED_USEC
+G_FILE_ATTRIBUTE_TIME_CREATED
+G_FILE_ATTRIBUTE_TIME_CREATED_USEC
+G_FILE_ATTRIBUTE_UNIX_DEVICE
+G_FILE_ATTRIBUTE_UNIX_INODE
+G_FILE_ATTRIBUTE_UNIX_MODE
+G_FILE_ATTRIBUTE_UNIX_NLINK
+G_FILE_ATTRIBUTE_UNIX_UID
+G_FILE_ATTRIBUTE_UNIX_GID
+G_FILE_ATTRIBUTE_UNIX_RDEV
+G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE
+G_FILE_ATTRIBUTE_UNIX_BLOCKS
+G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT
+G_FILE_ATTRIBUTE_DOS_IS_ARCHIVE
+G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT
+G_FILE_ATTRIBUTE_DOS_IS_SYSTEM
+G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG
+G_FILE_ATTRIBUTE_OWNER_USER
+G_FILE_ATTRIBUTE_OWNER_USER_REAL
+G_FILE_ATTRIBUTE_OWNER_GROUP
+G_FILE_ATTRIBUTE_THUMBNAIL_PATH
+G_FILE_ATTRIBUTE_THUMBNAILING_FAILED
+G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID
+G_FILE_ATTRIBUTE_PREVIEW_ICON
+G_FILE_ATTRIBUTE_FILESYSTEM_SIZE
+G_FILE_ATTRIBUTE_FILESYSTEM_FREE
+G_FILE_ATTRIBUTE_FILESYSTEM_USED
+G_FILE_ATTRIBUTE_FILESYSTEM_TYPE
+G_FILE_ATTRIBUTE_FILESYSTEM_READONLY
+G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW
+G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE
+G_FILE_ATTRIBUTE_GVFS_BACKEND
+G_FILE_ATTRIBUTE_SELINUX_CONTEXT
+G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT
+G_FILE_ATTRIBUTE_TRASH_ORIG_PATH
+G_FILE_ATTRIBUTE_TRASH_DELETION_DATE
+G_FILE_ATTRIBUTE_RECENT_MODIFIED
+g_file_info_new
+g_file_info_dup
+g_file_info_copy_into
+g_file_info_has_attribute
+g_file_info_has_namespace
+g_file_info_list_attributes
+g_file_info_get_attribute_type
+g_file_info_remove_attribute
+g_file_info_get_attribute_as_string
+g_file_info_get_attribute_data
+g_file_info_get_attribute_status
+g_file_info_get_attribute_string
+g_file_info_get_attribute_stringv
+g_file_info_get_attribute_byte_string
+g_file_info_get_attribute_boolean
+g_file_info_get_attribute_uint32
+g_file_info_get_attribute_int32
+g_file_info_get_attribute_uint64
+g_file_info_get_attribute_int64
+g_file_info_get_attribute_object
+g_file_info_set_attribute
+g_file_info_set_attribute_status
+g_file_info_set_attribute_string
+g_file_info_set_attribute_stringv
+g_file_info_set_attribute_byte_string
+g_file_info_set_attribute_boolean
+g_file_info_set_attribute_uint32
+g_file_info_set_attribute_int32
+g_file_info_set_attribute_uint64
+g_file_info_set_attribute_int64
+g_file_info_set_attribute_object
+g_file_info_clear_status
+g_file_info_get_file_type
+g_file_info_get_is_hidden
+g_file_info_get_is_backup
+g_file_info_get_is_symlink
+g_file_info_get_name
+g_file_info_get_display_name
+g_file_info_get_edit_name
+g_file_info_get_icon
+g_file_info_get_symbolic_icon
+g_file_info_get_content_type
+g_file_info_get_size
+g_file_info_get_modification_time
+g_file_info_get_modification_date_time
+g_file_info_get_symlink_target
+g_file_info_get_etag
+g_file_info_get_sort_order
+g_file_info_get_deletion_date
+g_file_info_set_attribute_mask
+g_file_info_unset_attribute_mask
+g_file_info_set_file_type
+g_file_info_set_is_hidden
+g_file_info_set_is_symlink
+g_file_info_set_name
+g_file_info_set_display_name
+g_file_info_set_edit_name
+g_file_info_set_icon
+g_file_info_set_symbolic_icon
+g_file_info_set_content_type
+g_file_info_set_size
+g_file_info_set_modification_time
+g_file_info_set_modification_date_time
+g_file_info_set_symlink_target
+g_file_info_set_sort_order
+g_file_attribute_matcher_new
+g_file_attribute_matcher_ref
+g_file_attribute_matcher_subtract
+g_file_attribute_matcher_unref
+g_file_attribute_matcher_matches
+g_file_attribute_matcher_matches_only
+g_file_attribute_matcher_enumerate_namespace
+g_file_attribute_matcher_enumerate_next
+g_file_attribute_matcher_to_string
+<SUBSECTION Standard>
+GFileInfoClass
+G_FILE_INFO
+G_IS_FILE_INFO
+G_TYPE_FILE_INFO
+G_FILE_INFO_CLASS
+G_IS_FILE_INFO_CLASS
+G_FILE_INFO_GET_CLASS
+g_file_attribute_matcher_get_type
+G_TYPE_FILE_TYPE
+<SUBSECTION Private>
+g_file_info_get_type
+g_file_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfileattribute</FILE>
+<TITLE>GFileAttribute</TITLE>
+GFileAttributeType
+GFileAttributeInfoFlags
+GFileAttributeStatus
+GFileAttributeInfo
+GFileAttributeInfoList
+g_file_attribute_info_list_new
+g_file_attribute_info_list_ref
+g_file_attribute_info_list_unref
+g_file_attribute_info_list_dup
+g_file_attribute_info_list_lookup
+g_file_attribute_info_list_add
+<SUBSECTION Standard>
+G_TYPE_FILE_ATTRIBUTE_INFO_FLAGS
+G_TYPE_FILE_ATTRIBUTE_INFO_LIST
+G_TYPE_FILE_ATTRIBUTE_MATCHER
+G_TYPE_FILE_ATTRIBUTE_STATUS
+G_TYPE_FILE_ATTRIBUTE_TYPE
+<SUBSECTION Private>
+g_file_attribute_info_list_get_type
+g_file_attribute_info_flags_get_type
+g_file_attribute_status_get_type
+g_file_attribute_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfilemonitor</FILE>
+<TITLE>GFileMonitor</TITLE>
+GFileMonitorEvent
+GFileMonitor
+g_file_monitor_cancel
+g_file_monitor_is_cancelled
+g_file_monitor_set_rate_limit
+g_file_monitor_emit_event
+<SUBSECTION Standard>
+GFileMonitorClass
+G_FILE_MONITOR
+G_IS_FILE_MONITOR
+G_TYPE_FILE_MONITOR
+G_FILE_MONITOR_CLASS
+G_IS_FILE_MONITOR_CLASS
+G_FILE_MONITOR_GET_CLASS
+<SUBSECTION Private>
+g_file_monitor_get_type
+GFileMonitorPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gicon</FILE>
+<TITLE>GIcon</TITLE>
+GIcon
+GIconIface
+g_icon_hash
+g_icon_equal
+g_icon_to_string
+g_icon_new_for_string
+g_icon_serialize
+g_icon_deserialize
+<SUBSECTION Standard>
+G_ICON
+G_IS_ICON
+G_TYPE_ICON
+G_ICON_GET_IFACE
+<SUBSECTION Private>
+g_icon_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gthemedicon</FILE>
+<TITLE>GThemedIcon</TITLE>
+GThemedIcon
+g_themed_icon_new
+g_themed_icon_new_from_names
+g_themed_icon_new_with_default_fallbacks
+g_themed_icon_prepend_name
+g_themed_icon_append_name
+g_themed_icon_get_names
+<SUBSECTION Standard>
+GThemedIconClass
+G_THEMED_ICON
+G_IS_THEMED_ICON
+G_TYPE_THEMED_ICON
+G_THEMED_ICON_CLASS
+G_IS_THEMED_ICON_CLASS
+G_THEMED_ICON_GET_CLASS
+<SUBSECTION Private>
+g_themed_icon_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gloadableicon</FILE>
+<TITLE>GLoadableIcon</TITLE>
+GLoadableIcon
+GLoadableIconIface
+g_loadable_icon_load
+g_loadable_icon_load_async
+g_loadable_icon_load_finish
+<SUBSECTION Standard>
+G_LOADABLE_ICON
+G_IS_LOADABLE_ICON
+G_TYPE_LOADABLE_ICON
+G_LOADABLE_ICON_GET_IFACE
+<SUBSECTION Private>
+g_loadable_icon_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfileicon</FILE>
+<TITLE>GFileIcon</TITLE>
+GFileIcon
+g_file_icon_new
+g_file_icon_get_file
+<SUBSECTION Standard>
+GFileIconClass
+G_FILE_ICON
+G_IS_FILE_ICON
+G_TYPE_FILE_ICON
+G_FILE_ICON_CLASS
+G_IS_FILE_ICON_CLASS
+G_FILE_ICON_GET_CLASS
+<SUBSECTION Private>
+g_file_icon_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gbytesicon</FILE>
+<TITLE>GBytesIcon</TITLE>
+GBytesIcon
+g_bytes_icon_new
+g_bytes_icon_get_bytes
+<SUBSECTION Standard>
+G_BYTES_ICON
+G_IS_BYTES_ICON
+G_TYPE_BYTES_ICON
+<SUBSECTION Private>
+g_bytes_icon_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gemblemedicon</FILE>
+<TITLE>GEmblemedIcon</TITLE>
+GEmblemedIcon
+g_emblemed_icon_new
+g_emblemed_icon_get_icon
+g_emblemed_icon_get_emblems
+g_emblemed_icon_add_emblem
+g_emblemed_icon_clear_emblems
+<SUBSECTION Standard>
+GEmblemedIconClass
+G_EMBLEMED_ICON
+G_EMBLEMED_ICON_CLASS
+G_EMBLEMED_ICON_GET_CLASS
+G_IS_EMBLEMED_ICON
+G_IS_EMBLEMED_ICON_CLASS
+G_TYPE_EMBLEMED_ICON
+
+<SUBSECTION Private>
+GEmblemedIconPrivate
+g_emblemed_icon_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gemblem</FILE>
+<TITLE>GEmblem</TITLE>
+GEmblem
+GEmblemOrigin
+g_emblem_new
+g_emblem_new_with_origin
+g_emblem_get_icon
+g_emblem_get_origin
+<SUBSECTION Private>
+GEmblemClass
+g_emblem_get_type
+G_EMBLEM
+G_EMBLEM_CLASS
+G_EMBLEM_GET_CLASS
+G_IS_EMBLEM
+G_IS_EMBLEM_CLASS
+G_TYPE_EMBLEM
+G_TYPE_EMBLEM_ORIGIN
+g_emblem_origin_get_type
+</SECTION>
+
+<SECTION>
+<FILE>ginputstream</FILE>
+<TITLE>GInputStream</TITLE>
+GInputStream
+g_input_stream_read
+g_input_stream_read_all
+g_input_stream_read_all_async
+g_input_stream_read_all_finish
+g_input_stream_skip
+g_input_stream_close
+g_input_stream_read_async
+g_input_stream_read_finish
+g_input_stream_skip_async
+g_input_stream_skip_finish
+g_input_stream_close_async
+g_input_stream_close_finish
+g_input_stream_is_closed
+g_input_stream_has_pending
+g_input_stream_set_pending
+g_input_stream_clear_pending
+g_input_stream_read_bytes
+g_input_stream_read_bytes_async
+g_input_stream_read_bytes_finish
+<SUBSECTION Standard>
+GInputStreamClass
+G_INPUT_STREAM
+G_IS_INPUT_STREAM
+G_TYPE_INPUT_STREAM
+G_INPUT_STREAM_CLASS
+G_IS_INPUT_STREAM_CLASS
+G_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_input_stream_get_type
+GInputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gfileinputstream</FILE>
+<TITLE>GFileInputStream</TITLE>
+GFileInputStream
+g_file_input_stream_query_info
+g_file_input_stream_query_info_async
+g_file_input_stream_query_info_finish
+<SUBSECTION Standard>
+GFileInputStreamClass
+G_FILE_INPUT_STREAM
+G_IS_FILE_INPUT_STREAM
+G_TYPE_FILE_INPUT_STREAM
+G_FILE_INPUT_STREAM_CLASS
+G_IS_FILE_INPUT_STREAM_CLASS
+G_FILE_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_file_input_stream_get_type
+GFileInputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gfilterinputstream</FILE>
+<TITLE>GFilterInputStream</TITLE>
+GFilterInputStream
+g_filter_input_stream_get_base_stream
+g_filter_input_stream_get_close_base_stream
+g_filter_input_stream_set_close_base_stream
+<SUBSECTION Standard>
+GFilterInputStreamClass
+G_FILTER_INPUT_STREAM
+G_IS_FILTER_INPUT_STREAM
+G_TYPE_FILTER_INPUT_STREAM
+G_FILTER_INPUT_STREAM_CLASS
+G_IS_FILTER_INPUT_STREAM_CLASS
+G_FILTER_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_filter_input_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixinputstream</FILE>
+<TITLE>GUnixInputStream</TITLE>
+GUnixInputStream
+g_unix_input_stream_new
+g_unix_input_stream_set_close_fd
+g_unix_input_stream_get_close_fd
+g_unix_input_stream_get_fd
+<SUBSECTION Standard>
+GUnixInputStreamClass
+G_UNIX_INPUT_STREAM
+G_IS_UNIX_INPUT_STREAM
+G_TYPE_UNIX_INPUT_STREAM
+G_UNIX_INPUT_STREAM_CLASS
+G_IS_UNIX_INPUT_STREAM_CLASS
+G_UNIX_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_unix_input_stream_get_type
+GUnixInputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gmemoryinputstream</FILE>
+<TITLE>GMemoryInputStream</TITLE>
+GMemoryInputStream
+g_memory_input_stream_new
+g_memory_input_stream_new_from_data
+g_memory_input_stream_new_from_bytes
+g_memory_input_stream_add_data
+g_memory_input_stream_add_bytes
+<SUBSECTION Standard>
+GMemoryInputStreamClass
+G_MEMORY_INPUT_STREAM
+G_IS_MEMORY_INPUT_STREAM
+G_TYPE_MEMORY_INPUT_STREAM
+G_MEMORY_INPUT_STREAM_CLASS
+G_IS_MEMORY_INPUT_STREAM_CLASS
+G_MEMORY_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+GMemoryInputStreamPrivate
+g_memory_input_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdatainputstream</FILE>
+<TITLE>GDataInputStream</TITLE>
+GDataInputStream
+GDataStreamByteOrder
+GDataStreamNewlineType
+g_data_input_stream_new
+g_data_input_stream_set_byte_order
+g_data_input_stream_get_byte_order
+g_data_input_stream_set_newline_type
+g_data_input_stream_get_newline_type
+g_data_input_stream_read_byte
+g_data_input_stream_read_int16
+g_data_input_stream_read_uint16
+g_data_input_stream_read_int32
+g_data_input_stream_read_uint32
+g_data_input_stream_read_int64
+g_data_input_stream_read_uint64
+g_data_input_stream_read_line
+g_data_input_stream_read_line_utf8
+g_data_input_stream_read_line_async
+g_data_input_stream_read_line_finish
+g_data_input_stream_read_line_finish_utf8
+g_data_input_stream_read_upto
+g_data_input_stream_read_upto_async
+g_data_input_stream_read_upto_finish
+g_data_input_stream_read_until
+g_data_input_stream_read_until_async
+g_data_input_stream_read_until_finish
+<SUBSECTION Standard>
+GDataInputStreamClass
+G_DATA_INPUT_STREAM
+G_IS_DATA_INPUT_STREAM
+G_TYPE_DATA_INPUT_STREAM
+G_DATA_INPUT_STREAM_CLASS
+G_IS_DATA_INPUT_STREAM_CLASS
+G_DATA_INPUT_STREAM_GET_CLASS
+G_TYPE_DATA_STREAM_BYTE_ORDER
+G_TYPE_DATA_STREAM_NEWLINE_TYPE
+<SUBSECTION Private>
+g_data_input_stream_get_type
+GDataInputStreamPrivate
+g_data_stream_byte_order_get_type
+g_data_stream_newline_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gbufferedinputstream</FILE>
+<TITLE>GBufferedInputStream</TITLE>
+GBufferedInputStream
+g_buffered_input_stream_new
+g_buffered_input_stream_new_sized
+g_buffered_input_stream_get_buffer_size
+g_buffered_input_stream_set_buffer_size
+g_buffered_input_stream_get_available
+g_buffered_input_stream_peek_buffer
+g_buffered_input_stream_peek
+g_buffered_input_stream_fill
+g_buffered_input_stream_fill_async
+g_buffered_input_stream_fill_finish
+g_buffered_input_stream_read_byte
+<SUBSECTION Standard>
+GBufferedInputStreamClass
+G_BUFFERED_INPUT_STREAM
+G_IS_BUFFERED_INPUT_STREAM
+G_TYPE_BUFFERED_INPUT_STREAM
+G_BUFFERED_INPUT_STREAM_CLASS
+G_IS_BUFFERED_INPUT_STREAM_CLASS
+G_BUFFERED_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_buffered_input_stream_get_type
+GBufferedInputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>goutputstream</FILE>
+<TITLE>GOutputStream</TITLE>
+GOutputStreamSpliceFlags
+GOutputStream
+g_output_stream_write
+g_output_stream_write_all
+g_output_stream_write_all_async
+g_output_stream_write_all_finish
+g_output_stream_writev
+g_output_stream_writev_all
+g_output_stream_writev_async
+g_output_stream_writev_finish
+g_output_stream_writev_all_async
+g_output_stream_writev_all_finish
+g_output_stream_splice
+g_output_stream_flush
+g_output_stream_close
+g_output_stream_write_async
+g_output_stream_write_finish
+g_output_stream_splice_async
+g_output_stream_splice_finish
+g_output_stream_flush_async
+g_output_stream_flush_finish
+g_output_stream_close_async
+g_output_stream_close_finish
+g_output_stream_is_closing
+g_output_stream_is_closed
+g_output_stream_has_pending
+g_output_stream_set_pending
+g_output_stream_clear_pending
+g_output_stream_write_bytes
+g_output_stream_write_bytes_async
+g_output_stream_write_bytes_finish
+g_output_stream_printf
+g_output_stream_vprintf
+<SUBSECTION Standard>
+GOutputStreamClass
+G_OUTPUT_STREAM
+G_IS_OUTPUT_STREAM
+G_TYPE_OUTPUT_STREAM
+G_OUTPUT_STREAM_CLASS
+G_IS_OUTPUT_STREAM_CLASS
+G_OUTPUT_STREAM_GET_CLASS
+G_TYPE_OUTPUT_STREAM_SPLICE_FLAGS
+<SUBSECTION Private>
+g_output_stream_get_type
+GOutputStreamPrivate
+g_output_stream_splice_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfileoutputstream</FILE>
+<TITLE>GFileOutputStream</TITLE>
+GFileOutputStream
+g_file_output_stream_query_info
+g_file_output_stream_query_info_async
+g_file_output_stream_query_info_finish
+g_file_output_stream_get_etag
+<SUBSECTION Standard>
+GFileOutputStreamClass
+G_FILE_OUTPUT_STREAM
+G_IS_FILE_OUTPUT_STREAM
+G_TYPE_FILE_OUTPUT_STREAM
+G_FILE_OUTPUT_STREAM_CLASS
+G_IS_FILE_OUTPUT_STREAM_CLASS
+G_FILE_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_file_output_stream_get_type
+GFileOutputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gfilteroutputstream</FILE>
+<TITLE>GFilterOutputStream</TITLE>
+GFilterOutputStream
+g_filter_output_stream_get_base_stream
+g_filter_output_stream_get_close_base_stream
+g_filter_output_stream_set_close_base_stream
+<SUBSECTION Standard>
+GFilterOutputStreamClass
+G_FILTER_OUTPUT_STREAM
+G_IS_FILTER_OUTPUT_STREAM
+G_TYPE_FILTER_OUTPUT_STREAM
+G_FILTER_OUTPUT_STREAM_CLASS
+G_IS_FILTER_OUTPUT_STREAM_CLASS
+G_FILTER_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_filter_output_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gbufferedoutputstream</FILE>
+<TITLE>GBufferedOutputStream</TITLE>
+GBufferedOutputStream
+g_buffered_output_stream_new
+g_buffered_output_stream_new_sized
+g_buffered_output_stream_get_buffer_size
+g_buffered_output_stream_set_buffer_size
+g_buffered_output_stream_get_auto_grow
+g_buffered_output_stream_set_auto_grow
+<SUBSECTION Standard>
+GBufferedOutputStreamClass
+G_BUFFERED_OUTPUT_STREAM
+G_IS_BUFFERED_OUTPUT_STREAM
+G_TYPE_BUFFERED_OUTPUT_STREAM
+G_BUFFERED_OUTPUT_STREAM_CLASS
+G_IS_BUFFERED_OUTPUT_STREAM_CLASS
+G_BUFFERED_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_buffered_output_stream_get_type
+GBufferedOutputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gmemoryoutputstream</FILE>
+<TITLE>GMemoryOutputStream</TITLE>
+GReallocFunc
+GMemoryOutputStream
+g_memory_output_stream_new
+g_memory_output_stream_new_resizable
+g_memory_output_stream_get_data
+g_memory_output_stream_get_size
+g_memory_output_stream_get_data_size
+g_memory_output_stream_steal_data
+g_memory_output_stream_steal_as_bytes
+<SUBSECTION Standard>
+GMemoryOutputStreamClass
+G_MEMORY_OUTPUT_STREAM
+G_IS_MEMORY_OUTPUT_STREAM
+G_TYPE_MEMORY_OUTPUT_STREAM
+G_MEMORY_OUTPUT_STREAM_CLASS
+G_IS_MEMORY_OUTPUT_STREAM_CLASS
+G_MEMORY_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_memory_output_stream_get_type
+GMemoryOutputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gdataoutputstream</FILE>
+<TITLE>GDataOutputStream</TITLE>
+GDataOutputStream
+g_data_output_stream_new
+g_data_output_stream_set_byte_order
+g_data_output_stream_get_byte_order
+g_data_output_stream_put_byte
+g_data_output_stream_put_int16
+g_data_output_stream_put_uint16
+g_data_output_stream_put_int32
+g_data_output_stream_put_uint32
+g_data_output_stream_put_int64
+g_data_output_stream_put_uint64
+g_data_output_stream_put_string
+<SUBSECTION Standard>
+GDataOutputStreamClass
+G_DATA_OUTPUT_STREAM
+G_IS_DATA_OUTPUT_STREAM
+G_TYPE_DATA_OUTPUT_STREAM
+G_DATA_OUTPUT_STREAM_CLASS
+G_IS_DATA_OUTPUT_STREAM_CLASS
+G_DATA_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_data_output_stream_get_type
+GDataOutputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gunixoutputstream</FILE>
+<TITLE>GUnixOutputStream</TITLE>
+GUnixOutputStream
+g_unix_output_stream_new
+g_unix_output_stream_set_close_fd
+g_unix_output_stream_get_close_fd
+g_unix_output_stream_get_fd
+<SUBSECTION Standard>
+GUnixOutputStreamClass
+G_UNIX_OUTPUT_STREAM
+G_IS_UNIX_OUTPUT_STREAM
+G_TYPE_UNIX_OUTPUT_STREAM
+G_UNIX_OUTPUT_STREAM_CLASS
+G_IS_UNIX_OUTPUT_STREAM_CLASS
+G_UNIX_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_unix_output_stream_get_type
+GUnixOutputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>giostream</FILE>
+<TITLE>GIOStream</TITLE>
+GIOStreamSpliceFlags
+GIOStream
+g_io_stream_get_input_stream
+g_io_stream_get_output_stream
+g_io_stream_splice_async
+g_io_stream_splice_finish
+g_io_stream_close
+g_io_stream_close_async
+g_io_stream_close_finish
+g_io_stream_is_closed
+g_io_stream_has_pending
+g_io_stream_set_pending
+g_io_stream_clear_pending
+<SUBSECTION Standard>
+GIOStreamClass
+G_IO_STREAM
+G_IO_STREAM_CLASS
+G_IO_STREAM_GET_CLASS
+G_IS_IO_STREAM
+G_IS_IO_STREAM_CLASS
+G_TYPE_IO_STREAM
+G_TYPE_IO_STREAM_SPLICE_FLAGS
+<SUBSECTION Private>
+GIOStreamPrivate
+GIOStreamAdapter
+g_io_stream_get_type
+g_io_stream_splice_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsimpleiostream</FILE>
+<TITLE>GSimpleIOStream</TITLE>
+GSimpleIOStream
+g_simple_io_stream_new
+<SUBSECTION Standard>
+GIOStreamClass
+G_TYPE_SIMPLE_IO_STREAM
+G_IS_SIMPLE_IO_STREAM
+G_SIMPLE_IO_STREAM
+<SUBSECTION Private>
+g_simple_io_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfileiostream</FILE>
+<TITLE>GFileIOStream</TITLE>
+GFileIOStream
+g_file_io_stream_get_etag
+g_file_io_stream_query_info
+g_file_io_stream_query_info_async
+g_file_io_stream_query_info_finish
+<SUBSECTION Standard>
+GFileIOStreamClass
+G_FILE_IO_STREAM
+G_FILE_IO_STREAM_CLASS
+G_FILE_IO_STREAM_GET_CLASS
+G_IS_FILE_IO_STREAM
+G_IS_FILE_IO_STREAM_CLASS
+G_TYPE_FILE_IO_STREAM
+<SUBSECTION Private>
+GFileIOStreamPrivate
+g_file_io_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gseekable</FILE>
+<TITLE>GSeekable</TITLE>
+GSeekable
+GSeekableIface
+g_seekable_tell
+g_seekable_can_seek
+g_seekable_seek
+g_seekable_can_truncate
+g_seekable_truncate
+<SUBSECTION Standard>
+G_SEEKABLE
+G_IS_SEEKABLE
+G_TYPE_SEEKABLE
+G_SEEKABLE_GET_IFACE
+<SUBSECTION Private>
+g_seekable_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gvolumemonitor</FILE>
+<TITLE>GVolumeMonitor</TITLE>
+GVolumeMonitor
+G_VOLUME_MONITOR_EXTENSION_POINT_NAME
+g_volume_monitor_get
+g_volume_monitor_get_connected_drives
+g_volume_monitor_get_volumes
+g_volume_monitor_get_mounts
+g_volume_monitor_adopt_orphan_mount
+g_volume_monitor_get_mount_for_uuid
+g_volume_monitor_get_volume_for_uuid
+<SUBSECTION Standard>
+GVolumeMonitorClass
+G_VOLUME_MONITOR
+G_IS_VOLUME_MONITOR
+G_TYPE_VOLUME_MONITOR
+G_VOLUME_MONITOR_CLASS
+G_IS_VOLUME_MONITOR_CLASS
+G_VOLUME_MONITOR_GET_CLASS
+<SUBSECTION Private>
+g_volume_monitor_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gmount</FILE>
+<TITLE>GMount</TITLE>
+GMount
+GMountIface
+g_mount_get_name
+g_mount_get_uuid
+g_mount_get_icon
+g_mount_get_symbolic_icon
+g_mount_get_drive
+g_mount_get_root
+g_mount_get_volume
+g_mount_get_default_location
+g_mount_can_unmount
+GMountMountFlags
+GMountUnmountFlags
+g_mount_unmount
+g_mount_unmount_finish
+g_mount_unmount_with_operation
+g_mount_unmount_with_operation_finish
+g_mount_remount
+g_mount_remount_finish
+g_mount_can_eject
+g_mount_eject
+g_mount_eject_finish
+g_mount_eject_with_operation
+g_mount_eject_with_operation_finish
+g_mount_guess_content_type
+g_mount_guess_content_type_finish
+g_mount_guess_content_type_sync
+g_mount_is_shadowed
+g_mount_shadow
+g_mount_unshadow
+g_mount_get_sort_key
+<SUBSECTION Standard>
+G_IS_MOUNT
+G_MOUNT
+G_MOUNT_GET_IFACE
+G_TYPE_MOUNT
+G_TYPE_MOUNT_MOUNT_FLAGS
+G_TYPE_MOUNT_UNMOUNT_FLAGS
+<SUBSECTION Private>
+g_mount_get_type
+g_mount_mount_flags_get_type
+g_mount_unmount_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gvolume</FILE>
+<TITLE>GVolume</TITLE>
+GVolume
+GVolumeIface
+g_volume_get_name
+g_volume_get_uuid
+g_volume_get_icon
+g_volume_get_symbolic_icon
+g_volume_get_drive
+g_volume_get_mount
+g_volume_can_mount
+g_volume_should_automount
+g_volume_get_activation_root
+g_volume_mount
+g_volume_mount_finish
+g_volume_can_eject
+g_volume_eject
+g_volume_eject_finish
+g_volume_eject_with_operation
+g_volume_eject_with_operation_finish
+G_VOLUME_IDENTIFIER_KIND_HAL_UDI
+G_VOLUME_IDENTIFIER_KIND_LABEL
+G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT
+G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE
+G_VOLUME_IDENTIFIER_KIND_UUID
+G_VOLUME_IDENTIFIER_KIND_CLASS
+g_volume_enumerate_identifiers
+g_volume_get_identifier
+g_volume_get_sort_key
+<SUBSECTION Standard>
+G_VOLUME
+G_IS_VOLUME
+G_TYPE_VOLUME
+G_VOLUME_GET_IFACE
+<SUBSECTION Private>
+g_volume_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdrive</FILE>
+<TITLE>GDrive</TITLE>
+GDrive
+GDriveIface
+GDriveStartFlags
+GDriveStartStopType
+g_drive_get_name
+g_drive_get_icon
+g_drive_get_symbolic_icon
+g_drive_has_volumes
+g_drive_get_volumes
+g_drive_can_eject
+g_drive_get_start_stop_type
+g_drive_can_start
+g_drive_can_start_degraded
+g_drive_can_stop
+g_drive_can_poll_for_media
+g_drive_poll_for_media
+g_drive_poll_for_media_finish
+g_drive_has_media
+g_drive_is_media_check_automatic
+g_drive_is_removable
+g_drive_is_media_removable
+g_drive_eject
+g_drive_eject_finish
+g_drive_eject_with_operation
+g_drive_eject_with_operation_finish
+g_drive_start
+g_drive_start_finish
+g_drive_stop
+g_drive_stop_finish
+g_drive_enumerate_identifiers
+g_drive_get_identifier
+g_drive_get_sort_key
+G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE
+<SUBSECTION Standard>
+G_DRIVE
+G_IS_DRIVE
+G_TYPE_DRIVE
+G_DRIVE_GET_IFACE
+G_TYPE_DRIVE_START_FLAGS
+G_TYPE_DRIVE_START_STOP_TYPE
+<SUBSECTION Private>
+g_drive_get_type
+g_drive_start_flags_get_type
+g_drive_start_stop_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gcancellable</FILE>
+<TITLE>GCancellable</TITLE>
+GCancellable
+g_cancellable_new
+g_cancellable_is_cancelled
+g_cancellable_set_error_if_cancelled
+g_cancellable_get_fd
+g_cancellable_make_pollfd
+g_cancellable_release_fd
+g_cancellable_source_new
+GCancellableSourceFunc
+g_cancellable_get_current
+g_cancellable_pop_current
+g_cancellable_push_current
+g_cancellable_reset
+g_cancellable_connect
+g_cancellable_disconnect
+g_cancellable_cancel
+<SUBSECTION Standard>
+GCancellableClass
+G_CANCELLABLE
+G_IS_CANCELLABLE
+G_TYPE_CANCELLABLE
+G_CANCELLABLE_CLASS
+G_IS_CANCELLABLE_CLASS
+G_CANCELLABLE_GET_CLASS
+<SUBSECTION Private>
+GCancellablePrivate
+g_cancellable_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gasyncresult</FILE>
+<TITLE>GAsyncResult</TITLE>
+GAsyncResult
+GAsyncResultIface
+GAsyncReadyCallback
+g_async_result_get_user_data
+g_async_result_get_source_object
+g_async_result_is_tagged
+g_async_result_legacy_propagate_error
+<SUBSECTION Standard>
+G_ASYNC_RESULT
+G_IS_ASYNC_RESULT
+G_TYPE_ASYNC_RESULT
+G_ASYNC_RESULT_GET_IFACE
+<SUBSECTION Private>
+g_async_result_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsimpleasyncresult</FILE>
+<TITLE>GSimpleAsyncResult</TITLE>
+GSimpleAsyncResult
+GSimpleAsyncThreadFunc
+g_simple_async_result_new
+g_simple_async_result_new_error
+g_simple_async_result_new_from_error
+g_simple_async_result_new_take_error
+g_simple_async_result_set_check_cancellable
+g_simple_async_result_set_op_res_gpointer
+g_simple_async_result_get_op_res_gpointer
+g_simple_async_result_set_op_res_gssize
+g_simple_async_result_get_op_res_gssize
+g_simple_async_result_set_op_res_gboolean
+g_simple_async_result_get_op_res_gboolean
+g_simple_async_result_get_source_tag
+g_simple_async_result_is_valid
+g_simple_async_result_set_handle_cancellation
+g_simple_async_result_complete
+g_simple_async_result_complete_in_idle
+g_simple_async_result_run_in_thread
+g_simple_async_result_set_from_error
+g_simple_async_result_take_error
+g_simple_async_result_propagate_error
+g_simple_async_result_set_error
+g_simple_async_result_set_error_va
+g_simple_async_report_error_in_idle
+g_simple_async_report_gerror_in_idle
+g_simple_async_report_take_gerror_in_idle
+<SUBSECTION Standard>
+GSimpleAsyncResultClass
+G_SIMPLE_ASYNC_RESULT
+G_IS_SIMPLE_ASYNC_RESULT
+G_TYPE_SIMPLE_ASYNC_RESULT
+G_SIMPLE_ASYNC_RESULT_CLASS
+G_IS_SIMPLE_ASYNC_RESULT_CLASS
+G_SIMPLE_ASYNC_RESULT_GET_CLASS
+<SUBSECTION Private>
+g_simple_async_result_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gioscheduler</FILE>
+<TITLE>GIOScheduler</TITLE>
+GIOSchedulerJob
+GIOSchedulerJobFunc
+g_io_scheduler_push_job
+g_io_scheduler_cancel_all_jobs
+g_io_scheduler_job_send_to_mainloop
+g_io_scheduler_job_send_to_mainloop_async
+</SECTION>
+
+<SECTION>
+<FILE>gioerror</FILE>
+<TITLE>GIOError</TITLE>
+G_IO_ERROR
+GIOErrorEnum
+g_io_error_from_errno
+g_io_error_from_win32_error
+<SUBSECTION Standard>
+G_TYPE_IO_ERROR_ENUM
+<SUBSECTION Private>
+g_io_error_quark
+g_io_error_enum_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gcontenttype</FILE>
+<TITLE>GContentType</TITLE>
+g_content_type_equals
+g_content_type_is_a
+g_content_type_is_mime_type
+g_content_type_is_unknown
+g_content_type_get_description
+g_content_type_get_mime_type
+g_content_type_get_icon
+g_content_type_get_symbolic_icon
+g_content_type_get_generic_icon_name
+g_content_type_can_be_executable
+g_content_type_from_mime_type
+g_content_type_guess
+g_content_type_guess_for_tree
+g_content_types_get_registered
+</SECTION>
+
+<SECTION>
+<FILE>gappinfo</FILE>
+<TITLE>GAppInfo</TITLE>
+GAppInfoCreateFlags
+GAppInfo
+GAppInfoIface
+GAppLaunchContext
+g_app_info_create_from_commandline
+g_app_info_dup
+g_app_info_equal
+g_app_info_get_id
+g_app_info_get_name
+g_app_info_get_display_name
+g_app_info_get_description
+g_app_info_get_executable
+g_app_info_get_commandline
+g_app_info_get_icon
+g_app_info_launch
+g_app_info_supports_files
+g_app_info_supports_uris
+g_app_info_launch_uris
+g_app_info_launch_uris_async
+g_app_info_launch_uris_finish
+g_app_info_should_show
+g_app_info_can_delete
+g_app_info_delete
+g_app_info_reset_type_associations
+g_app_info_set_as_default_for_type
+g_app_info_set_as_default_for_extension
+g_app_info_set_as_last_used_for_type
+g_app_info_add_supports_type
+g_app_info_can_remove_supports_type
+g_app_info_remove_supports_type
+g_app_info_get_supported_types
+g_app_info_get_all
+g_app_info_get_all_for_type
+g_app_info_get_default_for_type
+g_app_info_get_default_for_uri_scheme
+g_app_info_get_fallback_for_type
+g_app_info_get_recommended_for_type
+g_app_info_launch_default_for_uri
+g_app_info_launch_default_for_uri_async
+g_app_info_launch_default_for_uri_finish
+g_app_launch_context_setenv
+g_app_launch_context_unsetenv
+g_app_launch_context_get_environment
+g_app_launch_context_get_display
+g_app_launch_context_get_startup_notify_id
+g_app_launch_context_launch_failed
+g_app_launch_context_new
+<SUBSECTION Standard>
+GAppLaunchContextClass
+G_APP_INFO
+G_IS_APP_INFO
+G_TYPE_APP_INFO
+G_APP_INFO_GET_IFACE
+G_APP_LAUNCH_CONTEXT
+G_APP_LAUNCH_CONTEXT_CLASS
+G_APP_LAUNCH_CONTEXT_GET_CLASS
+G_IS_APP_LAUNCH_CONTEXT
+G_IS_APP_LAUNCH_CONTEXT_CLASS
+G_TYPE_APP_LAUNCH_CONTEXT
+G_TYPE_APP_INFO_CREATE_FLAGS
+<SUBSECTION Private>
+g_app_info_get_type
+g_app_info_create_flags_get_type
+g_app_launch_context_get_type
+GAppLaunchContextPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gappinfomonitor</FILE>
+<TITLE>GAppInfoMonitor</TITLE>
+g_app_info_monitor_get
+<SUBSECTION Standard>
+GAppInfoMonitor
+G_APP_INFO_MONITOR
+G_IS_APP_INFO_MONITOR
+G_TYPE_APP_INFO_MONITOR
+<SUBSECTION Private>
+g_app_info_monitor_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gmountoperation</FILE>
+<TITLE>GMountOperation</TITLE>
+GAskPasswordFlags
+GPasswordSave
+GMountOperation
+GMountOperationResult
+g_mount_operation_new
+g_mount_operation_get_username
+g_mount_operation_set_username
+g_mount_operation_get_password
+g_mount_operation_set_password
+g_mount_operation_get_anonymous
+g_mount_operation_set_anonymous
+g_mount_operation_get_domain
+g_mount_operation_set_domain
+g_mount_operation_get_password_save
+g_mount_operation_set_password_save
+g_mount_operation_get_choice
+g_mount_operation_set_choice
+g_mount_operation_get_is_tcrypt_hidden_volume
+g_mount_operation_set_is_tcrypt_hidden_volume
+g_mount_operation_get_is_tcrypt_system_volume
+g_mount_operation_set_is_tcrypt_system_volume
+g_mount_operation_get_pim
+g_mount_operation_set_pim
+g_mount_operation_reply
+<SUBSECTION Standard>
+GMountOperationClass
+G_MOUNT_OPERATION
+G_IS_MOUNT_OPERATION
+G_TYPE_MOUNT_OPERATION
+G_MOUNT_OPERATION_CLASS
+G_IS_MOUNT_OPERATION_CLASS
+G_MOUNT_OPERATION_GET_CLASS
+G_TYPE_ASK_PASSWORD_FLAGS
+G_TYPE_MOUNT_OPERATION_RESULT
+G_TYPE_PASSWORD_SAVE
+<SUBSECTION Private>
+g_mount_operation_get_type
+g_ask_password_flags_get_type
+GMountOperationPrivate
+g_mount_operation_result_get_type
+g_password_save_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfilenamecompleter</FILE>
+<TITLE>GFilenameCompleter</TITLE>
+GFilenameCompleter
+g_filename_completer_new
+g_filename_completer_get_completion_suffix
+g_filename_completer_get_completions
+g_filename_completer_set_dirs_only
+<SUBSECTION Standard>
+GFilenameCompleterClass
+G_FILENAME_COMPLETER
+G_IS_FILENAME_COMPLETER
+G_TYPE_FILENAME_COMPLETER
+G_FILENAME_COMPLETER_CLASS
+G_IS_FILENAME_COMPLETER_CLASS
+G_FILENAME_COMPLETER_GET_CLASS
+<SUBSECTION Private>
+g_filename_completer_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixmounts</FILE>
+<TITLE>Unix Mounts</TITLE>
+GUnixMountPoint
+GUnixMountEntry
+GUnixMountMonitor
+g_unix_mount_free
+g_unix_mount_compare
+g_unix_mount_copy
+g_unix_mount_get_mount_path
+g_unix_mount_get_device_path
+g_unix_mount_get_root_path
+g_unix_mount_get_fs_type
+g_unix_mount_get_options
+g_unix_mount_is_readonly
+g_unix_mount_is_system_internal
+g_unix_mount_guess_icon
+g_unix_mount_guess_symbolic_icon
+g_unix_mount_guess_name
+g_unix_mount_guess_can_eject
+g_unix_mount_guess_should_display
+g_unix_mount_point_free
+g_unix_mount_point_compare
+g_unix_mount_point_copy
+g_unix_mount_point_get_mount_path
+g_unix_mount_point_get_device_path
+g_unix_mount_point_get_fs_type
+g_unix_mount_point_get_options
+g_unix_mount_point_is_readonly
+g_unix_mount_point_is_user_mountable
+g_unix_mount_point_is_loopback
+g_unix_mount_point_guess_icon
+g_unix_mount_point_guess_symbolic_icon
+g_unix_mount_point_guess_name
+g_unix_mount_point_guess_can_eject
+g_unix_mount_points_get
+g_unix_mounts_get
+g_unix_mount_at
+g_unix_mount_for
+g_unix_mounts_changed_since
+g_unix_mount_points_changed_since
+g_unix_mount_monitor_get
+g_unix_mount_monitor_new
+g_unix_mount_monitor_set_rate_limit
+g_unix_is_mount_path_system_internal
+g_unix_is_system_fs_type
+g_unix_is_system_device_path
+<SUBSECTION Standard>
+GUnixMountMonitorClass
+G_UNIX_MOUNT_MONITOR
+G_IS_UNIX_MOUNT_MONITOR
+G_TYPE_UNIX_MOUNT_MONITOR
+G_UNIX_MOUNT_MONITOR_CLASS
+G_IS_UNIX_MOUNT_MONITOR_CLASS
+G_TYPE_UNIX_MOUNT_ENTRY
+G_TYPE_UNIX_MOUNT_POINT
+<SUBSECTION Private>
+g_unix_mount_monitor_get_type
+g_unix_mount_entry_get_type
+g_unix_mount_point_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdesktopappinfo</FILE>
+<TITLE>Desktop file based GAppInfo</TITLE>
+GDesktopAppInfo
+g_desktop_app_info_new_from_filename
+g_desktop_app_info_new_from_keyfile
+g_desktop_app_info_new
+g_desktop_app_info_get_filename
+g_desktop_app_info_get_is_hidden
+g_desktop_app_info_get_nodisplay
+g_desktop_app_info_get_show_in
+g_desktop_app_info_get_generic_name
+g_desktop_app_info_get_categories
+g_desktop_app_info_get_keywords
+g_desktop_app_info_get_startup_wm_class
+g_desktop_app_info_set_desktop_env
+g_desktop_app_info_get_string
+g_desktop_app_info_get_locale_string
+g_desktop_app_info_get_boolean
+g_desktop_app_info_get_string_list
+g_desktop_app_info_has_key
+GDesktopAppLaunchCallback
+g_desktop_app_info_launch_uris_as_manager
+g_desktop_app_info_launch_uris_as_manager_with_fds
+<SUBSECTION>
+g_desktop_app_info_list_actions
+g_desktop_app_info_get_action_name
+g_desktop_app_info_launch_action
+<SUBSECTION>
+g_desktop_app_info_search
+g_desktop_app_info_get_implementations
+<SUBSECTION>
+GDesktopAppInfoLookup
+GDesktopAppInfoLookupIface
+G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME
+<SUBSECTION Standard>
+GDesktopAppInfoClass
+G_TYPE_DESKTOP_APP_INFO
+G_DESKTOP_APP_INFO
+G_DESKTOP_APP_INFO_CLASS
+G_IS_DESKTOP_APP_INFO
+G_IS_DESKTOP_APP_INFO_CLASS
+G_DESKTOP_APP_INFO_GET_CLASS
+G_DESKTOP_APP_INFO_LOOKUP
+G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE
+G_IS_DESKTOP_APP_INFO_LOOKUP
+G_TYPE_DESKTOP_APP_INFO_LOOKUP
+<SUBSECTION Private>
+g_desktop_app_info_get_type
+g_desktop_app_info_lookup_get_default_for_uri_scheme
+g_desktop_app_info_lookup_get_type
+</SECTION>
+
+<SECTION>
+<FILE>giomodule</FILE>
+<TITLE>GIOModule</TITLE>
+GIOModule
+GIOModuleScope
+GIOModuleScopeFlags
+g_io_module_new
+g_io_module_scope_block
+g_io_module_scope_free
+g_io_module_scope_new
+g_io_modules_load_all_in_directory
+g_io_modules_load_all_in_directory_with_scope
+g_io_modules_scan_all_in_directory
+g_io_modules_scan_all_in_directory_with_scope
+g_io_module_load
+g_io_module_unload
+g_io_module_query
+<SUBSECTION Standard>
+GIOModuleClass
+G_IO_MODULE
+G_IO_IS_MODULE
+G_IO_TYPE_MODULE
+G_IO_MODULE_CLASS
+G_IO_IS_MODULE_CLASS
+G_IO_MODULE_GET_CLASS
+G_TYPE_IO_MODULE_SCOPE_FLAGS
+<SUBSECTION Private>
+g_io_module_get_type
+g_io_module_scope_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>extensionpoints</FILE>
+<TITLE>Extension Points</TITLE>
+GIOExtension
+GIOExtensionPoint
+g_io_extension_get_name
+g_io_extension_get_priority
+g_io_extension_get_type
+g_io_extension_point_get_extension_by_name
+g_io_extension_point_get_extensions
+g_io_extension_point_get_required_type
+g_io_extension_point_implement
+g_io_extension_point_lookup
+g_io_extension_point_register
+g_io_extension_point_set_required_type
+g_io_extension_ref_class
+</SECTION>
+
+<SECTION>
+<FILE>gunixfdlist</FILE>
+<TITLE>GUnixFDList</TITLE>
+GUnixFDList
+g_unix_fd_list_new_from_array
+g_unix_fd_list_new
+g_unix_fd_list_get_length
+g_unix_fd_list_get
+g_unix_fd_list_peek_fds
+g_unix_fd_list_steal_fds
+g_unix_fd_list_append
+<SUBSECTION Standard>
+GUnixFDListClass
+G_UNIX_FD_LIST
+G_UNIX_FD_LIST_CLASS
+G_IS_UNIX_FD_LIST
+G_IS_UNIX_FD_LIST_CLASS
+G_UNIX_FD_LIST_GET_CLASS
+G_TYPE_UNIX_FD_LIST
+<SUBSECTION Private>
+GUnixFDListPrivate
+g_unix_fd_list_get_type
+</SECTION>
+
+<SECTION>
+<FILE>ginetaddress</FILE>
+<TITLE>GInetAddress</TITLE>
+GInetAddress
+g_inet_address_new_from_string
+g_inet_address_new_from_bytes
+g_inet_address_new_any
+g_inet_address_new_loopback
+g_inet_address_equal
+g_inet_address_to_bytes
+g_inet_address_get_native_size
+g_inet_address_to_string
+g_inet_address_get_family
+g_inet_address_get_is_any
+g_inet_address_get_is_loopback
+g_inet_address_get_is_link_local
+g_inet_address_get_is_site_local
+g_inet_address_get_is_multicast
+g_inet_address_get_is_mc_link_local
+g_inet_address_get_is_mc_node_local
+g_inet_address_get_is_mc_site_local
+g_inet_address_get_is_mc_org_local
+g_inet_address_get_is_mc_global
+<SUBSECTION Standard>
+GInetAddressClass
+GInetAddressPrivate
+G_INET_ADDRESS
+G_INET_ADDRESS_CLASS
+G_INET_ADDRESS_GET_CLASS
+G_IS_INET_ADDRESS
+G_IS_INET_ADDRESS_CLASS
+G_TYPE_INET_ADDRESS
+<SUBSECTION Private>
+g_inet_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>ginetaddressmask</FILE>
+<TITLE>GInetAddressMask</TITLE>
+GInetAddressMask
+g_inet_address_mask_new
+g_inet_address_mask_new_from_string
+g_inet_address_mask_to_string
+g_inet_address_mask_get_family
+g_inet_address_mask_get_address
+g_inet_address_mask_get_length
+g_inet_address_mask_matches
+g_inet_address_mask_equal
+<SUBSECTION Standard>
+GInetAddressMaskClass
+GInetAddressMaskPrivate
+G_INET_ADDRESS_MASK
+G_INET_ADDRESS_MASK_CLASS
+G_INET_ADDRESS_MASK_GET_CLASS
+G_IS_INET_ADDRESS_MASK
+G_IS_INET_ADDRESS_MASK_CLASS
+G_TYPE_INET_ADDRESS_MASK
+<SUBSECTION Private>
+g_inet_address_mask_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketaddress</FILE>
+<TITLE>GSocketAddress</TITLE>
+GSocketAddress
+GSocketFamily
+g_socket_address_new_from_native
+g_socket_address_get_family
+g_socket_address_to_native
+g_socket_address_get_native_size
+<SUBSECTION Standard>
+GSocketAddressClass
+G_IS_SOCKET_ADDRESS
+G_IS_SOCKET_ADDRESS_CLASS
+G_SOCKET_ADDRESS
+G_SOCKET_ADDRESS_CLASS
+G_SOCKET_ADDRESS_GET_CLASS
+G_TYPE_SOCKET_ADDRESS
+G_TYPE_SOCKET_FAMILY
+<SUBSECTION Private>
+g_socket_address_get_type
+g_socket_family_get_type
+</SECTION>
+
+<SECTION>
+<FILE>ginetsocketaddress</FILE>
+<TITLE>GInetSocketAddress</TITLE>
+GInetSocketAddress
+g_inet_socket_address_new
+g_inet_socket_address_new_from_string
+g_inet_socket_address_get_address
+g_inet_socket_address_get_port
+g_inet_socket_address_get_flowinfo
+g_inet_socket_address_get_scope_id
+<SUBSECTION Standard>
+GInetSocketAddressClass
+GInetSocketAddressPrivate
+G_INET_SOCKET_ADDRESS
+G_INET_SOCKET_ADDRESS_CLASS
+G_INET_SOCKET_ADDRESS_GET_CLASS
+G_IS_INET_SOCKET_ADDRESS
+G_IS_INET_SOCKET_ADDRESS_CLASS
+G_TYPE_INET_SOCKET_ADDRESS
+<SUBSECTION Private>
+g_inet_socket_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixsocketaddress</FILE>
+<TITLE>GUnixSocketAddress</TITLE>
+GUnixSocketAddress
+GUnixSocketAddressType
+g_unix_socket_address_new
+g_unix_socket_address_new_abstract
+g_unix_socket_address_new_with_type
+g_unix_socket_address_get_is_abstract
+g_unix_socket_address_get_address_type
+g_unix_socket_address_get_path
+g_unix_socket_address_get_path_len
+g_unix_socket_address_abstract_names_supported
+<SUBSECTION Standard>
+GUnixSocketAddressClass
+GUnixSocketAddressPrivate
+G_IS_UNIX_SOCKET_ADDRESS
+G_IS_UNIX_SOCKET_ADDRESS_CLASS
+G_TYPE_UNIX_SOCKET_ADDRESS
+G_UNIX_SOCKET_ADDRESS
+G_UNIX_SOCKET_ADDRESS_CLASS
+G_UNIX_SOCKET_ADDRESS_GET_CLASS
+G_TYPE_UNIX_SOCKET_ADDRESS_TYPE
+<SUBSECTION Private>
+g_unix_socket_address_get_type
+g_unix_socket_address_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gnativesocketaddress</FILE>
+<TITLE>GNativeSocketAddress</TITLE>
+GNativeSocketAddress
+g_native_socket_address_new
+<SUBSECTION Standard>
+GNativeSocketAddressClass
+GNativeSocketAddressPrivate
+G_IS_NATIVE_SOCKET_ADDRESS
+G_IS_NATIVE_SOCKET_ADDRESS_CLASS
+G_TYPE_NATIVE_SOCKET_ADDRESS
+G_NATIVE_SOCKET_ADDRESS
+G_NATIVE_SOCKET_ADDRESS_CLASS
+G_NATIVE_SOCKET_ADDRESS_GET_CLASS
+G_TYPE_NATIVE_SOCKET_ADDRESS_TYPE
+<SUBSECTION Private>
+g_native_socket_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gresolver</FILE>
+<TITLE>GResolver</TITLE>
+GResolver
+g_resolver_get_default
+g_resolver_set_default
+g_resolver_lookup_by_name
+g_resolver_lookup_by_name_async
+g_resolver_lookup_by_name_finish
+GResolverNameLookupFlags
+g_resolver_lookup_by_name_with_flags
+g_resolver_lookup_by_name_with_flags_async
+g_resolver_lookup_by_name_with_flags_finish
+g_resolver_free_addresses
+g_resolver_lookup_by_address
+g_resolver_lookup_by_address_async
+g_resolver_lookup_by_address_finish
+g_resolver_lookup_service
+g_resolver_lookup_service_async
+g_resolver_lookup_service_finish
+g_resolver_free_targets
+<SUBSECTION>
+GResolverRecordType
+g_resolver_lookup_records
+g_resolver_lookup_records_async
+g_resolver_lookup_records_finish
+
+<SUBSECTION>
+G_RESOLVER_ERROR
+GResolverError
+
+<SUBSECTION Standard>
+GResolverClass
+G_IS_RESOLVER
+G_IS_RESOLVER_CLASS
+G_RESOLVER
+G_RESOLVER_CLASS
+G_RESOLVER_GET_CLASS
+G_TYPE_RESOLVER
+G_TYPE_RESOLVER_ERROR
+G_TYPE_RESOLVER_RECORD_TYPE
+G_TYPE_RESOLVER_NAME_LOOKUP_FLAGS
+
+<SUBSECTION Private>
+GResolverPrivate
+g_resolver_get_type
+g_resolver_error_quark
+g_resolver_record_type_get_type
+g_resolver_error_get_type
+g_resolver_name_lookup_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsrvtarget</FILE>
+<TITLE>GSrvTarget</TITLE>
+GSrvTarget
+g_srv_target_new
+g_srv_target_copy
+g_srv_target_free
+g_srv_target_get_hostname
+g_srv_target_get_port
+g_srv_target_get_priority
+g_srv_target_get_weight
+g_srv_target_list_sort
+<SUBSECTION Standard>
+G_TYPE_SRV_TARGET
+<SUBSECTION Private>
+g_srv_target_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketconnectable</FILE>
+<TITLE>GSocketConnectable</TITLE>
+GSocketConnectable
+GSocketConnectableIface
+g_socket_connectable_enumerate
+g_socket_connectable_proxy_enumerate
+g_socket_connectable_to_string
+<SUBSECTION Standard>
+G_IS_SOCKET_CONNECTABLE
+G_SOCKET_CONNECTABLE
+G_SOCKET_CONNECTABLE_GET_IFACE
+G_TYPE_SOCKET_CONNECTABLE
+<SUBSECTION Private>
+g_socket_connectable_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketaddressenumerator</FILE>
+<TITLE>GSocketAddressEnumerator</TITLE>
+GSocketAddressEnumerator
+GSocketAddressEnumeratorClass
+g_socket_address_enumerator_next
+g_socket_address_enumerator_next_async
+g_socket_address_enumerator_next_finish
+<SUBSECTION Standard>
+G_IS_SOCKET_ADDRESS_ENUMERATOR
+G_IS_SOCKET_ADDRESS_ENUMERATOR_CLASS
+G_SOCKET_ADDRESS_ENUMERATOR
+G_SOCKET_ADDRESS_ENUMERATOR_CLASS
+G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS
+G_TYPE_SOCKET_ADDRESS_ENUMERATOR
+<SUBSECTION Private>
+g_socket_address_enumerator_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gproxyaddressenumerator</FILE>
+<TITLE>GProxyAddressEnumerator</TITLE>
+GProxyAddressEnumerator
+GProxyAddressEnumeratorClass
+<SUBSECTION Standard>
+G_IS_PROXY_ADDRESS_ENUMERATOR
+G_IS_PROXY_ADDRESS_ENUMERATOR_CLASS
+G_PROXY_ADDRESS_ENUMERATOR
+G_PROXY_ADDRESS_ENUMERATOR_CLASS
+G_PROXY_ADDRESS_ENUMERATOR_GET_CLASS
+G_TYPE_PROXY_ADDRESS_ENUMERATOR
+<SUBSECTION Private>
+GProxyAddressEnumeratorPrivate
+g_proxy_address_enumerator_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gnetworkaddress</FILE>
+<TITLE>GNetworkAddress</TITLE>
+GNetworkAddress
+g_network_address_new
+g_network_address_new_loopback
+g_network_address_parse
+g_network_address_parse_uri
+g_network_address_get_hostname
+g_network_address_get_port
+g_network_address_get_scheme
+<SUBSECTION Standard>
+GNetworkAddressClass
+GNetworkAddressPrivate
+G_IS_NETWORK_ADDRESS
+G_IS_NETWORK_ADDRESS_CLASS
+G_NETWORK_ADDRESS
+G_NETWORK_ADDRESS_CLASS
+G_NETWORK_ADDRESS_GET_CLASS
+G_TYPE_NETWORK_ADDRESS
+<SUBSECTION Private>
+g_network_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gnetworkservice</FILE>
+<TITLE>GNetworkService</TITLE>
+GNetworkService
+g_network_service_new
+g_network_service_get_service
+g_network_service_get_protocol
+g_network_service_get_domain
+g_network_service_get_scheme
+g_network_service_set_scheme
+<SUBSECTION Standard>
+GNetworkServiceClass
+GNetworkServicePrivate
+G_IS_NETWORK_SERVICE
+G_IS_NETWORK_SERVICE_CLASS
+G_NETWORK_SERVICE
+G_NETWORK_SERVICE_CLASS
+G_NETWORK_SERVICE_GET_CLASS
+G_TYPE_NETWORK_SERVICE
+<SUBSECTION Private>
+g_network_service_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdatagrambased</FILE>
+<TITLE>GDatagramBased</TITLE>
+GDatagramBased
+GDatagramBasedInterface
+GDatagramBasedSourceFunc
+g_datagram_based_receive_messages
+g_datagram_based_send_messages
+g_datagram_based_create_source
+g_datagram_based_condition_check
+g_datagram_based_condition_wait
+<SUBSECTION Standard>
+G_DATAGRAM_BASED
+G_DATAGRAM_BASED_GET_IFACE
+G_IS_DATAGRAM_BASED
+G_TYPE_DATAGRAM_BASED
+G_TYPE_IS_DATAGRAM_BASED
+<SUBSECTION Private>
+g_datagram_based_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocket</FILE>
+<TITLE>GSocket</TITLE>
+GSocket
+GSocketSourceFunc
+GSocketType
+GSocketProtocol
+GSocketMsgFlags
+GInputVector
+GInputMessage
+GOutputVector
+GOutputMessage
+g_socket_new
+g_socket_new_from_fd
+g_socket_bind
+g_socket_listen
+g_socket_accept
+g_socket_connect
+g_socket_check_connect_result
+g_socket_receive
+g_socket_receive_from
+g_socket_receive_message
+g_socket_receive_messages
+g_socket_receive_with_blocking
+g_socket_send
+g_socket_send_to
+g_socket_send_message
+g_socket_send_message_with_timeout
+g_socket_send_messages
+g_socket_send_with_blocking
+g_socket_close
+g_socket_is_closed
+g_socket_shutdown
+g_socket_is_connected
+g_socket_create_source
+g_socket_condition_check
+g_socket_condition_wait
+g_socket_condition_timed_wait
+g_socket_get_available_bytes
+g_socket_set_listen_backlog
+g_socket_get_listen_backlog
+g_socket_get_blocking
+g_socket_set_blocking
+g_socket_get_keepalive
+g_socket_set_keepalive
+g_socket_get_timeout
+g_socket_set_timeout
+g_socket_set_ttl
+g_socket_get_ttl
+g_socket_get_broadcast
+g_socket_set_broadcast
+g_socket_get_option
+g_socket_set_option
+g_socket_get_family
+g_socket_get_fd
+g_socket_get_local_address
+g_socket_get_protocol
+g_socket_get_remote_address
+g_socket_get_socket_type
+g_socket_speaks_ipv4
+g_socket_get_credentials
+<SUBSECTION>
+g_socket_join_multicast_group
+g_socket_leave_multicast_group
+g_socket_join_multicast_group_ssm
+g_socket_leave_multicast_group_ssm
+g_socket_get_multicast_loopback
+g_socket_set_multicast_loopback
+g_socket_get_multicast_ttl
+g_socket_set_multicast_ttl
+<SUBSECTION Standard>
+GSocketClass
+G_IS_SOCKET
+G_IS_SOCKET_CLASS
+G_SOCKET
+G_SOCKET_CLASS
+G_TYPE_SOCKET
+G_SOCKET_GET_CLASS
+G_TYPE_SOCKET_MSG_FLAGS
+G_TYPE_SOCKET_PROTOCOL
+G_TYPE_SOCKET_TYPE
+<SUBSECTION Private>
+g_socket_get_type
+GSocketPrivate
+g_socket_msg_flags_get_type
+g_socket_protocol_get_type
+g_socket_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketclient</FILE>
+<TITLE>GSocketClient</TITLE>
+GSocketClient
+GSocketClientEvent
+g_socket_client_new
+g_socket_client_connect
+g_socket_client_connect_async
+g_socket_client_connect_finish
+g_socket_client_connect_to_host
+g_socket_client_connect_to_host_async
+g_socket_client_connect_to_host_finish
+g_socket_client_connect_to_service
+g_socket_client_connect_to_service_async
+g_socket_client_connect_to_service_finish
+g_socket_client_connect_to_uri
+g_socket_client_connect_to_uri_async
+g_socket_client_connect_to_uri_finish
+g_socket_client_set_family
+g_socket_client_set_local_address
+g_socket_client_set_protocol
+g_socket_client_set_socket_type
+g_socket_client_set_timeout
+g_socket_client_set_enable_proxy
+g_socket_client_set_proxy_resolver
+g_socket_client_set_tls
+g_socket_client_set_tls_validation_flags
+g_socket_client_get_family
+g_socket_client_get_local_address
+g_socket_client_get_protocol
+g_socket_client_get_socket_type
+g_socket_client_get_timeout
+g_socket_client_get_enable_proxy
+g_socket_client_get_proxy_resolver
+g_socket_client_get_tls
+g_socket_client_get_tls_validation_flags
+g_socket_client_add_application_proxy
+<SUBSECTION Standard>
+GSocketClientClass
+G_IS_SOCKET_CLIENT
+G_IS_SOCKET_CLIENT_CLASS
+G_SOCKET_CLIENT
+G_SOCKET_CLIENT_CLASS
+G_SOCKET_CLIENT_GET_CLASS
+G_TYPE_SOCKET_CLIENT
+G_TYPE_SOCKET_CLIENT_EVENT
+<SUBSECTION Private>
+GSocketClientPrivate
+g_socket_client_get_type
+g_socket_client_event_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketconnection</FILE>
+<TITLE>GSocketConnection</TITLE>
+GSocketConnection
+g_socket_connection_connect
+g_socket_connection_connect_async
+g_socket_connection_connect_finish
+<SUBSECTION>
+g_socket_connection_is_connected
+g_socket_connection_get_local_address
+g_socket_connection_get_remote_address
+g_socket_connection_get_socket
+<SUBSECTION>
+g_socket_connection_factory_create_connection
+g_socket_connection_factory_lookup_type
+g_socket_connection_factory_register_type
+<SUBSECTION Standard>
+GSocketConnectionClass
+G_IS_SOCKET_CONNECTION
+G_IS_SOCKET_CONNECTION_CLASS
+G_SOCKET_CONNECTION
+G_SOCKET_CONNECTION_CLASS
+G_SOCKET_CONNECTION_GET_CLASS
+G_TYPE_SOCKET_CONNECTION
+<SUBSECTION Private>
+GSocketConnectionPrivate
+g_socket_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixconnection</FILE>
+<TITLE>GUnixConnection</TITLE>
+GUnixConnection
+g_unix_connection_receive_fd
+g_unix_connection_send_fd
+g_unix_connection_receive_credentials
+g_unix_connection_receive_credentials_async
+g_unix_connection_receive_credentials_finish
+g_unix_connection_send_credentials
+g_unix_connection_send_credentials_async
+g_unix_connection_send_credentials_finish
+<SUBSECTION Standard>
+GUnixConnectionClass
+G_IS_UNIX_CONNECTION
+G_IS_UNIX_CONNECTION_CLASS
+G_TYPE_UNIX_CONNECTION
+G_UNIX_CONNECTION
+G_UNIX_CONNECTION_CLASS
+G_UNIX_CONNECTION_GET_CLASS
+<SUBSECTION Private>
+GUnixConnectionPrivate
+g_unix_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtcpconnection</FILE>
+<TITLE>GTcpConnection</TITLE>
+GTcpConnection
+g_tcp_connection_set_graceful_disconnect
+g_tcp_connection_get_graceful_disconnect
+<SUBSECTION Standard>
+GTcpConnectionClass
+G_IS_TCP_CONNECTION
+G_IS_TCP_CONNECTION_CLASS
+G_TYPE_TCP_CONNECTION
+G_TCP_CONNECTION
+G_TCP_CONNECTION_CLASS
+G_TCP_CONNECTION_GET_CLASS
+<SUBSECTION Private>
+GTcpConnectionPrivate
+g_tcp_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtcpwrapperconnection</FILE>
+<TITLE>GTcpWrapperConnection</TITLE>
+GTcpWrapperConnection
+g_tcp_wrapper_connection_new
+g_tcp_wrapper_connection_get_base_io_stream
+<SUBSECTION Standard>
+GTcpWrapperConnectionClass
+G_IS_TCP_WRAPPER_CONNECTION
+G_IS_TCP_WRAPPER_CONNECTION_CLASS
+G_TYPE_TCP_WRAPPER_CONNECTION
+G_TCP_WRAPPER_CONNECTION
+G_TCP_WRAPPER_CONNECTION_CLASS
+G_TCP_WRAPPER_CONNECTION_GET_CLASS
+<SUBSECTION Private>
+GTcpWrapperConnectionPrivate
+g_tcp_wrapper_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketcontrolmessage</FILE>
+<TITLE>GSocketControlMessage</TITLE>
+GSocketControlMessage
+g_socket_control_message_deserialize
+g_socket_control_message_get_level
+g_socket_control_message_get_msg_type
+g_socket_control_message_get_size
+g_socket_control_message_serialize
+<SUBSECTION Standard>
+GSocketControlMessageClass
+G_IS_SOCKET_CONTROL_MESSAGE
+G_IS_SOCKET_CONTROL_MESSAGE_CLASS
+G_SOCKET_CONTROL_MESSAGE
+G_SOCKET_CONTROL_MESSAGE_CLASS
+G_SOCKET_CONTROL_MESSAGE_GET_CLASS
+G_TYPE_SOCKET_CONTROL_MESSAGE
+<SUBSECTION Private>
+GSocketControlMessagePrivate
+g_socket_control_message_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketlistener</FILE>
+<TITLE>GSocketListener</TITLE>
+GSocketListener
+GSocketListenerEvent
+g_socket_listener_new
+g_socket_listener_add_socket
+g_socket_listener_add_address
+g_socket_listener_add_inet_port
+g_socket_listener_add_any_inet_port
+g_socket_listener_accept
+g_socket_listener_accept_async
+g_socket_listener_accept_finish
+g_socket_listener_accept_socket
+g_socket_listener_accept_socket_async
+g_socket_listener_accept_socket_finish
+g_socket_listener_close
+g_socket_listener_set_backlog
+<SUBSECTION Standard>
+GSocketListenerClass
+G_IS_SOCKET_LISTENER
+G_IS_SOCKET_LISTENER_CLASS
+G_SOCKET_LISTENER
+G_SOCKET_LISTENER_CLASS
+G_SOCKET_LISTENER_GET_CLASS
+G_TYPE_SOCKET_LISTENER
+G_TYPE_SOCKET_LISTENER_EVENT
+<SUBSECTION Private>
+GSocketListenerPrivate
+g_socket_listener_get_type
+g_socket_listener_event_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketservice</FILE>
+<TITLE>GSocketService</TITLE>
+GSocketService
+g_socket_service_new
+g_socket_service_start
+g_socket_service_stop
+g_socket_service_is_active
+<SUBSECTION Standard>
+GSocketServiceClass
+G_IS_SOCKET_SERVICE
+G_IS_SOCKET_SERVICE_CLASS
+G_SOCKET_SERVICE
+G_SOCKET_SERVICE_CLASS
+G_SOCKET_SERVICE_GET_CLASS
+G_TYPE_SOCKET_SERVICE
+<SUBSECTION Private>
+GSocketServicePrivate
+g_socket_service_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gthreadedsocketservice</FILE>
+<TITLE>GThreadedSocketService</TITLE>
+GThreadedSocketService
+g_threaded_socket_service_new
+<SUBSECTION Standard>
+GThreadedSocketServiceClass
+G_IS_THREADED_SOCKET_SERVICE
+G_IS_THREADED_SOCKET_SERVICE_CLASS
+G_THREADED_SOCKET_SERVICE
+G_THREADED_SOCKET_SERVICE_CLASS
+G_THREADED_SOCKET_SERVICE_GET_CLASS
+G_TYPE_THREADED_SOCKET_SERVICE
+<SUBSECTION Private>
+GThreadedSocketServicePrivate
+g_threaded_socket_service_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixfdmessage</FILE>
+<TITLE>GUnixFDMessage</TITLE>
+GUnixFDMessage
+g_unix_fd_message_new_with_fd_list
+g_unix_fd_message_new
+g_unix_fd_message_get_fd_list
+g_unix_fd_message_append_fd
+g_unix_fd_message_steal_fds
+<SUBSECTION Standard>
+GUnixFDMessageClass
+G_IS_UNIX_FD_MESSAGE
+G_IS_UNIX_FD_MESSAGE_CLASS
+G_TYPE_UNIX_FD_MESSAGE
+G_UNIX_FD_MESSAGE
+G_UNIX_FD_MESSAGE_CLASS
+G_UNIX_FD_MESSAGE_GET_CLASS
+<SUBSECTION Private>
+GUnixFDMessagePrivate
+g_unix_fd_message_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gconverter</FILE>
+<TITLE>GConverter</TITLE>
+GConverter
+GConverterIface
+GConverterResult
+GConverterFlags
+g_converter_convert
+g_converter_reset
+<SUBSECTION Standard>
+G_TYPE_CONVERTER
+G_CONVERTER
+G_IS_CONVERTER
+G_CONVERTER_GET_IFACE
+G_TYPE_CONVERTER_FLAGS
+G_TYPE_CONVERTER_RESULT
+<SUBSECTION Private>
+g_converter_get_type
+g_converter_flags_get_type
+g_converter_result_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gcharsetconverter</FILE>
+<TITLE>GCharsetConverter</TITLE>
+GCharsetConverter
+g_charset_converter_new
+g_charset_converter_set_use_fallback
+g_charset_converter_get_use_fallback
+g_charset_converter_get_num_fallbacks
+<SUBSECTION Standard>
+GCharsetConverterClass
+G_TYPE_CHARSET_CONVERTER
+G_CHARSET_CONVERTER
+G_IS_CHARSET_CONVERTER
+G_CHARSET_CONVERTER_CLASS
+G_IS_CHARSET_CONVERTER_CLASS
+G_CHARSET_CONVERTER_GET_CLASS
+<SUBSECTION Private>
+g_charset_converter_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gconverterinputstream</FILE>
+<TITLE>GConverterInputStream</TITLE>
+GConverterInputStream
+g_converter_input_stream_new
+g_converter_input_stream_get_converter
+<SUBSECTION Standard>
+GConverterInputStreamClass
+G_TYPE_CONVERTER_INPUT_STREAM
+G_CONVERTER_INPUT_STREAM
+G_IS_CONVERTER_INPUT_STREAM
+G_CONVERTER_INPUT_STREAM_CLASS
+G_IS_CONVERTER_INPUT_STREAM_CLASS
+G_CONVERTER_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+GConverterInputStreamPrivate
+g_converter_input_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gconverteroutputstream</FILE>
+<TITLE>GConverterOutputStream</TITLE>
+GConverterOutputStream
+g_converter_output_stream_new
+g_converter_output_stream_get_converter
+<SUBSECTION Standard>
+GConverterOutputStreamClass
+G_TYPE_CONVERTER_OUTPUT_STREAM
+G_CONVERTER_OUTPUT_STREAM
+G_IS_CONVERTER_OUTPUT_STREAM
+G_CONVERTER_OUTPUT_STREAM_CLASS
+G_IS_CONVERTER_OUTPUT_STREAM_CLASS
+G_CONVERTER_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+GConverterOutputStreamPrivate
+g_converter_output_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gzcompressor</FILE>
+<TITLE>GZlibCompressor</TITLE>
+GZlibCompressor
+GZlibCompressorFormat
+g_zlib_compressor_new
+g_zlib_compressor_get_file_info
+g_zlib_compressor_set_file_info
+<SUBSECTION Standard>
+GZlibCompressorClass
+G_TYPE_ZLIB_COMPRESSOR
+G_ZLIB_COMPRESSOR
+G_IS_ZLIB_COMPRESSOR
+G_ZLIB_COMPRESSOR_CLASS
+G_IS_ZLIB_COMPRESSOR_CLASS
+G_ZLIB_COMPRESSOR_GET_CLASS
+G_TYPE_ZLIB_COMPRESSOR_FORMAT
+<SUBSECTION Private>
+g_zlib_compressor_get_type
+g_zlib_compressor_format_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gzdecompressor</FILE>
+<TITLE>GZlibDecompressor</TITLE>
+GZlibDecompressor
+g_zlib_decompressor_new
+g_zlib_decompressor_get_file_info
+<SUBSECTION Standard>
+GZlibDecompressorClass
+G_TYPE_ZLIB_DECOMPRESSOR
+G_ZLIB_DECOMPRESSOR
+G_IS_ZLIB_DECOMPRESSOR
+G_ZLIB_DECOMPRESSOR_CLASS
+G_IS_ZLIB_DECOMPRESSOR_CLASS
+G_ZLIB_DECOMPRESSOR_GET_CLASS
+<SUBSECTION Private>
+g_zlib_decompressor_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gfiledescriptorbased</FILE>
+<TITLE>GFileDescriptorBased</TITLE>
+GFileDescriptorBased
+GFileDescriptorBasedIface
+g_file_descriptor_based_get_fd
+<SUBSECTION Private>
+g_file_descriptor_based_get_type
+G_FILE_DESCRIPTOR_BASED
+G_FILE_DESCRIPTOR_BASED_GET_IFACE
+G_IS_FILE_DESCRIPTOR_BASED
+G_TYPE_FILE_DESCRIPTOR_BASED
+</SECTION>
+
+<SECTION>
+<FILE>gsettingsbackend</FILE>
+<TITLE>GSettingsBackend</TITLE>
+GSettingsBackend
+GSettingsBackendClass
+G_SETTINGS_BACKEND_EXTENSION_POINT_NAME
+g_settings_backend_get_default
+g_settings_backend_changed
+g_settings_backend_path_changed
+g_settings_backend_keys_changed
+g_settings_backend_path_writable_changed
+g_settings_backend_writable_changed
+g_settings_backend_changed_tree
+g_settings_backend_flatten_tree
+g_keyfile_settings_backend_new
+g_memory_settings_backend_new
+g_null_settings_backend_new
+
+<SUBSECTION Standard>
+G_IS_SETTINGS_BACKEND
+G_IS_SETTINGS_BACKEND_CLASS
+G_SETTINGS_BACKEND
+G_SETTINGS_BACKEND_CLASS
+G_SETTINGS_BACKEND_GET_CLASS
+G_TYPE_SETTINGS_BACKEND
+
+<SUBSECTION Private>
+g_settings_backend_get_type
+GSettingsBackendPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gsettingsschema</FILE>
+<TITLE>GSettingsSchema, GSettingsSchemaSource</TITLE>
+GSettingsSchemaSource
+g_settings_schema_source_get_default
+g_settings_schema_source_ref
+g_settings_schema_source_unref
+
+<SUBSECTION>
+g_settings_schema_source_new_from_directory
+
+<SUBSECTION>
+g_settings_schema_source_list_schemas
+g_settings_schema_source_lookup
+
+<SUBSECTION>
+GSettingsSchema
+g_settings_schema_ref
+g_settings_schema_unref
+
+<SUBSECTION>
+g_settings_schema_get_id
+g_settings_schema_get_path
+
+<SUBSECTION>
+GSettingsSchemaKey
+g_settings_schema_has_key
+g_settings_schema_get_key
+g_settings_schema_key_ref
+g_settings_schema_key_unref
+g_settings_schema_list_children
+g_settings_schema_list_keys
+
+<SUBSECTION>
+g_settings_schema_key_get_value_type
+g_settings_schema_key_get_default_value
+g_settings_schema_key_get_range
+g_settings_schema_key_range_check
+
+<SUBSECTION>
+g_settings_schema_key_get_name
+g_settings_schema_key_get_summary
+g_settings_schema_key_get_description
+
+<SUBSECTION Standard>
+G_TYPE_SETTINGS_SCHEMA_KEY
+G_TYPE_SETTINGS_SCHEMA
+G_TYPE_SETTINGS_SCHEMA_SOURCE
+
+<SUBSECTION Private>
+g_settings_schema_get_type
+g_settings_schema_key_get_type
+g_settings_schema_source_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsettings</FILE>
+<TITLE>GSettings</TITLE>
+GSettings
+g_settings_new
+g_settings_new_with_path
+g_settings_new_with_backend
+g_settings_new_with_backend_and_path
+g_settings_new_full
+g_settings_sync
+g_settings_get_value
+g_settings_set_value
+g_settings_is_writable
+g_settings_delay
+g_settings_apply
+g_settings_revert
+g_settings_get_has_unapplied
+g_settings_get_child
+g_settings_reset
+g_settings_get_user_value
+g_settings_get_default_value
+
+<SUBSECTION Introspection>
+g_settings_list_schemas
+g_settings_list_relocatable_schemas
+g_settings_list_keys
+g_settings_list_children
+g_settings_get_range
+g_settings_range_check
+
+<SUBSECTION Convenience>
+g_settings_get
+g_settings_set
+g_settings_get_boolean
+g_settings_set_boolean
+g_settings_get_int
+g_settings_set_int
+g_settings_get_int64
+g_settings_set_int64
+g_settings_get_uint
+g_settings_set_uint
+g_settings_get_uint64
+g_settings_set_uint64
+g_settings_get_double
+g_settings_set_double
+g_settings_get_string
+g_settings_set_string
+g_settings_get_strv
+g_settings_set_strv
+g_settings_get_enum
+g_settings_set_enum
+g_settings_get_flags
+g_settings_set_flags
+
+<SUBSECTION MappedGet>
+GSettingsGetMapping
+g_settings_get_mapped
+
+<SUBSECTION Binding>
+GSettingsBindFlags
+g_settings_bind
+g_settings_bind_with_mapping
+g_settings_bind_writable
+g_settings_unbind
+GSettingsBindSetMapping
+GSettingsBindGetMapping
+
+<SUBSECTION>
+g_settings_create_action
+
+<SUBSECTION Standard>
+GSettingsClass
+G_IS_SETTINGS
+G_IS_SETTINGS_CLASS
+G_SETTINGS
+G_SETTINGS_CLASS
+G_SETTINGS_GET_CLASS
+G_TYPE_SETTINGS
+G_TYPE_SETTINGS_BIND_FLAGS
+
+<SUBSECTION Private>
+GSettingsPrivate
+g_settings_get_type
+g_settings_bind_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixcredentialsmessage</FILE>
+<TITLE>GUnixCredentialsMessage</TITLE>
+GUnixCredentialsMessage
+GUnixCredentialsMessageClass
+g_unix_credentials_message_new
+g_unix_credentials_message_new_with_credentials
+g_unix_credentials_message_get_credentials
+g_unix_credentials_message_is_supported
+<SUBSECTION Standard>
+G_IS_UNIX_CREDENTIALS_MESSAGE
+G_IS_UNIX_CREDENTIALS_MESSAGE_CLASS
+G_TYPE_UNIX_CREDENTIALS_MESSAGE
+G_UNIX_CREDENTIALS_MESSAGE
+G_UNIX_CREDENTIALS_MESSAGE_CLASS
+G_UNIX_CREDENTIALS_MESSAGE_GET_CLASS
+<SUBSECTION Private>
+GUnixCredentialsMessagePrivate
+g_unix_credentials_message_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gcredentials</FILE>
+<TITLE>GCredentials</TITLE>
+GCredentials
+GCredentialsType
+g_credentials_new
+g_credentials_to_string
+g_credentials_get_native
+g_credentials_set_native
+g_credentials_is_same_user
+g_credentials_get_unix_user
+g_credentials_set_unix_user
+g_credentials_get_unix_pid
+<SUBSECTION Standard>
+G_CREDENTIALS
+G_IS_CREDENTIALS
+G_TYPE_CREDENTIALS
+G_CREDENTIALS_CLASS
+G_IS_CREDENTIALS_CLASS
+G_CREDENTIALS_GET_CLASS
+G_TYPE_CREDENTIALS_TYPE
+<SUBSECTION Private>
+g_credentials_get_type
+g_credentials_type_get_type
+G_CREDENTIALS_NATIVE_SIZE
+G_CREDENTIALS_NATIVE_TYPE
+G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
+G_CREDENTIALS_SPOOFING_SUPPORTED
+G_CREDENTIALS_SUPPORTED
+G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
+G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+G_CREDENTIALS_USE_LINUX_UCRED
+G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+G_CREDENTIALS_USE_SOLARIS_UCRED
+</SECTION>
+
+<SECTION>
+<FILE>gdbusaddress</FILE>
+g_dbus_is_address
+g_dbus_is_supported_address
+g_dbus_address_get_stream
+g_dbus_address_get_stream_finish
+g_dbus_address_get_stream_sync
+g_dbus_address_get_for_bus_sync
+g_dbus_address_escape_value
+</SECTION>
+
+<SECTION>
+<FILE>gdbusutils</FILE>
+g_dbus_generate_guid
+g_dbus_is_guid
+g_dbus_is_name
+g_dbus_is_unique_name
+g_dbus_is_member_name
+g_dbus_is_interface_name
+g_dbus_gvalue_to_gvariant
+g_dbus_gvariant_to_gvalue
+</SECTION>
+
+<SECTION>
+<FILE>gdbusauthobserver</FILE>
+<TITLE>GDBusAuthObserver</TITLE>
+GDBusAuthObserver
+g_dbus_auth_observer_new
+g_dbus_auth_observer_authorize_authenticated_peer
+g_dbus_auth_observer_allow_mechanism
+<SUBSECTION Standard>
+G_DBUS_AUTH_OBSERVER
+G_IS_DBUS_AUTH_OBSERVER
+G_TYPE_DBUS_AUTH_OBSERVER
+<SUBSECTION Private>
+g_dbus_auth_observer_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusserver</FILE>
+<TITLE>GDBusServer</TITLE>
+GDBusServer
+GDBusServerFlags
+g_dbus_server_new_sync
+g_dbus_server_start
+g_dbus_server_stop
+g_dbus_server_is_active
+g_dbus_server_get_guid
+g_dbus_server_get_flags
+g_dbus_server_get_client_address
+<SUBSECTION Standard>
+G_DBUS_SERVER
+G_IS_DBUS_SERVER
+G_TYPE_DBUS_SERVER
+G_TYPE_DBUS_SERVER_FLAGS
+<SUBSECTION Private>
+g_dbus_server_get_type
+g_dbus_server_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusmessage</FILE>
+<TITLE>GDBusMessage</TITLE>
+GDBusMessage
+GDBusMessageType
+GDBusMessageFlags
+GDBusMessageHeaderField
+GDBusMessageByteOrder
+g_dbus_message_new
+g_dbus_message_new_signal
+g_dbus_message_new_method_call
+g_dbus_message_new_method_reply
+g_dbus_message_new_method_error
+g_dbus_message_new_method_error_valist
+g_dbus_message_new_method_error_literal
+g_dbus_message_print
+g_dbus_message_get_locked
+g_dbus_message_lock
+g_dbus_message_copy
+g_dbus_message_get_byte_order
+g_dbus_message_set_byte_order
+g_dbus_message_get_message_type
+g_dbus_message_set_message_type
+g_dbus_message_get_serial
+g_dbus_message_set_serial
+g_dbus_message_get_flags
+g_dbus_message_set_flags
+g_dbus_message_get_body
+g_dbus_message_set_body
+g_dbus_message_get_unix_fd_list
+g_dbus_message_set_unix_fd_list
+g_dbus_message_get_num_unix_fds
+g_dbus_message_set_num_unix_fds
+g_dbus_message_get_header_fields
+g_dbus_message_get_header
+g_dbus_message_set_header
+g_dbus_message_get_destination
+g_dbus_message_set_destination
+g_dbus_message_get_error_name
+g_dbus_message_set_error_name
+g_dbus_message_get_interface
+g_dbus_message_set_interface
+g_dbus_message_get_member
+g_dbus_message_set_member
+g_dbus_message_get_path
+g_dbus_message_set_path
+g_dbus_message_get_reply_serial
+g_dbus_message_set_reply_serial
+g_dbus_message_get_sender
+g_dbus_message_set_sender
+g_dbus_message_get_signature
+g_dbus_message_set_signature
+g_dbus_message_get_arg0
+g_dbus_message_to_blob
+g_dbus_message_bytes_needed
+g_dbus_message_new_from_blob
+g_dbus_message_to_gerror
+<SUBSECTION Standard>
+G_DBUS_MESSAGE
+G_IS_DBUS_MESSAGE
+G_TYPE_DBUS_MESSAGE
+G_TYPE_DBUS_MESSAGE_BYTE_ORDER
+G_TYPE_DBUS_MESSAGE_FLAGS
+G_TYPE_DBUS_MESSAGE_HEADER_FIELD
+G_TYPE_DBUS_MESSAGE_TYPE
+<SUBSECTION Private>
+g_dbus_message_get_type
+g_dbus_message_byte_order_get_type
+g_dbus_message_flags_get_type
+g_dbus_message_header_field_get_type
+g_dbus_message_type_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusconnection</FILE>
+<TITLE>GDBusConnection</TITLE>
+GBusType
+g_bus_get
+g_bus_get_finish
+g_bus_get_sync
+GDBusConnection
+GDBusConnectionFlags
+g_dbus_connection_new
+g_dbus_connection_new_finish
+g_dbus_connection_new_sync
+g_dbus_connection_new_for_address
+g_dbus_connection_new_for_address_finish
+g_dbus_connection_new_for_address_sync
+g_dbus_connection_start_message_processing
+g_dbus_connection_close
+g_dbus_connection_close_finish
+g_dbus_connection_close_sync
+g_dbus_connection_is_closed
+g_dbus_connection_flush
+g_dbus_connection_flush_finish
+g_dbus_connection_flush_sync
+g_dbus_connection_get_exit_on_close
+g_dbus_connection_set_exit_on_close
+g_dbus_connection_get_stream
+g_dbus_connection_get_flags
+g_dbus_connection_get_guid
+g_dbus_connection_get_unique_name
+GDBusCapabilityFlags
+g_dbus_connection_get_capabilities
+g_dbus_connection_get_peer_credentials
+g_dbus_connection_get_last_serial
+GDBusCallFlags
+g_dbus_connection_call
+g_dbus_connection_call_finish
+g_dbus_connection_call_sync
+g_dbus_connection_call_with_unix_fd_list
+g_dbus_connection_call_with_unix_fd_list_finish
+g_dbus_connection_call_with_unix_fd_list_sync
+g_dbus_connection_emit_signal
+GDBusSignalFlags
+GDBusSignalCallback
+g_dbus_connection_signal_subscribe
+g_dbus_connection_signal_unsubscribe
+GDBusSendMessageFlags
+g_dbus_connection_send_message
+g_dbus_connection_send_message_with_reply
+g_dbus_connection_send_message_with_reply_finish
+g_dbus_connection_send_message_with_reply_sync
+GDBusMessageFilterFunction
+g_dbus_connection_add_filter
+g_dbus_connection_remove_filter
+GDBusInterfaceVTable
+GDBusInterfaceMethodCallFunc
+GDBusInterfaceGetPropertyFunc
+GDBusInterfaceSetPropertyFunc
+g_dbus_connection_register_object
+g_dbus_connection_unregister_object
+g_dbus_connection_register_object_with_closures
+GDBusSubtreeVTable
+GDBusSubtreeEnumerateFunc
+GDBusSubtreeIntrospectFunc
+GDBusSubtreeDispatchFunc
+GDBusSubtreeFlags
+g_dbus_connection_register_subtree
+g_dbus_connection_unregister_subtree
+<SUBSECTION Standard>
+G_DBUS_CONNECTION
+G_IS_DBUS_CONNECTION
+G_TYPE_DBUS_CONNECTION
+G_TYPE_BUS_TYPE
+G_TYPE_DBUS_CALL_FLAGS
+G_TYPE_DBUS_CAPABILITY_FLAGS
+G_TYPE_DBUS_CONNECTION_FLAGS
+G_TYPE_DBUS_SEND_MESSAGE_FLAGS
+G_TYPE_DBUS_SIGNAL_FLAGS
+G_TYPE_DBUS_SUBTREE_FLAGS
+<SUBSECTION Private>
+g_dbus_connection_get_type
+g_bus_type_get_type
+g_dbus_call_flags_get_type
+g_dbus_capability_flags_get_type
+g_dbus_connection_flags_get_type
+g_dbus_send_message_flags_get_type
+g_dbus_signal_flags_get_type
+g_dbus_subtree_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusmethodinvocation</FILE>
+<TITLE>GDBusMethodInvocation</TITLE>
+GDBusMethodInvocation
+g_dbus_method_invocation_get_sender
+g_dbus_method_invocation_get_object_path
+g_dbus_method_invocation_get_interface_name
+g_dbus_method_invocation_get_method_name
+g_dbus_method_invocation_get_method_info
+g_dbus_method_invocation_get_property_info
+g_dbus_method_invocation_get_connection
+g_dbus_method_invocation_get_message
+g_dbus_method_invocation_get_parameters
+g_dbus_method_invocation_get_user_data
+g_dbus_method_invocation_return_value
+g_dbus_method_invocation_return_error
+g_dbus_method_invocation_return_error_valist
+g_dbus_method_invocation_return_error_literal
+g_dbus_method_invocation_return_gerror
+g_dbus_method_invocation_return_dbus_error
+g_dbus_method_invocation_take_error
+g_dbus_method_invocation_return_value_with_unix_fd_list
+<SUBSECTION Standard>
+G_DBUS_METHOD_INVOCATION
+G_IS_DBUS_METHOD_INVOCATION
+G_TYPE_DBUS_METHOD_INVOCATION
+<SUBSECTION Private>
+g_dbus_method_invocation_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusnameowning</FILE>
+GBusAcquiredCallback
+GBusNameAcquiredCallback
+GBusNameLostCallback
+GBusNameOwnerFlags
+g_bus_own_name
+g_bus_own_name_on_connection
+g_bus_unown_name
+g_bus_own_name_with_closures
+g_bus_own_name_on_connection_with_closures
+
+<SUBSECTION Standard>
+G_TYPE_BUS_NAME_OWNER_FLAGS
+<SUBSECTION Private>
+g_bus_name_owner_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusnamewatching</FILE>
+GBusNameAppearedCallback
+GBusNameVanishedCallback
+GBusNameWatcherFlags
+g_bus_watch_name
+g_bus_watch_name_on_connection
+g_bus_unwatch_name
+g_bus_watch_name_with_closures
+g_bus_watch_name_on_connection_with_closures
+
+<SUBSECTION Standard>
+G_TYPE_BUS_NAME_WATCHER_FLAGS
+<SUBSECTION Private>
+g_bus_name_watcher_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbuserror</FILE>
+GDBusError
+G_DBUS_ERROR
+g_dbus_error_is_remote_error
+g_dbus_error_get_remote_error
+g_dbus_error_strip_remote_error
+GDBusErrorEntry
+g_dbus_error_register_error_domain
+g_dbus_error_register_error
+g_dbus_error_unregister_error
+g_dbus_error_new_for_dbus_error
+g_dbus_error_set_dbus_error
+g_dbus_error_set_dbus_error_valist
+g_dbus_error_encode_gerror
+<SUBSECTION Standard>
+G_TYPE_DBUS_ERROR
+g_dbus_error_quark
+g_dbus_error_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusproxy</FILE>
+<TITLE>GDBusProxy</TITLE>
+GDBusProxyFlags
+GDBusProxy
+GDBusProxyClass
+g_dbus_proxy_new
+g_dbus_proxy_new_finish
+g_dbus_proxy_new_sync
+g_dbus_proxy_new_for_bus
+g_dbus_proxy_new_for_bus_finish
+g_dbus_proxy_new_for_bus_sync
+g_dbus_proxy_get_flags
+g_dbus_proxy_get_connection
+g_dbus_proxy_get_name
+g_dbus_proxy_get_name_owner
+g_dbus_proxy_get_object_path
+g_dbus_proxy_get_interface_name
+g_dbus_proxy_get_default_timeout
+g_dbus_proxy_set_default_timeout
+g_dbus_proxy_get_cached_property
+g_dbus_proxy_set_cached_property
+g_dbus_proxy_get_cached_property_names
+g_dbus_proxy_set_interface_info
+g_dbus_proxy_get_interface_info
+g_dbus_proxy_call
+g_dbus_proxy_call_finish
+g_dbus_proxy_call_sync
+g_dbus_proxy_call_with_unix_fd_list
+g_dbus_proxy_call_with_unix_fd_list_finish
+g_dbus_proxy_call_with_unix_fd_list_sync
+<SUBSECTION Standard>
+G_DBUS_PROXY
+G_IS_DBUS_PROXY
+G_TYPE_DBUS_PROXY
+G_DBUS_PROXY_CLASS
+G_IS_DBUS_PROXY_CLASS
+G_DBUS_PROXY_GET_CLASS
+G_TYPE_DBUS_PROXY_FLAGS
+<SUBSECTION Private>
+GDBusProxyPrivate
+g_dbus_proxy_get_type
+g_dbus_proxy_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusintrospection</FILE>
+GDBusAnnotationInfo
+GDBusArgInfo
+GDBusMethodInfo
+GDBusSignalInfo
+GDBusPropertyInfoFlags
+GDBusPropertyInfo
+GDBusInterfaceInfo
+GDBusNodeInfo
+g_dbus_annotation_info_lookup
+g_dbus_interface_info_lookup_method
+g_dbus_interface_info_lookup_signal
+g_dbus_interface_info_lookup_property
+g_dbus_interface_info_cache_build
+g_dbus_interface_info_cache_release
+g_dbus_interface_info_generate_xml
+g_dbus_node_info_new_for_xml
+g_dbus_node_info_lookup_interface
+g_dbus_node_info_generate_xml
+G_TYPE_DBUS_NODE_INFO
+G_TYPE_DBUS_INTERFACE_INFO
+G_TYPE_DBUS_METHOD_INFO
+G_TYPE_DBUS_SIGNAL_INFO
+G_TYPE_DBUS_PROPERTY_INFO
+G_TYPE_DBUS_ARG_INFO
+G_TYPE_DBUS_ANNOTATION_INFO
+g_dbus_node_info_ref
+g_dbus_interface_info_ref
+g_dbus_method_info_ref
+g_dbus_signal_info_ref
+g_dbus_property_info_ref
+g_dbus_arg_info_ref
+g_dbus_annotation_info_ref
+g_dbus_node_info_unref
+g_dbus_interface_info_unref
+g_dbus_method_info_unref
+g_dbus_signal_info_unref
+g_dbus_property_info_unref
+g_dbus_arg_info_unref
+g_dbus_annotation_info_unref
+<SUBSECTION Standard>
+G_TYPE_DBUS_PROPERTY_INFO_FLAGS
+<SUBSECTION Private>
+g_dbus_annotation_info_get_type
+g_dbus_arg_info_get_type
+g_dbus_interface_info_get_type
+g_dbus_method_info_get_type
+g_dbus_node_info_get_type
+g_dbus_property_info_get_type
+g_dbus_signal_info_get_type
+g_dbus_property_info_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gpermission</FILE>
+GPermission
+g_permission_get_allowed
+g_permission_get_can_acquire
+g_permission_get_can_release
+<SUBSECTION>
+g_permission_acquire
+g_permission_acquire_async
+g_permission_acquire_finish
+g_permission_release
+g_permission_release_async
+g_permission_release_finish
+<SUBSECTION>
+g_permission_impl_update
+<SUBSECTION Standard>
+G_PERMISSION
+G_PERMISSION_CLASS
+G_PERMISSION_GET_CLASS
+G_IS_PERMISSION
+G_IS_PERMISSION_CLASS
+GPermissionClass
+G_TYPE_PERMISSION
+<SUBSECTION Private>
+g_permission_get_type
+GPermissionPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gsimplepermission</FILE>
+GSimplePermission
+g_simple_permission_new
+
+<SUBSECTION Standard>
+G_SIMPLE_PERMISSION
+G_IS_SIMPLE_PERMISSION
+G_TYPE_SIMPLE_PERMISSION
+
+<SUBSECTION Private>
+g_simple_permission_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gapplication</FILE>
+GApplication
+GApplicationClass
+<SUBSECTION>
+GApplicationFlags
+g_application_id_is_valid
+g_application_new
+<SUBSECTION>
+g_application_get_application_id
+g_application_set_application_id
+<SUBSECTION>
+g_application_get_inactivity_timeout
+g_application_set_inactivity_timeout
+<SUBSECTION>
+g_application_get_flags
+g_application_set_flags
+<SUBSECTION>
+g_application_get_resource_base_path
+g_application_set_resource_base_path
+<SUBSECTION>
+g_application_get_dbus_connection
+g_application_get_dbus_object_path
+<SUBSECTION>
+g_application_set_action_group
+<SUBSECTION>
+g_application_get_is_registered
+g_application_get_is_remote
+g_application_register
+<SUBSECTION>
+g_application_hold
+g_application_release
+g_application_quit
+<SUBSECTION>
+g_application_activate
+g_application_open
+<SUBSECTION>
+g_application_send_notification
+g_application_withdraw_notification
+<SUBSECTION>
+g_application_run
+g_application_add_main_option_entries
+g_application_add_main_option
+g_application_add_option_group
+g_application_set_option_context_parameter_string
+g_application_set_option_context_summary
+g_application_set_option_context_description
+<SUBSECTION>
+g_application_set_default
+g_application_get_default
+<SUBSECTION>
+g_application_mark_busy
+g_application_unmark_busy
+g_application_get_is_busy
+g_application_bind_busy_property
+g_application_unbind_busy_property
+<SUBSECTION Standard>
+G_TYPE_APPLICATION
+G_APPLICATION
+G_APPLICATION_CLASS
+G_IS_APPLICATION
+G_IS_APPLICATION_CLASS
+G_APPLICATION_GET_CLASS
+G_TYPE_APPLICATION_FLAGS
+<SUBSECTION Private>
+GApplicationPrivate
+g_application_get_type
+g_application_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gapplicationcommandline</FILE>
+GApplicationCommandLine
+GApplicationCommandLineClass
+<SUBSECTION>
+g_application_command_line_get_arguments
+g_application_command_line_get_cwd
+g_application_command_line_get_environ
+g_application_command_line_get_options_dict
+g_application_command_line_get_stdin
+g_application_command_line_create_file_for_arg
+g_application_command_line_getenv
+g_application_command_line_get_is_remote
+g_application_command_line_get_platform_data
+<SUBSECTION>
+g_application_command_line_set_exit_status
+g_application_command_line_get_exit_status
+<SUBSECTION>
+g_application_command_line_print
+g_application_command_line_printerr
+<SUBSECTION Standard>
+G_TYPE_APPLICATION_COMMAND_LINE
+G_APPLICATION_COMMAND_LINE
+G_APPLICATION_COMMAND_LINE_CLASS
+G_IS_APPLICATION_COMMAND_LINE
+G_IS_APPLICATION_COMMAND_LINE_CLASS
+G_APPLICATION_COMMAND_LINE_GET_CLASS
+<SUBSECTION Private>
+GApplicationCommandLinePrivate
+g_application_command_line_get_type
+</SECTION>
+
+
+<SECTION>
+<FILE>gactiongroup</FILE>
+<TITLE>GActionGroup</TITLE>
+GActionGroup
+GActionGroupInterface
+
+<SUBSECTION>
+g_action_group_list_actions
+g_action_group_query_action
+
+<SUBSECTION>
+g_action_group_has_action
+g_action_group_get_action_enabled
+g_action_group_get_action_parameter_type
+g_action_group_get_action_state_type
+g_action_group_get_action_state_hint
+g_action_group_get_action_state
+
+<SUBSECTION>
+g_action_group_change_action_state
+g_action_group_activate_action
+
+<SUBSECTION>
+g_action_group_action_added
+g_action_group_action_removed
+g_action_group_action_enabled_changed
+g_action_group_action_state_changed
+
+<SUBSECTION Standard>
+g_action_group_get_type
+G_TYPE_ACTION_GROUP
+G_IS_ACTION_GROUP
+G_ACTION_GROUP_GET_IFACE
+G_ACTION_GROUP
+</SECTION>
+
+<SECTION>
+<FILE>gactiongroupexporter</FILE>
+g_dbus_connection_export_action_group
+g_dbus_connection_unexport_action_group
+</SECTION>
+
+<SECTION>
+<FILE>gdbusactiongroup</FILE>
+GDBusActionGroup
+g_dbus_action_group_get
+
+<SUBSECTION Standard>
+G_TYPE_DBUS_ACTION_GROUP
+G_DBUS_ACTION_GROUP
+G_DBUS_ACTION_GROUP_CLASS
+G_IS_DBUS_ACTION_GROUP
+G_IS_DBUS_ACTION_GROUP_CLASS
+G_DBUS_ACTION_GROUP_GET_CLASS
+
+<SUBSECTION Private>
+g_dbus_action_group_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gremoteactiongroup</FILE>
+GRemoteActionGroup
+GRemoteActionGroupInterface
+
+<SUBSECTION>
+g_remote_action_group_activate_action_full
+g_remote_action_group_change_action_state_full
+
+<SUBSECTION Standard>
+G_TYPE_REMOTE_ACTION_GROUP
+G_REMOTE_ACTION_GROUP
+G_IS_REMOTE_ACTION_GROUP
+G_REMOTE_ACTION_GROUP_GET_IFACE
+g_remote_action_group_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gaction</FILE>
+<TITLE>GAction</TITLE>
+GAction
+GActionInterface
+
+<SUBSECTION>
+g_action_name_is_valid
+g_action_get_name
+g_action_get_parameter_type
+g_action_get_state_type
+g_action_get_state_hint
+
+<SUBSECTION>
+g_action_get_enabled
+g_action_get_state
+
+<SUBSECTION>
+g_action_change_state
+g_action_activate
+
+<SUBSECTION>
+g_action_parse_detailed_name
+g_action_print_detailed_name
+
+<SUBSECTION Standard>
+g_action_get_type
+G_TYPE_ACTION
+G_IS_ACTION
+G_ACTION_GET_IFACE
+G_ACTION
+</SECTION>
+
+<SECTION>
+<FILE>gsimpleaction</FILE>
+<TITLE>GSimpleAction</TITLE>
+GSimpleAction
+
+<SUBSECTION>
+g_simple_action_new
+g_simple_action_new_stateful
+
+<SUBSECTION>
+g_simple_action_set_enabled
+g_simple_action_set_state
+g_simple_action_set_state_hint
+
+<SUBSECTION Standard>
+g_simple_action_get_type
+G_TYPE_SIMPLE_ACTION
+G_IS_SIMPLE_ACTION
+G_SIMPLE_ACTION
+</SECTION>
+
+<SECTION>
+<FILE>gpropertyaction</FILE>
+<TITLE>GPropertyAction</TITLE>
+GPropertyAction
+
+<SUBSECTION>
+g_property_action_new
+
+<SUBSECTION Standard>
+g_property_action_get_type
+G_TYPE_PROPERTY_ACTION
+G_IS_PROPERTY_ACTION
+G_PROPERTY_ACTION
+</SECTION>
+
+<SECTION>
+<FILE>gsimpleactiongroup</FILE>
+<TITLE>GSimpleActionGroup</TITLE>
+GSimpleActionGroup
+
+<SUBSECTION>
+g_simple_action_group_new
+
+<SUBSECTION>
+g_simple_action_group_lookup
+g_simple_action_group_insert
+g_simple_action_group_remove
+
+<SUBSECTION>
+g_simple_action_group_add_entries
+
+<SUBSECTION Standard>
+GSimpleActionGroupClass
+GSimpleActionGroupPrivate
+g_simple_action_group_get_type
+G_TYPE_SIMPLE_ACTION_GROUP
+G_IS_SIMPLE_ACTION_GROUP
+G_SIMPLE_ACTION_GROUP_CLASS
+G_SIMPLE_ACTION_GROUP_GET_CLASS
+G_IS_SIMPLE_ACTION_GROUP_CLASS
+G_SIMPLE_ACTION_GROUP
+</SECTION>
+
+<SECTION>
+<FILE>gactionmap</FILE>
+<TITLE>GActionMap</TITLE>
+GActionMap
+GActionMapInterface
+g_action_map_lookup_action
+GActionEntry
+g_action_map_add_action_entries
+g_action_map_add_action
+g_action_map_remove_action
+
+<SUBSECTION Standard>
+G_TYPE_ACTION_MAP
+G_ACTION_MAP
+G_IS_ACTION_MAP
+G_ACTION_MAP_GET_IFACE
+
+<SUBSECTION Private>
+g_action_map_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gproxyresolver</FILE>
+<TITLE>GProxyResolver</TITLE>
+GProxyResolver
+GProxyResolverInterface
+G_PROXY_RESOLVER_EXTENSION_POINT_NAME
+g_proxy_resolver_get_default
+g_proxy_resolver_is_supported
+g_proxy_resolver_lookup
+g_proxy_resolver_lookup_async
+g_proxy_resolver_lookup_finish
+<SUBSECTION Standard>
+G_PROXY_RESOLVER
+G_IS_PROXY_RESOLVER
+G_TYPE_PROXY_RESOLVER
+G_PROXY_RESOLVER_GET_IFACE
+<SUBSECTION Private>
+g_proxy_resolver_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gproxyaddress</FILE>
+<TITLE>GProxyAddress</TITLE>
+GProxyAddress
+GProxyAddressClass
+g_proxy_address_get_destination_protocol
+g_proxy_address_get_destination_hostname
+g_proxy_address_get_destination_port
+g_proxy_address_get_password
+g_proxy_address_get_protocol
+g_proxy_address_get_username
+g_proxy_address_get_uri
+g_proxy_address_new
+<SUBSECTION Standard>
+G_PROXY_ADDRESS
+G_PROXY_ADDRESS_CLASS
+G_PROXY_ADDRESS_GET_CLASS
+G_IS_PROXY_ADDRESS
+G_IS_PROXY_ADDRESS_CLASS
+G_TYPE_PROXY_ADDRESS
+<SUBSECTION Private>
+GProxyAddressPrivate
+g_proxy_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gproxy</FILE>
+<TITLE>GProxy</TITLE>
+GProxy
+GProxyInterface
+G_PROXY_EXTENSION_POINT_NAME
+g_proxy_connect
+g_proxy_connect_async
+g_proxy_connect_finish
+g_proxy_get_default_for_protocol
+g_proxy_supports_hostname
+<SUBSECTION Standard>
+G_PROXY
+G_PROXY_GET_IFACE
+G_IS_PROXY
+G_TYPE_PROXY
+<SUBSECTION Private>
+g_proxy_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gpollableinputstream</FILE>
+<TITLE>GPollableInputStream</TITLE>
+GPollableInputStream
+GPollableInputStreamInterface
+<SUBSECTION>
+g_pollable_input_stream_can_poll
+g_pollable_input_stream_is_readable
+g_pollable_input_stream_create_source
+g_pollable_input_stream_read_nonblocking
+<SUBSECTION Standard>
+G_POLLABLE_INPUT_STREAM
+G_POLLABLE_INPUT_STREAM_GET_INTERFACE
+G_IS_POLLABLE_INPUT_STREAM
+G_TYPE_POLLABLE_INPUT_STREAM
+<SUBSECTION Private>
+g_pollable_input_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gpollableoutputstream</FILE>
+<TITLE>GPollableOutputStream</TITLE>
+GPollableOutputStream
+GPollableOutputStreamInterface
+<SUBSECTION>
+g_pollable_output_stream_can_poll
+g_pollable_output_stream_is_writable
+g_pollable_output_stream_create_source
+g_pollable_output_stream_write_nonblocking
+g_pollable_output_stream_writev_nonblocking
+<SUBSECTION Standard>
+G_POLLABLE_OUTPUT_STREAM
+G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE
+G_IS_POLLABLE_OUTPUT_STREAM
+G_TYPE_POLLABLE_OUTPUT_STREAM
+<SUBSECTION Private>
+g_pollable_output_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gpollableutils</FILE>
+GPollableReturn
+GPollableSourceFunc
+g_pollable_source_new
+g_pollable_source_new_full
+<SUBSECTION>
+g_pollable_stream_read
+g_pollable_stream_write
+g_pollable_stream_write_all
+<SUBSECTION Standard>
+G_TYPE_POLLABLE_RETURN
+<SUBSECTION Private>
+g_pollable_return_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtls</FILE>
+G_TLS_ERROR
+GTlsError
+<SUBSECTION>
+GTlsAuthenticationMode
+GTlsCertificateFlags
+<SUBSECTION Standard>
+G_TYPE_TLS_AUTHENTICATION_MODE
+G_TYPE_TLS_CERTIFICATE_FLAGS
+G_TYPE_TLS_ERROR
+g_tls_authentication_mode_get_type
+g_tls_certificate_flags_get_type
+g_tls_error_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlsbackend</FILE>
+<TITLE>GTlsBackend</TITLE>
+G_TLS_BACKEND_EXTENSION_POINT_NAME
+GTlsBackend
+GTlsBackendInterface
+g_tls_backend_get_default
+g_tls_backend_supports_tls
+g_tls_backend_supports_dtls
+g_tls_backend_get_default_database
+g_tls_backend_set_default_database
+g_tls_backend_get_certificate_type
+g_tls_backend_get_client_connection_type
+g_tls_backend_get_server_connection_type
+g_tls_backend_get_dtls_client_connection_type
+g_tls_backend_get_dtls_server_connection_type
+g_tls_backend_get_file_database_type
+<SUBSECTION Standard>
+G_IS_TLS_BACKEND
+G_TLS_BACKEND
+G_TLS_BACKEND_GET_INTERFACE
+G_TYPE_TLS_BACKEND
+g_tls_error_quark
+<SUBSECTION Private>
+g_tls_backend_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlscertificate</FILE>
+<TITLE>GTlsCertificate</TITLE>
+GTlsCertificate
+g_tls_certificate_new_from_pem
+g_tls_certificate_new_from_file
+g_tls_certificate_new_from_files
+g_tls_certificate_list_new_from_file
+g_tls_certificate_get_issuer
+g_tls_certificate_verify
+g_tls_certificate_is_same
+<SUBSECTION Standard>
+GTlsCertificateClass
+GTlsCertificatePrivate
+G_IS_TLS_CERTIFICATE
+G_IS_TLS_CERTIFICATE_CLASS
+G_TLS_CERTIFICATE
+G_TLS_CERTIFICATE_CLASS
+G_TLS_CERTIFICATE_GET_CLASS
+G_TYPE_TLS_CERTIFICATE
+<SUBSECTION Private>
+g_tls_certificate_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlsconnection</FILE>
+<TITLE>GTlsConnection</TITLE>
+GTlsConnection
+g_tls_connection_set_certificate
+g_tls_connection_get_certificate
+g_tls_connection_get_peer_certificate
+g_tls_connection_get_peer_certificate_errors
+g_tls_connection_set_require_close_notify
+g_tls_connection_get_require_close_notify
+GTlsRehandshakeMode
+g_tls_connection_set_rehandshake_mode
+g_tls_connection_get_rehandshake_mode
+g_tls_connection_set_advertised_protocols
+g_tls_connection_get_negotiated_protocol
+g_tls_connection_set_use_system_certdb
+g_tls_connection_get_use_system_certdb
+g_tls_connection_get_database
+g_tls_connection_set_database
+g_tls_connection_get_interaction
+g_tls_connection_set_interaction
+<SUBSECTION>
+g_tls_connection_handshake
+g_tls_connection_handshake_async
+g_tls_connection_handshake_finish
+<SUBSECTION>
+g_tls_connection_emit_accept_certificate
+<SUBSECTION Standard>
+GTlsConnectionClass
+GTlsConnectionPrivate
+G_IS_TLS_CONNECTION
+G_IS_TLS_CONNECTION_CLASS
+G_TLS_CONNECTION
+G_TLS_CONNECTION_CLASS
+G_TLS_CONNECTION_GET_CLASS
+G_TYPE_TLS_CONNECTION
+G_TYPE_TLS_REHANDSHAKE_MODE
+<SUBSECTION Private>
+g_tls_connection_get_type
+g_tls_rehandshake_mode_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlsclientconnection</FILE>
+<TITLE>GTlsClientConnection</TITLE>
+GTlsClientConnection
+GTlsClientConnectionInterface
+g_tls_client_connection_new
+g_tls_client_connection_set_server_identity
+g_tls_client_connection_get_server_identity
+g_tls_client_connection_set_validation_flags
+g_tls_client_connection_get_validation_flags
+g_tls_client_connection_set_use_ssl3
+g_tls_client_connection_get_use_ssl3
+g_tls_client_connection_get_accepted_cas
+g_tls_client_connection_copy_session_state
+<SUBSECTION Standard>
+G_IS_TLS_CLIENT_CONNECTION
+G_TLS_CLIENT_CONNECTION
+G_TLS_CLIENT_CONNECTION_GET_INTERFACE
+G_TYPE_TLS_CLIENT_CONNECTION
+<SUBSECTION Private>
+g_tls_client_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlsdatabase</FILE>
+<TITLE>GTlsDatabase</TITLE>
+GTlsDatabase
+GTlsDatabaseClass
+GTlsDatabaseVerifyFlags
+G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER
+G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT
+g_tls_database_verify_chain
+g_tls_database_verify_chain_async
+g_tls_database_verify_chain_finish
+GTlsDatabaseLookupFlags
+g_tls_database_lookup_certificate_issuer
+g_tls_database_lookup_certificate_issuer_async
+g_tls_database_lookup_certificate_issuer_finish
+g_tls_database_lookup_certificates_issued_by
+g_tls_database_lookup_certificates_issued_by_async
+g_tls_database_lookup_certificates_issued_by_finish
+g_tls_database_create_certificate_handle
+g_tls_database_lookup_certificate_for_handle
+g_tls_database_lookup_certificate_for_handle_async
+g_tls_database_lookup_certificate_for_handle_finish
+<SUBSECTION Standard>
+G_IS_TLS_DATABASE
+G_IS_TLS_DATABASE_CLASS
+G_TLS_DATABASE
+G_TLS_DATABASE_CLASS
+G_TLS_DATABASE_GET_CLASS
+G_TYPE_TLS_DATABASE
+G_TYPE_TLS_DATABASE_LOOKUP_FLAGS
+G_TYPE_TLS_DATABASE_VERIFY_FLAGS
+<SUBSECTION Private>
+g_tls_database_lookup_flags_get_type
+g_tls_database_verify_flags_get_type
+g_tls_database_get_type
+GTlsDatabasePrivate
+</SECTION>
+
+<SECTION>
+<FILE>gtlsfiledatabase</FILE>
+<TITLE>GTlsFileDatabase</TITLE>
+GTlsFileDatabase
+GTlsFileDatabaseInterface
+g_tls_file_database_new
+<SUBSECTION Standard>
+G_TLS_FILE_DATABASE
+G_TLS_FILE_DATABASE_GET_INTERFACE
+G_TYPE_TLS_FILE_DATABASE
+G_IS_TLS_FILE_DATABASE
+<SUBSECTION Private>
+g_tls_file_database_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlsserverconnection</FILE>
+<TITLE>GTlsServerConnection</TITLE>
+GTlsServerConnection
+GTlsServerConnectionInterface
+g_tls_server_connection_new
+<SUBSECTION Standard>
+G_IS_TLS_SERVER_CONNECTION
+G_TLS_SERVER_CONNECTION
+G_TLS_SERVER_CONNECTION_GET_INTERFACE
+G_TYPE_TLS_SERVER_CONNECTION
+<SUBSECTION Private>
+g_tls_server_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gtlspassword</FILE>
+<TITLE>GTlsPassword</TITLE>
+GTlsPassword
+GTlsPasswordClass
+GTlsPasswordFlags
+g_tls_password_new
+g_tls_password_get_value
+g_tls_password_set_value
+g_tls_password_set_value_full
+g_tls_password_get_description
+g_tls_password_set_description
+g_tls_password_get_flags
+g_tls_password_set_flags
+g_tls_password_get_warning
+g_tls_password_set_warning
+<SUBSECTION Standard>
+g_tls_password_flags_get_type
+g_tls_password_get_type
+G_IS_TLS_PASSWORD
+G_TLS_PASSWORD
+G_TYPE_TLS_PASSWORD
+G_TYPE_TLS_PASSWORD_FLAGS
+G_TLS_PASSWORD_CLASS
+G_TLS_PASSWORD_GET_CLASS
+G_IS_TLS_PASSWORD_CLASS
+<SUBSECTION Private>
+GTlsPasswordPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gtlsinteraction</FILE>
+<TITLE>GTlsInteraction</TITLE>
+GTlsInteraction
+GTlsInteractionResult
+GTlsCertificateRequestFlags
+GTlsInteractionClass
+g_tls_interaction_invoke_ask_password
+g_tls_interaction_invoke_request_certificate
+g_tls_interaction_ask_password
+g_tls_interaction_ask_password_async
+g_tls_interaction_ask_password_finish
+g_tls_interaction_request_certificate
+g_tls_interaction_request_certificate_async
+g_tls_interaction_request_certificate_finish
+<SUBSECTION Standard>
+G_IS_TLS_INTERACTION
+G_IS_TLS_INTERACTION_CLASS
+G_TYPE_TLS_INTERACTION
+G_TLS_INTERACTION
+G_TLS_INTERACTION_CLASS
+G_TLS_INTERACTION_GET_CLASS
+G_TYPE_TLS_INTERACTION_RESULT
+G_TYPE_TLS_CERTIFICATE_REQUEST_FLAGS
+<SUBSECTION Private>
+GTlsInteractionPrivate
+g_tls_interaction_get_type
+g_tls_interaction_result_get_type
+g_tls_certificate_request_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdtlsconnection</FILE>
+<TITLE>GDtlsConnection</TITLE>
+GDtlsConnection
+g_dtls_connection_set_certificate
+g_dtls_connection_get_certificate
+g_dtls_connection_get_peer_certificate
+g_dtls_connection_get_peer_certificate_errors
+g_dtls_connection_set_require_close_notify
+g_dtls_connection_get_require_close_notify
+g_dtls_connection_set_rehandshake_mode
+g_dtls_connection_get_rehandshake_mode
+g_dtls_connection_set_advertised_protocols
+g_dtls_connection_get_negotiated_protocol
+g_dtls_connection_get_database
+g_dtls_connection_set_database
+g_dtls_connection_get_interaction
+g_dtls_connection_set_interaction
+<SUBSECTION>
+g_dtls_connection_handshake
+g_dtls_connection_handshake_async
+g_dtls_connection_handshake_finish
+<SUBSECTION>
+g_dtls_connection_shutdown
+g_dtls_connection_shutdown_async
+g_dtls_connection_shutdown_finish
+g_dtls_connection_close
+g_dtls_connection_close_async
+g_dtls_connection_close_finish
+<SUBSECTION>
+g_dtls_connection_emit_accept_certificate
+<SUBSECTION Standard>
+GDtlsConnectionClass
+GDtlsConnectionPrivate
+G_IS_DTLS_CONNECTION
+G_IS_DTLS_CONNECTION_CLASS
+G_DTLS_CONNECTION
+G_DTLS_CONNECTION_CLASS
+G_DTLS_CONNECTION_GET_CLASS
+G_TYPE_DTLS_CONNECTION
+G_DTLS_CONNECTION_GET_INTERFACE
+<SUBSECTION Private>
+g_dtls_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdtlsclientconnection</FILE>
+<TITLE>GDtlsClientConnection</TITLE>
+GDtlsClientConnection
+GDtlsClientConnectionInterface
+g_dtls_client_connection_new
+g_dtls_client_connection_set_server_identity
+g_dtls_client_connection_get_server_identity
+g_dtls_client_connection_set_validation_flags
+g_dtls_client_connection_get_validation_flags
+g_dtls_client_connection_get_accepted_cas
+<SUBSECTION Standard>
+G_IS_DTLS_CLIENT_CONNECTION
+G_DTLS_CLIENT_CONNECTION
+G_DTLS_CLIENT_CONNECTION_GET_INTERFACE
+G_TYPE_DTLS_CLIENT_CONNECTION
+<SUBSECTION Private>
+g_dtls_client_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdtlsserverconnection</FILE>
+<TITLE>GDtlsServerConnection</TITLE>
+GDtlsServerConnection
+GDtlsServerConnectionInterface
+g_dtls_server_connection_new
+<SUBSECTION Standard>
+G_IS_DTLS_SERVER_CONNECTION
+G_DTLS_SERVER_CONNECTION
+G_DTLS_SERVER_CONNECTION_GET_INTERFACE
+G_TYPE_DTLS_SERVER_CONNECTION
+<SUBSECTION Private>
+g_dtls_server_connection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusinterface</FILE>
+<TITLE>GDBusInterface</TITLE>
+GDBusInterface
+GDBusInterfaceIface
+g_dbus_interface_get_info
+g_dbus_interface_get_object
+g_dbus_interface_dup_object
+g_dbus_interface_set_object
+<SUBSECTION Standard>
+G_DBUS_INTERFACE
+G_IS_DBUS_INTERFACE
+G_TYPE_DBUS_INTERFACE
+g_dbus_interface_get_type
+G_DBUS_INTERFACE_GET_IFACE
+</SECTION>
+
+
+<SECTION>
+<FILE>gdbusinterfaceskeleton</FILE>
+<TITLE>GDBusInterfaceSkeleton</TITLE>
+GDBusInterfaceSkeleton
+GDBusInterfaceSkeletonClass
+g_dbus_interface_skeleton_flush
+g_dbus_interface_skeleton_get_info
+g_dbus_interface_skeleton_get_vtable
+g_dbus_interface_skeleton_get_properties
+g_dbus_interface_skeleton_export
+g_dbus_interface_skeleton_unexport
+g_dbus_interface_skeleton_unexport_from_connection
+g_dbus_interface_skeleton_get_connection
+g_dbus_interface_skeleton_get_connections
+g_dbus_interface_skeleton_has_connection
+g_dbus_interface_skeleton_get_object_path
+GDBusInterfaceSkeletonFlags
+g_dbus_interface_skeleton_get_flags
+g_dbus_interface_skeleton_set_flags
+<SUBSECTION Standard>
+G_DBUS_INTERFACE_SKELETON
+G_IS_DBUS_INTERFACE_SKELETON
+G_TYPE_DBUS_INTERFACE_SKELETON
+g_dbus_interface_skeleton_get_type
+G_DBUS_INTERFACE_SKELETON_CLASS
+G_IS_DBUS_INTERFACE_SKELETON_CLASS
+G_DBUS_INTERFACE_SKELETON_GET_CLASS
+<SUBSECTION Private>
+GDBusInterfaceSkeletonPrivate
+G_TYPE_DBUS_INTERFACE_SKELETON_FLAGS
+g_dbus_interface_skeleton_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusobject</FILE>
+<TITLE>GDBusObject</TITLE>
+GDBusObject
+GDBusObjectIface
+g_dbus_object_get_object_path
+g_dbus_object_get_interfaces
+g_dbus_object_get_interface
+<SUBSECTION Standard>
+G_DBUS_OBJECT
+G_IS_DBUS_OBJECT
+G_TYPE_DBUS_OBJECT
+g_dbus_object_get_type
+G_DBUS_OBJECT_GET_IFACE
+</SECTION>
+
+<SECTION>
+<FILE>gdbusobjectproxy</FILE>
+<TITLE>GDBusObjectProxy</TITLE>
+GDBusObjectProxy
+GDBusObjectProxyClass
+g_dbus_object_proxy_new
+g_dbus_object_proxy_get_connection
+<SUBSECTION Standard>
+G_DBUS_OBJECT_PROXY
+G_IS_DBUS_OBJECT_PROXY
+G_TYPE_DBUS_OBJECT_PROXY
+g_dbus_object_proxy_get_type
+G_DBUS_OBJECT_PROXY_CLASS
+G_IS_DBUS_OBJECT_PROXY_CLASS
+G_DBUS_OBJECT_PROXY_GET_CLASS
+<SUBSECTION Private>
+GDBusObjectProxyPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gdbusobjectskeleton</FILE>
+<TITLE>GDBusObjectSkeleton</TITLE>
+GDBusObjectSkeleton
+GDBusObjectSkeletonClass
+g_dbus_object_skeleton_new
+g_dbus_object_skeleton_flush
+g_dbus_object_skeleton_add_interface
+g_dbus_object_skeleton_remove_interface
+g_dbus_object_skeleton_remove_interface_by_name
+g_dbus_object_skeleton_set_object_path
+<SUBSECTION Standard>
+G_DBUS_OBJECT_SKELETON
+G_IS_DBUS_OBJECT_SKELETON
+G_TYPE_DBUS_OBJECT_SKELETON
+g_dbus_object_skeleton_get_type
+G_DBUS_OBJECT_SKELETON_CLASS
+G_IS_DBUS_OBJECT_SKELETON_CLASS
+G_DBUS_OBJECT_SKELETON_GET_CLASS
+<SUBSECTION Private>
+GDBusObjectSkeletonPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gdbusobjectmanager</FILE>
+<TITLE>GDBusObjectManager</TITLE>
+GDBusObjectManager
+GDBusObjectManagerIface
+g_dbus_object_manager_get_object_path
+g_dbus_object_manager_get_objects
+g_dbus_object_manager_get_object
+g_dbus_object_manager_get_interface
+<SUBSECTION Standard>
+G_DBUS_OBJECT_MANAGER
+G_IS_DBUS_OBJECT_MANAGER
+G_TYPE_DBUS_OBJECT_MANAGER
+g_dbus_object_manager_get_type
+G_DBUS_OBJECT_MANAGER_GET_IFACE
+</SECTION>
+
+<SECTION>
+<FILE>gdbusobjectmanagerclient</FILE>
+<TITLE>GDBusObjectManagerClient</TITLE>
+GDBusObjectManagerClient
+GDBusObjectManagerClientClass
+GDBusObjectManagerClientFlags
+GDBusProxyTypeFunc
+g_dbus_object_manager_client_new
+g_dbus_object_manager_client_new_finish
+g_dbus_object_manager_client_new_sync
+g_dbus_object_manager_client_new_for_bus
+g_dbus_object_manager_client_new_for_bus_finish
+g_dbus_object_manager_client_new_for_bus_sync
+g_dbus_object_manager_client_get_connection
+g_dbus_object_manager_client_get_flags
+g_dbus_object_manager_client_get_name
+g_dbus_object_manager_client_get_name_owner
+<SUBSECTION Standard>
+G_DBUS_OBJECT_MANAGER_CLIENT
+G_IS_DBUS_OBJECT_MANAGER_CLIENT
+G_TYPE_DBUS_OBJECT_MANAGER_CLIENT
+g_dbus_object_manager_client_get_type
+G_DBUS_OBJECT_MANAGER_CLIENT_CLASS
+G_IS_DBUS_OBJECT_MANAGER_CLIENT_CLASS
+G_DBUS_OBJECT_MANAGER_CLIENT_GET_CLASS
+<SUBSECTION Private>
+GDBusObjectManagerClientPrivate
+G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS
+g_dbus_object_manager_client_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gdbusobjectmanagerserver</FILE>
+<TITLE>GDBusObjectManagerServer</TITLE>
+GDBusObjectManagerServer
+GDBusObjectManagerServerClass
+g_dbus_object_manager_server_new
+g_dbus_object_manager_server_get_connection
+g_dbus_object_manager_server_set_connection
+g_dbus_object_manager_server_export
+g_dbus_object_manager_server_export_uniquely
+g_dbus_object_manager_server_is_exported
+g_dbus_object_manager_server_unexport
+<SUBSECTION Standard>
+G_DBUS_OBJECT_MANAGER_SERVER
+G_IS_DBUS_OBJECT_MANAGER_SERVER
+G_TYPE_DBUS_OBJECT_MANAGER_SERVER
+g_dbus_object_manager_server_get_type
+G_DBUS_OBJECT_MANAGER_SERVER_CLASS
+G_IS_DBUS_OBJECT_MANAGER_SERVER_CLASS
+G_DBUS_OBJECT_MANAGER_SERVER_GET_CLASS
+<SUBSECTION Private>
+GDBusObjectManagerServerPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gmemorymonitor</FILE>
+<TITLE>GMemoryMonitor</TITLE>
+GMemoryMonitor
+GMemoryMonitorInterface
+GMemoryMonitorWarningLevel
+G_MEMORY_MONITOR_EXTENSION_POINT_NAME
+g_memory_monitor_dup_default
+<SUBSECTION Standard>
+g_memory_monitor_get_type
+G_TYPE_MEMORY_MONITOR
+G_MEMORY_MONITOR
+G_IS_MEMORY_MONITOR
+G_MEMORY_MONITOR_GET_INTERFACE
+G_TYPE_MEMORY_MONITOR_WARNING_LEVEL
+g_memory_monitor_warning_level_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gnetworkmonitor</FILE>
+<TITLE>GNetworkMonitor</TITLE>
+GNetworkMonitor
+GNetworkMonitorInterface
+G_NETWORK_MONITOR_EXTENSION_POINT_NAME
+g_network_monitor_get_default
+g_network_monitor_get_network_available
+g_network_monitor_get_network_metered
+g_network_monitor_can_reach
+g_network_monitor_can_reach_async
+g_network_monitor_can_reach_finish
+GNetworkConnectivity
+g_network_monitor_get_connectivity
+<SUBSECTION Standard>
+g_network_monitor_get_type
+G_TYPE_NETWORK_CONNECTIVITY
+G_TYPE_NETWORK_MONITOR
+G_NETWORK_MONITOR
+G_IS_NETWORK_MONITOR
+G_NETWORK_MONITOR_GET_INTERFACE
+g_network_connectivity_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gmenuexporter</FILE>
+g_dbus_connection_export_menu_model
+g_dbus_connection_unexport_menu_model
+</SECTION>
+
+<SECTION>
+<FILE>gdbusmenumodel</FILE>
+GDBusMenuModel
+g_dbus_menu_model_get
+
+<SUBSECTION Standard>
+G_TYPE_DBUS_MENU_MODEL
+G_DBUS_MENU_MODEL
+G_IS_DBUS_MENU_MODEL
+
+<SUBSECTION Private>
+g_dbus_menu_model_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gmenu</FILE>
+GMenu
+g_menu_new
+g_menu_freeze
+
+<SUBSECTION>
+g_menu_insert
+g_menu_prepend
+g_menu_append
+
+<SUBSECTION>
+g_menu_insert_item
+g_menu_append_item
+g_menu_prepend_item
+
+<SUBSECTION>
+g_menu_insert_section
+g_menu_prepend_section
+g_menu_append_section
+
+<SUBSECTION>
+g_menu_append_submenu
+g_menu_insert_submenu
+g_menu_prepend_submenu
+
+<SUBSECTION>
+g_menu_remove
+g_menu_remove_all
+
+<SUBSECTION>
+GMenuItem
+g_menu_item_new
+g_menu_item_new_section
+g_menu_item_new_submenu
+g_menu_item_new_from_model
+
+<SUBSECTION>
+g_menu_item_set_label
+g_menu_item_set_icon
+g_menu_item_set_action_and_target_value
+g_menu_item_set_action_and_target
+g_menu_item_set_detailed_action
+g_menu_item_set_section
+g_menu_item_set_submenu
+
+<SUBSECTION>
+g_menu_item_get_attribute_value
+g_menu_item_get_attribute
+g_menu_item_get_link
+g_menu_item_set_attribute_value
+g_menu_item_set_attribute
+g_menu_item_set_link
+
+<SUBSECTION Private>
+g_menu_item_get_type
+g_menu_get_type
+
+<SUBSECTION Standard>
+G_TYPE_MENU
+G_MENU
+G_IS_MENU
+
+G_TYPE_MENU_ITEM
+G_MENU_ITEM
+G_IS_MENU_ITEM
+</SECTION>
+
+<SECTION>
+<FILE>gmenumodel</FILE>
+GMenuModel
+g_menu_model_is_mutable
+g_menu_model_get_n_items
+
+<SUBSECTION>
+G_MENU_ATTRIBUTE_ACTION
+G_MENU_ATTRIBUTE_ACTION_NAMESPACE
+G_MENU_ATTRIBUTE_TARGET
+G_MENU_ATTRIBUTE_LABEL
+G_MENU_ATTRIBUTE_ICON
+G_MENU_LINK_SECTION
+G_MENU_LINK_SUBMENU
+
+<SUBSECTION>
+g_menu_model_get_item_attribute_value
+g_menu_model_get_item_attribute
+g_menu_model_get_item_link
+g_menu_model_iterate_item_attributes
+g_menu_model_iterate_item_links
+
+<SUBSECTION>
+g_menu_model_items_changed
+
+<SUBSECTION>
+GMenuAttributeIter
+g_menu_attribute_iter_get_next
+g_menu_attribute_iter_get_name
+g_menu_attribute_iter_get_value
+g_menu_attribute_iter_next
+
+<SUBSECTION>
+GMenuLinkIter
+g_menu_link_iter_get_name
+g_menu_link_iter_get_next
+g_menu_link_iter_get_value
+g_menu_link_iter_next
+
+<SUBSECTION Private>
+g_menu_attribute_iter_get_type
+g_menu_link_iter_get_type
+g_menu_model_get_type
+g_menu_model_get_label_quark
+g_menu_model_get_action_quark
+g_menu_model_get_section_quark
+g_menu_model_get_submenu_quark
+g_menu_model_get_target_quark
+
+<SUBSECTION Standard>
+GMenuModelClass
+GMenuModelPrivate
+G_TYPE_MENU_MODEL
+G_MENU_MODEL
+G_IS_MENU_MODEL
+G_MENU_MODEL_CLASS
+G_IS_MENU_MODEL_CLASS
+G_MENU_MODEL_GET_CLASS
+
+GMenuAttributeIterClass
+GMenuAttributeIterPrivate
+G_TYPE_MENU_LINK_ITER
+G_MENU_LINK_ITER
+G_IS_MENU_LINK_ITER
+G_MENU_LINK_ITER_CLASS
+G_IS_MENU_LINK_ITER_CLASS
+G_MENU_LINK_ITER_GET_CLASS
+
+GMenuLinkIterClass
+GMenuLinkIterPrivate
+G_TYPE_MENU_ATTRIBUTE_ITER
+G_MENU_ATTRIBUTE_ITER
+G_IS_MENU_ATTRIBUTE_ITER
+G_MENU_ATTRIBUTE_ITER_CLASS
+G_IS_MENU_ATTRIBUTE_ITER_CLASS
+G_MENU_ATTRIBUTE_ITER_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>gresource</FILE>
+<TITLE>GResource</TITLE>
+GResource
+GResourceFlags
+GResourceLookupFlags
+g_resource_load
+g_resource_new_from_data
+g_resource_ref
+g_resource_unref
+g_resource_lookup_data
+g_resource_open_stream
+g_resource_enumerate_children
+g_resource_get_info
+
+<SUBSECTION Static>
+GStaticResource
+g_static_resource_init
+g_static_resource_fini
+g_static_resource_get_resource
+
+<SUBSECTION Global>
+g_resources_register
+g_resources_unregister
+g_resources_lookup_data
+g_resources_open_stream
+g_resources_enumerate_children
+g_resources_get_info
+
+<SUBSECTION>
+G_RESOURCE_ERROR
+GResourceError
+
+<SUBSECTION Standard>
+G_TYPE_RESOURCE
+G_TYPE_RESOURCE_ERROR
+G_TYPE_RESOURCE_FILE
+G_TYPE_RESOURCE_FLAGS
+G_TYPE_RESOURCE_LOOKUP_FLAGS
+
+<SUBSECTION Private>
+g_resource_get_type
+g_resource_error_get_type
+g_resource_flags_get_type
+g_resource_lookup_flags_get_type
+g_resource_error_quark
+</SECTION>
+
+<SECTION>
+<FILE>gtestdbus</FILE>
+<TITLE>GTestDBus</TITLE>
+GTestDBus
+GTestDBusFlags
+g_test_dbus_new
+g_test_dbus_get_flags
+g_test_dbus_get_bus_address
+g_test_dbus_add_service_dir
+g_test_dbus_up
+g_test_dbus_stop
+g_test_dbus_down
+g_test_dbus_unset
+<SUBSECTION Private>
+g_test_dbus_get_type
+g_test_dbus_flags_get_type
+<SUBSECTION Standard>
+G_TEST_DBUS
+G_IS_TEST_DBUS
+G_TYPE_TEST_DBUS
+G_TYPE_TEST_DBUS_FLAGS
+</SECTION>
+
+<SECTION>
+<FILE>gtask</FILE>
+<TITLE>GTask</TITLE>
+GTask
+g_task_new
+g_task_set_task_data
+g_task_set_priority
+g_task_set_check_cancellable
+g_task_set_return_on_cancel
+g_task_set_source_tag
+g_task_set_name
+<SUBSECTION>
+g_task_report_error
+g_task_report_new_error
+<SUBSECTION>
+g_task_get_task_data
+g_task_get_priority
+g_task_get_cancellable
+g_task_get_check_cancellable
+g_task_get_return_on_cancel
+g_task_get_context
+g_task_get_source_object
+g_task_get_source_tag
+g_task_get_name
+<SUBSECTION>
+g_task_return_boolean
+g_task_return_int
+g_task_return_pointer
+g_task_return_value
+g_task_return_error
+g_task_return_new_error
+g_task_return_error_if_cancelled
+<SUBSECTION>
+g_task_propagate_boolean
+g_task_propagate_int
+g_task_propagate_pointer
+g_task_propagate_value
+g_task_had_error
+g_task_get_completed
+<SUBSECTION>
+g_task_run_in_thread
+g_task_run_in_thread_sync
+GTaskThreadFunc
+g_task_attach_source
+<SUBSECTION>
+g_task_is_valid
+<SUBSECTION Standard>
+GTaskClass
+GTaskPrivate
+G_TYPE_TASK
+G_TASK
+G_IS_TASK
+G_TASK_CLASS
+G_IS_TASK_CLASS
+G_TASK_GET_CLASS
+g_task_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gnetworking</FILE>
+<TITLE>gnetworking.h</TITLE>
+g_networking_init
+<SUBSECTION Private>
+CMSG_LEN
+CMSG_SPACE
+GLIB_ALIGN_TO_SIZEOF
+T_SRV
+ws2funcs
+</SECTION>
+
+<SECTION>
+<FILE>gsimpleproxyresolver</FILE>
+<TITLE>GSimpleProxyResolver</TITLE>
+GSimpleProxyResolver
+g_simple_proxy_resolver_new
+g_simple_proxy_resolver_set_default_proxy
+g_simple_proxy_resolver_set_ignore_hosts
+g_simple_proxy_resolver_set_uri_proxy
+<SUBSECTION Standard>
+GSimpleProxyResolverClass
+GSimpleProxyResolverPrivate
+G_TYPE_SIMPLE_PROXY_RESOLVER
+G_SIMPLE_PROXY_RESOLVER
+G_IS_SIMPLE_PROXY_RESOLVER
+G_SIMPLE_PROXY_RESOLVER_CLASS
+G_IS_SIMPLE_PROXY_RESOLVER_CLASS
+G_SIMPLE_PROXY_RESOLVER_GET_CLASS
+g_simple_proxy_resolver_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsubprocess</FILE>
+<TITLE>GSubprocess</TITLE>
+GSubprocess
+GSubprocessFlags
+g_subprocess_new
+g_subprocess_newv
+g_subprocess_get_identifier
+<SUBSECTION IO>
+g_subprocess_get_stdin_pipe
+g_subprocess_get_stdout_pipe
+g_subprocess_get_stderr_pipe
+<SUBSECTION Waiting>
+g_subprocess_wait
+g_subprocess_wait_async
+g_subprocess_wait_finish
+g_subprocess_wait_check
+g_subprocess_wait_check_async
+g_subprocess_wait_check_finish
+<SUBSECTION Status>
+g_subprocess_get_successful
+g_subprocess_get_if_exited
+g_subprocess_get_exit_status
+g_subprocess_get_if_signaled
+g_subprocess_get_term_sig
+g_subprocess_get_status
+<SUBSECTION Control>
+g_subprocess_send_signal
+g_subprocess_force_exit
+<SUBSECTION communicate>
+g_subprocess_communicate
+g_subprocess_communicate_async
+g_subprocess_communicate_finish
+g_subprocess_communicate_utf8
+g_subprocess_communicate_utf8_async
+g_subprocess_communicate_utf8_finish
+<SUBSECTION Standard>
+G_IS_SUBPROCESS
+G_TYPE_SUBPROCESS
+G_SUBPROCESS
+G_TYPE_SUBPROCESS_FLAGS
+g_subprocess_get_type
+g_subprocess_flags_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsubprocesslauncher</FILE>
+<TITLE>GSubprocessLauncher</TITLE>
+GSubprocessLauncher
+g_subprocess_launcher_new
+g_subprocess_launcher_spawn
+g_subprocess_launcher_spawnv
+g_subprocess_launcher_set_environ
+g_subprocess_launcher_setenv
+g_subprocess_launcher_unsetenv
+g_subprocess_launcher_getenv
+g_subprocess_launcher_set_cwd
+g_subprocess_launcher_set_flags
+g_subprocess_launcher_set_stdin_file_path
+g_subprocess_launcher_take_stdin_fd
+g_subprocess_launcher_set_stdout_file_path
+g_subprocess_launcher_take_stdout_fd
+g_subprocess_launcher_set_stderr_file_path
+g_subprocess_launcher_take_stderr_fd
+g_subprocess_launcher_take_fd
+g_subprocess_launcher_set_child_setup
+<SUBSECTION Standard>
+G_IS_SUBPROCESS_LAUNCHER
+G_SUBPROCESS_LAUNCHER
+G_TYPE_SUBPROCESS_LAUNCHER
+g_subprocess_launcher_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gnotification</FILE>
+<TITLE>GNotification</TITLE>
+GNotification
+g_notification_new
+<SUBSECTION>
+g_notification_set_title
+g_notification_set_body
+g_notification_set_icon
+GNotificationPriority
+g_notification_set_priority
+g_notification_set_urgent
+<SUBSECTION>
+g_notification_set_default_action
+g_notification_set_default_action_and_target
+g_notification_set_default_action_and_target_value
+<SUBSECTION>
+g_notification_add_button
+g_notification_add_button_with_target
+g_notification_add_button_with_target_value
+<SUBSECTION Standard>
+G_IS_NOTIFICATION
+G_NOTIFICATION
+G_TYPE_NOTIFICATION
+G_TYPE_NOTIFICATION_BACKEND
+g_notification_get_type
+G_TYPE_NOTIFICATION_PRIORITY
+g_notification_priority_get_type
+</SECTION>
+
+<SECTION>
+<FILE>glistmodel</FILE>
+<TITLE>GListModel</TITLE>
+GListModel
+GListModelInterface
+<SUBSECTION>
+g_list_model_get_item_type
+g_list_model_get_n_items
+g_list_model_get_item
+g_list_model_get_object
+g_list_model_items_changed
+<SUBSECTION Standard>
+G_TYPE_LIST_MODEL
+G_LIST_MODEL
+G_IS_LIST_MODEL
+G_LIST_MODEL_GET_IFACE
+<SUBSECTION Private>
+g_list_model_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gliststore</FILE>
+<TITLE>GListStore</TITLE>
+GListStore
+<SUBSECTION>
+g_list_store_new
+g_list_store_insert
+g_list_store_insert_sorted
+g_list_store_append
+g_list_store_remove
+g_list_store_remove_all
+g_list_store_splice
+g_list_store_sort
+g_list_store_find
+g_list_store_find_with_equal_func
+<SUBSECTION Standard>
+G_TYPE_LIST_STORE
+<SUBSECTION Private>
+g_list_store_get_type
+</SECTION>
diff --git a/docs/reference/gio/gio-sections-win32.txt b/docs/reference/gio/gio-sections-win32.txt
new file mode 100644
index 0000000..52d137e
--- /dev/null
+++ b/docs/reference/gio/gio-sections-win32.txt
@@ -0,0 +1,112 @@
+<SECTION>
+<FILE>gwin32inputstream</FILE>
+<TITLE>GWin32InputStream</TITLE>
+GWin32InputStream
+g_win32_input_stream_new
+g_win32_input_stream_set_close_handle
+g_win32_input_stream_get_close_handle
+g_win32_input_stream_get_handle
+<SUBSECTION Standard>
+GWin32InputStreamClass
+G_WIN32_INPUT_STREAM
+G_IS_WIN32_INPUT_STREAM
+G_TYPE_WIN32_INPUT_STREAM
+G_WIN32_INPUT_STREAM_CLASS
+G_IS_WIN32_INPUT_STREAM_CLASS
+G_WIN32_INPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_win32_input_stream_get_type
+GWin32InputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gwin32outputstream</FILE>
+<TITLE>GWin32OutputStream</TITLE>
+GWin32OutputStream
+g_win32_output_stream_new
+g_win32_output_stream_set_close_handle
+g_win32_output_stream_get_close_handle
+g_win32_output_stream_get_handle
+<SUBSECTION Standard>
+GWin32OutputStreamClass
+G_WIN32_OUTPUT_STREAM
+G_IS_WIN32_OUTPUT_STREAM
+G_TYPE_WIN32_OUTPUT_STREAM
+G_WIN32_OUTPUT_STREAM_CLASS
+G_IS_WIN32_OUTPUT_STREAM_CLASS
+G_WIN32_OUTPUT_STREAM_GET_CLASS
+<SUBSECTION Private>
+g_win32_output_stream_get_type
+GWin32OutputStreamPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gwin32registrykey</FILE>
+
+<SUBSECTION>
+GWin32RegistrySubkeyIter
+g_win32_registry_subkey_iter_copy
+g_win32_registry_subkey_iter_free
+g_win32_registry_subkey_iter_assign
+
+<SUBSECTION>
+GWin32RegistryValueIter
+g_win32_registry_value_iter_copy
+g_win32_registry_value_iter_free
+g_win32_registry_value_iter_assign
+
+<SUBSECTION>
+GWin32RegistryKey
+g_win32_registry_key_new
+g_win32_registry_key_new_w
+g_win32_registry_key_get_child
+g_win32_registry_key_get_child_w
+
+<SUBSECTION>
+g_win32_registry_subkey_iter_init
+g_win32_registry_subkey_iter_clear
+g_win32_registry_subkey_iter_n_subkeys
+g_win32_registry_subkey_iter_next
+g_win32_registry_subkey_iter_get_name
+g_win32_registry_subkey_iter_get_name_w
+
+<SUBSECTION>
+g_win32_registry_value_iter_init
+g_win32_registry_value_iter_clear
+g_win32_registry_value_iter_n_values
+g_win32_registry_value_iter_next
+GWin32RegistryValueType
+g_win32_registry_value_iter_get_value_type
+g_win32_registry_value_iter_get_name
+g_win32_registry_value_iter_get_name_w
+g_win32_registry_value_iter_get_data
+g_win32_registry_value_iter_get_data_w
+
+<SUBSECTION>
+g_win32_registry_key_get_value
+g_win32_registry_key_get_value_w
+g_win32_registry_key_get_path
+g_win32_registry_key_get_path_w
+GWin32RegistryKeyWatchCallbackFunc
+GWin32RegistryKeyWatcherFlags
+g_win32_registry_key_watch
+g_win32_registry_key_has_changed
+g_win32_registry_key_erase_change_indicator
+
+<SUBSECTION Standard>
+GWin32RegistryKeyClass
+
+<SUBSECTION Private>
+GWin32RegistryKeyPrivate
+g_win32_registry_key_get_type
+g_win32_registry_subkey_iter_get_type
+g_win32_registry_value_iter_get_type
+G_TYPE_WIN32_REGISTRY_KEY
+G_WIN32_REGISTRY_KEY
+G_WIN32_REGISTRY_KEY_CLASS
+G_IS_WIN32_REGISTRY_KEY
+G_IS_WIN32_REGISTRY_KEY_CLASS
+G_WIN32_REGISTRY_KEY_GET_CLASS
+G_TYPE_WIN32_REGISTRY_SUBKEY_ITER
+G_TYPE_WIN32_REGISTRY_VALUE_ITER
+</SECTION>
diff --git a/docs/reference/gio/gio.xml b/docs/reference/gio/gio.xml
new file mode 100644
index 0000000..641b222
--- /dev/null
+++ b/docs/reference/gio/gio.xml
@@ -0,0 +1,775 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<refentry id="gio">
+  <refentryinfo>
+    <title>gio</title>
+    <productname>GIO</productname>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Matthias</firstname>
+        <surname>Clasen</surname>
+        <email>mclasen@redhat.com</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>gio</refentrytitle>
+    <manvolnum>1</manvolnum>
+    <refmiscinfo class="manual">User Commands</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>gio</refname>
+    <refpurpose>GIO commandline tool</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">help</arg>
+      <arg choice="opt"><replaceable>COMMAND</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">version</arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">cat</arg>
+      <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">copy</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain" rep="repeat"><replaceable>SOURCE</replaceable></arg>
+      <arg choice="plain"><replaceable>DESTINATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">info</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">list</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">mime</arg>
+      <arg choice="plain"><replaceable>MIMETYPE</replaceable></arg>
+      <arg choice="opt"><replaceable>HANDLER</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">mkdir</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">monitor</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">mount</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">move</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain" rep="repeat"><replaceable>SOURCE</replaceable></arg>
+      <arg choice="plain"><replaceable>DESTINATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">open</arg>
+      <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">rename</arg>
+      <arg choice="plain"><replaceable>LOCATION</replaceable></arg>
+      <arg choice="plain"><replaceable>NAME</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">remove</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">save</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain"><replaceable>DESTINATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">set</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="plain"><replaceable>LOCATION</replaceable></arg>
+      <arg choice="plain"><replaceable>ATTRIBUTE</replaceable></arg>
+      <arg choice="plain" rep="repeat"><replaceable>VALUE</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">trash</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">tree</arg>
+      <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+    <para><command>gio</command> is a utility that makes many of the GIO
+      features available from the commandline. In doing so, it provides
+      commands that are similar to traditional utilities, but let you
+      use GIO locations instead of local files: for example you can use
+      something like <filename>smb://server/resource/file.txt</filename>
+      as a location.</para>
+    <para>Plain filenames which contain a colon will be interpreted as URIs
+      with an unknown protocol. To avoid this, prefix them with a path such as
+      <filename>./</filename>, or with the <literal>file:</literal> protocol.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Commands</title>
+
+    <variablelist>
+      <varlistentry>
+        <term>
+          <command>help</command>
+          <arg choice="opt"><replaceable>COMMAND</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Displays a short synopsis of the available commands or provides
+            detailed help on a specific command.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>version</command>
+        </term>
+        <listitem>
+          <para>Prints the GLib version to which <command>gio</command>
+            belongs.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>cat</command>
+          <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Concatenates the given files and prints them to the standard
+            output.</para>
+          <para>The <command>cat</command> command works just like the traditional <command>cat</command> utility.</para>
+          <para>Note: just pipe through <command>cat</command> if you need its formatting options
+            like <option>-n</option>, <option>-T</option> or other.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>copy</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain" rep="repeat"><replaceable>SOURCE</replaceable></arg>
+          <arg choice="plain"><replaceable>DESTINATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Copies one or more files from <replaceable>SOURCE</replaceable>
+            to <replaceable>DESTINATION</replaceable>. If more than one source
+            is specified, the destination must be a directory.</para>
+          <para>The <command>copy</command> command is similar to the traditional <command>cp</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-T</option>, <option>--no-target-directory</option></term>
+                <listitem><para>Don’t copy into <replaceable>DESTINATION</replaceable> even if it is a directory.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-p</option>, <option>--progress</option></term>
+                <listitem><para>Show progress.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-i</option>, <option>--interactive</option></term>
+                <listitem><para>Prompt for confirmation before overwriting files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>--preserve</option></term>
+                <listitem><para>Preserve all attributes of copied files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-b</option>, <option>--backup</option></term>
+                <listitem><para>Create backups of existing destination files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-P</option>, <option>--no-dereference</option></term>
+                <listitem><para>Never follow symbolic links.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>--default-permissions</option></term>
+                <listitem><para>Use the default permissions of the current process for the destination file, rather than copying the permissions of the source file.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>
+          <command>info</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Shows information about the given locations.</para>
+          <para>The <command>info</command> command is similar to the traditional <command>ls</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-w</option>, <option>--query-writable</option></term>
+                <listitem><para>List writable attributes.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-f</option>, <option>--filesystem</option></term>
+                <listitem><para>Show information about the filesystem that the given
+                locations reside on.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-a</option> <option>--attributes=<replaceable>ATTRIBUTES</replaceable></option></term>
+                <listitem><para>The attributes to get.</para>
+                  <para>Attributes can be specified with their GIO name, e.g.
+                    <literal>standard::icon</literal>, or just by namespace, e.g. <literal>unix</literal>, or by <literal>*</literal>,
+                    which matches all attributes. Several attributes or groups
+                    of attributes can be specified, separated by comma.</para>
+                  <para>By default, all attributes are listed.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-n</option>, <option>--nofollow-symlinks</option></term>
+                <listitem><para>Don’t follow symbolic links.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>list</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Lists the contents of the given locations. If no location is
+            given, the contents of the current directory are shown.</para>
+          <para>The <command>list</command> command is similar to the traditional <command>ls</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-a</option> <option>--attributes=<replaceable>ATTRIBUTES</replaceable></option></term>
+                <listitem><para>The attributes to get.</para>
+                  <para>Attributes can be specified with their GIO name, e.g.
+                    <literal>standard::icon</literal>, or just by namespace, e.g. <literal>unix</literal>, or by <literal>*</literal>,
+                    which matches all attributes. Several attributes or groups
+                    of attributes can be specified, separated by comma.</para>
+                  <para>By default, all attributes are listed.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-h</option>, <option>--hidden</option></term>
+                <listitem><para>Show hidden files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-l</option>, <option>--long</option></term>
+                <listitem><para>Use a long listing format.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-n</option>, <option>--nofollow-symlinks</option></term>
+                <listitem><para>Don’t follow symbolic links.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-d</option>, <option>--print-display-names</option></term>
+                <listitem><para>Print display names.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-u</option>, <option>--print-uris</option></term>
+                <listitem><para>Print full URIs.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>mime</command>
+          <arg choice="plain"><replaceable>MIMETYPE</replaceable></arg>
+          <arg choice="opt"><replaceable>HANDLER</replaceable></arg>
+        </term>
+        <listitem>
+          <para>If no handler is given, the <command>mime</command> command lists the
+            registered and recommended applications for the mimetype.
+            If a handler is given, it is set as the default handler for
+            the mimetype.</para>
+          <para>Handlers must be specified by their desktop file name,
+            including the extension. Example: <literal>org.gnome.gedit.desktop</literal>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>mkdir</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Creates directories.</para>
+          <para>The <command>mkdir</command> command is similar to the traditional <command>mkdir</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-p</option>, <option>--parent</option></term>
+                <listitem><para>Create parent directories when necessary.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>monitor</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Monitors files or directories for changes, such as creation
+            deletion, content and attribute changes, and mount and unmount
+            operations affecting the monitored locations.</para>
+          <para>The <command>monitor</command> command uses the GIO file monitoring APIs to do
+            its job. GIO has different implementations for different platforms.
+            The most common implementation on Linux uses inotify.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-d</option>, <option>--dir=<replaceable>LOCATION</replaceable></option></term>
+                <listitem><para>Monitor the given location as a directory. Normally,
+                  the file type is used to determine whether to monitor a file or directory.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-f</option>, <option>--file=<replaceable>LOCATION</replaceable></option></term>
+                <listitem><para>Monitor the given location as a file. Normally,
+                  the file type is used to determine whether to monitor a file or directory.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-D</option>, <option>--direct=<replaceable>LOCATION</replaceable></option></term>
+                <listitem><para>Monitor the file directly. This allows changes made via hardlinks to be captured.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-s</option>, <option>--silent=<replaceable>LOCATION</replaceable></option></term>
+                <listitem><para>Monitor the file directly, but don’t report changes.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-n</option>, <option>--no-moves</option></term>
+                <listitem><para>Report moves and renames as simple deleted/created events.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-m</option>, <option>--mounts</option></term>
+                <listitem><para>Watch for mount events.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>mount</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Provides commandline access to various aspects of GIO’s mounting
+            functionality.</para>
+          <para>Mounting refers to the traditional concept of arranging multiple
+            file systems and devices in a single tree, rooted at <filename>/</filename>. Classical
+            mounting happens in the kernel and is controlled by the mount utility.
+            GIO expands this concept by introducing mount daemons that can make
+            file systems available to GIO applications without kernel
+            involvement.</para>
+          <para>GIO mounts can require authentication, and the <command>mount</command> command
+            may ask for user IDs, passwords, and so on, when required.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-m</option>, <option>--mountable</option></term>
+                <listitem><para>Mount as mountable.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-d</option>, <option>--device=<replaceable>ID</replaceable></option></term>
+                <listitem><para>Mount volume with device file, or other identifier.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-u</option>, <option>--unmount</option></term>
+                <listitem><para>Unmount the location.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-e</option>, <option>--eject</option></term>
+                <listitem><para>Eject the location.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-t</option>, <option>--stop=<replaceable>DEVICE</replaceable></option></term>
+                <listitem><para>Stop drive with device file.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-s</option>, <option>--unmount-scheme=<replaceable>SCHEME</replaceable></option></term>
+                <listitem><para>Unmount all mounts with the given scheme.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-f</option>, <option>--force</option></term>
+                <listitem><para>Ignore outstanding file operations when unmounting or ejecting.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-a</option>, <option>--anonymous</option></term>
+                <listitem><para>Use an anonymous user when authenticating.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-l</option>, <option>--list</option></term>
+                <listitem><para>List all GIO mounts.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-o</option>, <option>--monitor</option></term>
+                <listitem><para>Monitor mount-related events.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-i</option>, <option>--detail</option></term>
+                <listitem><para>Show extra information.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>--tcrypt-pim</option></term>
+                <listitem><para>The numeric PIM when unlocking a VeraCrypt volume.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>--tcrypt-hidden</option></term>
+                <listitem><para>Mount a TCRYPT hidden volume.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>--tcrypt-system</option></term>
+                <listitem><para>Mount a TCRYPT system volume.</para>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>move</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain" rep="repeat"><replaceable>SOURCE</replaceable></arg>
+          <arg choice="plain"><replaceable>DESTINATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Moves one or more files from <replaceable>SOURCE</replaceable>
+            to <replaceable>DESTINATION</replaceable>. If more than one source
+            is specified, the destination must be a directory.</para>
+          <para>The <command>move</command> command is similar to the traditional <command>mv</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-T</option>, <option>--no-target-directory</option></term>
+                <listitem><para>Don’t copy into <replaceable>DESTINATION</replaceable> even if it is a directory.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-p</option>, <option>--progress</option></term>
+                <listitem><para>Show progress.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-i</option>, <option>--interactive</option></term>
+                <listitem><para>Prompt for confirmation before overwriting files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-b</option>, <option>--backup</option></term>
+                <listitem><para>Create backups of existing destination files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-C</option>, <option>--no-copy-fallback</option></term>
+                <listitem><para>Don’t use copy and delete fallback.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>open</command>
+          <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Opens files with the default application that is registered
+            to handle files of this type.</para>
+          <para>GIO obtains this information from the shared-mime-info
+            database, with per-user overrides stored in
+            <filename><envar>$XDG_DATA_HOME</envar>/applications/mimeapps.list</filename>.</para>
+          <para>The <command>mime</command> command can be used to change the default handler for
+            a mimetype.</para>
+          <para>Environment variables will not be set on the application, as it
+            may be an existing process which is activated to handle the new file.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>rename</command>
+          <arg choice="plain"><replaceable>LOCATION</replaceable></arg>
+          <arg choice="plain"><replaceable>NAME</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Renames a file.</para>
+          <para>The <command>rename</command> command is similar to the traditional <command>rename</command> utility.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>remove</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Deletes each given file.</para>
+          <para>This command removes files irreversibly. If you want a reversible
+            way to remove files, see the <command>trash</command> command.</para>
+          <para>Note that not all URI schemes that are supported by GIO may
+            allow deletion of files.</para>
+          <para>The <command>remove</command> command is similar to the traditional <command>rm</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-f</option>, <option>--force</option></term>
+                <listitem><para>Ignore non-existent and non-deletable files.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>save</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain"><replaceable>DESTINATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Reads from standard input and saves the data to the given
+            location.</para>
+          <para>This is similar to just redirecting output to a file using
+            traditional shell syntax, but the <command>save</command> command allows saving to
+            location that GIO can write to.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-b</option>, <option>--backup</option></term>
+                <listitem><para>Back up existing destination files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-c</option>, <option>--create</option></term>
+                <listitem><para>Only create the destination if it doesn’t exist yet.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-a</option>, <option>--append</option></term>
+                <listitem><para>Append to the end of the file.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-p</option>, <option>--private</option></term>
+                <listitem><para>When creating, restrict access to the current user.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-u</option>, <option>--unlink</option></term>
+                <listitem><para>When replacing, replace as if the destination did not exist.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-v</option>, <option>--print-etag</option></term>
+                <listitem><para>Print the new ETag in the end.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-e</option>, <option>--etag=<replaceable>ETAG</replaceable></option></term>
+                <listitem><para>The ETag of the file that is overwritten.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>set</command>
+          <arg choice="plain"><replaceable>LOCATION</replaceable></arg>
+          <arg choice="plain"><replaceable>ATTRIBUTE</replaceable></arg>
+          <arg choice="plain" rep="repeat"><replaceable>VALUE</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Sets a file attribute on a file.</para>
+          <para>File attributes can be specified with their GIO name, e.g
+            <literal>standard::icon</literal>. Note that not all GIO file attributes are writable.
+            Use the <option>--query-writable</option> option of the <command>info</command> command to list
+            writable file attributes.</para>
+          <para>If the <replaceable>TYPE</replaceable> is unset,
+            <replaceable>VALUE</replaceable> does not have to be specified.
+            If the <replaceable>TYPE</replaceable> is <literal>stringv</literal>, multiple values can be given.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-t</option>, <option>--type=<replaceable>TYPE</replaceable></option></term>
+                <listitem><para>Specifies the type of the attribute. Supported
+                  types are <literal>string</literal>, <literal>stringv</literal>,
+                  <literal>bytestring</literal>, <literal>boolean</literal>,
+                  <literal>uint32</literal>, <literal>int32</literal>,
+                  <literal>uint64</literal>, <literal>int64</literal> and <literal>unset</literal>.</para>
+                  <para>If the type is not specified, <literal>string</literal> is assumed.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-n</option>, <option>--nofollow-symlinks</option></term>
+                <listitem><para>Don’t follow symbolic links.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>trash</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Sends files or directories to the ‘Trashcan’. This can be a
+            different folder depending on where the file is located, and not
+            all file systems support this concept. In the common case that the
+            file lives inside a user’s home directory, the trash folder is
+            <filename><envar>$XDG_DATA_HOME</envar>/Trash</filename>.</para>
+          <para>Note that moving files to the trash does not free up space on
+            the file system until the ‘Trashcan’ is emptied. If you are interested
+            in deleting a file irreversibly, see the <command>remove</command> command.</para>
+          <para>Inspecting and emptying the ‘Trashcan’ is normally supported by
+            graphical file managers such as Nautilus, but you can also see the
+            trash with the command: <command>gio list trash://</command>.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-f</option>, <option>--force</option></term>
+                <listitem><para>Ignore non-existent and non-deletable files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>--empty</option></term>
+                <listitem><para>Empty the trash.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>tree</command>
+          <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="opt" rep="repeat"><replaceable>LOCATION</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Lists the contents of the given locations recursively, in a
+            tree-like format. If no location is given, it defaults to the current
+            directory.</para>
+          <para>The <command>tree</command> command is similar to the traditional <command>tree</command> utility.</para>
+          <refsect3>
+            <title>Options</title>
+            <variablelist>
+              <varlistentry>
+                <term><option>-h</option>, <option>--hidden</option></term>
+                <listitem><para>Show hidden files.</para></listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><option>-l</option>, <option>--follow-symlinks</option></term>
+                <listitem><para>Follow symbolic links.</para></listitem>
+              </varlistentry>
+            </variablelist>
+          </refsect3>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Exit status</title>
+    <para>On success 0 is returned, a non-zero failure code otherwise.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry>
+        <refentrytitle>cat</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>cp</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>ls</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>mkdir</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>mv</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>rm</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>tree</refentrytitle>
+        <manvolnum>1</manvolnum>
+      </citerefentry>.
+    </para>
+  </refsect1>
+</refentry>
diff --git a/docs/reference/gio/glib-compile-resources.xml b/docs/reference/gio/glib-compile-resources.xml
new file mode 100644
index 0000000..5421f3d
--- /dev/null
+++ b/docs/reference/gio/glib-compile-resources.xml
@@ -0,0 +1,241 @@
+<refentry id="glib-compile-resources" lang="en">
+
+<refentryinfo>
+  <title>glib-compile-schemas</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Alexander</firstname>
+      <surname>Larsson</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>glib-compile-resources</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>glib-compile-resources</refname>
+  <refpurpose>GLib resource compiler</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>glib-compile-resources</command>
+    <arg choice="opt" rep="repeat">OPTION</arg>
+    <arg choice="req">FILE</arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>glib-compile-resources</command> reads the resource description from
+<replaceable>FILE</replaceable> and the files that it references
+and creates a binary resource bundle that is suitable for use with the
+<link linkend="GResource"><type>GResource</type></link> API.
+The resulting bundle is then written out as-is, or as C source for linking into
+an application.
+</para>
+<para>
+The XML resource files normally have the filename extension <filename>.gresource.xml</filename>.
+For a detailed description of the XML file format, see the
+<link linkend="GResource"><type>GResource</type></link> documentation.
+</para>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>-h</option>, <option>--help</option></term>
+<listitem><para>
+Print help and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--version</option></term>
+<listitem><para>
+Print program version and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--target=<replaceable>TARGET</replaceable></option></term>
+<listitem><para>
+Store the compiled resources in the file <replaceable>TARGET</replaceable>.
+If not specified a filename based on the <replaceable>FILE</replaceable>
+basename is used.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--sourcedir=<replaceable>DIRECTORY</replaceable></option></term>
+<listitem><para>
+The files referenced in <replaceable>FILE</replaceable> are loaded from
+this directory. If not specified, the current directory is used.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--generate</option></term>
+<listitem><para>
+Write the output file in the format selected for by its filename extension:
+<variablelist>
+<varlistentry>
+<term><literal>.c</literal></term>
+<listitem><para>C source</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>.h</literal></term>
+<listitem><para>C header</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>.gresource</literal></term>
+<listitem><para>resource bundle</para></listitem>
+</varlistentry>
+</variablelist>
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--generate-source</option></term>
+<listitem><para>
+Instead of a writing the resource bundle in binary form create a C source file
+that contains the resource bundle. This can then be compiled into an
+application for easy access.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--generate-header</option></term>
+<listitem><para>
+Generate a header file for use with C code generated by
+<option>--generate-source</option>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--generate-dependencies</option></term>
+<listitem><para>
+Prints the list of files that the resource bundle references to standard output.
+This can be used to track dependencies in the build system. For example, the
+following make rule would mark <replaceable>test.gresource</replaceable> as
+depending on all the files that <replaceable>test.gresource.xml</replaceable>
+includes, so that is is automatically rebuilt if any of them change:
+<programlisting>
+test.gresource: test.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies test.gresource.xml)
+</programlisting>
+Note that this may or may not be portable to non-GNU <command>make</command>.
+</para>
+<para>
+Also see <option>--dependency-file</option>.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--c-name</option></term>
+<listitem><para>
+Specify the prefix used for the C identifiers in the code generated by
+<option>--generate-source</option> and <option>--generate-header</option>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--manual-register</option></term>
+<listitem><para>
+By default code generated by <option>--generate-source</option> uses automatic
+initialization of the resource. This works on most systems by using the
+compiler support for constructors. However, some (uncommon) compilers may not
+support this, you can then specify <option>--manual-register</option>,
+which will generate custom register and unregister functions that your code
+can manually call at initialization and uninitialization time.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--internal</option></term>
+<listitem><para>
+By default code generated by <option>--generate-source</option> declares all
+initialization functions as <type>extern</type>.  So they are exported
+unless this is prevented by a link script or other means.  Since libraries
+usually want to use the functions only internally it can be more useful to
+declare them as
+<link linkend="G-GNUC-INTERNAL:CAPS"><literal>G_GNUC_INTERNAL</literal></link>
+which is what <option>--internal</option> does.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--external-data</option></term>
+<listitem><para>
+By default code generated by <option>--generate-source</option> embeds the
+resource data as a string literal. When <option>--external-data</option>
+is given, the data is only declared in the generated C file, and the data
+has to be linked externally.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--dependency-file=<replaceable>FILE</replaceable></option></term>
+<listitem><para>
+Write dependencies in the same style as gcc -M -MF to the given file.
+If <option>FILE</option> is -, the dependencies are written to the standard
+output. Unlike <option>--generate-dependencies</option>, this option can be
+combined with other <option>--generate</option> options to generate dependencies
+as a side-effect of generating sources.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--generate-phony-targets</option></term>
+<listitem><para>
+When creating a dependency file with <option>--dependency-file</option>
+include phony targets in the same style as gcc -MP. This would typically
+be used with <literal>make</literal>.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+
+<refsect1><title>Environment</title>
+<variablelist>
+
+<varlistentry>
+<term><envar>XMLLINT</envar></term>
+<listitem><para>
+The full path to the <command>xmllint</command> executable. This is used to
+preprocess resources with the <literal>xml-stripblanks</literal> preprocessing
+option. If this environment variable is not set, <command>xmllint</command> is
+searched for in the <envar>PATH</envar>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><envar>GDK_PIXBUF_PIXDATA</envar></term>
+<listitem><para>
+The full path to the <command>gdk-pixbuf-pixdata</command> executable. This is
+used to preprocess resources with the <literal>to-pixdata</literal> preprocessing
+option. If this environment variable is not set, <command>gdk-pixbuf-pixdata</command>
+is searched for in the <envar>PATH</envar>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><envar>JSON_GLIB_FORMAT</envar></term>
+<listitem><para>
+The full path to the <command>json-glib-format</command> executable. This is used
+to preprocess resources with the <literal>json-stripblanks</literal> preprocessing
+option. If this environment variable is not set, <command>json-glib-format</command>
+is searched for in the <envar>PATH</envar>.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+</refentry>
diff --git a/docs/reference/gio/glib-compile-schemas.xml b/docs/reference/gio/glib-compile-schemas.xml
new file mode 100644
index 0000000..0796bd7
--- /dev/null
+++ b/docs/reference/gio/glib-compile-schemas.xml
@@ -0,0 +1,118 @@
+<refentry id="glib-compile-schemas" lang="en">
+
+<refentryinfo>
+  <title>glib-compile-schemas</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Ryan</firstname>
+      <surname>Lortie</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>glib-compile-schemas</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>glib-compile-schemas</refname>
+  <refpurpose>GSettings schema compiler</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>glib-compile-schemas</command>
+    <arg choice="opt" rep="repeat">OPTION</arg>
+    <arg choice="req">DIRECTORY</arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>glib-compile-schemas</command> compiles all the GSettings XML
+schema files in <replaceable>DIRECTORY</replaceable> into a binary file
+with the name <filename>gschemas.compiled</filename> that can be used
+by <link linkend="GSettings"><type>GSettings</type></link>. The XML schema
+files must have the filename extension <filename>.gschema.xml</filename>.
+For a detailed description of the XML file format, see the
+<link linkend="GSettings"><type>GSettings</type></link> documentation.
+</para>
+<para>
+At runtime, GSettings looks for schemas in the
+<filename>glib-2.0/schemas</filename> subdirectories of all directories
+specified in the <envar>XDG_DATA_DIRS</envar> environment variable. The
+usual location to install schema files is
+<filename>/usr/share/glib-2.0/schemas</filename>.
+</para>
+<para>
+In addition to schema files, glib-compile-schemas reads 'vendor override'
+files, which are key files that can override default values for keys in
+the schemas. The group names in the key files are the schema id, and the
+values are written in serialized GVariant form.
+Vendor override files must have the filename extension
+<filename>.gschema.override</filename>.
+</para>
+<para>
+By convention, vendor override files begin with <filename>nn_</filename>
+where <filename>nn</filename> is a number from 00 to 99.  Higher
+numbered files have higher priority (eg: if the same override is made in
+a file numbered 10 and then again in a file numbered 20, the override
+from 20 will take precedence).
+</para>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>-h</option>, <option>--help</option></term>
+<listitem><para>
+Print help and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--version</option></term>
+<listitem><para>
+Print program version and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--targetdir=<replaceable>TARGET</replaceable></option></term>
+<listitem><para>
+Store <filename>gschemas.compiled</filename> in the <replaceable>TARGET</replaceable> directory instead of <replaceable>DIRECTORY</replaceable>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--strict</option></term>
+<listitem><para>
+Abort on any errors in schemas. Without this option, faulty schema files are
+simply omitted from the resulting compiled schema.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--dry-run</option></term>
+<listitem><para>
+Don't write <filename>gschemas.compiled</filename>. This option can be used
+to check <filename>.gschema.xml</filename> sources for errors.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--allow-any-name</option></term>
+<listitem><para>
+Do not enforce restrictions on key names. Note that this option is purely
+to facility the transition from GConf, and will be removed at some time
+in the future.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+</refentry>
diff --git a/docs/reference/gio/gresource.xml b/docs/reference/gio/gresource.xml
new file mode 100644
index 0000000..4ada0eb
--- /dev/null
+++ b/docs/reference/gio/gresource.xml
@@ -0,0 +1,127 @@
+<refentry id="gresource-tool" lang="en">
+
+<refentryinfo>
+  <title>gresource</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Matthias</firstname>
+      <surname>Clasen</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>gresource</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>gresource</refname>
+  <refpurpose>GResource tool</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>gresource</command>
+    <arg choice="opt">--section <replaceable>SECTION</replaceable></arg>
+    <arg choice="plain">list</arg>
+    <arg choice="plain"><replaceable>FILE</replaceable></arg>
+    <arg choice="opt"><replaceable>PATH</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gresource</command>
+    <arg choice="opt">--section <replaceable>SECTION</replaceable></arg>
+    <arg choice="plain">details</arg>
+    <arg choice="plain"><replaceable>FILE</replaceable></arg>
+    <arg choice="opt"><replaceable>PATH</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gresource</command>
+    <arg choice="opt">--section <replaceable>SECTION</replaceable></arg>
+    <arg choice="plain">extract</arg>
+    <arg choice="plain"><replaceable>FILE</replaceable></arg>
+    <arg choice="plain"><replaceable>PATH</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gresource</command>
+    <arg choice="plain">sections</arg>
+    <arg choice="plain"><replaceable>FILE</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gresource</command>
+    <arg choice="plain">help</arg>
+    <arg choice="opt"><replaceable>COMMAND</replaceable></arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>gresource</command> offers a simple commandline
+interface to <link linkend="GResource"><type>GResource</type></link>.
+It lets you list and extract resources that have been compiled
+into a resource file or included in an elf file (a binary or a
+shared library).
+</para>
+<para>
+The file to operate on is specified by the <replaceable>FILE</replaceable>
+argument.
+</para>
+<para>
+If an elf file includes multiple sections with resources, it is
+possible to select which one to operate on with the
+<arg choice="plain">--section</arg> option. Use the
+<arg choice="plain">sections</arg> command to find available sections.
+</para>
+</refsect1>
+
+<refsect1><title>Commands</title>
+<variablelist>
+
+<varlistentry>
+<term><option>list</option></term>
+<listitem><para>
+Lists resources. If <replaceable>SECTION</replaceable> is given, only
+list resources in this section. If <replaceable>PATH</replaceable> is
+given, only list matching resources.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>details</option></term>
+<listitem><para>
+Lists resources with details. If <replaceable>SECTION</replaceable>
+is given, only list resources in this section. If
+<replaceable>PATH</replaceable> is given, only list matching resources.
+Details include the section, size and compression of each resource.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>extract</option></term>
+<listitem><para>
+Extracts the resource named by <replaceable>PATH</replaceable> to stdout.
+Note that resources may contain binary data.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>sections</option></term>
+<listitem><para>
+Lists sections containing resources. This is only interesting if
+<replaceable>FILE</replaceable> is an elf file.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>help</option></term>
+<listitem><para>
+Prints help and exits.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+</refsect1>
+</refentry>
diff --git a/docs/reference/gio/gsettings.xml b/docs/reference/gio/gsettings.xml
new file mode 100644
index 0000000..d7dc65d
--- /dev/null
+++ b/docs/reference/gio/gsettings.xml
@@ -0,0 +1,248 @@
+<refentry id="gsettings-tool" lang="en">
+
+<refentryinfo>
+  <title>gsettings</title>
+  <productname>GIO</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Ryan</firstname>
+      <surname>Lortie</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+  <refentrytitle>gsettings</refentrytitle>
+  <manvolnum>1</manvolnum>
+  <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+  <refname>gsettings</refname>
+  <refpurpose>GSettings configuration tool</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">get</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="plain"><replaceable>KEY</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">monitor</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="opt"><replaceable>KEY</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">writable</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="plain"><replaceable>KEY</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">range</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="plain"><replaceable>KEY</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">describe</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="plain"><replaceable>KEY</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">set</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="plain"><replaceable>KEY</replaceable></arg>
+    <arg choice="plain"><replaceable>VALUE</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">reset</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+    <arg choice="plain"><replaceable>KEY</replaceable></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">reset-recursively</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">list-schemas</arg>
+    <arg choice="opt">--print-paths</arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">list-relocatable-schemas</arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">list-keys</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">list-children</arg>
+    <arg choice="plain"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">list-recursively</arg>
+    <arg choice="opt"><replaceable>SCHEMA</replaceable><arg choice="opt">:<replaceable>PATH</replaceable></arg></arg>
+  </cmdsynopsis>
+  <cmdsynopsis>
+    <command>gsettings</command>
+    <arg choice="plain">help</arg>
+    <arg choice="opt"><replaceable>COMMAND</replaceable></arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>gsettings</command> offers a simple commandline
+interface to <link linkend="GSettings"><type>GSettings</type></link>.
+It lets you get, set or monitor an individual key for changes.
+</para>
+<para>
+The <replaceable>SCHEMA</replaceable> and <replaceable>KEY</replaceable>
+arguments are required for most commands to specify the schema id and the
+name of the key to operate on. The schema id may optionally have a
+:<replaceable>PATH</replaceable> suffix. Specifying the path is only needed
+if the schema does not have a fixed path.
+</para>
+<para>
+When setting a key, you also need specify a <replaceable>VALUE</replaceable>
+The format for the value is that of a serialized
+<link linkend="GVariant"><type>GVariant</type></link>,
+so e.g. a string
+must include explicit quotes: "'foo'". This format is also used when printing
+out values.
+</para>
+<para>
+Note that gsettings needs a D-Bus session bus connection to write changes to
+the dconf database.
+</para>
+</refsect1>
+
+<refsect1><title>Commands</title>
+<variablelist>
+
+<varlistentry>
+<term><option>get</option></term>
+<listitem><para>
+Gets the value of <replaceable>KEY</replaceable>.
+The value is printed out as a serialised
+<link linkend="GVariant"><type>GVariant</type></link>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>monitor</option></term>
+<listitem><para>
+Monitors <replaceable>KEY</replaceable> for changes and prints the changed
+values. If no <replaceable>KEY</replaceable> is specified, all keys in the
+schema are monitored. Monitoring will continue until the process is terminated.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>writable</option></term>
+<listitem><para>
+Finds out whether <replaceable>KEY</replaceable> is writable.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>range</option></term>
+<listitem><para>
+Queries the range of valid values for <replaceable>KEY</replaceable>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>describe</option></term>
+<listitem><para>
+Queries the description of valid values for <replaceable>KEY</replaceable>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>set</option></term>
+<listitem><para>
+Sets the value of <replaceable>KEY</replaceable> to
+<replaceable>VALUE</replaceable>. The value is specified as a serialised
+<link linkend="GVariant"><type>GVariant</type></link>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>reset</option></term>
+<listitem><para>
+Resets <replaceable>KEY</replaceable> to its default value.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>reset-recursively</option></term>
+<listitem><para>
+Reset all keys under the given <replaceable>SCHEMA</replaceable>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>list-schemas</option></term>
+<listitem><para>
+Lists the installed, non-relocatable schemas.
+See <option>list-relocatable-schemas</option> if you are interested in
+relocatable schemas. If <optional><option>--print-paths</option></optional>
+is given, the path where each schema is mapped is also printed.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>list-relocatable-schemas</option></term>
+<listitem><para>
+Lists the installed, relocatable schemas.
+See <option>list-schemas</option> if you are interested in
+non-relocatable schemas.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>list-keys</option></term>
+<listitem><para>
+Lists the keys in <replaceable>SCHEMA</replaceable>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>list-children</option></term>
+<listitem><para>
+Lists the children of <replaceable>SCHEMA</replaceable>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>list-recursively</option></term>
+<listitem><para>
+Lists keys and values, recursively. If no <replaceable>SCHEMA</replaceable>
+is given, list keys in all schemas.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>help</option></term>
+<listitem><para>
+Prints help and exits.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+</refsect1>
+</refentry>
diff --git a/docs/reference/gio/gvfs-overview.odg b/docs/reference/gio/gvfs-overview.odg
new file mode 100644
index 0000000..ca2bb8d
--- /dev/null
+++ b/docs/reference/gio/gvfs-overview.odg
Binary files differ
diff --git a/docs/reference/gio/gvfs-overview.png b/docs/reference/gio/gvfs-overview.png
new file mode 100644
index 0000000..628684d
--- /dev/null
+++ b/docs/reference/gio/gvfs-overview.png
Binary files differ
diff --git a/docs/reference/gio/menu-example.png b/docs/reference/gio/menu-example.png
new file mode 100644
index 0000000..91aeccf
--- /dev/null
+++ b/docs/reference/gio/menu-example.png
Binary files differ
diff --git a/docs/reference/gio/menu-model.png b/docs/reference/gio/menu-model.png
new file mode 100644
index 0000000..a4d9f11
--- /dev/null
+++ b/docs/reference/gio/menu-model.png
Binary files differ
diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build
new file mode 100644
index 0000000..a4e67ca
--- /dev/null
+++ b/docs/reference/gio/meson.build
@@ -0,0 +1,239 @@
+if get_option('gtk_doc')
+  if installed_tests_enabled
+    subdir('gdbus-object-manager-example')
+  endif
+  subdir('xml')
+
+  ignore_headers = [
+    'fam',
+    'fen',
+    'gdbus-2.0',
+    'gvdb',
+    'inotify',
+    'kqueue',
+    'libasyncns',
+    'tests',
+    'win32',
+    'xdgmime',
+    'gappinfoprivate.h',
+    'gapplicationimpl.h',
+    'gasynchelper.h',
+    'gcontenttypeprivate.h',
+    'gcontextspecificgroup.h',
+    'gcredentialsprivate.h',
+    'gdbus-daemon-generated.h',
+    'gdbusactiongroup-private.h',
+    'gdbusauth.h',
+    'gdbusauthmechanismanon.h',
+    'gdbusauthmechanismexternal.h',
+    'gdbusauthmechanism.h',
+    'gdbusauthmechanismsha1.h',
+    'gdbusdaemon.h',
+    'gdbusprivate.h',
+    'gdelayedsettingsbackend.h',
+    'gdocumentportal.h',
+    'gdummyfile.h',
+    'gdummyproxyresolver.h',
+    'gdummytlsbackend.h',
+    'gfileattribute-priv.h',
+    'gfileinfo-priv.h',
+    'ghttpproxy.h',
+    'giomodule-priv.h',
+    'gioprivate.h',
+    'giowin32-priv.h',
+    'gio_probes.h',
+    'gio_trace.h',
+    'gio-tool.h',
+    'glocaldirectorymonitor.h',
+    'glocalfileenumerator.h',
+    'glocalfile.h',
+    'glocalfileinfo.h',
+    'glocalfileinputstream.h',
+    'glocalfileiostream.h',
+    'glocalfilemonitor.h',
+    'glocalfileoutputstream.h',
+    'glocalvfs.h',
+    'gmemorymonitordbus.h',
+    'gmemorymonitorportal.h',
+    'gmountprivate.h',
+    'gnativevolumemonitor.h',
+    'gnetworkingprivate.h',
+    'gnetworkmonitorbase.h',
+    'gnetworkmonitornetlink.h',
+    'gnetworkmonitornm.h',
+    'gnetworkmonitorportal.h',
+    'gnotificationbackend.h',
+    'gnotification-private.h',
+    'gopenuriportal.h',
+    'gpollfilemonitor.h',
+    'gportalsupport.h',
+    'gproxyresolverportal.h',
+    'gregistrysettingsbackend.h',
+    'gresourcefile.h',
+    'gsettingsbackendinternal.h',
+    'gsettings-mapping.h',
+    'gsettingsschema-internal.h',
+    'gsocketinputstream.h',
+    'gsocketoutputstream.h',
+    'gsocks4aproxy.h',
+    'gsocks4proxy.h',
+    'gsocks5proxy.h',
+    'gsubprocesslauncher-private.h',
+    'gthreadedresolver.h',
+    'gtrashportal.h',
+    'gunionvolumemonitor.h',
+    'gunixmount.h',
+    'gunixresolver.h',
+    'gunixvolume.h',
+    'gunixvolumemonitor.h',
+    'gwin32networkmonitor.h',
+    'gwin32appinfo.h',
+    'gwin32mount.h',
+    'gwin32resolver.h',
+    'gwin32volumemonitor.h',
+    'thumbnail-verify.h',
+    'xdp-dbus.h',
+  ]
+
+  sections_files = files('gio-sections-common.txt')
+
+  if host_system == 'windows'
+    ignore_headers += [
+      'gfiledescriptorbased.h',
+      'gunixconnection.h',
+      'gunixcredentialsmessage.h',
+      'gunixmounts.h',
+      'gunixfdlist.h',
+      'gunixfdmessage.h',
+      'gunixinputstream.h',
+      'gunixoutputstream.h',
+      'gunixsocketaddress.h',
+      'gdesktopappinfo.h',
+      'gosxappinfo.h',
+    ]
+    sections_files += files('gio-sections-win32.txt')
+    platform_file = files('gio-docs-win32.xml')
+  else
+    if glib_have_cocoa
+      ignore_headers += ['gdesktopappinfo.h']
+    else
+      ignore_headers += ['gosxappinfo.h']
+    endif
+
+    ignore_headers += [
+      'gwin32inputstream.h',
+      'gwin32outputstream.h',
+      'gwin32registrykey.h',
+    ]
+    platform_file = files('gio-docs-unix.xml')
+  endif
+
+  ignore_sources = [
+    'kqueue',
+    'tests',
+    'gdbus-daemon-generated.c',
+    'xdp-dbus.c',
+  ]
+
+  docpath = join_paths(glib_datadir, 'gtk-doc', 'html')
+  version_conf = configuration_data()
+  version_conf.set('VERSION', meson.project_version())
+  configure_file(
+    input: 'version.xml.in',
+    output: 'version.xml',
+    configuration: version_conf
+  )
+
+  # FIXME: configure_file() does not support more than one file in input
+  # argument. If input argument is omitted then meson checks that all items in
+  # the command array are strings. But if we have an input then extra files
+  # can be passed in command array.
+  # See https://github.com/mesonbuild/meson/issues/5893
+  concat_files_helper = find_program('concat-files-helper.py')
+  configure_file(
+    output : 'gio-sections.txt',
+    input : sections_files[0],
+    command : [concat_files_helper, '@OUTPUT@'] + sections_files,
+  )
+
+  configure_file(
+    output : 'gio-docs-platform.xml',
+    input : platform_file,
+    copy : true,
+  )
+
+  content_files = [
+    'overview.xml',
+    'migrating-posix.xml',
+    'migrating-gnome-vfs.xml',
+    'migrating-gconf.xml',
+    'migrating-gdbus.xml',
+    'gio-querymodules.xml',
+    'glib-compile-schemas.xml',
+    'glib-compile-resources.xml',
+    'gapplication.xml',
+    'gsettings.xml',
+    'gresource.xml',
+    'gdbus.xml',
+    'gdbus-codegen.xml',
+  ]
+
+  if installed_tests_enabled
+    content_files += [
+      gdbus_example_objectmanager_xml,
+      gdbus_example_objectmanager_sources,
+      gdbus_object_manager_example_doc
+    ]
+  endif
+
+  gnome.gtkdoc('gio',
+    main_xml : 'gio-docs.xml',
+    namespace : 'g',
+    mode : 'none',
+    dependencies : [libgio_dep, libgobject_dep, libglib_dep],
+    src_dir : 'gio',
+    scan_args : gtkdoc_common_scan_args + [
+      '--rebuild-types',
+      '--ignore-headers=' + ' '.join(ignore_headers),
+    ],
+    mkdb_args : [
+      '--ignore-files=' + ' '.join(ignore_sources),
+    ],
+    content_files : content_files,
+    expand_content_files : [
+      'overview.xml',
+      'migrating-posix.xml',
+      'migrating-gnome-vfs.xml',
+      'migrating-gconf.xml',
+      'migrating-gdbus.xml',
+      'gdbus-codegen.xml',
+    ],
+    html_assets : [
+      'gvfs-overview.png',
+      'menu-example.png',
+      'menu-model.png',
+    ],
+    fixxref_args: [
+      '--html-dir=' + docpath,
+      '--extra-dir=' + join_paths('gio', '..', 'glib', 'html'),
+      '--extra-dir=' + join_paths('gio', '..', 'gobject', 'html'),
+    ],
+    install: true,
+    check: true,
+  )
+endif
+
+
+if get_option('man')
+  manpages = ['gapplication', 'gio-querymodules', 'glib-compile-schemas',
+              'glib-compile-resources', 'gsettings', 'gresource', 'gdbus',
+              'gio', 'gdbus-codegen']
+  foreach page : manpages
+    custom_target(page + '-man',
+      input: page + '.xml',
+      output: page + '.1',
+      command: xsltproc_command,
+      install: true,
+      install_dir: man1_dir)
+  endforeach
+endif
diff --git a/docs/reference/gio/migrating-gconf.xml b/docs/reference/gio/migrating-gconf.xml
new file mode 100644
index 0000000..d9fd064
--- /dev/null
+++ b/docs/reference/gio/migrating-gconf.xml
@@ -0,0 +1,515 @@
+  <chapter>
+    <title>Migrating from GConf to GSettings</title>
+
+    <section>
+      <title>Before you start</title>
+
+      <para>
+        Converting individual applications and their settings from GConf to
+        GSettings can be done at will. But desktop-wide settings like font or
+        theme settings often have consumers in multiple modules. Therefore,
+        some consideration has to go into making sure that all users of a setting
+        are converted to GSettings at the same time or that the program
+        responsible for configuring that setting continues to update the value in
+        both places.
+      </para>
+      <para>
+        It is always a good idea to have a look at how others have handled
+        similar problems before.
+      </para>
+    </section>
+
+    <section>
+      <title>Conceptual differences</title>
+
+      <para>
+        Conceptually, GConf and GSettings are fairly similar. Both
+        have a concept of pluggable backends. Both keep information
+        about keys and their types in schemas. Both have a concept of
+        mandatory values, which lets you implement lock-down.
+      </para>
+      <para>
+        There are some differences in the approach to schemas. GConf
+        installs the schemas into the database and has API to handle
+        schema information (gconf_client_get_default_from_schema(),
+        gconf_value_get_schema(), etc). GSettings on the other hand
+        assumes that an application knows its own schemas, and does
+        not provide API to handle schema information at runtime.
+        GSettings is also more strict about requiring a schema whenever
+        you want to read or write a key. To deal with more free-form
+        information that would appear in schema-less entries in GConf,
+        GSettings allows for schemas to be 'relocatable'.
+      </para>
+      <para>
+        One difference in the way applications interact with their
+        settings is that with GConf you interact with a tree of
+        settings (ie the keys you pass to functions when reading
+        or writing values are actually paths with the actual name
+        of the key as the last element. With GSettings, you create
+        a GSettings object which has an implicit prefix that determines
+        where the settings get stored in the global tree of settings,
+        but the keys you pass when reading or writing values are just
+        the key names, not the full path.
+      </para>
+    </section>
+
+    <section>
+      <title>GConfClient (and GConfBridge) API conversion</title>
+
+      <para>
+        Most people use GConf via the high-level #GConfClient API.
+        The corresponding API is the #GSettings object. While not
+        every GConfClient function has a direct GSettings equivalent,
+        many do:
+        <table id="gconf-client-vs-gsettings">
+          <tgroup cols="2">
+            <thead>
+              <row><entry>GConfClient</entry><entry>GSettings</entry></row>
+            </thead>
+            <tbody>
+              <row><entry>gconf_client_get_default()</entry><entry>no direct equivalent,
+                                                                   instead you call g_settings_new() for the schemas you use</entry></row>
+              <row><entry>gconf_client_set()</entry><entry>g_settings_set()</entry></row>
+              <row><entry>gconf_client_get()</entry><entry>g_settings_get()</entry></row>
+              <row><entry>gconf_client_get_bool()</entry><entry>g_settings_get_boolean()</entry></row>
+              <row><entry>gconf_client_set_bool()</entry><entry>g_settings_set_boolean()</entry></row>
+              <row><entry>gconf_client_get_int()</entry><entry>g_settings_get_int()</entry></row>
+              <row><entry>gconf_client_set_int()</entry><entry>g_settings_set_int()</entry></row>
+              <row><entry>gconf_client_get_float()</entry><entry>g_settings_get_double()</entry></row>
+              <row><entry>gconf_client_set_float()</entry><entry>g_settings_set_double()</entry></row>
+              <row><entry>gconf_client_get_string()</entry><entry>g_settings_get_string()</entry></row>
+              <row><entry>gconf_client_set_string()</entry><entry>g_settings_set_string()</entry></row>
+              <row><entry>gconf_client_get_list()</entry><entry>for string lists, see g_settings_get_strv(), else see g_settings_get_value() and #GVariant API</entry></row>
+              <row><entry>gconf_client_set_list()</entry><entry>for string lists, see g_settings_set_strv(), else see g_settings_set_value() and #GVariant API</entry></row>
+              <row><entry>gconf_entry_get_is_writable()</entry><entry>g_settings_is_writable()</entry></row>
+              <row><entry>gconf_client_notify_add()</entry><entry>not required, the #GSettings::changed signal is emitted automatically</entry></row>
+              <row><entry>gconf_client_add_dir()</entry><entry>not required, each GSettings instance automatically watches all keys in its path</entry></row>
+              <row><entry>#GConfChangeSet</entry><entry>g_settings_delay(), g_settings_apply()</entry></row>
+              <row><entry>gconf_client_get_default_from_schema()</entry><entry>no equivalent, applications are expected to know their schema</entry></row>
+              <row><entry>gconf_client_all_entries()</entry><entry>no equivalent, applications are expected to know their schema, and GSettings does not allow schema-less entries</entry></row>
+              <row><entry>gconf_client_get_without_default()</entry><entry>no equivalent</entry></row>
+              <row><entry>gconf_bridge_bind_property()</entry><entry>g_settings_bind()</entry></row>
+              <row><entry>gconf_bridge_bind_property_full()</entry><entry>g_settings_bind_with_mapping()</entry></row>
+            </tbody>
+          </tgroup>
+        </table>
+      </para>
+      <para>
+        GConfBridge was a third-party library that used GConf to bind an object property
+        to a particular configuration key. GSettings offers this service itself.
+      </para>
+      <para>
+        There is a pattern that is sometimes used for GConf, where a setting can have
+        explicit 'value A', explicit 'value B' or 'use the system default'. With GConf,
+        'use the system default' is sometimes implemented by unsetting the user value.
+      </para>
+      <para>
+        This is not possible in GSettings, since it does not have API to determine if a value
+        is the default and does not let you unset values. The recommended way (and much
+        clearer) way in which this can be implemented in GSettings is to have a separate
+        'use-system-default' boolean setting.
+      </para>
+    </section>
+
+    <section>
+      <title>Change notification</title>
+
+      <para>
+        GConf requires you to call gconf_client_add_dir() and
+        gconf_client_notify_add() to get change notification. With
+        GSettings, this is not necessary; signals get emitted automatically
+        for every change.
+      </para>
+      <para>
+        The #GSettings::changed signal is emitted for each changed key.
+        There is also a #GSettings::change-event signal that you can handle
+        if you need to see groups of keys that get changed at the same time.
+      </para>
+      <para>
+        GSettings also notifies you about changes in writability of keys,
+        with the #GSettings::writable-changed signal (and the
+        #GSettings::writable-change-event signal).
+      </para>
+    </section>
+
+    <section><title>Change sets</title>
+      <para>
+        GConf has a concept of a set of changes which can be applied or reverted
+        at once: #GConfChangeSet (GConf doesn't actually apply changes atomically,
+        which is one of its shortcomings).
+      </para>
+      <para>
+        Instead of a separate object to represent a change set, GSettings has a
+        'delayed-apply' mode, which can be turned on for a GSettings object by
+        calling g_settings_delay(). In this mode, changes done to the GSettings
+        object are not applied - they are still visible when calling g_settings_get()
+        <emphasis>on the same object</emphasis>, but not to other GSettings instances
+        or even other processes.
+      </para>
+      <para>
+        To apply the pending changes all at once (GSettings <emphasis>does</emphasis>
+        atomicity here), call g_settings_apply(). To revert the pending changes,
+        call g_settings_revert() or just drop the reference to the #GSettings object.
+      </para>
+    </section>
+
+    <section>
+      <title>Schema conversion</title>
+
+      <para>
+        If you are porting your application from GConf, most likely you already
+        have a GConf schema. GConf comes with a commandline tool
+        gsettings-schema-convert that can help with the task of converting
+        a GConf schema into an equivalent GSettings schema. The tool is not
+        perfect and may need assistance in some cases.
+      </para>
+      <example><title>An example for using gsettings-schema-convert</title>
+        <para>Running <userinput>gsettings-schema-convert --gconf --xml --schema-id "org.gnome.font-rendering" --output org.gnome.font-rendering.gschema.xml destop_gnome_font_rendering.schemas</userinput> on the following <filename>desktop_gnome_font_rendering.schemas</filename> file:
+        <programlisting>
+<![CDATA[
+<?xml version="1.0"?>
+<gconfschemafile>
+    <schemalist>
+        <schema>
+            <key>/schemas/desktop/gnome/font_rendering/dpi</key>
+            <applyto>/desktop/gnome/font_rendering/dpi</applyto>
+            <owner>gnome</owner>
+            <type>int</type>
+            <default>96</default>
+            <locale name="C">
+                <short>DPI</short>
+                <long>The resolution used for converting font sizes to pixel sizes, in dots per inch.</long>
+            </locale>
+        </schema>
+    </schemalist>
+</gconfschemafile>
+]]>
+</programlisting>
+produces a <filename>org.gnome.font-rendering.gschema.xml</filename> file with the following content:
+<programlisting>
+<![CDATA[
+<schemalist>
+  <schema id="org.gnome.font-rendering" path="/desktop/gnome/font_rendering/">
+    <key name="dpi" type="i">
+      <default>96</default>
+      <summary>DPI</summary>
+      <description>The resolution used for converting font sizes to pixel sizes, in dots per inch.</description>
+    </key>
+  </schema>
+</schemalist>
+]]>
+</programlisting>
+</para>
+      </example>
+
+      <para>
+       GSettings schemas are identified at runtime by their id (as specified
+       in the XML source file). It is recommended to use a dotted name as schema
+       id, similar in style to a D-Bus bus name, e.g. "org.gnome.SessionManager".
+       In cases where the settings are general and not specific to one application,
+       the id should not use StudlyCaps, e.g. "org.gnome.font-rendering".
+       The filename used for the XML schema source is immaterial, but
+       schema compiler expects the files to have the extension
+       <filename>.gschema.xml</filename>. It is recommended to simply
+       use the schema id as the filename, followed by this extension,
+       e.g. <filename>org.gnome.SessionManager.gschema.xml</filename>.
+      </para>
+
+      <para>
+        The XML source file for your GSettings schema needs to get installed
+        into <filename>$datadir/glib-2.0/schemas</filename>, and needs to be
+        compiled into a binary form. At runtime, GSettings looks for compiled
+        schemas in the <filename>glib-2.0/schemas</filename> subdirectories
+        of all <envar>XDG_DATA_DIRS</envar> directories, so if you install
+        your schema in a different location, you need to set the
+        <envar>XDG_DATA_DIRS</envar> environment variable appropriately.
+      </para>
+      <para>
+        Schemas are compiled into binary form by the
+        <link linkend="glib-compile-schemas">glib-compile-schemas</link> utility.
+        GIO provides a <literal>glib_compile_schemas</literal>
+        variable for the schema compiler.
+      </para>
+      <para>
+        You can ignore all of this by using the provided m4 macros.  To
+        do this, add to your <filename>configure.ac</filename>:
+<programlisting>
+GLIB_GSETTINGS
+</programlisting>
+        The corresponding <filename>Makefile.am</filename> fragment looks like
+        this:
+<programlisting>
+# gsettings_SCHEMAS is a list of all the schemas you want to install
+gsettings_SCHEMAS = my.app.gschema.xml
+
+# include the appropriate makefile rules for schema handling
+@GSETTINGS_RULES@
+</programlisting>
+      </para>
+
+      <para>
+        This is not sufficient on its own.  You need to mention what the source
+        of the <filename>my.app.gschema.xml</filename> file is.  If the schema
+        file is distributed directly with your project's tarball then a mention
+        in <varname>EXTRA_DIST</varname> is appropriate.  If the schema file is
+        generated from another source then you will need the appropriate rule
+        for that, plus probably an item in <varname>EXTRA_DIST</varname> for the
+        source files used by that rule.
+      </para>
+
+      <para>
+        One possible pitfall in doing schema conversion is that the default
+        values in GSettings schemas are parsed by the #GVariant parser.
+        This means that strings need to include quotes in the XML.  Also note
+        that the types are now specified as #GVariant type strings.
+        <programlisting>
+<![CDATA[
+<type>string</type>
+<default>rgb</default>
+]]>
+        </programlisting>
+        becomes
+        <programlisting>
+<![CDATA[
+<key name="rgba-order" type="s">
+  <default>'rgb'</default> <!-- note quotes -->
+</key>
+]]>
+        </programlisting>
+      </para>
+      <para>
+        Another possible complication is that GConf specifies full paths
+        for each key, while a GSettings schema has a 'path' attribute that
+        contains the prefix for all the keys in the schema, and individual
+        keys just have a simple name. So
+        <programlisting>
+<![CDATA[
+<key>/schemas/desktop/gnome/font_rendering/antialiasing</key>
+]]>
+        </programlisting>
+        becomes
+        <programlisting>
+<![CDATA[
+<schema id="org.gnome.font" path="/desktop/gnome/font_rendering/">
+  <key name="antialiasing" type="s">
+]]>
+        </programlisting>
+      </para>
+      <para>
+        Default values can be localized in both GConf and GSettings schemas,
+        but GSettings uses gettext for the localization. You can specify
+        the gettext domain to use in the <tag class="attribute">gettext-domain</tag>
+        attribute. Therefore, when converting localized defaults in GConf,
+        <programlisting>
+<![CDATA[
+<key>/schemas/apps/my_app/font_size</key>
+  <locale name="C">
+    <default>18</default>
+  </locale>
+  <locale name="be">
+    <default>24</default>
+  </locale>
+</key>
+]]>
+        </programlisting>
+        becomes
+        <programlisting>
+<![CDATA[
+<schema id="..." gettext-domain="your-domain">
+ ...
+<key name="font-size" type="i">
+  <default l10n="messages" context="font_size">18</default>
+</key>
+]]>
+        </programlisting>
+      </para>
+      <para>
+        GSettings uses gettext for translation of default values.
+        The string that is translated is exactly the string that appears
+        inside of the <tag class='starttag'>default</tag> element.  This
+        includes the quotation marks that appear around strings.
+        Default values must be marked with the <varname>l10n</varname>
+        attribute in the <tag class='starttag'>default</tag> tag, which
+        should be set as equal to <literal>'messages'</literal> or
+        <literal>'time'</literal> depending on the desired category.  An
+        optional translation context can also be specified with the
+        <varname>context</varname> attribute, as in the example.  This
+        is usually recommended, since the string "<literal>18</literal>"
+        is not particularly easy to translate without context.  The
+        translated version of the default value should be stored in the
+        specified <varname>gettext-domain</varname>.  Care must be taken
+        during translation to ensure that all translated values remain
+        syntactically valid; mistakes here will cause runtime errors.
+      </para>
+      <para>
+        GSettings schemas have optional <tag class="starttag">summary</tag> and
+        <tag class="starttag">description</tag> elements for each key which
+        correspond to the <tag class="starttag">short</tag> and
+        <tag class="starttag">long</tag> elements in the GConf schema and
+        will be used in similar ways by a future gsettings-editor, so you
+        should use the same conventions for them: The summary is just a short
+        label with no punctuation, the description can be one or more complete
+        sentences. If multiple paragraphs are desired for the description, the
+        paragraphs should be separated by a completely empty line.
+      </para>
+      <para>
+        Translations for these strings will also be handled
+        via gettext, so you should arrange for these strings to be
+        extracted into your gettext catalog. One way to do that is to use
+        intltool. Since intltool 0.50.1, schema files are
+        supported, so all you have to do is to add your .gschema.xml
+        files to <filename>POTFILES.in</filename> with a line like
+        <programlisting>
+        [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml
+        </programlisting>
+      </para>
+      <para>
+        GSettings is a bit more restrictive about key names than GConf. Key
+        names in GSettings can be at most 32 characters long, and must only
+        consist of lowercase characters, numbers and dashes, with no
+        consecutive dashes. The first character must not be a number or dash,
+        and the last character cannot be '-'.
+      </para>
+      <para>
+        If you are using the GConf backend for GSettings during the
+        transition, you may want to keep your key names the same they
+        were in GConf, so that existing settings in the users GConf
+        database are preserved. You can achieve this by using the
+        <option>--allow-any-name</option> with the
+        <link linkend="glib-compile-schemas">glib-compile-schemas</link> schema
+        compiler. Note that this option is only meant
+        to ease the process of porting your application, allowing parts
+        of your application to continue to access GConf and parts to use
+        GSettings. By the time you have finished porting your application
+        you must ensure that all key names are valid.
+      </para>
+    </section>
+
+    <section><title>Data conversion</title>
+      <para>
+        GConf comes with a GSettings backend that can be used to
+        facility the transition to the GSettings API until you are
+        ready to make the jump to a different backend (most likely
+        dconf). To use it, you need to set the <envar>GSETTINGS_BACKEND</envar>
+        to 'gconf', e.g. by using
+<programlisting>
+  g_setenv ("GSETTINGS_BACKEND", "gconf", TRUE);
+</programlisting>
+        early on in your program. Note that this backend is meant purely
+        as a transition tool, and should not be used in production.
+      </para>
+      <para>
+        GConf also comes with a utility called
+        <command>gsettings-data-convert</command>, which is designed to help
+        with the task of migrating user settings from GConf into another
+        GSettings backend. It can be run manually, but it is designed to be
+        executed automatically, every time a user logs in. It keeps track of
+        the data migrations that it has already done, and it is harmless to
+        run it more than once.
+      </para>
+      <para>
+        To make use of this utility, you must install a keyfile in the
+        directory <filename>/usr/share/GConf/gsettings</filename> which
+        lists the GSettings keys and GConf paths to map to each other, for
+        each schema that you want to migrate user data for.
+      </para>
+      <para>
+        Here is an example:
+        <programlisting>
+<![CDATA[
+[org.gnome.fonts]
+antialiasing = /desktop/gnome/font_rendering/antialiasing
+dpi = /desktop/gnome/font_rendering/dpi
+hinting = /desktop/gnome/font_rendering/hinting
+rgba-order = /desktop/gnome/font_rendering/rgba_order
+
+[apps.myapp:/path/to/myapps/]
+some-odd-key1 = /apps/myapp/some_ODD-key1
+]]>
+        </programlisting>
+        The last key demonstrates that it may be necessary to modify the key
+        name to comply with stricter GSettings key name rules. Of course,
+        that means your application must use the new key names when looking
+        up settings in GSettings.
+      </para>
+      <para>
+        The last group in the example also shows how to handle the case
+        of 'relocatable' schemas, which don't have a fixed path. You can
+        specify the path to use in the group name, separated by a colon.
+      </para>
+      <para>
+        There are some limitations: <command>gsettings-data-convert</command>
+        does not do any transformation of the values. And it does not handle
+        complex GConf types other than lists of strings or integers.
+      </para>
+      <para>
+        Don't forget to require GConf 2.31.1 or newer in your configure
+        script if you are making use of the GConf backend or the conversion
+        utility.
+      </para>
+
+      <para>
+        If, as an application developer, you are interested in manually
+        ensuring that <command>gsettings-data-convert</command> has been
+        invoked (for example, to deal with the case where the user is
+        logged in during a distribution upgrade or for non-XDG desktop
+        environments which do not run the command as an autostart) you
+        may invoke it manually during your program initialisation.  This
+        is not recommended for all application authors -- it is your
+        choice if this use case concerns you enough.
+      </para>
+      <para>
+        Internally, <command>gsettings-data-convert</command> uses a
+        keyfile to track which settings have been migrated.  The
+        following code fragment will check that keyfile to see if your
+        data conversion script has been run yet and, if not, will
+        attempt to invoke the tool to run it.  You should adapt it to
+        your application as you see fit.
+      </para>
+      <para>
+        <programlisting>
+<![CDATA[
+static void
+ensure_migrated (const gchar *name)
+{
+  gboolean needed = TRUE;
+  GKeyFile *kf;
+  gchar **list;
+  gsize i, n;
+
+  kf = g_key_file_new ();
+
+  g_key_file_load_from_data_dirs (kf, "gsettings-data-convert",
+                                  NULL, G_KEY_FILE_NONE, NULL);
+  list = g_key_file_get_string_list (kf, "State", "converted", &n, NULL);
+
+  if (list)
+    {
+      for (i = 0; i < n; i++)
+        if (strcmp (list[i], name) == 0)
+          {
+            needed = FALSE;
+            break;
+          }
+
+      g_strfreev (list);
+    }
+
+  g_key_file_free (kf);
+
+  if (needed)
+    g_spawn_command_line_sync ("gsettings-data-convert",
+                               NULL, NULL, NULL, NULL);
+}
+
+]]>
+        </programlisting>
+      </para>
+      <para>
+        Although there is the possibility that the
+        <command>gsettings-data-convert</command> script will end up
+        running multiple times concurrently with this approach, it is
+        believed that this is safe.
+      </para>
+    </section>
+  </chapter>
diff --git a/docs/reference/gio/migrating-gdbus.xml b/docs/reference/gio/migrating-gdbus.xml
new file mode 100644
index 0000000..5e2d464
--- /dev/null
+++ b/docs/reference/gio/migrating-gdbus.xml
@@ -0,0 +1,309 @@
+<?xml version="1.0"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+                  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+<!ENTITY version SYSTEM "version.xml">
+]>
+<chapter>
+  <title>Migrating to GDBus</title>
+
+  <section>
+    <title>Conceptual differences</title>
+
+    <para>
+      The central concepts of D-Bus are modelled in a very similar way
+      in dbus-glib and GDBus. Both have objects representing connections,
+      proxies and method invocations. But there are some important
+      differences:
+      <itemizedlist>
+        <listitem><para>
+          dbus-glib uses the <ulink
+          url="http://www.freedesktop.org/wiki/Software/dbus#ReferenceImplementation.28dbus-daemonandlibdbus.29">libdbus
+          reference implementation</ulink>, GDBus doesn't. Instead, it
+          relies on GIO streams as transport layer, and has its own
+          implementation for the D-Bus connection setup and
+          authentication. Apart from using streams as transport,
+          avoiding libdbus also lets GDBus avoid some thorny
+          multithreading issues.
+        </para></listitem>
+        <listitem><para>
+          dbus-glib uses the GObject type system for method arguments and
+          return values, including a homegrown container specialization
+          mechanism. GDBus relies on the #GVariant type system which is
+          explicitly designed to match D-Bus types.
+        </para></listitem>
+        <listitem><para>
+          dbus-glib models only D-Bus interfaces and does not provide
+          any types for objects. GDBus models both D-Bus interfaces
+          (via the #GDBusInterface, #GDBusProxy and
+          #GDBusInterfaceSkeleton types) and objects (via the
+          #GDBusObject, #GDBusObjectSkeleton and #GDBusObjectProxy types).
+        </para></listitem>
+        <listitem><para>
+          GDBus includes native support for the <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties</ulink> (via the #GDBusProxy type) and <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink> D-Bus interfaces, dbus-glib doesn't.
+        </para></listitem>
+        <listitem><para>
+          The typical way to export an object in dbus-glib involves
+          generating glue code from XML introspection data using
+          <command>dbus-binding-tool</command>. GDBus provides a
+          similar tool called <command><link
+          linkend="gdbus-codegen">gdbus-codegen</link></command> that
+          can also generate Docbook D-Bus interface documentation.
+        </para></listitem>
+        <listitem><para>
+          dbus-glib doesn't provide any convenience API for owning and
+          watching bus names, GDBus provides the g_bus_own_name() and
+          g_bus_watch_name() family of convenience functions.
+        </para></listitem>
+        <listitem><para>
+          GDBus provides API to parse, generate and work with <link
+          linkend="gio-D-Bus-Introspection-Data">Introspection
+          XML</link>, dbus-glib doesn't.
+        </para></listitem>
+        <listitem><para>
+          GTestDBus provides API to create isolated unit tests <link
+          linkend="gio-D-Bus-Test-Scaffolding">GDBus Test Scaffolding</link>.
+        </para></listitem>
+      </itemizedlist>
+    </para>
+  </section>
+
+  <section>
+    <title>API comparison</title>
+
+    <table id="dbus-glib-vs-gdbus">
+      <title>dbus-glib APIs and their GDBus counterparts</title>
+      <tgroup cols="2">
+        <thead>
+           <row><entry>dbus-glib</entry><entry>GDBus</entry></row>
+        </thead>
+        <tbody>
+          <row><entry>#DBusGConnection</entry><entry>#GDBusConnection</entry></row>
+          <row><entry>#DBusGProxy</entry><entry>#GDBusProxy, #GDBusInterface - also see #GDBusObjectProxy</entry></row>
+          <row><entry>#DBusGObject</entry><entry>#GDBusInterfaceSkeleton, #GDBusInterface - also see #GDBusObjectSkeleton</entry></row>
+          <row><entry>#DBusGMethodInvocation</entry><entry>#GDBusMethodInvocation</entry></row>
+          <row><entry>dbus_g_bus_get()</entry><entry>g_bus_get_sync(), also see
+               g_bus_get()</entry></row>
+          <row><entry>dbus_g_proxy_new_for_name()</entry><entry>g_dbus_proxy_new_sync() and
+               g_dbus_proxy_new_for_bus_sync(), also see g_dbus_proxy_new()</entry></row>
+          <row><entry>dbus_g_proxy_add_signal()</entry><entry>not needed, use the generic #GDBusProxy::g-signal</entry></row>
+          <row><entry>dbus_g_proxy_connect_signal()</entry><entry>use g_signal_connect() with #GDBusProxy::g-signal</entry></row>
+          <row><entry>dbus_g_connection_register_g_object()</entry><entry>g_dbus_connection_register_object() - also see g_dbus_object_manager_server_export()</entry></row>
+          <row><entry>dbus_g_connection_unregister_g_object()</entry><entry>g_dbus_connection_unregister_object() - also see g_dbus_object_manager_server_unexport()</entry></row>
+          <row><entry>dbus_g_object_type_install_info()</entry><entry>introspection data is installed while registering
+               an object, see g_dbus_connection_register_object()</entry></row>
+          <row><entry>dbus_g_proxy_begin_call()</entry><entry>g_dbus_proxy_call()</entry></row>
+          <row><entry>dbus_g_proxy_end_call()</entry><entry>g_dbus_proxy_call_finish()</entry></row>
+          <row><entry>dbus_g_proxy_call()</entry><entry>g_dbus_proxy_call_sync()</entry></row>
+          <row><entry>dbus_g_error_domain_register()</entry><entry>g_dbus_error_register_error_domain()</entry></row>
+          <row><entry>dbus_g_error_has_name()</entry><entry>no direct equivalent, see g_dbus_error_get_remote_error()</entry></row>
+          <row><entry>dbus_g_method_return()</entry><entry>g_dbus_method_invocation_return_value()</entry></row>
+          <row><entry>dbus_g_method_return_error()</entry><entry>g_dbus_method_invocation_return_error() and variants</entry></row>
+          <row><entry>dbus_g_method_get_sender()</entry><entry>g_dbus_method_invocation_get_sender()</entry></row>
+        </tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section>
+    <title>Owning bus names</title>
+    <para>
+      Using dbus-glib, you typically call RequestName manually
+      to own a name, like in the following excerpt:
+      <informalexample><programlisting><![CDATA[
+  error = NULL;
+  res = dbus_g_proxy_call (system_bus_proxy,
+                           "RequestName",
+                           &error,
+                           G_TYPE_STRING, NAME_TO_CLAIM,
+                           G_TYPE_UINT,   DBUS_NAME_FLAG_ALLOW_REPLACEMENT,
+                           G_TYPE_INVALID,
+                           G_TYPE_UINT,   &result,
+                           G_TYPE_INVALID);
+  if (!res)
+    {
+      if (error != NULL)
+        {
+          g_warning ("Failed to acquire %s: %s",
+                     NAME_TO_CLAIM, error->message);
+          g_error_free (error);
+        }
+      else
+        {
+          g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
+        }
+      goto out;
+    }
+
+  if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+    {
+      if (error != NULL)
+        {
+          g_warning ("Failed to acquire %s: %s",
+                     NAME_TO_CLAIM, error->message);
+          g_error_free (error);
+        }
+      else
+        {
+          g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
+        }
+      exit (1);
+    }
+
+  dbus_g_proxy_add_signal (system_bus_proxy, "NameLost",
+                           G_TYPE_STRING, G_TYPE_INVALID);
+  dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost",
+                               G_CALLBACK (on_name_lost), NULL, NULL);
+
+  /* further setup ... */
+]]>
+      </programlisting></informalexample>
+    </para>
+    <para>
+    While you can do things this way with GDBus too, using
+    g_dbus_proxy_call_sync(), it is much nicer to use the high-level API
+    for this:
+    <informalexample><programlisting><![CDATA[
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const gchar     *name,
+                  gpointer         user_data)
+{
+  /* further setup ... */
+}
+
+/* ... */
+
+  owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
+                             NAME_TO_CLAIM,
+                             G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
+                             on_bus_acquired,
+                             on_name_acquired,
+                             on_name_lost,
+                             NULL,
+                             NULL);
+
+  g_main_loop_run (loop);
+
+  g_bus_unown_name (owner_id);
+]]>
+    </programlisting></informalexample>
+    Note that g_bus_own_name() works asynchronously and requires
+    you to enter your mainloop to await the on_name_aquired()
+    callback. Also note that in order to avoid race conditions (e.g.
+    when your service is activated by a method call), you have to export
+    your manager object <emphasis>before</emphasis> acquiring the
+    name. The on_bus_acquired() callback is the right place to do
+    such preparations.
+    </para>
+  </section>
+
+  <section>
+    <title>Creating proxies for well-known names</title>
+    <para>
+      dbus-glib lets you create proxy objects for well-known names, like the
+      following example:
+      <informalexample><programlisting><![CDATA[
+  proxy = dbus_g_proxy_new_for_name (system_bus_connection,
+                                     "org.freedesktop.Accounts",
+                                     "/org/freedesktop/Accounts",
+                                     "org.freedesktop.Accounts");
+      ]]>
+      </programlisting></informalexample>
+      For a #DBusGProxy constructed like this, method calls will be sent to
+      the current owner of the name, and that owner can change over time.
+    </para>
+    <para>
+      The same can be achieved with #GDBusProxy:
+      <informalexample><programlisting><![CDATA[
+  error = NULL;
+  proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         NULL, /* GDBusInterfaceInfo */
+                                         "org.freedesktop.Accounts",
+                                         "/org/freedesktop/Accounts",
+                                         "org.freedesktop.Accounts",
+                                         NULL, /* GCancellable */
+                                         &error);
+      ]]>
+      </programlisting></informalexample>
+      For an added layer of safety, you can specify what D-Bus
+      interface the proxy is expected to conform to by using the
+      #GDBusInterfaceInfo type.  Additionally, #GDBusProxy loads,
+      caches and tracks changes to the D-Bus properties on the remote
+      object. It also sets up match rules so D-Bus signals from the
+      remote object are delivered locally.
+    </para>
+    <para>
+      The #GDBusProxy type normally isn't used directly - instead
+      proxies subclassing #GDBusProxy generated by <command><link
+      linkend="gdbus-codegen">gdbus-codegen</link></command> is used, see <xref linkend="gdbus-example-gdbus-codegen"/>
+    </para>
+  </section>
+
+  <section>
+    <title>Generating code and docs</title>
+
+  <section id="gdbus-example-gdbus-codegen">
+    <title>Using gdbus-codegen</title>
+
+    <para>
+      dbus-glib comes with <command>dbus-binding-tool</command>, which
+      can produce somewhat nice client- and server-side wrappers for a D-Bus interface.
+      With GDBus, <command><link
+      linkend="gdbus-codegen">gdbus-codegen</link></command> is used and like
+      its counterpart, it also takes D-Bus Introspection XML as input:
+    </para>
+    <example id="gdbus-example-codegen-input"><title>Example D-Bus Introspection XML</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../gdbus-example-objectmanager.xml"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+    <para>
+      If this XML is processed like this
+<informalexample><programlisting><![CDATA[
+gdbus-codegen --interface-prefix org.gtk.GDBus.Example.ObjectManager. \
+              --generate-c-code generated-code	                      \
+              --c-namespace Example 				      \
+              --c-generate-object-manager			      \
+              --generate-docbook generated-docs                       \
+              gdbus-example-objectmanager.xml
+]]></programlisting></informalexample>
+      then two files <filename>generated-code.h</filename> and
+      <filename>generated-code.c</filename> are
+      generated. Additionally, two XML files
+      <filename>generated-docs-org.gtk.GDBus.Example.ObjectManager.Animal</filename> and
+      <filename>generated-docs-org.gtk.GDBus.Example.ObjectManager.Cat</filename>
+      with Docbook XML are generated. For an example of what the docs look
+      like see <link
+      linkend="gdbus-interface-org-gtk-GDBus-Example-ObjectManager-Animal">the Animal D-Bus interface documentation</link>.
+      and
+      <link
+      linkend="gdbus-interface-org-gtk-GDBus-Example-ObjectManager-Cat">the Cat D-Bus interface documentation</link>.
+    </para>
+    <para>
+      While the contents of <filename>generated-code.h</filename> and
+      <filename>generated-code.c</filename> are best described by the
+      <command><link
+      linkend="gdbus-codegen">gdbus-codegen</link></command> manual
+      page, brief examples of how this generated code can be used can be found in
+      <xref linkend="gdbus-example-codegen-server"/>
+      and <xref
+      linkend="gdbus-example-codegen-client"/>. Additionally, since
+      the generated code has 100% gtk-doc coverage, see
+      #ExampleAnimal, #ExampleCat, #ExampleObject and
+      #ExampleObjectManagerClient pages for documentation.
+    </para>
+
+    <example id="gdbus-example-codegen-server"><title>Server-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../gdbus-example-objectmanager-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+
+    <example id="gdbus-example-codegen-client"><title>Client-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../gdbus-example-objectmanager-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+
+  </section>
+
+  <xi:include href="../../../../gio/tests/gdbus-object-manager-example/objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml"/>
+  <xi:include href="../../../../gio/tests/gdbus-object-manager-example/objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml"/>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleAnimal.xml"/>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleCat.xml"/>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleObject.xml"/>
+  <xi:include href="../gdbus-object-manager-example/xml/ExampleObjectManagerClient.xml"/>
+
+  </section>
+
+</chapter>
diff --git a/docs/reference/gio/migrating-gnome-vfs.xml b/docs/reference/gio/migrating-gnome-vfs.xml
new file mode 100644
index 0000000..27194aa
--- /dev/null
+++ b/docs/reference/gio/migrating-gnome-vfs.xml
@@ -0,0 +1,133 @@
+  <chapter>
+    <title>Migrating from GnomeVFS to GIO</title>
+
+    <table id="gnome-vfs-vs-gio">
+      <title>Comparison of GnomeVFS and GIO concepts</title>
+      <tgroup cols="2">
+        <thead>
+          <row><entry>GnomeVFS</entry><entry>GIO</entry></row>
+        </thead>
+        <tbody>
+          <row><entry>GnomeVFSURI</entry><entry>GFile</entry></row>
+          <row><entry>GnomeVFSFileInfo</entry><entry>GFileInfo</entry></row>
+          <row><entry>GnomeVFSResult</entry><entry>GError, with G_IO_ERROR values</entry></row>
+          <row><entry>GnomeVFSHandle &amp; GnomeVFSAsyncHandle</entry><entry>GInputStream or GOutputStream</entry></row>
+          <row><entry>GnomeVFSDirectoryHandle</entry><entry>GFileEnumerator</entry></row>
+          <row><entry>mime type</entry><entry>content type</entry></row>
+          <row><entry>GnomeVFSMonitor</entry><entry>GFileMonitor</entry></row>
+          <row><entry>GnomeVFSVolumeMonitor</entry><entry>GVolumeMonitor</entry></row>
+          <row><entry>GnomeVFSVolume</entry><entry>GMount</entry></row>
+          <row><entry>GnomeVFSDrive</entry><entry>GVolume</entry></row>
+          <row><entry>-</entry><entry>GDrive</entry></row>
+          <row><entry>GnomeVFSContext</entry><entry>GCancellable</entry></row>
+          <row><entry>gnome_vfs_async_cancel</entry><entry>g_cancellable_cancel</entry></row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <section>
+      <title>Trash handling</title>
+
+      <para>
+        The handling of trashed files has been changed in GIO, compared
+        to gnome-vfs. gnome-vfs has a home-grown trash implementation that 
+        predates the freedesktop.org <ulink url="http://www.freedesktop.org/wiki/Specifications/trash-spec">Desktop Trash Can</ulink> specification
+        that is implemented in GIO. The location for storing trashed files 
+        has changed from <filename>$HOME/.Trash</filename> to 
+        <filename>$HOME/.local/share/Trash</filename> (or more correctly
+        <filename>$XDG_DATA_HOME/Trash</filename>), which means that 
+        there is a need for migrating files that have been trashed by 
+        gnome-vfs to the new location.
+      </para>
+      <para>
+        In gnome-vfs, the <filename>trash://</filename> scheme offering a 
+        merged view of all trash directories was implemented in nautilus,
+        and trash-handling applications had to find and monitor all trash 
+        directories themselves. With GIO, the <filename>trash://</filename>
+        implementation has been moved to gvfs and applications can simply
+        monitor that location:
+      </para>
+<informalexample><programlisting>
+static void
+file_changed (GFileMonitor      *file_monitor,
+              GFile             *child,
+              GFile             *other_file,
+              GFileMonitorEvent  event_type,
+              gpointer           user_data)
+{
+  switch (event_type)
+  {
+  case G_FILE_MONITOR_EVENT_DELETED:
+    g_print ("'%s' removed from trash\n", g_file_get_basename (child));
+    break;
+  case G_FILE_MONITOR_EVENT_CREATED:
+    g_print ("'%s' added to trash\n", g_file_get_basename (child));
+    break;
+  default: ;
+  }
+}
+
+static void
+start_monitoring_trash (void)
+{
+  GFile *file;
+  GFileMonitor *monitor;
+
+  file = g_file_new_for_uri ("trash://");
+  monitor = g_file_monitor_directory (file, 0, NULL, NULL);
+  g_object_unref (file);
+
+  g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), NULL);
+
+  /* ... */
+
+}       
+</programlisting></informalexample> 
+      <para>
+        GIO exposes some useful metadata about trashed files. There are
+        trash::orig-path and trash::deletion-date attributes. The 
+        standard::icon attribute of the <filename>trash://</filename> 
+        itself provides a suitable icon for displaying the trash can on 
+        the desktop. If you are using this icon, make sure to monitor
+        this attribute for changes, since the icon may be updated to
+        reflect that state of the trash can.
+      </para>
+      <para>
+        Moving a file to the trash is much simpler with GIO. Instead of
+        using gnome_vfs_find_directory() with %GNOME_VFS_DIRECTORY_KIND_TRASH 
+        to find out where to move the trashed file, just use the g_file_trash()
+        function.
+      </para>
+    </section>
+
+    <section>
+      <title>Operations on multiple files</title>
+
+      <para>
+        gnome-vfs has the dreaded gnome_vfs_xfer_uri_list() function which
+        has tons of options and offers the equivalent of cp, mv, ln, mkdir
+        and rm at the same time. 
+      </para>
+      <para>
+        GIO offers a much simpler I/O scheduler functionality instead, that
+        lets you schedule a function to be called in a separate thread, or
+        if threads are not available, as an idle in the mainloop.
+        See g_io_scheduler_push_job(). 
+      </para>
+
+    </section>
+
+    <section>
+      <title>Mime monitoring</title>
+
+      <para>
+        gnome-vfs offered a way to monitor the association between mime types
+        and default handlers for changes, with the #GnomeVFSMIMEMonitor object.
+        GIO does not offer a replacement for this functionality at this time,
+        since we have not found a compelling use case where
+        #GnomeVFSMIMEMonitor was used. If you think you have such a use
+        case, please report it at
+        <ulink url="https://gitlab.gnome.org/GNOME/glib/issues/new">https://gitlab.gnome.org/GNOME/glib/issues/new</ulink>.
+      </para>
+    </section>
+  </chapter>
diff --git a/docs/reference/gio/migrating-posix.xml b/docs/reference/gio/migrating-posix.xml
new file mode 100644
index 0000000..e7dc9f4
--- /dev/null
+++ b/docs/reference/gio/migrating-posix.xml
@@ -0,0 +1,27 @@
+<part id="migrating">
+  <title>Migrating to GIO</title>
+
+  <chapter>
+    <title>Migrating from POSIX to GIO</title>
+  
+    <table id="posix-vs-gio">
+      <title>Comparison of POSIX and GIO concepts</title>
+      <tgroup cols="2">
+        <thead>
+          <row><entry>POSIX</entry><entry>GIO</entry></row>
+        </thead>
+        <tbody>
+          <row><entry>char *path</entry><entry>GFile *file</entry></row>
+          <row><entry>struct stat *buf</entry><entry>GFileInfo *info</entry></row>
+          <row><entry>struct statvfs *buf</entry><entry>GFileInfo *info</entry></row>
+          <row><entry morerows="1">int fd</entry><entry>GInputStream *in</entry></row>
+          <row><entry>GOutputStream *out</entry></row>
+          <row><entry>DIR *</entry><entry>GFileEnumerator *enum</entry></row>
+          <row><entry>fstab entry</entry><entry>GUnixMountPoint *mount_point</entry></row>
+          <row><entry>mtab entry</entry><entry>GUnixMountEntry *mount_entry</entry></row>
+        </tbody>
+      </tgroup>
+    </table>  
+
+  </chapter>
+</part>
diff --git a/docs/reference/gio/overview.xml b/docs/reference/gio/overview.xml
new file mode 100644
index 0000000..7817ab6
--- /dev/null
+++ b/docs/reference/gio/overview.xml
@@ -0,0 +1,755 @@
+<part>
+  <title>GIO Overview</title>
+
+  <chapter>
+    <title>Introduction</title>
+
+  <para>
+    GIO is striving to provide a modern, easy-to-use VFS API that sits
+    at the right level in the library stack, as well as other generally
+    useful APIs for desktop applications (such as networking and
+    D-Bus support). The goal is to overcome the shortcomings of GnomeVFS
+    and provide an API that is so good that developers prefer it over raw
+    POSIX calls. Among other things that means using GObject. It also means
+    not cloning the POSIX API, but providing higher-level, document-centric
+    interfaces.
+  </para>
+
+  <para>
+    The abstract file system model of GIO consists of a number of
+    interfaces and base classes for I/O and files:
+    <variablelist>
+       <varlistentry>
+         <term>GFile</term>
+         <listitem><para>reference to a file</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GFileInfo</term>
+         <listitem><para>information about a file or filesystem</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GFileEnumerator</term>
+         <listitem><para>list files in directories</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GDrive</term>
+         <listitem><para>represents a drive</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GVolume</term>
+         <listitem><para>represents a file system in an abstract way</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GMount</term>
+         <listitem><para>represents a mounted file system</para></listitem>
+       </varlistentry>
+    </variablelist>
+    Then there is a number of stream classes, similar to the input and
+    output stream hierarchies that can be found in frameworks like Java:
+    <variablelist>
+       <varlistentry>
+         <term>GInputStream</term>
+         <listitem><para>read data</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GOutputStream</term>
+         <listitem><para>write data</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GIOStream</term>
+         <listitem><para>read and write data</para></listitem>
+       </varlistentry>
+       <varlistentry>
+         <term>GSeekable</term>
+         <listitem><para>interface optionally implemented by streams to support seeking</para></listitem>
+       </varlistentry>
+    </variablelist>
+    There are interfaces related to applications and the types
+    of files they handle:
+    <variablelist>
+       <varlistentry>
+          <term>GAppInfo</term>
+          <listitem><para>information about an installed application</para></listitem>
+       </varlistentry>
+       <varlistentry>
+          <term>GIcon</term>
+          <listitem><para>abstract type for file and application icons</para></listitem>
+       </varlistentry>
+    </variablelist>
+    There is a framework for storing and retrieving application settings:
+    <variablelist>
+       <varlistentry>
+          <term>GSettings</term>
+          <listitem><para>stores and retrieves application settings</para></listitem>
+       </varlistentry>
+    </variablelist>
+    There is support for network programming, including connectivity monitoring,
+    name resolution, lowlevel socket APIs and highlevel client and server
+    helper classes:
+    <variablelist>
+       <varlistentry>
+          <term>GSocket</term>
+          <listitem><para>lowlevel platform independent socket object</para></listitem>
+       </varlistentry>
+       <varlistentry>
+          <term>GResolver</term>
+          <listitem><para>asynchronous and cancellable DNS resolver</para></listitem>
+       </varlistentry>
+       <varlistentry>
+          <term>GSocketClient</term>
+          <listitem><para>high-level network client helper</para></listitem>
+       </varlistentry>
+       <varlistentry>
+          <term>GSocketService</term>
+          <listitem><para>high-level network server helper</para></listitem>
+       </varlistentry>
+       <varlistentry>
+          <term>GSocketConnection</term>
+          <listitem><para>network connection stream</para></listitem>
+       </varlistentry>
+       <varlistentry>
+          <term>GNetworkMonitor</term>
+          <listitem><para>network connectivity monitoring</para></listitem>
+       </varlistentry>
+    </variablelist>
+    There is support for connecting to <ulink url="http://www.freedesktop.org/wiki/Software/dbus">D-Bus</ulink>,
+    sending and receiving messages, owning and watching bus names,
+    and making objects available on the bus:
+    <variablelist>
+       <varlistentry>
+          <term>GDBusConnection</term>
+          <listitem><para>a D-Bus connection</para></listitem>
+       </varlistentry>
+
+       <varlistentry>
+          <term>GDBusMethodInvocation</term>
+          <listitem><para>for handling remote calls</para></listitem>
+       </varlistentry>
+
+       <varlistentry>
+          <term>GDBusServer</term>
+          <listitem><para>helper for accepting connections</para></listitem>
+       </varlistentry>
+
+       <varlistentry>
+          <term>GDBusProxy</term>
+          <listitem><para>proxy to access D-Bus interfaces on a remote object</para></listitem>
+       </varlistentry>
+
+    </variablelist>
+    Beyond these, GIO provides facilities for file monitoring,
+    asynchronous I/O and filename completion. In addition to the
+    interfaces, GIO provides implementations for the local case.
+    Implementations for various network file systems are provided
+    by the GVFS package as loadable modules.
+  </para>
+
+  <para>
+    Other design choices which consciously break with the GnomeVFS
+    design are to move backends out-of-process, which minimizes the
+    dependency bloat and makes the whole system more robust. The backends
+    are not included in GIO, but in the separate GVFS package. The GVFS
+    package also contains the GVFS daemon, which spawn further mount
+    daemons for each individual connection.
+  </para>
+
+  <figure id="gvfs-overview">
+    <title>GIO in the GTK+ library stack</title>
+    <graphic fileref="gvfs-overview.png" format="PNG"></graphic>
+  </figure>
+
+  <para>
+    The GIO model of I/O is stateful: if an application establishes e.g.
+    a SFTP connection to a server, it becomes available to all applications
+    in the session; the user does not have to enter his password over
+    and over again.
+  </para>
+  <para>
+    One of the big advantages of putting the VFS in the GLib layer
+    is that GTK+ can directly use it, e.g. in the filechooser.
+  </para>
+  </chapter>
+
+  <chapter>
+    <title>Writing GIO applications</title>
+
+    <para>
+      The information in the GLib <ulink url="http://developer.gnome.org/glib/stable/glib-programming.html">documentation</ulink> about writing GLib
+      applications is generally applicable when writing GIO applications.
+    </para>
+
+    <simplesect><title>Threads</title>
+
+    <para>
+       GDBus has its own private worker thread, so applications using
+       GDBus have at least 3 threads. GIO makes heavy use of the concept
+       of a <link linkend="g-main-context-push-thread-default">thread-default
+       main context</link> to execute callbacks of asynchronous
+       methods in the same context in which the operation was started.
+    </para>
+
+    </simplesect>
+
+    <simplesect id="async-programming"><title>Asynchronous Programming</title>
+
+    <para>
+      Many GIO functions come in two versions: synchronous and asynchronous,
+      denoted by an <code>_async</code> suffix. It is important to use these
+      appropriately: synchronous calls should not be used from
+      within a main loop which is shared with other code, such as one in the
+      application’s main thread. Synchronous calls block until they complete,
+      and I/O operations can take noticeable amounts of time (even on ‘fast’
+      SSDs). Blocking a main loop iteration while waiting for I/O means that
+      other sources in the main loop will not be dispatched, such as input and
+      redraw handlers for the application’s UI. This can cause the application
+      to ‘freeze’ until I/O completes.
+    </para>
+
+    <para>
+      A few self-contained groups of functions, such as code generated by
+      <link linkend="gdbus-codegen"><application>gdbus-codegen</application></link>,
+      use a different convention: functions are asynchronous default, and it is
+      the <emphasis>synchronous</emphasis> version which has a
+      <code>_sync</code>
+      suffix. Aside from naming differences, they should be treated the same
+      way as functions following the normal convention above.
+    </para>
+
+    <para>
+      The asynchronous (<code>_async</code>) versions of functions return
+      control to the caller immediately, after scheduling the I/O in the kernel
+      and adding a callback for it to the main loop. This callback will be
+      invoked when the operation has completed. From the callback, the paired
+      <code>_finish</code> function should be called to retrieve the return
+      value of the I/O operation, and any errors which occurred. For more
+      information on using and implementing asynchronous functions, see
+      <link linkend="GAsyncResult.description"><type>GAsyncResult</type></link>
+      and <link linkend="GTask.description"><type>GTask</type></link>.
+    </para>
+
+    <para>
+      By starting multiple asynchronous operations in succession, they will be
+      executed in parallel (up to an arbitrary limit imposed by GIO’s internal
+      worker thread pool).
+    </para>
+
+    <para>
+      The synchronous versions of functions can be used early in application
+      startup when there is no main loop to block, for example to load initial
+      configuration files. They can also be used for I/O on files which are
+      guaranteed to be small and on the local disk. Note that the user’s home
+      directory is not guaranteed to be on the local disk.
+    </para>
+    </simplesect>
+
+    <simplesect><title>Security</title>
+
+<para>
+When your program needs to carry out some privileged operation (say,
+create a new user account), there are various ways in which you can go
+about this:
+<itemizedlist>
+<listitem><para>
+Implement a daemon that offers the privileged operation. A convenient
+way to do this is as a D-Bus system-bus service. The daemon will probably
+need ways to check the identity and authorization of the caller before
+executing the operation. <ulink url="http://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html">polkit</ulink> is a framework that allows this.
+</para></listitem>
+<listitem><para>
+Use a small helper that is executed with elevated privileges via
+pkexec. <ulink url="http://www.freedesktop.org/software/polkit/docs/latest/pkexec.1.html">pkexec</ulink> is a small program launcher that is part of polkit.
+</para></listitem>
+<listitem><para>
+Use a small helper that is executed with elevated privileges by
+being suid root.
+</para></listitem>
+</itemizedlist>
+None of these approaches is the clear winner, they all have their
+advantages and disadvantages.
+</para>
+
+<para>
+When writing code that runs with elevated privileges, it is important
+to follow some basic rules of secure programming. David Wheeler has an
+excellent book on this topic,
+<ulink url="http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/index.html">Secure Programming for Linux and Unix HOWTO</ulink>.
+</para>
+
+<para>
+When using GIO in code that runs with elevated privileges, you have to
+be careful. GIO has extension points whose implementations get loaded
+from modules (executable code in shared objects), which could allow
+an attacker to sneak his own code into your application by tricking it
+into loading the code as a module. However, GIO will never load modules
+from your home directory except when explicitly asked to do so via an
+environment variable.
+</para>
+
+<para>
+In most cases, your helper program should be so small that you don't
+need GIO, whose APIs are largely designed to support full-blown desktop
+applications. If you can't resist the convenience of these APIs, here
+are some steps you should take:
+<itemizedlist>
+<listitem><para>
+Clear the environment, e.g. using the <function>clearenv()</function>
+function.
+David Wheeler has a good <ulink url="http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html">explanation</ulink> for why it is
+important to sanitize the environment.
+See <xref linkend="running-gio-apps"/>
+for a list of all environment variables affecting GIO. In particular,
+<envar>PATH</envar> (used to locate binaries), <envar>GIO_EXTRA_MODULES</envar> (used to locate loadable modules) and <envar>DBUS_{SYSTEM,SESSION}_BUS_ADDRESS</envar> (used to locate the D-Bus system and session bus) are important.
+</para></listitem>
+<listitem><para>
+Don't use GVfs, by setting <envar>GIO_USE_VFS=local</envar> in the environment.
+The reason to avoid GVfs in security-sensitive programs is that it uses
+many libraries which have not necessarily been audited for security problems.
+Gvfs is also heavily distributed and relies on a session bus to be present.
+</para></listitem>
+</itemizedlist>
+</para>
+
+    </simplesect>
+
+  </chapter>
+
+  <chapter>
+    <title>Compiling GIO applications</title>
+
+    <para>
+      GIO comes with a <filename>gio-2.0.pc</filename> file that you
+      should use together with <literal>pkg-config</literal> to obtain
+      the necessary information about header files and libraries. See
+      the <literal>pkg-config</literal> man page or the GLib documentation
+      for more information on how to use <literal>pkg-config</literal>
+      to compile your application.
+    </para>
+
+    <para>
+      If you are using GIO on UNIX-like systems, you may want to use
+      UNIX-specific GIO interfaces such as #GUnixInputStream,
+      #GUnixOutputStream, #GUnixMount or #GDesktopAppInfo.
+      To do so, use the <filename>gio-unix-2.0.pc</filename> file
+      instead of <filename>gio-2.0.pc</filename>
+    </para>
+  </chapter>
+
+  <chapter id="running-gio-apps">
+    <title>Running GIO applications</title>
+
+    <para>
+      GIO inspects a few environment variables in addition to the
+      ones used by GLib.
+    </para>
+
+    <formalpara>
+      <title><envar>XDG_DATA_HOME</envar>, <envar>XDG_DATA_DIRS</envar></title>
+
+      <para>
+        GIO uses these environment variables to locate MIME information.
+        For more information, see the <ulink url="http://freedesktop.org/Standards/shared-mime-info-spec">Shared MIME-info Database</ulink>
+        and the <ulink url="http://freedesktop.org/Standards/basedir-spec">Base Directory Specification</ulink>.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GVFS_DISABLE_FUSE</envar></title>
+
+      <para>
+        This variable can be set to keep #Gvfs from starting the fuse backend,
+        which may be unwanted or unnecessary in certain situations.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GIO_USE_VFS</envar></title>
+
+      <para>
+        This environment variable can be set to the name of a #GVfs
+        implementation to override the default for debugging purposes.
+        The #GVfs implementation for local files that is included in GIO
+        has the name "local", the implementation in the gvfs module has
+        the name "gvfs".  Most commonly, system software will set this to "local"
+	to avoid having `GFile` APIs perform unnecessary DBus calls.
+      </para><para>
+        The special value <literal>help</literal> can be used to print a list of
+        available implementations to standard output.
+      </para>
+    </formalpara>
+
+    <para>
+      The following environment variables are only useful for debugging
+      GIO itself or modules that it loads. They should not be set in a
+      production environment.
+    </para>
+
+    <formalpara>
+      <title><envar>GIO_USE_FILE_MONITOR</envar></title>
+
+      <para>
+        This variable can be set to the name of a #GFileMonitor
+        implementation to override the default for debugging purposes.
+        The #GFileMonitor implementation for local files that is included
+        in GIO on Linux has the name "inotify", others that are built
+        are built as modules (depending on the platform) are called
+        "fam" and "fen".
+      </para><para>
+        The special value <literal>help</literal> can be used to print a list of
+        available implementations to standard output.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GIO_USE_VOLUME_MONITOR</envar></title>
+
+      <para>
+        This variable can be set to the name of a #GVolumeMonitor
+        implementation to override the default for debugging purposes.
+        The #GVolumeMonitor implementation for local files that is included
+        in GIO has the name "unix", the udisks2-based implementation in the
+        gvfs module has the name "udisks2".
+      </para><para>
+        The special value <literal>help</literal> can be used to print a list of
+        available implementations to standard output.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GIO_USE_TLS</envar></title>
+
+      <para>
+        This variable can be set to the name of a #GTlsBackend
+        implementation to override the default for debugging purposes.
+        GIO does not include a #GTlsBackend implementation, the gnutls-based
+        implementation in the glib-networking module has the name "gnutls".
+      </para><para>
+        The special value <literal>help</literal> can be used to print a list of
+        available implementations to standard output.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GIO_MODULE_DIR</envar></title>
+
+      <para>
+        When this environment variable is set to a path, GIO will load
+	modules from this alternate directory instead of the directory
+	built into GIO. This is useful when running tests, for example.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GIO_EXTRA_MODULES</envar></title>
+
+      <para>
+        When this environment variable is set to a path, or a set of
+        paths separated by a colon, GIO will attempt to load
+        additional modules from within the path.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GSETTINGS_BACKEND</envar></title>
+
+      <para>
+        This variable can be set to the name of a #GSettingsBackend
+        implementation to override the default for debugging purposes.
+        The memory-based implementation that is included in GIO has
+        the name "memory", the one in dconf has the name "dconf".
+      </para><para>
+        The special value <literal>help</literal> can be used to print a list of
+        available implementations to standard output.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><envar>GSETTINGS_SCHEMA_DIR</envar></title>
+
+      <para>
+        This variable can be set to the names of directories to consider when looking for compiled schemas for #GSettings,
+        in addition to the <filename>glib-2.0/schemas</filename>
+        subdirectories of the XDG system data dirs. To specify multiple directories, use <constant>G_SEARCHPATH_SEPARATOR_S</constant> as a separator.
+      </para>
+    </formalpara>
+
+   <formalpara>
+      <title><envar>DBUS_SYSTEM_BUS_ADDRESS</envar></title>
+
+      <para>
+        This variable is consulted to find the address of the D-Bus system
+        bus. For the format of D-Bus addresses, see the D-Bus
+        <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#addresses">specification</ulink>.
+      </para>
+      <para>
+        Setting this variable overrides platform-specific ways of determining
+        the system bus address.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title><envar>DBUS_SESSION_BUS_ADDRESS</envar></title>
+
+      <para>
+        This variable is consulted to find the address of the D-Bus session bus.
+      </para>
+      <para>
+        Setting this variable overrides platform-specific ways of determining
+        the session bus address.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title><envar>DBUS_STARTER_BUS_TYPE</envar></title>
+
+      <para>
+        This variable is consulted to find out the 'starter' bus for an
+        application that has been started via D-Bus activation. The possible
+        values are 'system' or 'session'.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title><envar>G_DBUS_DEBUG</envar></title>
+
+      <para>
+         This variable can be set to a list of debug options, which
+         cause GLib to print out different types of debugging
+         information when using the D-Bus routines.
+         <variablelist>
+           <varlistentry>
+             <term>transport</term>
+             <listitem><para>Show IO activity (e.g. reads and writes)</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>message</term>
+             <listitem><para>Show all sent and received D-Bus messages</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>payload</term>
+             <listitem><para>Show payload for all sent and received D-Bus messages (implies message)</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>call</term>
+             <listitem><para>Trace g_dbus_connection_call() and g_dbus_connection_call_sync() API usage</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>signal</term>
+             <listitem><para>Show when a D-Bus signal is received</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>incoming</term>
+             <listitem><para>Show when an incoming D-Bus method call is received</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>return</term>
+             <listitem><para>Show when a reply is returned via the #GDBusMethodInvocation API</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>emission</term>
+             <listitem><para>Trace g_dbus_connection_emit_signal() API usage</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>authentication</term>
+             <listitem><para>Show information about connection authentication</para></listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>address</term>
+             <listitem><para>Show information about D-Bus address lookups and autolaunching</para></listitem>
+           </varlistentry>
+         </variablelist>
+         The special value <literal>all</literal> can be used to turn
+         on all debug options. The special value
+         <literal>help</literal> can be used to print a list of
+         supported options to standard output.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title><envar>G_DBUS_COOKIE_SHA1_KEYRING_DIR</envar></title>
+
+      <para>
+        Can be used to override the directory used to store the
+        keyring used in the <literal>DBUS_COOKIE_SHA1</literal>
+        authentication mechanism. Normally the directory used is
+        <filename>.dbus-keyrings</filename> in the user's home
+        directory.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title><envar>G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION</envar></title>
+
+      <para>
+        If set, the permissions of the directory used to store the
+        keyring used in the <literal>DBUS_COOKIE_SHA1</literal>
+        authentication mechanism won't be checked. Normally the
+        directory must be readable only by the user.
+      </para>
+   </formalpara>
+  </chapter>
+
+  <chapter id="extending-gio">
+    <title>Extending GIO</title>
+
+    <para>
+      A lot of the functionality that is accessible through GIO
+      is implemented in loadable modules, and modules provide a convenient
+      way to extend GIO. In addition to the #GIOModule API which supports
+      writing such modules, GIO has a mechanism to define extension points,
+      and register implementations thereof, see #GIOExtensionPoint.
+    </para>
+    <para>
+      The following extension points are currently defined by GIO:
+    </para>
+
+    <formalpara>
+       <title>G_VFS_EXTENSION_POINT_NAME</title>
+
+       <para>
+          Allows to override the functionality of the #GVfs class.
+          Implementations of this extension point must be derived from #GVfs.
+          GIO uses the implementation with the highest priority that is active,
+          see g_vfs_is_active().
+       </para>
+       <para>
+          GIO implements this extension point for local files, gvfs contains
+          an implementation that supports all the backends in gvfs.
+       </para>
+   </formalpara>
+
+   <formalpara>
+      <title>G_VOLUME_MONITOR_EXTENSION_POINT_NAME</title>
+
+      <para>
+         Allows to add more volume monitors.
+         Implementations of this extension point must be derived from
+         #GVolumeMonitor. GIO uses all registered extensions.
+      </para>
+      <para>
+        gvfs contains an implementation that works together with the #GVfs
+        implementation in gvfs.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title>G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME</title>
+
+      <para>
+         Allows to override the 'native' volume monitor.
+         Implementations of this extension point must be derived from
+         #GNativeVolumeMonitor. GIO uses the implementation with
+         the highest priority that is supported, as determined by the
+         is_supported() vfunc in #GVolumeMonitorClass.
+      </para>
+      <para>
+         GIO implements this extension point for local mounts,
+         gvfs contains a udisks2-based implementation.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title>G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME</title>
+
+      <para>
+        Allows to override the file monitor implementation for
+        local files. Implementations of this extension point must
+        be derived from #GLocalFileMonitor. GIO uses the implementation
+        with the highest priority that is supported, as determined by the
+        is_supported() vfunc in #GLocalFileMonitorClass.
+      </para>
+      <para>
+        GIO uses this extension point internally, to switch between
+        its fam-based and inotify-based file monitoring implementations.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title>G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME</title>
+
+      <para>
+        Allows to override the directory monitor implementation for
+        local files. Implementations of this extension point must be
+        derived from #GLocalDirectoryMonitor. GIO uses the implementation
+        with the highest priority that is supported, as determined by the
+        is_supported() vfunc in #GLocalDirectoryMonitorClass.
+      </para>
+      <para>
+        GIO uses this extension point internally, to switch between
+        its fam-based and inotify-based directory monitoring implementations.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title>G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME</title>
+
+      <para>
+        Unix-only. Allows to provide a way to associate default handlers
+        with URI schemes. Implementations of this extension point must
+        implement the #GDesktopAppInfoLookup interface. GIO uses the
+        implementation with the highest priority.
+      </para>
+      <para>
+        This extension point has been discontinued in GLib 2.28. It is
+        still available to keep API and ABI stability, but GIO is no
+        longer using it for default handlers. Instead, the mime handler
+        mechanism is used, together with x-scheme-handler pseudo-mimetypes.
+      </para>
+   </formalpara>
+
+   <formalpara>
+      <title>G_SETTINGS_BACKEND_EXTENSION_POINT_NAME</title>
+
+      <para>
+        Allows to provide an alternative storage for #GSettings.
+        Implementations of this extension point must derive from the
+        #GSettingsBackend type. GIO contains a keyfile-based
+        implementation of this extension point, another one is provided
+        by dconf.
+      </para>
+   </formalpara>
+
+   <formalpara>
+     <title>G_PROXY_EXTENSION_POINT_NAME</title>
+
+     <para>
+       Allows to provide implementations for network proxying.
+       Implementations of this extension point must provide the
+       #GProxy interface, and must be named after the network
+       protocol they are proxying.
+     </para>
+     <para>
+       glib-networking contains an implementation of this extension
+       point based on libproxy.
+     </para>
+   </formalpara>
+   <formalpara>
+     <title>G_TLS_BACKEND_EXTENSION_POINT_NAME</title>
+
+     <para>
+       Allows to provide implementations for TLS support.
+       Implementations of this extension point must implement
+       the #GTlsBackend interface.
+     </para>
+     <para>
+       glib-networking contains an implementation of this extension
+       point.
+     </para>
+   </formalpara>
+
+   <formalpara>
+     <title>G_NETWORK_MONITOR_EXTENSION_POINT_NAME</title>
+
+     <para>
+       Allows to provide implementations for network connectivity
+       monitoring.
+       Implementations of this extension point must implement
+       the #GNetworkMonitorInterface interface.
+     </para>
+     <para>
+       GIO contains an implementation of this extension point
+       that is using the netlink interface of the Linux kernel.
+     </para>
+   </formalpara>
+  </chapter>
+</part>
+
diff --git a/docs/reference/gio/version.xml.in b/docs/reference/gio/version.xml.in
new file mode 100644
index 0000000..d78bda9
--- /dev/null
+++ b/docs/reference/gio/version.xml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/docs/reference/gio/xml/gtkdocentities.ent.in b/docs/reference/gio/xml/gtkdocentities.ent.in
new file mode 100644
index 0000000..f12c9ff
--- /dev/null
+++ b/docs/reference/gio/xml/gtkdocentities.ent.in
@@ -0,0 +1,8 @@
+<!ENTITY package "@PACKAGE@">
+<!ENTITY package_bugreport "@PACKAGE_BUGREPORT@">
+<!ENTITY package_name "@PACKAGE_NAME@">
+<!ENTITY package_string "@PACKAGE_STRING@">
+<!ENTITY package_tarname "@PACKAGE_TARNAME@">
+<!ENTITY package_url "@PACKAGE_URL@">
+<!ENTITY package_version "@PACKAGE_VERSION@">
+<!ENTITY package_api_version "@PACKAGE_API_VERSION@">
diff --git a/docs/reference/gio/xml/meson.build b/docs/reference/gio/xml/meson.build
new file mode 100644
index 0000000..6aeb745
--- /dev/null
+++ b/docs/reference/gio/xml/meson.build
@@ -0,0 +1,14 @@
+ent_conf = configuration_data()
+ent_conf.set('PACKAGE', 'glib')
+ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new')
+ent_conf.set('PACKAGE_NAME', 'glib')
+ent_conf.set('PACKAGE_STRING', 'glib')
+ent_conf.set('PACKAGE_TARNAME', 'glib')
+ent_conf.set('PACKAGE_URL', 'FIXME')
+ent_conf.set('PACKAGE_VERSION', glib_version)
+ent_conf.set('PACKAGE_API_VERSION', glib_api_version)
+configure_file(
+  input: 'gtkdocentities.ent.in',
+  output: 'gtkdocentities.ent',
+  configuration: ent_conf
+)
diff --git a/docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg b/docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg
new file mode 100644
index 0000000..697d7db
--- /dev/null
+++ b/docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

+	 width="266px" height="212px" viewBox="0 0 266 212" enable-background="new 0 0 266 212" xml:space="preserve">

+<g>

+	<g>

+		<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="27.23" y1="23.192" x2="29.23" y2="23.192"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="3.9562,3.9562" x1="33.187" y1="23.192" x2="236.932" y2="23.192"/>

+		<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="238.91,23.192 240.91,23.192 

+			238.97,23.677 		"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="3.9907,3.9907" x1="235.099" y1="24.646" x2="27.971" y2="76.427"/>

+		<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="26.035,76.912 24.095,77.396 

+			26.095,77.396 		"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="4.0154,4.0154" x1="30.11" y1="77.396" x2="236.902" y2="77.396"/>

+		<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="238.91,77.396 240.91,77.396 

+			238.97,77.881 		"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="3.9907,3.9907" x1="235.099" y1="78.85" x2="27.971" y2="130.631"/>

+		<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="26.035,131.114 24.095,131.6 

+			26.095,131.6 		"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="4.0154,4.0154" x1="30.11" y1="131.6" x2="236.902" y2="131.6"/>

+		<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="238.91,131.6 240.91,131.6 

+			238.97,132.085 		"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="3.9907,3.9907" x1="235.099" y1="133.053" x2="27.971" y2="184.835"/>

+		<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="26.035,185.318 24.095,185.804 

+			26.095,185.804 		"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="4.0086,4.0086" x1="30.104" y1="185.804" x2="228.53" y2="185.804"/>

+		

+			<line fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" x1="230.534" y1="185.804" x2="232.534" y2="185.804"/>

+		<g>

+			<rect x="24.095" y="19.892" width="6.602" height="6.602"/>

+		</g>

+		<g>

+			<path d="M238.569,185.804c-2.84,1.054-6.363,2.852-8.548,4.756l1.721-4.756l-1.721-4.755

+				C232.206,182.953,235.729,184.751,238.569,185.804z"/>

+		</g>

+	</g>

+</g>

+<g id="graph0">

+	<title>sorted_binary_tree</title>

+	<g id="node1">

+		<title>C</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="60.23" cy="185.804" rx="18.067" ry="18.067"/>

+		<text transform="matrix(1 0 0 1 55.5435 190.8223)" font-family="'Times-Roman'" font-size="14.0528">C</text>

+	</g>

+	<g id="node2">

+		<title>E</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="132.502" cy="185.804" rx="18.067" ry="18.067"/>

+		<text transform="matrix(1 0 0 1 128.21 190.8223)" font-family="'Times-Roman'" font-size="14.0528">E</text>

+	</g>

+	<g id="node3">

+		<title>H</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="204.773" cy="185.804" rx="17.064" ry="18.067"/>

+		<text transform="matrix(1 0 0 1 199.6992 190.8223)" font-family="'Times-Roman'" font-size="14.0528">H</text>

+	</g>

+	<g id="node4">

+		<title>A</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="24.094" cy="131.6" rx="17.064" ry="18.068"/>

+		<text transform="matrix(1 0 0 1 19.02 136.6191)" font-family="'Times-Roman'" font-size="14.0528">A</text>

+	</g>

+	<g id="node5">

+		<title>D</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="96.366" cy="131.6" rx="17.064" ry="18.068"/>

+		<text transform="matrix(1 0 0 1 91.292 136.6191)" font-family="'Times-Roman'" font-size="14.0528">D</text>

+	</g>

+	<g id="edge6">

+		<title>D-&gt;C</title>

+		<path fill="none" stroke="#000000" d="M86.328,147.66c-3.011,4.016-7.026,9.034-10.038,14.053"/>

+		<polygon stroke="#000000" points="78.298,164.725 70.268,170.747 73.279,160.709 		"/>

+	</g>

+	<g id="edge8">

+		<title>D-&gt;E</title>

+		<path fill="none" stroke="#000000" d="M106.404,147.66c3.011,4.016,7.026,9.034,10.038,14.053"/>

+		<polygon stroke="#000000" points="119.453,160.709 122.464,170.747 114.434,164.725 		"/>

+	</g>

+	<g id="node6">

+		<title>I</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="240.909" cy="131.6" rx="18.068" ry="18.068"/>

+		<text transform="matrix(1 0 0 1 238.5693 136.6191)" font-family="'Times-Roman'" font-size="14.0528">I</text>

+	</g>

+	<g id="edge12">

+		<title>I-&gt;H</title>

+		<path fill="none" stroke="#000000" d="M230.871,146.656c-3.011,5.02-6.021,10.038-10.037,15.057"/>

+		<polygon stroke="#000000" points="223.846,163.721 214.812,169.743 217.822,159.705 		"/>

+	</g>

+	<g id="node7">

+		<title>B</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="60.23" cy="77.396" rx="18.068" ry="18.068"/>

+		<text transform="matrix(1 0 0 1 55.5435 82.415)" font-family="'Times-Roman'" font-size="14.0528">B</text>

+	</g>

+	<g id="edge3">

+		<title>B-&gt;A</title>

+		<path fill="none" stroke="#000000" d="M50.192,92.453c-3.011,5.019-6.022,10.038-10.038,15.057"/>

+		<polygon stroke="#000000" points="43.166,109.518 34.132,115.539 37.144,105.502 		"/>

+	</g>

+	<g id="edge5">

+		<title>B-&gt;D</title>

+		<path fill="none" stroke="#000000" d="M70.268,92.453c3.011,5.019,6.022,10.038,10.038,15.057"/>

+		<polygon stroke="#000000" points="83.317,105.502 86.328,115.539 77.294,109.518 		"/>

+	</g>

+	<g id="node8">

+		<title>G</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="204.773" cy="77.396" rx="17.064" ry="18.068"/>

+		<text transform="matrix(1 0 0 1 199.6992 82.415)" font-family="'Times-Roman'" font-size="14.0528">G</text>

+	</g>

+	<g id="edge11">

+		<title>G-&gt;I</title>

+		<path fill="none" stroke="#000000" d="M214.812,93.457c3.011,4.015,7.026,9.034,10.038,14.053"/>

+		<polygon stroke="#000000" points="227.86,106.506 230.871,116.543 222.842,110.521 		"/>

+	</g>

+	<g id="node9">

+		<title>F</title>

+		<ellipse fill="#FFFFFF" stroke="#000000" cx="132.502" cy="23.192" rx="18.068" ry="18.068"/>

+		<text transform="matrix(1 0 0 1 128.5942 28.2109)" font-family="'Times-Roman'" font-size="14.0528">F</text>

+	</g>

+	<g id="edge2">

+		<title>F-&gt;B</title>

+		<path fill="none" stroke="#000000" d="M117.445,34.234c-11.042,8.03-23.087,17.064-34.128,26.098"/>

+		<polygon stroke="#000000" points="85.325,63.343 75.287,66.354 81.31,57.321 		"/>

+	</g>

+	<g id="edge10">

+		<title>F-&gt;G</title>

+		<path fill="none" stroke="#000000" d="M147.559,34.234c11.041,8.03,23.087,17.064,34.129,26.098"/>

+		<polygon stroke="#000000" points="183.694,57.321 189.717,66.354 179.68,63.343 		"/>

+	</g>

+</g>

+</svg>

diff --git a/docs/reference/glib/Sorted_binary_tree_inorder.svg b/docs/reference/glib/Sorted_binary_tree_inorder.svg
new file mode 100644
index 0000000..3927430
--- /dev/null
+++ b/docs/reference/glib/Sorted_binary_tree_inorder.svg
@@ -0,0 +1,753 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="266"
+   height="226.79848"
+   id="svg3953"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="Sorted_binary_tree_inorder.svg"
+   inkscape:export-filename="/home/mclasen/Sources/glib/docs/reference/glib/Sorted_binary_tree_inorder.png"
+   inkscape:export-xdpi="60.543114"
+   inkscape:export-ydpi="60.543114">
+  <defs
+     id="defs3955">
+    <marker
+       inkscape:stockid="SquareL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="SquareL"
+       style="overflow:visible">
+      <path
+         id="path4940"
+         d="M -5,-5 -5,5 5,5 5,-5 -5,-5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="scale(0.8,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       style="overflow:visible"
+       id="DistanceStart"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DistanceStart">
+      <g
+         id="g2300">
+        <path
+           style="fill:none;stroke:#ffffff;stroke-width:1.14999998;stroke-linecap:square"
+           d="M 0,0 2,0"
+           id="path2306"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#000000;fill-rule:evenodd;stroke:none"
+           d="M 0,0 13,4 9,0 13,-4 0,0 z"
+           id="path2302"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square"
+           d="M 0,-4 0,40"
+           id="path2304"
+           inkscape:connector-curvature="0" />
+      </g>
+    </marker>
+    <marker
+       inkscape:stockid="DotL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotL"
+       style="overflow:visible">
+      <path
+         id="path4931"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
+         transform="matrix(0.8,0,0,0.8,5.92,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible">
+      <path
+         id="path4890"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path4869"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3961" />
+    <inkscape:perspective
+       id="perspective3971"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect2940"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect2942"
+       is_visible="true"
+       pattern="m 187.18135,13.365063 1,0"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:perspective
+       id="perspective4212"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-5"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-76"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-2"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-22"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-8"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4852"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective5886"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-3"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-11"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-74"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-79"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-9"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-6"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="-5.5963911"
+     inkscape:cy="76.419161"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="1366"
+     inkscape:window-height="702"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata3958">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-275.57143,-78.931534)">
+    <g
+       transform="matrix(0.9925764,0,0,0.9925764,278.52645,98.594058)"
+       id="graph0"
+       class="graph"
+       style="font-size:14px;font-family:Times-Roman">
+      <title
+         id="title5">sorted_binary_tree</title>
+      <g
+         id="node1"
+         class="node">
+        <title
+           id="title8">C</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="185"
+           sodipodi:cx="60"
+           d="m 78,185 c 0,9.94113 -8.058875,18 -18,18 -9.941125,0 -18,-8.05887 -18,-18 0,-9.94113 8.058875,-18 18,-18 9.941125,0 18,8.05887 18,18 z"
+           cx="60"
+           cy="185"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse10" />
+        <text
+           style="text-anchor:middle"
+           x="60"
+           y="190"
+           id="text12">C</text>
+      </g>
+      <g
+         id="node2"
+         class="node">
+        <title
+           id="title15">E</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="185"
+           sodipodi:cx="132"
+           d="m 150,185 c 0,9.94113 -8.05887,18 -18,18 -9.94113,0 -18,-8.05887 -18,-18 0,-9.94113 8.05887,-18 18,-18 9.94113,0 18,8.05887 18,18 z"
+           cx="132"
+           cy="185"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse17" />
+        <text
+           style="text-anchor:middle"
+           x="132"
+           y="190"
+           id="text19">E</text>
+      </g>
+      <g
+         id="node3"
+         class="node">
+        <title
+           id="title22">H</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="185"
+           sodipodi:cx="204"
+           d="m 221,185 c 0,9.94113 -7.61116,18 -17,18 -9.38884,0 -17,-8.05887 -17,-18 0,-9.94113 7.61116,-18 17,-18 9.38884,0 17,8.05887 17,18 z"
+           cx="204"
+           cy="185"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse24" />
+        <text
+           style="text-anchor:middle"
+           x="204"
+           y="190"
+           id="text26">H</text>
+      </g>
+      <g
+         id="node4"
+         class="node">
+        <title
+           id="title29">A</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="131"
+           sodipodi:cx="24"
+           d="m 41,131 c 0,9.94113 -7.611159,18 -17,18 -9.388841,0 -17,-8.05887 -17,-18 0,-9.94113 7.611159,-18 17,-18 9.388841,0 17,8.05887 17,18 z"
+           cx="24"
+           cy="131"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse31" />
+        <text
+           style="text-anchor:middle"
+           x="24"
+           y="136"
+           id="text33">A</text>
+      </g>
+      <g
+         id="node5"
+         class="node">
+        <title
+           id="title36">D</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="131"
+           sodipodi:cx="96"
+           d="m 113,131 c 0,9.94113 -7.61116,18 -17,18 -9.388841,0 -17,-8.05887 -17,-18 0,-9.94113 7.611159,-18 17,-18 9.38884,0 17,8.05887 17,18 z"
+           cx="96"
+           cy="131"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse38" />
+        <text
+           style="text-anchor:middle"
+           x="96"
+           y="136"
+           id="text40">D</text>
+      </g>
+      <g
+         id="edge6"
+         class="edge">
+        <title
+           id="title43">D-&gt;C</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 86,147 c -3,4 -7,9 -10,14"
+           id="path45"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="78,164 70,170 73,160 78,164 "
+           id="polygon47" />
+      </g>
+      <g
+         id="edge8"
+         class="edge">
+        <title
+           id="title50">D-&gt;E</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 106,147 c 3,4 7,9 10,14"
+           id="path52"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="119,160 122,170 114,164 119,160 "
+           id="polygon54" />
+      </g>
+      <g
+         id="node6"
+         class="node">
+        <title
+           id="title57">I</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="131"
+           sodipodi:cx="240"
+           d="m 258,131 c 0,9.94113 -8.05887,18 -18,18 -9.94113,0 -18,-8.05887 -18,-18 0,-9.94113 8.05887,-18 18,-18 9.94113,0 18,8.05887 18,18 z"
+           cx="240"
+           cy="131"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse59" />
+        <text
+           style="text-anchor:middle"
+           x="240"
+           y="136"
+           id="text61">I</text>
+      </g>
+      <g
+         id="edge12"
+         class="edge">
+        <title
+           id="title64">I-&gt;H</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 230,146 c -3,5 -6,10 -10,15"
+           id="path66"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="223,163 214,169 217,159 223,163 "
+           id="polygon68" />
+      </g>
+      <g
+         id="node7"
+         class="node">
+        <title
+           id="title71">B</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="77"
+           sodipodi:cx="60"
+           d="m 78,77 c 0,9.941125 -8.058875,18 -18,18 -9.941125,0 -18,-8.058875 -18,-18 0,-9.941125 8.058875,-18 18,-18 9.941125,0 18,8.058875 18,18 z"
+           cx="60"
+           cy="77"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse73" />
+        <text
+           style="text-anchor:middle"
+           x="60"
+           y="82"
+           id="text75">B</text>
+      </g>
+      <g
+         id="edge3"
+         class="edge">
+        <title
+           id="title78">B-&gt;A</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 50,92 c -3,5 -6,10 -10,15"
+           id="path80"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="43,109 34,115 37,105 43,109 "
+           id="polygon82" />
+      </g>
+      <g
+         id="edge5"
+         class="edge">
+        <title
+           id="title85">B-&gt;D</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 70,92 c 3,5 6,10 10,15"
+           id="path87"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="83,105 86,115 77,109 83,105 "
+           id="polygon89" />
+      </g>
+      <g
+         id="node8"
+         class="node">
+        <title
+           id="title92">G</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="77"
+           sodipodi:cx="204"
+           d="m 221,77 c 0,9.941125 -7.61116,18 -17,18 -9.38884,0 -17,-8.058875 -17,-18 0,-9.941125 7.61116,-18 17,-18 9.38884,0 17,8.058875 17,18 z"
+           cx="204"
+           cy="77"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse94" />
+        <text
+           style="text-anchor:middle"
+           x="204"
+           y="82"
+           id="text96">G</text>
+      </g>
+      <g
+         id="edge11"
+         class="edge">
+        <title
+           id="title99">G-&gt;I</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214,93 c 3,4 7,9 10,14"
+           id="path101"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="227,106 230,116 222,110 227,106 "
+           id="polygon103" />
+      </g>
+      <g
+         id="node9"
+         class="node">
+        <title
+           id="title106">F</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="23"
+           sodipodi:cx="132"
+           d="m 150,23 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z"
+           cx="132"
+           cy="23"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse108" />
+        <text
+           style="text-anchor:middle"
+           x="132"
+           y="28"
+           id="text110">F</text>
+      </g>
+      <g
+         id="edge2"
+         class="edge">
+        <title
+           id="title113">F-&gt;B</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="M 117,34 C 106,42 94,51 83,60"
+           id="path115"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="85,63 75,66 81,57 85,63 "
+           id="polygon117" />
+      </g>
+      <g
+         id="edge10"
+         class="edge">
+        <title
+           id="title120">F-&gt;G</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 147,34 c 11,8 23,17 34,26"
+           id="path122"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="183,57 189,66 179,63 183,57 "
+           id="polygon124" />
+      </g>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.82904756;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:3.31619022, 3.31619022;stroke-dashoffset:0;marker-start:url(#SquareL);marker-end:url(#Arrow2Lend)"
+       d="m 407.86585,83.916245 c -8.09235,12.934463 -16.24193,25.833125 -24.4484,38.695485 -4.10893,6.44009 -8.28,12.93078 -13.72464,18.28932 -5.44312,5.35704 -12.35084,9.56414 -19.94187,10.40186 -3.3055,0.36478 -6.64352,0.0886 -9.9615,-0.13591 -1e-5,0 -3e-5,0 -4e-5,0 -3.30753,-0.22377 -6.65223,-0.39935 -9.91915,0.16371 -3.67892,0.63407 -7.19225,2.2113 -10.11083,4.53904 -10e-6,1e-5 -2e-5,2e-5 -3e-5,2e-5 -2.91857,2.32774 -5.23772,5.40225 -6.67417,8.84797 -1.43645,3.44574 -1.98788,7.25719 -1.58695,10.96875 0.40093,3.71157 1.75359,7.31733 3.89275,10.37682 -1.57329,7.77579 -6.47676,14.83297 -13.21535,19.01981 -4.08578,2.53859 -8.72148,4.0255 -13.0897,6.03963 -2e-5,0 -3e-5,1e-5 -4e-5,2e-5 -4.36719,2.01365 -8.65699,4.73894 -11.05709,8.90627 -10e-6,1e-5 -10e-6,2e-5 -2e-5,3e-5 -1.54971,2.69079 -2.21037,5.86275 -2.00701,8.96123 0.20338,3.09874 1.25331,6.121 2.89275,8.75838 3.2781,5.27351 8.79594,8.88365 14.67878,10.8706 10e-6,0 2e-5,1e-5 4e-5,1e-5 5.05172,1.70623 10.53116,2.32159 15.76564,1.30607 1e-5,-1e-5 2e-5,-1e-5 3e-5,-1e-5 5.23327,-1.0153 10.20383,-3.73183 13.53666,-7.89237 2.8325,-3.53596 4.39168,-7.94004 5.28933,-12.38079 0,-1e-5 10e-6,-3e-5 10e-6,-4e-5 0.89772,-4.44111 1.18109,-8.97997 1.75051,-13.47498 0.87253,-6.88777 2.42162,-13.6897 4.61772,-20.27603 2.52197,-0.49612 5.17081,-0.33611 7.61472,0.45997 2.44389,0.79608 4.67875,2.2269 6.42464,4.11322 2e-5,1e-5 3e-5,3e-5 5e-5,5e-5 3.21102,3.46934 4.63062,8.27318 5.04051,12.98264 0.41,4.71077 -0.0852,9.44723 -0.1789,14.17488 -0.10721,5.4079 0.30156,10.912 -1.06029,16.14671 -1.55704,5.98502 -5.48588,11.32637 -10.73556,14.59527 -3.77605,-0.86428 -7.77873,-0.72238 -11.48409,0.40712 -3.70537,1.1295 -7.10659,3.24452 -9.75844,6.0682 -4.15358,4.42272 -6.37982,10.5847 -6.11019,16.64605 0,2e-5 0,3e-5 0,4e-5 0.23758,5.34073 2.36859,10.56193 5.83809,14.62917 10e-6,10e-6 2e-5,2e-5 3e-5,3e-5 3.46975,4.06752 8.24802,6.97932 13.4221,8.32573 4.51162,1.17403 9.34056,1.17129 13.82052,-0.11828 4.47975,-1.2895 8.59635,-3.87695 11.61522,-7.42904 3.02242,-3.55627 4.91711,-8.06019 5.34575,-12.70759 10e-6,-3e-5 10e-6,-5e-5 10e-6,-8e-5 0.42864,-4.64742 -0.61029,-9.42195 -2.93128,-13.47106 -1.10365,-2.89524 -1.08961,-6.20429 0.0386,-9.09005 0,-10e-6 1e-5,-3e-5 1e-5,-4e-5 1.1282,-2.88577 3.36222,-5.32694 6.1369,-6.70594 3.47162,-1.72538 7.76143,-1.72538 11.23305,0 3.47935,0.88812 6.65089,2.94914 8.87568,5.76782 2.22478,2.81869 3.49269,6.38223 3.5483,9.97271 0.0448,2.88989 -0.66677,5.7303 -1.2997,8.55039 -0.63291,2.82001 -1.19432,5.71596 -0.84587,8.58504 0,2e-5 0,3e-5 0,4e-5 0.43816,3.60767 2.33339,6.96423 4.97344,9.46172 2.64067,2.49807 5.99201,4.1741 9.49814,5.13355 10e-6,0 2e-5,1e-5 4e-5,1e-5 8.13425,2.22592 17.27288,0.51296 24.04882,-4.50774 2.95407,-2.80833 5.12951,-6.42944 6.22172,-10.35631 1.09222,-3.92687 1.09889,-8.15119 0.0191,-12.0815 -1.22234,-4.44914 -3.84239,-8.50594 -7.39496,-11.45011 -3.55256,-2.94417 -8.02526,-4.76546 -12.62397,-5.1405 -2e-5,0 -3e-5,0 -4e-5,0 -2.56836,0.72381 -5.27682,0.94784 -7.9292,0.65587 -10e-6,0 -2e-5,0 -4e-5,0 -3.77599,-0.41566 -7.46992,-1.91446 -10.28756,-4.46235 -10e-6,-1e-5 -2e-5,-1e-5 -2e-5,-2e-5 -2.8168,-2.54715 -4.70691,-6.17422 -4.91006,-9.96645 -0.14723,-2.74836 0.56276,-5.4692 1.41517,-8.08617 0.85243,-2.61706 1.85748,-5.20104 2.33283,-7.91207 0.92354,-5.26723 -0.28222,-10.88387 -3.28625,-15.30794 -3.00404,-4.42407 -7.77987,-7.61656 -13.01633,-8.70101 -3.38923,0.38773 -6.89239,-0.26847 -9.91151,-1.8566 -2e-5,-1e-5 -4e-5,-2e-5 -7e-5,-3e-5 -3.23617,-1.70233 -5.90142,-4.47336 -7.47657,-7.7733 -1.57515,-3.29994 -2.05353,-7.11482 -1.34194,-10.70152 0,-2e-5 1e-5,-5e-5 1e-5,-7e-5 0.98555,-6.30654 2.75458,-12.49035 5.25348,-18.36396 1e-5,-2e-5 2e-5,-5e-5 3e-5,-7e-5 2.90825,-6.83578 6.89834,-13.35821 12.56261,-18.16464 5.66117,-4.8038 13.16594,-7.75245 20.54108,-6.89651 4.32392,0.50183 8.42733,2.25397 12.75051,2.76214 4.7583,0.55932 9.69143,-0.45462 13.8434,-2.84533 2e-5,-2e-5 4e-5,-3e-5 6e-5,-4e-5 9.24006,1.13358 17.98407,5.97778 23.8453,13.21033 5.15234,6.35781 7.99577,14.2147 11.30601,21.69872 1.92466,4.3514 4.05797,8.66096 7.03333,12.37393 10e-6,2e-5 3e-5,4e-5 5e-5,6e-5 2.97478,3.71223 6.87266,6.82357 11.43539,8.16948 2e-5,1e-5 5e-5,1e-5 7e-5,2e-5 4.08278,1.20432 8.59203,0.91743 12.48927,-0.79459 2.77058,2.06261 4.93246,4.93513 6.1476,8.16838 10e-6,2e-5 2e-5,4e-5 2e-5,6e-5 1.21514,3.23328 1.48028,6.81866 0.75396,10.19551 -0.64549,3.00105 -2.03848,5.78453 -2.94997,8.71576 -0.45574,1.4656 -0.79214,2.97858 -0.84237,4.51258 -0.0502,1.5339 0.19468,3.09454 0.85538,4.47976 1.12213,2.35266 3.31808,4.00019 4.78859,6.15235 10e-6,2e-5 3e-5,4e-5 4e-5,6e-5 1.28491,1.88055 1.99273,4.15109 2.00406,6.42866 0,2e-5 0,5e-5 0,7e-5 0.0113,2.27755 -0.67387,4.55499 -1.94,6.44821 -1.26613,1.89323 -3.10926,3.39632 -5.21849,4.25572 -2.10924,0.8594 -4.47799,1.07243 -6.70672,0.60317 -6.72013,2.08 -13.07673,5.33027 -18.69744,9.56041 -3.43389,2.58434 -6.63757,5.58482 -8.83155,9.28034 -2.19309,3.69404 -3.30672,8.16333 -2.4015,12.36288 0.73825,3.42496 2.77646,6.49085 5.39143,8.82264 2.61545,2.33222 5.78751,3.97275 9.08008,5.17224 2e-5,1e-5 5e-5,2e-5 7e-5,3e-5 7.59964,2.76856 16.01971,3.25052 23.88562,1.3672 2e-5,-10e-6 4e-5,-3e-5 6e-5,-4e-5 5.55583,-4.2436 9.26683,-10.83973 10.0094,-17.79128 0.48273,-4.51901 -0.25456,-9.16391 -2.11291,-13.31132 -1.12772,-3.87126 -0.64207,-8.19191 1.31693,-11.71621 1.95901,-3.5243 5.37216,-6.21769 9.25535,-7.3036 3.03411,-0.84847 6.23896,-0.7413 9.38918,-0.78414 3.15001,-0.0428 6.40369,-0.26967 9.21028,-1.70056 1.87052,-0.95365 3.46254,-2.41445 4.68173,-4.12379 1.21923,-1.70942 2.07411,-3.66326 2.63108,-5.68772 0,-2e-5 10e-6,-4e-5 2e-5,-7e-5 1.11392,-4.04896 1.04531,-8.32057 0.84497,-12.51519 0,-2e-5 0,-5e-5 0,-7e-5 -0.20277,-4.24553 -0.53208,-8.48502 -0.98732,-12.71094 -1.04658,-3.18409 -3.10978,-6.02749 -5.8122,-8.01008 -2.70242,-1.9826 -6.03405,-3.09704 -9.38546,-3.13947 -1.77072,-0.0224 -3.53043,0.24491 -5.29437,0.40133 -1.76389,0.15642 -3.56824,0.19871 -5.27791,-0.26261 -1.52465,-0.4114 -2.93141,-1.21815 -4.11285,-2.26602 -2e-5,-2e-5 -3e-5,-3e-5 -5e-5,-5e-5 -1.1815,-1.04794 -2.14182,-2.33315 -2.88667,-3.72574 -1.48968,-2.78513 -2.11051,-5.95234 -2.4471,-9.09286 0,-2e-5 -10e-6,-5e-5 -10e-6,-7e-5 -0.7501,-6.99887 -0.1865,-14.13231 -1.52514,-21.0428 -0.72945,-3.76565 -2.0464,-7.46897 -4.28746,-10.58183 -2.2404,-3.11195 -5.46685,-5.60479 -9.18911,-6.5259 -3.02141,-0.74768 -6.20154,-0.44617 -9.27072,0.0716 -3.06933,0.51775 -6.11978,1.24879 -9.23079,1.35113 -2e-5,0 -5e-5,0 -7e-5,0 -3.90344,0.1284 -7.81108,-0.74979 -11.38322,-2.32877 -3.5723,-1.57904 -6.81761,-3.84706 -9.69109,-6.49241 -5.74696,-5.29072 -9.96674,-12.00296 -13.94631,-18.72474 -2.39922,-4.05246 -4.71299,-8.17874 -6.40846,-12.57238 -1.69522,-4.39298 -2.67881,-9.02583 -3.50306,-13.661852 l -1.9823,-11.149545"
+       id="path2938"
+       inkscape:path-effect="#path-effect2940;#path-effect2942"
+       inkscape:original-d="m 407.86585,83.916245 c 0,0 -14.11559,27.469705 -24.4484,38.695485 -9.34236,10.14972 -20.62893,24.18364 -33.66651,28.69118 -10.61846,3.67116 -11.93657,-7.91708 -19.88069,0.0278 -8.03966,8.04037 -7.9913,25.39502 -14.47923,34.7326 0,0 -7.13271,14.26573 -13.21535,19.01981 -8.72576,6.81989 -26.98503,4.24108 -24.14685,14.94595 2.83816,10.70488 4.57641,21.84782 15.56452,28.59021 9.79125,6.00799 28.36077,4.86263 29.30237,-6.5863 0.94161,-11.44892 3.2096,-17.00295 7.03985,-25.85581 3.83025,-8.85286 -1.10893,-26.61597 4.61772,-20.27603 0,0 11.6923,-3.64141 14.03941,4.57324 1.70869,5.98028 2.66345,21.33932 4.86161,27.15752 2.19816,5.81821 -0.52766,12.44562 -1.06029,16.14671 -1.09286,7.59409 -3.21008,13.10136 -10.73556,14.59527 0,0 -15.16484,1.49219 -21.24253,6.47532 -6.22299,5.10225 -7.51576,8.72253 -6.11019,16.64609 1.81705,10.24319 9.04679,20.97753 19.26022,22.95493 11.49367,2.22528 19.58074,2.59049 25.43574,-7.54732 4.1679,-7.21663 -1.97686,-19.09584 2.41448,-26.17873 0,0 0.33183,-12.5434 6.17549,-15.79603 3.2717,-1.82105 9.2379,-3.16852 11.23305,0 0,0 11.52539,9.6056 12.42398,15.74053 0.95363,6.51078 -5.98915,11.79446 -2.14557,17.13547 3.84359,5.34102 7.61186,11.46161 14.47158,14.59527 8.85083,4.04326 19.94604,4.31564 24.04886,-4.50773 0,0 8.1669,-13.23439 6.24082,-22.43781 -2.16604,-10.34997 -9.48077,-17.46228 -20.01897,-16.59061 0,0 -5.42758,1.53646 -7.9292,0.65587 -6.58909,-2.31941 -16.02955,-7.49314 -15.19768,-14.42882 0.83187,-6.93568 9.55833,8.44447 3.748,-15.99824 -1.55478,-6.54061 -9.59437,-24.45283 -16.30258,-24.00895 0,0 -6.96155,-0.35298 -9.91151,-1.8566 -7.36557,-3.75427 -10.83778,-10.45812 -8.81857,-18.47492 0,0 1.87298,-13.03292 5.25348,-18.36396 7.93496,-12.51342 19.58924,-22.07695 33.10372,-25.06122 4.24644,-0.93771 6.93062,3.3283 12.75051,2.76214 5.10303,-0.49642 9.84185,-6.05074 13.84346,-2.84537 0,0 16.88165,-1.28992 23.8453,13.21033 3.31247,6.89749 4.71066,17.81941 11.30601,21.69872 6.59535,3.87931 11.60217,19.87279 18.46884,20.54349 3.94867,0.38568 10.25015,-4.06981 12.48927,-0.79459 0,0 6.35327,10.96916 6.90158,18.36395 0.48511,6.54257 -6.59488,12.262 -2.93696,17.7081 3.65793,5.44611 4.68796,1.4131 4.78863,6.15241 0.15241,7.17408 -4.7607,16.6994 -11.86115,17.73583 0,0 -12.53135,5.17234 -18.69744,9.56041 -6.62245,4.71284 -15.87104,14.96813 -11.23305,21.64322 0,0 7.82042,10.07549 14.47158,13.99491 7.43886,4.38361 19.41887,8.75645 23.88562,1.3672 0,0 8.90884,-10.20704 10.00946,-17.79132 0.87615,-6.0375 -5.07693,-7.979 -2.11291,-13.31132 0,0 4.26218,-15.44258 10.57228,-19.01981 5.94288,-3.36906 15.32144,3.50888 18.59946,-2.4847 0,0 7.61918,-13.6222 8.1578,-22.32684 0.40659,-6.57079 4.32078,-8.81675 -0.98732,-12.71094 0,0 -9.00115,-10.11082 -15.19766,-11.14955 -3.63896,-0.61001 -8.14088,2.91403 -10.57228,0.13872 0,0 -8.10433,-8.53592 -9.44667,-15.08467 -1.56983,-7.65869 4.02354,-15.53542 -1.52515,-21.04287 -5.54869,-5.50744 -5.14034,-14.65591 -13.47657,-17.10773 -6.04893,-1.77908 -13.54572,5.32072 -18.50151,1.42268 -4.95579,-3.89803 -26.23756,-15.56939 -35.02069,-27.54592 -5.52823,-7.53822 -8.27517,-17.03053 -9.91152,-26.234232 l -1.9823,-11.149545"
+       sodipodi:nodetypes="cssssszszzsszsssssssssszssssszsssssassszssszssssssssssssssszszssc"
+       inkscape:connector-curvature="0" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,454.12853,95.367832)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-9"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,525.04284,40.275046)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-2"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,418.24759,148.76546)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-95"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,454.97612,201.88055)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-3"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,490.00948,149.33052)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-27"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,526.17295,202.4456)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-31"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,596.80473,93.955197)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-8"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,634.0983,148.2004)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-5"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,597.36978,202.44561)" />
+  </g>
+</svg>
diff --git a/docs/reference/glib/Sorted_binary_tree_postorder.svg b/docs/reference/glib/Sorted_binary_tree_postorder.svg
new file mode 100644
index 0000000..1160e42
--- /dev/null
+++ b/docs/reference/glib/Sorted_binary_tree_postorder.svg
@@ -0,0 +1,750 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="265.90625"
+   height="226.94397"
+   id="svg3953"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="Sorted_binary_tree_postorder.svg">
+  <defs
+     id="defs3955">
+    <marker
+       inkscape:stockid="SquareL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="SquareL"
+       style="overflow:visible">
+      <path
+         id="path4940"
+         d="M -5,-5 -5,5 5,5 5,-5 -5,-5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="scale(0.8,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       style="overflow:visible"
+       id="DistanceStart"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DistanceStart">
+      <g
+         id="g2300">
+        <path
+           style="fill:none;stroke:#ffffff;stroke-width:1.14999998;stroke-linecap:square"
+           d="M 0,0 2,0"
+           id="path2306"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#000000;fill-rule:evenodd;stroke:none"
+           d="M 0,0 13,4 9,0 13,-4 0,0 z"
+           id="path2302"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square"
+           d="M 0,-4 0,40"
+           id="path2304"
+           inkscape:connector-curvature="0" />
+      </g>
+    </marker>
+    <marker
+       inkscape:stockid="DotL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotL"
+       style="overflow:visible">
+      <path
+         id="path4931"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
+         transform="matrix(0.8,0,0,0.8,5.92,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible">
+      <path
+         id="path4890"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path4869"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3961" />
+    <inkscape:perspective
+       id="perspective3971"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect2940"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect2942"
+       is_visible="true"
+       pattern="m 187.18135,13.365063 1,0"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:perspective
+       id="perspective4212"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-5"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-76"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-2"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-22"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-8"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4852"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective5886"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-3"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-11"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-74"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-79"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-9"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-6"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="-131.03835"
+     inkscape:cy="76.407899"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="1366"
+     inkscape:window-height="702"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata3958">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-275.65625,-78.774784)">
+    <g
+       transform="matrix(0.9925764,0,0,0.9925764,278.52645,98.594058)"
+       id="graph0"
+       class="graph"
+       style="font-size:14px;font-family:Times-Roman">
+      <title
+         id="title5">sorted_binary_tree</title>
+      <g
+         id="node1"
+         class="node">
+        <title
+           id="title8">C</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="185"
+           sodipodi:cx="60"
+           d="m 78,185 c 0,9.94113 -8.058875,18 -18,18 -9.941125,0 -18,-8.05887 -18,-18 0,-9.94113 8.058875,-18 18,-18 9.941125,0 18,8.05887 18,18 z"
+           cx="60"
+           cy="185"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse10" />
+        <text
+           style="text-anchor:middle"
+           x="60"
+           y="190"
+           id="text12">C</text>
+      </g>
+      <g
+         id="node2"
+         class="node">
+        <title
+           id="title15">E</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="185"
+           sodipodi:cx="132"
+           d="m 150,185 c 0,9.94113 -8.05887,18 -18,18 -9.94113,0 -18,-8.05887 -18,-18 0,-9.94113 8.05887,-18 18,-18 9.94113,0 18,8.05887 18,18 z"
+           cx="132"
+           cy="185"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse17" />
+        <text
+           style="text-anchor:middle"
+           x="132"
+           y="190"
+           id="text19">E</text>
+      </g>
+      <g
+         id="node3"
+         class="node">
+        <title
+           id="title22">H</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="185"
+           sodipodi:cx="204"
+           d="m 221,185 c 0,9.94113 -7.61116,18 -17,18 -9.38884,0 -17,-8.05887 -17,-18 0,-9.94113 7.61116,-18 17,-18 9.38884,0 17,8.05887 17,18 z"
+           cx="204"
+           cy="185"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse24" />
+        <text
+           style="text-anchor:middle"
+           x="204"
+           y="190"
+           id="text26">H</text>
+      </g>
+      <g
+         id="node4"
+         class="node">
+        <title
+           id="title29">A</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="131"
+           sodipodi:cx="24"
+           d="m 41,131 c 0,9.94113 -7.611159,18 -17,18 -9.388841,0 -17,-8.05887 -17,-18 0,-9.94113 7.611159,-18 17,-18 9.388841,0 17,8.05887 17,18 z"
+           cx="24"
+           cy="131"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse31" />
+        <text
+           style="text-anchor:middle"
+           x="24"
+           y="136"
+           id="text33">A</text>
+      </g>
+      <g
+         id="node5"
+         class="node">
+        <title
+           id="title36">D</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="131"
+           sodipodi:cx="96"
+           d="m 113,131 c 0,9.94113 -7.61116,18 -17,18 -9.388841,0 -17,-8.05887 -17,-18 0,-9.94113 7.611159,-18 17,-18 9.38884,0 17,8.05887 17,18 z"
+           cx="96"
+           cy="131"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse38" />
+        <text
+           style="text-anchor:middle"
+           x="96"
+           y="136"
+           id="text40">D</text>
+      </g>
+      <g
+         id="edge6"
+         class="edge">
+        <title
+           id="title43">D-&gt;C</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 86,147 c -3,4 -7,9 -10,14"
+           id="path45"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="78,164 70,170 73,160 78,164 "
+           id="polygon47" />
+      </g>
+      <g
+         id="edge8"
+         class="edge">
+        <title
+           id="title50">D-&gt;E</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 106,147 c 3,4 7,9 10,14"
+           id="path52"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="119,160 122,170 114,164 119,160 "
+           id="polygon54" />
+      </g>
+      <g
+         id="node6"
+         class="node">
+        <title
+           id="title57">I</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="131"
+           sodipodi:cx="240"
+           d="m 258,131 c 0,9.94113 -8.05887,18 -18,18 -9.94113,0 -18,-8.05887 -18,-18 0,-9.94113 8.05887,-18 18,-18 9.94113,0 18,8.05887 18,18 z"
+           cx="240"
+           cy="131"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse59" />
+        <text
+           style="text-anchor:middle"
+           x="240"
+           y="136"
+           id="text61">I</text>
+      </g>
+      <g
+         id="edge12"
+         class="edge">
+        <title
+           id="title64">I-&gt;H</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 230,146 c -3,5 -6,10 -10,15"
+           id="path66"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="223,163 214,169 217,159 223,163 "
+           id="polygon68" />
+      </g>
+      <g
+         id="node7"
+         class="node">
+        <title
+           id="title71">B</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="77"
+           sodipodi:cx="60"
+           d="m 78,77 c 0,9.941125 -8.058875,18 -18,18 -9.941125,0 -18,-8.058875 -18,-18 0,-9.941125 8.058875,-18 18,-18 9.941125,0 18,8.058875 18,18 z"
+           cx="60"
+           cy="77"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse73" />
+        <text
+           style="text-anchor:middle"
+           x="60"
+           y="82"
+           id="text75">B</text>
+      </g>
+      <g
+         id="edge3"
+         class="edge">
+        <title
+           id="title78">B-&gt;A</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 50,92 c -3,5 -6,10 -10,15"
+           id="path80"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="43,109 34,115 37,105 43,109 "
+           id="polygon82" />
+      </g>
+      <g
+         id="edge5"
+         class="edge">
+        <title
+           id="title85">B-&gt;D</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 70,92 c 3,5 6,10 10,15"
+           id="path87"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="83,105 86,115 77,109 83,105 "
+           id="polygon89" />
+      </g>
+      <g
+         id="node8"
+         class="node">
+        <title
+           id="title92">G</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="77"
+           sodipodi:cx="204"
+           d="m 221,77 c 0,9.941125 -7.61116,18 -17,18 -9.38884,0 -17,-8.058875 -17,-18 0,-9.941125 7.61116,-18 17,-18 9.38884,0 17,8.058875 17,18 z"
+           cx="204"
+           cy="77"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse94" />
+        <text
+           style="text-anchor:middle"
+           x="204"
+           y="82"
+           id="text96">G</text>
+      </g>
+      <g
+         id="edge11"
+         class="edge">
+        <title
+           id="title99">G-&gt;I</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214,93 c 3,4 7,9 10,14"
+           id="path101"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="227,106 230,116 222,110 227,106 "
+           id="polygon103" />
+      </g>
+      <g
+         id="node9"
+         class="node">
+        <title
+           id="title106">F</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="23"
+           sodipodi:cx="132"
+           d="m 150,23 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z"
+           cx="132"
+           cy="23"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse108" />
+        <text
+           style="text-anchor:middle"
+           x="132"
+           y="28"
+           id="text110">F</text>
+      </g>
+      <g
+         id="edge2"
+         class="edge">
+        <title
+           id="title113">F-&gt;B</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="M 117,34 C 106,42 94,51 83,60"
+           id="path115"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="85,63 75,66 81,57 85,63 "
+           id="polygon117" />
+      </g>
+      <g
+         id="edge10"
+         class="edge">
+        <title
+           id="title120">F-&gt;G</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 147,34 c 11,8 23,17 34,26"
+           id="path122"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="183,57 189,66 179,63 183,57 "
+           id="polygon124" />
+      </g>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.82904756;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:3.31619022, 3.31619022;stroke-dashoffset:0;marker-start:url(#SquareL);marker-end:url(#Arrow2Lend)"
+       d="m 407.86585,83.916245 c -8.09235,12.934463 -16.24193,25.833125 -24.4484,38.695485 -4.10893,6.44009 -8.28,12.93078 -13.72464,18.28932 -5.44312,5.35704 -12.35084,9.56414 -19.94187,10.40186 -3.3055,0.36478 -6.64352,0.0886 -9.9615,-0.13591 -1e-5,0 -3e-5,0 -4e-5,0 -3.30753,-0.22377 -6.65223,-0.39935 -9.91915,0.16371 -3.67892,0.63407 -7.19225,2.2113 -10.11083,4.53904 -10e-6,1e-5 -2e-5,2e-5 -3e-5,2e-5 -2.91857,2.32774 -5.23772,5.40225 -6.67417,8.84797 -1.43645,3.44574 -1.98788,7.25719 -1.58695,10.96875 0.40093,3.71157 1.75359,7.31733 3.89275,10.37682 -1.57329,7.77579 -6.47676,14.83297 -13.21535,19.01981 -4.08578,2.53859 -8.72148,4.0255 -13.0897,6.03963 -2e-5,0 -3e-5,1e-5 -4e-5,2e-5 -4.36719,2.01365 -8.65699,4.73894 -11.05709,8.90627 -10e-6,1e-5 -10e-6,2e-5 -2e-5,3e-5 -1.54971,2.69079 -2.21037,5.86275 -2.00701,8.96123 0.20338,3.09874 1.25331,6.121 2.89275,8.75838 3.2781,5.27351 8.79594,8.88365 14.67878,10.8706 10e-6,0 2e-5,1e-5 4e-5,1e-5 5.05172,1.70623 10.53116,2.32159 15.76564,1.30607 1e-5,-1e-5 2e-5,-1e-5 3e-5,-1e-5 5.23327,-1.0153 10.20383,-3.73183 13.53666,-7.89237 2.8325,-3.53596 4.39168,-7.94004 5.28933,-12.38079 0,-1e-5 10e-6,-3e-5 10e-6,-4e-5 0.89772,-4.44111 1.18109,-8.97997 1.75051,-13.47498 0.87253,-6.88777 2.42162,-13.6897 4.61772,-20.27603 2.52197,-0.49612 5.17081,-0.33611 7.61472,0.45997 2.44389,0.79608 4.67875,2.2269 6.42464,4.11322 2e-5,1e-5 3e-5,3e-5 5e-5,5e-5 3.21102,3.46934 4.63062,8.27318 5.04051,12.98264 0.41,4.71077 -0.0852,9.44723 -0.1789,14.17488 -0.10721,5.4079 0.30156,10.912 -1.06029,16.14671 -1.55704,5.98502 -5.48588,11.32637 -10.73556,14.59527 -3.77605,-0.86428 -7.77873,-0.72238 -11.48409,0.40712 -3.70537,1.1295 -7.10659,3.24452 -9.75844,6.0682 -4.15358,4.42272 -6.37982,10.5847 -6.11019,16.64605 0,2e-5 0,3e-5 0,4e-5 0.23758,5.34073 2.36859,10.56193 5.83809,14.62917 10e-6,10e-6 2e-5,2e-5 3e-5,3e-5 3.46975,4.06752 8.24802,6.97932 13.4221,8.32573 4.51162,1.17403 9.34056,1.17129 13.82052,-0.11828 4.47975,-1.2895 8.59635,-3.87695 11.61522,-7.42904 3.02242,-3.55627 4.91711,-8.06019 5.34575,-12.70759 10e-6,-3e-5 10e-6,-5e-5 10e-6,-8e-5 0.42864,-4.64742 -0.61029,-9.42195 -2.93128,-13.47106 -1.10365,-2.89524 -1.08961,-6.20429 0.0386,-9.09005 0,-10e-6 1e-5,-3e-5 1e-5,-4e-5 1.1282,-2.88577 3.36222,-5.32694 6.1369,-6.70594 3.47162,-1.72538 7.76143,-1.72538 11.23305,0 3.47935,0.88812 6.65089,2.94914 8.87568,5.76782 2.22478,2.81869 3.49269,6.38223 3.5483,9.97271 0.0448,2.88989 -0.66677,5.7303 -1.2997,8.55039 -0.63291,2.82001 -1.19432,5.71596 -0.84587,8.58504 0,2e-5 0,3e-5 0,4e-5 0.43816,3.60767 2.33339,6.96423 4.97344,9.46172 2.64067,2.49807 5.99201,4.1741 9.49814,5.13355 10e-6,0 2e-5,1e-5 4e-5,1e-5 8.13425,2.22592 17.27288,0.51296 24.04882,-4.50774 2.95407,-2.80833 5.12951,-6.42944 6.22172,-10.35631 1.09222,-3.92687 1.09889,-8.15119 0.0191,-12.0815 -1.22234,-4.44914 -3.84239,-8.50594 -7.39496,-11.45011 -3.55256,-2.94417 -8.02526,-4.76546 -12.62397,-5.1405 -2e-5,0 -3e-5,0 -4e-5,0 -2.56836,0.72381 -5.27682,0.94784 -7.9292,0.65587 -10e-6,0 -2e-5,0 -4e-5,0 -3.77599,-0.41566 -7.46992,-1.91446 -10.28756,-4.46235 -10e-6,-1e-5 -2e-5,-1e-5 -2e-5,-2e-5 -2.8168,-2.54715 -4.70691,-6.17422 -4.91006,-9.96645 -0.14723,-2.74836 0.56276,-5.4692 1.41517,-8.08617 0.85243,-2.61706 1.85748,-5.20104 2.33283,-7.91207 0.92354,-5.26723 -0.28222,-10.88387 -3.28625,-15.30794 -3.00404,-4.42407 -7.77987,-7.61656 -13.01633,-8.70101 -3.38923,0.38773 -6.89239,-0.26847 -9.91151,-1.8566 -2e-5,-1e-5 -4e-5,-2e-5 -7e-5,-3e-5 -3.23617,-1.70233 -5.90142,-4.47336 -7.47657,-7.7733 -1.57515,-3.29994 -2.05353,-7.11482 -1.34194,-10.70152 0,-2e-5 1e-5,-5e-5 1e-5,-7e-5 0.98555,-6.30654 2.75458,-12.49035 5.25348,-18.36396 1e-5,-2e-5 2e-5,-5e-5 3e-5,-7e-5 2.90825,-6.83578 6.89834,-13.35821 12.56261,-18.16464 5.66117,-4.8038 13.16594,-7.75245 20.54108,-6.89651 4.32392,0.50183 8.42733,2.25397 12.75051,2.76214 4.7583,0.55932 9.69143,-0.45462 13.8434,-2.84533 2e-5,-2e-5 4e-5,-3e-5 6e-5,-4e-5 9.24006,1.13358 17.98407,5.97778 23.8453,13.21033 5.15234,6.35781 7.99577,14.2147 11.30601,21.69872 1.92466,4.3514 4.05797,8.66096 7.03333,12.37393 10e-6,2e-5 3e-5,4e-5 5e-5,6e-5 2.97478,3.71223 6.87266,6.82357 11.43539,8.16948 2e-5,1e-5 5e-5,1e-5 7e-5,2e-5 4.08278,1.20432 8.59203,0.91743 12.48927,-0.79459 2.77058,2.06261 4.93246,4.93513 6.1476,8.16838 10e-6,2e-5 2e-5,4e-5 2e-5,6e-5 1.21514,3.23328 1.48028,6.81866 0.75396,10.19551 -0.64549,3.00105 -2.03848,5.78453 -2.94997,8.71576 -0.45574,1.4656 -0.79214,2.97858 -0.84237,4.51258 -0.0502,1.5339 0.19468,3.09454 0.85538,4.47976 1.12213,2.35266 3.31808,4.00019 4.78859,6.15235 10e-6,2e-5 3e-5,4e-5 4e-5,6e-5 1.28491,1.88055 1.99273,4.15109 2.00406,6.42866 0,2e-5 0,5e-5 0,7e-5 0.0113,2.27755 -0.67387,4.55499 -1.94,6.44821 -1.26613,1.89323 -3.10926,3.39632 -5.21849,4.25572 -2.10924,0.8594 -4.47799,1.07243 -6.70672,0.60317 -6.72013,2.08 -13.07673,5.33027 -18.69744,9.56041 -3.43389,2.58434 -6.63757,5.58482 -8.83155,9.28034 -2.19309,3.69404 -3.30672,8.16333 -2.4015,12.36288 0.73825,3.42496 2.77646,6.49085 5.39143,8.82264 2.61545,2.33222 5.78751,3.97275 9.08008,5.17224 2e-5,1e-5 5e-5,2e-5 7e-5,3e-5 7.59964,2.76856 16.01971,3.25052 23.88562,1.3672 2e-5,-10e-6 4e-5,-3e-5 6e-5,-4e-5 5.55583,-4.2436 9.26683,-10.83973 10.0094,-17.79128 0.48273,-4.51901 -0.25456,-9.16391 -2.11291,-13.31132 -1.12772,-3.87126 -0.64207,-8.19191 1.31693,-11.71621 1.95901,-3.5243 5.37216,-6.21769 9.25535,-7.3036 3.03411,-0.84847 6.23896,-0.7413 9.38918,-0.78414 3.15001,-0.0428 6.40369,-0.26967 9.21028,-1.70056 1.87052,-0.95365 3.46254,-2.41445 4.68173,-4.12379 1.21923,-1.70942 2.07411,-3.66326 2.63108,-5.68772 0,-2e-5 10e-6,-4e-5 2e-5,-7e-5 1.11392,-4.04896 1.04531,-8.32057 0.84497,-12.51519 0,-2e-5 0,-5e-5 0,-7e-5 -0.20277,-4.24553 -0.53208,-8.48502 -0.98732,-12.71094 -1.04658,-3.18409 -3.10978,-6.02749 -5.8122,-8.01008 -2.70242,-1.9826 -6.03405,-3.09704 -9.38546,-3.13947 -1.77072,-0.0224 -3.53043,0.24491 -5.29437,0.40133 -1.76389,0.15642 -3.56824,0.19871 -5.27791,-0.26261 -1.52465,-0.4114 -2.93141,-1.21815 -4.11285,-2.26602 -2e-5,-2e-5 -3e-5,-3e-5 -5e-5,-5e-5 -1.1815,-1.04794 -2.14182,-2.33315 -2.88667,-3.72574 -1.48968,-2.78513 -2.11051,-5.95234 -2.4471,-9.09286 0,-2e-5 -10e-6,-5e-5 -10e-6,-7e-5 -0.7501,-6.99887 -0.1865,-14.13231 -1.52514,-21.0428 -0.72945,-3.76565 -2.0464,-7.46897 -4.28746,-10.58183 -2.2404,-3.11195 -5.46685,-5.60479 -9.18911,-6.5259 -3.02141,-0.74768 -6.20154,-0.44617 -9.27072,0.0716 -3.06933,0.51775 -6.11978,1.24879 -9.23079,1.35113 -2e-5,0 -5e-5,0 -7e-5,0 -3.90344,0.1284 -7.81108,-0.74979 -11.38322,-2.32877 -3.5723,-1.57904 -6.81761,-3.84706 -9.69109,-6.49241 -5.74696,-5.29072 -9.96674,-12.00296 -13.94631,-18.72474 -2.39922,-4.05246 -4.71299,-8.17874 -6.40846,-12.57238 -1.69522,-4.39298 -2.67881,-9.02583 -3.50306,-13.661852 l -1.9823,-11.149545"
+       id="path2938"
+       inkscape:path-effect="#path-effect2940;#path-effect2942"
+       inkscape:original-d="m 407.86585,83.916245 c 0,0 -14.11559,27.469705 -24.4484,38.695485 -9.34236,10.14972 -20.62893,24.18364 -33.66651,28.69118 -10.61846,3.67116 -11.93657,-7.91708 -19.88069,0.0278 -8.03966,8.04037 -7.9913,25.39502 -14.47923,34.7326 0,0 -7.13271,14.26573 -13.21535,19.01981 -8.72576,6.81989 -26.98503,4.24108 -24.14685,14.94595 2.83816,10.70488 4.57641,21.84782 15.56452,28.59021 9.79125,6.00799 28.36077,4.86263 29.30237,-6.5863 0.94161,-11.44892 3.2096,-17.00295 7.03985,-25.85581 3.83025,-8.85286 -1.10893,-26.61597 4.61772,-20.27603 0,0 11.6923,-3.64141 14.03941,4.57324 1.70869,5.98028 2.66345,21.33932 4.86161,27.15752 2.19816,5.81821 -0.52766,12.44562 -1.06029,16.14671 -1.09286,7.59409 -3.21008,13.10136 -10.73556,14.59527 0,0 -15.16484,1.49219 -21.24253,6.47532 -6.22299,5.10225 -7.51576,8.72253 -6.11019,16.64609 1.81705,10.24319 9.04679,20.97753 19.26022,22.95493 11.49367,2.22528 19.58074,2.59049 25.43574,-7.54732 4.1679,-7.21663 -1.97686,-19.09584 2.41448,-26.17873 0,0 0.33183,-12.5434 6.17549,-15.79603 3.2717,-1.82105 9.2379,-3.16852 11.23305,0 0,0 11.52539,9.6056 12.42398,15.74053 0.95363,6.51078 -5.98915,11.79446 -2.14557,17.13547 3.84359,5.34102 7.61186,11.46161 14.47158,14.59527 8.85083,4.04326 19.94604,4.31564 24.04886,-4.50773 0,0 8.1669,-13.23439 6.24082,-22.43781 -2.16604,-10.34997 -9.48077,-17.46228 -20.01897,-16.59061 0,0 -5.42758,1.53646 -7.9292,0.65587 -6.58909,-2.31941 -16.02955,-7.49314 -15.19768,-14.42882 0.83187,-6.93568 9.55833,8.44447 3.748,-15.99824 -1.55478,-6.54061 -9.59437,-24.45283 -16.30258,-24.00895 0,0 -6.96155,-0.35298 -9.91151,-1.8566 -7.36557,-3.75427 -10.83778,-10.45812 -8.81857,-18.47492 0,0 1.87298,-13.03292 5.25348,-18.36396 7.93496,-12.51342 19.58924,-22.07695 33.10372,-25.06122 4.24644,-0.93771 6.93062,3.3283 12.75051,2.76214 5.10303,-0.49642 9.84185,-6.05074 13.84346,-2.84537 0,0 16.88165,-1.28992 23.8453,13.21033 3.31247,6.89749 4.71066,17.81941 11.30601,21.69872 6.59535,3.87931 11.60217,19.87279 18.46884,20.54349 3.94867,0.38568 10.25015,-4.06981 12.48927,-0.79459 0,0 6.35327,10.96916 6.90158,18.36395 0.48511,6.54257 -6.59488,12.262 -2.93696,17.7081 3.65793,5.44611 4.68796,1.4131 4.78863,6.15241 0.15241,7.17408 -4.7607,16.6994 -11.86115,17.73583 0,0 -12.53135,5.17234 -18.69744,9.56041 -6.62245,4.71284 -15.87104,14.96813 -11.23305,21.64322 0,0 7.82042,10.07549 14.47158,13.99491 7.43886,4.38361 19.41887,8.75645 23.88562,1.3672 0,0 8.90884,-10.20704 10.00946,-17.79132 0.87615,-6.0375 -5.07693,-7.979 -2.11291,-13.31132 0,0 4.26218,-15.44258 10.57228,-19.01981 5.94288,-3.36906 15.32144,3.50888 18.59946,-2.4847 0,0 7.61918,-13.6222 8.1578,-22.32684 0.40659,-6.57079 4.32078,-8.81675 -0.98732,-12.71094 0,0 -9.00115,-10.11082 -15.19766,-11.14955 -3.63896,-0.61001 -8.14088,2.91403 -10.57228,0.13872 0,0 -8.10433,-8.53592 -9.44667,-15.08467 -1.56983,-7.65869 4.02354,-15.53542 -1.52515,-21.04287 -5.54869,-5.50744 -5.14034,-14.65591 -13.47657,-17.10773 -6.04893,-1.77908 -13.54572,5.32072 -18.50151,1.42268 -4.95579,-3.89803 -26.23756,-15.56939 -35.02069,-27.54592 -5.52823,-7.53822 -8.27517,-17.03053 -9.91152,-26.234232 l -1.9823,-11.149545"
+       sodipodi:nodetypes="cssssszszzsszsssssssssszssssszsssssassszssszssssssssssssssszszssc"
+       inkscape:connector-curvature="0" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,471.08015,79.546314)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-9"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,543.12457,23.323419)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-2"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,434.63417,132.94394)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-95"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,471.36269,185.49397)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-3"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,505.831,131.81383)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-27"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,542.55952,186.62408)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-31"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,614.32141,78.133679)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-8"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,649.91982,131.24877)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-5"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,613.1913,185.49398)" />
+  </g>
+</svg>
diff --git a/docs/reference/glib/Sorted_binary_tree_preorder.svg b/docs/reference/glib/Sorted_binary_tree_preorder.svg
new file mode 100644
index 0000000..ae3d22c
--- /dev/null
+++ b/docs/reference/glib/Sorted_binary_tree_preorder.svg
@@ -0,0 +1,750 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="265.90625"
+   height="226.94397"
+   id="svg3953"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="Sorted_binary_tree_preorder.svg">
+  <defs
+     id="defs3955">
+    <marker
+       inkscape:stockid="SquareL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="SquareL"
+       style="overflow:visible">
+      <path
+         id="path4940"
+         d="M -5,-5 -5,5 5,5 5,-5 -5,-5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="scale(0.8,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       style="overflow:visible"
+       id="DistanceStart"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DistanceStart">
+      <g
+         id="g2300">
+        <path
+           style="fill:none;stroke:#ffffff;stroke-width:1.14999998;stroke-linecap:square"
+           d="M 0,0 2,0"
+           id="path2306"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:#000000;fill-rule:evenodd;stroke:none"
+           d="M 0,0 13,4 9,0 13,-4 0,0 z"
+           id="path2302"
+           inkscape:connector-curvature="0" />
+        <path
+           style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square"
+           d="M 0,-4 0,40"
+           id="path2304"
+           inkscape:connector-curvature="0" />
+      </g>
+    </marker>
+    <marker
+       inkscape:stockid="DotL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotL"
+       style="overflow:visible">
+      <path
+         id="path4931"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
+         transform="matrix(0.8,0,0,0.8,5.92,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible">
+      <path
+         id="path4890"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path4869"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3961" />
+    <inkscape:perspective
+       id="perspective3971"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect2940"
+       is_visible="true" />
+    <inkscape:path-effect
+       effect="skeletal"
+       id="path-effect2942"
+       is_visible="true"
+       pattern="m 187.18135,13.365063 1,0"
+       copytype="single_stretched"
+       prop_scale="1"
+       scale_y_rel="false"
+       spacing="0"
+       normal_offset="0"
+       tang_offset="0"
+       prop_units="false"
+       vertical_pattern="false"
+       fuse_tolerance="0" />
+    <inkscape:perspective
+       id="perspective4212"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-5"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-76"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-2"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-22"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4744-8"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4852"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective5886"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-7"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-4"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-3"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-11"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-74"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-79"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-9"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective6303-6"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98775168"
+     inkscape:cx="303.24736"
+     inkscape:cy="-18.949243"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="1366"
+     inkscape:window-height="702"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata3958">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-275.65625,-78.774784)">
+    <g
+       transform="matrix(0.9925764,0,0,0.9925764,278.52645,98.594058)"
+       id="graph0"
+       class="graph"
+       style="font-size:14px;font-family:Times-Roman">
+      <title
+         id="title5">sorted_binary_tree</title>
+      <g
+         id="node1"
+         class="node">
+        <title
+           id="title8">C</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="185"
+           sodipodi:cx="60"
+           d="m 78,185 c 0,9.94113 -8.058875,18 -18,18 -9.941125,0 -18,-8.05887 -18,-18 0,-9.94113 8.058875,-18 18,-18 9.941125,0 18,8.05887 18,18 z"
+           cx="60"
+           cy="185"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse10" />
+        <text
+           style="text-anchor:middle"
+           x="60"
+           y="190"
+           id="text12">C</text>
+      </g>
+      <g
+         id="node2"
+         class="node">
+        <title
+           id="title15">E</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="185"
+           sodipodi:cx="132"
+           d="m 150,185 c 0,9.94113 -8.05887,18 -18,18 -9.94113,0 -18,-8.05887 -18,-18 0,-9.94113 8.05887,-18 18,-18 9.94113,0 18,8.05887 18,18 z"
+           cx="132"
+           cy="185"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse17" />
+        <text
+           style="text-anchor:middle"
+           x="132"
+           y="190"
+           id="text19">E</text>
+      </g>
+      <g
+         id="node3"
+         class="node">
+        <title
+           id="title22">H</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="185"
+           sodipodi:cx="204"
+           d="m 221,185 c 0,9.94113 -7.61116,18 -17,18 -9.38884,0 -17,-8.05887 -17,-18 0,-9.94113 7.61116,-18 17,-18 9.38884,0 17,8.05887 17,18 z"
+           cx="204"
+           cy="185"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse24" />
+        <text
+           style="text-anchor:middle"
+           x="204"
+           y="190"
+           id="text26">H</text>
+      </g>
+      <g
+         id="node4"
+         class="node">
+        <title
+           id="title29">A</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="131"
+           sodipodi:cx="24"
+           d="m 41,131 c 0,9.94113 -7.611159,18 -17,18 -9.388841,0 -17,-8.05887 -17,-18 0,-9.94113 7.611159,-18 17,-18 9.388841,0 17,8.05887 17,18 z"
+           cx="24"
+           cy="131"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse31" />
+        <text
+           style="text-anchor:middle"
+           x="24"
+           y="136"
+           id="text33">A</text>
+      </g>
+      <g
+         id="node5"
+         class="node">
+        <title
+           id="title36">D</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="131"
+           sodipodi:cx="96"
+           d="m 113,131 c 0,9.94113 -7.61116,18 -17,18 -9.388841,0 -17,-8.05887 -17,-18 0,-9.94113 7.611159,-18 17,-18 9.38884,0 17,8.05887 17,18 z"
+           cx="96"
+           cy="131"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse38" />
+        <text
+           style="text-anchor:middle"
+           x="96"
+           y="136"
+           id="text40">D</text>
+      </g>
+      <g
+         id="edge6"
+         class="edge">
+        <title
+           id="title43">D-&gt;C</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 86,147 c -3,4 -7,9 -10,14"
+           id="path45"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="78,164 70,170 73,160 78,164 "
+           id="polygon47" />
+      </g>
+      <g
+         id="edge8"
+         class="edge">
+        <title
+           id="title50">D-&gt;E</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 106,147 c 3,4 7,9 10,14"
+           id="path52"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="119,160 122,170 114,164 119,160 "
+           id="polygon54" />
+      </g>
+      <g
+         id="node6"
+         class="node">
+        <title
+           id="title57">I</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="131"
+           sodipodi:cx="240"
+           d="m 258,131 c 0,9.94113 -8.05887,18 -18,18 -9.94113,0 -18,-8.05887 -18,-18 0,-9.94113 8.05887,-18 18,-18 9.94113,0 18,8.05887 18,18 z"
+           cx="240"
+           cy="131"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse59" />
+        <text
+           style="text-anchor:middle"
+           x="240"
+           y="136"
+           id="text61">I</text>
+      </g>
+      <g
+         id="edge12"
+         class="edge">
+        <title
+           id="title64">I-&gt;H</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 230,146 c -3,5 -6,10 -10,15"
+           id="path66"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="223,163 214,169 217,159 223,163 "
+           id="polygon68" />
+      </g>
+      <g
+         id="node7"
+         class="node">
+        <title
+           id="title71">B</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="77"
+           sodipodi:cx="60"
+           d="m 78,77 c 0,9.941125 -8.058875,18 -18,18 -9.941125,0 -18,-8.058875 -18,-18 0,-9.941125 8.058875,-18 18,-18 9.941125,0 18,8.058875 18,18 z"
+           cx="60"
+           cy="77"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse73" />
+        <text
+           style="text-anchor:middle"
+           x="60"
+           y="82"
+           id="text75">B</text>
+      </g>
+      <g
+         id="edge3"
+         class="edge">
+        <title
+           id="title78">B-&gt;A</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 50,92 c -3,5 -6,10 -10,15"
+           id="path80"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="43,109 34,115 37,105 43,109 "
+           id="polygon82" />
+      </g>
+      <g
+         id="edge5"
+         class="edge">
+        <title
+           id="title85">B-&gt;D</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 70,92 c 3,5 6,10 10,15"
+           id="path87"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="83,105 86,115 77,109 83,105 "
+           id="polygon89" />
+      </g>
+      <g
+         id="node8"
+         class="node">
+        <title
+           id="title92">G</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="17"
+           sodipodi:cy="77"
+           sodipodi:cx="204"
+           d="m 221,77 c 0,9.941125 -7.61116,18 -17,18 -9.38884,0 -17,-8.058875 -17,-18 0,-9.941125 7.61116,-18 17,-18 9.38884,0 17,8.058875 17,18 z"
+           cx="204"
+           cy="77"
+           rx="17"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse94" />
+        <text
+           style="text-anchor:middle"
+           x="204"
+           y="82"
+           id="text96">G</text>
+      </g>
+      <g
+         id="edge11"
+         class="edge">
+        <title
+           id="title99">G-&gt;I</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 214,93 c 3,4 7,9 10,14"
+           id="path101"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="227,106 230,116 222,110 227,106 "
+           id="polygon103" />
+      </g>
+      <g
+         id="node9"
+         class="node">
+        <title
+           id="title106">F</title>
+        <ellipse
+           sodipodi:ry="18"
+           sodipodi:rx="18"
+           sodipodi:cy="23"
+           sodipodi:cx="132"
+           d="m 150,23 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z"
+           cx="132"
+           cy="23"
+           rx="18"
+           ry="18"
+           style="fill:#ffffff;stroke:#000000"
+           id="ellipse108" />
+        <text
+           style="text-anchor:middle"
+           x="132"
+           y="28"
+           id="text110">F</text>
+      </g>
+      <g
+         id="edge2"
+         class="edge">
+        <title
+           id="title113">F-&gt;B</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="M 117,34 C 106,42 94,51 83,60"
+           id="path115"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="85,63 75,66 81,57 85,63 "
+           id="polygon117" />
+      </g>
+      <g
+         id="edge10"
+         class="edge">
+        <title
+           id="title120">F-&gt;G</title>
+        <path
+           style="fill:none;stroke:#000000"
+           d="m 147,34 c 11,8 23,17 34,26"
+           id="path122"
+           inkscape:connector-curvature="0" />
+        <polygon
+           style="fill:#000000;stroke:#000000"
+           points="183,57 189,66 179,63 183,57 "
+           id="polygon124" />
+      </g>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:0.82904756;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:3.31619022, 3.31619022;stroke-dashoffset:0;marker-start:url(#SquareL);marker-end:url(#Arrow2Lend)"
+       d="m 407.86585,83.916245 c -8.09235,12.934463 -16.24193,25.833125 -24.4484,38.695485 -4.10893,6.44009 -8.28,12.93078 -13.72464,18.28932 -5.44312,5.35704 -12.35084,9.56414 -19.94187,10.40186 -3.3055,0.36478 -6.64352,0.0886 -9.9615,-0.13591 -1e-5,0 -3e-5,0 -4e-5,0 -3.30753,-0.22377 -6.65223,-0.39935 -9.91915,0.16371 -3.67892,0.63407 -7.19225,2.2113 -10.11083,4.53904 -10e-6,1e-5 -2e-5,2e-5 -3e-5,2e-5 -2.91857,2.32774 -5.23772,5.40225 -6.67417,8.84797 -1.43645,3.44574 -1.98788,7.25719 -1.58695,10.96875 0.40093,3.71157 1.75359,7.31733 3.89275,10.37682 -1.57329,7.77579 -6.47676,14.83297 -13.21535,19.01981 -4.08578,2.53859 -8.72148,4.0255 -13.0897,6.03963 -2e-5,0 -3e-5,1e-5 -4e-5,2e-5 -4.36719,2.01365 -8.65699,4.73894 -11.05709,8.90627 -10e-6,1e-5 -10e-6,2e-5 -2e-5,3e-5 -1.54971,2.69079 -2.21037,5.86275 -2.00701,8.96123 0.20338,3.09874 1.25331,6.121 2.89275,8.75838 3.2781,5.27351 8.79594,8.88365 14.67878,10.8706 10e-6,0 2e-5,1e-5 4e-5,1e-5 5.05172,1.70623 10.53116,2.32159 15.76564,1.30607 1e-5,-1e-5 2e-5,-1e-5 3e-5,-1e-5 5.23327,-1.0153 10.20383,-3.73183 13.53666,-7.89237 2.8325,-3.53596 4.39168,-7.94004 5.28933,-12.38079 0,-1e-5 10e-6,-3e-5 10e-6,-4e-5 0.89772,-4.44111 1.18109,-8.97997 1.75051,-13.47498 0.87253,-6.88777 2.42162,-13.6897 4.61772,-20.27603 2.52197,-0.49612 5.17081,-0.33611 7.61472,0.45997 2.44389,0.79608 4.67875,2.2269 6.42464,4.11322 2e-5,1e-5 3e-5,3e-5 5e-5,5e-5 3.21102,3.46934 4.63062,8.27318 5.04051,12.98264 0.41,4.71077 -0.0852,9.44723 -0.1789,14.17488 -0.10721,5.4079 0.30156,10.912 -1.06029,16.14671 -1.55704,5.98502 -5.48588,11.32637 -10.73556,14.59527 -3.77605,-0.86428 -7.77873,-0.72238 -11.48409,0.40712 -3.70537,1.1295 -7.10659,3.24452 -9.75844,6.0682 -4.15358,4.42272 -6.37982,10.5847 -6.11019,16.64605 0,2e-5 0,3e-5 0,4e-5 0.23758,5.34073 2.36859,10.56193 5.83809,14.62917 10e-6,10e-6 2e-5,2e-5 3e-5,3e-5 3.46975,4.06752 8.24802,6.97932 13.4221,8.32573 4.51162,1.17403 9.34056,1.17129 13.82052,-0.11828 4.47975,-1.2895 8.59635,-3.87695 11.61522,-7.42904 3.02242,-3.55627 4.91711,-8.06019 5.34575,-12.70759 10e-6,-3e-5 10e-6,-5e-5 10e-6,-8e-5 0.42864,-4.64742 -0.61029,-9.42195 -2.93128,-13.47106 -1.10365,-2.89524 -1.08961,-6.20429 0.0386,-9.09005 0,-10e-6 1e-5,-3e-5 1e-5,-4e-5 1.1282,-2.88577 3.36222,-5.32694 6.1369,-6.70594 3.47162,-1.72538 7.76143,-1.72538 11.23305,0 3.47935,0.88812 6.65089,2.94914 8.87568,5.76782 2.22478,2.81869 3.49269,6.38223 3.5483,9.97271 0.0448,2.88989 -0.66677,5.7303 -1.2997,8.55039 -0.63291,2.82001 -1.19432,5.71596 -0.84587,8.58504 0,2e-5 0,3e-5 0,4e-5 0.43816,3.60767 2.33339,6.96423 4.97344,9.46172 2.64067,2.49807 5.99201,4.1741 9.49814,5.13355 10e-6,0 2e-5,1e-5 4e-5,1e-5 8.13425,2.22592 17.27288,0.51296 24.04882,-4.50774 2.95407,-2.80833 5.12951,-6.42944 6.22172,-10.35631 1.09222,-3.92687 1.09889,-8.15119 0.0191,-12.0815 -1.22234,-4.44914 -3.84239,-8.50594 -7.39496,-11.45011 -3.55256,-2.94417 -8.02526,-4.76546 -12.62397,-5.1405 -2e-5,0 -3e-5,0 -4e-5,0 -2.56836,0.72381 -5.27682,0.94784 -7.9292,0.65587 -10e-6,0 -2e-5,0 -4e-5,0 -3.77599,-0.41566 -7.46992,-1.91446 -10.28756,-4.46235 -10e-6,-1e-5 -2e-5,-1e-5 -2e-5,-2e-5 -2.8168,-2.54715 -4.70691,-6.17422 -4.91006,-9.96645 -0.14723,-2.74836 0.56276,-5.4692 1.41517,-8.08617 0.85243,-2.61706 1.85748,-5.20104 2.33283,-7.91207 0.92354,-5.26723 -0.28222,-10.88387 -3.28625,-15.30794 -3.00404,-4.42407 -7.77987,-7.61656 -13.01633,-8.70101 -3.38923,0.38773 -6.89239,-0.26847 -9.91151,-1.8566 -2e-5,-1e-5 -4e-5,-2e-5 -7e-5,-3e-5 -3.23617,-1.70233 -5.90142,-4.47336 -7.47657,-7.7733 -1.57515,-3.29994 -2.05353,-7.11482 -1.34194,-10.70152 0,-2e-5 1e-5,-5e-5 1e-5,-7e-5 0.98555,-6.30654 2.75458,-12.49035 5.25348,-18.36396 1e-5,-2e-5 2e-5,-5e-5 3e-5,-7e-5 2.90825,-6.83578 6.89834,-13.35821 12.56261,-18.16464 5.66117,-4.8038 13.16594,-7.75245 20.54108,-6.89651 4.32392,0.50183 8.42733,2.25397 12.75051,2.76214 4.7583,0.55932 9.69143,-0.45462 13.8434,-2.84533 2e-5,-2e-5 4e-5,-3e-5 6e-5,-4e-5 9.24006,1.13358 17.98407,5.97778 23.8453,13.21033 5.15234,6.35781 7.99577,14.2147 11.30601,21.69872 1.92466,4.3514 4.05797,8.66096 7.03333,12.37393 10e-6,2e-5 3e-5,4e-5 5e-5,6e-5 2.97478,3.71223 6.87266,6.82357 11.43539,8.16948 2e-5,1e-5 5e-5,1e-5 7e-5,2e-5 4.08278,1.20432 8.59203,0.91743 12.48927,-0.79459 2.77058,2.06261 4.93246,4.93513 6.1476,8.16838 10e-6,2e-5 2e-5,4e-5 2e-5,6e-5 1.21514,3.23328 1.48028,6.81866 0.75396,10.19551 -0.64549,3.00105 -2.03848,5.78453 -2.94997,8.71576 -0.45574,1.4656 -0.79214,2.97858 -0.84237,4.51258 -0.0502,1.5339 0.19468,3.09454 0.85538,4.47976 1.12213,2.35266 3.31808,4.00019 4.78859,6.15235 10e-6,2e-5 3e-5,4e-5 4e-5,6e-5 1.28491,1.88055 1.99273,4.15109 2.00406,6.42866 0,2e-5 0,5e-5 0,7e-5 0.0113,2.27755 -0.67387,4.55499 -1.94,6.44821 -1.26613,1.89323 -3.10926,3.39632 -5.21849,4.25572 -2.10924,0.8594 -4.47799,1.07243 -6.70672,0.60317 -6.72013,2.08 -13.07673,5.33027 -18.69744,9.56041 -3.43389,2.58434 -6.63757,5.58482 -8.83155,9.28034 -2.19309,3.69404 -3.30672,8.16333 -2.4015,12.36288 0.73825,3.42496 2.77646,6.49085 5.39143,8.82264 2.61545,2.33222 5.78751,3.97275 9.08008,5.17224 2e-5,1e-5 5e-5,2e-5 7e-5,3e-5 7.59964,2.76856 16.01971,3.25052 23.88562,1.3672 2e-5,-10e-6 4e-5,-3e-5 6e-5,-4e-5 5.55583,-4.2436 9.26683,-10.83973 10.0094,-17.79128 0.48273,-4.51901 -0.25456,-9.16391 -2.11291,-13.31132 -1.12772,-3.87126 -0.64207,-8.19191 1.31693,-11.71621 1.95901,-3.5243 5.37216,-6.21769 9.25535,-7.3036 3.03411,-0.84847 6.23896,-0.7413 9.38918,-0.78414 3.15001,-0.0428 6.40369,-0.26967 9.21028,-1.70056 1.87052,-0.95365 3.46254,-2.41445 4.68173,-4.12379 1.21923,-1.70942 2.07411,-3.66326 2.63108,-5.68772 0,-2e-5 10e-6,-4e-5 2e-5,-7e-5 1.11392,-4.04896 1.04531,-8.32057 0.84497,-12.51519 0,-2e-5 0,-5e-5 0,-7e-5 -0.20277,-4.24553 -0.53208,-8.48502 -0.98732,-12.71094 -1.04658,-3.18409 -3.10978,-6.02749 -5.8122,-8.01008 -2.70242,-1.9826 -6.03405,-3.09704 -9.38546,-3.13947 -1.77072,-0.0224 -3.53043,0.24491 -5.29437,0.40133 -1.76389,0.15642 -3.56824,0.19871 -5.27791,-0.26261 -1.52465,-0.4114 -2.93141,-1.21815 -4.11285,-2.26602 -2e-5,-2e-5 -3e-5,-3e-5 -5e-5,-5e-5 -1.1815,-1.04794 -2.14182,-2.33315 -2.88667,-3.72574 -1.48968,-2.78513 -2.11051,-5.95234 -2.4471,-9.09286 0,-2e-5 -10e-6,-5e-5 -10e-6,-7e-5 -0.7501,-6.99887 -0.1865,-14.13231 -1.52514,-21.0428 -0.72945,-3.76565 -2.0464,-7.46897 -4.28746,-10.58183 -2.2404,-3.11195 -5.46685,-5.60479 -9.18911,-6.5259 -3.02141,-0.74768 -6.20154,-0.44617 -9.27072,0.0716 -3.06933,0.51775 -6.11978,1.24879 -9.23079,1.35113 -2e-5,0 -5e-5,0 -7e-5,0 -3.90344,0.1284 -7.81108,-0.74979 -11.38322,-2.32877 -3.5723,-1.57904 -6.81761,-3.84706 -9.69109,-6.49241 -5.74696,-5.29072 -9.96674,-12.00296 -13.94631,-18.72474 -2.39922,-4.05246 -4.71299,-8.17874 -6.40846,-12.57238 -1.69522,-4.39298 -2.67881,-9.02583 -3.50306,-13.661852 l -1.9823,-11.149545"
+       id="path2938"
+       inkscape:path-effect="#path-effect2940;#path-effect2942"
+       inkscape:original-d="m 407.86585,83.916245 c 0,0 -14.11559,27.469705 -24.4484,38.695485 -9.34236,10.14972 -20.62893,24.18364 -33.66651,28.69118 -10.61846,3.67116 -11.93657,-7.91708 -19.88069,0.0278 -8.03966,8.04037 -7.9913,25.39502 -14.47923,34.7326 0,0 -7.13271,14.26573 -13.21535,19.01981 -8.72576,6.81989 -26.98503,4.24108 -24.14685,14.94595 2.83816,10.70488 4.57641,21.84782 15.56452,28.59021 9.79125,6.00799 28.36077,4.86263 29.30237,-6.5863 0.94161,-11.44892 3.2096,-17.00295 7.03985,-25.85581 3.83025,-8.85286 -1.10893,-26.61597 4.61772,-20.27603 0,0 11.6923,-3.64141 14.03941,4.57324 1.70869,5.98028 2.66345,21.33932 4.86161,27.15752 2.19816,5.81821 -0.52766,12.44562 -1.06029,16.14671 -1.09286,7.59409 -3.21008,13.10136 -10.73556,14.59527 0,0 -15.16484,1.49219 -21.24253,6.47532 -6.22299,5.10225 -7.51576,8.72253 -6.11019,16.64609 1.81705,10.24319 9.04679,20.97753 19.26022,22.95493 11.49367,2.22528 19.58074,2.59049 25.43574,-7.54732 4.1679,-7.21663 -1.97686,-19.09584 2.41448,-26.17873 0,0 0.33183,-12.5434 6.17549,-15.79603 3.2717,-1.82105 9.2379,-3.16852 11.23305,0 0,0 11.52539,9.6056 12.42398,15.74053 0.95363,6.51078 -5.98915,11.79446 -2.14557,17.13547 3.84359,5.34102 7.61186,11.46161 14.47158,14.59527 8.85083,4.04326 19.94604,4.31564 24.04886,-4.50773 0,0 8.1669,-13.23439 6.24082,-22.43781 -2.16604,-10.34997 -9.48077,-17.46228 -20.01897,-16.59061 0,0 -5.42758,1.53646 -7.9292,0.65587 -6.58909,-2.31941 -16.02955,-7.49314 -15.19768,-14.42882 0.83187,-6.93568 9.55833,8.44447 3.748,-15.99824 -1.55478,-6.54061 -9.59437,-24.45283 -16.30258,-24.00895 0,0 -6.96155,-0.35298 -9.91151,-1.8566 -7.36557,-3.75427 -10.83778,-10.45812 -8.81857,-18.47492 0,0 1.87298,-13.03292 5.25348,-18.36396 7.93496,-12.51342 19.58924,-22.07695 33.10372,-25.06122 4.24644,-0.93771 6.93062,3.3283 12.75051,2.76214 5.10303,-0.49642 9.84185,-6.05074 13.84346,-2.84537 0,0 16.88165,-1.28992 23.8453,13.21033 3.31247,6.89749 4.71066,17.81941 11.30601,21.69872 6.59535,3.87931 11.60217,19.87279 18.46884,20.54349 3.94867,0.38568 10.25015,-4.06981 12.48927,-0.79459 0,0 6.35327,10.96916 6.90158,18.36395 0.48511,6.54257 -6.59488,12.262 -2.93696,17.7081 3.65793,5.44611 4.68796,1.4131 4.78863,6.15241 0.15241,7.17408 -4.7607,16.6994 -11.86115,17.73583 0,0 -12.53135,5.17234 -18.69744,9.56041 -6.62245,4.71284 -15.87104,14.96813 -11.23305,21.64322 0,0 7.82042,10.07549 14.47158,13.99491 7.43886,4.38361 19.41887,8.75645 23.88562,1.3672 0,0 8.90884,-10.20704 10.00946,-17.79132 0.87615,-6.0375 -5.07693,-7.979 -2.11291,-13.31132 0,0 4.26218,-15.44258 10.57228,-19.01981 5.94288,-3.36906 15.32144,3.50888 18.59946,-2.4847 0,0 7.61918,-13.6222 8.1578,-22.32684 0.40659,-6.57079 4.32078,-8.81675 -0.98732,-12.71094 0,0 -9.00115,-10.11082 -15.19766,-11.14955 -3.63896,-0.61001 -8.14088,2.91403 -10.57228,0.13872 0,0 -8.10433,-8.53592 -9.44667,-15.08467 -1.56983,-7.65869 4.02354,-15.53542 -1.52515,-21.04287 -5.54869,-5.50744 -5.14034,-14.65591 -13.47657,-17.10773 -6.04893,-1.77908 -13.54572,5.32072 -18.50151,1.42268 -4.95579,-3.89803 -26.23756,-15.56939 -35.02069,-27.54592 -5.52823,-7.53822 -8.27517,-17.03053 -9.91152,-26.234232 l -1.9823,-11.149545"
+       sodipodi:nodetypes="cssssszszzsszsssssssssszssssszsssssassszssszssssssssssssssszszssc"
+       inkscape:connector-curvature="0" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,436.04679,77.286097)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-9"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,509.22132,21.628256)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-2"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,402.42607,130.68372)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-95"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,435.76428,185.49397)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-3"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,473.62291,131.24878)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-27"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,508.09122,184.36387)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-31"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,580.41815,77.003571)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-8"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,616.01657,130.11867)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.04799998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="path5876-5"
+       sodipodi:cx="-146.78572"
+       sodipodi:cy="122.70478"
+       sodipodi:rx="5.3571429"
+       sodipodi:ry="5.3571429"
+       d="m -141.42858,122.70478 c 0,2.95867 -2.39847,5.35714 -5.35714,5.35714 -2.95867,0 -5.35714,-2.39847 -5.35714,-5.35714 0,-2.95867 2.39847,-5.35714 5.35714,-5.35714 2.95867,0 5.35714,2.39847 5.35714,5.35714 z"
+       transform="matrix(0.79107591,0,0,0.79107591,580.41815,185.49398)" />
+  </g>
+</svg>
diff --git a/docs/reference/glib/building.xml b/docs/reference/glib/building.xml
new file mode 100644
index 0000000..720a6ff
--- /dev/null
+++ b/docs/reference/glib/building.xml
@@ -0,0 +1,401 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-building">
+  <refmeta>
+    <refentrytitle>Compiling the GLib package</refentrytitle>
+    <manvolnum>3</manvolnum>
+    <refmiscinfo>GLib Library</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>Compiling the GLib Package</refname>
+    <refpurpose>How to compile GLib itself</refpurpose>
+  </refnamediv>
+
+  <refsect1 id="building">
+    <title>Building the Library on UNIX</title>
+    <para>
+      On UNIX, GLib uses the standard <application>Meson</application> build
+      system. The normal sequence for compiling and installing the GLib library
+      is thus:
+
+      <literallayout>
+        <userinput>meson _build</userinput>
+        <userinput>ninja -C _build</userinput>
+        <userinput>ninja -C _build install</userinput>
+      </literallayout>
+
+      On FreeBSD:
+      <literallayout>
+        <userinput>env CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib -Wl,--disable-new-dtags" meson -Dxattr=false -Dinstalled_tests=true -Diconv=external -Db_lundef=false _build</userinput>
+        <userinput>ninja -C _build</userinput>
+      </literallayout>
+    </para>
+
+    <para>
+      The standard options provided by <application>Meson</application> may be
+      passed to the <command>meson</command> command.  Please see the
+      <application>Meson</application> documentation or run
+      <command>meson configure --help</command> for information about
+      the standard options.
+    </para>
+    <para>
+      GLib is compiled with
+      <ulink url="https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fstrict-aliasing">strict aliasing</ulink>
+      disabled. It is strongly recommended that this is not re-enabled by
+      overriding the compiler flags, as GLib has not been tested with strict
+      aliasing and cannot be guaranteed to work.
+    </para>
+    <para>
+      The GTK+ documentation contains
+      <ulink url="https://developer.gnome.org/gtk3/stable/gtk-building.html">further details</ulink>
+      about the build process and ways to influence it.
+    </para>
+  </refsect1>
+  <refsect1 id="dependencies">
+    <title>Dependencies</title>
+    <para>
+      Before you can compile the GLib library, you need to have
+      various other tools and libraries installed on your system.
+      If you are building from a release archive, you will need
+      <ulink url="https://wiki.gnome.org/Projects/GLib/CompilerRequirements">a compliant C toolchain</ulink>,
+      <application>Meson</application>, and <application>pkg-config</application>;
+      the requirements are the same when building from a Git repository clone
+      of GLib.
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          <ulink url="https://www.freedesktop.org/wiki/Software/pkg-config/">pkg-config</ulink>
+          is a tool for tracking the compilation flags needed for
+          libraries that are used by the GLib library. (For each
+          library, a small <literal>.pc</literal> text file is
+          installed in a standard location that contains the compilation
+          flags needed for that library along with version number
+          information).
+        </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      A UNIX build of GLib requires that the system implements at
+      least the original 1990 version of POSIX. Beyond this, it
+      depends on a number of other libraries.
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          The <ulink url="http://www.gnu.org/software/libiconv/">GNU
+          libiconv library</ulink> is needed to build GLib if your
+          system doesn't have the <function>iconv()</function>
+          function for doing conversion between character
+          encodings. Most modern systems should have
+          <function>iconv()</function>, however many older systems lack
+          an <function>iconv()</function> implementation. On such systems,
+          you must install the libiconv library. This can be found at:
+          <ulink url="http://www.gnu.org/software/libiconv">http://www.gnu.org/software/libiconv</ulink>.
+        </para>
+        <para>
+          If your system has an <function>iconv()</function> implementation but
+          you want to use libiconv instead, you can pass the
+          <option>-Diconv=gnu</option> option to <command>meson</command>. This
+          forces libiconv to be used.
+        </para>
+        <para>
+          Note that if you have libiconv installed in your default include
+          search path (for instance, in <filename>/usr/local/</filename>), but
+          don't enable it, you will get an error while compiling GLib because
+          the <filename>iconv.h</filename> that libiconv installs hides the
+          system iconv.
+        </para>
+        <para>
+          If you are using the native iconv implementation on Solaris
+          instead of libiconv, you'll need to make sure that you have
+          the converters between locale encodings and UTF-8 installed.
+          At a minimum you'll need the SUNWuiu8 package. You probably
+          should also install the SUNWciu8, SUNWhiu8, SUNWjiu8, and
+          SUNWkiu8 packages.
+        </para>
+        <para>
+          The native iconv on Compaq Tru64 doesn't contain support for
+          UTF-8, so you'll need to use GNU libiconv instead. (When
+          using GNU libiconv for GLib, you'll need to use GNU libiconv
+          for GNU gettext as well.) This probably applies to related
+          operating systems as well.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Python 3.5 or newer is required. Your system Python must
+          conform to <ulink
+          url="https://www.python.org/dev/peps/pep-0394/">PEP 394
+          </ulink>
+          For FreeBSD, this means that the
+          <literal>lang/python3</literal> port must be installed.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The libintl library from the <ulink
+          url="http://www.gnu.org/software/gettext">GNU gettext
+          package</ulink> is needed if your system doesn't have the
+          <function>gettext()</function> functionality for handling
+          message translation databases.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          A thread implementation is needed. The thread support in GLib
+          can be based upon POSIX threads or win32 threads.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          GRegex uses the <ulink url="http://www.pcre.org/">PCRE library</ulink>
+          for regular expression matching. The default is to use the system
+          version of PCRE, to reduce the chances of security fixes going out
+          of sync. GLib additionally provides an internal copy of PCRE in case
+          the system version is too old, or does not support UTF-8; the internal
+          copy is patched to use GLib for memory management and to share the
+          same Unicode tables.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The optional extended attribute support in GIO requires the
+          <function>getxattr()</function> family of functions that may be
+          provided by the C library or by the standalone libattr library. To
+          build GLib without extended attribute support, use the
+          <option>-Dxattr=false</option> option.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The optional SELinux support in GIO requires libselinux.
+          To build GLib without SELinux support, use the
+          <option>-Dselinux=disabled</option> option.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The optional support for DTrace requires the
+          <filename>sys/sdt.h</filename> header, which is provided
+          by SystemTap on Linux. To build GLib without DTrace, use
+          the <option>-Ddtrace=false</option> option.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The optional support for
+          <ulink url="http://sourceware.org/systemtap/">SystemTap</ulink>
+          can be disabled with the <option>-Dsystemtap=false</option>
+          option. Additionally, you can control the location
+          where GLib installs the SystemTap probes, using the
+          <option>-Dtapset_install_dir=DIR</option> option.
+        </para>
+      </listitem>
+    </itemizedlist>
+
+  </refsect1>
+  <refsect1 id="extra-configuration-options">
+    <title>Extra Configuration Options</title>
+
+    <para>
+      In addition to the normal options, these additional ones are supported
+      when configuring the GLib library:
+    </para>
+
+    <formalpara>
+      <title><option>--buildtype</option></title>
+
+      <para>
+        This is a standard <application>Meson</application> option which
+        specifies how much debugging and optimization to enable. If the build
+        type starts with <literal>debug</literal>,
+        <literal>G_ENABLE_DEBUG</literal> will be defined and GLib will be built
+        with additional debug code enabled.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dforce_posix_threads=true</option></title>
+
+      <para>
+        Normally, <application>Meson</application> should be able to work out
+        the correct thread implementation to use. This option forces POSIX
+        threads to be used even if the platform provides another threading API
+        (for example, on Windows).
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dinternal_pcre=true</option></title>
+
+      <para>
+        Normally, GLib will be configured to use the system-supplied PCRE
+        library if it is suitable, falling back to an internal version
+        otherwise. If this option is specified, the internal version will always
+        be used.
+      </para>
+      <para>
+        Using the internal PCRE is the preferred solution if:
+        <itemizedlist>
+          <listitem>
+            <para>
+              your system has strict resource constraints; the system-supplied
+              PCRE has a separated copy of the tables used for Unicode
+              handling, whereas the internal copy shares the Unicode tables
+              used by GLib.
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              your system has PCRE built without some needed features,
+              such as UTF-8 and Unicode support.
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              you are planning to use both GRegex and PCRE API at the same
+              time, either directly or indirectly through a dependency; PCRE
+              uses some global variables for memory management and
+              other features, and if both GLib and PCRE try to access them
+              at the same time, this could lead to undefined behavior.
+            </para>
+          </listitem>
+        </itemizedlist>
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dbsymbolic_functions=false</option> and
+        <option>-Dbsymbolic_functions=true</option></title>
+
+      <para>
+        By default, GLib uses the <option>-Bsymbolic-functions</option>
+        linker flag to avoid intra-library PLT jumps. A side-effect
+        of this is that it is no longer possible to override
+        internal uses of GLib functions with
+        <envar>LD_PRELOAD</envar>. Therefore, it may make
+        sense to turn this feature off in some situations.
+        The <option>-Dbsymbolic_functions=false</option> option allows
+        to do that.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dgtk_doc=false</option> and
+        <option>-Dgtk_doc=true</option></title>
+
+      <para>
+        By default, GLib will detect whether the
+        <application>gtk-doc</application> package is installed.
+        If it is, then it will use it to extract and build the
+        documentation for the GLib library. These options
+        can be used to explicitly control whether
+        <application>gtk-doc</application> should be
+        used or not. If it is not used, the distributed,
+        pre-generated HTML files will be installed instead of
+        building them on your machine.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dman=false</option> and
+        <option>-Dman=true</option></title>
+
+      <para>
+        By default, GLib will detect whether <application>xsltproc</application>
+        and the necessary DocBook stylesheets are installed.
+        If they are, then it will use them to rebuild the included
+        man pages from the XML sources. These options can be used
+        to explicitly control whether man pages should be rebuilt
+        used or not. The distribution includes pre-generated man
+        pages.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dxattr=false</option> and
+        <option>-Dxattr=true</option></title>
+
+      <para>
+        By default, GLib will detect whether the
+        <function>getxattr()</function>
+        family of functions is available. If it is, then extended
+        attribute support will be included in GIO. These options can
+        be used to explicitly control whether extended attribute
+        support should be included or not. <function>getxattr()</function>
+        and friends can be provided by glibc or by the standalone
+        libattr library.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dselinux=auto</option>,
+        <option>-Dselinux=enabled</option> or
+        <option>-Dselinux=disabled</option></title>
+
+      <para>
+        By default, GLib will detect if libselinux is available and
+        include SELinux support in GIO if it is. These options can be
+        used to explicitly control whether SELinux support should
+        be included.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Ddtrace=false</option> and
+        <option>-Ddtrace=true</option></title>
+
+      <para>
+        By default, GLib will detect if DTrace support is available, and use it.
+        These options can be used to explicitly control whether DTrace support
+        is compiled into GLib.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Dsystemtap=false</option> and
+        <option>-Dsystemtap=true</option></title>
+
+      <para>
+        This option requires DTrace support. If it is available, then
+        GLib will also check for the presence of SystemTap.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Db_coverage=true</option> and
+        <option>-Db_coverage=false</option></title>
+
+      <para>
+        Enable the generation of coverage reports for the GLib tests.
+        This requires the lcov frontend to gcov from the
+        <ulink url="http://ltp.sourceforge.net">Linux Test Project</ulink>.
+        To generate a coverage report, use
+        <command>ninja coverage-html</command>. The report is placed in the
+        <filename>meson-logs</filename> directory.
+      </para>
+    </formalpara>
+
+    <formalpara>
+      <title><option>-Druntime_libdir=RELPATH</option></title>
+
+      <para>
+        Allows specifying a relative path to where to install the runtime
+        libraries (meaning library files used for running, not developing,
+        GLib applications). This can be used in operating system setups where
+        programs using GLib needs to run before e.g. <filename>/usr</filename>
+        is mounted.
+        For example, if <varname>LIBDIR</varname> is <filename>/usr/lib</filename> and
+        <filename>../../lib</filename> is passed to
+        <option>-Druntime_libdir</option> then the
+        runtime libraries are installed into <filename>/lib</filename> rather
+        than <filename>/usr/lib</filename>.
+      </para>
+    </formalpara>
+  </refsect1>
+
+</refentry>
diff --git a/docs/reference/glib/changes.xml b/docs/reference/glib/changes.xml
new file mode 100644
index 0000000..9b4aa74
--- /dev/null
+++ b/docs/reference/glib/changes.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-changes" revision="17 Jan 2002">
+<refmeta>
+<refentrytitle>Changes to GLib</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>Changes to GLib</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Changes to GLib</refname>
+<refpurpose>
+Incompatible changes made between successive versions of GLib
+</refpurpose>
+</refnamediv>
+
+
+<refsect1>
+<title>Incompatible changes from 2.0 to 2.2</title>
+
+<itemizedlist>
+
+<listitem>
+<para>
+GLib changed the seeding algorithm for the pseudo-random number
+generator Mersenne Twister, as used by <structname>GRand</structname>
+and <structname>GRandom</structname>. This was necessary, because some
+seeds would yield very bad pseudo-random streams. Also the
+pseudo-random integers generated by
+<function>g_rand*_int_range()</function> will have a
+slightly better equal distribution with the new version of GLib.
+</para>
+
+<para>
+Further information can be found at the website of the Mersenne
+Twister random number generator at <ulink
+url="http://www.math.keio.ac.jp/~matumoto/emt.html">http://www.math.keio.ac.jp/~matumoto/emt.html</ulink>.
+</para> 
+
+<para>
+The original seeding and generation algorithms, as found in GLib
+2.0.x, can be used instead of the new ones by setting the environment
+variable <envar>G_RANDOM_VERSION</envar> to the value of '2.0'. Use
+the GLib-2.0 algorithms only if you have sequences of numbers generated
+with Glib-2.0 that you need to reproduce exactly.  
+</para> 
+
+</listitem>
+
+</itemizedlist>
+
+</refsect1>
+
+<refsect1>
+<title>Incompatible changes from 1.2 to 2.0</title>
+
+<itemizedlist>
+
+<listitem>
+<para>
+The event loop functionality <structname>GMain</structname> has extensively 
+been revised to support multiple separate main loops in separate threads. 
+All sources (timeouts, idle functions, etc.) are associated with a 
+<structname>GMainContext</structname>.
+</para>
+
+<para>
+Compatibility functions exist so that most application code dealing with
+the main loop will continue to work. However, code that creates new custom 
+types of sources will require modification.
+</para>
+
+<para>
+The main changes here are:
+
+  <itemizedlist>
+
+  <listitem>
+  <para>
+   Sources are now exposed as <type>GSource *</type>, rather than simply as 
+   numeric ids.
+  </para>
+  </listitem>
+  
+  <listitem>
+  <para>
+   New types of sources are created by structure "derivation" from 
+   <structname>GSource</structname>, so the <literal>source_data</literal> 
+   parameter to the <structname>GSource</structname> virtual functions has been
+   replaced with a <type>GSource *</type>.
+  </para>
+  </listitem>
+  
+  <listitem>
+  <para>
+   Sources are first created, then later added to a specific 
+   <structname>GMainContext</structname>. 
+  </para>
+  </listitem>
+  
+  <listitem>
+  <para>
+   Dispatching has been modified so both the callback and data are passed
+   in to the <function>dispatch()</function> virtual function.
+  </para>
+  </listitem>
+
+  </itemizedlist>
+  To go along with this change, the vtable for 
+  <structname>GIOChannel</structname> has changed and
+  <function>add_watch()</function> has been replaced by 
+  <function>create_watch()</function>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>g_list_foreach()</function> and 
+<function>g_slist_foreach()</function> have been changed so they
+are now safe against removal of the current item, not the next item.
+</para>
+
+<para>
+It's not recommended to mutate the list in the callback to these
+functions in any case.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<structname>GDate</structname> now works in UTF-8, not in the current locale. 
+If you want to use it with the encoding of the locale, you need to convert 
+strings using <function>g_locale_to_utf8()</function> first.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>g_strsplit()</function> has been fixed to:
+
+  <itemizedlist>
+  <listitem>
+  <para>
+   include trailing empty tokens, rather than stripping them
+  </para>
+  </listitem>
+  <listitem>
+  <para>
+   split into a maximum of <literal>max_tokens</literal> tokens, rather 
+   than <literal>max_tokens + 1</literal>
+  </para>
+  </listitem>
+  </itemizedlist>
+
+  Code depending on either of these bugs will need to be fixed.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Deprecated functions that got removed:
+<function>g_set_error_handler()</function>, 
+<function>g_set_warning_handler()</function>,
+<function>g_set_message_handler()</function>, use 
+<function>g_log_set_handler()</function> instead.
+</para>
+</listitem>
+</itemizedlist>
+
+</refsect1>
+
+</refentry>
diff --git a/docs/reference/glib/compiling.xml b/docs/reference/glib/compiling.xml
new file mode 100644
index 0000000..02971a6
--- /dev/null
+++ b/docs/reference/glib/compiling.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-compiling" revision="17 Jan 2002">
+<refmeta>
+<refentrytitle>Compiling GLib Applications</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>GLib Library</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Compiling GLib Applications</refname>
+<refpurpose>
+How to compile your GLib application
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Compiling GLib Applications on UNIX</title>
+
+<para>
+To compile a GLib application, you need to tell the compiler where to
+find the GLib header files and libraries. This is done with the
+<application>pkg-config</application> utility.
+</para>
+<para>
+The following interactive shell session demonstrates how
+<application>pkg-config</application> is used (the actual output on
+your system may be different):
+<programlisting>
+$ pkg-config --cflags glib-2.0
+ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
+$ pkg-config --libs glib-2.0
+ -L/usr/lib -lm -lglib-2.0
+</programlisting>
+</para>
+<para>
+See the <ulink url="http://www.freedesktop.org/wiki/Software/pkg-config">pkg-config website</ulink>
+for more information about <application>pkg-config</application>.
+</para>
+<para>
+If your application uses or <structname>GObject</structname>
+features, it must be compiled and linked with the options returned
+by the following <application>pkg-config</application> invocation:
+<programlisting>
+$ pkg-config --cflags --libs gobject-2.0
+</programlisting>
+</para>
+<para>
+If your application uses modules, it must be compiled and linked
+with the options returned by one of the following
+<application>pkg-config</application> invocations:
+<programlisting>
+$ pkg-config --cflags --libs gmodule-no-export-2.0
+$ pkg-config --cflags --libs gmodule-2.0
+</programlisting>
+The difference between the two is that gmodule-2.0 adds
+<option>--export-dynamic</option> to the linker flags,
+which is often not needed.
+</para>
+<para>
+The simplest way to compile a program is to use the "backticks"
+feature of the shell. If you enclose a command in backticks
+(<emphasis>not single quotes</emphasis>), then its output will
+be substituted into the command line before execution. So to
+compile a GLib Hello, World, you would type the following:
+<programlisting>
+$ cc hello.c `pkg-config --cflags --libs glib-2.0` -o hello
+</programlisting>
+</para>
+<note><para>
+Note that the name of the file must come before the other options
+(such as <emphasis>pkg-config</emphasis>), or else you may get an
+error from the linker.
+</para></note>
+
+<para>
+Deprecated GLib functions are annotated to make the compiler
+emit warnings when they are used (e.g. with gcc, you need to use
+the -Wdeprecated-declarations option). If these warnings are
+problematic, they can be turned off by defining the preprocessor
+symbol %GLIB_DISABLE_DEPRECATION_WARNINGS by using the commandline
+option <literal>-DGLIB_DISABLE_DEPRECATION_WARNINGS</literal>
+</para>
+
+<para>
+GLib deprecation annotations are versioned; by defining the
+macros %GLIB_VERSION_MIN_REQUIRED and %GLIB_VERSION_MAX_ALLOWED,
+you can specify the range of GLib versions whose API you want
+to use. APIs that were deprecated before or introduced after
+this range will trigger compiler warnings.
+</para>
+
+<para>
+Since GLib 2.62, the older deprecation mechanism of hiding deprecated interfaces
+entirely from the compiler by using the preprocessor symbol
+<literal>G_DISABLE_DEPRECATED</literal> has been removed. All deprecations
+are now handled using the above mechanism.
+</para>
+
+<para>
+The recommended way of using GLib has always been to only include the
+toplevel headers <filename>glib.h</filename>,
+<filename>glib-object.h</filename>, <filename>gio.h</filename>.
+Starting with 2.32, GLib enforces this by generating an error
+when individual headers are directly included.
+</para>
+
+<para>
+Still, there are some exceptions; these headers have to be included
+separately:
+<filename>gmodule.h</filename>,
+<filename>glib-unix.h</filename>,
+<filename>glib/gi18n-lib.h</filename> or
+<filename>glib/gi18n.h</filename> (see
+the <link linkend="glib-I18N">Internationalization section</link>),
+<filename>glib/gprintf.h</filename> and
+<filename>glib/gstdio.h</filename>
+(we don't want to pull in all of stdio).
+</para>
+
+</refsect1>
+
+</refentry>
diff --git a/docs/reference/glib/cross.xml b/docs/reference/glib/cross.xml
new file mode 100644
index 0000000..c90b30b
--- /dev/null
+++ b/docs/reference/glib/cross.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-cross-compiling" revision="7 Aug 2018">
+<refmeta>
+<refentrytitle>Cross-compiling the GLib package</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>GLib Library</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Cross-compiling the GLib Package</refname>
+<refpurpose>
+How to cross-compile GLib
+</refpurpose>
+</refnamediv>
+
+    <refsect1 id="cross">
+      <title>Building the Library for a different architecture</title>
+      <para>
+        Cross-compilation is the process of compiling a program or
+        library on a different architecture or operating system then
+        it will be run upon. GLib is slightly more difficult to 
+        cross-compile than many packages because much of GLib is
+        about hiding differences between different systems. 
+      </para>
+      <para>
+        These notes cover things specific to cross-compiling GLib;
+        for general information about cross-compilation, see the
+        <ulink url="http://mesonbuild.com/Cross-compilation.html">meson</ulink>
+        info pages.
+      </para>
+      <para>
+        GLib tries to detect as much information as possible about
+        the target system by compiling and linking programs without
+        actually running anything; however, some information GLib
+        needs is not available this way. This information needs
+        to be provided to meson via a ‘cross file’.
+      </para>
+      <para>
+        As an example of using a cross file, to cross compile for
+        the ‘MingW32’ Win64 runtime environment on a Linux system,
+        create a file <filename>cross_file.txt</filename> with the following
+        contents:
+      </para>
+      <programlisting> 
+[host_machine]
+system = 'windows'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
+
+[properties]
+c_args = []
+c_link_args = []
+
+[binaries]
+c = 'x86_64-w64-mingw32-gcc'
+cpp = 'x86_64-w64-mingw32-g++'
+ar = 'x86_64-w64-mingw32-ar'
+ld = 'x86_64-w64-mingw32-ld'
+objcopy = 'x86_64-w64-mingw32-objcopy'
+strip = 'x86_64-w64-mingw32-strip'
+pkgconfig = 'x86_64-w64-mingw32-pkg-config'
+windres = 'x86_64-w64-mingw32-windres'
+      </programlisting>
+      <para>
+        Then execute the following commands:
+      </para>
+      <programlisting>
+meson --cross-file cross_file.txt builddir
+      </programlisting>
+      <para>
+        The complete list of cross properties follows. Most
+         of these won't need to be set in most cases.
+      </para>
+    </refsect1>
+    <refsect1 id="cross-properties">
+      <title>Cross properties</title>
+      <formalpara>
+        <title>have_[function]</title>
+
+        <para>
+           When meson checks if a function is supported, the test can be
+           overridden by setting the
+           <literal>have_<replaceable>function</replaceable></literal> property
+           to <constant>true</constant> or <constant>false</constant>.
+           For example <programlisting>Checking for function "fsync" : YES</programlisting>
+           can be overridden by setting <programlisting>have_fsync = false</programlisting>
+        </para>
+      </formalpara>
+      <formalpara>
+        <title>growing_stack=[true/false]</title>
+
+        <para>
+           Whether the stack grows up or down. Most places will want
+           <constant>false</constant>.
+           A few architectures, such as PA-RISC need <constant>true</constant>.
+        </para>
+      </formalpara>
+      <formalpara>
+         <title>have_strlcpy=[true/false]</title>
+
+         <para>
+            Whether you have <function>strlcpy()</function> that matches 
+            OpenBSD. Defaults to <constant>false</constant>, which is safe,
+            since GLib uses a built-in version in that case.
+	</para>
+      </formalpara>
+      <formalpara>
+         <title>va_val_copy=[true/false]</title>
+
+         <para>
+            Whether <type>va_list</type> can be copied as a pointer. If set 
+            to <constant>false</constant>, then <function>memcopy()</function>
+            will be used. Only matters if you don't have
+            <function>va_copy()</function> or <function>__va_copy()</function>.
+            (So, doesn't matter for GCC.)
+            Defaults to <constant>true</constant> which is slightly more common
+            than <constant>false</constant>.
+        </para>
+      </formalpara>
+      <formalpara>
+         <title>have_c99_vsnprintf=[true/false]</title>
+
+         <para>
+            Whether you have a <function>vsnprintf()</function> with C99 
+            semantics. (C99 semantics means returning the number of bytes 
+            that would have been written had the output buffer had enough 
+            space.) Defaults to <constant>false</constant>.
+         </para>
+      </formalpara>
+      <formalpara>
+         <title>have_c99_snprintf=[true/false]</title>
+
+         <para>
+            Whether you have a <function>snprintf()</function> with C99 
+            semantics. (C99 semantics means returning the number of bytes 
+            that would have been written had the output buffer had enough 
+            space.) Defaults to <constant>false</constant>.
+         </para>
+      </formalpara>
+
+    </refsect1>
+
+</refentry>
diff --git a/docs/reference/glib/file-name-encodings.png b/docs/reference/glib/file-name-encodings.png
new file mode 100644
index 0000000..7adbcea
--- /dev/null
+++ b/docs/reference/glib/file-name-encodings.png
Binary files differ
diff --git a/docs/reference/glib/file-name-encodings.sxd b/docs/reference/glib/file-name-encodings.sxd
new file mode 100644
index 0000000..46750dc
--- /dev/null
+++ b/docs/reference/glib/file-name-encodings.sxd
Binary files differ
diff --git a/docs/reference/glib/glib-docs.xml b/docs/reference/glib/glib-docs.xml
new file mode 100644
index 0000000..3ed1256
--- /dev/null
+++ b/docs/reference/glib/glib-docs.xml
@@ -0,0 +1,290 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN'
+                      'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd' [
+<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <bookinfo>
+    <title>GLib Reference Manual</title>
+    <releaseinfo>
+      for GLib &version;
+      The latest version of this documentation can be found on-line at
+      <ulink role="online-location" url="https://developer.gnome.org/glib/unstable/">https://developer.gnome.org/glib/unstable/</ulink>.
+    </releaseinfo>
+  </bookinfo>
+
+  <chapter id="glib">
+    <title>GLib Overview</title>
+    <para>
+      GLib is a general-purpose utility library, which provides many useful
+      data types, macros, type conversions, string utilities, file utilities,
+      a mainloop abstraction, and so on. It works on many UNIX-like platforms,
+      as well as Windows and OS X. GLib is released under the GNU Lesser
+      General Public License (GNU LGPL).
+    </para>
+
+    <xi:include href="building.xml" />
+    <xi:include href="cross.xml" />
+    <xi:include href="programming.xml" />
+    <xi:include href="xml/compiling.xml" />
+    <xi:include href="running.xml" />
+    <xi:include href="changes.xml" />
+    <xi:include href="resources.xml" />
+
+  </chapter>
+
+  <chapter id="glib-fundamentals">
+    <title>GLib Fundamentals</title>
+    <xi:include href="xml/version.xml" />
+    <xi:include href="xml/types.xml" />
+    <xi:include href="xml/macros.xml" />
+    <xi:include href="xml/type_conversion.xml" />
+    <xi:include href="xml/byte_order.xml" />
+    <xi:include href="xml/checkedmath.xml" />
+    <xi:include href="xml/numerical.xml" />
+    <xi:include href="xml/macros_misc.xml" />
+    <xi:include href="xml/atomic_operations.xml" />
+  </chapter>
+
+  <chapter id="glib-core">
+    <title>GLib Core Application Support</title>
+    <xi:include href="xml/main.xml" />
+    <xi:include href="xml/threads.xml" />
+    <xi:include href="xml/thread_pools.xml" />
+    <xi:include href="xml/async_queues.xml" />
+    <xi:include href="xml/modules.xml" />
+    <xi:include href="xml/memory.xml" />
+    <xi:include href="xml/memory_slices.xml" />
+    <xi:include href="xml/iochannels.xml" />
+    <xi:include href="xml/error_reporting.xml" />
+    <xi:include href="xml/warnings.xml" />
+    <xi:include href="xml/messages.xml" />
+  </chapter>
+
+  <chapter id="glib-utilities">
+    <title>GLib Utilities</title>
+    <xi:include href="xml/string_utils.xml" />
+    <xi:include href="xml/conversions.xml" />
+    <xi:include href="xml/unicode.xml" />
+    <xi:include href="xml/base64.xml" />
+    <xi:include href="xml/checksum.xml" />
+    <xi:include href="xml/hmac.xml" />
+    <xi:include href="xml/i18n.xml" />
+    <xi:include href="xml/date.xml" />
+    <xi:include href="xml/timezone.xml" />
+    <xi:include href="xml/date-time.xml" />
+    <xi:include href="xml/random_numbers.xml" />
+    <xi:include href="xml/hooks.xml" />
+    <xi:include href="xml/misc_utils.xml" />
+    <xi:include href="xml/scanner.xml" />
+    <xi:include href="xml/timers.xml" />
+    <xi:include href="xml/spawn.xml" />
+    <xi:include href="xml/fileutils.xml" />
+    <xi:include href="xml/gurifuncs.xml" />
+    <xi:include href="xml/ghostutils.xml" />
+    <xi:include href="xml/shell.xml" />
+    <xi:include href="xml/option.xml" />
+    <xi:include href="xml/patterns.xml" />
+    <xi:include href="xml/gregex.xml" />
+    <xi:include href="regex-syntax.xml" />
+    <xi:include href="xml/markup.xml" />
+    <xi:include href="xml/keyfile.xml" />
+    <xi:include href="xml/bookmarkfile.xml" />
+    <xi:include href="xml/testing.xml" />
+    <xi:include href="xml/gunix.xml" />
+    <xi:include href="xml/windows.xml" />
+    <xi:include href="xml/uuid.xml" />
+  </chapter>
+
+  <chapter id="glib-data-types">
+    <title>GLib Data Types</title>
+    <xi:include href="xml/linked_lists_double.xml" />
+    <xi:include href="xml/linked_lists_single.xml" />
+    <xi:include href="xml/queue.xml" />
+    <xi:include href="xml/sequence.xml" />
+    <xi:include href="xml/trash_stack.xml" />
+    <xi:include href="xml/hash_tables.xml" />
+    <xi:include href="xml/strings.xml" />
+    <xi:include href="xml/string_chunks.xml" />
+    <xi:include href="xml/arrays.xml" />
+    <xi:include href="xml/arrays_pointer.xml" />
+    <xi:include href="xml/arrays_byte.xml" />
+    <xi:include href="xml/trees-binary.xml" />
+    <xi:include href="xml/trees-nary.xml" />
+    <xi:include href="xml/quarks.xml" />
+    <xi:include href="xml/datalist.xml" />
+    <xi:include href="xml/datasets.xml" />
+    <xi:include href="xml/gvarianttype.xml"/>
+    <xi:include href="xml/gvariant.xml"/>
+    <xi:include href="gvariant-varargs.xml"/>
+    <xi:include href="gvariant-text.xml"/>
+    <xi:include href="xml/refcount.xml"/>
+    <xi:include href="xml/rcbox.xml"/>
+    <xi:include href="xml/arcbox.xml"/>
+    <xi:include href="xml/refstring.xml"/>
+  </chapter>
+
+  <chapter id="deprecated">
+    <title>Deprecated APIs</title>
+    <xi:include href="xml/threads-deprecated.xml"/>
+    <xi:include href="xml/caches.xml" />
+    <xi:include href="xml/relations.xml" />
+    <xi:include href="xml/completion.xml" />
+  </chapter>
+
+  <chapter id="tools">
+    <title>GLib Tools</title>
+    <xi:include href="glib-gettextize.xml" />
+  </chapter>
+
+  <chapter id="deprecated-tools">
+    <title>Deprecated Tools</title>
+    <xi:include href="gtester.xml" />
+    <xi:include href="gtester-report.xml" />
+  </chapter>
+
+  <index id="api-index-full">
+    <title>Index</title>
+    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-deprecated" role="deprecated">
+    <title>Index of deprecated symbols</title>
+    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-2" role="2.2">
+    <title>Index of new symbols in 2.2</title>
+    <xi:include href="xml/api-index-2.2.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-4" role="2.4">
+    <title>Index of new symbols in 2.4</title>
+    <xi:include href="xml/api-index-2.4.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-6" role="2.6">
+    <title>Index of new symbols in 2.6</title>
+    <xi:include href="xml/api-index-2.6.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-8" role="2.8">
+    <title>Index of new symbols in 2.8</title>
+    <xi:include href="xml/api-index-2.8.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-10" role="2.10">
+    <title>Index of new symbols in 2.10</title>
+    <xi:include href="xml/api-index-2.10.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-12" role="2.12">
+    <title>Index of new symbols in 2.12</title>
+    <xi:include href="xml/api-index-2.12.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-14" role="2.14">
+    <title>Index of new symbols in 2.14</title>
+    <xi:include href="xml/api-index-2.14.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-16" role="2.16">
+    <title>Index of new symbols in 2.16</title>
+    <xi:include href="xml/api-index-2.16.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-18" role="2.18">
+    <title>Index of new symbols in 2.18</title>
+    <xi:include href="xml/api-index-2.18.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-20" role="2.20">
+    <title>Index of new symbols in 2.20</title>
+    <xi:include href="xml/api-index-2.20.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-22" role="2.22">
+    <title>Index of new symbols in 2.22</title>
+    <xi:include href="xml/api-index-2.22.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-24" role="2.24">
+    <title>Index of new symbols in 2.24</title>
+    <xi:include href="xml/api-index-2.24.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-26" role="2.26">
+    <title>Index of new symbols in 2.26</title>
+    <xi:include href="xml/api-index-2.26.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-28" role="2.28">
+    <title>Index of new symbols in 2.28</title>
+    <xi:include href="xml/api-index-2.28.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-30" role="2.30">
+    <title>Index of new symbols in 2.30</title>
+    <xi:include href="xml/api-index-2.30.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-32" role="2.32">
+    <title>Index of new symbols in 2.32</title>
+    <xi:include href="xml/api-index-2.32.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-34" role="2.34">
+    <title>Index of new symbols in 2.34</title>
+    <xi:include href="xml/api-index-2.34.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-36" role="2.36">
+    <title>Index of new symbols in 2.36</title>
+    <xi:include href="xml/api-index-2.36.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-38" role="2.38">
+    <title>Index of new symbols in 2.38</title>
+    <xi:include href="xml/api-index-2.38.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-40" role="2.40">
+    <title>Index of new symbols in 2.40</title>
+    <xi:include href="xml/api-index-2.40.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-42" role="2.42">
+    <title>Index of new symbols in 2.42</title>
+    <xi:include href="xml/api-index-2.42.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-44" role="2.44">
+    <title>Index of new symbols in 2.44</title>
+    <xi:include href="xml/api-index-2.44.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-46" role="2.46">
+    <title>Index of new symbols in 2.46</title>
+    <xi:include href="xml/api-index-2.46.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-48" role="2.48">
+    <title>Index of new symbols in 2.48</title>
+    <xi:include href="xml/api-index-2.48.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-50" role="2.50">
+    <title>Index of new symbols in 2.50</title>
+    <xi:include href="xml/api-index-2.50.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-52" role="2.52">
+    <title>Index of new symbols in 2.52</title>
+    <xi:include href="xml/api-index-2.52.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-54" role="2.54">
+    <title>Index of new symbols in 2.54</title>
+    <xi:include href="xml/api-index-2.54.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-56" role="2.56">
+    <title>Index of new symbols in 2.56</title>
+    <xi:include href="xml/api-index-2.56.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-58" role="2.58">
+    <title>Index of new symbols in 2.58</title>
+    <xi:include href="xml/api-index-2.58.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-60" role="2.60">
+    <title>Index of new symbols in 2.60</title>
+    <xi:include href="xml/api-index-2.60.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-62" role="2.62">
+    <title>Index of new symbols in 2.62</title>
+    <xi:include href="xml/api-index-2.62.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-64" role="2.64">
+    <title>Index of new symbols in 2.64</title>
+    <xi:include href="xml/api-index-2.64.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-66" role="2.66">
+    <title>Index of new symbols in 2.66</title>
+    <xi:include href="xml/api-index-2.66.xml"><xi:fallback /></xi:include>
+  </index>
+
+  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+
+</book>
diff --git a/docs/reference/glib/glib-gettextize.xml b/docs/reference/glib/glib-gettextize.xml
new file mode 100644
index 0000000..f016b28
--- /dev/null
+++ b/docs/reference/glib/glib-gettextize.xml
@@ -0,0 +1,88 @@
+<refentry id="glib-gettextize" lang="en">
+
+<refentryinfo>
+<title>glib-gettextize</title>
+<productname>GLib</productname>
+<authorgroup>
+<author>
+<contrib>Developer</contrib>
+<firstname>Owen</firstname>
+<surname>Taylor</surname>
+</author>
+</authorgroup>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>glib-gettextize</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>glib-gettextize</refname>
+<refpurpose>gettext internationalization utility</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>glib-gettextize</command>
+<arg choice="opt" rep="repeat">OPTION</arg>
+<arg choice="opt">DIRECTORY</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>glib-gettextize</command> helps to prepare a source package for being
+internationalized through <application>gettext</application>. 
+It is a variant of the <command>gettextize</command> that ships with
+<application>gettext</application>. 
+</para>
+
+<para><command>glib-gettextize</command> differs
+from <command>gettextize</command> in that it doesn't create an
+<filename>intl/</filename> subdirectory and doesn't modify
+<filename>po/ChangeLog</filename> (note that newer versions of 
+<command>gettextize</command> behave like this when called with the
+<option>--no-changelog</option> option).
+</para>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>--help</option></term>
+<listitem><para>
+print help and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--version</option></term>
+<listitem><para>
+print version information and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-c</option>, <option>--copy</option></term>
+<listitem><para>
+copy files instead of making symlinks
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-f</option>, <option>--force</option></term>
+<listitem><para>
+force writing of new files even if old ones exist
+</para></listitem>
+</varlistentry>
+</variablelist>
+</refsect1>
+
+<refsect1><title>See also</title>
+<para>
+<citerefentry><refentrytitle>gettextize</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/docs/reference/glib/glib-overrides.txt b/docs/reference/glib/glib-overrides.txt
new file mode 100644
index 0000000..991fcf2
--- /dev/null
+++ b/docs/reference/glib/glib-overrides.txt
@@ -0,0 +1,294 @@
+# This file makes most of the thread related macros look like
+# functions, which they really were, if possible easy.
+
+<MACRO>
+<NAME>GLIB_DISABLE_DEPRECATION_WARNINGS</NAME>
+#ifdef GLIB_DISABLE_DEPRECATION_WARNINGS
+</MACRO>
+
+<MACRO>
+<NAME>G_ATOMIC_LOCK_FREE</NAME>
+#define G_ATOMIC_LOCK_FREE
+</MACRO>
+
+# default thread implementation
+
+<MACRO>
+<NAME>G_THREADS_IMPL_POSIX</NAME>
+#define G_THREADS_IMPL_POSIX
+</MACRO>
+
+<MACRO>
+<NAME>G_THREADS_IMPL_WIN32</NAME>
+#define G_THREADS_IMPL_NONE
+</MACRO>
+
+# threads supported?
+
+<FUNCTION>
+<NAME>g_thread_supported</NAME>
+<RETURNS>gboolean</RETURNS>
+</FUNCTION>
+
+# GMutex
+
+<FUNCTION>
+<NAME>g_mutex_new</NAME>
+<RETURNS>GMutex *</RETURNS>
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_mutex_lock</NAME>
+<RETURNS>void</RETURNS>
+GMutex *mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_mutex_trylock</NAME>
+<RETURNS>gboolean</RETURNS>
+GMutex *mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_mutex_unlock</NAME>
+<RETURNS>void</RETURNS>
+GMutex *mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_mutex_free</NAME>
+<RETURNS>void</RETURNS>
+GMutex *mutex
+</FUNCTION>
+
+# GStaticMutex
+
+<STRUCT>
+<NAME>GStaticMutex</NAME>
+</STRUCT>
+
+<MACRO>
+<NAME>G_STATIC_MUTEX_INIT</NAME>
+#define G_STATIC_MUTEX_INIT
+</MACRO>
+
+<FUNCTION>
+<NAME>g_static_mutex_lock</NAME>
+<RETURNS>void</RETURNS>
+GStaticMutex* mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_static_mutex_trylock</NAME>
+<RETURNS>gboolean</RETURNS>
+GStaticMutex* mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_static_mutex_unlock</NAME>
+<RETURNS>void</RETURNS>
+GStaticMutex* mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_static_mutex_get_mutex</NAME>
+<RETURNS>GMutex *</RETURNS>
+GStaticMutex* mutex
+</FUNCTION>
+
+# GThread
+
+<FUNCTION>
+<NAME>g_thread_yield</NAME>
+<RETURNS>void</RETURNS>
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_thread_create</NAME>
+<RETURNS>GThread *</RETURNS>
+GThreadFunc func
+gpointer data,
+gboolean joinable,
+GError **error
+</FUNCTION>
+
+# G_LOCK_* macros
+
+<MACRO>
+<NAME>G_LOCK_DEFINE</NAME>
+#define G_LOCK_DEFINE(name)    
+</MACRO>
+
+<MACRO>
+<NAME>G_LOCK_DEFINE_STATIC</NAME>
+#define G_LOCK_DEFINE_STATIC(name)
+</MACRO>
+
+<MACRO>
+<NAME>G_LOCK_EXTERN</NAME>
+#define G_LOCK_EXTERN(name)    
+</MACRO>
+
+<MACRO>
+<NAME>G_LOCK</NAME>
+#define G_LOCK(name)
+</MACRO>
+
+<MACRO>
+<NAME>G_UNLOCK</NAME>
+#define G_UNLOCK(name)
+</MACRO>
+
+<MACRO>
+<NAME>G_TRYLOCK</NAME>
+#define G_TRYLOCK(name)
+</MACRO>
+
+# GCond
+
+<FUNCTION>
+<NAME>g_cond_new</NAME>
+<RETURNS>GCond*</RETURNS>
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_cond_signal</NAME>
+<RETURNS>void</RETURNS>
+GCond *cond
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_cond_broadcast</NAME>
+<RETURNS>void</RETURNS>
+GCond *cond
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_cond_wait</NAME>
+<RETURNS>void</RETURNS>
+GCond *cond, GMutex *mutex
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_cond_timed_wait</NAME>
+<RETURNS>gboolean</RETURNS>
+GCond *cond, GMutex *mutex, GTimeVal *abs_time
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_cond_free</NAME>
+<RETURNS>void</RETURNS>
+GCond *cond
+</FUNCTION>
+
+# GPrivate
+<MACRO>
+<NAME>G_PRIVATE_INIT</NAME>
+#define G_PRIVATE_INIT(notify)
+</MACRO>
+
+# GStaticPrivate
+
+<MACRO>
+<NAME>G_STATIC_PRIVATE_INIT</NAME>
+#define G_STATIC_PRIVATE_INIT 
+</MACRO>
+
+# Definitions for different operating systems
+
+<MACRO>
+<NAME>G_OS_UNIX</NAME>
+#define G_OS_UNIX
+</MACRO>
+
+<MACRO>
+<NAME>G_OS_WIN32</NAME>
+#define G_OS_WIN32
+</MACRO>
+
+# g_ascii_isxxx
+
+<FUNCTION>
+<NAME>g_ascii_isalnum</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isalpha</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_iscntrl</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isdigit</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isgraph</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_islower</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isprint</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_ispunct</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isspace</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isupper</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_ascii_isxdigit</NAME>
+<RETURNS>gboolean</RETURNS>
+gchar c
+</FUNCTION>
+
+# g_atomic
+
+<FUNCTION>
+<NAME>g_atomic_int_inc</NAME>
+<RETURNS>void</RETURNS>
+gint *atomic
+</FUNCTION>
+
+<FUNCTION>
+<NAME>g_atomic_int_dec_and_test</NAME>
+<RETURNS>gboolean</RETURNS>
+gint *atomic
+</FUNCTION>
+
+<MACRO>
+<NAME>G_VA_COPY</NAME>
+#define G_VA_COPY(ap1,ap2)    
+</MACRO>
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
new file mode 100644
index 0000000..eed38b7
--- /dev/null
+++ b/docs/reference/glib/glib-sections.txt
@@ -0,0 +1,3825 @@
+<INCLUDE>glib.h</INCLUDE>
+
+<SECTION>
+<TITLE>Basic Types</TITLE>
+<FILE>types</FILE>
+gboolean
+gpointer
+gconstpointer
+gchar
+guchar
+
+<SUBSECTION>
+gint
+G_MININT
+G_MAXINT
+guint
+G_MAXUINT
+gshort
+G_MINSHORT
+G_MAXSHORT
+gushort
+G_MAXUSHORT
+glong
+G_MINLONG
+G_MAXLONG
+gulong
+G_MAXULONG
+
+<SUBSECTION>
+gint8
+G_MININT8
+G_MAXINT8
+guint8
+G_MAXUINT8
+gint16
+G_MININT16
+G_MAXINT16
+G_GINT16_MODIFIER
+G_GINT16_FORMAT
+guint16
+G_MAXUINT16
+G_GUINT16_FORMAT
+gint32
+G_MININT32
+G_MAXINT32
+G_GINT32_MODIFIER
+G_GINT32_FORMAT
+guint32
+G_MAXUINT32
+G_GUINT32_FORMAT
+gint64
+G_MININT64
+G_MAXINT64
+G_GINT64_MODIFIER
+G_GINT64_FORMAT
+G_GINT64_CONSTANT
+guint64
+G_MAXUINT64
+G_GUINT64_FORMAT
+G_GUINT64_CONSTANT
+
+<SUBSECTION>
+gfloat
+G_MINFLOAT
+G_MAXFLOAT
+gdouble
+G_MINDOUBLE
+G_MAXDOUBLE
+
+<SUBSECTION>
+gsize
+G_MAXSIZE
+G_GSIZE_MODIFIER
+G_GSIZE_FORMAT
+gssize
+G_MINSSIZE
+G_MAXSSIZE
+G_GSSIZE_MODIFIER
+G_GSSIZE_FORMAT
+goffset
+G_MINOFFSET
+G_MAXOFFSET
+G_GOFFSET_MODIFIER
+G_GOFFSET_FORMAT
+G_GOFFSET_CONSTANT
+
+<SUBSECTION>
+gintptr
+G_GINTPTR_MODIFIER
+G_GINTPTR_FORMAT
+guintptr
+G_GUINTPTR_FORMAT
+
+<SUBSECTION Private>
+GLIB_SIZEOF_SSIZE_T
+GLIB_SIZEOF_VOID_P
+GLIB_SIZEOF_LONG
+GLIB_SIZEOF_SIZE_T
+G_HAVE_GINT64
+</SECTION>
+
+<SECTION>
+<TITLE>Version Information</TITLE>
+<FILE>version</FILE>
+glib_major_version
+glib_minor_version
+glib_micro_version
+glib_binary_age
+glib_interface_age
+glib_check_version
+
+<SUBSECTION>
+GLIB_MAJOR_VERSION
+GLIB_MINOR_VERSION
+GLIB_MICRO_VERSION
+GLIB_CHECK_VERSION
+
+<SUBSECTION>
+GLIB_VERSION_2_26
+GLIB_VERSION_2_28
+GLIB_VERSION_2_30
+GLIB_VERSION_2_32
+GLIB_VERSION_2_34
+GLIB_VERSION_2_36
+GLIB_VERSION_2_38
+GLIB_VERSION_2_40
+GLIB_VERSION_2_42
+GLIB_VERSION_2_44
+GLIB_VERSION_2_46
+GLIB_VERSION_2_48
+GLIB_VERSION_2_50
+GLIB_VERSION_2_52
+GLIB_VERSION_2_54
+GLIB_VERSION_2_56
+GLIB_VERSION_2_58
+GLIB_VERSION_2_60
+GLIB_VERSION_2_62
+GLIB_VERSION_2_64
+GLIB_VERSION_2_66
+GLIB_VERSION_MIN_REQUIRED
+GLIB_VERSION_MAX_ALLOWED
+GLIB_DISABLE_DEPRECATION_WARNINGS
+
+<SUBSECTION Private>
+G_ENCODE_VERSION
+GLIB_AVAILABLE_ENUMERATOR_IN_2_26
+GLIB_AVAILABLE_ENUMERATOR_IN_2_28
+GLIB_AVAILABLE_ENUMERATOR_IN_2_30
+GLIB_AVAILABLE_ENUMERATOR_IN_2_32
+GLIB_AVAILABLE_ENUMERATOR_IN_2_34
+GLIB_AVAILABLE_ENUMERATOR_IN_2_36
+GLIB_AVAILABLE_ENUMERATOR_IN_2_38
+GLIB_AVAILABLE_ENUMERATOR_IN_2_40
+GLIB_AVAILABLE_ENUMERATOR_IN_2_42
+GLIB_AVAILABLE_ENUMERATOR_IN_2_44
+GLIB_AVAILABLE_ENUMERATOR_IN_2_46
+GLIB_AVAILABLE_ENUMERATOR_IN_2_48
+GLIB_AVAILABLE_ENUMERATOR_IN_2_50
+GLIB_AVAILABLE_ENUMERATOR_IN_2_52
+GLIB_AVAILABLE_ENUMERATOR_IN_2_54
+GLIB_AVAILABLE_ENUMERATOR_IN_2_56
+GLIB_AVAILABLE_ENUMERATOR_IN_2_58
+GLIB_AVAILABLE_ENUMERATOR_IN_2_60
+GLIB_AVAILABLE_ENUMERATOR_IN_2_62
+GLIB_AVAILABLE_ENUMERATOR_IN_2_64
+GLIB_AVAILABLE_ENUMERATOR_IN_2_66
+GLIB_AVAILABLE_IN_ALL
+GLIB_AVAILABLE_IN_2_26
+GLIB_AVAILABLE_IN_2_28
+GLIB_AVAILABLE_IN_2_30
+GLIB_AVAILABLE_IN_2_32
+GLIB_AVAILABLE_IN_2_34
+GLIB_AVAILABLE_IN_2_36
+GLIB_AVAILABLE_IN_2_38
+GLIB_AVAILABLE_IN_2_40
+GLIB_AVAILABLE_IN_2_42
+GLIB_AVAILABLE_IN_2_44
+GLIB_AVAILABLE_IN_2_46
+GLIB_AVAILABLE_IN_2_48
+GLIB_AVAILABLE_IN_2_50
+GLIB_AVAILABLE_IN_2_52
+GLIB_AVAILABLE_IN_2_54
+GLIB_AVAILABLE_IN_2_56
+GLIB_AVAILABLE_IN_2_58
+GLIB_AVAILABLE_IN_2_60
+GLIB_AVAILABLE_IN_2_62
+GLIB_AVAILABLE_IN_2_64
+GLIB_AVAILABLE_IN_2_66
+GLIB_AVAILABLE_MACRO_IN_2_26
+GLIB_AVAILABLE_MACRO_IN_2_28
+GLIB_AVAILABLE_MACRO_IN_2_30
+GLIB_AVAILABLE_MACRO_IN_2_32
+GLIB_AVAILABLE_MACRO_IN_2_34
+GLIB_AVAILABLE_MACRO_IN_2_36
+GLIB_AVAILABLE_MACRO_IN_2_38
+GLIB_AVAILABLE_MACRO_IN_2_40
+GLIB_AVAILABLE_MACRO_IN_2_42
+GLIB_AVAILABLE_MACRO_IN_2_44
+GLIB_AVAILABLE_MACRO_IN_2_46
+GLIB_AVAILABLE_MACRO_IN_2_48
+GLIB_AVAILABLE_MACRO_IN_2_50
+GLIB_AVAILABLE_MACRO_IN_2_52
+GLIB_AVAILABLE_MACRO_IN_2_54
+GLIB_AVAILABLE_MACRO_IN_2_56
+GLIB_AVAILABLE_MACRO_IN_2_58
+GLIB_AVAILABLE_MACRO_IN_2_60
+GLIB_AVAILABLE_MACRO_IN_2_62
+GLIB_AVAILABLE_MACRO_IN_2_64
+GLIB_AVAILABLE_MACRO_IN_2_66
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_64
+GLIB_AVAILABLE_STATIC_INLINE_IN_2_66
+GLIB_AVAILABLE_TYPE_IN_2_26
+GLIB_AVAILABLE_TYPE_IN_2_28
+GLIB_AVAILABLE_TYPE_IN_2_30
+GLIB_AVAILABLE_TYPE_IN_2_32
+GLIB_AVAILABLE_TYPE_IN_2_34
+GLIB_AVAILABLE_TYPE_IN_2_36
+GLIB_AVAILABLE_TYPE_IN_2_38
+GLIB_AVAILABLE_TYPE_IN_2_40
+GLIB_AVAILABLE_TYPE_IN_2_42
+GLIB_AVAILABLE_TYPE_IN_2_44
+GLIB_AVAILABLE_TYPE_IN_2_46
+GLIB_AVAILABLE_TYPE_IN_2_48
+GLIB_AVAILABLE_TYPE_IN_2_50
+GLIB_AVAILABLE_TYPE_IN_2_52
+GLIB_AVAILABLE_TYPE_IN_2_54
+GLIB_AVAILABLE_TYPE_IN_2_56
+GLIB_AVAILABLE_TYPE_IN_2_58
+GLIB_AVAILABLE_TYPE_IN_2_60
+GLIB_AVAILABLE_TYPE_IN_2_62
+GLIB_AVAILABLE_TYPE_IN_2_64
+GLIB_AVAILABLE_TYPE_IN_2_66
+GLIB_DEPRECATED_ENUMERATOR
+GLIB_DEPRECATED_ENUMERATOR_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_26
+GLIB_DEPRECATED_ENUMERATOR_IN_2_26_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_28
+GLIB_DEPRECATED_ENUMERATOR_IN_2_28_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_30
+GLIB_DEPRECATED_ENUMERATOR_IN_2_30_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_32
+GLIB_DEPRECATED_ENUMERATOR_IN_2_32_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_34
+GLIB_DEPRECATED_ENUMERATOR_IN_2_34_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_36
+GLIB_DEPRECATED_ENUMERATOR_IN_2_36_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_38
+GLIB_DEPRECATED_ENUMERATOR_IN_2_38_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_40
+GLIB_DEPRECATED_ENUMERATOR_IN_2_40_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_42
+GLIB_DEPRECATED_ENUMERATOR_IN_2_42_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_44
+GLIB_DEPRECATED_ENUMERATOR_IN_2_44_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_46
+GLIB_DEPRECATED_ENUMERATOR_IN_2_46_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_48
+GLIB_DEPRECATED_ENUMERATOR_IN_2_48_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_50
+GLIB_DEPRECATED_ENUMERATOR_IN_2_50_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_52
+GLIB_DEPRECATED_ENUMERATOR_IN_2_52_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_54
+GLIB_DEPRECATED_ENUMERATOR_IN_2_54_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_56
+GLIB_DEPRECATED_ENUMERATOR_IN_2_56_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_58
+GLIB_DEPRECATED_ENUMERATOR_IN_2_58_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_60
+GLIB_DEPRECATED_ENUMERATOR_IN_2_60_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_62
+GLIB_DEPRECATED_ENUMERATOR_IN_2_62_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_64
+GLIB_DEPRECATED_ENUMERATOR_IN_2_64_FOR
+GLIB_DEPRECATED_ENUMERATOR_IN_2_66
+GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR
+GLIB_DEPRECATED_IN_2_26
+GLIB_DEPRECATED_IN_2_26_FOR
+GLIB_DEPRECATED_IN_2_28
+GLIB_DEPRECATED_IN_2_28_FOR
+GLIB_DEPRECATED_IN_2_30
+GLIB_DEPRECATED_IN_2_30_FOR
+GLIB_DEPRECATED_IN_2_32
+GLIB_DEPRECATED_IN_2_32_FOR
+GLIB_DEPRECATED_IN_2_34
+GLIB_DEPRECATED_IN_2_34_FOR
+GLIB_DEPRECATED_IN_2_36
+GLIB_DEPRECATED_IN_2_36_FOR
+GLIB_DEPRECATED_IN_2_38
+GLIB_DEPRECATED_IN_2_38_FOR
+GLIB_DEPRECATED_IN_2_40
+GLIB_DEPRECATED_IN_2_40_FOR
+GLIB_DEPRECATED_IN_2_42
+GLIB_DEPRECATED_IN_2_42_FOR
+GLIB_DEPRECATED_IN_2_44
+GLIB_DEPRECATED_IN_2_44_FOR
+GLIB_DEPRECATED_IN_2_46
+GLIB_DEPRECATED_IN_2_46_FOR
+GLIB_DEPRECATED_IN_2_48
+GLIB_DEPRECATED_IN_2_48_FOR
+GLIB_DEPRECATED_IN_2_50
+GLIB_DEPRECATED_IN_2_50_FOR
+GLIB_DEPRECATED_IN_2_52
+GLIB_DEPRECATED_IN_2_52_FOR
+GLIB_DEPRECATED_IN_2_54
+GLIB_DEPRECATED_IN_2_54_FOR
+GLIB_DEPRECATED_IN_2_56
+GLIB_DEPRECATED_IN_2_56_FOR
+GLIB_DEPRECATED_IN_2_58
+GLIB_DEPRECATED_IN_2_58_FOR
+GLIB_DEPRECATED_IN_2_60
+GLIB_DEPRECATED_IN_2_60_FOR
+GLIB_DEPRECATED_IN_2_62
+GLIB_DEPRECATED_IN_2_62_FOR
+GLIB_DEPRECATED_IN_2_64
+GLIB_DEPRECATED_IN_2_64_FOR
+GLIB_DEPRECATED_IN_2_66
+GLIB_DEPRECATED_IN_2_66_FOR
+GLIB_DEPRECATED_MACRO
+GLIB_DEPRECATED_MACRO_FOR
+GLIB_DEPRECATED_MACRO_IN_2_26
+GLIB_DEPRECATED_MACRO_IN_2_26_FOR
+GLIB_DEPRECATED_MACRO_IN_2_28
+GLIB_DEPRECATED_MACRO_IN_2_28_FOR
+GLIB_DEPRECATED_MACRO_IN_2_30
+GLIB_DEPRECATED_MACRO_IN_2_30_FOR
+GLIB_DEPRECATED_MACRO_IN_2_32
+GLIB_DEPRECATED_MACRO_IN_2_32_FOR
+GLIB_DEPRECATED_MACRO_IN_2_34
+GLIB_DEPRECATED_MACRO_IN_2_34_FOR
+GLIB_DEPRECATED_MACRO_IN_2_36
+GLIB_DEPRECATED_MACRO_IN_2_36_FOR
+GLIB_DEPRECATED_MACRO_IN_2_38
+GLIB_DEPRECATED_MACRO_IN_2_38_FOR
+GLIB_DEPRECATED_MACRO_IN_2_40
+GLIB_DEPRECATED_MACRO_IN_2_40_FOR
+GLIB_DEPRECATED_MACRO_IN_2_42
+GLIB_DEPRECATED_MACRO_IN_2_42_FOR
+GLIB_DEPRECATED_MACRO_IN_2_44
+GLIB_DEPRECATED_MACRO_IN_2_44_FOR
+GLIB_DEPRECATED_MACRO_IN_2_46
+GLIB_DEPRECATED_MACRO_IN_2_46_FOR
+GLIB_DEPRECATED_MACRO_IN_2_48
+GLIB_DEPRECATED_MACRO_IN_2_48_FOR
+GLIB_DEPRECATED_MACRO_IN_2_50
+GLIB_DEPRECATED_MACRO_IN_2_50_FOR
+GLIB_DEPRECATED_MACRO_IN_2_52
+GLIB_DEPRECATED_MACRO_IN_2_52_FOR
+GLIB_DEPRECATED_MACRO_IN_2_54
+GLIB_DEPRECATED_MACRO_IN_2_54_FOR
+GLIB_DEPRECATED_MACRO_IN_2_56
+GLIB_DEPRECATED_MACRO_IN_2_56_FOR
+GLIB_DEPRECATED_MACRO_IN_2_58
+GLIB_DEPRECATED_MACRO_IN_2_58_FOR
+GLIB_DEPRECATED_MACRO_IN_2_60
+GLIB_DEPRECATED_MACRO_IN_2_60_FOR
+GLIB_DEPRECATED_MACRO_IN_2_62
+GLIB_DEPRECATED_MACRO_IN_2_62_FOR
+GLIB_DEPRECATED_MACRO_IN_2_64
+GLIB_DEPRECATED_MACRO_IN_2_64_FOR
+GLIB_DEPRECATED_MACRO_IN_2_66
+GLIB_DEPRECATED_MACRO_IN_2_66_FOR
+GLIB_DEPRECATED_TYPE
+GLIB_DEPRECATED_TYPE_FOR
+GLIB_DEPRECATED_TYPE_IN_2_26
+GLIB_DEPRECATED_TYPE_IN_2_26_FOR
+GLIB_DEPRECATED_TYPE_IN_2_28
+GLIB_DEPRECATED_TYPE_IN_2_28_FOR
+GLIB_DEPRECATED_TYPE_IN_2_30
+GLIB_DEPRECATED_TYPE_IN_2_30_FOR
+GLIB_DEPRECATED_TYPE_IN_2_32
+GLIB_DEPRECATED_TYPE_IN_2_32_FOR
+GLIB_DEPRECATED_TYPE_IN_2_34
+GLIB_DEPRECATED_TYPE_IN_2_34_FOR
+GLIB_DEPRECATED_TYPE_IN_2_36
+GLIB_DEPRECATED_TYPE_IN_2_36_FOR
+GLIB_DEPRECATED_TYPE_IN_2_38
+GLIB_DEPRECATED_TYPE_IN_2_38_FOR
+GLIB_DEPRECATED_TYPE_IN_2_40
+GLIB_DEPRECATED_TYPE_IN_2_40_FOR
+GLIB_DEPRECATED_TYPE_IN_2_42
+GLIB_DEPRECATED_TYPE_IN_2_42_FOR
+GLIB_DEPRECATED_TYPE_IN_2_44
+GLIB_DEPRECATED_TYPE_IN_2_44_FOR
+GLIB_DEPRECATED_TYPE_IN_2_46
+GLIB_DEPRECATED_TYPE_IN_2_46_FOR
+GLIB_DEPRECATED_TYPE_IN_2_48
+GLIB_DEPRECATED_TYPE_IN_2_48_FOR
+GLIB_DEPRECATED_TYPE_IN_2_50
+GLIB_DEPRECATED_TYPE_IN_2_50_FOR
+GLIB_DEPRECATED_TYPE_IN_2_52
+GLIB_DEPRECATED_TYPE_IN_2_52_FOR
+GLIB_DEPRECATED_TYPE_IN_2_54
+GLIB_DEPRECATED_TYPE_IN_2_54_FOR
+GLIB_DEPRECATED_TYPE_IN_2_56
+GLIB_DEPRECATED_TYPE_IN_2_56_FOR
+GLIB_DEPRECATED_TYPE_IN_2_58
+GLIB_DEPRECATED_TYPE_IN_2_58_FOR
+GLIB_DEPRECATED_TYPE_IN_2_60
+GLIB_DEPRECATED_TYPE_IN_2_60_FOR
+GLIB_DEPRECATED_TYPE_IN_2_62
+GLIB_DEPRECATED_TYPE_IN_2_62_FOR
+GLIB_DEPRECATED_TYPE_IN_2_64
+GLIB_DEPRECATED_TYPE_IN_2_64_FOR
+GLIB_DEPRECATED_TYPE_IN_2_66
+GLIB_DEPRECATED_TYPE_IN_2_66_FOR
+GLIB_VERSION_CUR_STABLE
+GLIB_VERSION_PREV_STABLE
+</SECTION>
+
+<SECTION>
+<TITLE>Standard Macros</TITLE>
+<FILE>macros</FILE>
+<SUBSECTION>
+G_OS_WIN32
+G_OS_UNIX
+
+<SUBSECTION>
+G_DIR_SEPARATOR
+G_DIR_SEPARATOR_S
+G_IS_DIR_SEPARATOR
+G_SEARCHPATH_SEPARATOR
+G_SEARCHPATH_SEPARATOR_S
+
+<SUBSECTION>
+TRUE
+FALSE
+
+<SUBSECTION>
+NULL
+
+<SUBSECTION>
+MIN
+MAX
+
+<SUBSECTION>
+ABS
+CLAMP
+G_APPROX_VALUE
+
+<SUBSECTION>
+G_SIZEOF_MEMBER
+G_STRUCT_MEMBER
+G_STRUCT_MEMBER_P
+G_STRUCT_OFFSET
+
+<SUBSECTION>
+G_MEM_ALIGN
+
+<SUBSECTION>
+G_ALIGNOF
+
+<SUBSECTION>
+G_CONST_RETURN
+
+<SUBSECTION>
+G_N_ELEMENTS
+</SECTION>
+
+<SECTION>
+<TITLE>Type Conversion Macros</TITLE>
+<FILE>type_conversion</FILE>
+GINT_TO_POINTER
+GPOINTER_TO_INT
+
+<SUBSECTION>
+GUINT_TO_POINTER
+GPOINTER_TO_UINT
+GSIZE_TO_POINTER
+GPOINTER_TO_SIZE
+</SECTION>
+
+<SECTION>
+<TITLE>Byte Order Macros</TITLE>
+<FILE>byte_order</FILE>
+G_BYTE_ORDER
+G_LITTLE_ENDIAN
+G_BIG_ENDIAN
+G_PDP_ENDIAN
+
+<SUBSECTION>
+g_htonl
+g_htons
+g_ntohl
+g_ntohs
+
+<SUBSECTION>
+GINT_FROM_BE
+GINT_FROM_LE
+GINT_TO_BE
+GINT_TO_LE
+
+<SUBSECTION>
+GUINT_FROM_BE
+GUINT_FROM_LE
+GUINT_TO_BE
+GUINT_TO_LE
+
+<SUBSECTION>
+GLONG_FROM_BE
+GLONG_FROM_LE
+GLONG_TO_BE
+GLONG_TO_LE
+
+<SUBSECTION>
+GULONG_FROM_BE
+GULONG_FROM_LE
+GULONG_TO_BE
+GULONG_TO_LE
+
+<SUBSECTION>
+GSIZE_FROM_BE
+GSIZE_FROM_LE
+GSIZE_TO_BE
+GSIZE_TO_LE
+
+<SUBSECTION>
+GSSIZE_FROM_BE
+GSSIZE_FROM_LE
+GSSIZE_TO_BE
+GSSIZE_TO_LE
+
+<SUBSECTION>
+GINT16_FROM_BE
+GINT16_FROM_LE
+GINT16_TO_BE
+GINT16_TO_LE
+
+<SUBSECTION>
+GUINT16_FROM_BE
+GUINT16_FROM_LE
+GUINT16_TO_BE
+GUINT16_TO_LE
+
+<SUBSECTION>
+GINT32_FROM_BE
+GINT32_FROM_LE
+GINT32_TO_BE
+GINT32_TO_LE
+
+<SUBSECTION>
+GUINT32_FROM_BE
+GUINT32_FROM_LE
+GUINT32_TO_BE
+GUINT32_TO_LE
+
+<SUBSECTION>
+GINT64_FROM_BE
+GINT64_FROM_LE
+GINT64_TO_BE
+GINT64_TO_LE
+
+<SUBSECTION>
+GUINT64_FROM_BE
+GUINT64_FROM_LE
+GUINT64_TO_BE
+GUINT64_TO_LE
+
+<SUBSECTION>
+GUINT16_SWAP_BE_PDP
+GUINT16_SWAP_LE_BE
+GUINT16_SWAP_LE_PDP
+
+<SUBSECTION>
+GUINT32_SWAP_BE_PDP
+GUINT32_SWAP_LE_BE
+GUINT32_SWAP_LE_PDP
+
+<SUBSECTION>
+GUINT64_SWAP_LE_BE
+
+<SUBSECTION Private>
+GUINT16_SWAP_LE_BE_CONSTANT
+GUINT32_SWAP_LE_BE_CONSTANT
+GUINT64_SWAP_LE_BE_CONSTANT
+GUINT16_SWAP_LE_BE_IA32
+GUINT32_SWAP_LE_BE_IA32
+GUINT64_SWAP_LE_BE_IA32
+GUINT16_SWAP_LE_BE_IA64
+GUINT32_SWAP_LE_BE_IA64
+GUINT64_SWAP_LE_BE_IA64
+GUINT32_SWAP_LE_BE_X86_64
+GUINT64_SWAP_LE_BE_X86_64
+
+</SECTION>
+
+<SECTION>
+<TITLE>Bounds-checked integer arithmetic</TITLE>
+<FILE>checkedmath</FILE>
+g_uint_checked_add
+g_uint_checked_mul
+g_uint64_checked_add
+g_uint64_checked_mul
+g_size_checked_add
+g_size_checked_mul
+</SECTION>
+
+<SECTION>
+<TITLE>Numerical Definitions</TITLE>
+<FILE>numerical</FILE>
+G_IEEE754_FLOAT_BIAS
+G_IEEE754_DOUBLE_BIAS
+GFloatIEEE754
+GDoubleIEEE754
+
+<SUBSECTION>
+G_E
+G_LN2
+G_LN10
+G_PI
+G_PI_2
+G_PI_4
+G_SQRT2
+G_LOG_2_BASE_10
+</SECTION>
+
+<SECTION>
+<TITLE>Miscellaneous Macros</TITLE>
+<FILE>macros_misc</FILE>
+G_INLINE_FUNC
+
+<SUBSECTION>
+g_auto
+g_autoptr
+g_autofree
+g_autolist
+g_autoslist
+g_autoqueue
+G_DEFINE_AUTOPTR_CLEANUP_FUNC
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC
+G_DEFINE_AUTO_CLEANUP_FREE_FUNC
+
+<SUBSECTION>
+G_STMT_START
+G_STMT_END
+
+<SUBSECTION>
+G_BEGIN_DECLS
+G_END_DECLS
+
+<SUBSECTION>
+G_VA_COPY
+
+<SUBSECTION>
+G_STRINGIFY
+G_PASTE
+G_STATIC_ASSERT
+G_STATIC_ASSERT_EXPR
+
+<SUBSECTION>
+G_GNUC_CHECK_VERSION
+G_GNUC_EXTENSION
+G_GNUC_CONST
+G_GNUC_PURE
+G_GNUC_MALLOC
+G_GNUC_ALLOC_SIZE
+G_GNUC_ALLOC_SIZE2
+G_GNUC_DEPRECATED
+G_GNUC_DEPRECATED_FOR
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+G_GNUC_END_IGNORE_DEPRECATIONS
+G_GNUC_NORETURN
+G_GNUC_FALLTHROUGH
+G_GNUC_UNUSED
+G_GNUC_PRINTF
+G_GNUC_SCANF
+G_GNUC_STRFTIME
+G_GNUC_FORMAT
+G_GNUC_NULL_TERMINATED
+G_GNUC_WARN_UNUSED_RESULT
+G_GNUC_FUNCTION
+G_GNUC_PRETTY_FUNCTION
+G_GNUC_NO_INLINE
+G_GNUC_NO_INSTRUMENT
+G_HAVE_GNUC_VISIBILITY
+G_GNUC_INTERNAL
+G_GNUC_MAY_ALIAS
+
+<SUBSECTION>
+G_DEPRECATED
+G_DEPRECATED_FOR
+G_UNAVAILABLE
+
+<SUBSECTION>
+G_LIKELY
+G_UNLIKELY
+
+<SUBSECTION>
+G_STRLOC
+G_STRFUNC
+
+<SUBSECTION Private>
+GLIB_VAR
+G_STRINGIFY_ARG
+G_PASTE_ARGS
+G_HAVE_INLINE
+G_CAN_INLINE
+inline
+G_HAVE___INLINE
+G_HAVE___INLINE__
+G_INLINE_DEFINE_NEEDED
+G_HAVE_GNUC_VARARGS
+G_HAVE_ISO_VARARGS
+G_HAVE_GROWING_STACK
+G_VA_COPY_AS_ARRAY
+GLIB_DEPRECATED
+GLIB_DEPRECATED_FOR
+GLIB_UNAVAILABLE
+GLIB_UNAVAILABLE_ENUMERATOR
+GLIB_UNAVAILABLE_MACRO
+GLIB_UNAVAILABLE_STATIC_INLINE
+GLIB_UNAVAILABLE_TYPE
+G_ANALYZER_ANALYZING
+G_ANALYZER_NORETURN
+g_autoptr_cleanup_generic_gfree
+g_has_typeof
+g_macro__has_attribute
+g_macro__has_builtin
+g_macro__has_feature
+</SECTION>
+
+<SECTION>
+<TITLE>Error Reporting</TITLE>
+<FILE>error_reporting</FILE>
+GError
+g_error_new
+g_error_new_literal
+g_error_new_valist
+g_error_free
+g_error_copy
+g_error_matches
+g_set_error
+g_set_error_literal
+g_propagate_error
+g_clear_error
+g_prefix_error
+g_propagate_prefixed_error
+</SECTION>
+
+<SECTION>
+<TITLE>The Main Event Loop</TITLE>
+<FILE>main</FILE>
+GMainLoop
+g_main_loop_new
+g_main_loop_ref
+g_main_loop_unref
+g_main_loop_run
+g_main_loop_quit
+g_main_loop_is_running
+g_main_loop_get_context
+g_main_new
+g_main_destroy
+g_main_run
+g_main_quit
+g_main_is_running
+
+<SUBSECTION>
+G_PRIORITY_HIGH
+G_PRIORITY_DEFAULT
+G_PRIORITY_HIGH_IDLE
+G_PRIORITY_DEFAULT_IDLE
+G_PRIORITY_LOW
+
+<SUBSECTION>
+G_SOURCE_CONTINUE
+G_SOURCE_REMOVE
+
+<SUBSECTION>
+GMainContext
+g_main_context_new
+g_main_context_ref
+g_main_context_unref
+g_main_context_default
+g_main_context_iteration
+g_main_iteration
+g_main_context_pending
+g_main_pending
+g_main_context_find_source_by_id
+g_main_context_find_source_by_user_data
+g_main_context_find_source_by_funcs_user_data
+g_main_context_wakeup
+g_main_context_acquire
+g_main_context_release
+g_main_context_is_owner
+g_main_context_wait
+g_main_context_prepare
+g_main_context_query
+g_main_context_check
+g_main_context_dispatch
+g_main_context_set_poll_func
+g_main_context_get_poll_func
+GPollFunc
+g_main_context_add_poll
+g_main_context_remove_poll
+g_main_depth
+g_main_current_source
+g_main_set_poll_func
+g_main_context_invoke
+g_main_context_invoke_full
+
+<SUBSECTION>
+GMainContextPusher
+g_main_context_pusher_new
+g_main_context_pusher_free
+
+<SUBSECTION>
+g_main_context_get_thread_default
+g_main_context_ref_thread_default
+g_main_context_push_thread_default
+g_main_context_pop_thread_default
+
+<SUBSECTION>
+g_timeout_source_new
+g_timeout_source_new_seconds
+g_timeout_add
+g_timeout_add_full
+g_timeout_add_seconds
+g_timeout_add_seconds_full
+
+<SUBSECTION>
+g_idle_source_new
+g_idle_add
+g_idle_add_full
+g_idle_remove_by_data
+
+<SUBSECTION>
+GPid
+G_PID_FORMAT
+GChildWatchFunc
+g_child_watch_source_new
+g_child_watch_add
+g_child_watch_add_full
+
+<SUBSECTION>
+GPollFD
+g_poll
+G_POLLFD_FORMAT
+
+<SUBSECTION>
+GSource
+GSourceDummyMarshal
+GSourceFuncs
+GSourceDisposeFunc
+GSourceCallbackFuncs
+g_source_new
+g_source_ref
+g_source_unref
+g_source_set_funcs
+g_source_set_dispose_function
+g_source_attach
+g_source_destroy
+g_source_is_destroyed
+g_source_set_priority
+g_source_get_priority
+g_source_set_can_recurse
+g_source_get_can_recurse
+g_source_get_id
+g_source_get_name
+g_source_set_name
+g_source_set_name_by_id
+g_source_get_context
+g_source_set_callback
+GSourceFunc
+G_SOURCE_FUNC
+g_source_set_callback_indirect
+g_source_set_ready_time
+g_source_get_ready_time
+g_source_add_unix_fd
+g_source_remove_unix_fd
+g_source_modify_unix_fd
+g_source_query_unix_fd
+g_source_add_poll
+g_source_remove_poll
+g_source_add_child_source
+g_source_remove_child_source
+g_source_get_time
+g_source_get_current_time
+g_source_remove
+g_source_remove_by_funcs_user_data
+g_source_remove_by_user_data
+GClearHandleFunc
+g_clear_handle_id
+
+<SUBSECTION Private>
+GLIB_HAVE_ALLOCA_H
+alloca
+GLIB_USING_SYSTEM_PRINTF
+GLIB_SYSDEF_POLLERR
+GLIB_SYSDEF_POLLHUP
+GLIB_SYSDEF_POLLIN
+GLIB_SYSDEF_POLLNVAL
+GLIB_SYSDEF_POLLOUT
+GLIB_SYSDEF_POLLPRI
+GLIB_SYSDEF_AF_INET
+GLIB_SYSDEF_AF_INET6
+GLIB_SYSDEF_AF_UNIX
+GLIB_SYSDEF_MSG_DONTROUTE
+GLIB_SYSDEF_MSG_OOB
+GLIB_SYSDEF_MSG_PEEK
+G_WIN32_MSG_HANDLE
+g_idle_funcs
+g_timeout_funcs
+g_child_watch_funcs
+g_unix_signal_funcs
+g_unix_fd_source_funcs
+GSourcePrivate
+</SECTION>
+
+
+<SECTION>
+<TITLE>Threads</TITLE>
+<FILE>threads</FILE>
+<SUBSECTION>
+G_THREAD_ERROR
+GThreadError
+
+<SUBSECTION>
+GThread
+GThreadFunc
+g_thread_new
+g_thread_try_new
+g_thread_ref
+g_thread_unref
+g_thread_join
+g_thread_yield
+g_thread_exit
+g_thread_self
+
+<SUBSECTION>
+GMutex
+g_mutex_init
+g_mutex_clear
+g_mutex_lock
+g_mutex_trylock
+g_mutex_unlock
+
+<SUBSECTION>
+GMutexLocker
+g_mutex_locker_new
+g_mutex_locker_free
+
+<SUBSECTION>
+G_LOCK_DEFINE
+G_LOCK_DEFINE_STATIC
+G_LOCK_EXTERN
+G_LOCK
+G_TRYLOCK
+G_UNLOCK
+
+<SUBSECTION>
+GRecMutex
+g_rec_mutex_init
+g_rec_mutex_clear
+g_rec_mutex_lock
+g_rec_mutex_trylock
+g_rec_mutex_unlock
+
+<SUBSECTION>
+GRecMutexLocker
+g_rec_mutex_locker_new
+g_rec_mutex_locker_free
+
+<SUBSECTION>
+GRWLockWriterLocker
+g_rw_lock_writer_locker_new
+g_rw_lock_writer_locker_free
+
+<SUBSECTION>
+GRWLockReaderLocker
+g_rw_lock_reader_locker_new
+g_rw_lock_reader_locker_free
+
+<SUBSECTION>
+GRWLock
+g_rw_lock_init
+g_rw_lock_clear
+g_rw_lock_writer_lock
+g_rw_lock_writer_trylock
+g_rw_lock_writer_unlock
+g_rw_lock_reader_lock
+g_rw_lock_reader_trylock
+g_rw_lock_reader_unlock
+
+<SUBSECTION>
+GCond
+g_cond_init
+g_cond_clear
+g_cond_wait
+g_cond_timed_wait
+g_cond_wait_until
+g_cond_signal
+g_cond_broadcast
+
+<SUBSECTION>
+GPrivate
+G_PRIVATE_INIT
+g_private_get
+g_private_set
+g_private_replace
+
+<SUBSECTION>
+GOnce
+GOnceStatus
+G_ONCE_INIT
+g_once
+g_once_init_enter
+g_once_init_leave
+
+<SUBSECTION>
+g_bit_lock
+g_bit_trylock
+g_bit_unlock
+g_pointer_bit_lock
+g_pointer_bit_trylock
+g_pointer_bit_unlock
+
+<SUBSECTION>
+g_get_num_processors
+
+<SUBSECTION Private>
+G_LOCK_NAME
+atexit
+g_thread_error_quark
+g_once_impl
+</SECTION>
+
+<SECTION>
+<TITLE>Deprecated Thread APIs</TITLE>
+<FILE>threads-deprecated</FILE>
+
+<SUBSECTION>
+G_THREADS_IMPL_POSIX
+G_THREADS_IMPL_WIN32
+
+<SUBSECTION>
+g_thread_init
+g_thread_supported
+g_thread_get_initialized
+
+<SUBSECTION>
+g_thread_create
+g_thread_create_full
+GThreadPriority
+g_thread_set_priority
+g_thread_foreach
+
+<SUBSECTION>
+g_mutex_new
+g_mutex_free
+g_cond_new
+g_cond_free
+g_private_new
+
+<SUBSECTION>
+GStaticMutex
+G_STATIC_MUTEX_INIT
+g_static_mutex_init
+g_static_mutex_lock
+g_static_mutex_trylock
+g_static_mutex_unlock
+g_static_mutex_get_mutex
+g_static_mutex_free
+
+<SUBSECTION>
+GStaticRecMutex
+G_STATIC_REC_MUTEX_INIT
+g_static_rec_mutex_init
+g_static_rec_mutex_lock
+g_static_rec_mutex_trylock
+g_static_rec_mutex_unlock
+g_static_rec_mutex_lock_full
+g_static_rec_mutex_unlock_full
+g_static_rec_mutex_free
+
+<SUBSECTION>
+GStaticRWLock
+G_STATIC_RW_LOCK_INIT
+g_static_rw_lock_init
+g_static_rw_lock_reader_lock
+g_static_rw_lock_reader_trylock
+g_static_rw_lock_reader_unlock
+g_static_rw_lock_writer_lock
+g_static_rw_lock_writer_trylock
+g_static_rw_lock_writer_unlock
+g_static_rw_lock_free
+
+<SUBSECTION>
+GStaticPrivate
+G_STATIC_PRIVATE_INIT
+g_static_private_init
+g_static_private_get
+g_static_private_set
+g_static_private_free
+
+<SUBSECTION Private>
+GThreadFunctions
+g_thread_init_with_errorcheck_mutexes
+G_THREADS_ENABLED
+g_static_mutex_get_mutex_impl
+g_thread_use_default_impl
+g_threads_got_initialized
+g_thread_functions_for_glib_use
+g_thread_gettime
+g_once_init_enter_impl
+</SECTION>
+
+<SECTION>
+<TITLE>Thread Pools</TITLE>
+<FILE>thread_pools</FILE>
+GThreadPool
+g_thread_pool_new
+g_thread_pool_push
+g_thread_pool_set_max_threads
+g_thread_pool_get_max_threads
+g_thread_pool_get_num_threads
+g_thread_pool_unprocessed
+g_thread_pool_free
+g_thread_pool_set_max_unused_threads
+g_thread_pool_get_max_unused_threads
+g_thread_pool_get_num_unused_threads
+g_thread_pool_stop_unused_threads
+g_thread_pool_set_sort_function
+g_thread_pool_set_max_idle_time
+g_thread_pool_get_max_idle_time
+g_thread_pool_move_to_front
+</SECTION>
+
+<SECTION>
+<TITLE>Asynchronous Queues</TITLE>
+<FILE>async_queues</FILE>
+GAsyncQueue
+g_async_queue_new
+g_async_queue_new_full
+g_async_queue_ref
+g_async_queue_unref
+g_async_queue_push
+g_async_queue_push_sorted
+g_async_queue_push_front
+g_async_queue_remove
+g_async_queue_pop
+g_async_queue_try_pop
+g_async_queue_timeout_pop
+g_async_queue_length
+g_async_queue_sort
+
+<SUBSECTION>
+g_async_queue_lock
+g_async_queue_unlock
+g_async_queue_ref_unlocked
+g_async_queue_unref_and_unlock
+g_async_queue_push_unlocked
+g_async_queue_push_sorted_unlocked
+g_async_queue_push_front_unlocked
+g_async_queue_remove_unlocked
+g_async_queue_pop_unlocked
+g_async_queue_try_pop_unlocked
+g_async_queue_timeout_pop_unlocked
+g_async_queue_length_unlocked
+g_async_queue_sort_unlocked
+
+<SUBSECTION>
+g_async_queue_timed_pop
+g_async_queue_timed_pop_unlocked
+</SECTION>
+
+<SECTION>
+<TITLE>Atomic Operations</TITLE>
+<FILE>atomic_operations</FILE>
+G_ATOMIC_LOCK_FREE
+
+<SUBSECTION>
+g_atomic_int_get
+g_atomic_int_set
+g_atomic_int_inc
+g_atomic_int_dec_and_test
+g_atomic_int_compare_and_exchange
+g_atomic_int_add
+g_atomic_int_and
+g_atomic_int_or
+g_atomic_int_xor
+
+<SUBSECTION>
+g_atomic_pointer_get
+g_atomic_pointer_set
+g_atomic_pointer_compare_and_exchange
+g_atomic_pointer_add
+g_atomic_pointer_and
+g_atomic_pointer_or
+g_atomic_pointer_xor
+
+<SUBSECTION>
+g_atomic_int_exchange_and_add
+</SECTION>
+
+<SECTION>
+<TITLE>IO Channels</TITLE>
+<FILE>iochannels</FILE>
+GIOChannel
+
+<SUBSECTION>
+g_io_channel_unix_new
+g_io_channel_unix_get_fd
+g_io_channel_win32_new_fd
+g_io_channel_win32_new_socket
+g_io_channel_win32_new_messages
+
+<SUBSECTION>
+g_io_channel_init
+
+<SUBSECTION>
+g_io_channel_new_file
+g_io_channel_read_chars
+g_io_channel_read_unichar
+g_io_channel_read_line
+g_io_channel_read_line_string
+g_io_channel_read_to_end
+g_io_channel_write_chars
+g_io_channel_write_unichar
+g_io_channel_flush
+g_io_channel_seek_position
+GSeekType
+g_io_channel_shutdown
+
+<SUBSECTION>
+GIOStatus
+GIOChannelError
+G_IO_CHANNEL_ERROR
+g_io_channel_error_from_errno
+
+<SUBSECTION>
+g_io_channel_ref
+g_io_channel_unref
+
+<SUBSECTION>
+g_io_create_watch
+g_io_add_watch
+g_io_add_watch_full
+GIOCondition
+GIOFunc
+
+<SUBSECTION>
+GIOFuncs
+
+<SUBSECTION>
+g_io_channel_get_buffer_size
+g_io_channel_set_buffer_size
+g_io_channel_get_buffer_condition
+g_io_channel_get_flags
+g_io_channel_set_flags
+GIOFlags
+g_io_channel_get_line_term
+g_io_channel_set_line_term
+g_io_channel_get_buffered
+g_io_channel_set_buffered
+g_io_channel_get_encoding
+g_io_channel_set_encoding
+g_io_channel_get_close_on_unref
+g_io_channel_set_close_on_unref
+
+<SUBSECTION>
+g_io_channel_read
+GIOError
+g_io_channel_write
+g_io_channel_seek
+g_io_channel_close
+
+<SUBSECTION Private>
+g_io_channel_win32_poll
+g_io_channel_win32_make_pollfd
+g_io_channel_win32_get_fd
+g_io_channel_win32_new_stream_socket
+g_io_channel_win32_set_debug
+g_io_channel_error_quark
+g_io_watch_funcs
+G_IO_FLAG_IS_WRITEABLE
+</SECTION>
+
+<SECTION>
+<TITLE>Memory Allocation</TITLE>
+<FILE>memory</FILE>
+g_new
+g_new0
+g_renew
+g_try_new
+g_try_new0
+g_try_renew
+
+<SUBSECTION>
+g_malloc
+g_malloc0
+g_realloc
+g_try_malloc
+g_try_malloc0
+g_try_realloc
+g_malloc_n
+g_malloc0_n
+g_realloc_n
+g_try_malloc_n
+g_try_malloc0_n
+g_try_realloc_n
+
+<SUBSECTION>
+g_free
+g_clear_pointer
+g_steal_pointer
+g_mem_gc_friendly
+
+<SUBSECTION>
+g_alloca
+g_newa
+
+<SUBSECTION>
+g_memmove
+g_memdup
+
+<SUBSECTION>
+GMemVTable
+g_mem_set_vtable
+g_mem_is_system_malloc
+
+<SUBSECTION>
+glib_mem_profiler_table
+g_mem_profile
+</SECTION>
+
+<SECTION>
+<TITLE>Warnings and Assertions</TITLE>
+<FILE>warnings</FILE>
+g_print
+g_set_print_handler
+GPrintFunc
+
+<SUBSECTION>
+g_printerr
+g_set_printerr_handler
+
+<SUBSECTION>
+g_return_if_fail
+g_return_val_if_fail
+g_return_if_reached
+g_return_val_if_reached
+g_warn_if_fail
+g_warn_if_reached
+
+<SUBSECTION>
+g_on_error_query
+g_on_error_stack_trace
+
+<SUBSECTION>
+G_BREAKPOINT
+
+<SUBSECTION Private>
+g_return_if_fail_warning
+g_assert_warning
+g_warn_message
+</SECTION>
+
+<SECTION>
+<TITLE>Glob-style pattern matching</TITLE>
+<FILE>patterns</FILE>
+GPatternSpec
+g_pattern_spec_new
+g_pattern_spec_free
+g_pattern_spec_equal
+g_pattern_match
+g_pattern_match_string
+g_pattern_match_simple
+</SECTION>
+
+<SECTION>
+<TITLE>Perl-compatible regular expressions</TITLE>
+<FILE>gregex</FILE>
+GRegexError
+G_REGEX_ERROR
+GRegexCompileFlags
+GRegexMatchFlags
+GRegex
+GRegexEvalCallback
+g_regex_new
+g_regex_ref
+g_regex_unref
+g_regex_get_pattern
+g_regex_get_max_backref
+g_regex_get_capture_count
+g_regex_get_has_cr_or_lf
+g_regex_get_max_lookbehind
+g_regex_get_string_number
+g_regex_get_compile_flags
+g_regex_get_match_flags
+g_regex_escape_string
+g_regex_escape_nul
+g_regex_match_simple
+g_regex_match
+g_regex_match_full
+g_regex_match_all
+g_regex_match_all_full
+g_regex_split_simple
+g_regex_split
+g_regex_split_full
+g_regex_replace
+g_regex_replace_literal
+g_regex_replace_eval
+g_regex_check_replacement
+GMatchInfo
+g_match_info_get_regex
+g_match_info_get_string
+g_match_info_ref
+g_match_info_unref
+g_match_info_free
+g_match_info_matches
+g_match_info_next
+g_match_info_get_match_count
+g_match_info_is_partial_match
+g_match_info_expand_references
+g_match_info_fetch
+g_match_info_fetch_pos
+g_match_info_fetch_named
+g_match_info_fetch_named_pos
+g_match_info_fetch_all
+<SUBSECTION Private>
+g_regex_error_quark
+</SECTION>
+
+<SECTION>
+<TITLE>Message Logging</TITLE>
+<FILE>messages</FILE>
+G_LOG_DOMAIN
+G_LOG_FATAL_MASK
+G_LOG_LEVEL_USER_SHIFT
+GLogFunc
+GLogLevelFlags
+
+<SUBSECTION>
+g_log
+g_logv
+g_message
+g_warning
+g_warning_once
+g_critical
+g_error
+g_info
+g_debug
+
+<SUBSECTION>
+g_log_set_handler
+g_log_set_handler_full
+g_log_remove_handler
+g_log_set_always_fatal
+g_log_set_fatal_mask
+g_log_default_handler
+g_log_set_default_handler
+
+<SUBSECTION>
+g_log_structured
+g_log_variant
+GLogField
+g_log_structured_array
+G_DEBUG_HERE
+
+<SUBSECTION>
+GLogWriterOutput
+GLogWriterFunc
+g_log_set_writer_func
+g_log_writer_supports_color
+g_log_writer_is_journald
+g_log_writer_format_fields
+g_log_writer_journald
+g_log_writer_standard_streams
+g_log_writer_default
+
+<SUBSECTION Private>
+g_log_structured_standard
+</SECTION>
+
+<SECTION>
+<TITLE>Timers</TITLE>
+<FILE>timers</FILE>
+GTimer
+g_timer_new
+g_timer_start
+g_timer_stop
+g_timer_continue
+g_timer_elapsed
+g_timer_reset
+g_timer_destroy
+g_timer_is_active
+</SECTION>
+
+<SECTION>
+<TITLE>Spawning Processes</TITLE>
+<FILE>spawn</FILE>
+GSpawnError
+G_SPAWN_ERROR
+GSpawnFlags
+GSpawnChildSetupFunc
+g_spawn_async_with_fds
+g_spawn_async_with_pipes
+g_spawn_async
+g_spawn_sync
+G_SPAWN_EXIT_ERROR
+g_spawn_check_exit_status
+g_spawn_command_line_async
+g_spawn_command_line_sync
+g_spawn_close_pid
+<SUBSECTION Private>
+g_spawn_error_quark
+g_spawn_exit_error_quark
+</SECTION>
+
+<SECTION>
+<TITLE>Simple XML Subset Parser</TITLE>
+<FILE>markup</FILE>
+GMarkupError
+G_MARKUP_ERROR
+GMarkupParseFlags
+GMarkupParseContext
+GMarkupParser
+g_markup_escape_text
+g_markup_printf_escaped
+g_markup_vprintf_escaped
+g_markup_parse_context_new
+g_markup_parse_context_parse
+g_markup_parse_context_end_parse
+g_markup_parse_context_free
+g_markup_parse_context_get_position
+g_markup_parse_context_get_element
+g_markup_parse_context_get_element_stack
+g_markup_parse_context_get_user_data
+g_markup_parse_context_push
+g_markup_parse_context_pop
+g_markup_parse_context_ref
+g_markup_parse_context_unref
+<SUBSECTION>
+GMarkupCollectType
+g_markup_collect_attributes
+<SUBSECTION Private>
+g_markup_error_quark
+</SECTION>
+
+
+<SECTION>
+<TITLE>Shell-related Utilities</TITLE>
+<FILE>shell</FILE>
+GShellError
+G_SHELL_ERROR
+g_shell_parse_argv
+g_shell_quote
+g_shell_unquote
+<SUBSECTION Private>
+g_shell_error_quark
+</SECTION>
+
+
+<SECTION>
+<TITLE>Commandline option parser</TITLE>
+<FILE>option</FILE>
+GOptionError
+G_OPTION_ERROR
+GOptionArgFunc
+GOptionContext
+g_option_context_new
+g_option_context_set_summary
+g_option_context_get_summary
+g_option_context_set_description
+g_option_context_get_description
+GTranslateFunc
+g_option_context_set_translate_func
+g_option_context_set_translation_domain
+g_option_context_free
+g_option_context_parse
+g_option_context_parse_strv
+g_option_context_set_help_enabled
+g_option_context_get_help_enabled
+g_option_context_set_ignore_unknown_options
+g_option_context_get_ignore_unknown_options
+g_option_context_get_help
+g_option_context_get_strict_posix
+g_option_context_set_strict_posix
+GOptionArg
+GOptionFlags
+G_OPTION_REMAINING
+GOptionEntry
+g_option_context_add_main_entries
+GOptionGroup
+g_option_context_add_group
+g_option_context_set_main_group
+g_option_context_get_main_group
+g_option_group_new
+g_option_group_ref
+g_option_group_unref
+g_option_group_free
+g_option_group_add_entries
+GOptionParseFunc
+g_option_group_set_parse_hooks
+GOptionErrorFunc
+g_option_group_set_error_hook
+g_option_group_set_translate_func
+g_option_group_set_translation_domain
+<SUBSECTION Private>
+g_option_error_quark
+</SECTION>
+
+
+<SECTION>
+<TITLE>File Utilities</TITLE>
+<FILE>fileutils</FILE>
+<INCLUDE>glib.h,glib/gstdio.h,fcntl.h,sys/types.h,sys/stat.h</INCLUDE>
+GFileError
+G_FILE_ERROR
+GFileTest
+g_file_error_from_errno
+g_file_get_contents
+g_file_set_contents
+g_file_test
+g_mkstemp
+g_mkstemp_full
+g_file_open_tmp
+g_file_read_link
+g_mkdir_with_parents
+g_mkdtemp
+g_mkdtemp_full
+g_dir_make_tmp
+
+<SUBSECTION>
+GDir
+g_dir_open
+g_dir_read_name
+g_dir_rewind
+g_dir_close
+
+<SUBSECTION>
+GMappedFile
+g_mapped_file_new
+g_mapped_file_new_from_fd
+g_mapped_file_ref
+g_mapped_file_unref
+g_mapped_file_free
+g_mapped_file_get_length
+g_mapped_file_get_contents
+g_mapped_file_get_bytes
+
+<SUBSECTION>
+g_open
+g_rename
+g_mkdir
+GStatBuf
+g_stat
+g_lstat
+g_unlink
+g_remove
+g_rmdir
+g_fopen
+g_freopen
+g_fsync
+g_chmod
+g_access
+g_creat
+g_chdir
+g_utime
+g_close
+
+<SUBSECTION Private>
+g_file_error_quark
+utimbuf
+</SECTION>
+
+
+<SECTION>
+<TITLE>String Utility Functions</TITLE>
+<FILE>string_utils</FILE>
+<INCLUDE>glib.h,glib/gprintf.h</INCLUDE>
+g_strdup
+g_strndup
+g_strdupv
+g_strnfill
+g_stpcpy
+g_strstr_len
+g_strrstr
+g_strrstr_len
+g_str_has_prefix
+g_str_has_suffix
+g_strcmp0
+g_str_to_ascii
+g_str_tokenize_and_fold
+g_str_match_string
+
+<SUBSECTION>
+g_strlcpy
+g_strlcat
+
+<SUBSECTION>
+g_strdup_printf
+g_strdup_vprintf
+g_printf
+g_vprintf
+g_fprintf
+g_vfprintf
+g_sprintf
+g_vsprintf
+g_snprintf
+g_vsnprintf
+g_vasprintf
+g_printf_string_upper_bound
+
+<SUBSECTION>
+g_str_is_ascii
+g_ascii_isalnum
+g_ascii_isalpha
+g_ascii_iscntrl
+g_ascii_isdigit
+g_ascii_isgraph
+g_ascii_islower
+g_ascii_isprint
+g_ascii_ispunct
+g_ascii_isspace
+g_ascii_isupper
+g_ascii_isxdigit
+
+<SUBSECTION>
+g_ascii_digit_value
+g_ascii_xdigit_value
+
+<SUBSECTION>
+g_ascii_strcasecmp
+g_ascii_strncasecmp
+
+<SUBSECTION>
+g_ascii_strup
+g_ascii_strdown
+
+<SUBSECTION>
+g_ascii_tolower
+g_ascii_toupper
+
+<SUBSECTION>
+g_string_ascii_up
+g_string_ascii_down
+
+<SUBSECTION>
+g_strup
+g_strdown
+
+<SUBSECTION>
+g_strcasecmp
+g_strncasecmp
+
+<SUBSECTION>
+g_strreverse
+
+<SUBSECTION>
+g_ascii_strtoll
+g_ascii_strtoull
+G_ASCII_DTOSTR_BUF_SIZE
+g_ascii_strtod
+g_ascii_dtostr
+g_ascii_formatd
+g_strtod
+
+<SUBSECTION>
+GNumberParserError
+G_NUMBER_PARSER_ERROR
+g_ascii_string_to_signed
+g_ascii_string_to_unsigned
+
+<SUBSECTION Private>
+g_number_parser_error_quark
+
+<SUBSECTION>
+g_strchug
+g_strchomp
+g_strstrip
+
+<SUBSECTION>
+g_strdelimit
+G_STR_DELIMITERS
+g_strescape
+g_strcompress
+g_strcanon
+g_strsplit
+g_strsplit_set
+g_strfreev
+g_strconcat
+g_strjoin
+g_strjoinv
+
+<SUBSECTION>
+GStrv
+g_strv_length
+g_strv_contains
+g_strv_equal
+
+<SUBSECTION>
+g_strerror
+g_strsignal
+
+<SUBSECTION Private>
+GAsciiType
+g_ascii_table
+</SECTION>
+
+<SECTION>
+<TITLE>Date and Time Functions</TITLE>
+<FILE>date</FILE>
+G_USEC_PER_SEC
+GTimeVal
+g_get_current_time
+g_usleep
+g_time_val_add
+g_time_val_from_iso8601
+g_time_val_to_iso8601
+
+<SUBSECTION>
+g_get_monotonic_time
+g_get_real_time
+
+<SUBSECTION>
+GDate
+GTime
+GDateDMY
+GDateDay
+GDateMonth
+GDateYear
+GDateWeekday
+
+<SUBSECTION>
+G_DATE_BAD_DAY
+G_DATE_BAD_JULIAN
+G_DATE_BAD_YEAR
+
+<SUBSECTION>
+g_date_new
+g_date_new_dmy
+g_date_new_julian
+g_date_clear
+g_date_free
+g_date_copy
+
+<SUBSECTION>
+g_date_set_day
+g_date_set_month
+g_date_set_year
+g_date_set_dmy
+g_date_set_julian
+g_date_set_time
+g_date_set_time_t
+g_date_set_time_val
+g_date_set_parse
+
+<SUBSECTION>
+g_date_add_days
+g_date_subtract_days
+g_date_add_months
+g_date_subtract_months
+g_date_add_years
+g_date_subtract_years
+g_date_days_between
+g_date_compare
+g_date_clamp
+g_date_order
+
+<SUBSECTION>
+g_date_get_day
+g_date_get_month
+g_date_get_year
+g_date_get_julian
+g_date_get_weekday
+g_date_get_day_of_year
+
+<SUBSECTION>
+g_date_get_days_in_month
+g_date_is_first_of_month
+g_date_is_last_of_month
+g_date_is_leap_year
+g_date_get_monday_week_of_year
+g_date_get_monday_weeks_in_year
+g_date_get_sunday_week_of_year
+g_date_get_sunday_weeks_in_year
+g_date_get_iso8601_week_of_year
+
+<SUBSECTION>
+g_date_strftime
+g_date_to_struct_tm
+
+<SUBSECTION>
+g_date_valid
+g_date_valid_day
+g_date_valid_month
+g_date_valid_year
+g_date_valid_dmy
+g_date_valid_julian
+g_date_valid_weekday
+
+<SUBSECTION Private>
+g_date_weekday
+g_date_month
+g_date_year
+g_date_day
+g_date_julian
+g_date_day_of_year
+g_date_monday_week_of_year
+g_date_sunday_week_of_year
+g_date_days_in_month
+g_date_monday_weeks_in_year
+g_date_sunday_weeks_in_year
+</SECTION>
+
+<SECTION>
+<FILE>timezone</FILE>
+<SUBSECTION>
+GTimeZone
+g_time_zone_unref
+g_time_zone_ref
+<SUBSECTION>
+g_time_zone_new
+g_time_zone_new_local
+g_time_zone_new_utc
+g_time_zone_new_offset
+<SUBSECTION>
+GTimeType
+g_time_zone_find_interval
+g_time_zone_adjust_time
+<SUBSECTION>
+g_time_zone_get_identifier
+g_time_zone_get_abbreviation
+g_time_zone_get_offset
+g_time_zone_is_dst
+</SECTION>
+
+<SECTION>
+<FILE>date-time</FILE>
+GTimeSpan
+G_TIME_SPAN_DAY
+G_TIME_SPAN_HOUR
+G_TIME_SPAN_MINUTE
+G_TIME_SPAN_SECOND
+G_TIME_SPAN_MILLISECOND
+
+<SUBSECTION>
+GDateTime
+g_date_time_unref
+g_date_time_ref
+
+<SUBSECTION>
+g_date_time_new_now
+g_date_time_new_now_local
+g_date_time_new_now_utc
+
+<SUBSECTION>
+g_date_time_new_from_unix_local
+g_date_time_new_from_unix_utc
+
+<SUBSECTION>
+g_date_time_new_from_timeval_local
+g_date_time_new_from_timeval_utc
+g_date_time_new_from_iso8601
+
+<SUBSECTION>
+g_date_time_new
+g_date_time_new_local
+g_date_time_new_utc
+
+<SUBSECTION>
+g_date_time_add
+
+<SUBSECTION>
+g_date_time_add_years
+g_date_time_add_months
+g_date_time_add_weeks
+g_date_time_add_days
+
+<SUBSECTION>
+g_date_time_add_hours
+g_date_time_add_minutes
+g_date_time_add_seconds
+
+<SUBSECTION>
+g_date_time_add_full
+
+<SUBSECTION>
+g_date_time_compare
+g_date_time_difference
+g_date_time_hash
+g_date_time_equal
+
+<SUBSECTION>
+g_date_time_get_ymd
+
+<SUBSECTION>
+g_date_time_get_year
+g_date_time_get_month
+g_date_time_get_day_of_month
+
+<SUBSECTION>
+g_date_time_get_week_numbering_year
+g_date_time_get_week_of_year
+g_date_time_get_day_of_week
+
+<SUBSECTION>
+g_date_time_get_day_of_year
+
+<SUBSECTION>
+g_date_time_get_hour
+g_date_time_get_minute
+g_date_time_get_second
+g_date_time_get_microsecond
+g_date_time_get_seconds
+
+<SUBSECTION>
+g_date_time_to_unix
+g_date_time_to_timeval
+
+<SUBSECTION>
+g_date_time_get_utc_offset
+g_date_time_get_timezone
+g_date_time_get_timezone_abbreviation
+g_date_time_is_daylight_savings
+
+<SUBSECTION>
+g_date_time_to_timezone
+g_date_time_to_local
+g_date_time_to_utc
+
+<SUBSECTION>
+g_date_time_format
+g_date_time_format_iso8601
+</SECTION>
+
+<SECTION>
+<TITLE>Hook Functions</TITLE>
+<FILE>hooks</FILE>
+GHookList
+GHookFinalizeFunc
+GHook
+GHookFunc
+GHookCheckFunc
+
+<SUBSECTION>
+g_hook_list_init
+g_hook_list_invoke
+g_hook_list_invoke_check
+g_hook_list_marshal
+GHookMarshaller
+g_hook_list_marshal_check
+GHookCheckMarshaller
+g_hook_list_clear
+
+<SUBSECTION>
+g_hook_alloc
+g_hook_append
+g_hook_prepend
+g_hook_insert_before
+g_hook_insert_sorted
+GHookCompareFunc
+g_hook_compare_ids
+
+<SUBSECTION>
+g_hook_get
+g_hook_find
+GHookFindFunc
+g_hook_find_data
+g_hook_find_func
+g_hook_find_func_data
+
+<SUBSECTION>
+g_hook_first_valid
+g_hook_next_valid
+
+GHookFlagMask
+G_HOOK_FLAGS
+G_HOOK_FLAG_USER_SHIFT
+
+<SUBSECTION>
+G_HOOK
+G_HOOK_IS_VALID
+G_HOOK_ACTIVE
+G_HOOK_IN_CALL
+G_HOOK_IS_UNLINKED
+
+<SUBSECTION>
+g_hook_ref
+g_hook_unref
+
+g_hook_free
+g_hook_destroy
+g_hook_destroy_link
+</SECTION>
+
+<SECTION>
+<TITLE>Miscellaneous Utility Functions</TITLE>
+<FILE>misc_utils</FILE>
+g_get_application_name
+g_set_application_name
+g_get_prgname
+g_set_prgname
+g_get_environ
+g_environ_getenv
+g_environ_setenv
+g_environ_unsetenv
+g_getenv
+g_setenv
+g_unsetenv
+g_listenv
+g_get_user_name
+g_get_real_name
+g_get_user_cache_dir
+g_get_user_data_dir
+g_get_user_config_dir
+g_get_user_runtime_dir
+GUserDirectory
+g_get_user_special_dir
+g_get_system_data_dirs
+g_get_system_config_dirs
+g_reload_user_special_dirs_cache
+g_get_os_info
+
+<SUBSECTION>
+G_OS_INFO_KEY_NAME
+G_OS_INFO_KEY_PRETTY_NAME
+G_OS_INFO_KEY_VERSION
+G_OS_INFO_KEY_VERSION_CODENAME
+G_OS_INFO_KEY_VERSION_ID
+G_OS_INFO_KEY_ID
+G_OS_INFO_KEY_HOME_URL
+G_OS_INFO_KEY_DOCUMENTATION_URL
+G_OS_INFO_KEY_SUPPORT_URL
+G_OS_INFO_KEY_BUG_REPORT_URL
+G_OS_INFO_KEY_PRIVACY_POLICY_URL
+
+<SUBSECTION>
+g_get_host_name
+g_get_home_dir
+g_get_tmp_dir
+g_get_current_dir
+g_basename
+g_dirname
+g_canonicalize_filename
+g_path_is_absolute
+g_path_skip_root
+g_path_get_basename
+g_path_get_dirname
+g_build_filename
+g_build_filenamev
+g_build_filename_valist
+g_build_path
+g_build_pathv
+
+<SUBSECTION>
+g_format_size
+GFormatSizeFlags
+g_format_size_full
+g_format_size_for_display
+
+<SUBSECTION>
+g_find_program_in_path
+
+<SUBSECTION>
+g_bit_nth_lsf
+g_bit_nth_msf
+g_bit_storage
+
+<SUBSECTION>
+g_spaced_primes_closest
+
+<SUBSECTION>
+g_atexit
+g_abort
+
+<SUBSECTION>
+g_parse_debug_string
+GDebugKey
+
+<SUBSECTION>
+GVoidFunc
+GFreeFunc
+
+<SUBSECTION>
+g_qsort_with_data
+
+<SUBSECTION>
+g_nullify_pointer
+
+<SUBSECTION Private>
+G_NATIVE_ATEXIT
+g_ATEXIT
+g_win32_get_system_data_dirs_for_module
+ATEXIT
+g_bit_nth_lsf_impl
+g_bit_nth_msf_impl
+g_bit_storage_impl
+
+</SECTION>
+
+<SECTION>
+<TITLE>Lexical Scanner</TITLE>
+<FILE>scanner</FILE>
+GScanner
+GScannerConfig
+g_scanner_new
+g_scanner_destroy
+
+<SUBSECTION>
+g_scanner_input_file
+g_scanner_sync_file_offset
+g_scanner_input_text
+g_scanner_peek_next_token
+g_scanner_get_next_token
+g_scanner_eof
+
+<SUBSECTION>
+g_scanner_cur_line
+g_scanner_cur_position
+g_scanner_cur_token
+g_scanner_cur_value
+
+<SUBSECTION>
+g_scanner_set_scope
+g_scanner_scope_add_symbol
+g_scanner_scope_foreach_symbol
+g_scanner_scope_lookup_symbol
+g_scanner_scope_remove_symbol
+g_scanner_add_symbol
+g_scanner_remove_symbol
+g_scanner_foreach_symbol
+
+<SUBSECTION>
+g_scanner_freeze_symbol_table
+g_scanner_thaw_symbol_table
+g_scanner_lookup_symbol
+
+<SUBSECTION>
+g_scanner_warn
+g_scanner_error
+g_scanner_unexp_token
+GScannerMsgFunc
+
+<SUBSECTION>
+G_CSET_a_2_z
+G_CSET_A_2_Z
+G_CSET_DIGITS
+G_CSET_LATINC
+G_CSET_LATINS
+GTokenType
+GTokenValue
+GErrorType
+
+</SECTION>
+
+<SECTION>
+<TITLE>Key-value file parser</TITLE>
+<FILE>keyfile</FILE>
+GKeyFile
+G_KEY_FILE_ERROR
+GKeyFileError
+GKeyFileFlags
+
+<SUBSECTION>
+g_key_file_new
+g_key_file_free
+g_key_file_ref
+g_key_file_unref
+g_key_file_set_list_separator
+g_key_file_load_from_file
+g_key_file_load_from_data
+g_key_file_load_from_bytes
+g_key_file_load_from_data_dirs
+g_key_file_load_from_dirs
+g_key_file_to_data
+g_key_file_save_to_file
+g_key_file_get_start_group
+g_key_file_get_groups
+g_key_file_get_keys
+g_key_file_has_group
+g_key_file_has_key
+
+<SUBSECTION>
+g_key_file_get_value
+g_key_file_get_string
+g_key_file_get_locale_string
+g_key_file_get_locale_for_key
+g_key_file_get_boolean
+g_key_file_get_integer
+g_key_file_get_int64
+g_key_file_get_uint64
+g_key_file_get_double
+g_key_file_get_string_list
+g_key_file_get_locale_string_list
+g_key_file_get_boolean_list
+g_key_file_get_integer_list
+g_key_file_get_double_list
+g_key_file_get_comment
+
+<SUBSECTION>
+g_key_file_set_value
+g_key_file_set_string
+g_key_file_set_locale_string
+g_key_file_set_boolean
+g_key_file_set_integer
+g_key_file_set_int64
+g_key_file_set_uint64
+g_key_file_set_double
+g_key_file_set_string_list
+g_key_file_set_locale_string_list
+g_key_file_set_boolean_list
+g_key_file_set_integer_list
+g_key_file_set_double_list
+g_key_file_set_comment
+g_key_file_remove_group
+g_key_file_remove_key
+g_key_file_remove_comment
+
+<SUBSECTION>
+G_KEY_FILE_DESKTOP_GROUP
+G_KEY_FILE_DESKTOP_KEY_TYPE
+G_KEY_FILE_DESKTOP_KEY_VERSION
+G_KEY_FILE_DESKTOP_KEY_NAME
+G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME
+G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY
+G_KEY_FILE_DESKTOP_KEY_COMMENT
+G_KEY_FILE_DESKTOP_KEY_ICON
+G_KEY_FILE_DESKTOP_KEY_HIDDEN
+G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN
+G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN
+G_KEY_FILE_DESKTOP_KEY_TRY_EXEC
+G_KEY_FILE_DESKTOP_KEY_EXEC
+G_KEY_FILE_DESKTOP_KEY_PATH
+G_KEY_FILE_DESKTOP_KEY_TERMINAL
+G_KEY_FILE_DESKTOP_KEY_MIME_TYPE
+G_KEY_FILE_DESKTOP_KEY_CATEGORIES
+G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY
+G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS
+G_KEY_FILE_DESKTOP_KEY_URL
+G_KEY_FILE_DESKTOP_KEY_ACTIONS
+G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE
+G_KEY_FILE_DESKTOP_TYPE_APPLICATION
+G_KEY_FILE_DESKTOP_TYPE_LINK
+G_KEY_FILE_DESKTOP_TYPE_DIRECTORY
+
+<SUBSECTION Private>
+g_key_file_error_quark
+g_key_file_get_type
+</SECTION>
+
+<SECTION>
+<TITLE>Bookmark file parser</TITLE>
+<FILE>bookmarkfile</FILE>
+GBookmarkFile
+G_BOOKMARK_FILE_ERROR
+GBookmarkFileError
+g_bookmark_file_new
+g_bookmark_file_free
+g_bookmark_file_load_from_file
+g_bookmark_file_load_from_data
+g_bookmark_file_load_from_data_dirs
+g_bookmark_file_to_data
+g_bookmark_file_to_file
+g_bookmark_file_has_item
+g_bookmark_file_has_group
+g_bookmark_file_has_application
+g_bookmark_file_get_size
+g_bookmark_file_get_uris G_GNUC_MALLOC
+
+<SUBSECTION>
+g_bookmark_file_get_title
+g_bookmark_file_get_description
+g_bookmark_file_get_mime_type
+g_bookmark_file_get_is_private
+g_bookmark_file_get_icon
+g_bookmark_file_get_added
+g_bookmark_file_get_added_date_time
+g_bookmark_file_get_modified
+g_bookmark_file_get_modified_date_time
+g_bookmark_file_get_visited
+g_bookmark_file_get_visited_date_time
+g_bookmark_file_get_groups
+g_bookmark_file_get_applications
+g_bookmark_file_get_app_info
+g_bookmark_file_get_application_info
+
+<SUBSECTION>
+g_bookmark_file_set_title
+g_bookmark_file_set_description
+g_bookmark_file_set_mime_type
+g_bookmark_file_set_is_private
+g_bookmark_file_set_icon
+g_bookmark_file_set_added
+g_bookmark_file_set_added_date_time
+g_bookmark_file_set_groups
+g_bookmark_file_set_modified
+g_bookmark_file_set_modified_date_time
+g_bookmark_file_set_visited
+g_bookmark_file_set_visited_date_time
+g_bookmark_file_set_app_info
+g_bookmark_file_set_application_info
+g_bookmark_file_add_group
+g_bookmark_file_add_application
+g_bookmark_file_remove_group
+g_bookmark_file_remove_application
+g_bookmark_file_remove_item
+g_bookmark_file_move_item
+
+<SUBSECTION Private>
+g_bookmark_file_error_quark
+</SECTION>
+
+<SECTION>
+<TITLE>Dynamic Loading of Modules</TITLE>
+<FILE>modules</FILE>
+<INCLUDE>gmodule.h</INCLUDE>
+GModule
+g_module_supported
+g_module_build_path
+g_module_open
+GModuleFlags
+g_module_symbol
+g_module_name
+g_module_make_resident
+g_module_close
+g_module_error
+<SUBSECTION>
+GModuleCheckInit
+GModuleUnload
+G_MODULE_SUFFIX
+G_MODULE_EXPORT
+G_MODULE_IMPORT
+</SECTION>
+
+<SECTION>
+<TITLE>Automatic String Completion</TITLE>
+<FILE>completion</FILE>
+GCompletion
+g_completion_new
+GCompletionFunc
+g_completion_add_items
+g_completion_remove_items
+g_completion_clear_items
+g_completion_complete
+g_completion_complete_utf8
+g_completion_set_compare
+GCompletionStrncmpFunc
+g_completion_free
+</SECTION>
+
+<SECTION>
+<TITLE>Windows Compatibility Functions</TITLE>
+<FILE>windows</FILE>
+MAXPATHLEN
+GWin32OSType
+
+g_win32_check_windows_version
+g_win32_get_command_line
+g_win32_error_message
+g_win32_getlocale
+g_win32_get_package_installation_directory
+g_win32_get_package_installation_directory_of_module
+g_win32_get_package_installation_subdirectory
+g_win32_get_windows_version
+g_win32_locale_filename_from_utf8
+G_WIN32_DLLMAIN_FOR_DLL_NAME
+G_WIN32_HAVE_WIDECHAR_API
+G_WIN32_IS_NT_BASED
+
+<SUBSECTION Private>
+g_win32_ftruncate
+
+</SECTION>
+
+<SECTION>
+<TITLE>UNIX-specific utilities and integration</TITLE>
+<FILE>gunix</FILE>
+G_UNIX_ERROR
+g_unix_open_pipe
+g_unix_set_fd_nonblocking
+
+<SUBSECTION>
+g_unix_signal_add
+g_unix_signal_add_full
+g_unix_signal_source_new
+
+<SUBSECTION>
+GUnixFDSourceFunc
+g_unix_fd_add
+g_unix_fd_add_full
+g_unix_fd_source_new
+
+<SUBSECTION>
+g_unix_get_passwd_entry
+
+<SUBSECTION Private>
+g_unix_error_quark
+</SECTION>
+
+# Data Structures
+
+<SECTION>
+<TITLE>Memory Slices</TITLE>
+<FILE>memory_slices</FILE>
+g_slice_alloc
+g_slice_alloc0
+g_slice_copy
+g_slice_free1
+g_slice_free_chain_with_offset
+
+<SUBSECTION>
+g_slice_new
+g_slice_new0
+g_slice_dup
+g_slice_free
+g_slice_free_chain
+
+<SUBSECTION Private>
+GSliceConfig
+g_slice_set_config
+g_slice_get_config
+g_slice_get_config_state
+g_slice_debug_tree_statistics
+</SECTION>
+
+<SECTION>
+<TITLE>Doubly-Linked Lists</TITLE>
+<FILE>linked_lists_double</FILE>
+GList
+
+<SUBSECTION>
+g_list_append
+g_list_prepend
+g_list_insert
+g_list_insert_before
+g_list_insert_before_link
+g_list_insert_sorted
+g_list_remove
+g_list_remove_link
+g_list_delete_link
+g_list_remove_all
+g_list_free
+g_list_free_full
+g_clear_list
+
+<SUBSECTION>
+g_list_alloc
+g_list_free_1
+g_list_free1
+
+<SUBSECTION>
+g_list_length
+g_list_copy
+g_list_copy_deep
+g_list_reverse
+g_list_sort
+GCompareFunc
+g_list_insert_sorted_with_data
+g_list_sort_with_data
+GCompareDataFunc
+g_list_concat
+g_list_foreach
+GFunc
+
+<SUBSECTION>
+g_list_first
+g_list_last
+g_list_previous
+g_list_next
+g_list_nth
+g_list_nth_data
+g_list_nth_prev
+
+<SUBSECTION>
+g_list_find
+g_list_find_custom
+g_list_position
+g_list_index
+</SECTION>
+
+<SECTION>
+<TITLE>Singly-Linked Lists</TITLE>
+<FILE>linked_lists_single</FILE>
+GSList
+
+<SUBSECTION>
+g_slist_alloc
+g_slist_append
+g_slist_prepend
+g_slist_insert
+g_slist_insert_before
+g_slist_insert_sorted
+g_slist_remove
+g_slist_remove_link
+g_slist_delete_link
+g_slist_remove_all
+g_slist_free
+g_slist_free_full
+g_slist_free_1
+g_slist_free1
+g_clear_slist
+
+<SUBSECTION>
+g_slist_length
+g_slist_copy
+g_slist_copy_deep
+g_slist_reverse
+g_slist_insert_sorted_with_data
+g_slist_sort
+g_slist_sort_with_data
+g_slist_concat
+g_slist_foreach
+
+<SUBSECTION>
+g_slist_last
+g_slist_next
+g_slist_nth
+g_slist_nth_data
+
+<SUBSECTION>
+g_slist_find
+g_slist_find_custom
+g_slist_position
+g_slist_index
+</SECTION>
+
+<SECTION>
+<TITLE>Double-ended Queues</TITLE>
+<FILE>queue</FILE>
+
+GQueue
+g_queue_new
+g_queue_free
+g_queue_free_full
+G_QUEUE_INIT
+g_queue_init
+g_queue_clear
+g_queue_clear_full
+g_queue_is_empty
+g_queue_get_length
+g_queue_reverse
+g_queue_copy
+g_queue_foreach
+g_queue_find
+g_queue_find_custom
+g_queue_sort
+g_queue_push_head
+g_queue_push_tail
+g_queue_push_nth
+g_queue_pop_head
+g_queue_pop_tail
+g_queue_pop_nth
+g_queue_peek_head
+g_queue_peek_tail
+g_queue_peek_nth
+g_queue_index
+g_queue_remove
+g_queue_remove_all
+g_queue_insert_before
+g_queue_insert_before_link
+g_queue_insert_after
+g_queue_insert_after_link
+g_queue_insert_sorted
+g_queue_push_head_link
+g_queue_push_tail_link
+g_queue_push_nth_link
+g_queue_pop_head_link
+g_queue_pop_tail_link
+g_queue_pop_nth_link
+g_queue_peek_head_link
+g_queue_peek_tail_link
+g_queue_peek_nth_link
+g_queue_link_index
+g_queue_unlink
+g_queue_delete_link
+</SECTION>
+
+<SECTION>
+<TITLE>Sequences</TITLE>
+<FILE>sequence</FILE>
+
+GSequence
+GSequenceIter
+GSequenceIterCompareFunc
+
+<SUBSECTION>
+g_sequence_new
+g_sequence_free
+g_sequence_get_length
+g_sequence_is_empty
+g_sequence_foreach
+g_sequence_foreach_range
+g_sequence_sort
+g_sequence_sort_iter
+
+<SUBSECTION>
+g_sequence_get_begin_iter
+g_sequence_get_end_iter
+g_sequence_get_iter_at_pos
+g_sequence_append
+g_sequence_prepend
+g_sequence_insert_before
+g_sequence_move
+g_sequence_swap
+g_sequence_insert_sorted
+g_sequence_insert_sorted_iter
+g_sequence_sort_changed
+g_sequence_sort_changed_iter
+g_sequence_remove
+g_sequence_remove_range
+g_sequence_move_range
+g_sequence_search
+g_sequence_search_iter
+g_sequence_lookup
+g_sequence_lookup_iter
+
+<SUBSECTION>
+g_sequence_get
+g_sequence_set
+
+<SUBSECTION>
+g_sequence_iter_is_begin
+g_sequence_iter_is_end
+g_sequence_iter_next
+g_sequence_iter_prev
+g_sequence_iter_get_position
+g_sequence_iter_move
+g_sequence_iter_get_sequence
+
+<SUBSECTION>
+g_sequence_iter_compare
+g_sequence_range_get_midpoint
+</SECTION>
+
+<SECTION>
+<TITLE>Trash Stacks</TITLE>
+<FILE>trash_stack</FILE>
+GTrashStack
+
+g_trash_stack_push
+g_trash_stack_pop
+g_trash_stack_peek
+g_trash_stack_height
+</SECTION>
+
+<SECTION>
+<TITLE>Hash Tables</TITLE>
+<FILE>hash_tables</FILE>
+GHashTable
+g_hash_table_new
+g_hash_table_new_full
+GHashFunc
+GEqualFunc
+g_hash_table_insert
+g_hash_table_replace
+g_hash_table_add
+g_hash_table_contains
+g_hash_table_size
+g_hash_table_lookup
+g_hash_table_lookup_extended
+g_hash_table_foreach
+g_hash_table_find
+GHFunc
+g_hash_table_remove
+g_hash_table_steal
+g_hash_table_steal_extended
+g_hash_table_foreach_remove
+g_hash_table_foreach_steal
+g_hash_table_remove_all
+g_hash_table_steal_all
+g_hash_table_get_keys
+g_hash_table_get_values
+g_hash_table_get_keys_as_array
+GHRFunc
+g_hash_table_freeze
+g_hash_table_thaw
+g_hash_table_destroy
+g_hash_table_ref
+g_hash_table_unref
+GHashTableIter
+g_hash_table_iter_init
+g_hash_table_iter_next
+g_hash_table_iter_get_hash_table
+g_hash_table_iter_replace
+g_hash_table_iter_remove
+g_hash_table_iter_steal
+
+<SUBSECTION>
+g_direct_equal
+g_direct_hash
+g_int_equal
+g_int_hash
+g_int64_equal
+g_int64_hash
+g_double_equal
+g_double_hash
+g_str_equal
+g_str_hash
+
+</SECTION>
+
+<SECTION>
+<TITLE>Strings</TITLE>
+<FILE>strings</FILE>
+GString
+g_string_new
+g_string_new_len
+g_string_sized_new
+g_string_assign
+g_string_sprintf
+g_string_sprintfa
+g_string_vprintf
+g_string_append_vprintf
+g_string_printf
+g_string_append_printf
+g_string_append
+g_string_append_c
+g_string_append_unichar
+g_string_append_len
+g_string_append_uri_escaped
+g_string_prepend
+g_string_prepend_c
+g_string_prepend_unichar
+g_string_prepend_len
+g_string_insert
+g_string_insert_c
+g_string_insert_unichar
+g_string_insert_len
+g_string_overwrite
+g_string_overwrite_len
+g_string_erase
+g_string_truncate
+g_string_set_size
+g_string_free
+g_string_free_to_bytes
+
+<SUBSECTION>
+g_string_up
+g_string_down
+
+<SUBSECTION>
+g_string_hash
+g_string_equal
+
+<SUBSECTION Private>
+g_string_append_c_inline
+g_autoptr_cleanup_gstring_free
+</SECTION>
+
+<SECTION>
+<TITLE>String Chunks</TITLE>
+<FILE>string_chunks</FILE>
+GStringChunk
+g_string_chunk_new
+g_string_chunk_insert
+g_string_chunk_insert_const
+g_string_chunk_insert_len
+g_string_chunk_clear
+g_string_chunk_free
+
+</SECTION>
+
+<SECTION>
+<TITLE>Arrays</TITLE>
+<FILE>arrays</FILE>
+GArray
+g_array_new
+g_array_steal
+g_array_sized_new
+g_array_copy
+g_array_ref
+g_array_unref
+g_array_get_element_size
+g_array_append_val
+g_array_append_vals
+g_array_prepend_val
+g_array_prepend_vals
+g_array_insert_val
+g_array_insert_vals
+g_array_remove_index
+g_array_remove_index_fast
+g_array_remove_range
+g_array_sort
+g_array_sort_with_data
+g_array_binary_search
+g_array_index
+g_array_set_size
+g_array_set_clear_func
+g_array_free
+</SECTION>
+
+<SECTION>
+<TITLE>Pointer Arrays</TITLE>
+<FILE>arrays_pointer</FILE>
+GPtrArray
+g_ptr_array_new
+g_ptr_array_steal
+g_ptr_array_sized_new
+g_ptr_array_new_with_free_func
+g_ptr_array_copy
+g_ptr_array_new_full
+g_ptr_array_set_free_func
+g_ptr_array_ref
+g_ptr_array_unref
+g_ptr_array_add
+g_ptr_array_extend
+g_ptr_array_extend_and_steal
+g_ptr_array_insert
+g_ptr_array_remove
+g_ptr_array_remove_index
+g_ptr_array_remove_fast
+g_ptr_array_remove_index_fast
+g_ptr_array_remove_range
+g_ptr_array_steal_index
+g_ptr_array_steal_index_fast
+g_ptr_array_sort
+g_ptr_array_sort_with_data
+g_ptr_array_set_size
+g_ptr_array_index
+g_ptr_array_free
+g_ptr_array_foreach
+g_ptr_array_find
+g_ptr_array_find_with_equal_func
+
+</SECTION>
+
+<SECTION>
+<TITLE>Byte Arrays</TITLE>
+<FILE>arrays_byte</FILE>
+<SUBSECTION>
+GByteArray
+g_byte_array_new
+g_byte_array_steal
+g_byte_array_new_take
+g_byte_array_sized_new
+g_byte_array_ref
+g_byte_array_unref
+g_byte_array_append
+g_byte_array_prepend
+g_byte_array_remove_index
+g_byte_array_remove_index_fast
+g_byte_array_remove_range
+g_byte_array_sort
+g_byte_array_sort_with_data
+g_byte_array_set_size
+g_byte_array_free
+g_byte_array_free_to_bytes
+
+<SUBSECTION>
+GBytes
+g_bytes_new
+g_bytes_new_take
+g_bytes_new_static
+g_bytes_new_with_free_func
+g_bytes_new_from_bytes
+g_bytes_get_data
+g_bytes_get_size
+g_bytes_hash
+g_bytes_equal
+g_bytes_compare
+g_bytes_ref
+g_bytes_unref
+g_bytes_unref_to_data
+g_bytes_unref_to_array
+
+<SUBSECTION Private>
+g_bytes_get_type
+</SECTION>
+
+<SECTION>
+<TITLE>Balanced Binary Trees</TITLE>
+<FILE>trees-binary</FILE>
+GTree
+g_tree_new
+g_tree_ref
+g_tree_unref
+g_tree_new_with_data
+g_tree_new_full
+g_tree_insert
+g_tree_replace
+g_tree_nnodes
+g_tree_height
+g_tree_lookup
+g_tree_lookup_extended
+g_tree_foreach
+g_tree_traverse
+GTraverseFunc
+g_tree_search
+g_tree_remove
+g_tree_steal
+g_tree_destroy
+</SECTION>
+
+<SECTION>
+<TITLE>N-ary Trees</TITLE>
+<FILE>trees-nary</FILE>
+GNode
+g_node_new
+g_node_copy
+GCopyFunc
+g_node_copy_deep
+
+<SUBSECTION>
+g_node_insert
+g_node_insert_before
+g_node_insert_after
+g_node_append
+g_node_prepend
+
+<SUBSECTION>
+g_node_insert_data
+g_node_insert_data_after
+g_node_insert_data_before
+g_node_append_data
+g_node_prepend_data
+
+<SUBSECTION>
+g_node_reverse_children
+g_node_traverse
+GTraverseType
+GTraverseFlags
+GNodeTraverseFunc
+g_node_children_foreach
+GNodeForeachFunc
+
+<SUBSECTION>
+g_node_get_root
+g_node_find
+g_node_find_child
+g_node_child_index
+g_node_child_position
+g_node_first_child
+g_node_last_child
+g_node_nth_child
+g_node_first_sibling
+g_node_next_sibling
+g_node_prev_sibling
+g_node_last_sibling
+
+<SUBSECTION>
+G_NODE_IS_LEAF
+G_NODE_IS_ROOT
+g_node_depth
+g_node_n_nodes
+g_node_n_children
+g_node_is_ancestor
+g_node_max_height
+
+<SUBSECTION>
+g_node_unlink
+g_node_destroy
+</SECTION>
+
+
+<SECTION>
+<TITLE>Quarks</TITLE>
+<FILE>quarks</FILE>
+GQuark
+G_DEFINE_QUARK
+g_quark_from_string
+g_quark_from_static_string
+g_quark_to_string
+g_quark_try_string
+g_intern_string
+g_intern_static_string
+</SECTION>
+
+<SECTION>
+<TITLE>Keyed Data Lists</TITLE>
+<FILE>datalist</FILE>
+GData
+g_datalist_init
+
+<SUBSECTION>
+g_datalist_id_set_data
+g_datalist_id_set_data_full
+g_datalist_id_get_data
+g_datalist_id_remove_data
+g_datalist_id_remove_no_notify
+GDuplicateFunc
+g_datalist_id_dup_data
+g_datalist_id_replace_data
+
+<SUBSECTION>
+g_datalist_set_data
+g_datalist_set_data_full
+g_datalist_get_data
+g_datalist_remove_data
+g_datalist_remove_no_notify
+
+<SUBSECTION>
+g_datalist_foreach
+g_datalist_clear
+g_datalist_set_flags
+g_datalist_unset_flags
+g_datalist_get_flags
+G_DATALIST_FLAGS_MASK
+</SECTION>
+
+
+<SECTION>
+<TITLE>Datasets</TITLE>
+<FILE>datasets</FILE>
+g_dataset_id_set_data
+g_dataset_id_set_data_full
+GDestroyNotify
+g_dataset_id_get_data
+g_dataset_id_remove_data
+g_dataset_id_remove_no_notify
+
+<SUBSECTION>
+g_dataset_set_data
+g_dataset_set_data_full
+g_dataset_get_data
+g_dataset_remove_data
+g_dataset_remove_no_notify
+
+<SUBSECTION>
+g_dataset_foreach
+GDataForeachFunc
+g_dataset_destroy
+
+</SECTION>
+
+<SECTION>
+<TITLE>Relations and Tuples</TITLE>
+<FILE>relations</FILE>
+GRelation
+g_relation_new
+g_relation_index
+g_relation_insert
+g_relation_exists
+g_relation_count
+g_relation_select
+g_relation_delete
+g_relation_destroy
+
+<SUBSECTION>
+g_relation_print
+
+<SUBSECTION>
+GTuples
+g_tuples_destroy
+g_tuples_index
+</SECTION>
+
+<SECTION>
+<TITLE>Caches</TITLE>
+<FILE>caches</FILE>
+GCache
+g_cache_new
+g_cache_insert
+g_cache_remove
+g_cache_destroy
+
+<SUBSECTION>
+g_cache_key_foreach
+g_cache_value_foreach
+
+<SUBSECTION>
+GCacheDestroyFunc
+GCacheDupFunc
+GCacheNewFunc
+</SECTION>
+
+<SECTION>
+<TITLE>Random Numbers</TITLE>
+<FILE>random_numbers</FILE>
+GRand
+g_rand_new_with_seed
+g_rand_new_with_seed_array
+g_rand_new
+g_rand_copy
+g_rand_free
+g_rand_set_seed
+g_rand_set_seed_array
+g_rand_boolean
+g_rand_int
+g_rand_int_range
+g_rand_double
+g_rand_double_range
+g_random_set_seed
+g_random_boolean
+g_random_int
+g_random_int_range
+g_random_double
+g_random_double_range
+</SECTION>
+
+<SECTION>
+<TITLE>Character Set Conversion</TITLE>
+<FILE>conversions</FILE>
+g_convert
+g_convert_with_fallback
+GIConv
+g_convert_with_iconv
+G_CONVERT_ERROR
+g_iconv_open
+g_iconv
+g_iconv_close
+g_locale_to_utf8
+g_filename_to_utf8
+g_filename_from_utf8
+g_get_filename_charsets
+g_filename_display_name
+g_filename_display_basename
+g_locale_from_utf8
+GConvertError
+
+<SUBSECTION>
+g_get_charset
+g_get_codeset
+g_get_console_charset
+
+<SUBSECTION Private>
+g_convert_error_quark
+</SECTION>
+
+<SECTION>
+<TITLE>Unicode Manipulation</TITLE>
+<FILE>unicode</FILE>
+gunichar
+gunichar2
+
+<SUBSECTION>
+g_unichar_validate
+g_unichar_isalnum
+g_unichar_isalpha
+g_unichar_iscntrl
+g_unichar_isdefined
+g_unichar_isdigit
+g_unichar_isgraph
+g_unichar_islower
+g_unichar_ismark
+g_unichar_isprint
+g_unichar_ispunct
+g_unichar_isspace
+g_unichar_istitle
+g_unichar_isupper
+g_unichar_isxdigit
+g_unichar_iswide
+g_unichar_iswide_cjk
+g_unichar_iszerowidth
+g_unichar_toupper
+g_unichar_tolower
+g_unichar_totitle
+g_unichar_digit_value
+g_unichar_xdigit_value
+g_unichar_compose
+g_unichar_decompose
+g_unichar_fully_decompose
+G_UNICHAR_MAX_DECOMPOSITION_LENGTH
+GUnicodeType
+G_UNICODE_COMBINING_MARK
+g_unichar_type
+GUnicodeBreakType
+g_unichar_break_type
+g_unichar_combining_class
+g_unicode_canonical_ordering
+g_unicode_canonical_decomposition
+g_unichar_get_mirror_char
+GUnicodeScript
+g_unichar_get_script
+g_unicode_script_from_iso15924
+g_unicode_script_to_iso15924
+
+<SUBSECTION>
+g_utf8_next_char
+g_utf8_get_char
+g_utf8_get_char_validated
+g_utf8_offset_to_pointer
+g_utf8_pointer_to_offset
+g_utf8_prev_char
+g_utf8_find_next_char
+g_utf8_find_prev_char
+g_utf8_strlen
+g_utf8_strncpy
+g_utf8_strchr
+g_utf8_strrchr
+g_utf8_strreverse
+g_utf8_substring
+g_utf8_validate
+g_utf8_validate_len
+g_utf8_make_valid
+
+<SUBSECTION>
+g_utf8_strup
+g_utf8_strdown
+g_utf8_casefold
+g_utf8_normalize
+GNormalizeMode
+g_utf8_collate
+g_utf8_collate_key
+g_utf8_collate_key_for_filename
+
+<SUBSECTION>
+g_utf8_to_utf16
+g_utf8_to_ucs4
+g_utf8_to_ucs4_fast
+g_utf16_to_ucs4
+g_utf16_to_utf8
+g_ucs4_to_utf16
+g_ucs4_to_utf8
+g_unichar_to_utf8
+
+<SUBSECTION Private>
+g_utf8_skip
+</SECTION>
+
+<SECTION>
+<TITLE>I18N</TITLE>
+<FILE>i18n</FILE>
+<INCLUDE>glib.h,glib/gi18n.h</INCLUDE>
+_
+Q_
+C_
+N_
+NC_
+g_dgettext
+g_dcgettext
+g_dngettext
+g_dpgettext
+g_dpgettext2
+g_strip_context
+<SUBSECTION>
+g_get_language_names
+g_get_locale_variants
+</SECTION>
+
+<SECTION>
+<TITLE>Base64 Encoding</TITLE>
+<FILE>base64</FILE>
+g_base64_encode_step
+g_base64_encode_close
+g_base64_encode
+g_base64_decode_step
+g_base64_decode
+g_base64_decode_inplace
+</SECTION>
+
+<SECTION>
+<TITLE>URI Functions</TITLE>
+<FILE>gurifuncs</FILE>
+G_URI_RESERVED_CHARS_ALLOWED_IN_PATH
+G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT
+G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO
+G_URI_RESERVED_CHARS_GENERIC_DELIMITERS
+G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS
+g_uri_parse_scheme
+g_uri_escape_string
+g_uri_unescape_string
+g_uri_unescape_segment
+g_uri_list_extract_uris
+g_filename_from_uri
+g_filename_to_uri
+</SECTION>
+
+<SECTION>
+<TITLE>Data Checksums</TITLE>
+<FILE>checksum</FILE>
+GChecksumType
+g_checksum_type_get_length
+GChecksum
+g_checksum_new
+g_checksum_copy
+g_checksum_free
+g_checksum_reset
+g_checksum_update
+g_checksum_get_string
+g_checksum_get_digest
+<SUBSECTION>
+g_compute_checksum_for_data
+g_compute_checksum_for_string
+g_compute_checksum_for_bytes
+</SECTION>
+
+<SECTION>
+<TITLE>Data HMACs</TITLE>
+<FILE>hmac</FILE>
+GHmac
+g_hmac_new
+g_hmac_copy
+g_hmac_ref
+g_hmac_unref
+g_hmac_update
+g_hmac_get_string
+g_hmac_get_digest
+<SUBSECTION>
+g_compute_hmac_for_data
+g_compute_hmac_for_string
+g_compute_hmac_for_bytes
+</SECTION>
+
+<SECTION>
+<TITLE>Testing</TITLE>
+<FILE>testing</FILE>
+G_TEST_OPTION_ISOLATE_DIRS
+g_test_minimized_result
+g_test_maximized_result
+g_test_init
+g_test_initialized
+g_test_quick
+g_test_slow
+g_test_thorough
+g_test_perf
+g_test_verbose
+g_test_undefined
+g_test_quiet
+g_test_subprocess
+g_test_run
+GTestFunc
+g_test_add_func
+GTestDataFunc
+g_test_add_data_func
+g_test_add_data_func_full
+g_test_add
+
+GTestFileType
+g_test_build_filename
+g_test_get_filename
+g_test_get_dir
+
+g_test_fail
+g_test_skip
+g_test_incomplete
+g_test_failed
+g_test_message
+g_test_bug_base
+g_test_bug
+g_test_summary
+GTestLogFatalFunc
+g_test_log_set_fatal_handler
+
+g_test_timer_start
+g_test_timer_elapsed
+g_test_timer_last
+
+g_test_queue_free
+g_test_queue_destroy
+g_test_queue_unref
+
+g_test_expect_message
+g_test_assert_expected_messages
+
+GTestTrapFlags
+GTestSubprocessFlags
+g_test_trap_subprocess
+g_test_trap_has_passed
+g_test_trap_reached_timeout
+g_test_trap_assert_passed
+g_test_trap_assert_failed
+g_test_trap_assert_stdout
+g_test_trap_assert_stdout_unmatched
+g_test_trap_assert_stderr
+g_test_trap_assert_stderr_unmatched
+g_test_trap_fork
+
+g_test_rand_bit
+g_test_rand_int
+g_test_rand_int_range
+g_test_rand_double
+g_test_rand_double_range
+
+g_assert
+g_assert_not_reached
+
+g_assert_cmpstr
+g_assert_cmpint
+g_assert_cmpuint
+g_assert_cmphex
+g_assert_cmpfloat
+g_assert_cmpfloat_with_epsilon
+g_assert_cmpmem
+g_assert_cmpvariant
+g_assert_no_error
+g_assert_error
+g_assert_true
+g_assert_false
+g_assert_null
+g_assert_nonnull
+g_assert_no_errno
+g_test_set_nonfatal_assertions
+
+GTestCase
+GTestSuite
+GTestFixtureFunc
+g_test_create_case
+g_test_create_suite
+g_test_get_root
+g_test_suite_add
+g_test_suite_add_suite
+g_test_run_suite
+
+<SUBSECTION Private>
+g_test_trap_assertions
+g_assertion_message
+g_assertion_message_expr
+g_assertion_message_cmpstr
+g_assertion_message_cmpnum
+g_assertion_message_error
+g_test_assert_expected_messages_internal
+
+g_test_config_vars
+
+g_test_add_vtable
+GTestConfig
+GTestLogType
+GTestLogMsg
+GTestLogBuffer
+GTestResult
+
+g_test_log_type_name
+g_test_log_buffer_new
+g_test_log_buffer_free
+g_test_log_buffer_push
+g_test_log_buffer_pop
+g_test_log_msg_free
+</SECTION>
+
+<SECTION>
+<TITLE>GVariantType</TITLE>
+<FILE>gvarianttype</FILE>
+GVariantType
+G_VARIANT_TYPE_BOOLEAN
+G_VARIANT_TYPE_BYTE
+G_VARIANT_TYPE_INT16
+G_VARIANT_TYPE_UINT16
+G_VARIANT_TYPE_INT32
+G_VARIANT_TYPE_UINT32
+G_VARIANT_TYPE_INT64
+G_VARIANT_TYPE_UINT64
+G_VARIANT_TYPE_HANDLE
+G_VARIANT_TYPE_DOUBLE
+G_VARIANT_TYPE_STRING
+G_VARIANT_TYPE_OBJECT_PATH
+G_VARIANT_TYPE_SIGNATURE
+G_VARIANT_TYPE_VARIANT
+G_VARIANT_TYPE_ANY
+G_VARIANT_TYPE_BASIC
+G_VARIANT_TYPE_MAYBE
+G_VARIANT_TYPE_ARRAY
+G_VARIANT_TYPE_TUPLE
+G_VARIANT_TYPE_UNIT
+G_VARIANT_TYPE_DICT_ENTRY
+G_VARIANT_TYPE_DICTIONARY
+G_VARIANT_TYPE_STRING_ARRAY
+G_VARIANT_TYPE_OBJECT_PATH_ARRAY
+G_VARIANT_TYPE_BYTESTRING
+G_VARIANT_TYPE_BYTESTRING_ARRAY
+G_VARIANT_TYPE_VARDICT
+
+<SUBSECTION>
+G_VARIANT_TYPE
+g_variant_type_free
+g_variant_type_copy
+g_variant_type_new
+
+<SUBSECTION>
+g_variant_type_string_is_valid
+g_variant_type_string_scan
+g_variant_type_get_string_length
+g_variant_type_peek_string
+g_variant_type_dup_string
+
+<SUBSECTION>
+g_variant_type_is_definite
+g_variant_type_is_container
+g_variant_type_is_basic
+g_variant_type_is_maybe
+g_variant_type_is_array
+g_variant_type_is_tuple
+g_variant_type_is_dict_entry
+g_variant_type_is_variant
+
+<SUBSECTION>
+g_variant_type_hash
+g_variant_type_equal
+g_variant_type_is_subtype_of
+
+<SUBSECTION>
+g_variant_type_new_maybe
+g_variant_type_new_array
+g_variant_type_new_tuple
+g_variant_type_new_dict_entry
+
+<SUBSECTION>
+g_variant_type_element
+g_variant_type_n_items
+g_variant_type_first
+g_variant_type_next
+g_variant_type_key
+g_variant_type_value
+</SECTION>
+
+<SECTION>
+<TITLE>GVariant</TITLE>
+<FILE>gvariant</FILE>
+GVariant
+g_variant_unref
+g_variant_ref
+g_variant_ref_sink
+g_variant_is_floating
+g_variant_take_ref
+g_variant_get_type
+g_variant_get_type_string
+g_variant_is_of_type
+g_variant_is_container
+g_variant_compare
+
+<SUBSECTION>
+g_variant_classify
+GVariantClass
+
+<SUBSECTION>
+g_variant_check_format_string
+g_variant_get
+g_variant_get_va
+g_variant_new
+g_variant_new_va
+
+<SUBSECTION>
+g_variant_new_boolean
+g_variant_new_byte
+g_variant_new_int16
+g_variant_new_uint16
+g_variant_new_int32
+g_variant_new_uint32
+g_variant_new_int64
+g_variant_new_uint64
+g_variant_new_handle
+g_variant_new_double
+g_variant_new_string
+g_variant_new_take_string
+g_variant_new_printf
+g_variant_new_object_path
+g_variant_is_object_path
+g_variant_new_signature
+g_variant_is_signature
+g_variant_new_variant
+g_variant_new_strv
+g_variant_new_objv
+g_variant_new_bytestring
+g_variant_new_bytestring_array
+
+<SUBSECTION>
+g_variant_get_boolean
+g_variant_get_byte
+g_variant_get_int16
+g_variant_get_uint16
+g_variant_get_int32
+g_variant_get_uint32
+g_variant_get_int64
+g_variant_get_uint64
+g_variant_get_handle
+g_variant_get_double
+g_variant_get_string
+g_variant_dup_string
+g_variant_get_variant
+g_variant_get_strv
+g_variant_dup_strv
+g_variant_get_objv
+g_variant_dup_objv
+g_variant_get_bytestring
+g_variant_dup_bytestring
+g_variant_get_bytestring_array
+g_variant_dup_bytestring_array
+
+<SUBSECTION>
+g_variant_new_maybe
+g_variant_new_array
+g_variant_new_tuple
+g_variant_new_dict_entry
+g_variant_new_fixed_array
+
+<SUBSECTION>
+g_variant_get_maybe
+g_variant_n_children
+g_variant_get_child_value
+g_variant_get_child
+g_variant_lookup_value
+g_variant_lookup
+g_variant_get_fixed_array
+
+<SUBSECTION>
+g_variant_get_size
+g_variant_get_data
+g_variant_get_data_as_bytes
+g_variant_store
+g_variant_new_from_data
+g_variant_new_from_bytes
+g_variant_byteswap
+g_variant_get_normal_form
+g_variant_is_normal_form
+
+<SUBSECTION>
+g_variant_hash
+g_variant_equal
+
+<SUBSECTION>
+g_variant_print
+g_variant_print_string
+
+<SUBSECTION>
+GVariantIter
+g_variant_iter_copy
+g_variant_iter_free
+g_variant_iter_init
+g_variant_iter_n_children
+g_variant_iter_new
+g_variant_iter_next_value
+g_variant_iter_next
+g_variant_iter_loop
+
+<SUBSECTION>
+G_VARIANT_BUILDER_INIT
+GVariantBuilder
+g_variant_builder_unref
+g_variant_builder_ref
+g_variant_builder_new
+g_variant_builder_init
+g_variant_builder_clear
+g_variant_builder_add_value
+g_variant_builder_add
+g_variant_builder_add_parsed
+g_variant_builder_end
+g_variant_builder_open
+g_variant_builder_close
+
+<SUBSECTION>
+G_VARIANT_DICT_INIT
+GVariantDict
+g_variant_dict_unref
+g_variant_dict_ref
+g_variant_dict_new
+g_variant_dict_init
+g_variant_dict_clear
+g_variant_dict_contains
+g_variant_dict_lookup
+g_variant_dict_lookup_value
+g_variant_dict_insert
+g_variant_dict_insert_value
+g_variant_dict_remove
+g_variant_dict_end
+
+<SUBSECTION>
+GVariantParseError
+G_VARIANT_PARSE_ERROR
+g_variant_parse
+g_variant_new_parsed_va
+g_variant_new_parsed
+g_variant_parse_error_print_context
+
+<SUBSECTION Private>
+g_variant_parse_error_quark
+g_variant_parser_get_error_quark
+g_variant_type_checked_
+g_variant_type_string_get_depth_
+</SECTION>
+
+
+<SECTION>
+<FILE>ghostutils</FILE>
+<TITLE>Hostname Utilities</TITLE>
+g_hostname_to_ascii
+g_hostname_to_unicode
+<SUBSECTION>
+g_hostname_is_non_ascii
+g_hostname_is_ascii_encoded
+<SUBSECTION>
+g_hostname_is_ip_address
+</SECTION>
+
+<SECTION>
+<FILE>uuid</FILE>
+<TITLE>GUuid</TITLE>
+g_uuid_string_is_valid
+g_uuid_string_random
+</SECTION>
+
+<SECTION>
+<FILE>refcount</FILE>
+grefcount
+g_ref_count_init
+g_ref_count_inc
+g_ref_count_dec
+g_ref_count_compare
+<SUBSECTION>
+gatomicrefcount
+g_atomic_ref_count_init
+g_atomic_ref_count_inc
+g_atomic_ref_count_dec
+g_atomic_ref_count_compare
+</SECTION>
+
+<SECTION>
+<FILE>rcbox</FILE>
+g_rc_box_alloc
+g_rc_box_alloc0
+g_rc_box_new
+g_rc_box_new0
+g_rc_box_dup
+g_rc_box_acquire
+g_rc_box_release
+g_rc_box_release_full
+g_rc_box_get_size
+</SECTION>
+
+<SECTION>
+<FILE>arcbox</FILE>
+g_atomic_rc_box_alloc
+g_atomic_rc_box_alloc0
+g_atomic_rc_box_new
+g_atomic_rc_box_new0
+g_atomic_rc_box_dup
+g_atomic_rc_box_acquire
+g_atomic_rc_box_release
+g_atomic_rc_box_release_full
+g_atomic_rc_box_get_size
+</SECTION>
+
+<SECTION>
+<FILE>refstring</FILE>
+GRefString
+g_ref_string_new
+g_ref_string_new_intern
+g_ref_string_new_len
+g_ref_string_acquire
+g_ref_string_release
+g_ref_string_length
+</SECTION>
diff --git a/docs/reference/glib/gtester-report.xml b/docs/reference/glib/gtester-report.xml
new file mode 100644
index 0000000..eee9337
--- /dev/null
+++ b/docs/reference/glib/gtester-report.xml
@@ -0,0 +1,78 @@
+<refentry id="gtester-report">
+
+<refentryinfo>
+<title>gtester-report</title>
+<productname>GLib</productname>
+<authorgroup>
+<author>
+<contrib>Developer</contrib>
+<firstname>Tim</firstname>
+<surname>Janik</surname>
+</author>
+</authorgroup>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>gtester-report</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>gtester-report</refname>
+<refpurpose>test report formatting utility</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>gtester-report</command>
+<arg choice="opt" rep="repeat">option</arg>
+<arg>gtester-log</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>gtester-report</command> is a script which converts
+the XML output generated by gtester into HTML.
+</para>
+<para>Since GLib 2.62, <command>gtester-report</command> is deprecated. Use
+TAP for reporting test results instead, and feed it to the test harness provided
+by your build system.</para>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>-h</option>, <option>--help</option></term>
+<listitem><para>
+print help and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-v</option>, <option>--version</option></term>
+<listitem><para>
+print version information and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-s</option>, <option>--subunit</option></term>
+<listitem><para>
+Output subunit. Needs python-subunit.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+
+<refsect1><title>See also</title>
+<para>
+<citerefentry>
+<refentrytitle>gtester</refentrytitle>
+<manvolnum>1</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/docs/reference/glib/gtester.xml b/docs/reference/glib/gtester.xml
new file mode 100644
index 0000000..5626d4d
--- /dev/null
+++ b/docs/reference/glib/gtester.xml
@@ -0,0 +1,192 @@
+<refentry id="gtester">
+
+<refentryinfo>
+<title>gtester</title>
+<productname>GLib</productname>
+<authorgroup>
+<author>
+<contrib>Developer</contrib>
+<firstname>Tim</firstname>
+<surname>Janik</surname>
+</author>
+<author>
+<contrib>Developer</contrib>
+<firstname>Sven</firstname>
+<surname>Herzberg</surname>
+</author>
+</authorgroup>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>gtester</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>gtester</refname>
+<refpurpose>test running utility</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>gtester</command>
+<arg choice="opt" rep="repeat">OPTION</arg>
+<arg>testprogram</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>gtester</command> is a utility to run unit tests that have
+been written using the GLib test framework.
+</para>
+<para>Since GLib 2.62, <command>gtester-report</command> is deprecated. Use
+TAP for reporting test results instead, and feed it to the test harness provided
+by your build system.</para>
+<para>
+When called with the <option>-o</option> option, <command>gtester</command>
+writes an XML report of the test results, which can be converted
+into HTML using the <command>gtester-report</command> utility.
+</para>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>-h</option>, <option>--help</option></term>
+<listitem><para>
+print help and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-v</option>, <option>--version</option></term>
+<listitem><para>
+print version information and exit
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--g-fatal-warnings</option></term>
+<listitem><para>
+make warnings fatal
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-k</option>, <option>--keep-going</option></term>
+<listitem><para>
+continue running after tests failed
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-l</option></term>
+<listitem><para>
+list paths of available test cases
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-m=<replaceable>MODE</replaceable></option></term>
+<listitem><para>
+    run test cases in <replaceable>MODE</replaceable>, which can be one of:
+
+    <variablelist>
+      <varlistentry>
+      <term><option>perf</option></term>
+      <listitem><para>
+          run performance tests
+      </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+      <term><option>slow</option>, <option>thorough</option></term>
+      <listitem><para>
+          run slow tests, or repeat non-deterministic tests more often
+      </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+      <term><option>quick</option></term>
+      <listitem><para>
+          do not run slow or performance tests, or do extra repeats
+          of non-deterministic tests (default)
+      </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+      <term><option>undefined</option></term>
+      <listitem><para>
+          run test cases that deliberately provoke checks or assertion
+          failures, if implemented (default)
+      </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+      <term><option>no-undefined</option></term>
+      <listitem><para>
+          do not run test cases that deliberately provoke checks or
+          assertion failures
+      </para></listitem>
+      </varlistentry>
+    </variablelist>
+
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-p=<replaceable>TESTPATH</replaceable></option></term>
+<listitem><para>
+only run test cases matching <replaceable>TESTPATH</replaceable>
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-s=<replaceable>TESTPATH</replaceable></option></term>
+<listitem><para>
+skip test cases matching <replaceable>TESTPATH</replaceable>
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--seed=<replaceable>SEEDSTRING</replaceable></option></term>
+<listitem><para>
+run all test cases with random number seed <replaceable>SEEDSTRING</replaceable>
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-o=<replaceable>LOGFILE</replaceable></option></term>
+<listitem><para>
+write the test log to <replaceable>LOGFILE</replaceable>
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-q</option>, <option>--quiet</option></term>
+<listitem><para>
+suppress per test binary output
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--verbose</option></term>
+<listitem><para>
+report success per testcase
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+
+<refsect1><title>See also</title>
+<para>
+<citerefentry>
+<refentrytitle>gtester-report</refentrytitle>
+<manvolnum>1</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/docs/reference/glib/gvariant-text.xml b/docs/reference/glib/gvariant-text.xml
new file mode 100644
index 0000000..55d476e
--- /dev/null
+++ b/docs/reference/glib/gvariant-text.xml
@@ -0,0 +1,622 @@
+<?xml version='1.0' encoding='utf-8'?>
+
+<refentry id='gvariant-text'>
+ <refmeta>
+  <refentrytitle>GVariant Text Format</refentrytitle>
+ </refmeta>
+ <refnamediv>
+  <refname>GVariant Text Format</refname>
+  <refpurpose>textual representation of GVariants</refpurpose>
+ </refnamediv>
+
+ <refsect1>
+  <title>GVariant Text Format</title>
+
+  <para>
+   This page attempts to document the GVariant text format as produced by
+   <link linkend='g-variant-print'><function>g_variant_print()</function></link> and parsed by the
+   <link linkend='g-variant-parse'><function>g_variant_parse()</function></link> family of functions.  In most
+   cases the style closely resembles the formatting of literals in Python but there are some additions and
+   exceptions.
+  </para>
+
+  <para>
+   The functions that deal with GVariant text format absolutely always deal in utf-8.  Conceptually, GVariant
+   text format is a string of Unicode characters -- not bytes.  Non-ASCII but otherwise printable Unicode
+   characters are not treated any differently from normal ASCII characters.
+  </para>
+
+  <para>
+   The parser makes two passes.  The purpose of the first pass is to determine the type of the value being
+   parsed.  The second pass does the actual parsing.  Based on the fact that all elements in an array have to
+   have the same type, GVariant is able to make some deductions that would not otherwise be possible.  As an
+   example:
+
+   <informalexample><programlisting>[[1, 2, 3], [4, 5, 6]]</programlisting></informalexample>
+
+   is parsed as an array of arrays of integers (type '<literal>aai</literal>'), but
+
+   <informalexample><programlisting>[[1, 2, 3], [4, 5, 6.0]]</programlisting></informalexample>
+
+   is parsed as an array of arrays of doubles (type '<literal>aad</literal>').
+  </para>
+
+  <para>
+   As another example, GVariant is able to determine that
+
+   <informalexample><programlisting>["hello", nothing]</programlisting></informalexample>
+
+   is an array of maybe strings (type '<literal>ams</literal>').
+  </para>
+
+  <para>
+   What the parser accepts as valid input is dependent on context.  The API permits for out-of-band type
+   information to be supplied to the parser (which will change its behaviour).  This can be seen in the
+   GSettings and GDBus command line utilities where the type information is available from the schema or the
+   remote introspection information.  The additional information can cause parses to succeed when they would not
+   otherwise have been able to (by resolving ambiguous type information) or can cause them to fail (due to
+   conflicting type information).  Unless stated otherwise, the examples given in this section assume that no
+   out-of-band type data has been given to the parser.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Syntax Summary</title>
+
+  <para>
+   The following table describes the rough meaning of symbols that may appear inside GVariant text format.
+   Each symbol is described in detail in its own section, including usage examples.
+  </para>
+
+  <informaltable>
+   <tgroup cols='2'>
+    <colspec colname='col_0'/>
+    <colspec colname='col_1'/>
+    <tbody>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>Symbol</emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+         <emphasis role='strong'>Meaning</emphasis>
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>true</literal></emphasis>,
+        <emphasis role='strong'><literal>false</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+         <link linkend='gvariant-text-booleans'>Booleans</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>""</literal></emphasis>,
+        <emphasis role='strong'><literal>''</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+         String literal.  See <link linkend='gvariant-text-strings'>Strings</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        numbers
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        See <link linkend='gvariant-text-numbers'>Numbers</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>()</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-tuples'>Tuples</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>[]</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-arrays'>Arrays</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>{}</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-dictionaries'>Dictionaries and Dictionary Entries</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>&lt;&gt;</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-variants'>Variants</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>just</literal></emphasis>,
+        <emphasis role='strong'><literal>nothing</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-maybe-types'>Maybe Types</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>@</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-type-annotations'>Type Annotations</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        type keywords
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <literal>boolean</literal>,
+        <literal>byte</literal>,
+        <literal>int16</literal>,
+        <literal>uint16</literal>,
+        <literal>int32</literal>,
+        <literal>uint32</literal>,
+        <literal>handle</literal>,
+        <literal>int64</literal>,
+        <literal>uint64</literal>,
+        <literal>double</literal>,
+        <literal>string</literal>,
+        <literal>objectpath</literal>,
+        <literal>signature</literal>
+       </para>
+       <para>
+        See <link linkend='gvariant-text-type-annotations'>Type Annotations</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>b""</literal></emphasis>,
+        <emphasis role='strong'><literal>b''</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-bytestrings'>Bytestrings</link>.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>%</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <link linkend='gvariant-text-positional'>Positional Parameters</link>.
+       </para>
+      </entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </informaltable>
+
+  <refsect2 id='gvariant-text-booleans'>
+   <title>Booleans</title>
+   <para>
+    The strings <literal>true</literal> and <literal>false</literal> are parsed as booleans.  This is the only
+    way to specify a boolean value.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-strings'>
+   <title>Strings</title>
+   <para>
+    Strings literals must be quoted using <literal>""</literal> or <literal>''</literal>.  The two are
+    completely equivalent (except for the fact that each one is unable to contain itself unescaped).
+   </para>
+   <para>
+    Strings are Unicode strings with no particular encoding.  For example, to specify the character
+    <literal>é</literal>, you just write <literal>'é'</literal>.  You could also give the Unicode codepoint of
+    that character (U+E9) as the escape sequence <literal>'\u00e9'</literal>.  Since the strings are pure
+    Unicode, you should not attempt to encode the utf-8 byte sequence corresponding to the string using escapes;
+    it won't work and you'll end up with the individual characters corresponding to each byte.
+   </para>
+   <para>
+    Unicode escapes of the form <literal>\uxxxx</literal> and <literal>\Uxxxxxxxx</literal> are supported, in
+    hexadecimal.  The usual control sequence escapes <literal>\a</literal>, <literal>\b</literal>,
+    <literal>\f</literal>, <literal>\n</literal>, <literal>\r</literal>, <literal>\t</literal> and
+    <literal>\v</literal> are supported.  Additionally, a <literal>\</literal> before a newline character causes
+    the newline to be ignored.  Finally, any other character following <literal>\</literal> is copied literally
+    (for example, <literal>\"</literal> or <literal>\\</literal>) but for forwards compatibility with future
+    additions you should only use this feature when necessary for escaping backslashes or quotes.
+   </para>
+   <para>
+    The usual octal and hexadecimal escapes <literal>\0nnn</literal> and <literal>\xnn</literal> are not
+    supported here.  Those escapes are used to encode byte values and GVariant strings are Unicode.
+   </para>
+   <para>
+    Single-character strings are not interpreted as bytes.  Bytes must be specified by their numerical value.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-numbers'>
+   <title>Numbers</title>
+   <para>
+    Numbers are given by default as decimal values.  Octal and hex values can be given in the usual way (by
+    prefixing with <literal>0</literal> or <literal>0x</literal>).  Note that GVariant considers bytes to be
+    unsigned integers and will print them as a two digit hexadecimal number by default.
+   </para>
+   <para>
+    Floating point numbers can also be given in the usual ways, including scientific and hexadecimal notations.
+   </para>
+   <para>
+    For lack of additional information, integers will be parsed as int32 values by default.  If the number has a
+    point or an 'e' in it, then it will be parsed as a double precision floating point number by default.  If
+    type information is available (either explicitly or inferred) then that type will be used instead.
+   </para>
+   <para>
+    Some examples:
+   </para>
+   <para>
+    <literal>5</literal> parses as the int32 value five.
+   </para>
+   <para>
+    <literal>37.5</literal> parses as a floating point value.
+   </para>
+   <para>
+    <literal>3.75e1</literal> parses the same as the value above.
+   </para>
+   <para>
+    <literal>uint64 7</literal> parses seven as a uint64.
+    See <link linkend='gvariant-text-type-annotations'>Type Annotations</link>.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-tuples'>
+   <title>Tuples</title>
+   <para>
+    Tuples are formed using the same syntax as Python.  Here are some examples:
+   </para>
+   <para>
+    <literal>()</literal> parses as the empty tuple.
+   </para>
+   <para>
+    <literal>(5,)</literal> is a tuple containing a single value.
+   </para>
+   <para>
+    <literal>("hello", 42)</literal> is a pair.  Note that values of different types are permitted.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-arrays'>
+   <title>Arrays</title>
+   <para>
+    Arrays are formed using the same syntax as Python uses for lists (which is arguably the term that GVariant
+    should have used).  Note that, unlike Python lists, GVariant arrays are statically typed.  This has two
+    implications.
+   </para>
+   <para>
+    First, all items in the array must have the same type.  Second, the type of the array must be known, even in
+    the case that it is empty.  This means that (unless there is some other way to infer it) type information
+    will need to be given explicitly for empty arrays.
+   </para>
+   <para>
+    The parser is able to infer some types based on the fact that all items in an array must have the same type.
+    See the examples below:
+   </para>
+   <para>
+    <literal>[1]</literal> parses (without additional type information) as a one-item array of signed integers.
+   </para>
+   <para>
+    <literal>[1, 2, 3]</literal> parses (similarly) as a three-item array.
+   </para>
+   <para>
+    <literal>[1, 2, 3.0]</literal> parses as an array of doubles.  This is the most simple case of the type
+    inferencing in action.
+   </para>
+   <para>
+    <literal>[(1, 2), (3, 4.0)]</literal> causes the 2 to also be parsed as a double (but the 1 and 3 are still
+    integers).
+   </para>
+   <para>
+    <literal>["", nothing]</literal> parses as an array of maybe strings.  The presence of
+    "<literal>nothing</literal>" clearly implies that the array elements are nullable.
+   </para>
+   <para>
+    <literal>[[], [""]]</literal> will parse properly because the type of the first (empty) array can be
+    inferred to be equal to the type of the second array (both are arrays of strings).
+   </para>
+   <para>
+    <literal>[b'hello', []]</literal> looks odd but will parse properly.
+    See <link linkend='gvariant-text-bytestrings'>Bytestrings</link>
+   </para>
+   <para>
+    And some examples of errors:
+   </para>
+   <para>
+    <literal>["hello", 42]</literal> fails to parse due to conflicting types.
+   </para>
+   <para>
+    <literal>[]</literal> will fail to parse without additional type information.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-dictionaries'>
+   <title>Dictionaries and Dictionary Entries</title>
+   <para>
+    Dictionaries and dictionary entries are both specified using the <literal>{}</literal> characters.
+   </para>
+   <para>
+    The dictionary syntax is more commonly used.  This is what the printer elects to use in the normal case of
+    dictionary entries appearing in an array (aka "a dictionary").  The separate syntax for dictionary entries
+    is typically only used for when the entries appear on their own, outside of an array (which is valid but
+    unusual).  Of course, you are free to use the dictionary entry syntax within arrays but there is no good
+    reason to do so (and the printer itself will never do so).  Note that, as with arrays, the type of empty
+    dictionaries must be established (either explicitly or through inference).
+   </para>
+   <para>
+    The dictionary syntax is the same as Python's syntax for dictionaries.  Some examples:
+   </para>
+   <para>
+    <literal>@a{sv} {}</literal> parses as the empty dictionary of everyone's favourite type.
+   </para>
+   <para>
+    <literal>@a{sv} []</literal> is the same as above (owing to the fact that dictionaries are really arrays).
+   </para>
+   <para>
+    <literal>{1: "one", 2: "two", 3: "three"}</literal> parses as a dictionary mapping integers to strings.
+   </para>
+   <para>
+    The dictionary entry syntax looks just like a pair (2-tuple) that uses braces instead of parens.  The
+    presence of a comma immediately following the key differentiates it from the dictionary syntax (which
+    features a colon after the first key).  Some examples:
+   </para>
+   <para>
+    <literal>{1, "one"}</literal> is a free-standing dictionary entry that can be parsed on its own or as part
+    of another container value.
+   </para>
+   <para>
+    <literal>[{1, "one"}, {2, "two"}, {3, "three"}]</literal> is exactly equivalent to the dictionary example
+    given above.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-variants'>
+   <title>Variants</title>
+   <para>
+    Variants are denoted using angle brackets (aka "XML brackets"), <literal>&lt;&gt;</literal>.  They may not
+    be omitted.
+   </para>
+   <para>
+    Using <literal>&lt;&gt;</literal> effectively disrupts the type inferencing that occurs between array
+    elements.  This can have positive and negative effects.
+   </para>
+   <para>
+    <literal>[&lt;"hello"&gt;, &lt;42&gt;]</literal> will parse whereas <literal>["hello", 42]</literal> would
+    not.
+   </para>
+   <para>
+    <literal>[&lt;['']&gt;, &lt;[]&gt;]</literal> will fail to parse even though <literal>[[''], []]</literal>
+    parses successfully.  You would need to specify <literal>[&lt;['']&gt;, &lt;@as []&gt;]</literal>.
+   </para>
+   <para>
+    <literal>{"title": &lt;"frobit"&gt;, "enabled": &lt;true&gt;, "width": &lt;800&gt;}</literal> is an example of
+    perhaps the most pervasive use of both dictionaries and variants.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-maybe-types'>
+   <title>Maybe Types</title>
+   <para>
+    The syntax for specifying maybe types is inspired by Haskell.
+   </para>
+   <para>
+    The null case is specified using the keyword <literal>nothing</literal> and the non-null case is explicitly
+    specified using the keyword <literal>just</literal>.  GVariant allows <literal>just</literal> to be omitted
+    in every case that it is able to unambiguously determine the intention of the writer.  There are two cases
+    where it must be specified:
+   </para>
+   <itemizedlist>
+    <listitem>
+     <para>when using nested maybes, in order to specify the <literal>just nothing</literal> case</para>
+    </listitem>
+    <listitem>
+     <para>
+      to establish the nullability of the type of a value without explicitly specifying its full type
+     </para>
+    </listitem>
+   </itemizedlist>
+   <para>
+    Some examples:
+   </para>
+   <para>
+    <literal>just 'hello'</literal> parses as a non-null nullable string.
+   </para>
+   <para>
+    <literal>@ms 'hello'</literal> is the same (demonstrating how <literal>just</literal> can be dropped if the type is already
+    known).
+   </para>
+   <para>
+    <literal>nothing</literal> will not parse wtihout extra type information.
+   </para>
+   <para>
+    <literal>@ms nothing</literal> parses as a null nullable string.
+   </para>
+   <para>
+    <literal>[just 3, nothing]</literal> is an array of nullable integers
+   </para>
+   <para>
+    <literal>[3, nothing]</literal> is the same as the above (demonstrating another place were
+    <literal>just</literal> can be dropped).
+   </para>
+   <para>
+    <literal>[3, just nothing]</literal> parses as an array of maybe maybe integers (type
+    <literal>'ammi'</literal>).
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-type-annotations'>
+   <title>Type Annotations</title>
+   <para>
+    Type annotations allow additional type information to be given to the parser.  Depending on the context,
+    this type information can change the output of the parser, cause an error when parsing would otherwise have
+    succeeded or resolve an error when parsing would have otherwise failed.
+   </para>
+   <para>
+    Type annotations come in two forms: type codes and type keywords.
+   </para>
+   <para>
+    Type keywords can be seen as more verbose (and more legible) versions of a common subset of the type codes.
+    The type keywords <literal>boolean</literal>, <literal>byte</literal>, <literal>int16</literal>,
+    <literal>uint16</literal>, <literal>int32</literal>, <literal>uint32</literal>, <literal>handle</literal>,
+    <literal>int64</literal>, <literal>uint64</literal>, <literal>double</literal>, <literal>string</literal>,
+    <literal>objectpath</literal> and literal <literal>signature</literal> are each exactly equivalent to their
+    corresponding type code.
+   </para>
+   <para>
+    Type codes are an <literal>@</literal> ("at" sign) followed by a definite GVariant type string.  Some
+    examples:
+   </para>
+   <para>
+    <literal>uint32 5</literal> causes the number to be parsed unsigned instead of signed (the default).
+   </para>
+   <para>
+    <literal>@u 5</literal> is the same
+   </para>
+   <para>
+    <literal>objectpath "/org/gnome/xyz"</literal> creates an object path instead of a normal string
+   </para>
+   <para>
+    <literal>@au []</literal> specifies the type of the empty array (which would not parse otherwise)
+   </para>
+   <para>
+    <literal>@ms ""</literal> indicates that a string value is meant to have a maybe type
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-bytestrings'>
+   <title>Bytestrings</title>
+   <para>
+    The bytestring syntax is a piece of syntactic sugar meant to complement the bytestring APIs in GVariant.  It
+    constructs arrays of non-nul bytes (type '<literal>ay</literal>') with a nul terminator at the end. These are
+    normal C strings with no particular encoding enforced, so the bytes may not be valid UTF-8.
+    Bytestrings are a special case of byte arrays; byte arrays (also type '<literal>ay</literal>'), in the general
+    case, can contain nul at any position, and need not end with nul.
+   </para>
+   <para>
+    Bytestrings are specified with either <literal>b""</literal> or <literal>b''</literal>.  As with strings,
+    there is no fundamental difference between the two different types of quotes.
+   </para>
+   <para>
+    Bytestrings support the full range of escapes that you would expect (ie: those supported by
+    <link linkend='g-strcompress'><function>g_strcompress()</function></link>.  This includes the normal control
+    sequence escapes (as mentioned in the section on strings) as well as octal and hexadecimal escapes of the
+    forms <literal>\0nnn</literal> and <literal>\xnn</literal>.
+   </para>
+   <para>
+    <literal>b'abc'</literal> is equivalent to <literal>[byte 0x61, 0x62, 0x63, 0]</literal>.
+   </para>
+   <para>
+    When formatting arrays of bytes, the printer will choose to display the array as a bytestring if it contains
+    a nul character at the end and no other nul bytes within.  Otherwise, it is formatted as a normal array.
+   </para>
+  </refsect2>
+
+  <refsect2 id='gvariant-text-positional'>
+   <title>Positional Parameters</title>
+   <para>
+    Positional parameters are not a part of the normal GVariant text format, but they are mentioned here because
+    they can be used with <link linkend='g-variant-new-parsed'><function>g_variant_new_parsed()</function></link>.
+   </para>
+   <para>
+    A positional parameter is indicated with a <literal>%</literal> followed by any valid
+    <link linkend='gvariant-format-strings'>GVariant Format String</link>.  Variable arguments are collected as
+    specified by the format string and the resulting value is inserted at the current position.
+   </para>
+   <para>
+    This feature is best explained by example:
+   </para>
+   <informalexample><programlisting><![CDATA[char *t = "xyz";
+gboolean en = false;
+GVariant *value;
+
+value = g_variant_new_parsed ("{'title': <%s>, 'enabled': <%b>}", t, en);]]></programlisting></informalexample>
+   <para>
+    This constructs a dictionary mapping strings to variants (type '<literal>a{sv}</literal>') with two items in
+    it.  The key names are parsed from the string and the values for those keys are taken as variable arguments
+    parameters.
+   </para>
+   <para>
+    The arguments are always collected in the order that they appear in the string to be parsed.  Format strings
+    that collect multiple arguments are permitted, so you may require more varargs parameters than the number of
+    <literal>%</literal> signs that appear.  You can also give format strings that collect no arguments, but
+    there's no good reason to do so.
+   </para>
+  </refsect2>
+ </refsect1>
+</refentry>
diff --git a/docs/reference/glib/gvariant-varargs.xml b/docs/reference/glib/gvariant-varargs.xml
new file mode 100644
index 0000000..8529a28
--- /dev/null
+++ b/docs/reference/glib/gvariant-varargs.xml
@@ -0,0 +1,1172 @@
+<?xml version='1.0' encoding='utf-8'?>
+
+<refentry id='gvariant-format-strings'>
+ <refmeta>
+  <refentrytitle>GVariant Format Strings</refentrytitle>
+ </refmeta>
+ <refnamediv>
+  <refname>GVariant Format Strings</refname>
+  <refpurpose>varargs conversion of GVariants</refpurpose>
+ </refnamediv>
+
+ <refsect1>
+  <title>Variable Argument Conversions</title>
+
+  <para>
+   This page attempts to document how to perform variable argument
+   conversions with GVariant.
+  </para>
+  <para>
+   Conversions occur according to format strings.  A format string is a two-way mapping between a single
+   <link linkend='GVariant'>GVariant</link> value and one or more C values.
+  </para>
+  <para>
+   A conversion from C values into a <link linkend='GVariant'>GVariant</link> value is made using the
+   <link linkend='g-variant-new'><function>g_variant_new()</function></link> function.  A conversion from a
+   <link linkend='GVariant'>GVariant</link> into C values is made using the
+   <link linkend='g-variant-get'><function>g_variant_get()</function></link> function.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Syntax</title>
+
+  <para>
+   This section exhaustively describes all possibilities for GVariant format strings.  There are no valid forms of
+   format strings other than those described here.  Please note that the format string syntax is likely to expand in the
+   future.
+  </para>
+  <para>
+   Valid format strings have one of the following forms:
+  </para>
+  <itemizedlist>
+   <listitem>
+    <para>any type string</para>
+   </listitem>
+   <listitem>
+    <para>
+     a type string prefixed with a '<literal>@</literal>'
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     '<literal>&amp;s</literal>' '<literal>&amp;o</literal>', '<literal>&amp;g</literal>', '<literal>^as</literal>',
+     '<literal>^a&amp;s</literal>', '<literal>^ao</literal>', '<literal>^a&amp;o</literal>','<literal>^ay</literal>',
+     '<literal>^&amp;ay</literal>', '<literal>^aay</literal>' or '<literal>^a&amp;ay</literal>'.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     any format string, prefixed with an '<literal>m</literal>'
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     a sequence of zero or more format strings, concatenated and enclosed in parentheses
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     an opening brace, followed by two format strings, followed by a closing brace (subject to the constraint that the
+     first format string correspond to a type valid for use as the key type of a dictionary)
+    </para>
+   </listitem>
+  </itemizedlist>
+ </refsect1>
+ <refsect1>
+  <title>Symbols</title>
+
+   <para>
+    The following table describes the rough meaning of symbols that may appear inside a GVariant format string.  Each
+    symbol is described in detail in its own section, including usage examples.
+  </para>
+
+  <informaltable>
+   <tgroup cols='2'>
+    <colspec colname='col_0'/>
+    <colspec colname='col_1'/>
+    <tbody>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>Symbol</emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+         <emphasis role='strong'>Meaning</emphasis>
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>b</literal>, <literal>y</literal>, <literal>n</literal>, <literal>q</literal>, <literal>i</literal>,
+         <literal>u</literal>, <literal>x</literal>, <literal>t</literal>, <literal>h</literal>, <literal>d</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used for building or deconstructing boolean, byte and numeric types.  See
+        <link linkend='gvariant-format-strings-numeric-types'>Numeric Types</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>s</literal>, <literal>o</literal>, <literal>g</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used for building or deconstructing string types.  See
+        <link linkend='gvariant-format-strings-strings'>Strings</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>v</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used for building or deconstructing variant types.  See
+        <link linkend='gvariant-format-strings-variants'>Variants</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>a</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used for building or deconstructing arrays.  See
+        <link linkend='gvariant-format-strings-arrays'>Arrays</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>m</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+         Used for building or deconstructing maybe types.  See
+         <link linkend='gvariant-format-strings-maybe-types'>Maybe Types</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>()</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+         Used for building or deconstructing tuples.  See
+         <link linkend='gvariant-format-strings-tuples'>Tuples</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>{}</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used for building or deconstructing dictionary entries. See
+        <link linkend='gvariant-format-strings-dictionaries'>Dictionaries</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>@</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used as a prefix for a GVariant type string (not a prefix for a format string, so <literal>@as</literal> is
+        a valid format string but <literal>@^as</literal> is not).  Denotes that a pointer to a
+        <link linkend='GVariant'>GVariant</link> should be used in place of the normal C type or types.  For
+        <link linkend='g-variant-new'><function>g_variant_new()</function></link> this means that you must pass a
+        non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> <code>(<link linkend='GVariant'>GVariant</link>
+        *)</code>; if it is a floating reference, ownership will be taken, as
+        if by using <link linkend="g-variant-ref-sink"><function>g_variant_ref_sink()</function></link>.
+        For <link linkend='g-variant-get'><function>g_variant_get()</function></link> this means that you
+        must pass a pointer to a <code>(<link linkend='GVariant'>GVariant</link> *)</code> for the value to be returned
+        by reference or <link linkend='NULL:CAPS'><literal>NULL</literal></link> to ignore the value.  See
+        <link linkend='gvariant-format-strings-gvariant'><code>GVariant *</code></link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'>
+         <literal>*</literal>, <literal>?</literal>, <literal>r</literal>
+        </emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Exactly equivalent to <literal>@*</literal>, <literal>@?</literal> and <literal>@r</literal>.  Provided only for
+        completeness so that all GVariant type strings can be used also as format strings.  See <link
+        linkend='gvariant-format-strings-gvariant'><code>GVariant *</code></link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>&amp;</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used as a prefix for a GVariant type string (not a prefix for a format string, so <literal>&amp;s</literal> is
+        a valid format string but <literal>&amp;@s</literal> is not).
+        Denotes that a C pointer to serialised data
+        should be used in place of the normal C type.  See
+        <link linkend='gvariant-format-strings-pointers'>Pointers</link> below.
+       </para>
+      </entry>
+     </row>
+
+     <row rowsep='1'>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        <emphasis role='strong'><literal>^</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used as a prefix on some specific types of format strings.  See
+        <link linkend='gvariant-format-strings-convenience'>Convenience Conversions</link> below.
+       </para>
+      </entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </informaltable>
+
+
+  <refsect2 id='gvariant-format-strings-numeric-types'>
+   <title>Numeric Types</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>b</literal>, <literal>y</literal>, <literal>n</literal>, <literal>q</literal>,
+     <literal>i</literal>, <literal>u</literal>, <literal>x</literal>, <literal>t</literal>, <literal>h</literal>,
+     <literal>d</literal>
+    </emphasis>
+   </para>
+
+   <para>
+    Variable argument conversions from numeric types work in the most obvious way possible.  Upon encountering one of
+    these characters, <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes the equivalent C
+    type as an argument.  <link linkend='g-variant-get'><function>g_variant_get()</function></link> takes a pointer to
+    the equivalent C type (or <link linkend='NULL:CAPS'><literal>NULL</literal></link> to ignore the value).
+   </para>
+
+   <para>
+    The equivalent C types are as follows:
+   </para>
+
+   <informaltable>
+    <tgroup cols='2'>
+     <colspec colname='col_0'/><colspec colname='col_1'/>
+     <tbody>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+          <emphasis role='strong'>Character</emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+          <emphasis role='strong'>Equivalent C type</emphasis>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>b</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='gboolean'><type>gboolean</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>y</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='guchar'><type>guchar</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>n</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='gint16'><type>gint16</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>q</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='guint16'><type>guint16</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>i</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='gint32'><type>gint32</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>u</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='guint32'><type>guint32</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>x</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='gint64'><type>gint64</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>t</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='guint64'><type>guint64</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>h</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='gint32'><type>gint32</type></link>
+        </para>
+       </entry>
+      </row>
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>d</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <link linkend='gdouble'><type>gdouble</type></link>
+        </para>
+       </entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </informaltable>
+
+   <anchor id='gvariant-varargs'/>
+   <para>
+    Note that in C, small integer types in variable argument lists are promoted up to <link
+    linkend='gint'><type>int</type></link> or <link linkend='guint'><type>unsigned int</type></link> as appropriate, and
+    read back accordingly.  <link linkend='gint'><type>int</type></link> is 32 bits on every platform on which GLib is
+    currently supported.  This means that you can use C expressions of type <link linkend='gint'><type>int</type></link>
+    with <link linkend='g-variant-new'><function>g_variant_new()</function></link> and format characters
+    '<literal>b</literal>', '<literal>y</literal>', '<literal>n</literal>', '<literal>q</literal>',
+    '<literal>i</literal>', '<literal>u</literal>' and '<literal>h</literal>'.  Specifically, you can use integer
+    literals with these characters.
+   </para>
+
+   <para>
+    When using the '<literal>x</literal>' and '<literal>t</literal>' characters, you must ensure that the value that you
+    provide is 64 bit.  This means that you should use a cast or make use of the
+    <link linkend='G-GINT64-CONSTANT:CAPS'><literal>G_GINT64_CONSTANT</literal></link> or
+    <link linkend='G-GUINT64-CONSTANT:CAPS'><literal>G_GUINT64_CONSTANT</literal></link> macros.
+   </para>
+
+   <para>
+    No type promotion occurs when using <link linkend='g-variant-get'><function>g_variant_get()</function></link> since
+    it operates with pointers.  The pointers must always point to a memory region of exactly the correct size.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *value1, *value2, *value3, *value4;
+
+value1 = g_variant_new ("y", 200);
+value2 = g_variant_new ("b", TRUE);
+value3 = g_variant_new ("d", 37.5):
+value4 = g_variant_new ("x", G_GINT64_CONSTANT (998877665544332211));
+
+{
+  gdouble floating;
+  gboolean truth;
+  gint64 bignum;
+
+
+  g_variant_get (value1, "y", NULL);      /* ignore the value. */
+  g_variant_get (value2, "b", &truth);
+  g_variant_get (value3, "d", &floating);
+  g_variant_get (value4, "x", &bignum);
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-strings'>
+   <title>Strings</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>s</literal>, <literal>o</literal>, <literal>g</literal>
+    </emphasis>
+   </para>
+
+   <para>
+    String conversions occur to and from standard nul-terminated C strings.  Upon encountering an
+    '<literal>s</literal>', '<literal>o</literal>' or '<literal>g</literal>' in a format string,
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a <code>(const
+    <link linkend='gchar'>gchar</link> *)</code> and makes a copy of it.
+    <link linkend='NULL:CAPS'><literal>NULL</literal></link> is not a valid string; use
+    <link linkend='gvariant-format-strings-maybe-types'>maybe types</link> to encode that.  If the '<literal>o</literal>' or
+    '<literal>g</literal>' characters are used, care must be taken to ensure that the passed string is a valid DBus
+    object path or DBus type signature, respectively.
+   </para>
+   <para>
+    Upon encounting '<literal>s</literal>', '<literal>o</literal>' or '<literal>g</literal>', <link
+    linkend='g-variant-get'><function>g_variant_get()</function></link> takes a pointer to a
+    <code>(<link linkend='gchar'>gchar</link> *)</code> (ie: <code>(<link linkend='gchar'>gchar</link> **)</code>) and
+    sets it to a newly-allocated copy of the string.  It is appropriate to free this copy using
+    <link linkend='g-free'><function>g_free()</function></link>.
+    <link linkend='NULL:CAPS'><literal>NULL</literal></link> may also be passed to indicate that the value of the
+    string should be ignored (in which case no copy is made).
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *value1, *value2, *value3;
+
+value1 = g_variant_new ("s", "hello world!");
+value2 = g_variant_new ("o", "/must/be/a/valid/path");
+value3 = g_variant_new ("g", "iias");
+
+#if 0
+  g_variant_new ("s", NULL);      /* not valid: NULL is not a string. */
+#endif
+
+{
+  gchar *result;
+
+  g_variant_get (value1, "s", &result);
+  g_print ("It was '%s'\n", result);
+  g_free (result);
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-variants'>
+   <title>Variants</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>v</literal>
+    </emphasis>
+   </para>
+
+   <para>
+    Upon encountering a '<literal>v</literal>',
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a <code>(<link
+    linkend='GVariant'>GVariant</link> *)</code>.  The value of the
+    <link linkend='GVariant'><type>GVariant</type></link> is used as the contents of the variant value.
+   </para>
+   <para>
+    Upon encountering a '<literal>v</literal>', <link
+    linkend='g-variant-get'><function>g_variant_get()</function></link> takes a pointer to a
+    <code>(<link linkend='GVariant'>GVariant</link> *)</code> (ie: <code>(<link linkend='GVariant'>GVariant</link> **)
+    </code>).  It is set to a new reference to a <link linkend='GVariant'><type>GVariant</type></link> instance
+    containing the contents of the variant value.  It is appropriate to free this reference using
+    <link linkend='g-variant-unref'><function>g_variant_unref()</function></link>.
+    <link linkend='NULL:CAPS'><literal>NULL</literal></link> may also be passed to indicate that the value should be
+    ignored (in which case no new reference is created).
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *x, *y;
+
+/* the following two lines are equivalent: */
+x = g_variant_new ("v", y);
+x = g_variant_new_variant (y);
+
+/* as are these: */
+g_variant_get (x, "v", &y);
+y = g_variant_get_variant (x);]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+
+  <refsect2 id='gvariant-format-strings-arrays'>
+   <title>Arrays</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>a</literal>
+    </emphasis>
+   </para>
+
+   <para>
+    Upon encountering an '<literal>a</literal>' character followed by a type string,
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> will take a
+    <code>(<link linkend='GVariantBuilder'>GVariantBuilder</link> *)</code> that has been created as an array builder
+    for an array of the type given in the type string.  The builder will have
+    <link linkend='g-variant-builder-end'><function>g_variant_builder_end()</function></link> called on it and the
+    result will be used as the value.  As a special exception, if the given type string is a definite type, then
+    <link linkend='NULL:CAPS'><literal>NULL</literal></link> may be given to mean an empty array of that type.
+   </para>
+
+   <para>
+    Upon encountering an '<literal>a</literal>' character followed by a type string,
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> will take a pointer to a
+    <code>(<link linkend='GVariantIter'>GVariantIter</link> *)</code> (ie:
+    <code>(<link linkend='GVariantIter'>GVariantIter</link> **)</code>).
+    A new heap-allocated iterator is created and returned, initialised for iterating over the elements of the array.
+    This iterator should be freed when you are done with it, using
+    <link linkend='g-variant-iter-free'><function>g_variant_iter_free()</function></link>.
+    <link linkend='NULL:CAPS'><literal>NULL</literal></link> may also be given to indicate that the value of the array
+    should be ignored.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariantBuilder *builder;
+GVariant *value;
+
+builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+g_variant_builder_add (builder, "s", "when");
+g_variant_builder_add (builder, "s", "in");
+g_variant_builder_add (builder, "s", "the");
+g_variant_builder_add (builder, "s", "course");
+value = g_variant_new ("as", builder);
+g_variant_builder_unref (builder);
+
+{
+  GVariantIter *iter;
+  gchar *str;
+
+  g_variant_get (value, "as", &iter);
+  while (g_variant_iter_loop (iter, "s", &str))
+    g_print ("%s\n", str);
+  g_variant_iter_free (iter);
+}
+
+g_variant_unref (value);]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-maybe-types'>
+   <title>Maybe Types</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>m</literal>
+    </emphasis>
+   </para>
+   <para>
+    Maybe types are handled in two separate ways depending on the format string that follows the
+    '<literal>m</literal>'.  The method that is used currently depends entirely on the character immediately following the
+    '<literal>m</literal>'.
+   </para>
+
+   <para>
+    The first way is used with format strings starting with '<literal>a</literal>', '<literal>s</literal>',
+    '<literal>o</literal>', '<literal>g</literal>', '<literal>v</literal>', '<literal>@</literal>',
+    '<literal>*</literal>', '<literal>?</literal>', '<literal>r</literal>', '<literal>&amp;</literal>', or
+    '<literal>^</literal>'.  In all of these cases, for non-maybe types,
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a pointer to a
+    non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> value and
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> returns (by reference) a
+    non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> pointer.  When any of these format strings are
+    prefixed with an '<literal>m</literal>', the type of arguments that are collected does not change in any way, but
+    <link linkend='NULL:CAPS'><literal>NULL</literal></link> becomes a permissible value, to indicate the Nothing case.
+   </para>
+   <para>
+    Note that the "special exception" introduced in the array section for constructing empty arrays is ignored
+    here.  Using a <literal>NULL</literal> pointer with the format string '<literal>mas</literal>' constructs
+    the Nothing value -- not an empty array.
+   </para>
+   <para>
+    The second way is used with all other format strings.  For
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> an additional
+    <link linkend='gboolean'><type>gboolean</type></link> argument is collected and for
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> an additional
+    <code>(<link linkend='gboolean'>gboolean</link> *)</code>.  Following this argument, the arguments that are normally
+    collected for the equivalent non-maybe type will be collected.
+   </para>
+   <para>
+    If <link linkend='FALSE:CAPS'><literal>FALSE</literal></link> is given to
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> then the Nothing value is constructed and
+    the collected arguments are ignored.  Otherwise (if <link linkend='TRUE:CAPS'><literal>TRUE</literal></link> was
+    given), the arguments are used in the normal way to create the Just value.
+   </para>
+   <para>
+    If <link linkend='NULL:CAPS'><literal>NULL</literal></link> is given to
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> then the value is ignored.  If a
+    non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> pointer is given then it is used to return by reference
+    whether the value was Just.  In the case that the value was Just, the
+    <link linkend='gboolean'><type>gboolean</type></link> will be set to
+    <link linkend='TRUE:CAPS'><literal>TRUE</literal></link> and the value will be stored in the arguments in the usual
+    way.  In the case that the value was Nothing, the <link linkend='gboolean'><type>gboolean</type></link> will be set to
+    <link linkend='FALSE:CAPS'><literal>FALSE</literal></link> and the arguments will be collected in the normal way
+    but have their values set to binary zero.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *value1, *value2, *value3, *value4, *value5, *value6;
+value1 = g_variant_new ("ms", "Hello world");
+value2 = g_variant_new ("ms", NULL);
+value3 = g_variant_new ("(m(ii)s)", TRUE, 123, 456, "Done");
+value4 = g_variant_new ("(m(ii)s)", FALSE, -1, -1, "Done");          /* both '-1' are ignored. */
+value5 = g_variant_new ("(m@(ii)s)", NULL, "Done");
+
+{
+  GVariant *contents;
+  const gchar *cstr;
+  gboolean just;
+  gint32 x, y;
+  gchar *str;
+
+  g_variant_get (value1, "ms", &str);
+  if (str != NULL)
+    g_print ("str: %s\n", str);
+  else
+    g_print ("it was null\n");
+  g_free (str);
+
+
+  g_variant_get (value2, "m&s", &cstr);
+  if (cstr != NULL)
+    g_print ("str: %s\n", cstr);
+  else
+    g_print ("it was null\n");
+  /* don't free 'cstr' */
+
+
+  /* NULL passed for the gboolean *, but two 'gint32 *' still collected */
+  g_variant_get (value3, "(m(ii)s)", NULL, NULL, NULL, &str);
+  g_print ("string is %s\n", str);
+  g_free (str);
+
+  /* note: &s used, so g_free() not needed */
+  g_variant_get (value4, "(m(ii)&s)", &just, &x, &y, &cstr);
+  if (just)
+    g_print ("it was (%d, %d)\n", x, y);
+  else
+    g_print ("it was null\n");
+  g_print ("string is %s\n", cstr);
+  /* don't free 'cstr' */
+
+
+  g_variant_get (value5, "(m*s)", &contents, NULL); /* ignore the string. */
+  if (contents != NULL)
+    {
+      g_variant_get (contents, "(ii)", &x, &y);
+      g_print ("it was (%d, %d)\n", x, y);
+      g_variant_unref (contents);
+    }
+  else
+    g_print ("it was null\n");
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-tuples'>
+   <title>Tuples</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <code>()</code>
+    </emphasis>
+   </para>
+
+   <para>
+    Tuples are handled by handling each item in the tuple, in sequence.  Each item is handled in the usual way.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *value1, *value2;
+
+value1 = g_variant_new ("(s(ii))", "Hello", 55, 77);
+value2 = g_variant_new ("()");
+
+{
+  gchar *string;
+  gint x, y;
+
+  g_variant_get (value1, "(s(ii))", &string, &x, &y);
+  g_print ("%s, %d, %d\n", string, x, y);
+  g_free (string);
+
+  g_variant_get (value2, "()");   /* do nothing... */
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-gvariant'>
+   <title>GVariant *</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>@</literal>, <literal>*</literal>, <literal>?</literal>, <literal>r</literal>
+    </emphasis>
+
+   </para>
+   <para>
+    Upon encountering a '<literal>@</literal>' in front of a type string,
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a
+    non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> pointer to a
+    <link linkend='GVariant'><type>GVariant</type></link> and uses its value directly instead of collecting arguments to
+    create the value.  The provided <link linkend='GVariant'><type>GVariant</type></link> must have a type that matches the
+    type string following the '<literal>@</literal>'.  '<literal>*</literal>' is
+    the same as '<literal>@*</literal>' (ie: take a <link linkend='GVariant'><type>GVariant</type></link> of any type).
+    '<literal>?</literal>' is the same as '<literal>@?</literal>' (ie: take a
+    <link linkend='GVariant'><type>GVariant</type></link> of any basic type).  '<literal>r</literal>' is the same as
+    '<literal>@r</literal>' (ie: take a <link linkend='GVariant'><type>GVariant</type></link> of any tuple type).
+   </para>
+   <para>
+    Upon encountering a '<literal>@</literal>' in front of a type string,
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link>
+    takes a pointer to a <code>(<link linkend='GVariant'>GVariant</link> *)</code> (ie: a
+    <code>(<link linkend='GVariant'>GVariant</link> **)</code>) and sets it to a new reference to a
+    <link linkend='GVariant'><type>GVariant</type></link> containing the value (instead of deconstructing the value into
+    C types in the usual way).  <link linkend='NULL:CAPS'><literal>NULL</literal></link> can be given to ignore the
+    value.  '<literal>*</literal>', '<literal>?</literal>' and '<literal>r</literal>' are handled in a way analogous to
+    what is stated above.
+   </para>
+   <para>
+    You can always use '<literal>*</literal>' as an alternative to '<literal>?</literal>', '<literal>r</literal>' or any
+    use of '<literal>@</literal>'.  Using the other characters where possible is recommended, however, due to the
+    improvements in type safety and code self-documentation.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *value1, *value2;
+
+value1 = g_variant_new ("(i@ii)", 44, g_variant_new_int32 (55), 66);
+
+/* note: consumes floating reference count on 'value1' */
+value2 = g_variant_new ("(@(iii)*)", value1, g_variant_new_string ("foo"));
+
+{
+  const gchar *string;
+  GVariant *tmp;
+  gsize length;
+  gint x, y, z;
+
+  g_variant_get (value2, "((iii)*)", &x, &y, &z, &tmp);
+  string = g_variant_get_string (tmp, &length);
+  g_print ("it is %d %d %d %s (length=%d)\n", x, y, z, string, (int) length);
+  g_variant_unref (tmp);
+
+  /* quick way to skip all the values in a tuple */
+  g_variant_get (value2, "(rs)", NULL, &string); /* or "(@(iii)s)" */
+  g_print ("i only got the string: %s\n", string);
+  g_free (string);
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-dictionaries'>
+   <title>Dictionaries</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <code>{}</code>
+    </emphasis>
+   </para>
+
+   <para>
+    Dictionary entries are handled by handling first the key, then the value.  Each is handled in the usual way.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariantBuilder *b;
+GVariant *dict;
+
+b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+g_variant_builder_add (b, "{sv}", "name", g_variant_new_string ("foo"));
+g_variant_builder_add (b, "{sv}", "timeout", g_variant_new_int32 (10));
+dict = g_variant_builder_end (b);]]></programlisting></informalexample>
+   </refsect3>
+
+   <para>
+    To extract data from nested dictionaries you can go through a vardict.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *data;
+gint value = 1;
+gint max = 3;
+
+/* type (oa{sa{sv}) */
+data = g_variant_new_parsed ("(%o, {'brightness': {'value': <%i>, 'max': <%i>}})",
+                             "/object/path", value, max);
+{
+  GVariant *params;
+  GVariant *p_brightness;
+  gchar *obj
+  gint p_max;
+
+  g_variant_get (data, "(o@a{?*})", &obj, &params);
+  g_print ("object_path: %s\n", obj);
+
+  p_brightness = g_variant_lookup_value (params, "brightness", G_VARIANT_TYPE_VARDICT);
+  g_variant_lookup (p_brightness, "max", "i", &p_max);
+  g_print ("max: %d\n", p_max);
+}]]></programlisting></informalexample>
+   </refsect3>
+
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-pointers'>
+   <title>Pointers</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <code>&amp;</code>
+    </emphasis>
+   </para>
+
+   <para>
+    The '<code>&amp;</code>' character is used to indicate that serialised data should be directly exchanged via a
+    pointer.
+   </para>
+   <para>
+    Currently, the only use for this character is when it is applied to a string (ie: '<literal>&amp;s</literal>',
+    '<literal>&amp;o</literal>' or '<code>&amp;g</code>').  For
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> this has absolutely no effect.  The string
+    is collected and duplicated normally.  For <link linkend='g-variant-get'><function>g_variant_get()</function></link>
+    it means that instead of creating a newly allocated copy of the string, a pointer to the serialised data is
+    returned.  This pointer should not be freed.  Validity checks are performed to ensure that the string data will
+    always be properly nul-terminated.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[{
+  const gchar *str;
+  GVariant *value;
+
+  value = g_variant_new ("&s", "hello world");
+  g_variant_get (value, "&s", &str);
+  g_print ("string is: %s\n", str);
+  /* no need to free str */
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-convenience'>
+   <title>Convenience Conversions</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>^</literal>
+    </emphasis>
+   </para>
+
+   <para>
+    The '<literal>^</literal>' character currently supports conversion to and from bytestrings or to and from arrays
+    of strings or bytestrings.  It does not support byte arrays.  It has a number of forms.
+   </para>
+
+   <para>
+    In all forms, when used with <link linkend='g-variant-new'><function>g_variant_new()</function></link> one
+    pointer value is collected from the variable arguments and passed to a function (as given in the table below).
+    The result of that function is used as the value for this position.  When used with
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> one pointer value is produced by using
+    the function (given in the table) and returned by reference.
+   </para>
+
+   <informaltable>
+    <tgroup cols='2'>
+     <colspec colname='col_0'/>
+     <colspec colname='col_1'/>
+     <colspec colname='col_2'/>
+     <tbody>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>Conversion</emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+          <emphasis role='strong'>
+            Used with <link linkend='g-variant-new'><function>g_variant_new()</function></link>
+          </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+          <emphasis role='strong'>
+            Used with <link linkend='g-variant-get'><function>g_variant_get()</function></link>
+          </emphasis>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^as</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1' morerows='1'>
+        <para>
+         equivalent to <link linkend='g-variant-new-strv'><function>g_variant_new_strv()</function></link>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-dup-strv'><function>g_variant_dup_strv()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^a&amp;s</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-get-strv'><function>g_variant_get_strv()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^ao</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1' morerows='1'>
+        <para>
+         equivalent to <link linkend='g-variant-new-objv'><function>g_variant_new_objv()</function></link>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-dup-objv'><function>g_variant_dup_objv()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^a&amp;o</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-get-objv'><function>g_variant_get_objv()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^ay</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1' morerows='1'>
+        <para>
+         equivalent to <link linkend='g-variant-new-bytestring'><function>g_variant_new_bytestring()</function></link>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-dup-bytestring'><function>g_variant_dup_bytestring()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^&amp;ay</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-get-bytestring'><function>g_variant_get_bytestring()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^aay</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1' morerows='1'>
+        <para>
+         equivalent to <link linkend='g-variant-new-bytestring-array'><function>g_variant_new_bytestring_array()</function></link>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-dup-bytestring-array'><function>g_variant_dup_bytestring_array()</function></link>
+        </para>
+       </entry>
+      </row>
+
+      <row rowsep='1'>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         <emphasis role='strong'>
+          <literal>^a&amp;ay</literal>
+         </emphasis>
+        </para>
+       </entry>
+       <entry colsep='1' rowsep='1'>
+        <para>
+         equivalent to <link linkend='g-variant-get-bytestring-array'><function>g_variant_get_bytestring_array()</function></link>
+        </para>
+       </entry>
+      </row>
+
+     </tbody>
+    </tgroup>
+   </informaltable>
+  </refsect2>
+ </refsect1>
+</refentry>
diff --git a/docs/reference/glib/mainloop-states.eps b/docs/reference/glib/mainloop-states.eps
new file mode 100644
index 0000000..b3d159b
--- /dev/null
+++ b/docs/reference/glib/mainloop-states.eps
@@ -0,0 +1,306 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: mainloop-stages.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3c
+%%CreationDate: Wed Nov 29 12:23:52 2000
+%%For: otaylor@fresnel.labs.redhat.com (Owen Taylor)
+%%BoundingBox: 0 0 503 291
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 291 moveto 0 0 lineto 503 0 lineto 503 291 lineto closepath clip newpath
+-106.0 402.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+%%Page: 1 1
+10 setmiterlimit
+ 0.06000 0.06000 sc
+%
+% Fig objects follow
+%
+/Times-Roman ff 270.00 scf sf
+9300 6225 m
+gs 1 -1 sc (Initial[n+1]) dup sw pop 2 div neg 0 rm  col0 sh gr
+/Times-Roman ff 270.00 scf sf
+9300 6540 m
+gs 1 -1 sc (\(Recursion\)) dup sw pop 2 div neg 0 rm  col0 sh gr
+% Polyline
+15.000 slw
+ [60] 0 sd
+n 1905 6000 m 1800 6000 1800 6420 105 arcto 4 {pop} repeat
+  1800 6525 3120 6525 105 arcto 4 {pop} repeat
+  3225 6525 3225 6105 105 arcto 4 {pop} repeat
+  3225 6000 1905 6000 105 arcto 4 {pop} repeat
+ cp gs col0 s gr  [] 0 sd
+% Polyline
+ [60] 0 sd
+gs  clippath
+3865 5498 m 3806 5431 l 3688 5535 l 3808 5490 l 3747 5602 l cp
+3184 5976 m 3243 6043 l 3361 5939 l 3242 5985 l 3302 5872 l cp
+eoclip
+n 3225 6000 m
+ 3825 5475 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 3302 5872 m 3242 5985 l 3361 5939 l 3302 5872 l  cp gs 0.00 setgray ef gr  col0 s
+% arrowhead
+n 3747 5602 m 3808 5490 l 3688 5535 l 3747 5602 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+n 4980 5775 m 4875 5775 4875 6270 105 arcto 4 {pop} repeat
+  4875 6375 6870 6375 105 arcto 4 {pop} repeat
+  6975 6375 6975 5880 105 arcto 4 {pop} repeat
+  6975 5775 4980 5775 105 arcto 4 {pop} repeat
+ cp gs col0 s gr 
+% Polyline
+ [60] 0 sd
+gs  clippath
+8457 5969 m 8515 5900 l 8394 5799 l 8458 5911 l 8337 5868 l cp
+8042 5505 m 7984 5574 l 8105 5675 l 8042 5564 l 8162 5606 l cp
+eoclip
+n 8025 5550 m
+ 8475 5925 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 8162 5606 m 8042 5564 l 8105 5675 l 8162 5606 l  cp gs 0.00 setgray ef gr  col0 s
+% arrowhead
+n 8337 5868 m 8458 5911 l 8394 5799 l 8337 5868 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+ [60] 0 sd
+n 8580 5850 m 8475 5850 8475 6570 105 arcto 4 {pop} repeat
+  8475 6675 10020 6675 105 arcto 4 {pop} repeat
+  10125 6675 10125 5955 105 arcto 4 {pop} repeat
+  10125 5850 8580 5850 105 arcto 4 {pop} repeat
+ cp gs col0 s gr  [] 0 sd
+% Polyline
+n 7155 3825 m 7050 3825 7050 4320 105 arcto 4 {pop} repeat
+  7050 4425 9045 4425 105 arcto 4 {pop} repeat
+  9150 4425 9150 3930 105 arcto 4 {pop} repeat
+  9150 3825 7155 3825 105 arcto 4 {pop} repeat
+ cp gs col0 s gr 
+% Polyline
+n 5055 2100 m 4950 2100 4950 2595 105 arcto 4 {pop} repeat
+  4950 2700 6945 2700 105 arcto 4 {pop} repeat
+  7050 2700 7050 2205 105 arcto 4 {pop} repeat
+  7050 2100 5055 2100 105 arcto 4 {pop} repeat
+ cp gs col0 s gr 
+% Polyline
+n 2730 3900 m 2625 3900 2625 4395 105 arcto 4 {pop} repeat
+  2625 4500 4620 4500 105 arcto 4 {pop} repeat
+  4725 4500 4725 4005 105 arcto 4 {pop} repeat
+  4725 3900 2730 3900 105 arcto 4 {pop} repeat
+ cp gs col0 s gr 
+% Polyline
+ [60] 0 sd
+n 8580 1875 m 8475 1875 8475 2295 105 arcto 4 {pop} repeat
+  8475 2400 9645 2400 105 arcto 4 {pop} repeat
+  9750 2400 9750 1980 105 arcto 4 {pop} repeat
+  9750 1875 8580 1875 105 arcto 4 {pop} repeat
+ cp gs col0 s gr  [] 0 sd
+% Polyline
+ [60] 0 sd
+gs  clippath
+8518 2419 m 8451 2358 l 8345 2474 l 8460 2416 l 8412 2534 l cp
+8003 2848 m 8070 2909 l 8176 2793 l 8062 2852 l 8109 2733 l cp
+eoclip
+n 8047 2868 m
+ 8475 2400 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 8109 2733 m 8062 2852 l 8176 2793 l 8109 2733 l  cp gs 0.00 setgray ef gr  col0 s
+% arrowhead
+n 8412 2534 m 8460 2416 l 8345 2474 l 8412 2534 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+2 slj
+gs  clippath
+3340 4475 m 3252 4494 l 3286 4648 l 3305 4522 l 3374 4629 l cp
+eoclip
+n 4875 6075 m 4874 6075 l 4872 6074 l 4868 6073 l 4861 6072 l 4852 6070 l
+ 4839 6067 l 4824 6064 l 4805 6059 l 4783 6054 l 4759 6048 l
+ 4731 6041 l 4701 6033 l 4669 6025 l 4635 6015 l 4600 6004 l
+ 4563 5993 l 4526 5981 l 4487 5967 l 4448 5953 l 4408 5937 l
+ 4367 5920 l 4326 5901 l 4284 5881 l 4241 5859 l 4198 5835 l
+ 4154 5809 l 4109 5781 l 4063 5749 l 4016 5715 l 3968 5678 l
+ 3920 5638 l 3872 5595 l 3825 5550 l 3780 5503 l 3737 5455 l
+ 3697 5407 l 3660 5359 l 3626 5312 l 3594 5266 l 3566 5221 l
+ 3540 5177 l 3516 5134 l 3494 5091 l 3474 5049 l 3455 5008 l
+ 3438 4967 l 3422 4927 l 3408 4888 l 3394 4849 l 3382 4812 l
+ 3371 4775 l 3360 4740 l 3350 4706 l 3342 4674 l 3334 4644 l
+ 3327 4616 l 3321 4592 l 3316 4570 l 3311 4551 l 3308 4536 l
+ 3305 4523 l 3303 4514 l
+ 3300 4500 l gs col0 s gr gr
+
+% arrowhead
+0 slj
+n 3374 4629 m 3305 4522 l 3286 4648 l 3374 4629 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+2 slj
+gs  clippath
+6943 6114 m 6978 6197 l 7123 6135 l 6995 6141 l 7087 6052 l cp
+eoclip
+n 8475 4500 m 8475 4501 l 8475 4503 l 8475 4508 l 8475 4515 l 8474 4525 l
+ 8474 4538 l 8473 4553 l 8472 4573 l 8470 4594 l 8468 4619 l
+ 8465 4646 l 8462 4675 l 8457 4706 l 8452 4739 l 8445 4773 l
+ 8437 4808 l 8427 4845 l 8416 4882 l 8403 4921 l 8388 4961 l
+ 8370 5002 l 8350 5045 l 8326 5090 l 8299 5137 l 8268 5186 l
+ 8232 5237 l 8192 5290 l 8148 5345 l 8100 5400 l 8057 5445 l
+ 8013 5490 l 7968 5533 l 7923 5573 l 7878 5612 l 7833 5649 l
+ 7789 5684 l 7745 5717 l 7701 5749 l 7658 5779 l 7615 5807 l
+ 7573 5834 l 7531 5861 l 7489 5886 l 7447 5910 l 7407 5933 l
+ 7366 5955 l 7327 5977 l 7288 5997 l 7250 6017 l 7214 6035 l
+ 7180 6052 l 7147 6068 l 7117 6083 l 7090 6096 l 7065 6108 l
+ 7043 6118 l 7025 6127 l 7010 6134 l 6998 6140 l 6989 6144 l
+
+ 6975 6150 l gs col0 s gr gr
+
+% arrowhead
+0 slj
+n 7087 6052 m 6995 6141 l 7123 6135 l 7087 6052 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+2 slj
+gs  clippath
+8433 3848 m 8521 3831 l 8493 3676 l 8471 3803 l 8404 3693 l cp
+eoclip
+n 7050 2400 m 7051 2400 l 7054 2401 l 7058 2401 l 7066 2403 l 7076 2404 l
+ 7090 2407 l 7107 2410 l 7127 2414 l 7150 2418 l 7177 2424 l
+ 7206 2430 l 7238 2437 l 7271 2445 l 7306 2454 l 7343 2463 l
+ 7381 2474 l 7419 2486 l 7458 2499 l 7498 2513 l 7538 2528 l
+ 7579 2545 l 7621 2564 l 7663 2585 l 7706 2608 l 7750 2634 l
+ 7795 2662 l 7841 2694 l 7887 2728 l 7933 2766 l 7980 2807 l
+ 8025 2850 l 8068 2895 l 8109 2942 l 8147 2988 l 8181 3034 l
+ 8213 3080 l 8241 3125 l 8267 3169 l 8290 3212 l 8311 3254 l
+ 8330 3296 l 8347 3337 l 8362 3377 l 8376 3417 l 8389 3456 l
+ 8401 3494 l 8412 3532 l 8421 3569 l 8430 3604 l 8438 3637 l
+ 8445 3669 l 8451 3698 l 8457 3725 l 8461 3748 l 8465 3768 l
+ 8468 3785 l 8471 3799 l 8472 3809 l
+ 8475 3825 l gs col0 s gr gr
+
+% arrowhead
+0 slj
+n 8404 3693 m 8471 3803 l 8493 3676 l 8404 3693 l  cp gs 0.00 setgray ef gr  col0 s
+% Polyline
+2 slj
+gs  clippath
+4970 2442 m 4959 2353 l 4803 2372 l 4928 2403 l 4814 2461 l cp
+eoclip
+n 3375 3900 m 3375 3899 l 3376 3897 l 3377 3892 l 3378 3886 l 3380 3876 l
+ 3383 3863 l 3386 3848 l 3391 3828 l 3396 3806 l 3402 3781 l
+ 3409 3753 l 3417 3722 l 3425 3689 l 3435 3655 l 3446 3619 l
+ 3457 3581 l 3469 3543 l 3483 3504 l 3497 3464 l 3513 3423 l
+ 3530 3383 l 3549 3341 l 3569 3299 l 3591 3257 l 3615 3214 l
+ 3641 3170 l 3669 3125 l 3701 3080 l 3735 3034 l 3772 2988 l
+ 3812 2941 l 3855 2895 l 3900 2850 l 3950 2804 l 4001 2762 l
+ 4052 2723 l 4102 2687 l 4152 2655 l 4201 2625 l 4248 2599 l
+ 4295 2576 l 4340 2555 l 4385 2536 l 4429 2519 l 4472 2504 l
+ 4515 2490 l 4557 2477 l 4598 2466 l 4638 2456 l 4677 2447 l
+ 4715 2439 l 4751 2432 l 4784 2426 l 4815 2420 l 4843 2415 l
+ 4868 2411 l 4890 2408 l 4908 2406 l 4922 2404 l 4933 2402 l
+
+ 4950 2400 l gs col0 s gr gr
+
+% arrowhead
+0 slj
+n 4814 2461 m 4928 2403 l 4803 2372 l 4814 2461 l  cp gs 0.00 setgray ef gr  col0 s
+/Times-Roman ff 360.00 scf sf
+5925 6225 m
+gs 1 -1 sc (Initial[n]) dup sw pop 2 div neg 0 rm  col0 sh gr
+/Times-Roman ff 360.00 scf sf
+8100 4275 m
+gs 1 -1 sc (Dispatching) dup sw pop 2 div neg 0 rm  col0 sh gr
+/Times-Roman ff 360.00 scf sf
+3675 4350 m
+gs 1 -1 sc (Prepared) dup sw pop 2 div neg 0 rm  col0 sh gr
+/Times-Roman ff 360.00 scf sf
+5925 2550 m
+gs 1 -1 sc (Polling) dup sw pop 2 div neg 0 rm  col0 sh gr
+/Times-Roman ff 270.00 scf sf
+4050 3300 m
+gs 1 -1 sc (query\(\)) col0 sh gr
+/Times-Roman ff 270.00 scf sf
+7800 3225 m
+gs 1 -1 sc (check\(\)) dup sw pop neg 0 rm  col0 sh gr
+/Times-Roman ff 270.00 scf sf
+2475 6375 m
+gs 1 -1 sc (Working) dup sw pop 2 div neg 0 rm  col0 sh gr
+/Times-Roman ff 270.00 scf sf
+3900 5400 m
+gs 1 -1 sc (prepare\(\)) col0 sh gr
+/Times-Roman ff 270.00 scf sf
+8025 5325 m
+gs 1 -1 sc (dispatch\(\)) dup sw pop neg 0 rm  col0 sh gr
+/Times-Roman ff 270.00 scf sf
+9150 2250 m
+gs 1 -1 sc (Working) dup sw pop 2 div neg 0 rm  col0 sh gr
+$F2psEnd
+rs
diff --git a/docs/reference/glib/mainloop-states.fig b/docs/reference/glib/mainloop-states.fig
new file mode 100644
index 0000000..6acbedb
--- /dev/null
+++ b/docs/reference/glib/mainloop-states.fig
@@ -0,0 +1,65 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 8625 6000 9975 6600
+4 1 0 50 0 0 18 0.0000 4 240 1290 9300 6225 Initial[n+1]\001
+4 1 0 50 0 0 18 0.0000 4 255 1335 9300 6540 (Recursion)\001
+-6
+2 4 1 2 0 7 50 0 -1 4.000 0 0 7 0 0 5
+	 3225 6525 3225 6000 1800 6000 1800 6525 3225 6525
+2 1 1 2 0 7 50 0 -1 4.000 0 0 -1 1 1 2
+	1 1 2.00 90.00 120.00
+	1 1 2.00 90.00 120.00
+	 3225 6000 3825 5475
+2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5
+	 6975 6375 6975 5775 4875 5775 4875 6375 6975 6375
+2 1 1 2 0 7 50 0 -1 4.000 0 0 -1 1 1 2
+	1 1 2.00 90.00 120.00
+	1 1 2.00 90.00 120.00
+	 8025 5550 8475 5925
+2 4 1 2 0 7 50 0 -1 4.000 0 0 7 0 0 5
+	 10125 6675 10125 5850 8475 5850 8475 6675 10125 6675
+2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5
+	 9150 4425 9150 3825 7050 3825 7050 4425 9150 4425
+2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5
+	 7050 2700 7050 2100 4950 2100 4950 2700 7050 2700
+2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5
+	 4725 4500 4725 3900 2625 3900 2625 4500 4725 4500
+2 4 1 2 0 7 50 0 -1 4.000 0 0 7 0 0 5
+	 9750 2400 9750 1875 8475 1875 8475 2400 9750 2400
+2 1 1 2 0 7 50 0 -1 4.000 0 0 -1 1 1 2
+	1 1 2.00 90.00 120.00
+	1 1 2.00 90.00 120.00
+	 8047 2868 8475 2400
+3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3
+	1 1 2.00 90.00 120.00
+	 4875 6075 3825 5550 3300 4500
+	 0.000 -1.000 0.000
+3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3
+	1 1 2.00 90.00 120.00
+	 8475 4500 8100 5400 6975 6150
+	 0.000 -1.000 0.000
+3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3
+	1 1 2.00 90.00 120.00
+	 7050 2400 8025 2850 8475 3825
+	 0.000 -1.000 0.000
+3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3
+	1 1 2.00 90.00 120.00
+	 3375 3900 3900 2850 4950 2400
+	 0.000 -1.000 0.000
+4 1 0 50 0 0 24 0.0000 4 315 1290 5925 6225 Initial[n]\001
+4 1 0 50 0 0 24 0.0000 4 330 1770 8100 4275 Dispatching\001
+4 1 0 50 0 0 24 0.0000 4 330 1320 3675 4350 Prepared\001
+4 1 0 50 0 0 24 0.0000 4 330 1050 5925 2550 Polling\001
+4 0 0 50 0 0 18 0.0000 4 255 825 4050 3300 query()\001
+4 2 0 50 0 0 18 0.0000 4 255 855 7800 3225 check()\001
+4 1 0 50 0 0 18 0.0000 4 255 990 2475 6375 Working\001
+4 0 0 50 0 0 18 0.0000 4 255 1050 3900 5400 prepare()\001
+4 2 0 50 0 0 18 0.0000 4 255 1140 8025 5325 dispatch()\001
+4 1 0 50 0 0 18 0.0000 4 255 990 9150 2250 Working\001
diff --git a/docs/reference/glib/mainloop-states.gif b/docs/reference/glib/mainloop-states.gif
new file mode 100644
index 0000000..0ba1a89
--- /dev/null
+++ b/docs/reference/glib/mainloop-states.gif
Binary files differ
diff --git a/docs/reference/glib/mainloop-states.png b/docs/reference/glib/mainloop-states.png
new file mode 100644
index 0000000..4e9fc9d
--- /dev/null
+++ b/docs/reference/glib/mainloop-states.png
Binary files differ
diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
new file mode 100644
index 0000000..62d95f7
--- /dev/null
+++ b/docs/reference/glib/meson.build
@@ -0,0 +1,105 @@
+if get_option('gtk_doc')
+  subdir('xml')
+
+  ignore_headers = [
+    'gallocator.h',
+    'gdatasetprivate.h',
+    'glibintl.h',
+    'gbsearcharray.h',
+    'glib-private.h',
+    'gmoduleconf.h',
+    'grcboxprivate.h',
+    'gstdioprivate.h',
+    'gthreadprivate.h',
+    'gunibreak.h',
+    'gunicomp.h',
+    'gunidecomp.h',
+    'gunichartables.h',
+    'glib_probes.h',
+    'glib_trace.h',
+    'libcharset.h',
+    'gdebug.h',
+    'gprintfint.h',
+    'gmirroringtable.h',
+    'gscripttable.h',
+    'glib-mirroring-tab',
+    'gnulib',
+    'pcre',
+    'update-pcre',
+    'gbytesprivate.h',
+    'gvariant-internal.h',
+    'gvariant-serialiser.h',
+    'gvariant-core.h',
+    'gvarianttypeinfo.h',
+    'gwakeup.h',
+    'gtranslit-data.h',
+    'glib-init.h',
+    'gconstructor.h',
+    'valgrind.h',
+    'gutilsprivate.h',
+    'gvalgrind.h',
+    'dirent.h',
+  ]
+
+  docpath = join_paths(glib_datadir, 'gtk-doc', 'html')
+  version_conf = configuration_data()
+  version_conf.set('GLIB_VERSION', meson.project_version())
+  configure_file(
+    input: 'version.xml.in',
+    output: 'version.xml',
+    configuration: version_conf
+  )
+
+  gnome.gtkdoc('glib',
+               main_xml : 'glib-docs.xml',
+               namespace : 'g',
+               mode : 'none',
+               src_dir : [ 'glib', 'gmodule' ],
+               dependencies : libglib_dep,
+               scan_args : gtkdoc_common_scan_args + [
+                 '--ignore-headers=' + ' '.join(ignore_headers),
+               ],
+               content_files : [
+                 'cross.xml',
+                 'running.xml',
+                 'building.xml',
+                 'changes.xml',
+                 'compiling.xml',
+                 'programming.xml',
+                 'resources.xml',
+                 'regex-syntax.xml',
+                 'glib-gettextize.xml',
+                 'gtester.xml',
+                 'gtester-report.xml',
+                 'gvariant-varargs.xml',
+                 'gvariant-text.xml',
+               ],
+               expand_content_files : [
+                 'compiling.xml',
+               ],
+               html_assets : [
+                 'file-name-encodings.png',
+                 'mainloop-states.gif',
+                 'Sorted_binary_tree_breadth-first_traversal.svg',
+                 'Sorted_binary_tree_inorder.svg',
+                 'Sorted_binary_tree_postorder.svg',
+                 'Sorted_binary_tree_preorder.svg',
+               ],
+               fixxref_args: [
+                 '--html-dir=' + docpath,
+               ],
+               install: true,
+               check: true)
+endif
+
+if get_option('man')
+  manpages = ['glib-gettextize', 'gtester', 'gtester-report']
+  foreach page : manpages
+    custom_target(page + '-man',
+      input: page + '.xml',
+      output: page + '.1',
+      command: xsltproc_command,
+      install: true,
+      install_dir: man1_dir)
+  endforeach
+endif
diff --git a/docs/reference/glib/programming.xml b/docs/reference/glib/programming.xml
new file mode 100644
index 0000000..52df907
--- /dev/null
+++ b/docs/reference/glib/programming.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-programming">
+<refmeta>
+<refentrytitle>Writing GLib Applications</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>GLib Library</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Writing GLib Applications</refname>
+<refpurpose>
+General considerations when programming with GLib
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Writing GLib Applications</title>
+
+<refsect2>
+<title>Threads</title>
+
+<para>
+The general policy of GLib is that all functions are invisibly threadsafe
+with the exception of data structure manipulation functions, where, if
+you have two threads manipulating the <emphasis>same</emphasis> data
+structure, they must use a lock to synchronize their operation.
+</para>
+
+<para>
+GLib creates a worker thread for its own purposes so GLib applications
+will always have at least 2 threads.
+</para>
+
+<para>
+See the sections on <link linkend="glib-Threads">threads</link> and
+<link linkend="glib-Thread-Pools">threadpools</link> for GLib APIs that
+support multithreaded applications.
+</para>
+
+</refsect2>
+
+<refsect2>
+<title>Security</title>
+
+<para>
+When writing code that runs with elevated privileges, it is important
+to follow some basic rules of secure programming. David Wheeler has an
+excellent book on this topic,
+<ulink url="http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/index.html">Secure Programming for Linux and Unix HOWTO</ulink>.
+</para>
+
+<para>
+When it comes to GLib and its associated libraries, GLib and
+GObject are generally fine to use in code that runs with elevated
+privileges; they don't load modules (executable code in shared objects)
+or run other programs 'behind your back'. GIO has to be used
+carefully in privileged programs, see the <ulink url="http://developer.gnome.org/gio/stable/ch02.html">GIO documentation</ulink> for details.
+</para>
+
+</refsect2>
+
+</refsect1>
+
+</refentry>
diff --git a/docs/reference/glib/regex-syntax.xml b/docs/reference/glib/regex-syntax.xml
new file mode 100644
index 0000000..5dd9291
--- /dev/null
+++ b/docs/reference/glib/regex-syntax.xml
@@ -0,0 +1,2531 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-regex-syntax" revision="11 Jul 2006">
+ <refmeta>
+  <refentrytitle>Regular expression syntax</refentrytitle>
+ </refmeta>
+
+
+<!--
+Based on the man page for pcrepattern.
+
+Remember to sync this document with the file docs/pcrepattern.3 in the
+pcre package when upgrading to a newer version of pcre.
+
+In sync with PCRE 7.0
+-->
+
+<refnamediv>
+<refname>Regular expression syntax</refname>
+<refpurpose>
+syntax and semantics of regular expressions supported by GRegex
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>GRegex regular expression details</title>
+<para>
+A regular expression is a pattern that is matched against a
+string from left to right. Most characters stand for themselves in a
+pattern, and match the corresponding characters in the string. As a
+trivial example, the pattern
+</para>
+
+<programlisting>
+The quick brown fox
+</programlisting>
+
+<para>
+matches a portion of a string that is identical to itself. When
+caseless matching is specified (the <varname>G_REGEX_CASELESS</varname> flag), letters are
+matched independently of case.
+</para>
+
+<para>
+The power of regular expressions comes from the ability to include
+alternatives and repetitions in the pattern. These are encoded in the
+pattern by the use of metacharacters, which do not stand for themselves
+but instead are interpreted in some special way.
+</para>
+
+<para>
+There are two different sets of metacharacters: those that are recognized
+anywhere in the pattern except within square brackets, and those
+that are recognized in square brackets. Outside square brackets, the
+metacharacters are as follows:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Metacharacters outside square brackets</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Character</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\</entry>
+    <entry>general escape character with several uses</entry>
+  </row>
+  <row>
+    <entry>^</entry>
+    <entry>assert start of string (or line, in multiline mode)</entry>
+  </row>
+  <row>
+    <entry>$</entry>
+    <entry>assert end of string (or line, in multiline mode)</entry>
+  </row>
+  <row>
+    <entry>.</entry>
+    <entry>match any character except newline (by default)</entry>
+  </row>
+  <row>
+    <entry>[</entry>
+    <entry>start character class definition</entry>
+  </row>
+  <row>
+    <entry>|</entry>
+    <entry>start of alternative branch</entry>
+  </row>
+  <row>
+    <entry>(</entry>
+    <entry>start subpattern</entry>
+  </row>
+  <row>
+    <entry>)</entry>
+    <entry>end subpattern</entry>
+  </row>
+  <row>
+    <entry>?</entry>
+    <entry>extends the meaning of (, or 0/1 quantifier, or quantifier minimizer</entry>
+  </row>
+  <row>
+    <entry>*</entry>
+    <entry>0 or more quantifier</entry>
+  </row>
+  <row>
+    <entry>+</entry>
+    <entry>1 or more quantifier, also "possessive quantifier"</entry>
+  </row>
+  <row>
+    <entry>{</entry>
+    <entry>start min/max quantifier</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Part of a pattern that is in square brackets is called a "character
+class". In a character class the only metacharacters are:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Metacharacters inside square brackets</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Character</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\</entry>
+    <entry>general escape character</entry>
+  </row>
+  <row>
+    <entry>^</entry>
+    <entry>negate the class, but only if the first character</entry>
+  </row>
+  <row>
+    <entry>-</entry>
+    <entry>indicates character range</entry>
+  </row>
+  <row>
+    <entry>[</entry>
+    <entry>POSIX character class (only if followed by POSIX syntax)</entry>
+  </row>
+  <row>
+    <entry>]</entry>
+    <entry>terminates the character class</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+</refsect1>
+
+<refsect1>
+<title>Backslash</title>
+<para>
+The backslash character has several uses. Firstly, if it is followed by
+a non-alphanumeric character, it takes away any special meaning that
+character may have. This use of backslash as an escape character
+applies both inside and outside character classes.
+</para>
+
+<para>
+For example, if you want to match a * character, you write \* in the
+pattern. This escaping action applies whether or not the following
+character would otherwise be interpreted as a metacharacter, so it is
+always safe to precede a non-alphanumeric with backslash to specify
+that it stands for itself. In particular, if you want to match a
+backslash, you write \\.
+</para>
+
+<para>
+If a pattern is compiled with the <varname>G_REGEX_EXTENDED</varname>
+option, whitespace in the pattern (other than in a character class) and
+characters between a # outside a character class and the next newline
+are ignored.
+An escaping backslash can be used to include a whitespace or # character
+as part of the pattern.
+</para>
+
+<para>
+Note that the C compiler interprets backslash in strings itself, therefore
+you need to duplicate all \ characters when you put a regular expression
+in a C string, like "\\d{3}".
+</para>
+
+<para>
+If you want to remove the special meaning from a sequence of characters,
+you can do so by putting them between \Q and \E.
+The \Q...\E sequence is recognized both inside and outside character
+classes.
+</para>
+
+<refsect2>
+<title>Non-printing characters</title>
+<para>
+A second use of backslash provides a way of encoding non-printing
+characters in patterns in a visible manner. There is no restriction on the
+appearance of non-printing characters, apart from the binary zero that
+terminates a pattern, but when a pattern is being prepared by text
+editing, it is usually easier to use one of the following escape
+sequences than the binary character it represents:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Non-printing characters</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Escape</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\a</entry>
+    <entry>alarm, that is, the BEL character (hex 07)</entry>
+  </row>
+  <row>
+    <entry>\cx</entry>
+    <entry>"control-x", where x is any character</entry>
+  </row>
+  <row>
+    <entry>\e</entry>
+    <entry>escape (hex 1B)</entry>
+  </row>
+  <row>
+    <entry>\f</entry>
+    <entry>formfeed (hex 0C)</entry>
+  </row>
+  <row>
+    <entry>\n</entry>
+    <entry>newline (hex 0A)</entry>
+  </row>
+  <row>
+    <entry>\r</entry>
+    <entry>carriage return (hex 0D)</entry>
+  </row>
+  <row>
+    <entry>\t</entry>
+    <entry>tab (hex 09)</entry>
+  </row>
+  <row>
+    <entry>\ddd</entry>
+    <entry>character with octal code ddd, or backreference</entry>
+  </row>
+  <row>
+    <entry>\xhh</entry>
+    <entry>character with hex code hh</entry>
+  </row>
+  <row>
+    <entry>\x{hhh..}</entry>
+    <entry>character with hex code hhh..</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The precise effect of \cx is as follows: if x is a lower case letter,
+it is converted to upper case. Then bit 6 of the character (hex 40) is
+inverted. Thus \cz becomes hex 1A, but \c{ becomes hex 3B, while \c;
+becomes hex 7B.
+</para>
+
+<para>
+After \x, from zero to two hexadecimal digits are read (letters can be
+in upper or lower case). Any number of hexadecimal digits may appear
+between \x{ and }, but the value of the character code
+must be less than 2**31 (that is, the maximum hexadecimal value is
+7FFFFFFF). If characters other than hexadecimal digits appear between
+\x{ and }, or if there is no terminating }, this form of escape is not
+recognized. Instead, the initial \x will be interpreted as a basic hexadecimal
+escape, with no following digits, giving a character whose
+value is zero.
+</para>
+
+<para>
+Characters whose value is less than 256 can be defined by either of the
+two syntaxes for \x. There is no difference
+in the way they are handled. For example, \xdc is exactly the same as
+\x{dc}.
+</para>
+
+<para>
+After \0 up to two further octal digits are read. If there are fewer
+than two digits, just those that are present are used.
+Thus the sequence \0\x\07 specifies two binary zeros followed by a BEL
+character (code value 7). Make sure you supply two digits after the
+initial zero if the pattern character that follows is itself an octal
+digit.
+</para>
+
+<para>
+The handling of a backslash followed by a digit other than 0 is complicated.
+Outside a character class, GRegex reads it and any following digits as a
+decimal number. If the number is less than 10, or if there
+have been at least that many previous capturing left parentheses in the
+expression, the entire sequence is taken as a back reference. A
+description of how this works is given later, following the discussion
+of parenthesized subpatterns.
+</para>
+
+<para>
+Inside a character class, or if the decimal number is greater than 9
+and there have not been that many capturing subpatterns, GRegex re-reads
+up to three octal digits following the backslash, and uses them to generate
+a data character. Any subsequent digits stand for themselves. For example:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Non-printing characters</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Escape</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\040</entry>
+    <entry>is another way of writing a space</entry>
+  </row>
+  <row>
+    <entry>\40</entry>
+    <entry>is the same, provided there are fewer than 40 previous capturing subpatterns</entry>
+  </row>
+  <row>
+    <entry>\7</entry>
+    <entry>is always a back reference</entry>
+  </row>
+  <row>
+    <entry>\11</entry>
+    <entry>might be a back reference, or another way of writing a tab</entry>
+  </row>
+  <row>
+    <entry>\011</entry>
+    <entry>is always a tab</entry>
+  </row>
+  <row>
+    <entry>\0113</entry>
+    <entry>is a tab followed by the character "3"</entry>
+  </row>
+  <row>
+    <entry>\113</entry>
+    <entry>might be a back reference, otherwise the character with octal code 113</entry>
+  </row>
+  <row>
+    <entry>\377</entry>
+    <entry>might be a back reference, otherwise the byte consisting entirely of 1 bits</entry>
+  </row>
+  <row>
+    <entry>\81</entry>
+    <entry>is either a back reference, or a binary zero followed by the two characters "8" and "1"</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Note that octal values of 100 or greater must not be introduced by a
+leading zero, because no more than three octal digits are ever read.
+</para>
+
+<para>
+All the sequences that define a single character can be used both inside
+and outside character classes. In addition, inside a character class, the
+sequence \b is interpreted as the backspace character (hex 08), and the
+sequences \R and \X are interpreted as the characters "R" and "X", respectively.
+Outside a character class, these sequences have different meanings (see below).
+</para>
+</refsect2>
+
+<refsect2>
+<title>Absolute and relative back references</title>
+<para>
+The sequence \g followed by a positive or negative number, optionally enclosed
+in braces, is an absolute or relative back reference. Back references are
+discussed later, following the discussion of parenthesized subpatterns.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Generic character types</title>
+
+<para>
+Another use of backslash is for specifying generic character types.
+The following are always recognized:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Generic characters</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Escape</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\d</entry>
+    <entry>any decimal digit</entry>
+  </row>
+  <row>
+    <entry>\D</entry>
+    <entry>any character that is not a decimal digit</entry>
+  </row>
+  <row>
+    <entry>\s</entry>
+    <entry>any whitespace character</entry>
+  </row>
+  <row>
+    <entry>\S</entry>
+    <entry>any character that is not a whitespace character</entry>
+  </row>
+  <row>
+    <entry>\w</entry>
+    <entry>any "word" character</entry>
+  </row>
+  <row>
+    <entry>\W</entry>
+    <entry>any "non-word" character</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Each pair of escape sequences partitions the complete set of characters
+into two disjoint sets. Any given character matches one, and only one,
+of each pair.
+</para>
+
+<para>
+These character type sequences can appear both inside and outside character
+classes. They each match one character of the appropriate type.
+If the current matching point is at the end of the passed string, all
+of them fail, since there is no character to match.
+</para>
+
+<para>
+For compatibility with Perl, \s does not match the VT character (code
+11). This makes it different from the POSIX "space" class. The \s
+characters are HT (9), LF (10), FF (12), CR (13), and space (32).
+</para>
+
+<para>
+A "word" character is an underscore or any character less than 256 that
+is a letter or digit.</para>
+
+<para>
+Characters with values greater than 128 never match \d,
+\s, or \w, and always match \D, \S, and \W.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Newline sequences</title>
+<para>Outside a character class, the escape sequence \R matches any Unicode
+newline sequence.
+This particular group matches either the two-character sequence CR followed by
+LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab,
+U+000B), FF (formfeed, U+000C), CR (carriage return, U+000D), NEL (next
+line, U+0085), LS (line separator, U+2028), or PS (paragraph separator, U+2029).
+The two-character sequence is treated as a single unit that
+cannot be split. Inside a character class, \R matches the letter "R".</para>
+</refsect2>
+
+<refsect2>
+<title>Unicode character properties</title>
+<para>
+To support generic character types there are three additional escape
+sequences, they are:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Generic character types</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Escape</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\p{xx}</entry>
+    <entry>a character with the xx property</entry>
+  </row>
+  <row>
+    <entry>\P{xx}</entry>
+    <entry>a character without the xx property</entry>
+  </row>
+  <row>
+    <entry>\X</entry>
+    <entry>an extended Unicode sequence</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The property names represented by xx above are limited to the Unicode
+script names, the general category properties, and "Any", which matches
+any character (including newline). Other properties such as "InMusicalSymbols"
+are not currently supported. Note that \P{Any} does not match any characters,
+so always causes a match failure.
+</para>
+
+<para>
+Sets of Unicode characters are defined as belonging to certain scripts. A
+character from one of these sets can be matched using a script name. For
+example, \p{Greek} or \P{Han}.
+</para>
+
+<para>
+Those that are not part of an identified script are lumped together as
+"Common". The current list of scripts can be found in the documentation for
+the #GUnicodeScript enumeration. Script names for use with \p{} can be
+found by replacing all spaces with underscores, e.g. for Linear B use
+\p{Linear_B}.
+</para>
+
+<para>
+Each character has exactly one general category property, specified by a
+two-letter abbreviation. For compatibility with Perl, negation can be specified
+by including a circumflex between the opening brace and the property name. For
+example, \p{^Lu} is the same as \P{Lu}.
+</para>
+
+<para>
+If only one letter is specified with \p or \P, it includes all the general
+category properties that start with that letter. In this case, in the absence
+of negation, the curly brackets in the escape sequence are optional; these two
+examples have the same effect:
+</para>
+
+<programlisting>
+\p{L}
+\pL
+</programlisting>
+
+<para>
+In addition to the two-letter category codes listed in the
+documentation for the #GUnicodeType enumeration, the following
+general category property codes are supported:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Property codes</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Code</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>C</entry>
+    <entry>Other</entry>
+  </row>
+  <row>
+    <entry>L</entry>
+    <entry>Letter</entry>
+  </row>
+  <row>
+    <entry>M</entry>
+    <entry>Mark</entry>
+  </row>
+  <row>
+    <entry>N</entry>
+    <entry>Number</entry>
+  </row>
+  <row>
+    <entry>P</entry>
+    <entry>Punctuation</entry>
+  </row>
+  <row>
+    <entry>S</entry>
+    <entry>Symbol</entry>
+  </row>
+  <row>
+    <entry>Z</entry>
+    <entry>Separator</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The special property L&amp; is also supported: it matches a character that has
+the Lu, Ll, or Lt property, in other words, a letter that is not classified as
+a modifier or "other".
+</para>
+
+<para>
+The long synonyms for these properties that Perl supports (such as \ep{Letter})
+are not supported by GRegex, nor is it permitted to prefix any of these
+properties with "Is".
+</para>
+
+<para>
+No character that is in the Unicode table has the Cn (unassigned) property.
+Instead, this property is assumed for any code point that is not in the
+Unicode table.
+</para>
+
+<para>
+Specifying caseless matching does not affect these escape sequences.
+For example, \p{Lu} always matches only upper case letters.
+</para>
+
+<para>
+The \X escape matches any number of Unicode characters that form an
+extended Unicode sequence. \X is equivalent to
+</para>
+
+<programlisting>
+(?&gt;\PM\pM*)
+</programlisting>
+
+<para>
+That is, it matches a character without the "mark" property, followed
+by zero or more characters with the "mark" property, and treats the
+sequence as an atomic group (see below). Characters with the "mark"
+property are typically accents that affect the preceding character.
+</para>
+
+<para>
+Matching characters by Unicode property is not fast, because GRegex has
+to search a structure that contains data for over fifteen thousand
+characters. That is why the traditional escape sequences such as \d and
+\w do not use Unicode properties.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Simple assertions</title>
+<para>
+The final use of backslash is for certain simple assertions. An
+assertion specifies a condition that has to be met at a particular point in
+a match, without consuming any characters from the string. The
+use of subpatterns for more complicated assertions is described below.
+The backslashed assertions are:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Simple assertions</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Escape</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>\b</entry>
+    <entry>matches at a word boundary</entry>
+  </row>
+  <row>
+    <entry>\B</entry>
+    <entry>matches when not at a word boundary</entry>
+  </row>
+  <row>
+    <entry>\A</entry>
+    <entry>matches at the start of the string</entry>
+  </row>
+  <row>
+    <entry>\Z</entry>
+    <entry>matches at the end of the string or before a newline at the end of the string</entry>
+  </row>
+  <row>
+    <entry>\z</entry>
+    <entry>matches only at the end of the string</entry>
+  </row>
+  <row>
+    <entry>\G</entry>
+    <entry>matches at first matching position in the string</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+These assertions may not appear in character classes (but note that \b
+has a different meaning, namely the backspace character, inside a
+character class).
+</para>
+
+<para>
+A word boundary is a position in the string where the current
+character and the previous character do not both match \w or \W (i.e.
+one matches \w and the other matches \W), or the start or end of the
+string if the first or last character matches \w, respectively.
+</para>
+
+<para>
+The \A, \Z, and \z assertions differ from the traditional circumflex
+and dollar (described in the next section) in that they only ever match
+at the very start and end of the string, whatever options are
+set. Thus, they are independent of multiline mode. These three assertions
+are not affected by the <varname>G_REGEX_MATCH_NOTBOL</varname> or <varname>G_REGEX_MATCH_NOTEOL</varname> options,
+which affect only the behaviour of the circumflex and dollar metacharacters.
+However, if the start_position argument of a matching function is non-zero,
+indicating that matching is to start at a point other than the beginning of
+the string, \A can never match. The difference between \Z and \z is
+that \Z matches before a newline at the end of the string as well at the
+very end, whereas \z matches only at the end.
+</para>
+
+<para>
+The \G assertion is true only when the current matching position is at
+the start point of the match, as specified by the start_position argument
+to the matching functions. It differs from \A when the value of startoffset is
+non-zero.
+</para>
+
+<para>
+Note, however, that the interpretation of \G, as the start of the
+current match, is subtly different from Perl’s, which defines it as the
+end of the previous match. In Perl, these can be different when the
+previously matched string was empty.
+</para>
+
+<para>
+If all the alternatives of a pattern begin with \G, the expression is
+anchored to the starting match position, and the "anchored" flag is set
+in the compiled regular expression.
+</para>
+</refsect2>
+</refsect1>
+
+<refsect1>
+<title>Circumflex and dollar</title>
+<para>
+Outside a character class, in the default matching mode, the circumflex
+character is an assertion that is true only if the current matching
+point is at the start of the string. If the start_position argument to
+the matching functions is non-zero, circumflex can never match if the
+<varname>G_REGEX_MULTILINE</varname> option is unset. Inside a character class, circumflex
+has an entirely different meaning (see below).
+</para>
+
+<para>
+Circumflex need not be the first character of the pattern if a number
+of alternatives are involved, but it should be the first thing in each
+alternative in which it appears if the pattern is ever to match that
+branch. If all possible alternatives start with a circumflex, that is,
+if the pattern is constrained to match only at the start of the string,
+it is said to be an "anchored" pattern. (There are also other
+constructs that can cause a pattern to be anchored.)
+</para>
+
+<para>
+A dollar character is an assertion that is true only if the current
+matching point is at the end of the string, or immediately
+before a newline at the end of the string (by default). Dollar need not
+be the last character of the pattern if a number of alternatives are
+involved, but it should be the last item in any branch in which it
+appears. Dollar has no special meaning in a character class.
+</para>
+
+<para>
+The meaning of dollar can be changed so that it matches only at the
+very end of the string, by setting the <varname>G_REGEX_DOLLAR_ENDONLY</varname> option at
+compile time. This does not affect the \Z assertion.
+</para>
+
+<para>
+The meanings of the circumflex and dollar characters are changed if the
+<varname>G_REGEX_MULTILINE</varname> option is set. When this is the case,
+a circumflex matches immediately after internal newlines as well as at the
+start of the string. It does not match after a newline that ends the string.
+A dollar matches before any newlines in the string, as well as at the very
+end, when <varname>G_REGEX_MULTILINE</varname> is set. When newline is
+specified as the two-character sequence CRLF, isolated CR and LF characters
+do not indicate newlines.
+</para>
+
+<para>
+For example, the pattern /^abc$/ matches the string "def\nabc" (where
+\n represents a newline) in multiline mode, but not otherwise. Consequently,
+patterns that are anchored in single line mode because all branches start with
+^ are not anchored in multiline mode, and a match for circumflex is possible
+when the <varname>start_position</varname> argument of a matching function
+is non-zero. The <varname>G_REGEX_DOLLAR_ENDONLY</varname> option is ignored
+if <varname>G_REGEX_MULTILINE</varname> is set.
+</para>
+
+<para>
+Note that the sequences \A, \Z, and \z can be used to match the start and
+end of the string in both modes, and if all branches of a pattern start with
+\A it is always anchored, whether or not <varname>G_REGEX_MULTILINE</varname>
+is set.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Full stop (period, dot)</title>
+<para>
+Outside a character class, a dot in the pattern matches any one character
+in the string, including a non-printing character, but not (by
+default) newline. In UTF-8 a character might be more than one byte long.
+</para>
+
+<para>
+When a line ending is defined as a single character, dot never matches that
+character; when the two-character sequence CRLF is used, dot does not match CR
+if it is immediately followed by LF, but otherwise it matches all characters
+(including isolated CRs and LFs). When any Unicode line endings are being
+recognized, dot does not match CR or LF or any of the other line ending
+characters.
+</para>
+
+<para>
+If the <varname>G_REGEX_DOTALL</varname> flag is set, dots match newlines
+as well. The handling of dot is entirely independent of the handling of circumflex
+and dollar, the only relationship being that they both involve newline
+characters. Dot has no special meaning in a character class.
+</para>
+
+<para>
+The behaviour of dot with regard to newlines can be changed. If the
+<varname>G_REGEX_DOTALL</varname> option is set, a dot matches any one
+character, without exception. If newline is defined as the two-character
+sequence CRLF, it takes two dots to match it.
+</para>
+
+<para>
+The handling of dot is entirely independent of the handling of circumflex and
+dollar, the only relationship being that they both involve newlines. Dot has no
+special meaning in a character class.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Matching a single byte</title>
+<para>
+Outside a character class, the escape sequence \C matches any one byte,
+both in and out of UTF-8 mode. Unlike a dot, it always matches any line
+ending characters.
+The feature is provided in Perl in order to match individual bytes in
+UTF-8 mode. Because it breaks up UTF-8 characters into individual
+bytes, what remains in the string may be a malformed UTF-8 string. For
+this reason, the \C escape sequence is best avoided.
+</para>
+
+<para>
+GRegex does not allow \C to appear in lookbehind assertions (described
+below), because in UTF-8 mode this would make it impossible to calculate
+the length of the lookbehind.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Square brackets and character classes</title>
+<para>
+An opening square bracket introduces a character class, terminated by a
+closing square bracket. A closing square bracket on its own is not special. If a closing square bracket is required as a member of the class,
+it should be the first data character in the class (after an initial
+circumflex, if present) or escaped with a backslash.
+</para>
+
+<para>
+A character class matches a single character in the string.  A matched character
+must be in the set of characters defined by the class, unless the first
+character in the class definition is a circumflex, in which case the
+string character must not be in the set defined by the class. If a
+circumflex is actually required as a member of the class, ensure it is
+not the first character, or escape it with a backslash.
+</para>
+
+<para>
+For example, the character class [aeiou] matches any lower case vowel,
+while [^aeiou] matches any character that is not a lower case vowel.
+Note that a circumflex is just a convenient notation for specifying the
+characters that are in the class by enumerating those that are not. A
+class that starts with a circumflex is not an assertion: it still consumes
+a character from the string, and therefore it fails if the current pointer
+is at the end of the string.
+</para>
+
+<para>
+In UTF-8 mode, characters with values greater than 255 can be included
+in a class as a literal string of bytes, or by using the \x{ escaping
+mechanism.
+</para>
+
+<para>
+When caseless matching is set, any letters in a class represent both
+their upper case and lower case versions, so for example, a caseless
+[aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not
+match "A", whereas a caseful version would.
+</para>
+
+<para>
+Characters that might indicate line breaks are never treated
+in any special way when matching character classes, whatever line-ending
+sequence is in use, and whatever setting of the <varname>G_REGEX_DOTALL</varname>
+and <varname>G_REGEX_MULTILINE</varname> options is used. A class such as [^a]
+always matches one of these characters.
+</para>
+
+<para>
+The minus (hyphen) character can be used to specify a range of characters in
+a character class. For example, [d-m] matches any letter
+between d and m, inclusive. If a minus character is required in a
+class, it must be escaped with a backslash or appear in a position
+where it cannot be interpreted as indicating a range, typically as the
+first or last character in the class.
+</para>
+
+<para>
+It is not possible to have the literal character "]" as the end character
+of a range. A pattern such as [W-]46] is interpreted as a class of
+two characters ("W" and "-") followed by a literal string "46]", so it
+would match "W46]" or "-46]". However, if the "]" is escaped with a
+backslash it is interpreted as the end of range, so [W-\]46] is interpreted
+as a class containing a range followed by two other characters.
+The octal or hexadecimal representation of "]" can also be used to end
+a range.
+</para>
+
+<para>
+Ranges operate in the collating sequence of character values. They can
+also be used for characters specified numerically, for example
+[\000-\037]. In UTF-8 mode, ranges can include characters whose values
+are greater than 255, for example [\x{100}-\x{2ff}].
+</para>
+
+<para>
+The character types \d, \D, \p, \P, \s, \S, \w, and \W may also appear
+in a character class, and add the characters that they match to the
+class. For example, [\dABCDEF] matches any hexadecimal digit. A
+circumflex can conveniently be used with the upper case character types to
+specify a more restricted set of characters than the matching lower
+case type. For example, the class [^\W_] matches any letter or digit,
+but not underscore.
+</para>
+
+<para>
+The only metacharacters that are recognized in character classes are
+backslash, hyphen (only where it can be interpreted as specifying a
+range), circumflex (only at the start), opening square bracket (only
+when it can be interpreted as introducing a POSIX class name - see the
+next section), and the terminating closing square bracket. However,
+escaping other non-alphanumeric characters does no harm.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Posix character classes</title>
+<para>
+GRegex supports the POSIX notation for character classes. This uses names
+enclosed by [: and :] within the enclosing square brackets. For example,
+</para>
+
+<programlisting>
+[01[:alpha:]%]
+</programlisting>
+
+<para>
+matches "0", "1", any alphabetic character, or "%". The supported class
+names are
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Posix classes</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Name</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>alnum</entry>
+    <entry>letters and digits</entry>
+  </row>
+  <row>
+    <entry>alpha</entry>
+    <entry>letters</entry>
+  </row>
+  <row>
+    <entry>ascii</entry>
+    <entry>character codes 0 - 127</entry>
+  </row>
+  <row>
+    <entry>blank</entry>
+    <entry>space or tab only</entry>
+  </row>
+  <row>
+    <entry>cntrl</entry>
+    <entry>control characters</entry>
+  </row>
+  <row>
+    <entry>digit</entry>
+    <entry>decimal digits (same as \d)</entry>
+  </row>
+  <row>
+    <entry>graph</entry>
+    <entry>printing characters, excluding space</entry>
+  </row>
+  <row>
+    <entry>lower</entry>
+    <entry>lower case letters</entry>
+  </row>
+  <row>
+    <entry>print</entry>
+    <entry>printing characters, including space</entry>
+  </row>
+  <row>
+    <entry>punct</entry>
+    <entry>printing characters, excluding letters and digits</entry>
+  </row>
+  <row>
+    <entry>space</entry>
+    <entry>white space (not quite the same as \s)</entry>
+  </row>
+  <row>
+    <entry>upper</entry>
+    <entry>upper case letters</entry>
+  </row>
+  <row>
+    <entry>word</entry>
+    <entry>"word" characters (same as \w)</entry>
+  </row>
+  <row>
+    <entry>xdigit</entry>
+    <entry>hexadecimal digits</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13),
+and space (32). Notice that this list includes the VT character (code
+11). This makes "space" different to \s, which does not include VT (for
+Perl compatibility).
+</para>
+
+<para>
+The name "word" is a Perl extension, and "blank" is a GNU extension.
+Another Perl extension is negation, which is indicated by a ^ character
+after the colon. For example,
+</para>
+
+<programlisting>
+[12[:^digit:]]
+</programlisting>
+
+<para>
+matches "1", "2", or any non-digit. GRegex also recognize the
+POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but
+these are not supported, and an error is given if they are encountered.
+</para>
+
+<para>
+In UTF-8 mode, characters with values greater than 128 do not match any
+of the POSIX character classes.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Vertical bar</title>
+<para>
+Vertical bar characters are used to separate alternative patterns. For
+example, the pattern
+</para>
+
+<programlisting>
+ gilbert|sullivan
+</programlisting>
+
+<para>
+matches either "gilbert" or "sullivan". Any number of alternatives may
+appear, and an empty alternative is permitted (matching the empty
+string). The matching process tries each alternative in turn, from
+left to right, and the first one that succeeds is used. If the alternatives are within a subpattern (defined below), "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Internal option setting</title>
+<para>
+The settings of the <varname>G_REGEX_CASELESS</varname>, <varname>G_REGEX_MULTILINE</varname>, <varname>G_REGEX_MULTILINE</varname>,
+and <varname>G_REGEX_EXTENDED</varname> options can be changed from within the pattern by a
+sequence of Perl-style option letters enclosed between "(?" and ")". The
+option letters are
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Option settings</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Option</entry>
+    <entry>Flag</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>i</entry>
+    <entry><varname>G_REGEX_CASELESS</varname></entry>
+  </row>
+  <row>
+    <entry>m</entry>
+    <entry><varname>G_REGEX_MULTILINE</varname></entry>
+  </row>
+  <row>
+    <entry>s</entry>
+    <entry><varname>G_REGEX_DOTALL</varname></entry>
+  </row>
+  <row>
+    <entry>x</entry>
+    <entry><varname>G_REGEX_EXTENDED</varname></entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+For example, (?im) sets caseless, multiline matching. It is also
+possible to unset these options by preceding the letter with a hyphen, and a
+combined setting and unsetting such as (?im-sx), which sets <varname>G_REGEX_CASELESS</varname>
+and <varname>G_REGEX_MULTILINE</varname> while unsetting <varname>G_REGEX_DOTALL</varname> and <varname>G_REGEX_EXTENDED</varname>,
+is also permitted. If a letter appears both before and after the
+hyphen, the option is unset.
+</para>
+
+<para>
+When an option change occurs at top level (that is, not inside subpattern
+parentheses), the change applies to the remainder of the pattern
+that follows.
+</para>
+
+<para>
+An option change within a subpattern (see below for a description of subpatterns)
+affects only that part of the current pattern that follows it, so
+</para>
+
+<programlisting>
+(a(?i)b)c
+</programlisting>
+
+<para>
+matches abc and aBc and no other strings (assuming <varname>G_REGEX_CASELESS</varname> is not
+used). By this means, options can be made to have different settings
+in different parts of the pattern. Any changes made in one alternative
+do carry on into subsequent branches within the same subpattern. For
+example,
+</para>
+
+<programlisting>
+(a(?i)b|c)
+</programlisting>
+
+<para>
+matches "ab", "aB", "c", and "C", even though when matching "C" the
+first branch is abandoned before the option setting. This is because
+the effects of option settings happen at compile time. There would be
+some very weird behaviour otherwise.
+</para>
+
+<para>
+The options <varname>G_REGEX_UNGREEDY</varname> and
+<varname>G_REGEX_EXTRA</varname> and <varname>G_REGEX_DUPNAMES</varname>
+can be changed in the same way as the Perl-compatible options by using
+the characters U, X and J respectively.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Subpatterns</title>
+<para>
+Subpatterns are delimited by parentheses (round brackets), which can be
+nested. Turning part of a pattern into a subpattern does two things:
+</para>
+
+<itemizedlist>
+<listitem><para>
+It localizes a set of alternatives. For example, the pattern
+cat(aract|erpillar|) matches one of the words "cat", "cataract", or
+"caterpillar". Without the parentheses, it would match "cataract",
+"erpillar" or an empty string.
+</para></listitem>
+<listitem><para>
+It sets up the subpattern as a capturing subpattern. This means
+that, when the whole pattern matches, that portion of the
+string that matched the subpattern can be obtained using <function>g_match_info_fetch()</function>.
+Opening parentheses are counted from left to right (starting from 1, as
+subpattern 0 is the whole matched string) to obtain numbers for the
+capturing subpatterns.
+</para></listitem>
+</itemizedlist>
+
+<para>
+For example, if the string "the red king" is matched against the pattern
+</para>
+
+<programlisting>
+the ((red|white) (king|queen))
+</programlisting>
+
+<para>
+the captured substrings are "red king", "red", and "king", and are numbered 1, 2, and 3, respectively.
+</para>
+
+<para>
+The fact that plain parentheses fulfil two functions is not always
+helpful. There are often times when a grouping subpattern is required
+without a capturing requirement. If an opening parenthesis is followed
+by a question mark and a colon, the subpattern does not do any capturing,
+and is not counted when computing the number of any subsequent
+capturing subpatterns. For example, if the string "the white queen" is
+matched against the pattern
+</para>
+
+<programlisting>
+the ((?:red|white) (king|queen))
+</programlisting>
+
+<para>
+the captured substrings are "white queen" and "queen", and are numbered
+1 and 2. The maximum number of capturing subpatterns is 65535.
+</para>
+
+<para>
+As a convenient shorthand, if any option settings are required at the
+start of a non-capturing subpattern, the option letters may appear
+between the "?" and the ":". Thus the two patterns
+</para>
+
+<programlisting>
+(?i:saturday|sunday)
+(?:(?i)saturday|sunday)
+</programlisting>
+
+<para>
+match exactly the same set of strings. Because alternative branches are
+tried from left to right, and options are not reset until the end of
+the subpattern is reached, an option setting in one branch does affect
+subsequent branches, so the above patterns match "SUNDAY" as well as
+"Saturday".
+</para>
+</refsect1>
+
+<refsect1>
+<title>Named subpatterns</title>
+<para>
+Identifying capturing parentheses by number is simple, but it can be
+very hard to keep track of the numbers in complicated regular expressions.
+Furthermore, if an expression is modified, the numbers may
+change. To help with this difficulty, GRegex supports the naming of
+subpatterns.  A subpattern can be named in one of three ways: (?&lt;name&gt;...) or
+(?'name'...) as in Perl, or (?P&lt;name&gt;...) as in Python.
+References to capturing parentheses from other
+parts of the pattern, such as backreferences, recursion, and conditions,
+can be made by name as well as by number.
+</para>
+
+<para>
+Names consist of up to 32 alphanumeric characters and underscores. Named
+capturing parentheses are still allocated numbers as well as names, exactly as
+if the names were not present.
+By default, a name must be unique within a pattern, but it is possible to relax
+this constraint by setting the <varname>G_REGEX_DUPNAMES</varname> option at
+compile time. This can be useful for patterns where only one instance of the
+named parentheses can match. Suppose you want to match the name of a weekday,
+either as a 3-letter abbreviation or as the full name, and in both cases you
+want to extract the abbreviation. This pattern (ignoring the line breaks) does
+the job:
+</para>
+
+<programlisting>
+(?&lt;DN&gt;Mon|Fri|Sun)(?:day)?|
+(?&lt;DN&gt;Tue)(?:sday)?|
+(?&lt;DN&gt;Wed)(?:nesday)?|
+(?&lt;DN&gt;Thu)(?:rsday)?|
+(?&lt;DN&gt;Sat)(?:urday)?
+</programlisting>
+
+<para>
+There are five capturing substrings, but only one is ever set after a match.
+The function for extracting the data by name returns the substring
+for the first (and in this example, the only) subpattern of that name that
+matched. This saves searching to find which numbered subpattern it was. If you
+make a reference to a non-unique named subpattern from elsewhere in the
+pattern, the one that corresponds to the lowest number is used.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Repetition</title>
+<para>
+Repetition is specified by quantifiers, which can follow any of the
+following items:
+</para>
+
+<itemizedlist>
+<listitem><para>a literal data character</para></listitem>
+<listitem><para>the dot metacharacter</para></listitem>
+<listitem><para>the \C escape sequence</para></listitem>
+<listitem><para>the \X escape sequence (in UTF-8 mode)</para></listitem>
+<listitem><para>the \R escape sequence</para></listitem>
+<listitem><para>an escape such as \d that matches a single character</para></listitem>
+<listitem><para>a character class</para></listitem>
+<listitem><para>a back reference (see next section)</para></listitem>
+<listitem><para>a parenthesized subpattern (unless it is an assertion)</para></listitem>
+</itemizedlist>
+
+<para>
+The general repetition quantifier specifies a minimum and maximum number
+of permitted matches, by giving the two numbers in curly brackets
+(braces), separated by a comma. The numbers must be less than 65536,
+and the first must be less than or equal to the second. For example:
+</para>
+
+<programlisting>
+z{2,4}
+</programlisting>
+
+<para>
+matches "zz", "zzz", or "zzzz". A closing brace on its own is not a
+special character. If the second number is omitted, but the comma is
+present, there is no upper limit; if the second number and the comma
+are both omitted, the quantifier specifies an exact number of required
+matches. Thus
+</para>
+
+<programlisting>
+[aeiou]{3,}
+</programlisting>
+
+<para>
+matches at least 3 successive vowels, but may match many more, while
+</para>
+
+<programlisting>
+\d{8}
+</programlisting>
+
+<para>
+matches exactly 8 digits. An opening curly bracket that appears in a
+position where a quantifier is not allowed, or one that does not match
+the syntax of a quantifier, is taken as a literal character. For example,
+{,6} is not a quantifier, but a literal string of four characters.
+</para>
+
+<para>
+In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to
+individual bytes. Thus, for example, \x{100}{2} matches two UTF-8
+characters, each of which is represented by a two-byte sequence. Similarly,
+\X{3} matches three Unicode extended sequences, each of which may be
+several bytes long (and they may be of different lengths).
+</para>
+
+<para>
+The quantifier {0} is permitted, causing the expression to behave as if
+the previous item and the quantifier were not present.
+</para>
+
+<para>
+For convenience, the three most common quantifiers have single-character
+abbreviations:
+</para>
+
+<table frame="all" colsep="1" rowsep="1">
+<title>Abbreviations for quantifiers</title>
+<tgroup cols="2">
+<colspec colnum="1" align="center"/>
+<thead>
+  <row>
+    <entry>Abbreviation</entry>
+    <entry>Meaning</entry>
+  </row>
+</thead>
+<tbody>
+  <row>
+    <entry>*</entry>
+    <entry>is equivalent to {0,}</entry>
+  </row>
+  <row>
+    <entry>+</entry>
+    <entry>is equivalent to {1,}</entry>
+  </row>
+  <row>
+    <entry>?</entry>
+    <entry>is equivalent to {0,1}</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+It is possible to construct infinite loops by following a subpattern
+that can match no characters with a quantifier that has no upper limit,
+for example:
+</para>
+
+<programlisting>
+(a?)*
+</programlisting>
+
+<para>
+Because there are cases where this can be useful, such patterns are
+accepted, but if any repetition of the subpattern does in fact match
+no characters, the loop is forcibly broken.
+</para>
+
+<para>
+By default, the quantifiers are "greedy", that is, they match as much
+as possible (up to the maximum number of permitted times), without
+causing the rest of the pattern to fail. The classic example of where
+this gives problems is in trying to match comments in C programs. These
+appear between /* and */ and within the comment, individual * and /
+characters may appear. An attempt to match C comments by applying the
+pattern
+</para>
+
+<programlisting>
+/\*.*\*/
+</programlisting>
+
+<para>
+to the string
+</para>
+
+<programlisting>
+/* first comment */  not comment  /* second comment */
+</programlisting>
+
+<para>
+fails, because it matches the entire string owing to the greediness of
+the .* item.
+</para>
+
+<para>
+However, if a quantifier is followed by a question mark, it ceases to
+be greedy, and instead matches the minimum number of times possible, so
+the pattern
+</para>
+
+<programlisting>
+/\*.*?\*/
+</programlisting>
+
+<para>
+does the right thing with the C comments. The meaning of the various
+quantifiers is not otherwise changed, just the preferred number of
+matches. Do not confuse this use of question mark with its use as a
+quantifier in its own right. Because it has two uses, it can sometimes
+appear doubled, as in
+</para>
+
+<programlisting>
+\d??\d
+</programlisting>
+
+<para>
+which matches one digit by preference, but can match two if that is the
+only way the rest of the pattern matches.
+</para>
+
+<para>
+If the <varname>G_REGEX_UNGREEDY</varname> flag is set, the quantifiers are not greedy
+by default, but individual ones can be made greedy by following them with
+a question mark. In other words, it inverts the default behaviour.
+</para>
+
+<para>
+When a parenthesized subpattern is quantified with a minimum repeat
+count that is greater than 1 or with a limited maximum, more memory is
+required for the compiled pattern, in proportion to the size of the
+minimum or maximum.
+</para>
+
+<para>
+If a pattern starts with .* or .{0,} and the <varname>G_REGEX_DOTALL</varname> flag
+is set, thus allowing the dot to match newlines, the
+pattern is implicitly anchored, because whatever follows will be tried
+against every character position in the string, so there is no
+point in retrying the overall match at any position after the first.
+GRegex normally treats such a pattern as though it were preceded by \A.
+</para>
+
+<para>
+In cases where it is known that the string contains no newlines, it
+is worth setting <varname>G_REGEX_DOTALL</varname> in order to obtain this optimization,
+or alternatively using ^ to indicate anchoring explicitly.
+</para>
+
+<para>
+However, there is one situation where the optimization cannot be used.
+When .* is inside capturing parentheses that are the subject of a
+backreference elsewhere in the pattern, a match at the start may fail
+where a later one succeeds. Consider, for example:
+</para>
+
+<programlisting>
+(.*)abc\1
+</programlisting>
+
+<para>
+If the string is "xyz123abc123" the match point is the fourth character.
+For this reason, such a pattern is not implicitly anchored.
+</para>
+
+<para>
+When a capturing subpattern is repeated, the value captured is the
+substring that matched the final iteration. For example, after
+</para>
+
+<programlisting>
+(tweedle[dume]{3}\s*)+
+</programlisting>
+
+<para>
+has matched "tweedledum tweedledee" the value of the captured substring
+is "tweedledee". However, if there are nested capturing subpatterns,
+the corresponding captured values may have been set in previous iterations.
+For example, after
+</para>
+
+<programlisting>
+/(a|(b))+/
+</programlisting>
+
+<para>
+matches "aba" the value of the second captured substring is "b".
+</para>
+</refsect1>
+
+<refsect1>
+<title>Atomic grouping and possessive quantifiers</title>
+<para>
+With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
+repetition, failure of what follows normally causes the repeated
+item to be re-evaluated to see if a different number
+of repeats allows the rest of the pattern to match. Sometimes it
+is useful to prevent this, either to change the nature of the
+match, or to cause it fail earlier than it otherwise might, when the
+author of the pattern knows there is no point in carrying on.
+</para>
+
+<para>
+Consider, for example, the pattern \d+foo when applied to the string
+</para>
+
+<programlisting>
+123456bar
+</programlisting>
+
+<para>
+After matching all 6 digits and then failing to match "foo", the normal
+action of the matcher is to try again with only 5 digits matching the
+\d+ item, and then with 4, and so on, before ultimately failing.
+"Atomic grouping" (a term taken from Jeffrey Friedl’s book) provides
+the means for specifying that once a subpattern has matched, it is not
+to be re-evaluated in this way.
+</para>
+
+<para>
+If we use atomic grouping for the previous example, the matcher
+give up immediately on failing to match "foo" the first time. The notation
+is a kind of special parenthesis, starting with (?&gt; as in this
+example:
+</para>
+
+<programlisting>
+(?>\d+)foo
+</programlisting>
+
+<para>
+This kind of parenthesis "locks up" the part of the pattern it contains
+once it has matched, and a failure further into the pattern is
+prevented from backtracking into it. Backtracking past it to previous
+items, however, works as normal.
+</para>
+
+<para>
+An alternative description is that a subpattern of this type matches
+the string of characters that an identical standalone pattern would
+match, if anchored at the current point in the string.
+</para>
+
+<para>
+Atomic grouping subpatterns are not capturing subpatterns. Simple cases
+such as the above example can be thought of as a maximizing repeat that
+must swallow everything it can. So, while both \d+ and \d+? are prepared
+to adjust the number of digits they match in order to make the
+rest of the pattern match, (?>\d+) can only match an entire sequence of
+digits.
+</para>
+
+<para>
+Atomic groups in general can of course contain arbitrarily complicated
+subpatterns, and can be nested. However, when the subpattern for an
+atomic group is just a single repeated item, as in the example above, a
+simpler notation, called a "possessive quantifier" can be used. This
+consists of an additional + character following a quantifier. Using
+this notation, the previous example can be rewritten as
+</para>
+
+<programlisting>
+\d++foo
+</programlisting>
+
+<para>
+Possessive quantifiers are always greedy; the setting of the
+<varname>G_REGEX_UNGREEDY</varname> option is ignored. They are a convenient notation for the
+simpler forms of atomic group. However, there is no difference in the
+meaning of a possessive quantifier and the equivalent
+atomic group, though there may be a performance difference;
+possessive quantifiers should be slightly faster.
+</para>
+
+<para>
+The possessive quantifier syntax is an extension to the Perl syntax.
+It was invented by Jeffrey Friedl in the first edition of his book and
+then implemented by Mike McCloskey in Sun's Java package.
+It ultimately found its way into Perl at release 5.10.
+</para>
+
+<para>
+GRegex has an optimization that automatically "possessifies" certain simple
+pattern constructs. For example, the sequence A+B is treated as A++B because
+there is no point in backtracking into a sequence of A's when B must follow.
+</para>
+
+<para>
+When a pattern contains an unlimited repeat inside a subpattern that
+can itself be repeated an unlimited number of times, the use of an
+atomic group is the only way to avoid some failing matches taking a
+very long time indeed. The pattern
+</para>
+ 
+<programlisting>
+(\D+|&lt;\d+&gt;)*[!?]
+</programlisting>
+
+<para>
+matches an unlimited number of substrings that either consist of non-
+digits, or digits enclosed in &lt;&gt;, followed by either ! or ?. When it
+matches, it runs quickly. However, if it is applied to
+</para>
+
+<programlisting>
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+</programlisting>
+
+<para>
+it takes a long time before reporting failure. This is because the
+string can be divided between the internal \D+ repeat and the external
+* repeat in a large number of ways, and all have to be tried. (The
+example uses [!?] rather than a single character at the end, because
+GRegex has an optimization that allows for fast failure
+when a single character is used. It remember the last single character
+that is required for a match, and fail early if it is not present
+in the string.) If the pattern is changed so that it uses an atomic
+group, like this:
+</para>
+
+<programlisting>
+((?>\D+)|&lt;\d+&gt;)*[!?]
+</programlisting>
+
+<para>
+sequences of non-digits cannot be broken, and failure happens quickly.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Back references</title>
+<para>
+Outside a character class, a backslash followed by a digit greater than
+0 (and possibly further digits) is a back reference to a capturing subpattern
+earlier (that is, to its left) in the pattern, provided there have been that
+many previous capturing left parentheses.
+</para>
+
+<para>
+However, if the decimal number following the backslash is less than 10,
+it is always taken as a back reference, and causes an error only if
+there are not that many capturing left parentheses in the entire pattern.
+In other words, the parentheses that are referenced need not be
+to the left of the reference for numbers less than 10. A "forward back
+reference" of this type can make sense when a repetition is involved and
+the subpattern to the right has participated in an earlier iteration.
+</para>
+
+<para>
+It is not possible to have a numerical "forward back reference" to subpattern
+whose number is 10 or more using this syntax because a sequence such as \e50 is
+interpreted as a character defined in octal. See the subsection entitled
+"Non-printing characters" above for further details of the handling of digits
+following a backslash. There is no such problem when named parentheses are used.
+A back reference to any subpattern is possible using named parentheses (see below).
+</para>
+
+<para>
+Another way of avoiding the ambiguity inherent in the use of digits following a
+backslash is to use the \g escape sequence (introduced in Perl 5.10.)
+This escape must be followed by a positive or a negative number,
+optionally enclosed in braces.
+</para>
+
+<para>
+A positive number specifies an absolute reference without the ambiguity that is
+present in the older syntax. It is also useful when literal digits follow the
+reference. A negative number is a relative reference. Consider "(abc(def)ghi)\g{-1}",
+the sequence \g{-1} is a reference to the most recently started capturing
+subpattern before \g, that is, is it equivalent to \2. Similarly, \g{-2}
+would be equivalent to \1. The use of relative references can be helpful in
+long patterns, and also in patterns that are created by joining together
+fragments that contain references within themselves.
+</para>
+
+<para>
+A back reference matches whatever actually matched the capturing subpattern
+in the current string, rather than anything matching
+the subpattern itself (see "Subpatterns as subroutines" below for a way
+of doing that). So the pattern
+</para>
+
+<programlisting>
+(sens|respons)e and \1ibility
+</programlisting>
+
+<para>
+matches "sense and sensibility" and "response and responsibility", but
+not "sense and responsibility". If caseful matching is in force at the
+time of the back reference, the case of letters is relevant. For example,
+</para>
+
+<programlisting>
+((?i)rah)\s+\1
+</programlisting>
+
+<para>
+matches "rah rah" and "RAH RAH", but not "RAH rah", even though the
+original capturing subpattern is matched caselessly.
+</para>
+
+<para>
+Back references to named subpatterns use the Perl syntax \k&lt;name&gt; or \k'name'
+or the Python syntax (?P=name). We could rewrite the above example in either of
+the following ways:
+</para>
+
+<programlisting>
+(?&lt;p1&gt;(?i)rah)\s+\k&lt;p1&gt;
+(?P&lt;p1&gt;(?i)rah)\s+(?P=p1)
+</programlisting>
+
+<para>
+A subpattern that is referenced by name may appear in the pattern before or
+after the reference.
+</para>
+
+<para>
+There may be more than one back reference to the same subpattern. If a
+subpattern has not actually been used in a particular match, any back
+references to it always fail. For example, the pattern
+</para>
+
+<programlisting>
+(a|(bc))\2
+</programlisting>
+
+<para>
+always fails if it starts to match "a" rather than "bc". Because there
+may be many capturing parentheses in a pattern, all digits following
+the backslash are taken as part of a potential back reference number.
+If the pattern continues with a digit character, some delimiter must be
+used to terminate the back reference. If the <varname>G_REGEX_EXTENDED</varname> flag is
+set, this can be whitespace. Otherwise an empty comment (see "Comments" below) can be used.
+</para>
+
+<para>
+A back reference that occurs inside the parentheses to which it refers
+fails when the subpattern is first used, so, for example, (a\1) never
+matches. However, such references can be useful inside repeated subpatterns.
+For example, the pattern
+</para>
+
+<programlisting>
+(a|b\1)+
+</programlisting>
+
+<para>
+matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration
+of the subpattern, the back reference matches the character
+string corresponding to the previous iteration. In order for this to
+work, the pattern must be such that the first iteration does not need
+to match the back reference. This can be done using alternation, as in
+the example above, or by a quantifier with a minimum of zero.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Assertions</title>
+<para>
+An assertion is a test on the characters following or preceding the
+current matching point that does not actually consume any characters.
+The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are
+described above.
+</para>
+
+<para>
+More complicated assertions are coded as subpatterns. There are two
+kinds: those that look ahead of the current position in the
+string, and those that look behind it. An assertion subpattern is
+matched in the normal way, except that it does not cause the current
+matching position to be changed.
+</para>
+
+<para>
+Assertion subpatterns are not capturing subpatterns, and may not be
+repeated, because it makes no sense to assert the same thing several
+times. If any kind of assertion contains capturing subpatterns within
+it, these are counted for the purposes of numbering the capturing
+subpatterns in the whole pattern. However, substring capturing is carried
+out only for positive assertions, because it does not make sense for
+negative assertions.
+</para>
+
+<refsect2>
+<title>Lookahead assertions</title>
+<para>
+Lookahead assertions start with (?= for positive assertions and (?! for
+negative assertions. For example,
+</para>
+
+<programlisting>
+\w+(?=;)
+</programlisting>
+
+<para>
+matches a word followed by a semicolon, but does not include the semicolon
+in the match, and
+</para>
+
+<programlisting>
+foo(?!bar)
+</programlisting>
+
+<para>
+matches any occurrence of "foo" that is not followed by "bar". Note
+that the apparently similar pattern
+</para>
+
+<programlisting>
+(?!foo)bar
+</programlisting>
+
+<para>
+does not find an occurrence of "bar" that is preceded by something
+other than "foo"; it finds any occurrence of "bar" whatsoever, because
+the assertion (?!foo) is always true when the next three characters are
+"bar". A lookbehind assertion is needed to achieve the other effect.
+</para>
+
+<para>
+If you want to force a matching failure at some point in a pattern, the
+most convenient way to do it is with (?!) because an empty string
+always matches, so an assertion that requires there not to be an empty
+string must always fail.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Lookbehind assertions</title>
+<para>
+Lookbehind assertions start with (?&lt;= for positive assertions and (?&lt;!
+for negative assertions. For example,
+</para>
+
+<programlisting>
+(?&lt;!foo)bar
+</programlisting>
+
+<para>
+does find an occurrence of "bar" that is not preceded by "foo". The
+contents of a lookbehind assertion are restricted such that all the
+strings it matches must have a fixed length. However, if there are
+several top-level alternatives, they do not all have to have the same
+fixed length. Thus
+</para>
+
+<programlisting>
+(?&lt;=bullock|donkey)
+</programlisting>
+
+<para>
+is permitted, but
+</para>
+
+<programlisting>
+(?&lt;!dogs?|cats?)
+</programlisting>
+
+<para>
+causes an error at compile time. Branches that match different length
+strings are permitted only at the top level of a lookbehind assertion.
+An assertion such as
+</para>
+
+<programlisting>
+(?&lt;=ab(c|de))
+</programlisting>
+
+<para>
+is not permitted, because its single top-level branch can match two
+different lengths, but it is acceptable if rewritten to use two top-
+level branches:
+</para>
+
+<programlisting>
+(?&lt;=abc|abde)
+</programlisting>
+
+<para>
+The implementation of lookbehind assertions is, for each alternative,
+to temporarily move the current position back by the fixed length and
+then try to match. If there are insufficient characters before the
+current position, the assertion fails.
+</para>
+
+<para>
+GRegex does not allow the \C escape (which matches a single byte in UTF-8
+mode) to appear in lookbehind assertions, because it makes it impossible
+to calculate the length of the lookbehind. The \X and \R escapes, which can
+match different numbers of bytes, are also not permitted.
+</para>
+
+<para>
+Possessive quantifiers can be used in conjunction with lookbehind assertions to
+specify efficient matching at the end of the subject string. Consider a simple
+pattern such as
+</para>
+
+<programlisting>
+abcd$
+</programlisting>
+
+<para>
+when applied to a long string that does not match. Because matching
+proceeds from left to right, GRegex will look for each "a" in the string
+and then see if what follows matches the rest of the pattern. If the
+pattern is specified as
+</para>
+
+<programlisting>
+^.*abcd$
+</programlisting>
+
+<para>
+the initial .* matches the entire string at first, but when this fails
+(because there is no following "a"), it backtracks to match all but the
+last character, then all but the last two characters, and so on. Once
+again the search for "a" covers the entire string, from right to left,
+so we are no better off. However, if the pattern is written as
+</para>
+
+<programlisting>
+^.*+(?&lt;=abcd)
+</programlisting>
+
+<para>
+there can be no backtracking for the .*+ item; it can match only the
+entire string. The subsequent lookbehind assertion does a single test
+on the last four characters. If it fails, the match fails immediately.
+For long strings, this approach makes a significant difference to the
+processing time.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Using multiple assertions</title>
+<para>
+Several assertions (of any sort) may occur in succession. For example,
+</para>
+
+<programlisting>
+(?&lt;=\d{3})(?&lt;!999)foo
+</programlisting>
+
+<para>
+matches "foo" preceded by three digits that are not "999". Notice that
+each of the assertions is applied independently at the same point in
+the string. First there is a check that the previous three
+characters are all digits, and then there is a check that the same
+three characters are not "999". This pattern does not match "foo" preceded
+by six characters, the first of which are digits and the last
+three of which are not "999". For example, it doesn’t match "123abcfoo".
+A pattern to do that is
+</para>
+
+<programlisting>
+(?&lt;=\d{3}...)(?&lt;!999)foo
+</programlisting>
+
+<para>
+This time the first assertion looks at the preceding six characters,
+checking that the first three are digits, and then the second assertion
+checks that the preceding three characters are not "999".
+</para>
+
+<para>
+Assertions can be nested in any combination. For example,
+</para>
+
+<programlisting>
+(?&lt;=(?&lt;!foo)bar)baz
+</programlisting>
+
+<para>
+matches an occurrence of "baz" that is preceded by "bar" which in turn
+is not preceded by "foo", while
+</para>
+
+<programlisting>
+(?&lt;=\d{3}(?!999)...)foo
+</programlisting>
+
+<para>
+is another pattern that matches "foo" preceded by three digits and any
+three characters that are not "999".
+</para>
+</refsect2>
+</refsect1>
+
+<refsect1>
+<title>Conditional subpatterns</title>
+<para>
+It is possible to cause the matching process to obey a subpattern
+conditionally or to choose between two alternative subpatterns, depending
+on the result of an assertion, or whether a previous capturing subpattern
+matched or not. The two possible forms of conditional subpattern are
+</para>
+
+<programlisting>
+(?(condition)yes-pattern)
+(?(condition)yes-pattern|no-pattern)
+</programlisting>
+
+<para>
+If the condition is satisfied, the yes-pattern is used; otherwise the
+no-pattern (if present) is used. If there are more than two alternatives
+in the subpattern, a compile-time error occurs.
+</para>
+
+<para>
+There are four kinds of condition: references to subpatterns, references to
+recursion, a pseudo-condition called DEFINE, and assertions.
+</para>
+
+<refsect2>
+<title>Checking for a used subpattern by number</title>
+<para>
+If the text between the parentheses consists of a sequence of digits, the
+condition is true if the capturing subpattern of that number has previously
+matched.
+</para>
+
+<para>
+Consider the following pattern, which contains non-significant white space
+to make it more readable (assume the <varname>G_REGEX_EXTENDED</varname>)
+and to divide it into three parts for ease of discussion:
+</para>
+
+<programlisting>
+( \( )?    [^()]+    (?(1) \) )
+</programlisting>
+
+<para>
+The first part matches an optional opening parenthesis, and if that
+character is present, sets it as the first captured substring. The second
+part matches one or more characters that are not parentheses. The
+third part is a conditional subpattern that tests whether the first set
+of parentheses matched or not. If they did, that is, if string started
+with an opening parenthesis, the condition is true, and so the yes-pattern
+is executed and a closing parenthesis is required. Otherwise,
+since no-pattern is not present, the subpattern matches nothing. In
+other words, this pattern matches a sequence of non-parentheses,
+optionally enclosed in parentheses.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Checking for a used subpattern by name</title>
+<para>
+Perl uses the syntax (?(&lt;name&gt;)...) or (?('name')...) to test for a used
+subpattern by name, the Python syntax (?(name)...) is also recognized. However,
+there is a possible ambiguity with this syntax, because subpattern names may
+consist entirely of digits. GRegex looks first for a named subpattern; if it
+cannot find one and the name consists entirely of digits, GRegex looks for a
+subpattern of that number, which must be greater than zero. Using subpattern
+names that consist entirely of digits is not recommended.
+</para>
+
+<para>
+Rewriting the above example to use a named subpattern gives this:
+</para>
+
+<programlisting>
+(?&lt;OPEN&gt; \( )?    [^()]+    (?(&lt;OPEN&gt;) \) )
+</programlisting>
+</refsect2>
+
+<refsect2>
+<title>Checking for pattern recursion</title>
+<para>
+If the condition is the string (R), and there is no subpattern with the name R,
+the condition is true if a recursive call to the whole pattern or any
+subpattern has been made. If digits or a name preceded by ampersand follow the
+letter R, for example:
+</para>
+
+<programlisting>
+(?(R3)...)
+(?(R&amp;name)...)
+</programlisting>
+
+<para>
+the condition is true if the most recent recursion is into the subpattern whose
+number or name is given. This condition does not check the entire recursion
+stack.
+</para>
+
+<para>
+At "top level", all these recursion test conditions are false. Recursive
+patterns are described below.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Defining subpatterns for use by reference only</title>
+<para>
+If the condition is the string (DEFINE), and there is no subpattern with the
+name DEFINE, the condition is always false. In this case, there may be only one
+alternative in the subpattern. It is always skipped if control reaches this
+point in the pattern; the idea of DEFINE is that it can be used to define
+"subroutines" that can be referenced from elsewhere. (The use of "subroutines"
+is described below.) For example, a pattern to match an IPv4 address could be
+written like this (ignore whitespace and line breaks):
+</para>
+
+<programlisting>
+(?(DEFINE) (?&lt;byte&gt; 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
+\b (?&amp;byte) (\.(?&amp;byte)){3} \b
+</programlisting>
+
+<para>
+The first part of the pattern is a DEFINE group inside which another group
+named "byte" is defined. This matches an individual component of an IPv4
+address (a number less than 256). When matching takes place, this part of the
+pattern is skipped because DEFINE acts like a false condition.
+</para>
+
+<para>
+The rest of the pattern uses references to the named group to match the four
+dot-separated components of an IPv4 address, insisting on a word boundary at
+each end.
+</para>
+</refsect2>
+
+<refsect2>
+<title>Assertion conditions</title>
+<para>
+If the condition is not in any of the above formats, it must be an
+assertion. This may be a positive or negative lookahead or lookbehind
+assertion. Consider this pattern, again containing non-significant
+white space, and with the two alternatives on the second line:
+</para>
+
+<programlisting>
+(?(?=[^a-z]*[a-z])
+\d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
+</programlisting>
+
+<para>
+The condition is a positive lookahead assertion that matches an
+optional sequence of non-letters followed by a letter. In other words,
+it tests for the presence of at least one letter in the string. If a
+letter is found, the string is matched against the first alternative;
+otherwise it is matched against the second. This pattern matches
+strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
+letters and dd are digits.
+</para>
+</refsect2>
+</refsect1>
+
+<refsect1>
+<title>Comments</title>
+<para>
+The sequence (?# marks the start of a comment that continues up to the
+next closing parenthesis. Nested parentheses are not permitted. The
+characters that make up a comment play no part in the pattern matching
+at all.
+</para>
+
+<para>
+If the <varname>G_REGEX_EXTENDED</varname> option is set, an unescaped #
+character outside a character class introduces a comment that continues to
+immediately after the next newline in the pattern.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Recursive patterns</title>
+<para>
+Consider the problem of matching a string in parentheses, allowing for
+unlimited nested parentheses. Without the use of recursion, the best
+that can be done is to use a pattern that matches up to some fixed
+depth of nesting. It is not possible to handle an arbitrary nesting
+depth.
+</para>
+
+<para>
+For some time, Perl has provided a facility that allows regular expressions to
+recurse (amongst other things). It does this by interpolating Perl code in the
+expression at run time, and the code can refer to the expression itself. A Perl
+pattern using code interpolation to solve the parentheses problem can be
+created like this:
+</para>
+
+<programlisting>
+$re = qr{\( (?: (?&gt;[^()]+) | (?p{$re}) )* \)}x;
+</programlisting>
+
+<para>
+The (?p{...}) item interpolates Perl code at run time, and in this case refers
+recursively to the pattern in which it appears.
+</para>
+
+<para>
+Obviously, GRegex cannot support the interpolation of Perl code. Instead, it
+supports special syntax for recursion of the entire pattern, and also for
+individual subpattern recursion. This kind of recursion was introduced into
+Perl at release 5.10.
+</para>
+
+<para>
+A special item that consists of (? followed by a number greater than zero and a
+closing parenthesis is a recursive call of the subpattern of the given number,
+provided that it occurs inside that subpattern. (If not, it is a "subroutine"
+call, which is described in the next section.) The special item (?R) or (?0) is
+a recursive call of the entire regular expression.
+</para>
+
+<para>
+In GRegex (like Python, but unlike Perl), a recursive subpattern call is always
+treated as an atomic group. That is, once it has matched some of the subject
+string, it is never re-entered, even if it contains untried alternatives and
+there is a subsequent matching failure.
+</para>
+
+<para>
+This pattern solves the nested parentheses problem (assume the
+<varname>G_REGEX_EXTENDED</varname> option is set so that white space is
+ignored):
+</para>
+
+<programlisting>
+\( ( (?&gt;[^()]+) | (?R) )* \)
+</programlisting>
+
+<para>
+First it matches an opening parenthesis. Then it matches any number of
+substrings which can either be a sequence of non-parentheses, or a
+recursive match of the pattern itself (that is, a correctly parenthesized
+substring). Finally there is a closing parenthesis.
+</para>
+
+<para>
+If this were part of a larger pattern, you would not want to recurse
+the entire pattern, so instead you could use this:
+</para>
+
+<programlisting>
+( \( ( (?&gt;[^()]+) | (?1) )* \) )
+</programlisting>
+
+<para>
+We have put the pattern into parentheses, and caused the recursion to
+refer to them instead of the whole pattern. In a larger pattern, keeping
+track of parenthesis numbers can be tricky. It may be more convenient to
+use named parentheses instead.
+The Perl syntax for this is (?&amp;name); GRegex also supports the(?P>name)
+syntax. We could rewrite the above example as follows:
+</para>
+
+<programlisting>
+(?&lt;pn&gt; \( ( (?&gt;[^()]+) | (?&amp;pn) )* \) )
+</programlisting>
+
+<para>
+If there is more than one subpattern with the same name, the earliest one is
+used. This particular example pattern contains nested unlimited repeats, and so
+the use of atomic grouping for matching strings of non-parentheses is important
+when applying the pattern to strings that do not match.
+For example, when this pattern is applied to
+</para>
+
+<programlisting>
+(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+</programlisting>
+
+<para>
+it yields "no match" quickly. However, if atomic grouping is not used,
+the match runs for a very long time indeed because there are so many
+different ways the + and * repeats can carve up the string, and all
+have to be tested before failure can be reported.
+</para>
+
+<para>
+At the end of a match, the values set for any capturing subpatterns are
+those from the outermost level of the recursion at which the subpattern
+value is set.
+
+<!-- Callouts are not supported by GRegex
+If you want to obtain intermediate values, a callout
+function can be used (see below and the pcrecallout documentation). -->
+
+If the pattern above is matched against
+</para>
+
+<programlisting>
+(ab(cd)ef)
+</programlisting>
+
+<para>
+the value for the capturing parentheses is "ef", which is the last
+value taken on at the top level. If additional parentheses are added,
+giving
+</para>
+
+<programlisting>
+\( ( ( (?&gt;[^()]+) | (?R) )* ) \)
+   ^                        ^
+   ^                        ^
+</programlisting>
+
+<para>
+the string they capture is "ab(cd)ef", the contents of the top level
+parentheses.
+</para>
+
+<para>
+Do not confuse the (?R) item with the condition (R), which tests for
+recursion. Consider this pattern, which matches text in angle brackets,
+allowing for arbitrary nesting. Only digits are allowed in nested
+brackets (that is, when recursing), whereas any characters are permitted
+at the outer level.
+</para>
+
+<programlisting>
+&lt; (?: (?(R) \d++ | [^&lt;&gt;]*+) | (?R)) * &gt;
+</programlisting>
+
+<para>
+In this pattern, (?(R) is the start of a conditional subpattern, with
+two different alternatives for the recursive and non-recursive cases.
+The (?R) item is the actual recursive call.
+</para>
+</refsect1>
+
+<refsect1>
+<title>Subpatterns as subroutines</title>
+<para>
+If the syntax for a recursive subpattern reference (either by number or
+by name) is used outside the parentheses to which it refers, it operates
+like a subroutine in a programming language. The "called" subpattern may
+be defined before or after the reference. An earlier example pointed out
+that the pattern
+</para>
+
+<programlisting>
+(sens|respons)e and \1ibility
+</programlisting>
+
+<para>
+matches "sense and sensibility" and "response and responsibility", but
+not "sense and responsibility". If instead the pattern
+</para>
+
+<programlisting>
+(sens|respons)e and (?1)ibility
+</programlisting>
+
+<para>
+is used, it does match "sense and responsibility" as well as the other
+two strings. Another example is given in the discussion of DEFINE above.
+</para>
+
+<para>
+Like recursive subpatterns, a "subroutine" call is always treated as an atomic
+group. That is, once it has matched some of the string, it is never
+re-entered, even if it contains untried alternatives and there is a subsequent
+matching failure.
+</para>
+
+<para>
+When a subpattern is used as a subroutine, processing options such as
+case-independence are fixed when the subpattern is defined. They cannot be
+changed for different calls. For example, consider this pattern:
+</para>
+
+<programlisting>
+(abc)(?i:(?1))
+</programlisting>
+
+<para>
+It matches "abcabc". It does not match "abcABC" because the change of
+processing option does not affect the called subpattern.
+</para>
+</refsect1>
+
+<!-- Callouts are not supported by GRegex
+<refsect1>
+<title>Callouts</title>
+<para>
+Perl has a feature whereby using the sequence (?{...}) causes arbitrary
+Perl code to be obeyed in the middle of matching a regular expression.
+This makes it possible, amongst other things, to extract different substrings that match the same pair of parentheses when there is a repetition.
+</para>
+
+<para>
+PCRE provides a similar feature, but of course it cannot obey arbitrary
+Perl code. The feature is called "callout". The caller of PCRE provides
+an external function by putting its entry point in the global variable
+pcre_callout. By default, this variable contains NULL, which disables
+all calling out.
+</para>
+
+<para>
+Within a regular expression, (?C) indicates the points at which the
+external function is to be called. If you want to identify different
+callout points, you can put a number less than 256 after the letter C.
+The default value is zero. For example, this pattern has two callout
+points:
+</para>
+
+<programlisting>
+(?C1)abc(?C2)def
+</programlisting>
+
+<para>
+If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are
+automatically installed before each item in the pattern. They are all
+numbered 255.
+</para>
+
+<para>
+During matching, when PCRE reaches a callout point (and pcre_callout is
+set), the external function is called. It is provided with the number
+of the callout, the position in the pattern, and, optionally, one item
+of data originally supplied by the caller of pcre_exec(). The callout
+function may cause matching to proceed, to backtrack, or to fail altogether. A complete description of the interface to the callout function
+is given in the pcrecallout documentation.
+</para>
+</refsect1>
+-->
+
+<refsect1>
+<title>Copyright</title>
+<para>
+This document was copied and adapted from the PCRE documentation,
+specifically from the man page for pcrepattern.
+The original copyright note is:
+</para>
+
+<programlisting>
+Copyright (c) 1997-2006 University of Cambridge.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the name of Google
+      Inc. nor the names of their contributors may be used to endorse or
+      promote products derived from this software without specific prior
+      written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+</programlisting>
+</refsect1>
+
+</refentry>
diff --git a/docs/reference/glib/resources.xml b/docs/reference/glib/resources.xml
new file mode 100644
index 0000000..c5cfa78
--- /dev/null
+++ b/docs/reference/glib/resources.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-resources" revision="17 Jan 2002">
+<refmeta>
+<refentrytitle>Mailing lists and bug reports</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>Mailing lists and bug reports</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Mailing lists and bug reports</refname>
+<refpurpose>
+Getting help with GLib
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Filing a bug report or feature request</title>
+
+<para>
+If you encounter a bug, misfeature, or missing feature in GLib, please
+file a bug report on the issue tracker at
+<ulink url="https://gitlab.gnome.org/GNOME/glib/issues/new">https://gitlab.gnome.org/GNOME/glib/issues/new</ulink>.
+We'd also appreciate reports of incomplete or misleading information in 
+the GLib documentation; file those with the ‘Documentation’ label.
+</para>
+
+<para>
+Don't hesitate to file a bug report, even if you think we may know
+about it already, or aren't sure of the details. Just give us as much
+information as you have, and if it's already fixed or has already been
+discussed, we'll add a note to that effect in the report.
+</para>
+
+<para>
+The issue tracker should definitely be used for feature requests, it's
+not only for bugs. We track all GLib development in GitLab, so it's
+the way to be sure the GLib developers won't forget about an issue.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>Code Contributions</title>
+
+<para>
+If you develop a bugfix or enhancement for GLib, please open a merge request
+for that in GitLab as well. All branches must be offered under the terms of
+the GNU LGPL license, so be sure you  are authorized to give us the branch
+under those terms.
+</para>
+
+<para>
+If you want to discuss your branch before or after developing it, open a
+topic on <ulink url="https://discourse.gnome.org/tags/glib">Discourse</ulink>.
+But be sure to create the GitLab merge request as well; if the branch is only
+on the list and not in GitLab, it's likely to slip through the cracks.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>Discussions and user questions</title>
+
+<para>
+The <ulink url="https://gitlab.gnome.org/GNOME/glib/issues">GLib issue tracker</ulink>
+is meant for discussions with actionable topics. If you want to ask a question
+about using GLib, or discuss new features, you should use
+<ulink url="https://discourse.gnome.org/tags/glib">the glib tag on Discourse</ulink>.
+</para>
+
+</refsect1>
+
+
+</refentry>
diff --git a/docs/reference/glib/running.xml b/docs/reference/glib/running.xml
new file mode 100644
index 0000000..aaafddf
--- /dev/null
+++ b/docs/reference/glib/running.xml
@@ -0,0 +1,411 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<refentry id="glib-running">
+<refmeta>
+<refentrytitle>Running GLib Applications</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>GLib Library</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Running GLib Applications</refname>
+<refpurpose>
+How to run and debug your GLib application
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Running and debugging GLib Applications</title>
+
+<refsect2>
+<title>Environment variables</title>
+
+<para>
+  The runtime behaviour of GLib applications can be influenced by a
+  number of environment variables.
+</para>
+
+<formalpara>
+  <title>Standard variables</title>
+
+  <para>
+    GLib reads standard environment variables like <envar>LANG</envar>,
+    <envar>PATH</envar>, <envar>HOME</envar>, <envar>TMPDIR</envar>,
+    <envar>TZ</envar> and <envar>LOGNAME</envar>.
+  </para>
+</formalpara>
+
+<formalpara>
+  <title>XDG directories</title>
+
+  <para>
+    GLib consults the environment variables <envar>XDG_DATA_HOME</envar>,
+    <envar>XDG_DATA_DIRS</envar>, <envar>XDG_CONFIG_HOME</envar>,
+    <envar>XDG_CONFIG_DIRS</envar>, <envar>XDG_CACHE_HOME</envar> and
+    <envar>XDG_RUNTIME_DIR</envar> for the various XDG directories.
+    For more information, see the <ulink url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG basedir spec</ulink>.
+  </para>
+</formalpara>
+
+<formalpara id="G_FILENAME_ENCODING">
+  <title><envar>G_FILENAME_ENCODING</envar></title>
+
+  <para>
+    This environment variable can be set to a comma-separated list of character
+    set names. GLib assumes that filenames are encoded in the first character
+    set from that list rather than in UTF-8. The special token "@locale" can be
+    used to specify the character set for the current locale.
+  </para>
+</formalpara>
+
+<formalpara id="G_BROKEN_FILENAMES">
+  <title><envar>G_BROKEN_FILENAMES</envar></title>
+
+  <para>
+    If this environment variable is set, GLib assumes that filenames are in
+    the locale encoding rather than in UTF-8. G_FILENAME_ENCODING takes
+    priority over G_BROKEN_FILENAMES.
+  </para>
+</formalpara>
+
+<formalpara id="G_MESSAGES_PREFIXED">
+  <title><envar>G_MESSAGES_PREFIXED</envar></title>
+
+  <para>
+    A list of log levels for which messages should be prefixed by the
+    program name and PID of the application. The default is to prefix
+    everything except <literal>G_LOG_LEVEL_MESSAGE</literal> and
+    <literal>G_LOG_LEVEL_INFO</literal>.
+    The possible values are
+    <literal>error</literal>,
+    <literal>warning</literal>,
+    <literal>critical</literal>,
+    <literal>message</literal>,
+    <literal>info</literal> and
+    <literal>debug</literal>.
+    You can also use the special values
+    <literal>all</literal> and
+    <literal>help</literal>.
+  </para>
+  <para>
+    This environment variable only affects the default log handler,
+    g_log_default_handler().
+  </para>
+</formalpara>
+
+<formalpara id="G_MESSAGES_DEBUG">
+  <title><envar>G_MESSAGES_DEBUG</envar></title>
+
+  <para>
+    A space-separated list of log domains for which informational
+    and debug messages should be printed. By default, these
+    messages are not printed.
+  </para>
+  <para>
+    You can also use the special value <literal>all</literal>.
+  </para>
+  <para>
+    This environment variable only affects the default log handler,
+    g_log_default_handler().
+  </para>
+</formalpara>
+
+<formalpara id="G-DEBUG:CAPS">
+  <title><envar>G_DEBUG</envar></title>
+
+  <para>
+    This environment variable can be set to a list of debug options,
+    which cause GLib to print out different types of debugging information.
+    <variablelist>
+      <varlistentry>
+        <term>fatal-warnings</term>
+        <listitem><para>Causes GLib to abort the program at the first call
+           to g_warning() or g_critical().  Use of this flag is not
+           recommended except when debugging.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>fatal-criticals</term>
+        <listitem><para>Causes GLib to abort the program at the first call
+           to g_critical().  This flag can be useful during debugging and
+           testing.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>gc-friendly</term>
+        <listitem><para>Newly allocated memory that isn't directly initialized,
+          as well as memory being freed will be reset to 0. The point here is
+          to allow memory checkers and similar programs that use Boehm GC alike
+          algorithms to produce more accurate results.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>resident-modules</term>
+        <listitem><para>All modules loaded by GModule will be made resident.
+          This can be useful for tracking memory leaks in modules which are
+          later unloaded; but it can also hide bugs where code is accessed
+          after the module would have normally been unloaded.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>bind-now-modules</term>
+        <listitem><para>All modules loaded by GModule will bind their symbols
+          at load time, even when the code uses %G_MODULE_BIND_LAZY.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+    The special value <literal>all</literal> can be used to turn on all debug options.
+    The special value <literal>help</literal> can be used to print all available options.
+  </para>
+</formalpara>
+
+<formalpara id="G_SLICE">
+  <title><envar>G_SLICE</envar></title>
+
+  <para>
+    This environment variable allows reconfiguration of the GSlice
+    memory allocator.
+    <variablelist>
+      <varlistentry>
+        <term>always-malloc</term>
+        <listitem><para>This will cause all slices allocated through
+          g_slice_alloc() and released by g_slice_free1() to be actually
+          allocated via direct calls to g_malloc() and g_free().
+          This is most useful for memory checkers and similar programs that
+          use Boehm GC alike algorithms to produce more accurate results.
+          It can also be in conjunction with debugging features of the system's
+          malloc() implementation such as glibc's MALLOC_CHECK_=2 to debug
+          erroneous slice allocation code, although
+          <literal>debug-blocks</literal> is usually a better suited debugging
+          tool.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>debug-blocks</term>
+        <listitem><para>Using this option (present since GLib 2.13) engages
+          extra code which performs sanity checks on the released memory
+          slices. Invalid slice addresses or slice sizes will be reported and
+          lead to a program halt. This option is for debugging scenarios.
+          In particular, client packages sporting their own test suite should
+          <emphasis>always enable this option when running tests</emphasis>.
+          Global slice validation is ensured by storing size and address
+          information for each allocated chunk, and maintaining a global
+          hash table of that data. That way, multi-thread scalability is
+          given up, and memory consumption is increased. However, the
+          resulting code usually performs acceptably well, possibly better
+          than with comparable memory checking carried out using external
+          tools.</para>
+          <para>An example of a memory corruption scenario that cannot be
+          reproduced with <literal>G_SLICE=always-malloc</literal>, but will
+          be caught by <literal>G_SLICE=debug-blocks</literal> is as follows:
+          <programlisting>
+            void *slist = g_slist_alloc (); /* void* gives up type-safety */
+            g_list_free (slist);            /* corruption: sizeof (GSList) != sizeof (GList) */
+          </programlisting></para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+    The special value <literal>all</literal> can be used to turn on all options.
+    The special value <literal>help</literal> can be used to print all available options.
+  </para>
+</formalpara>
+
+<formalpara id="G_RANDOM_VERSION">
+  <title><envar>G_RANDOM_VERSION</envar></title>
+
+  <para>
+    If this environment variable is set to '2.0', the outdated
+    pseudo-random number seeding and generation algorithms from
+    GLib 2.0 are used instead of the newer, better ones. You should
+    only set this variable if you have sequences of numbers that were
+    generated with Glib 2.0 that you need to reproduce exactly.
+  </para>
+</formalpara>
+
+<formalpara id="LIBCHARSET_ALIAS_DIR">
+  <title><envar>LIBCHARSET_ALIAS_DIR</envar></title>
+
+  <para>
+    Allows to specify a nonstandard location for the
+    <filename>charset.aliases</filename> file that is used by the
+    character set conversion routines. The default location is the
+    <replaceable>libdir</replaceable> specified at compilation time.
+  </para>
+</formalpara>
+
+<formalpara id="TZDIR">
+  <title><envar>TZDIR</envar></title>
+
+  <para>
+    Allows to specify a nonstandard location for the timezone data files
+    that are used by the #GDateTime API. The default location is under
+    <filename>/usr/share/zoneinfo</filename>. For more information,
+    also look at the <command>tzset</command> manual page.
+  </para>
+</formalpara>
+
+<formalpara id="G_ENABLE_DIAGNOSTIC">
+  <title><envar>G_ENABLE_DIAGNOSTIC</envar></title>
+
+  <para>
+    If set to a non-zero value, this environment variable enables
+    diagnostic messages, like deprecation messages for GObject properties
+    and signals.
+  </para>
+</formalpara>
+
+<formalpara id="G_DEBUGGER">
+  <title><envar>G_DEBUGGER</envar></title>
+
+  <para>
+    When running on Windows, if set to a non-empty string, GLib will
+    try to interpret the contents of this environment variable as
+    a command line to a debugger, and run it if the process crashes.
+    The debugger command line should contain <literal>%p</literal> and <literal>%e</literal> substitution
+    tokens, which GLib will replace with the process ID of the crashing
+    process and a handle to an event that the debugger should signal
+    to let GLib know that the debugger successfully attached to the
+    process. If <literal>%e</literal> is absent, or if the debugger is not able to
+    signal events, GLib will resume execution after 60 seconds.
+    If <literal>%p</literal> is absent, the debugger won't know which process to attach to,
+    and GLib will also resume execution after 60 seconds.
+  </para>
+  <para>
+    Additionally, even if <envar>G_DEBUGGER</envar> is not set, GLib would still
+    try to print basic exception information (code and address) into
+    stderr.
+  </para>
+  <para>
+    By default the debugger gets a new console allocated for it.
+    Set the <envar>G_DEBUGGER_OLD_CONSOLE</envar> environment variable to any
+    non-empty string to make the debugger inherit the console of
+    the crashing process. Normally this is only used by the GLib
+    testsuite.
+  </para>
+  <para>
+    The exception handler is written with the aim of making it as
+    simple as possible, to minimize the risk of it invoking
+    buggy functions or running buggy code, which would result
+    in exceptions being raised recursively. Because of that
+    it lacks most of the amenities that one would expect of GLib.
+    Namely, it does not support Unicode, so it is highly advisable
+    to only use ASCII characters in <envar>G_DEBUGGER</envar>.
+  </para>
+  <para>
+    See also <link linkend="G_VEH_CATCH"><envar>G_VEH_CATCH</envar></link>.
+  </para>
+</formalpara>
+
+<formalpara id="G_VEH_CATCH">
+  <title><envar>G_VEH_CATCH</envar></title>
+
+  <para>
+    Catching some exceptions can break the program, since Windows
+    will sometimes use exceptions for execution flow control and
+    other purposes other than signalling a crash.
+  </para>
+  <para>
+    The <envar>G_VEH_CATCH</envar> environment variable augments
+    <ulink url="https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling">Vectored Exception Handling</ulink>
+    on Windows (see <link linkend="G_DEBUGGER"><envar>G_DEBUGGER</envar></link>), allowing GLib to catch more
+    exceptions. Set this variable to a comma-separated list of
+    hexadecimal exception codes that should additionally be caught.
+  </para>
+  <para>
+    By default GLib will only catch Access Violation, Stack Overflow and
+    Illegal Instruction <ulink url="https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_exception_record">exceptions</ulink>.
+  </para>
+</formalpara>
+
+</refsect2>
+
+<refsect2 id="setlocale">
+<title>Locale</title>
+
+<para>
+A number of interfaces in GLib depend on the current locale in which
+an application is running. Therefore, most GLib-using applications should
+call <function>setlocale (LC_ALL, "")</function> to set up the current
+locale.
+</para>
+
+<para>
+On Windows, in a C program there are several locale concepts
+that not necessarily are synchronized. On one hand, there is the
+system default ANSI code-page, which determines what encoding is used
+for file names handled by the C library's functions and the Win32
+API. (We are talking about the "narrow" functions here that take
+character pointers, not the "wide" ones.)
+</para>
+
+<para>
+On the other hand, there is the C library's current locale. The
+character set (code-page) used by that is not necessarily the same as
+the system default ANSI code-page. Strings in this character set are
+returned by functions like <function>strftime()</function>.
+</para>
+
+</refsect2>
+
+<para>
+GLib ships with a set of Python macros for the GDB debugger. These includes pretty
+printers for lists, hashtables and GObject types. It also has a backtrace filter
+that makes backtraces with signal emissions easier to read.
+</para>
+
+<para>
+To use this you need a version of GDB that supports Python scripting; anything
+from 7.0 should be fine. You then need to install GLib in the same prefix as
+GDB so that the Python GDB autoloaded files get installed in the right place
+for GDB to pick up.
+</para>
+
+<para>
+General pretty printing should just happen without having to do anything special.
+To get the signal emission filtered backtrace you must use the "new-backtrace" command
+instead of the standard one.
+</para>
+
+<para>
+There is also a new command called gforeach that can be used to apply a command
+on each item in a list. E.g. you can do
+<programlisting>
+gforeach i in some_list_variable: print *(GtkWidget *)l
+</programlisting>
+Which would print the contents of each widget in a list of widgets.
+</para>
+
+<refsect2>
+<title>SystemTap</title>
+
+<para>
+<ulink url="http://sourceware.org/systemtap/">SystemTap</ulink> is a dynamic whole-system
+analysis toolkit.  GLib ships with a file <filename>libglib-2.0.so.*.stp</filename> which defines a
+set of probe points, which you can hook into with custom SystemTap scripts.
+See the files <filename>libglib-2.0.so.*.stp</filename>, <filename>libgobject-2.0.so.*.stp</filename>
+and <filename>libgio-2.0.so.*.stp</filename> which
+are in your shared SystemTap scripts directory.
+</para>
+
+</refsect2>
+
+<refsect2>
+<title>Memory statistics</title>
+
+<para>
+g_mem_profile() will output a summary g_malloc() memory usage, if memory
+profiling has been enabled by calling
+<literal>g_mem_set_vtable (glib_mem_profiler_table)</literal> upon startup.
+</para>
+
+<para>
+If GLib has been configured with <option>--enable-debug=yes</option>,
+then g_slice_debug_tree_statistics() can be called in a debugger to
+output details about the memory usage of the slice allocator.
+</para>
+
+</refsect2>
+</refsect1>
+</refentry>
diff --git a/docs/reference/glib/version.xml.in b/docs/reference/glib/version.xml.in
new file mode 100644
index 0000000..af9b9c4
--- /dev/null
+++ b/docs/reference/glib/version.xml.in
@@ -0,0 +1 @@
+@GLIB_VERSION@
diff --git a/docs/reference/glib/xml/gtkdocentities.ent.in b/docs/reference/glib/xml/gtkdocentities.ent.in
new file mode 100644
index 0000000..f12c9ff
--- /dev/null
+++ b/docs/reference/glib/xml/gtkdocentities.ent.in
@@ -0,0 +1,8 @@
+<!ENTITY package "@PACKAGE@">
+<!ENTITY package_bugreport "@PACKAGE_BUGREPORT@">
+<!ENTITY package_name "@PACKAGE_NAME@">
+<!ENTITY package_string "@PACKAGE_STRING@">
+<!ENTITY package_tarname "@PACKAGE_TARNAME@">
+<!ENTITY package_url "@PACKAGE_URL@">
+<!ENTITY package_version "@PACKAGE_VERSION@">
+<!ENTITY package_api_version "@PACKAGE_API_VERSION@">
diff --git a/docs/reference/glib/xml/meson.build b/docs/reference/glib/xml/meson.build
new file mode 100644
index 0000000..6aeb745
--- /dev/null
+++ b/docs/reference/glib/xml/meson.build
@@ -0,0 +1,14 @@
+ent_conf = configuration_data()
+ent_conf.set('PACKAGE', 'glib')
+ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new')
+ent_conf.set('PACKAGE_NAME', 'glib')
+ent_conf.set('PACKAGE_STRING', 'glib')
+ent_conf.set('PACKAGE_TARNAME', 'glib')
+ent_conf.set('PACKAGE_URL', 'FIXME')
+ent_conf.set('PACKAGE_VERSION', glib_version)
+ent_conf.set('PACKAGE_API_VERSION', glib_api_version)
+configure_file(
+  input: 'gtkdocentities.ent.in',
+  output: 'gtkdocentities.ent',
+  configuration: ent_conf
+)
diff --git a/docs/reference/gobject/glib-genmarshal.xml b/docs/reference/gobject/glib-genmarshal.xml
new file mode 100644
index 0000000..2b3e86f
--- /dev/null
+++ b/docs/reference/gobject/glib-genmarshal.xml
@@ -0,0 +1,579 @@
+<refentry id="glib-genmarshal" lang="en">
+
+<refentryinfo>
+  <title>glib-genmarshal</title>
+  <productname>GObject</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Emmanuele</firstname>
+      <surname>Bassi</surname>
+    </author>
+    <author>
+      <contrib>Original developer</contrib>
+      <firstname>Tim</firstname>
+      <surname>Janik</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>glib-genmarshal</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>glib-genmarshal</refname>
+<refpurpose>C code marshaller generation utility for GLib closures</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>glib-genmarshal</command>
+<arg choice="opt" rep="repeat">OPTION</arg>
+<arg choice="opt" rep="repeat">FILE</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>glib-genmarshal</command> is a small utility that generates C code
+marshallers for callback functions of the GClosure mechanism in the GObject
+sublibrary of GLib. The marshaller functions have a standard signature,
+they get passed in the invoking closure, an array of value structures holding
+the callback function parameters and a value structure for the return value
+of the callback. The marshaller is then responsible to call the respective C
+code function of the closure with all the parameters on the stack and to
+collect its return value.
+</para>
+
+<para><command>glib-genmarshal</command> takes a list of marshallers to generate as
+input. The marshaller list is either read from files passed as additional arguments
+on the command line; or from standard input, by using <literal>-</literal> as the
+input file.
+</para>
+
+<refsect2><title>Marshaller list format</title>
+<para>
+The marshaller lists are processed line by line, a line can contain a
+comment in the form of
+<informalexample><programlisting>
+# this is a comment
+</programlisting></informalexample>
+or a marshaller specification of the form
+<programlisting>
+<replaceable>RTYPE</replaceable>:<replaceable>PTYPE</replaceable>
+<replaceable>RTYPE</replaceable>:<replaceable>PTYPE</replaceable>,<replaceable>PTYPE</replaceable>
+<replaceable>RTYPE</replaceable>:<replaceable>PTYPE</replaceable>,<replaceable>PTYPE</replaceable>,<replaceable>PTYPE</replaceable>
+</programlisting>
+</para>
+<para>
+The <replaceable>RTYPE</replaceable> part specifies the callback's return
+type and the <replaceable>PTYPE</replaceable>s right to the colon specify
+the callback's parameter list, except for the first and the last arguments
+which are always pointers.
+</para>
+</refsect2>
+<refsect2><title>Parameter types</title>
+<para>
+Currently, the following types are supported:
+<variablelist>
+<varlistentry>
+<term><replaceable>VOID</replaceable></term>
+<listitem><para>
+indicates no return type, or no extra parameters.
+If <replaceable>VOID</replaceable> is used as the parameter list, no
+additional parameters may be present.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>BOOLEAN</replaceable></term>
+<listitem><para>
+for boolean types (gboolean)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>CHAR</replaceable></term>
+<listitem><para>
+for signed char types (gchar)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>UCHAR</replaceable></term>
+<listitem><para>
+for unsigned char types (guchar)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>INT</replaceable></term>
+<listitem><para>
+for signed integer types (gint)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>UINT</replaceable></term>
+<listitem><para>
+for unsigned integer types (guint)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>LONG</replaceable></term>
+<listitem><para>
+for signed long integer types (glong)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>ULONG</replaceable></term>
+<listitem><para>
+for unsigned long integer types (gulong)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>INT64</replaceable></term>
+<listitem><para>
+for signed 64bit integer types (gint64)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>UINT64</replaceable></term>
+<listitem><para>
+for unsigned 64bit integer types (guint64)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>ENUM</replaceable></term>
+<listitem><para>
+for enumeration types (gint)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>FLAGS</replaceable></term>
+<listitem><para>
+for flag enumeration types (guint)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>FLOAT</replaceable></term>
+<listitem><para>
+for single-precision float types (gfloat)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>DOUBLE</replaceable></term>
+<listitem><para>
+for double-precision float types (gdouble)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>STRING</replaceable></term>
+<listitem><para>
+for string types (gchar*)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>BOXED</replaceable></term>
+<listitem><para>
+for boxed (anonymous but reference counted) types (GBoxed*)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>PARAM</replaceable></term>
+<listitem><para>
+for GParamSpec or derived types (GParamSpec*)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>POINTER</replaceable></term>
+<listitem><para>
+for anonymous pointer types (gpointer)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>OBJECT</replaceable></term>
+<listitem><para>
+for GObject or derived types (GObject*)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>VARIANT</replaceable></term>
+<listitem><para>
+for GVariant types (GVariant*)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>NONE</replaceable></term>
+<listitem><para>
+deprecated alias for <replaceable>VOID</replaceable>
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><replaceable>BOOL</replaceable></term>
+<listitem><para>
+deprecated alias for <replaceable>BOOLEAN</replaceable>
+</para></listitem>
+</varlistentry>
+</variablelist>
+</para>
+</refsect2>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>--header</option></term>
+<listitem><para>
+Generate header file contents of the marshallers. This option is mutually
+exclusive with the <option>--body</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--body</option></term>
+<listitem><para>
+Generate C code file contents of the marshallers. This option is mutually
+exclusive with the <option>--header</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--prefix=<replaceable>PREFIX</replaceable></option></term>
+<listitem><para>
+Specify marshaller prefix. The default prefix is <literal>`g_cclosure_user_marshal'</literal>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--skip-source</option></term>
+<listitem><para>
+Skip source location remarks in generated comments.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--stdinc</option></term>
+<listitem><para>
+Use the standard marshallers of the GObject library, and include
+<filename>glib-object.h</filename> in generated header files. This
+option is mutually exclusive with the <option>--nostdinc</option>
+option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--nostdinc</option></term>
+<listitem><para>
+Do not use the standard marshallers of the GObject library, and skip
+<filename>glib-object.h</filename> include directive in generated header files.
+This option is mutually exclusive with the <option>--stdinc</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--internal</option></term>
+<listitem><para>
+Mark generated functions as internal, using <literal>G_GNUC_INTERNAL</literal>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--valist-marshallers</option></term>
+<listitem><para>
+Generate valist marshallers, for use with <function>g_signal_set_va_marshaller()</function>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-v</option>, <option>--version</option></term>
+<listitem><para>
+Print version information.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--g-fatal-warnings</option></term>
+<listitem><para>
+Make warnings fatal, that is, exit immediately once a warning occurs.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-h</option>, <option>--help</option></term>
+<listitem><para>
+Print brief help and exit.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-v</option>, <option>--version</option></term>
+<listitem><para>
+Print version and exit.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--output=FILE</option></term>
+<listitem><para>
+Write output to <replaceable>FILE</replaceable> instead of the standard output.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--prototypes</option></term>
+<listitem><para>
+Generate function prototypes before the function definition in the C source
+file, in order to avoid a <literal>missing-prototypes</literal> compiler
+warning. This option is only useful when using the <option>--body</option>
+option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--pragma-once</option></term>
+<listitem><para>
+Use the <literal>once</literal> pragma instead of an old style header guard
+when generating the C header file. This option is only useful when using the
+<option>--header</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--include-header=<replaceable>HEADER</replaceable></option></term>
+<listitem><para>
+Adds a <literal>#include</literal> directive for the given file in the C
+source file. This option is only useful when using the <option>--body</option>
+option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-D <replaceable>SYMBOL[=VALUE]</replaceable></option></term>
+<listitem><para>
+Adds a <literal>#define</literal> C pre-processor directive for
+<replaceable>SYMBOL</replaceable> and its given <replaceable>VALUE</replaceable>,
+or "1" if the value is unset. You can use this option multiple times; if you do,
+all the symbols will be defined in the same order given on the command line, before
+the symbols undefined using the <option>-U</option> option. This option is only
+useful when using the <option>--body</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-U <replaceable>SYMBOL</replaceable></option></term>
+<listitem><para>
+Adds a <literal>#undef</literal> C pre-processor directive to undefine the
+given <replaceable>SYMBOL</replaceable>. You can use this option multiple times;
+if you do, all the symbols will be undefined in the same order given on the
+command line, after the symbols defined using the <option>-D</option> option.
+This option is only useful when using the <option>--body</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--quiet</option></term>
+<listitem><para>
+Minimizes the output of <command>glib-genmarshal</command>, by printing only
+warnings and errors. This option is mutually exclusive with the
+<option>--verbose</option> option.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--verbose</option></term>
+<listitem><para>
+Increases the verbosity of <command>glib-genmarshal</command>, by printing
+debugging information. This option is mutually exclusive with the
+<option>--quiet</option> option.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+
+<refsect1><title>Using <command>glib-genmarshal</command> with Meson</title>
+<para>
+Meson supports generating closure marshallers using <command>glib-genmarshal</command>
+out of the box in its "gnome" module.
+</para>
+
+<para>
+In your <filename>meson.build</filename> file you will typically call the
+<literal>gnome.genmarshal()</literal> method with the source list of marshallers
+to generate:
+</para>
+<informalexample><programlisting>
+gnome = import('gnome')
+marshal_files = gnome.genmarshal('marshal',
+  sources: 'marshal.list',
+  internal: true,
+)
+</programlisting></informalexample>
+<para>
+The <literal>marshal_files</literal> variable will contain an array of two elements
+in the following order:
+</para>
+<itemizedlist>
+  <listitem><para>a build target for the source file</para></listitem>
+  <listitem><para>a build target for the header file</para></listitem>
+</itemizedlist>
+<para>
+You should use the returned objects to provide a dependency on every other
+build target that references the source or header file; for instance, if you
+are using the source to build a library:
+</para>
+<informalexample><programlisting>
+mainlib = library('project',
+  sources: project_sources + marshal_files,
+  ...
+)
+</programlisting></informalexample>
+<para>
+Additionally, if you are including the generated header file inside a build
+target that depends on the library you just built, you must ensure that the
+internal dependency includes the generated header as a required source file:
+</para>
+<informalexample><programlisting>
+mainlib_dep = declare_dependency(sources: marshal_files[1], link_with: mainlib)
+</programlisting></informalexample>
+<para>
+You should not include the generated source file as well, otherwise it will
+be built separately for every target that depends on it, causing build
+failures. To know more about why all this is required, please refer to the
+<ulink url="https://mesonbuild.com/FAQ.html#how-do-i-tell-meson-that-my-sources-use-generated-headers">
+corresponding Meson FAQ entry</ulink>.
+</para>
+<para>
+For more information on how to use the method, see the
+<ulink url="https://mesonbuild.com/Gnome-module.html#gnomegenmarshal">Meson
+documentation for <literal>gnome.genmarshal()</literal></ulink>.
+</para>
+</refsect1>
+
+<refsect1><title>Using <command>glib-genmarshal</command> with Autotools</title>
+<para>
+In order to use <command>glib-genmarshal</command> in your project when using
+Autotools as the build system, you will first need to modify your
+<filename>configure.ac</filename> file to ensure you find the appropriate
+command using <command>pkg-config</command>, similarly as to how you discover
+the compiler and linker flags for GLib.
+</para>
+<informalexample><programlisting>
+PKG_PROG_PKG_CONFIG([0.28])
+
+PKG_CHECK_VAR([GLIB_GENMARSHAL], [glib-2.0], [glib_genmarshal])
+</programlisting></informalexample>
+<para>
+In your <filename>Makefile.am</filename> file you will typically need very
+simple rules to generate the C files needed for the build.
+</para>
+<informalexample><programlisting>
+marshal.h: marshal.list
+        $(AM_V_GEN)$(GLIB_GENMARSHAL) \
+                --header \
+                --output=$@ \
+                $&lt;
+
+marshal.c: marshal.list marshal.h
+        $(AM_V_GEN)$(GLIB_GENMARSHAL) \
+                --include-header=marshal.h \
+                --body \
+                --output=$@ \
+                $&lt;
+
+BUILT_SOURCES += marshal.h marshal.c
+CLEANFILES += marshal.h marshal.c
+EXTRA_DIST += marshal.list
+</programlisting></informalexample>
+<para>
+In the example above, the first rule generates the header file and depends on
+a <filename>marshal.list</filename> file in order to regenerate the result in
+case the marshallers list is updated. The second rule generates the source file
+for the same <filename>marshal.list</filename>, and includes the file generated
+by the header rule.
+</para>
+</refsect1>
+
+<refsect1><title>Example</title>
+<para>
+To generate marshallers for the following callback functions:
+</para>
+<informalexample><programlisting>
+void   foo (gpointer data1,
+            gpointer data2);
+void   bar (gpointer data1,
+            gint     param1,
+            gpointer data2);
+gfloat baz (gpointer data1,
+            gboolean param1,
+            guchar   param2,
+            gpointer data2);
+</programlisting></informalexample>
+<para>
+The <filename>marshaller.list</filename> file has to look like this:
+</para>
+<programlisting>
+VOID:VOID
+VOID:INT
+FLOAT:BOOLEAN,UCHAR
+</programlisting>
+<para>
+and you call glib-genmarshal like this:
+</para>
+<programlisting>
+glib-genmarshal --header marshaller.list > marshaller.h
+glib-genmarshal --body marshaller.list > marshaller.c
+</programlisting>
+<para>
+The generated marshallers have the arguments encoded in their function name.
+For this particular list, they are
+</para>
+<programlisting>
+g_cclosure_user_marshal_VOID__VOID(...),
+g_cclosure_user_marshal_VOID__INT(...),
+g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR(...).
+</programlisting>
+<para>
+They can be used directly for GClosures or be passed in as the
+GSignalCMarshaller c_marshaller; argument upon creation of signals:
+</para>
+<informalexample><programlisting>
+GClosure *cc_foo, *cc_bar, *cc_baz;
+
+cc_foo = g_cclosure_new (NULL, foo, NULL);
+g_closure_set_marshal (cc_foo, g_cclosure_user_marshal_VOID__VOID);
+cc_bar = g_cclosure_new (NULL, bar, NULL);
+g_closure_set_marshal (cc_bar, g_cclosure_user_marshal_VOID__INT);
+cc_baz = g_cclosure_new (NULL, baz, NULL);
+g_closure_set_marshal (cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
+</programlisting></informalexample>
+</refsect1>
+<refsect1><title>See also</title>
+<para>
+<citerefentry>
+<refentrytitle>glib-mkenums</refentrytitle>
+<manvolnum>1</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/docs/reference/gobject/glib-mkenums.xml b/docs/reference/gobject/glib-mkenums.xml
new file mode 100644
index 0000000..2200328
--- /dev/null
+++ b/docs/reference/gobject/glib-mkenums.xml
@@ -0,0 +1,653 @@
+<refentry id="glib-mkenums" lang="en">
+
+<refentryinfo>
+  <title>gdbus</title>
+  <productname>GObject</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Owen</firstname>
+      <surname>Taylor</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>glib-mkenums</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>glib-mkenums</refname>
+<refpurpose>C language enum description generation utility</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>glib-mkenums</command>
+<arg choice="opt" rep="repeat">OPTION</arg>
+<arg choice="opt" rep="repeat">FILE</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para><command>glib-mkenums</command> is a small utility that parses C code to
+extract enum definitions and produces enum descriptions based on text templates
+specified by the user. Typically, you can use this tool to generate enumeration
+types for the GType type system, for GObject properties and signal marshalling;
+additionally, you can use it to generate enumeration values of GSettings schemas.
+</para>
+
+<para><command>glib-mkenums</command> takes a list of valid C code files as
+input. The options specified control the text that generated, substituting various
+keywords enclosed in <literal>@</literal> characters in the templates.
+</para>
+
+<refsect2><title>Production text substitutions</title>
+<para>
+Certain keywords enclosed in <literal>@</literal> characters will be substituted in the
+emitted text. For the substitution examples of the keywords below,
+the following example enum definition is assumed:
+</para>
+<informalexample><programlisting>
+typedef enum
+{
+  PREFIX_THE_XVALUE    = 1 &lt;&lt; 3,
+  PREFIX_ANOTHER_VALUE = 1 &lt;&lt; 4
+} PrefixTheXEnum;
+</programlisting></informalexample>
+<variablelist>
+<varlistentry>
+<term><literal>@EnumName@</literal>></term>
+<listitem><para>
+The name of the enum currently being processed, enum names are assumed to be
+properly namespaced and to use mixed capitalization to separate
+words (e.g. <literal>PrefixTheXEnum</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@enum_name@</literal></term>
+<listitem><para>
+The enum name with words lowercase and word-separated by underscores
+(e.g. <literal>prefix_the_xenum</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@ENUMNAME@</literal></term>
+<listitem><para>
+The enum name with words uppercase and word-separated by underscores
+(e.g. <literal>PREFIX_THE_XENUM</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@ENUMSHORT@</literal></term>
+<listitem><para>
+The enum name with words uppercase and word-separated by underscores,
+prefix stripped (e.g. <literal>THE_XENUM</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@ENUMPREFIX@</literal></term>
+<listitem><para>
+The prefix of the enum name (e.g. <literal>PREFIX</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@VALUENAME@</literal></term>
+<listitem><para>
+The enum value name currently being processed with words uppercase and
+word-separated by underscores,
+this is the assumed literal notation of enum values in the C sources
+(e.g. <literal>PREFIX_THE_XVALUE</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@valuenick@</literal></term>
+<listitem><para>
+A nick name for the enum value currently being processed, this is usually
+generated by stripping common prefix words of all the enum values of the
+current enum, the words are lowercase and underscores are substituted by a
+minus (e.g. <literal>the-xvalue</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@valuenum@</literal></term>
+<listitem><para>
+The integer value for the enum value currently being processed. If the
+evaluation fails then <command>glib-mkenums</command> will exit with an
+error status, but this only happens if <literal>@valuenum@</literal>
+appears in your value production template. (Since: 2.26)
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@type@</literal></term>
+<listitem><para>
+This is substituted either by "enum" or "flags", depending on whether the
+enum value definitions contained bit-shift operators or not (e.g. <literal>flags</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@Type@</literal></term>
+<listitem><para>
+The same as <literal>@type@</literal> with the first letter capitalized (e.g. <literal>Flags</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@TYPE@</literal></term>
+<listitem><para>
+The same as <literal>@type@</literal> with all letters uppercased (e.g. <literal>FLAGS</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@filename@</literal></term>
+<listitem><para>
+The full path of the input file currently being processed (e.g. <literal>/build/environment/project/src/foo.h</literal>).
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>@basename@</literal></term>
+<listitem><para>
+The base name of the input file currently being processed (e.g. <literal>foo.h</literal>).
+Typically you want to use <literal>@basename@</literal> in place of <literal>@filename@</literal>
+in your templates, to improve the reproducibility of the build. (Since: 2.22)
+</para></listitem>
+</varlistentry>
+</variablelist>
+</refsect2>
+<refsect2><title>Trigraph extensions</title>
+<para>
+Some C comments are treated specially in the parsed enum definitions,
+such comments start out with the trigraph sequence <literal>/*&lt;</literal>
+and end with the trigraph sequence <literal>&gt;*/</literal>.
+</para>
+
+<para>The following options can be specified per enum definition:</para>
+<variablelist>
+<varlistentry>
+<term><literal>skip</literal></term>
+<listitem><para>
+Indicates this enum definition should  be skipped.
+</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>flags</literal></term>
+<listitem><para>
+Indicates this enum should be treated as a flags definition.
+</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>underscore_name</literal></term>
+<listitem><para>
+Specifies the word separation used in the <function>*_get_type()</function>
+function. For instance, <literal>/*&lt; underscore_name=gnome_vfs_uri_hide_options &gt;*/</literal>.
+</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>since</literal></term>
+<listitem><para>
+Specifies the version tag that will be used to substitute the <literal>@enumsince@</literal>
+keyword in the template, useful when documenting methods generated from the enums
+(e.g. <literal>Since: @enumsince@</literal>). (Since: 2.66)
+</para></listitem>
+</varlistentry>
+</variablelist>
+
+<para>The following options can be specified per value definition:</para>
+<variablelist>
+<varlistentry>
+<term><literal>skip</literal></term>
+<listitem><para>
+Indicates the value should be skipped.
+</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>nick</literal></term>
+<listitem><para>
+Specifies the otherwise auto-generated nickname.
+</para></listitem>
+</varlistentry>
+</variablelist>
+
+<para>Examples:</para>
+<informalexample><programlisting>
+typedef enum /*&lt; skip &gt;*/
+{
+  PREFIX_FOO
+} PrefixThisEnumWillBeSkipped;
+typedef enum /*&lt; flags,prefix=PREFIX,since=1.0 &gt;*/
+{
+  PREFIX_THE_ZEROTH_VALUE,	/*&lt; skip &gt;*/
+  PREFIX_THE_FIRST_VALUE,
+  PREFIX_THE_SECOND_VALUE,
+  PREFIX_THE_THIRD_VALUE,	/*&lt; nick=the-last-value &gt;*/
+} PrefixTheFlagsEnum;
+</programlisting></informalexample>
+</refsect2>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>--fhead</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> prior to processing input files.
+</para>
+<para>
+You can specify this option multiple times, and the <replaceable>TEXT</replaceable>
+will be concatenated.
+</para>
+<para>
+When used along with a template file, <replaceable>TEXT</replaceable>
+will be prepended to the template's <literal>file-header</literal> section.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--fprod</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> every time a new input file
+is being processed.
+</para>
+<para>
+You can specify this option multiple times, and the <replaceable>TEXT</replaceable>
+will be concatenated.
+</para>
+<para>
+When used along with a template file, <replaceable>TEXT</replaceable>
+will be appended to the template's <literal>file-production</literal> section.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--ftail</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> after all input files have been
+processed.
+</para>
+<para>
+You can specify this option multiple times, and the <replaceable>TEXT</replaceable>
+will be concatenated.
+</para>
+<para>
+When used along with a template file, <replaceable>TEXT</replaceable>
+will be appended to the template's <literal>file-tail</literal> section.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--eprod</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> every time an enum is encountered
+in the input files.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--vhead</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> before iterating over the set of
+values of an enum.
+</para>
+<para>
+You can specify this option multiple times, and the <replaceable>TEXT</replaceable>
+will be concatenated.
+</para>
+<para>
+When used along with a template file, <replaceable>TEXT</replaceable>
+will be prepended to the template's <literal>value-header</literal> section.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--vprod</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> for every value of an enum.
+</para>
+<para>
+You can specify this option multiple times, and the <replaceable>TEXT</replaceable>
+will be concatenated.
+</para>
+<para>
+When used along with a template file, <replaceable>TEXT</replaceable>
+will be appended to the template's <literal>value-production</literal> section.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--vtail</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Emits <replaceable>TEXT</replaceable> after iterating over all values
+of an enum.
+</para>
+<para>
+You can specify this option multiple times, and the <replaceable>TEXT</replaceable>
+will be concatenated.
+</para>
+<para>
+When used along with a template file, <replaceable>TEXT</replaceable>
+will be appended to the template's <literal>value-tail</literal> section.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--comments</option> <replaceable>TEXT</replaceable></term>
+<listitem><para>
+Template for auto-generated comments, the default (for C code generations) is
+<literal>"/* @comment@ */"</literal>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--template</option> <replaceable>FILE</replaceable></term>
+<listitem><para>
+Read templates from the given file. The templates are enclosed in
+specially-formatted C comments:
+</para>
+<informalexample><programlisting>
+/*** BEGIN section ***/
+/*** END section ***/
+</programlisting></informalexample>
+<para>
+<replaceable>section</replaceable> may be <literal>file-header</literal>,
+<literal>file-production</literal>, <literal>file-tail</literal>,
+<literal>enumeration-production</literal>, <literal>value-header</literal>,
+<literal>value-production</literal>, <literal>value-tail</literal> or
+<literal>comment</literal>.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--identifier-prefix</option> <replaceable>PREFIX</replaceable></term>
+<listitem><para>
+Indicates what portion of the enum name should be interpreted as the
+prefix (eg, the "<literal>Gtk</literal>" in
+"<literal>GtkDirectionType</literal>"). Normally this will be figured
+out automatically, but you may need to override the default if your
+namespace is capitalized oddly.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--symbol-prefix</option> <replaceable>PREFIX</replaceable></term>
+<listitem><para>
+Indicates what prefix should be used to correspond to the identifier
+prefix in related C function names (eg, the "<literal>gtk</literal>"
+in "<literal>gtk_direction_type_get_type</literal>". Equivalently,
+this is the lowercase version of the prefix component of the enum
+value names (eg, the "<literal>GTK</literal>" in
+"<literal>GTK_DIR_UP</literal>". The default value is the identifier
+prefix, converted to lowercase.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--help</option></term>
+<listitem><para>
+Print brief help and exit.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--version</option></term>
+<listitem><para>
+Print version and exit.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--output=FILE</option></term>
+<listitem><para>
+Write output to FILE instead of stdout.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>@RSPFILE</option></term>
+<listitem><para>
+When passed as the sole argument, read and parse the actual arguments from
+<literal>RSPFILE</literal>. Useful on systems with a low command-line length
+limit. For example, Windows has a limit of 8191 characters.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+
+<refsect1><title>Using templates</title>
+<para>
+Instead of passing the various sections of the generated file to the command
+line of <command>glib-mkenums</command>, it's strongly recommended to use a
+template file, especially for generating C sources.
+</para>
+
+<para>
+A C header template file will typically look like this:
+</para>
+<informalexample><programlisting>
+/*** BEGIN file-header ***/
+#pragma once
+
+/* Include the main project header */
+#include "project.h"
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@basename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+/*** END file-tail ***/
+</programlisting></informalexample>
+
+<para>
+A C source template file will typically look like this:
+</para>
+<informalexample><programlisting>
+/*** BEGIN file-header ***/
+#include "config.h"
+#include "enum-types.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@basename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+  static volatile gsize g_@type@_type_id__volatile;
+
+  if (g_once_init_enter (&amp;g_define_type_id__volatile))
+    {
+      static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+            { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+            { 0, NULL, NULL }
+      };
+
+      GType g_@type@_type_id =
+        g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+
+      g_once_init_leave (&amp;g_@type@_type_id__volatile, g_@type@_type_id);
+    }
+  return g_@type@_type_id__volatile;
+}
+
+/*** END value-tail ***/
+</programlisting></informalexample>
+
+<para>
+Template files are easier to modify and update, and can be used
+to generate various types of outputs using the same command line
+or tools during the build.
+</para>
+</refsect1>
+
+<refsect1><title>Using glib-mkenums with Meson</title>
+<para>
+Meson supports generating enumeration types using <command>glib-mkenums</command>
+out of the box in its "gnome" module.
+</para>
+
+<para>
+In your <filename>meson.build</filename> file you will typically call the
+<literal>gnome.mkenums_simple()</literal> method to generate idiomatic enumeration
+types from a list of headers to inspect:
+</para>
+<informalexample><programlisting>
+project_headers = [
+  'project-foo.h',
+  'project-bar.h',
+  'project-baz.h',
+]
+
+gnome = import('gnome')
+enum_files = gnome.mkenums_simple('enum-types',
+  sources: project_headers,
+)
+</programlisting></informalexample>
+
+<para>
+The <literal>enum_files</literal> variable will contain an array of two elements
+in the following order:
+</para>
+<itemizedlist>
+  <listitem><para>a build target for the source file</para></listitem>
+  <listitem><para>a build target for the header file</para></listitem>
+</itemizedlist>
+<para>
+You should use the returned objects to provide a dependency on every other
+build target that references the source or header file; for instance, if you
+are using the source to build a library:
+</para>
+<informalexample><programlisting>
+mainlib = library('project',
+  sources: project_sources + enum_files,
+  ...
+)
+</programlisting></informalexample>
+<para>
+Additionally, if you are including the generated header file inside a build
+target that depends on the library you just built, you must ensure that the
+internal dependency includes the generated header as a required source file:
+</para>
+<informalexample><programlisting>
+mainlib_dep = declare_dependency(sources: enum_files[1], link_with: mainlib)
+</programlisting></informalexample>
+<para>
+You should not include the generated source file as well, otherwise it will
+be built separately for every target that depends on it, causing build
+failures. To know more about why all this is required, please refer to the
+<ulink url="https://mesonbuild.com/FAQ.html#how-do-i-tell-meson-that-my-sources-use-generated-headers">
+corresponding Meson FAQ entry</ulink>.
+</para>
+
+<para>
+If you are generating C header and source files that require special
+templates, you can use <literal>gnome.mkenums()</literal> to provide those
+headers, for instance:
+</para>
+<informalexample><programlisting>
+enum_files = gnome.mkenums('enum-types',
+  sources: project_headers,
+  h_template: 'enum-types.h.in',
+  c_template: 'enum-types.c.in',
+  install_header: true,
+)
+</programlisting></informalexample>
+<para>
+For more information, see the <ulink url="https://mesonbuild.com/Gnome-module.html#gnomegenmarshal">Meson
+documentation for <literal>gnome.mkenums()</literal></ulink>.
+</para>
+</refsect1>
+
+<refsect1><title>Using glib-mkenums with Autotools</title>
+<para>
+In order to use <command>glib-mkenums</command> in your project when using
+Autotools as the build system, you will first need to modify your
+<filename>configure.ac</filename> file to ensure you find the appropriate
+command using <command>pkg-config</command>, similarly as to how you discover
+the compiler and linker flags for GLib.
+</para>
+<informalexample><programlisting>
+PKG_PROG_PKG_CONFIG([0.28])
+
+PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums])
+</programlisting></informalexample>
+<para>
+In your <filename>Makefile.am</filename> file you will typically use rules
+like these:
+</para>
+<informalexample><programlisting>
+# A list of headers to inspect
+project_headers = \
+        project-foo.h \
+        project-bar.h \
+        project-baz.h
+
+enum-types.h: $(project_headers) enum-types.h.in
+        $(AM_V_GEN)$(GLIB_MKENUMS) \
+                --template=enum-types.h.in \
+                --output=$@ \
+                $(project_headers)
+
+enum-types.c: $(project_headers) enum-types.c.in enum-types.h
+        $(AM_V_GEN)$(GLIB_MKENUMS) \
+                --template=enum-types.c.in \
+                --output=$@ \
+                $(project_headers)
+
+# Build the enum types files before every other target
+BUILT_SOURCES += enum-types.h enum-types.c
+CLEANFILES += enum-types.h enum-types.c
+EXTRA_DIST += enum-types.h.in enum-types.c.in
+</programlisting></informalexample>
+<para>
+In the example above, we have a variable called <literal>project_headers</literal>
+where we reference all header files we want to inspect for generating enumeration
+GTypes. In the <filename>enum-types.h</filename> rule we use <command>glib-mkenums</command>
+with a template called <filename>enum-types.h.in</filename> in order to generate the
+header file; similarly, in the <filename>enum-types.c</filename> rule we use a
+template called <filename>enum-types.c.in</filename>.
+</para>
+</refsect1>
+
+<refsect1><title>See also</title>
+<para>
+<citerefentry>
+<refentrytitle>glib-genmarshal</refentrytitle>
+<manvolnum>1</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/docs/reference/gobject/gobject-docs.xml b/docs/reference/gobject/gobject-docs.xml
new file mode 100644
index 0000000..74cfcd9
--- /dev/null
+++ b/docs/reference/gobject/gobject-docs.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN'
+                      'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd' [
+
+<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <bookinfo>
+    <title>GObject Reference Manual</title>
+    <releaseinfo>
+      for GObject &version;
+      The latest version of this documentation can be found on-line at
+      <ulink role="online-location" url="https://developer.gnome.org/gobject/unstable/">https://developer.gnome.org/gobject/unstable/</ulink>.
+    </releaseinfo>
+  </bookinfo>
+
+  <preface>
+    <title>Introduction</title>
+      <para>
+			Most modern programming languages come with their own native object
+			systems and additional fundamental algorithmic language constructs.
+			Just as GLib serves as an implementation of such fundamental
+			types and algorithms (linked lists, hash tables and so forth), the
+			GLib Object System provides the required implementations of a
+			flexible, extensible, and intentionally easy to map (into other
+			languages) object-oriented framework for C.
+			The substantial elements that are provided can be summarized as:
+			<itemizedlist>
+				<listitem><para>
+					 A generic type system to register arbitrary single-inherited
+						flat and deep derived types as well as interfaces for
+						structured types.
+						It takes care of creation, initialization and memory management
+						of the assorted object and class structures, maintains
+						parent/child relationships and deals with dynamic implementations
+						of such types. That is, their type specific implementations are
+						relocatable/unloadable during runtime.
+				</para></listitem>
+				<listitem><para>
+						A collection of fundamental type implementations, such as integers,
+						doubles, enums and structured types, to name a few.
+				</para></listitem>
+				<listitem><para>
+						A sample fundamental type implementation to base object hierarchies
+						upon - the GObject fundamental type.
+				</para></listitem>
+				<listitem><para>
+						A signal system that allows very flexible user customization of
+						virtual/overridable object methods and can serve as a powerful
+						notification mechanism.
+				</para></listitem>
+				<listitem><para>
+						An extensible parameter/value system, supporting all the provided
+						fundamental types that can be used to generically handle object
+						properties or otherwise parameterized types.
+				</para></listitem>
+			</itemizedlist>
+		</para>
+  </preface>
+
+  <part label="I">
+    <title>Concepts</title>
+
+    <xi:include href="tut_intro.xml" />
+    <xi:include href="tut_gtype.xml" />
+    <xi:include href="tut_gobject.xml" />
+    <xi:include href="tut_gsignal.xml" />
+  </part>
+  <reference label="II">
+    <title>API Reference</title>
+
+      <xi:include href="xml/gtype.xml" />
+      <xi:include href="xml/gtypeplugin.xml" />
+      <xi:include href="xml/gtypemodule.xml" />
+      <xi:include href="xml/objects.xml" />
+      <xi:include href="xml/enumerations_flags.xml" />
+      <xi:include href="xml/gboxed.xml" />
+      <xi:include href="xml/generic_values.xml" />
+      <xi:include href="xml/param_value_types.xml" />
+      <xi:include href="xml/gparamspec.xml" />
+      <xi:include href="xml/value_collection.xml" />
+      <xi:include href="xml/signals.xml" />
+      <xi:include href="xml/gclosure.xml" />
+      <xi:include href="xml/value_arrays.xml" />
+      <xi:include href="xml/gbinding.xml" />
+  </reference>
+  <reference label="III">
+    <title>Tools Reference</title>
+
+    <xi:include href="glib-mkenums.xml" />
+    <xi:include href="glib-genmarshal.xml" />
+    <xi:include href="gobject-query.xml" />
+  </reference>
+
+  <xi:include href="tut_howto.xml" />
+  <xi:include href="tut_tools.xml" />
+
+  <index id="api-index-full">
+    <title>Index</title>
+    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-deprecated" role="deprecated">
+    <title>Index of deprecated symbols</title>
+    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-2" role="2.2">
+    <title>Index of new symbols in 2.2</title>
+    <xi:include href="xml/api-index-2.2.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-4" role="2.4">
+    <title>Index of new symbols in 2.4</title>
+    <xi:include href="xml/api-index-2.4.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-6" role="2.6">
+    <title>Index of new symbols in 2.6</title>
+    <xi:include href="xml/api-index-2.6.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-8" role="2.8">
+    <title>Index of new symbols in 2.8</title>
+    <xi:include href="xml/api-index-2.8.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-10" role="2.10">
+    <title>Index of new symbols in 2.10</title>
+    <xi:include href="xml/api-index-2.10.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-12" role="2.12">
+    <title>Index of new symbols in 2.12</title>
+    <xi:include href="xml/api-index-2.12.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-14" role="2.14">
+    <title>Index of new symbols in 2.14</title>
+    <xi:include href="xml/api-index-2.14.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-18" role="2.18">
+    <title>Index of new symbols in 2.18</title>
+    <xi:include href="xml/api-index-2.18.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-22" role="2.22">
+    <title>Index of new symbols in 2.22</title>
+    <xi:include href="xml/api-index-2.22.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-24" role="2.24">
+    <title>Index of new symbols in 2.24</title>
+    <xi:include href="xml/api-index-2.24.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-26" role="2.26">
+    <title>Index of new symbols in 2.26</title>
+    <xi:include href="xml/api-index-2.26.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-28" role="2.28">
+    <title>Index of new symbols in 2.28</title>
+    <xi:include href="xml/api-index-2.28.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-30" role="2.30">
+    <title>Index of new symbols in 2.30</title>
+    <xi:include href="xml/api-index-2.30.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-32" role="2.32">
+    <title>Index of new symbols in 2.32</title>
+    <xi:include href="xml/api-index-2.32.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-34" role="2.34">
+    <title>Index of new symbols in 2.34</title>
+    <xi:include href="xml/api-index-2.34.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-36" role="2.36">
+    <title>Index of new symbols in 2.36</title>
+    <xi:include href="xml/api-index-2.36.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-38" role="2.38">
+    <title>Index of new symbols in 2.38</title>
+    <xi:include href="xml/api-index-2.38.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-40" role="2.40">
+    <title>Index of new symbols in 2.40</title>
+    <xi:include href="xml/api-index-2.40.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-42" role="2.42">
+    <title>Index of new symbols in 2.42</title>
+    <xi:include href="xml/api-index-2.42.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-44" role="2.44">
+    <title>Index of new symbols in 2.44</title>
+    <xi:include href="xml/api-index-2.44.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-46" role="2.46">
+    <title>Index of new symbols in 2.46</title>
+    <xi:include href="xml/api-index-2.46.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-54" role="2.54">
+    <title>Index of new symbols in 2.54</title>
+    <xi:include href="xml/api-index-2.54.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-56" role="2.56">
+    <title>Index of new symbols in 2.56</title>
+    <xi:include href="xml/api-index-2.56.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-62" role="2.62">
+    <title>Index of new symbols in 2.62</title>
+    <xi:include href="xml/api-index-2.62.xml"><xi:fallback /></xi:include>
+  </index>
+  <index id="api-index-2-66" role="2.66">
+    <title>Index of new symbols in 2.66</title>
+    <xi:include href="xml/api-index-2.66.xml"><xi:fallback /></xi:include>
+  </index>
+
+  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+
+</book>
diff --git a/docs/reference/gobject/gobject-overrides.txt b/docs/reference/gobject/gobject-overrides.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/reference/gobject/gobject-overrides.txt
diff --git a/docs/reference/gobject/gobject-query.xml b/docs/reference/gobject/gobject-query.xml
new file mode 100644
index 0000000..437d714
--- /dev/null
+++ b/docs/reference/gobject/gobject-query.xml
@@ -0,0 +1,123 @@
+<refentry id="gobject-query" lang="en">
+
+<refentryinfo>
+  <title>gobject-query</title>
+  <productname>GObject</productname>
+  <authorgroup>
+    <author>
+      <contrib>Developer</contrib>
+      <firstname>Tim</firstname>
+      <surname>Janik</surname>
+    </author>
+  </authorgroup>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>gobject-query</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>gobject-query</refname>
+<refpurpose>display a tree of types</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<cmdsynopsis>
+<command>gobject-query</command>
+<arg choice="plain">froots</arg>
+<arg choice="opt" rep="repeat">OPTION</arg>
+</cmdsynopsis>
+<cmdsynopsis>
+<command>gobject-query</command>
+<arg choice="plain">tree</arg>
+<arg choice="opt" rep="repeat">OPTION</arg>
+</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para>
+<command>gobject-query</command> is a small utility that draws a tree of
+types.
+</para>
+
+<para>
+<command>gobject-query</command> takes a mandatory argument that specifies
+whether it should iterate over the fundamental types or print a type tree.
+</para>
+</refsect1>
+
+<refsect1><title>Commands</title>
+<variablelist>
+<varlistentry>
+<term><option>froots</option></term>
+<listitem><para>
+iterate over fundamental roots
+</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><option>tree</option></term>
+<listitem><para>
+print type tree
+</para></listitem>
+</varlistentry>
+</variablelist>
+</refsect1>
+
+<refsect1><title>Options</title>
+<variablelist>
+
+<varlistentry>
+<term><option>-r</option> <replaceable>TYPE</replaceable></term>
+<listitem><para>
+specify the root type
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-n</option></term>
+<listitem><para>
+don't descend type tree
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-b</option> <replaceable>STRING</replaceable></term>
+<listitem><para>
+specify indent string
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-i</option> <replaceable>STRING</replaceable></term>
+<listitem><para>
+specify incremental indent string
+</para></listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term><option>-s</option> <replaceable>NUMBER</replaceable></term>
+<listitem><para>
+specify line spacing
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-h</option>, <option>--help</option></term>
+<listitem><para>
+Print brief help and exit.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>-v</option>, <option>--version</option></term>
+<listitem><para>
+Print version and exit.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+</refsect1>
+</refentry>
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
new file mode 100644
index 0000000..e5ffe5b
--- /dev/null
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -0,0 +1,994 @@
+<INCLUDE>glib-object.h</INCLUDE>
+
+<SECTION>
+<FILE>gtype</FILE>
+<TITLE>Type Information</TITLE>
+GType
+G_TYPE_FUNDAMENTAL
+G_TYPE_FUNDAMENTAL_MAX
+G_TYPE_MAKE_FUNDAMENTAL
+G_TYPE_IS_ABSTRACT
+G_TYPE_IS_DERIVED
+G_TYPE_IS_FUNDAMENTAL
+G_TYPE_IS_VALUE_TYPE
+G_TYPE_HAS_VALUE_TABLE
+G_TYPE_IS_CLASSED
+G_TYPE_IS_INSTANTIATABLE
+G_TYPE_IS_DERIVABLE
+G_TYPE_IS_DEEP_DERIVABLE
+G_TYPE_IS_INTERFACE
+GTypeInterface
+GTypeInstance
+GTypeClass
+GTypeInfo
+GTypeFundamentalInfo
+GInterfaceInfo
+GTypeValueTable
+G_TYPE_FROM_INSTANCE
+G_TYPE_FROM_CLASS
+G_TYPE_FROM_INTERFACE
+G_TYPE_INSTANCE_GET_CLASS
+G_TYPE_INSTANCE_GET_INTERFACE
+G_TYPE_INSTANCE_GET_PRIVATE
+G_TYPE_CLASS_GET_PRIVATE
+G_TYPE_CHECK_INSTANCE
+G_TYPE_CHECK_INSTANCE_CAST
+G_TYPE_CHECK_INSTANCE_TYPE
+G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE
+G_TYPE_CHECK_CLASS_CAST
+G_TYPE_CHECK_CLASS_TYPE
+G_TYPE_CHECK_VALUE
+G_TYPE_CHECK_VALUE_TYPE
+G_TYPE_FLAG_RESERVED_ID_BIT
+g_type_init
+GTypeDebugFlags
+g_type_init_with_debug_flags
+g_type_name
+g_type_qname
+g_type_from_name
+g_type_parent
+g_type_depth
+g_type_next_base
+g_type_is_a
+g_type_class_ref
+g_type_class_peek
+g_type_class_peek_static
+g_type_class_unref
+g_type_class_peek_parent
+g_type_class_add_private
+g_type_add_class_private
+g_type_interface_peek
+g_type_interface_peek_parent
+g_type_default_interface_ref
+g_type_default_interface_peek
+g_type_default_interface_unref
+g_type_children
+g_type_interfaces
+g_type_interface_prerequisites
+g_type_set_qdata
+g_type_get_qdata
+g_type_query
+GTypeQuery
+GBaseInitFunc
+GBaseFinalizeFunc
+GClassInitFunc
+GClassFinalizeFunc
+GInstanceInitFunc
+GInterfaceInitFunc
+GInterfaceFinalizeFunc
+GTypeClassCacheFunc
+GTypeFlags
+GTypeFundamentalFlags
+g_type_register_static
+g_type_register_static_simple
+g_type_register_dynamic
+g_type_register_fundamental
+g_type_add_interface_static
+g_type_add_interface_dynamic
+g_type_interface_add_prerequisite
+g_type_get_plugin
+g_type_interface_get_plugin
+g_type_fundamental_next
+g_type_fundamental
+g_type_create_instance
+g_type_free_instance
+g_type_add_class_cache_func
+g_type_remove_class_cache_func
+g_type_class_unref_uncached
+g_type_add_interface_check
+g_type_remove_interface_check
+GTypeInterfaceCheckFunc
+g_type_value_table_peek
+g_type_ensure
+g_type_get_type_registration_serial
+g_type_get_instance_count
+
+G_DECLARE_FINAL_TYPE
+G_DECLARE_DERIVABLE_TYPE
+G_DECLARE_INTERFACE
+G_DEFINE_TYPE
+G_DEFINE_TYPE_WITH_PRIVATE
+G_DEFINE_TYPE_WITH_CODE
+G_DEFINE_ABSTRACT_TYPE
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE
+G_ADD_PRIVATE
+G_PRIVATE_OFFSET
+G_PRIVATE_FIELD
+G_PRIVATE_FIELD_P
+G_DEFINE_INTERFACE
+G_DEFINE_INTERFACE_WITH_CODE
+G_IMPLEMENT_INTERFACE
+G_DEFINE_TYPE_EXTENDED
+G_DEFINE_BOXED_TYPE
+G_DEFINE_BOXED_TYPE_WITH_CODE
+G_DEFINE_POINTER_TYPE
+G_DEFINE_POINTER_TYPE_WITH_CODE
+
+<SUBSECTION Private>
+G_TYPE_FUNDAMENTAL_SHIFT
+g_type_check_instance
+g_type_check_instance_cast
+g_type_check_instance_is_a
+g_type_check_instance_is_fundamentally_a
+g_type_check_class_cast
+g_type_check_class_is_a
+g_type_check_is_value_type
+g_type_check_value
+g_type_check_value_holds
+g_type_class_adjust_private_offset
+g_type_add_instance_private
+g_type_instance_get_private
+g_type_class_get_instance_private_offset
+g_type_class_get_private
+g_type_test_flags
+g_type_name_from_instance
+g_type_name_from_class
+
+<SUBSECTION>
+G_TYPE_INVALID
+G_TYPE_NONE
+G_TYPE_INTERFACE
+G_TYPE_CHAR
+G_TYPE_UCHAR
+G_TYPE_BOOLEAN
+G_TYPE_INT
+G_TYPE_UINT
+G_TYPE_LONG
+G_TYPE_ULONG
+G_TYPE_INT64
+G_TYPE_UINT64
+G_TYPE_ENUM
+G_TYPE_FLAGS
+G_TYPE_FLOAT
+G_TYPE_DOUBLE
+G_TYPE_STRING
+G_TYPE_POINTER
+G_TYPE_BOXED
+G_TYPE_PARAM
+G_TYPE_OBJECT
+G_TYPE_GTYPE
+G_TYPE_VARIANT
+G_TYPE_CHECKSUM
+
+<SUBSECTION>
+G_TYPE_RESERVED_GLIB_FIRST
+G_TYPE_RESERVED_GLIB_LAST
+G_TYPE_RESERVED_BSE_FIRST
+G_TYPE_RESERVED_BSE_LAST
+G_TYPE_RESERVED_USER_FIRST
+
+<SUBSECTION Private>
+GOBJECT_VAR
+</SECTION>
+
+<SECTION>
+<FILE>gtypeplugin</FILE>
+<TITLE>GTypePlugin</TITLE>
+GTypePlugin
+GTypePluginClass
+GTypePluginUse
+GTypePluginUnuse
+GTypePluginCompleteTypeInfo
+GTypePluginCompleteInterfaceInfo
+g_type_plugin_use
+g_type_plugin_unuse
+g_type_plugin_complete_type_info
+g_type_plugin_complete_interface_info
+<SUBSECTION Standard>
+G_TYPE_PLUGIN
+G_IS_TYPE_PLUGIN
+G_TYPE_TYPE_PLUGIN
+g_type_plugin_get_type
+G_TYPE_PLUGIN_CLASS
+G_IS_TYPE_PLUGIN_CLASS
+G_TYPE_PLUGIN_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>gtypemodule</FILE>
+<TITLE>GTypeModule</TITLE>
+GTypeModule
+GTypeModuleClass
+g_type_module_use
+g_type_module_unuse
+g_type_module_set_name
+g_type_module_register_type
+g_type_module_add_interface
+g_type_module_register_enum
+g_type_module_register_flags
+
+G_DEFINE_DYNAMIC_TYPE
+G_DEFINE_DYNAMIC_TYPE_EXTENDED
+G_IMPLEMENT_INTERFACE_DYNAMIC
+G_ADD_PRIVATE_DYNAMIC
+
+<SUBSECTION Standard>
+G_TYPE_MODULE
+G_IS_TYPE_MODULE
+G_TYPE_TYPE_MODULE
+g_type_module_get_type
+G_TYPE_MODULE_CLASS
+G_IS_TYPE_MODULE_CLASS
+G_TYPE_MODULE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<TITLE>The Base Object Type</TITLE>
+<FILE>objects</FILE>
+GObject
+GObjectClass
+GObjectConstructParam
+GObjectGetPropertyFunc
+GObjectSetPropertyFunc
+GObjectFinalizeFunc
+G_TYPE_IS_OBJECT
+G_OBJECT
+G_IS_OBJECT
+G_OBJECT_CLASS
+G_IS_OBJECT_CLASS
+G_OBJECT_GET_CLASS
+G_OBJECT_TYPE
+G_OBJECT_TYPE_NAME
+G_OBJECT_CLASS_TYPE
+G_OBJECT_CLASS_NAME
+g_object_class_install_property
+g_object_class_install_properties
+g_object_class_find_property
+g_object_class_list_properties
+g_object_class_override_property
+g_object_interface_install_property
+g_object_interface_find_property
+g_object_interface_list_properties
+g_object_new
+g_object_new_with_properties
+g_object_newv
+GParameter
+g_object_ref
+g_object_unref
+g_object_ref_sink
+g_set_object
+g_clear_object
+GInitiallyUnowned
+GInitiallyUnownedClass
+G_TYPE_INITIALLY_UNOWNED
+g_object_is_floating
+g_object_force_floating
+GWeakNotify
+g_object_weak_ref
+g_object_weak_unref
+g_object_add_weak_pointer
+g_object_remove_weak_pointer
+g_set_weak_pointer
+g_clear_weak_pointer
+GToggleNotify
+g_object_add_toggle_ref
+g_object_remove_toggle_ref
+g_object_connect
+g_object_disconnect
+g_object_set
+g_object_setv
+g_object_get
+g_object_getv
+g_object_notify
+g_object_notify_by_pspec
+g_object_freeze_notify
+g_object_thaw_notify
+g_object_get_data
+g_object_set_data
+g_object_set_data_full
+g_object_steal_data
+g_object_dup_data
+g_object_replace_data
+g_object_get_qdata
+g_object_set_qdata
+g_object_set_qdata_full
+g_object_steal_qdata
+g_object_dup_qdata
+g_object_replace_qdata
+g_object_set_property
+g_object_get_property
+g_object_new_valist
+g_object_set_valist
+g_object_get_valist
+g_object_watch_closure
+g_object_run_dispose
+G_OBJECT_WARN_INVALID_PROPERTY_ID
+
+<SUBSECTION Weak references>
+GWeakRef
+g_weak_ref_init
+g_weak_ref_clear
+g_weak_ref_get
+g_weak_ref_set
+
+<SUBSECTION Testing>
+g_assert_finalize_object
+
+<SUBSECTION Standard>
+G_INITIALLY_UNOWNED
+G_INITIALLY_UNOWNED_CLASS
+G_INITIALLY_UNOWNED_GET_CLASS
+G_IS_INITIALLY_UNOWNED
+G_IS_INITIALLY_UNOWNED_CLASS
+
+<SUBSECTION Private>
+G_OBJECT_WARN_INVALID_PSPEC
+g_initially_unowned_get_type
+g_object_compat_control
+g_object_get_type
+</SECTION>
+
+<SECTION>
+<TITLE>Enumeration and Flag Types</TITLE>
+<FILE>enumerations_flags</FILE>
+GEnumClass
+GFlagsClass
+G_ENUM_CLASS_TYPE
+G_ENUM_CLASS_TYPE_NAME
+G_TYPE_IS_ENUM
+G_ENUM_CLASS
+G_IS_ENUM_CLASS
+G_TYPE_IS_FLAGS
+G_FLAGS_CLASS
+G_IS_FLAGS_CLASS
+G_FLAGS_CLASS_TYPE
+G_FLAGS_CLASS_TYPE_NAME
+GEnumValue
+GFlagsValue
+g_enum_get_value
+g_enum_get_value_by_name
+g_enum_get_value_by_nick
+g_enum_to_string
+g_flags_get_first_value
+g_flags_get_value_by_name
+g_flags_get_value_by_nick
+g_flags_to_string
+g_enum_register_static
+g_flags_register_static
+g_enum_complete_type_info
+g_flags_complete_type_info
+</SECTION>
+
+<SECTION>
+<FILE>gboxed</FILE>
+<TITLE>Boxed Types</TITLE>
+GBoxedCopyFunc
+GBoxedFreeFunc
+g_boxed_copy
+g_boxed_free
+g_boxed_type_register_static
+g_pointer_type_register_static
+
+<SUBSECTION>
+G_TYPE_HASH_TABLE
+G_TYPE_DATE
+G_TYPE_GSTRING
+G_TYPE_STRV
+G_TYPE_REGEX
+G_TYPE_MATCH_INFO
+G_TYPE_ARRAY
+G_TYPE_BYTE_ARRAY
+G_TYPE_PTR_ARRAY
+G_TYPE_BYTES
+G_TYPE_VARIANT_TYPE
+G_TYPE_ERROR
+G_TYPE_DATE_TIME
+G_TYPE_TIME_ZONE
+G_TYPE_IO_CHANNEL
+G_TYPE_IO_CONDITION
+G_TYPE_VARIANT_BUILDER
+G_TYPE_VARIANT_DICT
+G_TYPE_KEY_FILE
+G_TYPE_MAIN_CONTEXT
+G_TYPE_MAIN_LOOP
+G_TYPE_MAPPED_FILE
+G_TYPE_MARKUP_PARSE_CONTEXT
+G_TYPE_SOURCE
+G_TYPE_POLLFD
+G_TYPE_THREAD
+G_TYPE_OPTION_GROUP
+
+<SUBSECTION Standard>
+G_TYPE_IS_BOXED
+
+<SUBSECTION Private>
+g_gstring_get_type
+g_strv_get_type
+g_date_get_type
+g_hash_table_get_type
+g_regex_get_type
+g_match_info_get_type
+g_array_get_type
+g_byte_array_get_type
+g_ptr_array_get_type
+g_error_get_type
+g_date_time_get_type
+g_time_zone_get_type
+g_variant_get_gtype
+g_variant_type_get_gtype
+g_variant_builder_get_type
+g_variant_dict_get_type
+g_gtype_get_type
+g_main_context_get_type
+g_main_loop_get_type
+g_source_get_type
+g_pollfd_get_type
+g_bytes_get_type
+g_key_file_get_type
+g_checksum_get_type
+g_mapped_file_get_type
+g_markup_parse_context_get_type
+g_thread_get_type
+g_option_group_get_type
+</SECTION>
+
+<SECTION>
+<TITLE>Generic values</TITLE>
+<FILE>generic_values</FILE>
+G_VALUE_INIT
+G_VALUE_HOLDS
+G_VALUE_TYPE
+G_VALUE_TYPE_NAME
+G_TYPE_IS_VALUE
+G_TYPE_IS_VALUE_ABSTRACT
+G_IS_VALUE
+GValue
+G_TYPE_VALUE
+G_TYPE_VALUE_ARRAY
+g_value_init
+g_value_copy
+g_value_reset
+g_value_unset
+g_value_init_from_instance
+g_value_set_instance
+g_value_fits_pointer
+g_value_peek_pointer
+g_value_type_compatible
+g_value_type_transformable
+g_value_transform
+GValueTransform
+g_value_register_transform_func
+g_strdup_value_contents
+
+<SUBSECTION Private>
+G_VALUE_NOCOPY_CONTENTS
+g_value_get_type
+g_value_array_get_type
+</SECTION>
+
+<SECTION>
+<TITLE>Value arrays</TITLE>
+<FILE>value_arrays</FILE>
+GValueArray
+g_value_array_get_nth
+g_value_array_new
+g_value_array_copy
+g_value_array_free
+g_value_array_append
+g_value_array_prepend
+g_value_array_insert
+g_value_array_remove
+g_value_array_sort
+g_value_array_sort_with_data
+</SECTION>
+
+<SECTION>
+<TITLE>GParamSpec</TITLE>
+<FILE>gparamspec</FILE>
+G_TYPE_IS_PARAM
+G_PARAM_SPEC
+G_IS_PARAM_SPEC
+G_PARAM_SPEC_CLASS
+G_IS_PARAM_SPEC_CLASS
+G_PARAM_SPEC_GET_CLASS
+G_PARAM_SPEC_TYPE
+G_PARAM_SPEC_TYPE_NAME
+G_PARAM_SPEC_VALUE_TYPE
+GParamSpec
+GParamSpecClass
+GParamFlags
+G_PARAM_STATIC_STRINGS
+G_PARAM_MASK
+G_PARAM_USER_SHIFT
+g_param_spec_ref
+g_param_spec_unref
+g_param_spec_sink
+g_param_spec_ref_sink
+g_param_spec_get_default_value
+g_param_value_set_default
+g_param_value_defaults
+g_param_value_validate
+g_param_value_convert
+g_param_values_cmp
+g_param_spec_is_valid_name
+g_param_spec_get_name
+g_param_spec_get_name_quark
+g_param_spec_get_nick
+g_param_spec_get_blurb
+g_param_spec_get_qdata
+g_param_spec_set_qdata
+g_param_spec_set_qdata_full
+g_param_spec_steal_qdata
+g_param_spec_get_redirect_target
+g_param_spec_internal
+GParamSpecTypeInfo
+g_param_type_register_static
+GParamSpecPool
+g_param_spec_pool_new
+g_param_spec_pool_insert
+g_param_spec_pool_remove
+g_param_spec_pool_lookup
+g_param_spec_pool_list
+g_param_spec_pool_list_owned
+</SECTION>
+
+<SECTION>
+<TITLE>Standard Parameter and Value Types</TITLE>
+<FILE>param_value_types</FILE>
+
+<SUBSECTION gboolean>
+G_IS_PARAM_SPEC_BOOLEAN
+G_PARAM_SPEC_BOOLEAN
+G_VALUE_HOLDS_BOOLEAN
+G_TYPE_PARAM_BOOLEAN
+GParamSpecBoolean
+g_param_spec_boolean
+g_value_set_boolean
+g_value_get_boolean
+
+<SUBSECTION gchar>
+G_IS_PARAM_SPEC_CHAR
+G_PARAM_SPEC_CHAR
+G_VALUE_HOLDS_CHAR
+G_TYPE_PARAM_CHAR
+GParamSpecChar
+g_param_spec_char
+g_value_set_char
+g_value_get_char
+g_value_get_schar
+g_value_set_schar
+
+<SUBSECTION guchar>
+G_IS_PARAM_SPEC_UCHAR
+G_PARAM_SPEC_UCHAR
+G_VALUE_HOLDS_UCHAR
+G_TYPE_PARAM_UCHAR
+GParamSpecUChar
+g_param_spec_uchar
+g_value_set_uchar
+g_value_get_uchar
+
+<SUBSECTION gint>
+G_IS_PARAM_SPEC_INT
+G_PARAM_SPEC_INT
+G_VALUE_HOLDS_INT  
+G_TYPE_PARAM_INT
+GParamSpecInt
+g_param_spec_int
+g_value_set_int
+g_value_get_int
+
+<SUBSECTION guint>
+G_IS_PARAM_SPEC_UINT
+G_PARAM_SPEC_UINT
+G_VALUE_HOLDS_UINT  
+G_TYPE_PARAM_UINT
+GParamSpecUInt
+g_param_spec_uint
+g_value_set_uint
+g_value_get_uint
+
+<SUBSECTION glong>
+G_IS_PARAM_SPEC_LONG
+G_PARAM_SPEC_LONG
+G_VALUE_HOLDS_LONG 
+G_TYPE_PARAM_LONG
+GParamSpecLong
+g_param_spec_long
+g_value_set_long
+g_value_get_long
+
+<SUBSECTION gulong>
+G_IS_PARAM_SPEC_ULONG
+G_PARAM_SPEC_ULONG
+G_VALUE_HOLDS_ULONG 
+G_TYPE_PARAM_ULONG
+GParamSpecULong
+g_param_spec_ulong
+g_value_set_ulong
+g_value_get_ulong
+
+<SUBSECTION gint64>
+G_IS_PARAM_SPEC_INT64
+G_PARAM_SPEC_INT64
+G_VALUE_HOLDS_INT64
+G_TYPE_PARAM_INT64
+GParamSpecInt64
+g_param_spec_int64
+g_value_set_int64
+g_value_get_int64
+
+<SUBSECTION guint64>
+G_IS_PARAM_SPEC_UINT64
+G_PARAM_SPEC_UINT64
+G_VALUE_HOLDS_UINT64
+G_TYPE_PARAM_UINT64
+GParamSpecUInt64
+g_param_spec_uint64
+g_value_set_uint64
+g_value_get_uint64
+
+<SUBSECTION gfloat>
+G_IS_PARAM_SPEC_FLOAT
+G_PARAM_SPEC_FLOAT
+G_VALUE_HOLDS_FLOAT
+G_TYPE_PARAM_FLOAT
+GParamSpecFloat
+g_param_spec_float
+g_value_set_float
+g_value_get_float
+
+<SUBSECTION gdouble>
+G_IS_PARAM_SPEC_DOUBLE
+G_PARAM_SPEC_DOUBLE
+G_VALUE_HOLDS_DOUBLE
+G_TYPE_PARAM_DOUBLE
+GParamSpecDouble
+g_param_spec_double
+g_value_set_double
+g_value_get_double
+
+<SUBSECTION GEnum>
+G_IS_PARAM_SPEC_ENUM
+G_PARAM_SPEC_ENUM
+G_VALUE_HOLDS_ENUM
+G_TYPE_PARAM_ENUM
+GParamSpecEnum
+g_param_spec_enum
+g_value_set_enum
+g_value_get_enum
+
+<SUBSECTION GFLags>
+G_IS_PARAM_SPEC_FLAGS
+G_PARAM_SPEC_FLAGS
+G_VALUE_HOLDS_FLAGS
+G_TYPE_PARAM_FLAGS
+GParamSpecFlags
+g_param_spec_flags
+g_value_set_flags
+g_value_get_flags
+
+<SUBSECTION gchararray>
+G_IS_PARAM_SPEC_STRING
+G_PARAM_SPEC_STRING
+G_VALUE_HOLDS_STRING
+G_TYPE_PARAM_STRING
+G_VALUE_IS_INTERNED_STRING
+G_VALUE_INTERNED_STRING
+GParamSpecString
+gchararray
+g_param_spec_string
+g_value_set_string
+g_value_set_static_string
+g_value_take_string
+g_value_set_string_take_ownership
+g_value_get_string
+g_value_dup_string
+g_value_set_interned_string
+
+<SUBSECTION GParamSpec>
+G_IS_PARAM_SPEC_PARAM
+G_PARAM_SPEC_PARAM
+G_VALUE_HOLDS_PARAM
+G_TYPE_PARAM_PARAM
+GParamSpecParam
+g_param_spec_param
+g_value_set_param
+g_value_take_param
+g_value_set_param_take_ownership
+g_value_get_param
+g_value_dup_param
+
+<SUBSECTION GBoxed>
+G_IS_PARAM_SPEC_BOXED
+G_PARAM_SPEC_BOXED
+G_VALUE_HOLDS_BOXED
+G_TYPE_PARAM_BOXED
+GParamSpecBoxed
+g_param_spec_boxed
+g_value_set_boxed
+g_value_set_static_boxed
+g_value_take_boxed
+g_value_set_boxed_take_ownership
+g_value_get_boxed
+g_value_dup_boxed
+
+<SUBSECTION gpointer>
+G_IS_PARAM_SPEC_POINTER
+G_PARAM_SPEC_POINTER
+G_VALUE_HOLDS_POINTER
+G_TYPE_PARAM_POINTER
+GParamSpecPointer
+g_param_spec_pointer
+g_value_set_pointer
+g_value_get_pointer
+
+<SUBSECTION GObject>
+G_IS_PARAM_SPEC_OBJECT
+G_PARAM_SPEC_OBJECT
+G_VALUE_HOLDS_OBJECT
+G_TYPE_PARAM_OBJECT
+GParamSpecObject
+g_param_spec_object
+g_value_set_object
+g_value_take_object
+g_value_set_object_take_ownership
+g_value_get_object
+g_value_dup_object
+
+<SUBSECTION gunichar>
+G_IS_PARAM_SPEC_UNICHAR
+G_PARAM_SPEC_UNICHAR
+G_TYPE_PARAM_UNICHAR
+GParamSpecUnichar
+g_param_spec_unichar
+
+<SUBSECTION GValueArray>
+G_IS_PARAM_SPEC_VALUE_ARRAY
+G_PARAM_SPEC_VALUE_ARRAY
+G_TYPE_PARAM_VALUE_ARRAY
+GParamSpecValueArray
+g_param_spec_value_array
+
+<SUBSECTION Override>
+G_IS_PARAM_SPEC_OVERRIDE
+G_PARAM_SPEC_OVERRIDE
+G_TYPE_PARAM_OVERRIDE
+GParamSpecOverride
+g_param_spec_override
+
+<SUBSECTION GType>
+G_IS_PARAM_SPEC_GTYPE
+G_PARAM_SPEC_GTYPE
+G_VALUE_HOLDS_GTYPE
+G_TYPE_PARAM_GTYPE
+GParamSpecGType
+g_param_spec_gtype
+g_value_get_gtype
+g_value_set_gtype
+
+<SUBSECTION GVariant>
+G_IS_PARAM_SPEC_VARIANT
+G_PARAM_SPEC_VARIANT
+G_VALUE_HOLDS_VARIANT
+G_TYPE_PARAM_VARIANT
+GParamSpecVariant
+g_param_spec_variant
+g_value_get_variant
+g_value_dup_variant
+g_value_set_variant
+g_value_take_variant
+
+<SUBSECTION Private>
+g_value_set_instance
+g_param_spec_types
+</SECTION>
+
+<SECTION>
+<TITLE>Varargs Value Collection</TITLE>
+<FILE>value_collection</FILE>
+<INCLUDE>glib-object.h,gobject/gvaluecollector.h</INCLUDE>
+GTypeCValue
+G_VALUE_COLLECT_INIT
+G_VALUE_COLLECT
+G_VALUE_COLLECT_SKIP
+G_VALUE_LCOPY
+G_VALUE_COLLECT_FORMAT_MAX_LENGTH
+</SECTION>
+
+<SECTION>
+<TITLE>Signals</TITLE>
+<FILE>signals</FILE>
+GSignalInvocationHint
+GSignalAccumulator
+GSignalCMarshaller
+GSignalCVaMarshaller
+GSignalEmissionHook
+GSignalFlags
+GSignalMatchType
+GSignalQuery
+G_SIGNAL_TYPE_STATIC_SCOPE
+G_SIGNAL_MATCH_MASK
+G_SIGNAL_FLAGS_MASK
+g_signal_new
+g_signal_newv
+g_signal_new_valist
+g_signal_set_va_marshaller
+g_signal_query
+g_signal_lookup
+g_signal_name
+g_signal_list_ids
+g_signal_emit
+g_signal_emit_by_name
+g_signal_emitv
+g_signal_emit_valist
+g_signal_connect
+g_signal_connect_after
+g_signal_connect_swapped
+g_signal_connect_object
+GConnectFlags
+g_signal_connect_data
+g_signal_connect_closure
+g_signal_connect_closure_by_id
+g_signal_handler_block
+g_signal_handler_unblock
+g_signal_handler_disconnect
+g_signal_handler_find
+g_signal_handlers_block_matched
+g_signal_handlers_unblock_matched
+g_signal_handlers_disconnect_matched
+g_signal_handler_is_connected
+g_signal_handlers_block_by_func
+g_signal_handlers_unblock_by_func
+g_signal_handlers_disconnect_by_func
+g_signal_handlers_disconnect_by_data
+g_signal_has_handler_pending
+g_signal_stop_emission
+g_signal_stop_emission_by_name
+g_signal_override_class_closure
+g_signal_chain_from_overridden
+g_signal_new_class_handler
+g_signal_override_class_handler
+g_signal_chain_from_overridden_handler
+g_signal_add_emission_hook
+g_signal_remove_emission_hook
+g_signal_is_valid_name
+g_signal_parse_name
+g_signal_get_invocation_hint
+g_signal_type_cclosure_new
+g_signal_accumulator_first_wins
+g_signal_accumulator_true_handled
+g_clear_signal_handler
+<SUBSECTION Private>
+g_signal_handlers_destroy
+</SECTION>
+
+<SECTION>
+<FILE>gclosure</FILE>
+<TITLE>Closures</TITLE>
+G_CLOSURE_NEEDS_MARSHAL
+G_CLOSURE_N_NOTIFIERS
+G_CCLOSURE_SWAP_DATA
+G_CALLBACK
+GCallback
+GClosure
+G_TYPE_CLOSURE
+GCClosure
+GClosureMarshal
+GVaClosureMarshal
+GClosureNotify
+g_cclosure_new
+g_cclosure_new_swap
+g_cclosure_new_object
+g_cclosure_new_object_swap
+g_cclosure_marshal_generic
+g_closure_new_object
+g_closure_ref
+g_closure_sink
+g_closure_unref
+g_closure_invoke
+g_closure_invalidate
+g_closure_add_finalize_notifier
+g_closure_add_invalidate_notifier
+g_closure_remove_finalize_notifier
+g_closure_remove_invalidate_notifier
+g_closure_new_simple
+g_closure_set_marshal
+g_closure_add_marshal_guards
+g_closure_set_meta_marshal
+g_source_set_closure
+g_source_set_dummy_callback
+
+<SUBSECTION>
+g_cclosure_marshal_VOID__VOID
+g_cclosure_marshal_VOID__BOOLEAN
+g_cclosure_marshal_VOID__CHAR
+g_cclosure_marshal_VOID__UCHAR
+g_cclosure_marshal_VOID__INT
+g_cclosure_marshal_VOID__UINT
+g_cclosure_marshal_VOID__LONG
+g_cclosure_marshal_VOID__ULONG
+g_cclosure_marshal_VOID__ENUM
+g_cclosure_marshal_VOID__FLAGS
+g_cclosure_marshal_VOID__FLOAT
+g_cclosure_marshal_VOID__DOUBLE
+g_cclosure_marshal_VOID__STRING
+g_cclosure_marshal_VOID__PARAM
+g_cclosure_marshal_VOID__BOXED
+g_cclosure_marshal_VOID__POINTER
+g_cclosure_marshal_VOID__OBJECT
+g_cclosure_marshal_VOID__VARIANT
+g_cclosure_marshal_STRING__OBJECT_POINTER
+g_cclosure_marshal_VOID__UINT_POINTER
+g_cclosure_marshal_BOOLEAN__FLAGS
+g_cclosure_marshal_BOOL__FLAGS
+g_cclosure_marshal_BOOLEAN__BOXED_BOXED
+g_cclosure_marshal_BOOL__BOXED_BOXED
+
+<SUBSECTION>
+g_cclosure_marshal_generic_va
+g_cclosure_marshal_VOID__VOIDv
+g_cclosure_marshal_VOID__BOOLEANv
+g_cclosure_marshal_VOID__CHARv
+g_cclosure_marshal_VOID__UCHARv
+g_cclosure_marshal_VOID__INTv
+g_cclosure_marshal_VOID__UINTv
+g_cclosure_marshal_VOID__LONGv
+g_cclosure_marshal_VOID__ULONGv
+g_cclosure_marshal_VOID__ENUMv
+g_cclosure_marshal_VOID__FLAGSv
+g_cclosure_marshal_VOID__FLOATv
+g_cclosure_marshal_VOID__DOUBLEv
+g_cclosure_marshal_VOID__STRINGv
+g_cclosure_marshal_VOID__PARAMv
+g_cclosure_marshal_VOID__BOXEDv
+g_cclosure_marshal_VOID__POINTERv
+g_cclosure_marshal_VOID__OBJECTv
+g_cclosure_marshal_VOID__VARIANTv
+g_cclosure_marshal_STRING__OBJECT_POINTERv
+g_cclosure_marshal_VOID__UINT_POINTERv
+g_cclosure_marshal_BOOLEAN__FLAGSv
+g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv
+
+<SUBSECTION Private>
+GClosureNotifyData
+g_closure_get_type
+g_io_channel_get_type
+g_io_condition_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gbinding</FILE>
+GBinding
+GBindingFlags
+g_binding_get_source
+g_binding_get_source_property
+g_binding_get_target
+g_binding_get_target_property
+g_binding_get_flags
+g_binding_unbind
+<SUBSECTION>
+g_object_bind_property
+GBindingTransformFunc
+g_object_bind_property_full
+g_object_bind_property_with_closures
+<SUBSECTION Standard>
+G_TYPE_BINDING
+G_TYPE_BINDING_FLAGS
+G_BINDING
+G_IS_BINDING
+<SUBSECTION Private>
+g_binding_flags_get_type
+g_binding_get_type
+</SECTION>
diff --git a/docs/reference/gobject/images/glue.png b/docs/reference/gobject/images/glue.png
new file mode 100644
index 0000000..f5f3aab
--- /dev/null
+++ b/docs/reference/gobject/images/glue.png
Binary files differ
diff --git a/docs/reference/gobject/meson.build b/docs/reference/gobject/meson.build
new file mode 100644
index 0000000..a9a6543
--- /dev/null
+++ b/docs/reference/gobject/meson.build
@@ -0,0 +1,68 @@
+if get_option('gtk_doc')
+  subdir('xml')
+
+  ignore_headers = [
+    'tests',
+    'gatomicarray.h',
+    'gobject_probes.h',
+    'gobject_trace.h',
+    'gtype-private.h',
+    'glib-enumtypes.h',
+  ]
+
+  docpath = join_paths(glib_datadir, 'gtk-doc', 'html')
+  version_conf = configuration_data()
+  version_conf.set('GLIB_VERSION', meson.project_version())
+  configure_file(
+    input: 'version.xml.in',
+    output: 'version.xml',
+    configuration: version_conf
+  )
+
+  gtkdocincl = include_directories('.')
+
+  gnome.gtkdoc('gobject',
+    main_xml : 'gobject-docs.xml',
+    namespace : 'g',
+    mode : 'none',
+    dependencies : [libgobject_dep, libglib_dep],
+    include_directories : [gtkdocincl],
+    src_dir : 'gobject',
+    scan_args : gtkdoc_common_scan_args + [
+      '--rebuild-types',
+      '--ignore-headers=' + ' '.join(ignore_headers),
+    ],
+    content_files : [
+      'glib-mkenums.xml',
+      'glib-genmarshal.xml',
+      'gobject-query.xml',
+      'tut_gobject.xml',
+      'tut_gsignal.xml',
+      'tut_gtype.xml',
+      'tut_howto.xml',
+      'tut_intro.xml',
+      'tut_tools.xml'
+    ],
+    html_assets : [
+      'images/glue.png'
+    ],
+    fixxref_args: [
+      '--html-dir=' + docpath,
+      '--extra-dir=' + join_paths('gobject', '..', 'glib', 'html'),
+    ],
+    install: true,
+    check: true,
+  )
+endif
+
+if get_option('man')
+  manpages = ['glib-mkenums', 'glib-genmarshal', 'gobject-query']
+  foreach page : manpages
+    custom_target(page + '-man',
+      input: page + '.xml',
+      output: page + '.1',
+      command: xsltproc_command,
+      install: true,
+      install_dir: man1_dir)
+  endforeach
+endif
diff --git a/docs/reference/gobject/tut_gobject.xml b/docs/reference/gobject/tut_gobject.xml
new file mode 100644
index 0000000..fc7d6fe
--- /dev/null
+++ b/docs/reference/gobject/tut_gobject.xml
@@ -0,0 +1,728 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<chapter id="chapter-gobject">
+  <title>The GObject base class</title>
+
+  <para>
+    The previous chapter discussed the details of GLib's Dynamic Type System.
+    The GObject library also contains an implementation for a base fundamental
+    type named <link linkend="GObject"><type>GObject</type></link>.
+  </para>
+
+  <para>
+    <link linkend="GObject"><type>GObject</type></link> is a fundamental classed instantiable type. It implements:
+    <itemizedlist>
+      <listitem><para>Memory management with reference counting</para></listitem>
+      <listitem><para>Construction/Destruction of instances</para></listitem>
+      <listitem><para>Generic per-object properties with set/get function pairs</para></listitem>
+      <listitem><para>Easy use of signals</para></listitem>
+    </itemizedlist>
+    All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer)
+    inherit from <link linkend="GObject"><type>GObject</type></link> which is why it is important to understand
+    the details of how it works.
+  </para>
+
+  <sect1 id="gobject-instantiation">
+    <title>Object instantiation</title>
+
+    <para>
+      The <function><link linkend="g-object-new">g_object_new</link></function>
+      family of functions can be used to instantiate any GType which inherits
+      from the GObject base type. All these functions make sure the class and
+      instance structures have been correctly initialized by GLib's type system
+      and then invoke at one point or another the constructor class method
+      which is used to:
+      <itemizedlist>
+        <listitem><para>
+            Allocate and clear memory through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>,
+          </para></listitem>
+        <listitem><para>
+            Initialize the object's instance with the construction properties.
+          </para></listitem>
+      </itemizedlist>
+     Although one can expect all class and instance members (except the fields
+     pointing to the parents) to be set to zero, some consider it good practice
+     to explicitly set them.
+    </para>
+
+    <para>
+      Once all construction operations have been completed and constructor
+      properties set, the constructed class method is called.
+    </para>
+
+    <para>
+      Objects which inherit from GObject are allowed to override this
+      constructed class method.
+      The example below shows how <type>ViewerFile</type> overrides the parent's construction process:
+<informalexample><programlisting>
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
+
+struct _ViewerFile
+{
+  GObject parent_instance;
+
+  /* instance members */
+  gchar *filename;
+  guint zoom_level;
+};
+
+/* will create viewer_file_get_type and set viewer_file_parent_class */
+G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
+
+static void
+viewer_file_constructed (GObject *obj)
+{
+  /* update the object state depending on constructor properties */
+
+  /* Always chain up to the parent constructed function to complete object
+   * initialisation. */
+  G_OBJECT_CLASS (viewer_file_parent_class)-&gt;constructed (obj);
+}
+
+static void
+viewer_file_finalize (GObject *obj)
+{
+  ViewerFile *self = VIEWER_FILE (obj);
+
+  g_free (self->filename);
+
+  /* Always chain up to the parent finalize function to complete object
+   * destruction. */
+  G_OBJECT_CLASS (viewer_file_parent_class)-&gt;finalize (obj);
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class-&gt;constructed = viewer_file_constructed;
+  object_class-&gt;finalize = viewer_file_finalize;
+}
+
+static void
+viewer_file_init (ViewerFile *self)
+{
+  /* initialize the object */
+}
+
+</programlisting></informalexample>
+      If the user instantiates an object <type>ViewerFile</type> with:
+<informalexample><programlisting>
+ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
+</programlisting></informalexample>        
+      If this is the first instantiation of such an object, the
+      <function>viewer_file_class_init</function> function will be invoked
+      after any <function>viewer_file_base_class_init</function> function.
+      This will make sure the class structure of this new object is
+      correctly initialized. Here, <function>viewer_file_class_init</function>
+      is expected to override the object's class methods and setup the
+      class' own methods. In the example above, the <literal>constructed</literal>
+      method is the only overridden method: it is set to
+      <function>viewer_file_constructed</function>.
+    </para>
+
+    <para>
+      Once <function><link linkend="g-object-new">g_object_new</link></function> has obtained a reference to an initialized
+      class structure, it invokes its constructor method to create an instance of the new 
+      object, if the constructor has been overridden in <function>viewer_file_class_init</function>.
+      Overridden constructors must chain up to their parent’s constructor. In
+      order to find the parent class and chain up to the parent class
+      constructor, we can use the <literal>viewer_file_parent_class</literal>
+      pointer that has been set up for us by the
+      <link linkend="G-DEFINE-TYPE:CAPS"><literal>G_DEFINE_TYPE</literal></link>
+      macro.
+    </para>
+
+    <para>
+      Finally, at one point or another, <function>g_object_constructor</function> is invoked
+      by the last constructor in the chain. This function allocates the object's instance buffer
+      through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
+      which means that the <function>instance_init</function> function is invoked at this point if one
+      was registered. After <function>instance_init</function> returns, the object is fully initialized and should be 
+      ready to have its methods called by the user. When
+      <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
+      returns, <function>g_object_constructor</function> sets the construction properties
+      (i.e. the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns
+      to the user's constructor.
+    </para>
+
+    <para>
+      The process described above might seem a bit complicated, but it can be
+      summarized easily by the table below which lists the functions invoked
+      by <function><link linkend="g-object-new">g_object_new</link></function>
+      and their order of invocation:
+    </para>
+
+    <para>
+      <table id="gobject-construction-table">
+        <title><function><link linkend="g-object-new">g_object_new</link></function></title>
+        <tgroup cols="3">
+          <colspec colwidth="*" colnum="1" align="left"/>
+          <colspec colwidth="*" colnum="2" align="left"/>
+          <colspec colwidth="8*" colnum="3" align="left"/>
+
+          <thead>
+            <row>
+              <entry>Invocation time</entry>
+              <entry>Function invoked</entry>
+              <entry>Function's parameters</entry>
+              <entry>Remark</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry morerows="3">First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
+              <entry>target type's <function>base_init</function> function</entry>
+              <entry>On the inheritance tree of classes from fundamental type to target type. 
+                <function>base_init</function> is invoked once for each class structure.</entry>
+              <entry>Never used in practice. Unlikely you will need it.</entry>
+            </row>
+            <row>
+              <!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
+              <entry>target type's <function>class_init</function> function</entry>
+              <entry>On target type's class structure</entry>
+              <entry>
+                Here, you should make sure to initialize or override class methods (that is,
+                assign to each class' method its function pointer) and create the signals and
+                the properties associated to your object.
+              </entry>
+            </row>
+            <row>
+              <!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
+              <entry>interface's <function>base_init</function> function</entry>
+              <entry>On interface's vtable</entry>
+              <entry></entry>
+            </row>
+            <row>
+              <!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
+              <entry>interface's <function>interface_init</function> function</entry>
+              <entry>On interface's vtable</entry>
+              <entry></entry>
+            </row>
+            <row>
+              <entry morerows="2">Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
+              <entry>target type's class <function>constructor</function> method: <function>GObjectClass->constructor</function></entry>
+              <entry>On object's instance</entry>
+              <entry>
+                If you need to handle construct properties in a custom way, or implement a singleton class, override the constructor
+                method and make sure to chain up to the object's
+                parent class before doing your own initialization.
+                In doubt, do not override the constructor method.
+              </entry>
+            </row>
+            <row>
+              <!--entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
+              <entry>type's <function>instance_init</function> function</entry>
+              <entry>On the inheritance tree of classes from fundamental type to target type. 
+              the <function>instance_init</function> provided for each type is invoked once for each instance 
+              structure.</entry>
+              <entry>
+                Provide an <function>instance_init</function> function to initialize your object before its construction
+                properties are set. This is the preferred way to initialize a GObject instance.
+                This function is equivalent to C++ constructors.
+              </entry>
+            </row>
+            <row>
+              <!--entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
+              <entry>target type's class <function>constructed</function> method: <function>GObjectClass->constructed</function></entry>
+              <entry>On object's instance</entry>
+              <entry>
+                If you need to perform object initialization steps after all construct properties have been set.
+                This is the final step in the object initialization process, and is only called if the <function>constructor</function>
+                method returned a new object instance (rather than, for example, an existing singleton).
+              </entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+    </para>
+
+    <para>
+      Readers should feel concerned about one little twist in the order in
+      which functions are invoked: while, technically, the class' constructor
+      method is called <emphasis>before</emphasis> the GType's <function>instance_init</function>
+      function (since <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> which calls <function>instance_init</function> is called by
+      <function>g_object_constructor</function> which is the top-level class 
+      constructor method and to which users are expected to chain to), the
+      user's code which runs in a user-provided constructor will always
+      run <emphasis>after</emphasis> GType's <function>instance_init</function> function since the
+      user-provided constructor <emphasis>must</emphasis> (you've been warned)
+      chain up <emphasis>before</emphasis> doing anything useful.
+    </para>
+  </sect1>
+
+  <sect1 id="gobject-memory">
+    <title>Object memory management</title>
+
+    <para>
+      The memory-management API for GObjects is a bit complicated but the idea behind it
+      is pretty simple: the goal is to provide a flexible model based on reference counting
+      which can be integrated in applications which use or require different memory management
+      models (such as garbage collection). The methods which are used to
+      manipulate this reference count are described below.
+    </para>
+
+    <sect2 id="gobject-memory-refcount">
+      <title>Reference count</title>
+
+      <para>
+        The functions <function><link linkend="g-object-ref">g_object_ref</link></function>/<function><link linkend="g-object-unref">g_object_unref</link></function> respectively 
+        increase and decrease the reference count. These functions are
+        thread-safe.
+        <function><link linkend="g-clear-object">g_clear_object</link></function>
+        is a convenience wrapper around <function>g_object_unref</function>
+        which also clears the pointer passed to it.
+      </para>
+      <para>
+        The reference count is initialized to one by 
+        <function><link linkend="g-object-new">g_object_new</link></function> which means that the caller
+        is currently the sole owner of the newly-created reference.
+        When the reference count reaches zero, that is, 
+        when <function><link linkend="g-object-unref">g_object_unref</link></function> is called by the last client holding
+        a reference to the object, the <emphasis>dispose</emphasis> and the 
+        <emphasis>finalize</emphasis> class methods are invoked.
+      </para>
+      <para>
+        Finally, after <emphasis>finalize</emphasis> is invoked, 
+        <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is called to free the object instance.
+        Depending on the memory allocation policy decided when the type was registered (through
+        one of the <function>g_type_register_*</function> functions), the object's instance 
+        memory will be freed or returned to the object pool for this type.
+        Once the object has been freed, if it was the last instance of the type, the type's class
+        will be destroyed as described in <xref linkend="gtype-instantiable-classed"/> and 
+          <xref linkend="gtype-non-instantiable-classed"/>.
+      </para>
+
+      <para>
+        The table below summarizes the destruction process of a GObject:
+        <table id="gobject-destruction-table">
+          <title><function><link linkend="g-object-unref">g_object_unref</link></function></title>
+          <tgroup cols="3">
+            <colspec colwidth="*" colnum="1" align="left"/>
+            <colspec colwidth="*" colnum="2" align="left"/>
+            <colspec colwidth="8*" colnum="3" align="left"/>
+
+            <thead>
+              <row>
+                <entry>Invocation time</entry>
+                <entry>Function invoked</entry>
+                <entry>Function's parameters</entry>
+                <entry>Remark</entry>
+              </row>
+            </thead>
+            <tbody>
+              <row>
+                <entry morerows="1">Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
+                  of target type
+                 </entry>
+                <entry>target type's dispose class function</entry>
+                <entry>GObject instance</entry>
+                <entry>
+                  When dispose ends, the object should not hold any reference to any other
+                  member object. The object is also expected to be able to answer client
+                  method invocations (with possibly an error code but no memory violation)
+                  until finalize is executed. dispose can be executed more than once.
+                dispose should chain up to its parent implementation just before returning
+                to the caller.
+                </entry>
+              </row>
+              <row>
+                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
+                  of target type
+                </entry-->
+                <entry>target type's finalize class function</entry>
+                <entry>GObject instance</entry>
+                <entry>
+                  Finalize is expected to complete the destruction process initiated by
+                  dispose. It should complete the object's destruction. finalize will be
+                  executed only once.
+                finalize should chain up to its parent implementation just before returning
+                to the caller.
+                  The reason why the destruction process is split is two different phases is
+                  explained in <xref linkend="gobject-memory-cycles"/>.
+                </entry>
+              </row>
+              <row>
+                <entry morerows="3">Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
+                  instance of target type
+                 </entry>
+                <entry>interface's <function>interface_finalize</function> function</entry>
+                <entry>On interface's vtable</entry>
+                <entry>Never used in practice. Unlikely you will need it.</entry>
+              </row>
+              <row>
+                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function>for the last
+                  instance of target type
+                 </entry-->
+                <entry>interface's <function>base_finalize</function> function</entry>
+                <entry>On interface's vtable</entry>
+                <entry>Never used in practice. Unlikely you will need it.</entry>
+              </row>
+              <row>
+                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
+                  instance of target type
+                 </entry-->
+                <entry>target type's <function>class_finalize</function> function</entry>
+                <entry>On target type's class structure</entry>
+                <entry>Never used in practice. Unlikely you will need it.</entry>
+              </row>
+              <row>
+                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
+                  instance of target type
+                 </entry-->
+                <entry>type's <function>base_finalize</function> function</entry>
+                <entry>On the inheritance tree of classes from fundamental type to target type.
+                  <function>base_init</function> is invoked once for each class structure.</entry>
+                <entry>Never used in practice. Unlikely you will need it.</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>                
+      </para>
+
+    </sect2>
+
+    <sect2 id="gobject-memory-weakref">
+      <title>Weak References</title>
+    
+      <para>
+      Weak references are used to monitor object finalization:
+      <function><link linkend="g-object-weak-ref">g_object_weak_ref</link></function> adds a monitoring callback which does
+      not hold a reference to the object but which is invoked when the object runs 
+      its dispose method. As such, each weak ref can be invoked more than once upon
+      object finalization (since dispose can run more than once during object 
+      finalization).
+      </para>
+
+      <para>
+        <function><link linkend="g-object-weak-unref">g_object_weak_unref</link></function> can be used to remove a monitoring
+        callback from the object. 
+      </para>
+  
+      <para>
+        Weak references are also used to implement <function><link linkend="g-object-add-weak-pointer">g_object_add_weak_pointer</link></function>
+        and <function><link linkend="g-object-remove-weak-pointer">g_object_remove_weak_pointer</link></function>. These functions add a weak reference
+        to the object they are applied to which makes sure to nullify the pointer given by the user
+        when object is finalized.
+      </para>
+
+      <para>
+        Similarly, <link linkend="GWeakRef"><type>GWeakRef</type></link> can be
+        used to implement weak references if thread safety is required.
+      </para>
+    </sect2>
+  
+    <sect2 id="gobject-memory-cycles">
+      <title>Reference counts and cycles</title>
+
+      <para>
+        GObject's memory management model was designed to be easily integrated in existing code
+        using garbage collection. This is why the destruction process is split in two phases:
+        the first phase, executed in the dispose handler is supposed to release all references
+        to other member objects. The second phase, executed by the finalize handler is supposed
+        to complete the object's destruction process. Object methods should be able to run
+        without program error in-between the two phases.
+      </para>
+  
+      <para>
+        This two-step destruction process is very useful to break reference counting cycles.
+        While the detection of the cycles is up to the external code, once the cycles have been
+        detected, the external code can invoke <function><link linkend="g-object-run-dispose">g_object_run_dispose</link></function> which 
+        will indeed break any existing cycles since it will run the dispose handler associated
+        to the object and thus release all references to other objects.
+      </para>
+  
+      <para>
+        This explains one of the rules about the dispose handler stated earlier:
+        the dispose handler can be invoked multiple times. Let's say we
+        have a reference count cycle: object A references B which itself references object A.
+        Let's say we have detected the cycle and we want to destroy the two objects. One way to 
+        do this would be to invoke <function><link linkend="g-object-run-dispose">g_object_run_dispose</link></function> on one of the 
+        objects.
+      </para>
+  
+      <para>
+        If object A releases all its references to all objects, this means it releases its
+        reference to object B. If object B was not owned by anyone else, this is its last
+        reference count which means this last unref runs B's dispose handler which, in turn,
+        releases B's reference on object A. If this is A's last reference count, this last 
+        unref runs A's dispose handler which is running for the second time before
+        A's finalize handler is invoked !
+      </para>
+  
+      <para>
+        The above example, which might seem a bit contrived, can really happen if
+        GObjects are being handled by language bindings — hence the rules for
+        object destruction should be closely followed.
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="gobject-properties">
+    <title>Object properties</title>
+  
+    <para>
+      One of GObject's nice features is its generic get/set mechanism for object
+      properties. When an object
+      is instantiated, the object's <function>class_init</function> handler should be used to register
+      the object's properties with <function><link linkend="g-object-class-install-properties">g_object_class_install_properties</link></function>.
+    </para>
+  
+    <para>
+      The best way to understand how object properties work is by looking at a real example
+      of how it is used:
+<informalexample><programlisting>
+/************************************************/
+/* Implementation                               */
+/************************************************/
+
+typedef enum
+{
+  PROP_FILENAME = 1,
+  PROP_ZOOM_LEVEL,
+  N_PROPERTIES
+} ViewerFileProperty;
+
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
+static void
+viewer_file_set_property (GObject      *object,
+                          guint         property_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  ViewerFile *self = VIEWER_FILE (object);
+
+  switch ((ViewerFileProperty) property_id)
+    {
+    case PROP_FILENAME:
+      g_free (self-&gt;filename);
+      self-&gt;filename = g_value_dup_string (value);
+      g_print ("filename: %s\n", self-&gt;filename);
+      break;
+
+    case PROP_ZOOM_LEVEL:
+      self-&gt;zoom_level = g_value_get_uint (value);
+      g_print ("zoom level: &percnt;u\n", self-&gt;zoom_level);
+      break;
+
+    default:
+      /* We don't have any other property... */
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+viewer_file_get_property (GObject    *object,
+                          guint       property_id,
+                          GValue     *value,
+                          GParamSpec *pspec)
+{
+  ViewerFile *self = VIEWER_FILE (object);
+
+  switch ((ViewerFileProperty) property_id)
+    {
+    case PROP_FILENAME:
+      g_value_set_string (value, self-&gt;filename);
+      break;
+
+    case PROP_ZOOM_LEVEL:
+      g_value_set_uint (value, self-&gt;zoom_level);
+      break;
+
+    default:
+      /* We don't have any other property... */
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class-&gt;set_property = viewer_file_set_property;
+  object_class-&gt;get_property = viewer_file_get_property;
+
+  obj_properties[PROP_FILENAME] =
+    g_param_spec_string ("filename",
+                         "Filename",
+                         "Name of the file to load and display from.",
+                         NULL  /* default value */,
+                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  obj_properties[PROP_ZOOM_LEVEL] =
+    g_param_spec_uint ("zoom-level",
+                       "Zoom level",
+                       "Zoom level to view the file at.",
+                       0  /* minimum value */,
+                       10 /* maximum value */,
+                       2  /* default value */,
+                       G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class,
+                                     N_PROPERTIES,
+                                     obj_properties);
+}
+
+/************************************************/
+/* Use                                          */
+/************************************************/
+
+ViewerFile *file;
+GValue val = G_VALUE_INIT;
+
+file = g_object_new (VIEWER_TYPE_FILE, NULL);
+
+g_value_init (&amp;val, G_TYPE_UINT);
+g_value_set_char (&amp;val, 11);
+
+g_object_set_property (G_OBJECT (file), "zoom-level", &amp;val);
+
+g_value_unset (&amp;val);
+</programlisting></informalexample>
+      The client code above looks simple but a lot of things happen under the hood:
+    </para>
+  
+    <para>
+      <function><link linkend="g-object-set-property">g_object_set_property</link></function> first ensures a property
+      with this name was registered in <emphasis>file</emphasis>'s <function>class_init</function> handler. If so it walks the class hierarchy,
+      from bottom-most most-derived type, to top-most fundamental type to find the class
+      which registered that property. It then tries to convert the user-provided
+      <link linkend="GValue"><type>GValue</type></link>
+      into a <type>GValue</type> whose type is that of the associated property.
+    </para>
+
+    <para>
+      If the user provides a <type>signed char</type> <type>GValue</type>, as is shown
+      here, and if the object's property was registered as an <type>unsigned int</type>,
+      <function><link linkend="g-value-transform">g_value_transform</link></function> will try to transform the input signed char into
+      an unsigned int. Of course, the success of the transformation depends on the availability
+      of the required transform function. In practice, there will almost always be a transformation
+      <footnote>
+        <para>Its behaviour might not be what you expect but it is up to you to actually avoid
+          relying on these transformations.
+        </para>
+      </footnote>
+      which matches and conversion will be carried out if needed.
+    </para>
+  
+    <para>
+      After transformation, the <link linkend="GValue"><type>GValue</type></link> is validated by 
+      <function><link linkend="g-param-value-validate">g_param_value_validate</link></function> which makes sure the user's
+      data stored in the <link linkend="GValue"><type>GValue</type></link> matches the characteristics specified by
+      the property's <link linkend="GParamSpec"><type>GParamSpec</type></link>.
+      Here, the <link linkend="GParamSpec"><type>GParamSpec</type></link> we 
+      provided in <function>class_init</function> has a validation function which makes sure that the GValue
+      contains a value which respects the minimum and maximum bounds of the 
+      <link linkend="GParamSpec"><type>GParamSpec</type></link>. In the example above, the client's GValue does not
+      respect these constraints (it is set to 11, while the maximum is 10). As such, the
+      <function><link linkend="g-object-set-property">g_object_set_property</link></function> function will return with an error.
+    </para>
+  
+    <para>
+      If the user's GValue had been set to a valid value, <function><link linkend="g-object-set-property">g_object_set_property</link></function>
+      would have proceeded with calling the object's
+      <function>set_property</function> class method. Here, since our
+      implementation of <type>ViewerFile</type> did override this method, execution would jump to
+      <function>viewer_file_set_property</function> after having retrieved from the 
+      <link linkend="GParamSpec"><type>GParamSpec</type></link> the <emphasis>param_id</emphasis>
+      <footnote>
+        <para>
+          It should be noted that the param_id used here need only to uniquely identify each 
+          <link linkend="GParamSpec"><type>GParamSpec</type></link> within the <type>ViewerFileClass</type> such that the switch
+          used in the set and get methods actually works. Of course, this locally-unique 
+          integer is purely an optimization: it would have been possible to use a set of 
+          <emphasis>if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {}</emphasis> statements.
+        </para>
+      </footnote>
+      which had been stored by
+      <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
+    </para>
+  
+    <para>
+      Once the property has been set by the object's
+      <function>set_property</function> class method, execution
+      returns to <function><link linkend="g-object-set-property">g_object_set_property</link></function> which makes sure that
+      the "notify" signal is emitted on the object's instance with the changed property as
+      parameter unless notifications were frozen by <function><link linkend="g-object-freeze-notify">g_object_freeze_notify</link></function>.
+    </para>
+  
+    <para>
+      <function><link linkend="g-object-thaw-notify">g_object_thaw_notify</link></function> can be used to re-enable notification of 
+      property modifications through the
+      <link linkend="GObject-notify"><type>“notify”</type></link> signal. It is important to remember that
+      even if properties are changed while property change notification is frozen, the "notify"
+      signal will be emitted once for each of these changed properties as soon as the property
+      change notification is thawed: no property change is lost for the "notify"
+      signal, although multiple notifications for a single property are
+      compressed. Signals can only be delayed by the notification freezing
+      mechanism.
+    </para>
+    
+    <para>
+      It sounds like a tedious task to set up GValues every time when one wants to modify a property.
+      In practice one will rarely do this. The functions <function><link linkend="g-object-set-property">g_object_set_property</link></function>
+      and <function><link linkend="g-object-get-property">g_object_get_property</link></function>
+      are meant to be used by language bindings. For application there is an easier way and
+      that is described next.
+    </para>
+
+    <sect2 id="gobject-multi-properties">
+      <title>Accessing multiple properties at once</title>
+  
+      <para>
+        It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and 
+        <function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (variadic version) functions can be used to set
+        multiple properties at once. The client code shown above can then be re-written as:
+<informalexample><programlisting>
+ViewerFile *file;
+file = /* */;
+g_object_set (G_OBJECT (file),
+              "zoom-level", 6, 
+              "filename", "~/some-file.txt", 
+              NULL);
+</programlisting></informalexample>
+        This saves us from managing the GValues that we were needing to handle when using
+        <function><link linkend="g-object-set-property">g_object_set_property</link></function>.
+        The code above will trigger one notify signal emission for each property modified.
+      </para>
+    
+      <para>
+        Equivalent <function>_get</function> versions are also available:
+        <function><link linkend="g-object-get">g_object_get</link></function>
+        and <function><link linkend="g-object-get-valist">g_object_get_valist</link></function> (variadic version) can be used to get numerous
+        properties at once.
+      </para>
+      
+      <para>
+        These high level functions have one drawback — they don't provide a return value.
+        One should pay attention to the argument types and ranges when using them.
+        A known source of errors is to pass a different type from what the
+        property expects; for instance, passing an integer when the property
+        expects a floating point value and thus shifting all subsequent parameters
+        by some number of bytes. Also forgetting the terminating
+        <literal>NULL</literal> will lead to undefined behaviour.
+      </para>
+    
+      <para>
+        This explains how <function><link linkend="g-object-new">g_object_new</link></function>,
+        <function><link linkend="g-object-newv">g_object_newv</link></function> and <function><link linkend="g-object-new-valist">g_object_new_valist</link></function> 
+        work: they parse the user-provided variable number of parameters and invoke
+        <function><link linkend="g-object-set">g_object_set</link></function> on the parameters only after the object has been successfully constructed.
+        The "notify" signal will be emitted for each property set.
+      </para>
+    
+    </sect2>
+
+<!-- @todo tell here about how to pass use handle properties in derived classes -->
+
+  </sect1>
+
+</chapter>
diff --git a/docs/reference/gobject/tut_gsignal.xml b/docs/reference/gobject/tut_gsignal.xml
new file mode 100644
index 0000000..4ed4211
--- /dev/null
+++ b/docs/reference/gobject/tut_gsignal.xml
@@ -0,0 +1,495 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<chapter id="chapter-signal">
+  <title>The GObject messaging system</title>
+
+  <sect1 id="closure">
+    <title>Closures</title>
+
+    <para>
+      Closures are central to the concept of asynchronous signal delivery
+      which is widely used throughout GTK+ and GNOME applications. A closure is an 
+      abstraction, a generic representation of a callback. It is a small structure
+      which contains three objects:
+      <itemizedlist>
+        <listitem><para>a function pointer (the callback itself) whose prototype looks like:
+<informalexample><programlisting>
+return_type function_callback (… , gpointer user_data);
+</programlisting></informalexample>
+        </para></listitem>
+        <listitem><para>
+           the <parameter>user_data</parameter> pointer which is passed to the callback upon invocation of the closure
+          </para></listitem>
+        <listitem><para>
+           a function pointer which represents the destructor of the closure: whenever the
+           closure's refcount reaches zero, this function will be called before the closure
+           structure is freed.
+          </para></listitem>
+      </itemizedlist>
+    </para>
+
+    <para>
+      The <link linkend="GClosure"><type>GClosure</type></link> structure represents the common functionality of all
+      closure implementations: there exists a different closure implementation for
+      each separate runtime which wants to use the GObject type system.
+      <footnote><para>
+        In practice, closures sit at the boundary of language runtimes: if you are
+        writing Python code and one of your Python callbacks receives a signal from
+        a GTK+ widget, the C code in GTK+ needs to execute your Python
+        code. The closure invoked by the GTK+ object invokes the Python callback:
+        it behaves as a normal C object for GTK+ and as a normal Python object for
+        Python code.
+      </para></footnote>
+      The GObject library provides a simple <link linkend="GCClosure"><type>GCClosure</type></link> type which
+      is a specific implementation of closures to be used with C/C++ callbacks.
+    </para>
+    <para>
+      A <link linkend="GClosure"><type>GClosure</type></link> provides simple services:
+      <itemizedlist>
+        <listitem><para>
+          Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures 
+          were created for: they hide the details of callback invocation from the
+          callback invoker.</para>
+        </listitem>
+        <listitem><para>
+          Notification: the closure notifies listeners of certain events such as
+          closure invocation, closure invalidation and closure finalization. Listeners
+          can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
+          (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function> 
+          (invalidation notification) and 
+          <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
+          There exist symmetric deregistration functions for finalization and invalidation
+          events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
+          <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation 
+          process.
+          <footnote><para>
+            Closures are reference counted and notify listeners of their destruction in a two-stage
+            process: the invalidation notifiers are invoked before the finalization notifiers.
+          </para></footnote></para>
+        </listitem>
+      </itemizedlist>
+    </para>
+
+    <sect2>
+      <title>C Closures</title>
+
+      <para>
+        If you are using C or C++
+        to connect a callback to a given event, you will either use simple <link linkend="GCClosure"><type>GCClosure</type></link>s
+        which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function> 
+        functions (which will be presented a bit later).
+      </para>
+
+      <para>
+        <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
+        user-provided callback_func with the user-provided
+        <parameter>user_data</parameter> as its last parameter. When the closure
+        is finalized (second stage of the destruction process), it will invoke
+        the <parameter>destroy_data</parameter> function if the user has
+        supplied one.
+      </para>
+  
+      <para>
+        <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
+        user-provided <parameter>callback_func</parameter> with the
+        user-provided <parameter>user_data</parameter> as its first parameter
+        (instead of being the 
+        last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
+        is finalized (second stage of the destruction process), it will invoke
+        the <parameter>destroy_data</parameter> function if the user has
+        supplied one.
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Non-C closures (for the fearless)</title>
+
+      <para>
+        As was explained above, closures hide the details of callback invocation. In C,
+        callback invocation is just like function invocation: it is a matter of creating
+        the correct stack frame for the called function and executing a <emphasis>call</emphasis>
+        assembly instruction.
+      </para>
+  
+      <para>
+        C closure marshallers transform the array of GValues which represent 
+        the parameters to the target function into a C-style function parameter list, invoke
+        the user-supplied C function with this new parameter list, get the return value of the
+        function, transform it into a GValue and return this GValue to the marshaller caller.
+      </para>
+
+      <para>
+        A generic C closure marshaller is available as
+        <link linkend="g-cclosure-marshal-generic"><function>g_cclosure_marshal_generic</function></link>
+        which implements marshalling for all function types using libffi. Custom
+        marshallers for different types are not needed apart from performance
+        critical code where the libffi-based marshaller may be too slow.
+      </para>
+
+      <para>
+        An example of a custom marshaller is given below, illustrating how
+        <type>GValue</type>s can be converted to a C function call. The
+        marshaller is for a C function which takes an integer as its first
+        parameter and returns void.
+<informalexample><programlisting>
+g_cclosure_marshal_VOID__INT (GClosure     *closure,
+                              GValue       *return_value,
+                              guint         n_param_values,
+                              const GValue *param_values,
+                              gpointer      invocation_hint,
+                              gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__INT) (gpointer     data1,
+                                          gint         arg_1,
+                                          gpointer     data2);
+  register GMarshalFunc_VOID__INT callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 2);
+
+  data1 = g_value_peek_pointer (param_values + 0);
+  data2 = closure->data;
+
+  callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_marshal_value_peek_int (param_values + 1),
+            data2);
+}
+</programlisting></informalexample>
+      </para>
+  
+      <para>
+        There exist other kinds of marshallers, for example there is a generic
+        Python marshaller which is used by all Python closures (a Python closure
+        is used to invoke a callback written in Python). This Python marshaller
+        transforms the input GValue list representing the function parameters
+        into a Python tuple which is the equivalent structure in Python.
+      </para>
+
+    </sect2>
+  </sect1>
+
+  <sect1 id="signal">
+    <title>Signals</title>
+
+    <para>
+      GObject's signals have nothing to do with standard UNIX signals: they connect 
+      arbitrary application-specific events with any number of listeners.
+      For example, in GTK+, every user event (keystroke or mouse move) is received
+      from the windowing system and generates a GTK+ event in the form of a signal emission
+      on the widget object instance.
+    </para>
+
+    <para>
+      Each signal is registered in the type system together with the type on which
+      it can be emitted: users of the type are said to <emphasis>connect</emphasis>
+      to the signal on a given type instance when they register a closure to be 
+      invoked upon the signal emission. Users can also emit the signal by themselves 
+      or stop the emission of the signal from within one of the closures connected 
+      to the signal.
+    </para>
+
+    <para>
+      When a signal is emitted on a given type instance, all the closures
+      connected to this signal on this type instance will be invoked. All the closures
+      connected to such a signal represent callbacks whose signature looks like:
+<informalexample><programlisting>
+return_type function_callback (gpointer instance, …, gpointer user_data);
+</programlisting></informalexample>
+    </para>
+
+    <sect2 id="signal-registration">
+      <title>Signal registration</title>
+
+	  <para>
+		To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
+		<function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
+<informalexample><programlisting>
+guint g_signal_newv (const gchar        *signal_name,
+                     GType               itype,
+                     GSignalFlags        signal_flags,
+                     GClosure           *class_closure,
+                     GSignalAccumulator  accumulator,
+                     gpointer            accu_data,
+                     GSignalCMarshaller  c_marshaller,
+                     GType               return_type,
+                     guint               n_params,
+                     GType              *param_types);
+</programlisting></informalexample>
+		The number of parameters to these functions is a bit intimidating but they are relatively
+		simple:
+		<itemizedlist>
+		  <listitem><para>
+			  <parameter>signal_name</parameter>: is a string which can be used to uniquely identify a given signal.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>itype</parameter>: is the instance type on which this signal can be emitted.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>signal_flags</parameter>: partly defines the order in which closures which were connected to the
+			  signal are invoked.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>class_closure</parameter>: this is the default closure for the signal: if it is not NULL upon
+			  the signal emission, it will be invoked upon this emission of the signal. The 
+			  moment where this closure is invoked compared to other closures connected to that 
+			  signal depends partly on the signal_flags.
+			</para></listitem>
+			<listitem><para>
+			  <parameter>accumulator</parameter>: this is a function pointer which is invoked after each closure
+			  has been invoked. If it returns FALSE, signal emission is stopped. If it returns
+			  TRUE, signal emission proceeds normally. It is also used to compute the return
+			  value of the signal based on the return value of all the invoked closures.
+			  For example, an accumulator could ignore
+			  <literal>NULL</literal> returns from closures; or it
+			  could build a list of the values returned by the
+			  closures.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>accu_data</parameter>: this pointer will be passed down to each invocation of the
+			  accumulator during emission.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>c_marshaller</parameter>: this is the default C marshaller for any closure which is connected to
+			this signal.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>return_type</parameter>: this is the type of the return value of the signal.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>n_params</parameter>: this is the number of parameters this signal takes.
+			</para></listitem>
+		  <listitem><para>
+			  <parameter>param_types</parameter>: this is an array of GTypes which indicate the type of each parameter
+			  of the signal. The length of this array is indicated by n_params.
+			</para></listitem>
+		</itemizedlist>
+      </para>
+
+	  <para>
+		As you can see from the above definition, a signal is basically a description
+		of the closures which can be connected to this signal and a description of the
+		order in which the closures connected to this signal will be invoked.
+	  </para>
+
+	</sect2>
+
+	<sect2 id="signal-connection">
+	  <title>Signal connection</title>
+
+	  <para>
+		If you want to connect to a signal with a closure, you have three possibilities:
+		<itemizedlist>
+		  <listitem><para>
+		  You can register a class closure at signal registration: this is a
+		  system-wide operation. i.e.: the class closure will be invoked during each emission
+		  of a given signal on <emphasis>any</emphasis> of the instances of the type which supports that signal.
+			</para></listitem>
+		  <listitem><para>
+		  You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
+		  overrides the class closure of a given type. It is possible to call this function
+		  only on a derived type of the type on which the signal was registered.
+		  This function is of use only to language bindings.
+			</para></listitem>
+		  <listitem><para>
+		  You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
+		  family of functions. This is an instance-specific operation: the closure
+		  will be invoked only during emission of a given signal on a given instance.
+			</para></listitem>
+		</itemizedlist>
+		It is also possible to connect a different kind of callback on a given signal: 
+		emission hooks are invoked whenever a given signal is emitted whatever the instance on 
+		which it is emitted. Emission hooks are used for example to get all mouse_clicked
+		emissions in an application to be able to emit the small mouse click sound.
+		Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
+		and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
+	  </para>
+
+	</sect2>
+
+	<sect2 id="signal-emission">
+	  <title>Signal emission</title>
+
+	  <para>
+		Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family 
+		of functions.
+<informalexample><programlisting>
+void g_signal_emitv (const GValue *instance_and_params,
+                     guint         signal_id,
+                     GQuark        detail,
+                     GValue       *return_value);
+</programlisting></informalexample>
+		<itemizedlist>
+		  <listitem><para>
+			The <parameter>instance_and_params</parameter> array of GValues contains the list of input
+			parameters to the signal. The first element of the array is the 
+			instance pointer on which to invoke the signal. The following elements of
+			the array contain the list of parameters to the signal.
+			</para></listitem>
+		  <listitem><para>
+			<parameter>signal_id</parameter> identifies the signal to invoke.
+			</para></listitem>
+		  <listitem><para>
+			<parameter>detail</parameter> identifies the specific detail of the signal to invoke. A detail is a kind of 
+			magic token/argument which is passed around during signal emission and which is used
+			by closures connected to the signal to filter out unwanted signal emissions. In most 
+			cases, you can safely set this value to zero. See <xref linkend="signal-detail"/> for
+			more details about this parameter.
+			</para></listitem>
+		  <listitem><para>
+			<parameter>return_value</parameter> holds the return value of the last closure invoked during emission if
+			no accumulator was specified. If an accumulator was specified during signal creation,
+			this accumulator is used to calculate the return value as a function of the return
+			values of all the closures invoked during emission. 
+			If no closure is invoked during
+			emission, the <parameter>return_value</parameter> is nonetheless initialized to zero/null.
+			</para></listitem>
+		  </itemizedlist>
+		</para>
+
+	  <para>
+		Signal emission can be decomposed in 5 steps:
+		<orderedlist>
+		  <listitem><para>
+			<literal>RUN_FIRST</literal>: if the
+			<link linkend="G-SIGNAL-RUN-FIRST:CAPS"><literal>G_SIGNAL_RUN_FIRST</literal></link> flag was used
+			during signal registration and if there exists a class closure for this signal,
+			the class closure is invoked.
+			</para></listitem>
+		  <listitem><para>
+			<literal>EMISSION_HOOK</literal>: if any emission hook was added to
+			the signal, they are invoked from first to last added. Accumulate return values.
+			</para></listitem>
+		  <listitem><para>
+			<literal>HANDLER_RUN_FIRST</literal>: if any closure were connected
+			with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of 
+			functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
+			family of functions) they are run here, from first to last connected.
+			</para></listitem>
+		  <listitem><para>
+			<literal>RUN_LAST</literal>: if the <literal>G_SIGNAL_RUN_LAST</literal>
+			flag was set during registration and if a class closure
+			was set, it is invoked here.
+			</para></listitem>
+		  <listitem><para>
+			<literal>HANDLER_RUN_LAST</literal>: if any closure were connected
+			with the <function>g_signal_connect_after</function> family of 
+			functions, if they were not invoked during <literal>HANDLER_RUN_FIRST</literal> and if they 
+			are not blocked, they are run here, from first to last connected.
+			</para></listitem>
+		  <listitem><para>
+			<literal>RUN_CLEANUP</literal>: if the <literal>G_SIGNAL_RUN_CLEANUP</literal> flag
+			was set during registration and if a class closure was set,
+			it is invoked here. Signal emission is completed here.
+			</para></listitem>
+		</orderedlist>
+	  </para>
+  
+	  <para>
+		If, at any point during emission (except in <literal>RUN_CLEANUP</literal> or
+		<literal>EMISSION_HOOK</literal> state), one of the closures stops the signal emission with
+		<function><link linkend="g-signal-stop-emission">g_signal_stop_emission</link></function>,
+		emission jumps to <literal>RUN_CLEANUP</literal> state.
+	  </para>
+  
+	  <para>
+		If, at any point during emission, one of the closures or emission hook 
+		emits the same signal on the same instance, emission is restarted from
+		the <literal>RUN_FIRST</literal> state.
+	  </para>
+  
+	  <para>
+		The accumulator function is invoked in all states, after invocation
+		of each closure (except in <literal>RUN_EMISSION_HOOK</literal> and
+		<literal>RUN_CLEANUP</literal>). It accumulates
+		the closure return value into the signal return value and returns TRUE or
+		FALSE. If, at any point, it does not return TRUE, emission jumps
+		to <literal>RUN_CLEANUP</literal> state.
+	  </para>
+
+	  <para>
+		If no accumulator function was provided, the value returned by the last handler
+		run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
+	  </para>
+
+	</sect2>
+
+
+	<sect2 id="signal-detail">
+	  <title>The <emphasis>detail</emphasis> argument</title>
+
+	  <para>All the functions related to signal emission or signal connection have a parameter
+		named the <emphasis>detail</emphasis>. Sometimes, this parameter is hidden by the API
+		but it is always there, in one form or another. 
+	  </para>
+
+	  <para>
+	    Of the three main connection functions,
+		only one has an explicit detail parameter as a <link linkend="GQuark"><type>GQuark</type></link>:
+		<link linkend="g-signal-connect-closure-by-id"><function>g_signal_connect_closure_by_id</function></link>.
+		<footnote>
+		  <para>A GQuark is an integer which uniquely represents a string. It is possible to transform
+		   back and forth between the integer and string representations with the functions 
+		   <function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
+		  </para>
+		</footnote>
+	  </para>
+	  <para>
+	    The two other functions,
+	    <link linkend="g-signal-connect-closure"><function>g_signal_connect_closure</function></link> and
+	    <link linkend="g-signal-connect-data"><function>g_signal_connect_data</function></link>
+	    hide the detail parameter in the signal name identification.
+		Their <parameter>detailed_signal</parameter> parameter is a
+		string which identifies the name of the signal to connect to.
+		The format of this string should match
+		<emphasis>signal_name::detail_name</emphasis>. For example,
+		connecting to the signal named
+		<emphasis>notify::cursor_position</emphasis> will actually
+		connect to the signal named <emphasis>notify</emphasis> with the
+		<emphasis>cursor_position</emphasis> detail.
+		Internally, the detail string is transformed to a GQuark if it is present.
+	  </para>
+
+	  <para>
+	    Of the four main signal emission functions, one hides it in its
+	    signal name parameter:
+	    <link linkend="g-signal-connect"><function>g_signal_connect</function></link>.
+	    The other three have an explicit detail parameter as a
+	    <link linkend="GQuark"><type>GQuark</type></link> again:
+	    <link linkend="g-signal-emit"><function>g_signal_emit</function></link>,
+	    <link linkend="g-signal-emitv"><function>g_signal_emitv</function></link> and
+	    <link linkend="g-signal-emit-valist"><function>g_signal_emit_valist</function></link>.
+	  </para>
+
+	  <para>
+        If a detail is provided by the user to the emission function, it is used during emission to match
+        against the closures which also provide a detail.
+        If a closure's detail does not match the detail provided by the user, it
+        will not be invoked (even though it is connected to a signal which is
+        being emitted).
+	  </para>
+
+	  <para>
+		This completely optional filtering mechanism is mainly used as an optimization for signals
+		which are often emitted for many different reasons: the clients can filter out which events they are
+		interested in before the closure's marshalling code runs. For example, this is used extensively
+		by the <link linkend="GObject-notify"><structfield>notify</structfield></link> signal of GObject: whenever a property is modified on a GObject,
+		instead of just emitting the <emphasis>notify</emphasis> signal, GObject associates as a detail to this
+		signal emission the name of the property modified. This allows clients who wish to be notified of changes
+		to only one property to filter most events before receiving them.
+	  </para>
+
+	  <para>
+		As a simple rule, users can and should set the detail parameter to zero: this will disable completely
+        this optional filtering for that signal.
+	  </para>
+
+	</sect2>
+
+  </sect1>
+</chapter>
+
diff --git a/docs/reference/gobject/tut_gtype.xml b/docs/reference/gobject/tut_gtype.xml
new file mode 100644
index 0000000..a1c6005
--- /dev/null
+++ b/docs/reference/gobject/tut_gtype.xml
@@ -0,0 +1,1003 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+  <chapter id="chapter-gtype">
+    <title>The GLib Dynamic Type System</title>
+
+      <para>
+        A type, as manipulated by the GLib type system, is much more generic than what
+        is usually understood as an Object type. It is best explained by looking at the 
+        structure and the functions used to register new types in the type system.
+        <informalexample><programlisting>
+typedef struct _GTypeInfo               GTypeInfo;
+struct _GTypeInfo
+{
+  /* interface types, classed types, instantiated types */
+  guint16                class_size;
+  
+  GBaseInitFunc          base_init;
+  GBaseFinalizeFunc      base_finalize;
+  
+  /* classed types, instantiated types */
+  GClassInitFunc         class_init;
+  GClassFinalizeFunc     class_finalize;
+  gconstpointer          class_data;
+  
+  /* instantiated types */
+  guint16                instance_size;
+  guint16                n_preallocs;
+  GInstanceInitFunc      instance_init;
+  
+  /* value handling */
+  const GTypeValueTable *value_table;
+};
+GType g_type_register_static (GType             parent_type,
+                              const gchar      *type_name,
+                              const GTypeInfo  *info,
+                              GTypeFlags        flags);
+GType g_type_register_fundamental (GType                       type_id,
+                                   const gchar                *type_name,
+                                   const GTypeInfo            *info,
+                                   const GTypeFundamentalInfo *finfo,
+                                   GTypeFlags                  flags);
+        </programlisting></informalexample>
+      </para>
+
+      <para>
+        <function><link linkend="g-type-register-static">g_type_register_static</link></function>,
+        <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function> and 
+        <function><link linkend="g-type-register-fundamental">g_type_register_fundamental</link></function>
+        are the C functions, defined in
+        <filename>gtype.h</filename> and implemented in <filename>gtype.c</filename>
+        which you should use to register a new <link linkend="GType"><type>GType</type></link> in the program's type system.
+        It is not likely you will ever need to use 
+        <function><link linkend="g-type-register-fundamental">g_type_register_fundamental</link></function>
+        but in case you want to, the last chapter explains how to create
+        new fundamental types.
+      </para>
+
+      <para>
+        Fundamental types are top-level types which do not derive from any other type 
+        while other non-fundamental types derive from other types.
+        Upon initialization, the type system not only initializes its
+        internal data structures but it also registers a number of core
+        types: some of these are fundamental types. Others are types derived from these 
+        fundamental types.
+      </para>
+
+      <para>
+        Fundamental and non-fundamental types are defined by:
+        <itemizedlist>
+          <listitem><para>
+            class size: the class_size field in <link linkend="GTypeInfo"><type>GTypeInfo</type></link>.
+          </para></listitem>
+          <listitem><para>
+            class initialization functions (C++ constructor): the <function>base_init</function> and 
+            <function>class_init</function> fields in <link linkend="GTypeInfo"><type>GTypeInfo</type></link>.
+          </para></listitem>
+          <listitem><para>
+            class destruction functions (C++ destructor): the base_finalize and 
+            class_finalize fields in <link linkend="GTypeInfo"><type>GTypeInfo</type></link>.
+          </para></listitem>
+          <listitem><para>
+            instance size (C++ parameter to new): the instance_size field in 
+            <link linkend="GTypeInfo"><type>GTypeInfo</type></link>.
+          </para></listitem>
+          <listitem><para>
+            instantiation policy (C++ type of new operator): the n_preallocs
+            field in <link linkend="GTypeInfo"><type>GTypeInfo</type></link>.
+          </para></listitem>
+          <listitem><para>
+            copy functions (C++ copy operators): the value_table field in 
+            <link linkend="GTypeInfo"><type>GTypeInfo</type></link>.
+          </para></listitem>
+          <listitem><para>
+            type characteristic flags: <link linkend="GTypeFlags"><type>GTypeFlags</type></link>.
+          </para></listitem>
+        </itemizedlist>
+        Fundamental types are also defined by a set of <link linkend="GTypeFundamentalFlags"><type>GTypeFundamentalFlags</type></link> 
+        which are stored in a <link linkend="GTypeFundamentalInfo"><type>GTypeFundamentalInfo</type></link>.
+        Non-fundamental types are furthermore defined by the type of their parent which is
+        passed as the parent_type parameter to <function><link linkend="g-type-register-static">g_type_register_static</link></function>
+        and <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>.
+      </para>
+      
+      <sect1 id="gtype-copy">
+        <title>Copy functions</title>
+
+        <para>
+          The major common point between <emphasis>all</emphasis> GLib types (fundamental and 
+          non-fundamental, classed and non-classed, instantiable and non-instantiable) is that
+          they can all be manipulated through a single API to copy/assign them.
+        </para>
+
+        <para>
+          The <link linkend="GValue"><type>GValue</type></link> structure is used as an abstract container for all of these 
+          types. Its simplistic API (defined in <filename>gobject/gvalue.h</filename>) can be 
+          used to invoke the value_table functions registered
+          during type registration: for example <function><link linkend="g-value-copy">g_value_copy</link></function> copies the 
+          content of a <link linkend="GValue"><type>GValue</type></link> to another <link linkend="GValue"><type>GValue</type></link>. This is similar
+          to a C++ assignment which invokes the C++ copy operator to modify the default
+          bit-by-bit copy semantics of C++/C structures/classes.
+        </para>
+
+        <para>
+          The following code shows how you can copy around a 64 bit integer, as well as a <link linkend="GObject"><type>GObject</type></link>
+          instance pointer:
+<informalexample><programlisting>
+static void test_int (void)
+{
+  GValue a_value = G_VALUE_INIT;
+  GValue b_value = G_VALUE_INIT;
+  guint64 a, b;
+
+  a = 0xdeadbeef;
+
+  g_value_init (&amp;a_value, G_TYPE_UINT64);
+  g_value_set_uint64 (&amp;a_value, a);
+
+  g_value_init (&amp;b_value, G_TYPE_UINT64);
+  g_value_copy (&amp;a_value, &amp;b_value);
+
+  b = g_value_get_uint64 (&amp;b_value);
+
+  if (a == b) {
+    g_print ("Yay !! 10 lines of code to copy around a uint64.\n");
+  } else {
+    g_print ("Are you sure this is not a Z80 ?\n");
+  }
+}
+
+static void test_object (void)
+{
+  GObject *obj;
+  GValue obj_vala = G_VALUE_INIT;
+  GValue obj_valb = G_VALUE_INIT;
+  obj = g_object_new (VIEWER_TYPE_FILE, NULL);
+
+  g_value_init (&amp;obj_vala, VIEWER_TYPE_FILE);
+  g_value_set_object (&amp;obj_vala, obj);
+
+  g_value_init (&amp;obj_valb, G_TYPE_OBJECT);
+
+  /* g_value_copy's semantics for G_TYPE_OBJECT types is to copy the reference.
+   * This function thus calls g_object_ref.
+   * It is interesting to note that the assignment works here because
+   * VIEWER_TYPE_FILE is a G_TYPE_OBJECT.
+   */
+  g_value_copy (&amp;obj_vala, &amp;obj_valb);
+
+  g_object_unref (G_OBJECT (obj));
+  g_object_unref (G_OBJECT (obj));
+}
+</programlisting></informalexample>
+          The important point about the above code is that the exact semantics of the copy calls
+          is undefined since they depend on the implementation of the copy function. Certain 
+          copy functions might decide to allocate a new chunk of memory and then to copy the 
+          data from the source to the destination. Others might want to simply increment
+          the reference count of the instance and copy the reference to the new GValue.
+        </para>
+        
+        <para>
+          The value table used to specify these assignment functions is
+          documented in
+          <link linkend="GTypeValueTable"><type>GTypeValueTable</type></link>.
+        </para>
+        <para>
+          Interestingly, it is also very unlikely
+          you will ever need to specify a value_table during type registration
+          because these value_tables are inherited from the parent types for
+          non-fundamental types.
+        </para>
+      </sect1>
+
+      <sect1 id="gtype-conventions">
+        <title>Conventions</title>
+
+
+      <para>
+        There are a number of conventions users are expected to follow when creating new types
+        which are to be exported in a header file:
+        <itemizedlist>
+          <listitem><para>
+            Type names (including object names) must be at least three
+            characters long and start with ‘a–z’, ‘A–Z’ or ‘_’.
+          </para></listitem>
+          <listitem><para>
+            Use the <function>object_method</function> pattern for function names: to invoke
+            the method named <function>save</function> on an instance of object type <type>file</type>, call 
+            <function>file_save</function>.
+          </para></listitem>
+          <listitem><para>Use prefixing to avoid namespace conflicts with other projects.
+            If your library (or application) is named <emphasis>Viewer</emphasis>,
+            prefix all your function names with <emphasis>viewer_</emphasis>.
+            For example: <function>viewer_object_method</function>.
+          </para></listitem>
+          <listitem><para>Create a macro named <function>PREFIX_TYPE_OBJECT</function> which always 
+            returns the GType for the associated object type. For an object of type 
+            <emphasis>File</emphasis> in the <emphasis>Viewer</emphasis> namespace,
+            use: <function>VIEWER_TYPE_FILE</function>.
+            This macro is implemented using a function named
+            <function>prefix_object_get_type</function>; for example, <function>viewer_file_get_type</function>.
+          </para></listitem>
+          <listitem>
+            <para>
+              Use <link linkend="G-DECLARE-FINAL-TYPE:CAPS"><function>G_DECLARE_FINAL_TYPE</function></link>
+              or <link linkend="G-DECLARE-DERIVABLE-TYPE:CAPS"><function>G_DECLARE_DERIVABLE_TYPE</function></link>
+              to define various other conventional macros for your object:
+            </para>
+            <itemizedlist>
+              <listitem><para><function>PREFIX_OBJECT (obj)</function>, which 
+                returns a pointer of type <type>PrefixObject</type>. This macro is used to enforce
+                static type safety by doing explicit casts wherever needed. It also enforces
+                dynamic type safety by doing runtime checks. It is possible to disable the dynamic
+                type checks in production builds (see <link linkend="glib-building">building GLib</link>).
+                For example, we would create 
+                <function>VIEWER_FILE (obj)</function> to keep the previous example.
+              </para></listitem>
+              <listitem><para><function>PREFIX_OBJECT_CLASS (klass)</function>, which
+                is strictly equivalent to the previous casting macro: it does static casting with
+                dynamic type checking of class structures. It is expected to return a pointer
+                to a class structure of type <type>PrefixObjectClass</type>. An example is:
+                <function>VIEWER_FILE_CLASS</function>.
+              </para></listitem>
+              <listitem><para><function>PREFIX_IS_OBJECT (obj)</function>, which
+                returns a <type>gboolean</type> which indicates whether the input
+                object instance pointer is non-<type>NULL</type> and of type <type>OBJECT</type>.
+                For example, <function>VIEWER_IS_FILE</function>.
+              </para></listitem>
+              <listitem><para><function>PREFIX_IS_OBJECT_CLASS (klass)</function>, which returns a boolean
+                if the input class pointer is a pointer to a class of type OBJECT.
+                For example, <function>VIEWER_IS_FILE_CLASS</function>.
+              </para></listitem>
+              <listitem><para><function>PREFIX_OBJECT_GET_CLASS (obj)</function>,
+                which returns the class pointer associated to an instance of a given type. This macro
+                is used for static and dynamic type safety purposes (just like the previous casting
+                macros).
+                For example, <function>VIEWER_FILE_GET_CLASS</function>.
+              </para></listitem>
+            </itemizedlist>
+          </listitem>
+        </itemizedlist>
+        The implementation of these macros is pretty straightforward: a number of simple-to-use 
+        macros are provided in <filename>gtype.h</filename>. For the example we used above, we would 
+        write the following trivial code to declare the macros:
+<informalexample><programlisting>
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
+</programlisting></informalexample>
+      </para>
+
+      <para>
+        Unless your code has special requirements, you can use the
+        <function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
+	macro to define a class:
+<informalexample><programlisting>
+G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
+</programlisting></informalexample>
+      </para>
+
+      <para>
+        Otherwise, the <function>viewer_file_get_type</function> function must be
+        implemented manually:
+<informalexample><programlisting>
+GType viewer_file_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    const GTypeInfo info = {
+      /* You fill this structure. */
+    };
+    type = g_type_register_static (G_TYPE_OBJECT,
+                                   "ViewerFile",
+                                   &amp;info, 0);
+  }
+  return type;
+}
+</programlisting></informalexample>
+      </para>
+
+      </sect1>
+
+      <sect1 id="gtype-non-instantiable">
+        <title>Non-instantiable non-classed fundamental types</title>
+
+        <para>
+          A lot of types are not instantiable by the type system and do not have
+          a class. Most of these types are fundamental trivial types such as <emphasis>gchar</emphasis>, 
+          and are already registered by GLib.
+        </para>
+
+        <para>
+          In the rare case of needing to register such a type in the type
+          system, fill a
+          <link linkend="GTypeInfo"><type>GTypeInfo</type></link> structure with zeros since these types are also most of the time
+          fundamental:
+          <informalexample><programlisting>
+  GTypeInfo info = {
+    0,                                /* class_size */
+    NULL,                        /* base_init */
+    NULL,                        /* base_destroy */
+    NULL,                        /* class_init */
+    NULL,                        /* class_destroy */
+    NULL,                        /* class_data */
+    0,                                /* instance_size */
+    0,                                /* n_preallocs */
+    NULL,                        /* instance_init */
+    NULL,                        /* value_table */
+  };
+  static const GTypeValueTable value_table = {
+    value_init_long0,                /* value_init */
+    NULL,                        /* value_free */
+    value_copy_long0,                /* value_copy */
+    NULL,                        /* value_peek_pointer */
+    "i",                        /* collect_format */
+    value_collect_int,        /* collect_value */
+    "p",                        /* lcopy_format */
+    value_lcopy_char,                /* lcopy_value */
+  };
+  info.value_table = &amp;value_table;
+  type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &amp;info, &amp;finfo, 0);
+          </programlisting></informalexample>
+        </para>
+
+
+        <para>
+          Having non-instantiable types might seem a bit useless: what good is a type
+          if you cannot instantiate an instance of that type ? Most of these types
+          are used in conjunction with <link linkend="GValue"><type>GValue</type></link>s: a GValue is initialized
+          with an integer or a string and it is passed around by using the registered 
+          type's value_table. <link linkend="GValue"><type>GValue</type></link>s (and by extension these trivial fundamental
+          types) are most useful when used in conjunction with object properties and signals.
+        </para>
+
+      </sect1>
+
+      <sect1 id="gtype-instantiable-classed">
+        <title>Instantiable classed types: objects</title>
+
+        <para>
+          This section covers the theory behind objects. See
+          <xref linkend="howto-gobject"/> for the recommended way to define a
+          GObject.
+        </para>
+
+        <para>
+          Types which are registered with a class and are declared instantiable are
+          what most closely resembles an <emphasis>object</emphasis>. 
+          Although <link linkend="GObject"><type>GObject</type></link>s (detailed in <xref linkend="chapter-gobject"/>) 
+          are the most well known type of instantiable
+          classed types, other kinds of similar objects used as the base of an inheritance 
+          hierarchy have been externally developed and they are all built on the fundamental
+          features described below.
+        </para>
+
+        <para>
+          For example, the code below shows how you could register 
+          such a fundamental object type in the type system (using none of the
+          GObject convenience API):
+<informalexample><programlisting>
+typedef struct {
+  GObject parent;
+
+  /* instance members */
+  gchar *filename;
+} ViewerFile;
+
+typedef struct {
+  GObjectClass parent;
+
+  /* class members */
+  /* the first is public, pure and virtual */
+  void (*open)  (ViewerFile  *self,
+                 GError     **error);
+
+  /* the second is public and virtual */
+  void (*close) (ViewerFile  *self,
+                 GError     **error);
+} ViewerFileClass;
+
+#define VIEWER_TYPE_FILE (viewer_file_get_type ())
+
+GType 
+viewer_file_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    const GTypeInfo info = {
+      sizeof (ViewerFileClass),
+      NULL,           /* base_init */
+      NULL,           /* base_finalize */
+      (GClassInitFunc) viewer_file_class_init,
+      NULL,           /* class_finalize */
+      NULL,           /* class_data */
+      sizeof (ViewerFile),
+      0,              /* n_preallocs */
+      (GInstanceInitFunc) NULL /* instance_init */
+    };
+    type = g_type_register_static (G_TYPE_OBJECT,
+                                   "ViewerFile",
+                                   &amp;info, 0);
+  }
+  return type;
+}
+</programlisting></informalexample>
+          Upon the first call to <function>viewer_file_get_type</function>, the type named
+          <emphasis>ViewerFile</emphasis> will be registered in the type system as inheriting
+          from the type <emphasis>G_TYPE_OBJECT</emphasis>.
+        </para>
+
+        <para>
+          Every object must define two structures: its class structure and its 
+          instance structure. All class structures must contain as first member
+          a <link linkend="GTypeClass"><type>GTypeClass</type></link> structure. All instance structures must contain as first
+          member a <link linkend="GTypeInstance"><type>GTypeInstance</type></link> structure. The declaration of these C types,
+          coming from <filename>gtype.h</filename> is shown below:
+<informalexample><programlisting>
+struct _GTypeClass
+{
+  GType g_type;
+};
+struct _GTypeInstance
+{
+  GTypeClass *g_class;
+};
+</programlisting></informalexample>
+          These constraints allow the type system to make sure that every object instance
+          (identified by a pointer to the object's instance structure) contains in its
+          first bytes a pointer to the object's class structure.
+        </para>
+        <para>
+          This relationship is best explained by an example: let's take object B which
+          inherits from object A:
+<informalexample><programlisting>
+/* A definitions */
+typedef struct {
+  GTypeInstance parent;
+  int field_a;
+  int field_b;
+} A;
+typedef struct {
+  GTypeClass parent_class;
+  void (*method_a) (void);
+  void (*method_b) (void);
+} AClass;
+
+/* B definitions. */
+typedef struct {
+  A parent;
+  int field_c;
+  int field_d;
+} B;
+typedef struct {
+  AClass parent_class;
+  void (*method_c) (void);
+  void (*method_d) (void);
+} BClass;
+</programlisting></informalexample>          
+          The C standard mandates that the first field of a C structure is stored starting
+          in the first byte of the buffer used to hold the structure's fields in memory.
+          This means that the first field of an instance of an object B is A's first field
+          which in turn is <type>GTypeInstance</type>'s first field which in
+          turn is <structfield>g_class</structfield>, a pointer
+          to B's class structure.
+        </para>
+
+        <para>
+          Thanks to these simple conditions, it is possible to detect the type of every
+          object instance by doing: 
+<informalexample><programlisting>
+B *b;
+b->parent.parent.g_class->g_type
+</programlisting></informalexample>
+          or, more quickly:
+<informalexample><programlisting>
+B *b;
+((GTypeInstance *) b)->g_class->g_type
+</programlisting></informalexample>
+        </para>
+
+        <sect2 id="gtype-instantiable-classed-init-done">
+          <title>Initialization and Destruction</title>
+
+          <para>
+            instantiation of these types can be done with 
+            <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>,
+            which will look up the type information
+            structure associated with the type requested. Then, the instance size and instantiation
+            policy (if the <structfield>n_preallocs</structfield> field is set
+            to a non-zero value, the type system allocates
+            the object's instance structures in chunks rather than mallocing for every instance)
+            declared by the user are used to get a buffer to hold the object's instance
+            structure.
+          </para>
+
+          <para>
+            If this is the first instance of the object ever created, the type system must create a class structure.
+            It allocates a buffer to hold the object's class structure and initializes it. The first part of the
+            class structure (ie: the embedded parent class structure) is initialized by copying the contents from
+            the class structure of the parent class. The rest of class structure is initialized to zero.  If there
+            is no parent, the entire class structure is initialized to zero. The type system then invokes the
+            <function>base_class_initialization</function> functions
+            (<link linkend="GBaseInitFunc"><type>GBaseInitFunc</type></link>) from topmost 
+            fundamental object to bottom-most most derived object. The object's <function>class_init</function>
+            (<link linkend="GClassInitFunc"><type>GClassInitFunc</type></link>) function is invoked afterwards to complete
+            initialization of the class structure.
+            Finally, the object's interfaces are initialized (we will discuss interface initialization
+            in more detail later).
+          </para>
+
+          <para>
+            Once the type system has a pointer to an initialized class structure, it sets the object's
+            instance class pointer to the object's class structure and invokes the object's
+            <function>instance_init</function>
+            (<link linkend="GInstanceInitFunc"><type>GInstanceInitFunc</type></link>)
+            functions, from top-most fundamental 
+            type to bottom-most most-derived type.
+          </para>
+
+          <para>
+            Object instance destruction through <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is very simple:
+            the instance structure is returned to the instance pool if there is one and if this was the
+            last living instance of the object, the class is destroyed.
+          </para>
+
+
+          <para>
+            Class destruction (the concept of destruction is sometimes partly 
+            referred to as finalization in GType) is the symmetric process of 
+            the initialization: interfaces are destroyed first. 
+            Then, the most derived 
+            class_finalize (<link linkend="GClassFinalizeFunc"><type>GClassFinalizeFunc</type></link>) function is invoked. Finally, the
+            base_class_finalize (<link linkend="GBaseFinalizeFunc"><type>GBaseFinalizeFunc</type></link>) functions are 
+            invoked from bottom-most most-derived type to top-most fundamental type and
+            the class structure is freed.
+          </para>
+
+          <para>
+            The base initialization/finalization process is
+            very similar to the C++ constructor/destructor paradigm. The practical details are different
+            though and it is important not to get confused by superficial similarities. 
+            GTypes have no instance destruction mechanism. It is
+            the user's responsibility to implement correct destruction semantics on top
+            of the existing GType code. (This is what GObject does: see 
+            <xref linkend="chapter-gobject"/>.)
+           Furthermore, C++ code equivalent to the <function>base_init</function>
+           and <function>class_init</function> callbacks of GType is usually not needed because C++ cannot really create object 
+           types at runtime.
+          </para>
+
+          <para>
+            The instantiation/finalization process can be summarized as follows:
+            <table id="gtype-init-fini-table">
+              <title>GType Instantiation/Finalization</title>
+              <tgroup cols="3">
+                <colspec colwidth="*" colnum="1" align="left"/>
+                <colspec colwidth="*" colnum="2" align="left"/>
+                <colspec colwidth="8*" colnum="3" align="left"/>
+    
+                <thead>
+                  <row>
+                    <entry>Invocation time</entry>
+                    <entry>Function invoked</entry>
+                    <entry>Function's parameters</entry>
+                  </row>
+                </thead>
+                <tbody>
+                  <row>
+                    <entry morerows="2">First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
+                    <entry>type's <function>base_init</function> function</entry>
+                    <entry>On the inheritance tree of classes from fundamental type to target type. 
+                      <function>base_init</function> is invoked once for each class structure.</entry>
+                  </row>
+                  <row>
+                    <!--entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry-->
+                    <entry>target type's <function>class_init</function> function</entry>
+                    <entry>On target type's class structure</entry>
+                  </row>
+                  <row>
+                    <!--entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry-->
+                    <entry>interface initialization, see 
+                      <xref linkend="gtype-non-instantiable-classed-init"/></entry>
+                    <entry></entry>
+                  </row>
+                  <row>
+                    <entry>Each call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
+                    <entry>target type's <function>instance_init</function> function</entry>
+                    <entry>On object's instance</entry>
+                  </row>
+                  <row>
+                    <entry morerows="2">Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
+                    <entry>interface destruction, see
+                      <xref linkend="gtype-non-instantiable-classed-dest"/></entry>
+                    <entry></entry>
+                  </row>
+                  <row>
+                    <!--entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry-->
+                    <entry>target type's <function>class_finalize</function> function</entry>
+                    <entry>On target type's class structure</entry>
+                  </row>
+                  <row>
+                    <!--entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry-->
+                    <entry>type's <function>base_finalize</function> function</entry>
+                    <entry>On the inheritance tree of classes from fundamental type to target type. 
+                      <function>base_finalize</function> is invoked once for each class structure.</entry>
+                  </row>
+                </tbody>
+              </tgroup>
+            </table>
+          </para>
+          
+        </sect2>
+
+      </sect1>
+
+      <sect1 id="gtype-non-instantiable-classed">
+        <title>Non-instantiable classed types: interfaces</title>
+
+        <para>
+          This section covers the theory behind interfaces. See
+          <xref linkend="howto-interface"/> for the recommended way to define an
+          interface.
+        </para>
+
+        <para>
+          GType's interfaces are very similar to Java's interfaces. They allow
+          to describe a common API that several classes will adhere to.
+          Imagine the play, pause and stop buttons on hi-fi equipment — those can
+          be seen as a playback interface. Once you know what they do, you can
+          control your CD player, MP3 player or anything that uses these symbols.
+          To declare an interface you have to register a non-instantiable
+          classed type which derives from 
+          <link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
+<informalexample><programlisting>
+#define VIEWER_TYPE_EDITABLE viewer_editable_get_type ()
+G_DECLARE_INTERFACE (ViewerEditable, viewer_editable, VIEWER, EDITABLE, GObject)
+
+struct _ViewerEditableInterface {
+  GTypeInterface parent;
+
+  void (*save) (ViewerEditable  *self,
+                GError         **error);
+};
+
+void viewer_editable_save (ViewerEditable  *self,
+                           GError         **error);
+</programlisting></informalexample>
+          The interface function, <function>viewer_editable_save</function> is implemented
+          in a pretty simple way:
+<informalexample><programlisting>
+void
+viewer_editable_save (ViewerEditable  *self,
+                      GError         **error)
+{
+  ViewerEditableinterface *iface;
+
+  g_return_if_fail (VIEWER_IS_EDITABLE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  iface = VIEWER_EDITABLE_GET_IFACE (self);
+  g_return_if_fail (iface->save != NULL);
+  iface->save (self);
+}
+</programlisting></informalexample>
+         <function>viewer_editable_get_type</function> registers a type named <emphasis>ViewerEditable</emphasis>
+         which inherits from <type>G_TYPE_INTERFACE</type>. All interfaces must
+         be children of <type>G_TYPE_INTERFACE</type> in the  inheritance tree.
+        </para>
+
+        <para>
+          An interface is defined by only one structure which must contain as first member
+          a <link linkend="GTypeInterface"><type>GTypeInterface</type></link> structure. The interface structure is expected to
+          contain the function pointers of the interface methods. It is good style to 
+          define helper functions for each of the interface methods which simply call
+          the interface's method directly: <function>viewer_editable_save</function>
+          is one of these.
+        </para>
+
+        <para>
+        If you have no special requirements you can use the
+        <link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link> macro
+        to implement an interface:
+<informalexample><programlisting>
+static void
+viewer_file_save (ViewerEditable *self)
+{
+  g_print ("File implementation of editable interface save method.\n");
+}
+
+static void
+viewer_file_editable_interface_init (ViewerEditableInterface *iface)
+{
+  iface->save = viewer_file_save;
+}
+
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, VIEWER_TYPE_FILE,
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+                                                viewer_file_editable_interface_init))
+</programlisting></informalexample>
+        </para>
+
+        <para>
+          If your code does have special requirements, you must write a custom
+          <function>get_type</function> function to register your GType which
+          inherits from some <link linkend="GObject"><type>GObject</type></link>
+          and which implements the interface <type>ViewerEditable</type>. For
+          example, this code registers a new <type>ViewerFile</type> class which
+          implements <type>ViewerEditable</type>:
+<informalexample><programlisting>
+static void
+viewer_file_save (ViewerEditable *editable)
+{
+  g_print ("File implementation of editable interface save method.\n");
+}
+
+static void
+viewer_file_editable_interface_init (gpointer g_iface,
+                                     gpointer iface_data)
+{
+  ViewerEditableInterface *iface = g_iface;
+
+  iface->save = viewer_file_save;
+}
+
+GType 
+viewer_file_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    const GTypeInfo info = {
+      sizeof (ViewerFileClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      NULL,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (ViewerFile),
+      0,      /* n_preallocs */
+      NULL    /* instance_init */
+    };
+    const GInterfaceInfo editable_info = {
+      (GInterfaceInitFunc) viewer_file_editable_interface_init,  /* interface_init */
+      NULL,   /* interface_finalize */
+      NULL    /* interface_data */
+    };
+    type = g_type_register_static (VIEWER_TYPE_FILE,
+                                   "ViewerFile",
+                                   &amp;info, 0);
+    g_type_add_interface_static (type,
+                                 VIEWER_TYPE_EDITABLE,
+                                 &amp;editable_info);
+  }
+  return type;
+}
+</programlisting></informalexample>
+        </para>
+
+        <para>
+          <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> records in the type system that
+          a given type implements also <type>FooInterface</type> 
+          (<function>foo_interface_get_type</function> returns the type of 
+          <type>FooInterface</type>).
+                The <link linkend="GInterfaceInfo"><type>GInterfaceInfo</type></link> structure holds
+          information about the implementation of the interface:
+<informalexample><programlisting>
+struct _GInterfaceInfo
+{
+  GInterfaceInitFunc     interface_init;
+  GInterfaceFinalizeFunc interface_finalize;
+  gpointer               interface_data;
+};
+</programlisting></informalexample>
+        </para>
+
+        <sect2 id="gtype-non-instantiable-classed-init">
+          <title>Interface Initialization</title>
+
+          <para>
+            When an instantiable classed type which implements an interface
+            (either directly or by inheriting an implementation from a superclass)
+            is created for the first time, its class structure is initialized
+            following the process described in <xref linkend="gtype-instantiable-classed"/>.
+            After that, the interface implementations associated with
+            the type are initialized.
+          </para>
+
+          <para>
+            First a memory buffer is allocated to hold the interface structure. The parent's
+            interface structure is then copied over to the new interface structure (the parent
+            interface is already initialized at that point). If there is no parent interface,
+            the interface structure is initialized with zeros. The
+            <structfield>g_type</structfield> and the
+            <structfield>g_instance_type</structfield> fields are then
+            initialized: <structfield>g_type</structfield> is set to the type of
+            the most-derived interface and
+            <structfield>g_instance_type</structfield> is set to the type of the
+            most derived type which implements  this interface.
+          </para>
+
+          <para>
+            The interface's <function>base_init</function> function is called,
+            and then the interface's <function>default_init</function> is invoked.
+            Finally if the type has registered an implementation of the interface,
+            the implementation's <function>interface_init</function>
+            function is invoked. If there are multiple implementations of an
+            interface the <function>base_init</function> and
+            <function>interface_init</function> functions will be invoked once
+            for each implementation initialized.
+          </para>
+
+          <para>
+            It is thus recommended to use a <function>default_init</function> function to
+            initialize an interface. This function is called only once for the interface no
+            matter how many implementations there are. The
+            <function>default_init</function> function is declared by
+            <link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link>
+            which can be used to define the interface:
+<informalexample><programlisting>
+G_DEFINE_INTERFACE (ViewerEditable, viewer_editable, G_TYPE_OBJECT)
+
+static void
+viewer_editable_default_init (ViewerEditableInterface *iface)
+{
+  /* add properties and signals here, will only be called once */
+}
+</programlisting></informalexample>
+          </para>
+
+          <para>
+            Or you can do that yourself in a GType function for your interface:
+<informalexample><programlisting>
+GType
+viewer_editable_get_type (void)
+{
+  static volatile gsize type_id = 0;
+  if (g_once_init_enter (&amp;type_id)) {
+    const GTypeInfo info = {
+      sizeof (ViewerEditableInterface),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      viewer_editable_default_init, /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      0,      /* instance_size */
+      0,      /* n_preallocs */
+      NULL    /* instance_init */
+    };
+    GType type = g_type_register_static (G_TYPE_INTERFACE,
+                                         "ViewerEditable",
+                                         &amp;info, 0);
+    g_once_init_leave (&amp;type_id, type);
+  }
+  return type_id;
+}
+
+static void
+viewer_editable_default_init (ViewerEditableInterface *iface)
+{
+  /* add properties and signals here, will only called once */
+}
+</programlisting></informalexample>
+          </para>
+
+        <para>
+          In summary, interface initialization uses the following functions:
+        </para>
+
+          <para>
+          <table id="ginterface-init-table">
+            <title>Interface Initialization</title>
+            <tgroup cols="3">
+              <colspec colwidth="*" colnum="1" align="left"/>
+              <colspec colwidth="*" colnum="2" align="left"/>
+              <colspec colwidth="8*" colnum="3" align="left"/>
+              
+              <thead>
+                <row>
+                  <entry>Invocation time</entry>
+                  <entry>Function Invoked</entry>
+                  <entry>Function's parameters</entry>
+                  <entry>Remark</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
+                    for <emphasis>any</emphasis> type implementing interface
+                   </entry>
+                  <entry>interface's <function>base_init</function> function</entry>
+                  <entry>On interface's vtable</entry>
+                  <entry>Rarely necessary to use this. Called once per instantiated classed type implementing the interface.</entry>
+                </row>
+                <row>
+                  <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
+                    for <emphasis>each</emphasis> type implementing interface
+                   </entry>
+                  <entry>interface's <function>default_init</function> function</entry>
+                  <entry>On interface's vtable</entry>
+                  <entry>Register interface's signals, properties, etc. here. Will be called once.</entry>
+                </row>
+                <row>
+                  <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
+                    for <emphasis>any</emphasis> type implementing interface
+                   </entry>
+                  <entry>implementation's <function>interface_init</function> function</entry>
+                  <entry>On interface's vtable</entry>
+                  <entry>
+                    Initialize interface implementation. Called for each class that that
+                    implements the interface. Initialize the interface method pointers
+                    in the interface structure to the implementing class's implementation.
+                  </entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table>
+        </para>
+        
+        </sect2>
+        
+        <sect2 id="gtype-non-instantiable-classed-dest">
+          <title>Interface Destruction</title>
+
+          <para>
+            When the last instance of an instantiable type which registered 
+            an interface implementation is destroyed, the interface's 
+            implementations associated to the type are destroyed.
+          </para>
+
+          <para>
+            To destroy an interface implementation, GType first calls the 
+            implementation's <function>interface_finalize</function> function 
+            and then the interface's most-derived 
+            <function>base_finalize</function> function.
+          </para>
+
+          <para>
+            Again, it is important to understand, as in 
+            <xref linkend="gtype-non-instantiable-classed-init"/>,
+              that both <function>interface_finalize</function> and <function>base_finalize</function>
+              are invoked exactly once for the destruction of each implementation of an interface. Thus,
+              if you were to use one of these functions, you would need to use a static integer variable
+              which would hold the number of instances of implementations of an interface such that
+              the interface's class is destroyed only once (when the integer variable reaches zero).
+          </para>
+          
+        <para>
+          The above process can be summarized as follows:
+          <table id="ginterface-fini-table">
+            <title>Interface Finalization</title>
+            <tgroup cols="3">
+              <colspec colwidth="*" colnum="1" align="left"/>
+              <colspec colwidth="*" colnum="2" align="left"/>
+              <colspec colwidth="8*" colnum="3" align="left"/>
+              
+              <thead>
+                <row>
+                  <entry>Invocation time</entry>
+                  <entry>Function Invoked</entry>
+                  <entry>Function's parameters</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry morerows="1">Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for type
+                    implementing interface
+                   </entry>
+                  <entry>interface's <function>interface_finalize</function> function</entry>
+                  <entry>On interface's vtable</entry>
+                </row>
+                <row>
+                  <!--entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function>for type
+                    implementing interface
+                   </entry-->
+                  <entry>interface's <function>base_finalize</function> function</entry>
+                  <entry>On interface's vtable</entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table>
+        </para>
+      </sect2>
+    </sect1>
+  </chapter>
diff --git a/docs/reference/gobject/tut_howto.xml b/docs/reference/gobject/tut_howto.xml
new file mode 100644
index 0000000..bfb8d95
--- /dev/null
+++ b/docs/reference/gobject/tut_howto.xml
@@ -0,0 +1,1535 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<part label="IV">
+  <title>Tutorial</title>
+  <partintro>
+    <para>
+      This chapter tries to answer the real-life questions of users and presents
+      the most common use cases in order from most likely to least
+      likely.
+    </para>
+  </partintro>
+
+<chapter id="howto-gobject">
+  <title>How to define and implement a new GObject</title>
+  
+  <para>
+    This chapter focuses on the implementation of a subtype of GObject, for
+    example to create a custom class hierarchy, or to subclass a GTK+ widget.
+  </para>
+
+  <para>
+    Throughout the chapter, a running example of a file viewer program is used,
+    which has a <type>ViewerFile</type> class to represent a single file being
+    viewed, and various derived classes for different types of files with
+    special functionality, such as audio files. The example application also
+    supports editing files (for example, to tweak a photo being viewed), using
+    a <type>ViewerEditable</type> interface.
+  </para>
+
+  <sect1 id="howto-gobject-header">
+    <title>Boilerplate header code</title>
+    
+    <para>
+      The first step before writing the code for your GObject is to write the
+      type's header which contains the needed type, function and macro
+      definitions. Each of these elements is nothing but a convention which
+      is followed by almost all users of GObject, and has been refined over
+      multiple years of experience developing GObject-based code. If you are
+      writing a library, it is particularly important for you to adhere closely
+      to these conventions; users of your library will assume that you have.
+      Even if not writing a library, it will help other people who want to work
+      on your project.
+    </para>
+
+    <para>
+      Pick a name convention for your headers and source code and stick to it:
+      <itemizedlist>
+        <listitem><para>use a dash to separate the prefix from the typename:
+        <filename>viewer-file.h</filename> and <filename>viewer-file.c</filename>
+        (this is the convention used by Nautilus and most GNOME libraries).</para></listitem>
+        <listitem><para>use an underscore to separate the prefix from the
+        typename: <filename>viewer_file.h</filename> and
+        <filename>viewer_file.c</filename>.</para></listitem>
+        <listitem><para>Do not separate the prefix from the typename:
+        <filename>viewerfile.h</filename> and <filename>viewerfile.c</filename>.
+        (this is the convention used by GTK+)</para></listitem>
+      </itemizedlist>
+      Some people like the first two solutions better: it makes reading file
+      names easier for those with poor eyesight.
+    </para>
+
+    <para>
+      The basic conventions for any header which exposes a GType are described
+      in <xref linkend="gtype-conventions"/>.
+    </para>
+
+    <para>
+      If you want to declare a type named ‘file’ in namespace ‘viewer’, name the
+      type instance <function>ViewerFile</function> and its class
+      <function>ViewerFileClass</function> (names are case sensitive). The
+      recommended method of declaring a type differs based on whether the type
+      is final or derivable.
+    </para>
+
+    <para>
+      Final types cannot be subclassed further, and should be the default choice
+      for new types — changing a final type to be derivable is always a change
+      that will be compatible with existing uses of the code, but the converse
+      will often cause problems. Final types are declared using
+      <link linkend="G-DECLARE-FINAL-TYPE:CAPS"><function>G_DECLARE_FINAL_TYPE</function></link>,
+      and require a structure to hold the instance data to be declared in the
+      source code (not the header file).
+
+<informalexample><programlisting>
+/*
+ * Copyright/Licensing information.
+ */
+
+/* inclusion guard */
+#ifndef __VIEWER_FILE_H__
+#define __VIEWER_FILE_H__
+
+#include &lt;glib-object.h&gt;
+/*
+ * Potentially, include other headers on which this header depends.
+ */
+
+G_BEGIN_DECLS
+
+/*
+ * Type declaration.
+ */
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
+
+/*
+ * Method definitions.
+ */
+ViewerFile *viewer_file_new (void);
+
+G_END_DECLS
+
+#endif /* __VIEWER_FILE_H__ */
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      Derivable types <emphasis>can</emphasis> be subclassed further, and their class and
+      instance structures form part of the public API which must not be changed
+      if API stability is cared about. They are declared using
+      <link linkend="G-DECLARE-DERIVABLE-TYPE:CAPS"><function>G_DECLARE_DERIVABLE_TYPE</function></link>:
+<informalexample><programlisting>
+/*
+ * Copyright/Licensing information.
+ */
+
+/* inclusion guard */
+#ifndef __VIEWER_FILE_H__
+#define __VIEWER_FILE_H__
+
+#include &lt;glib-object.h&gt;
+/*
+ * Potentially, include other headers on which this header depends.
+ */
+
+G_BEGIN_DECLS
+
+/*
+ * Type declaration.
+ */
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
+
+struct _ViewerFileClass
+{
+  GObjectClass parent_class;
+
+  /* Class virtual function fields. */
+  void (* open) (ViewerFile  *file,
+                 GError     **error);
+
+  /* Padding to allow adding up to 12 new virtual functions without
+   * breaking ABI. */
+  gpointer padding[12];
+};
+
+/*
+ * Method definitions.
+ */
+ViewerFile *viewer_file_new (void);
+
+G_END_DECLS
+
+#endif /* __VIEWER_FILE_H__ */
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      The convention for header includes is to add the minimum number of
+      <function>#include</function> directives to the top of your headers needed
+      to compile that header. This
+      allows client code to simply <function>#include "viewer-file.h"</function>,
+      without needing to know the prerequisites for
+      <filename>viewer-file.h</filename>.
+    </para>
+  </sect1>
+
+  <sect1 id="howto-gobject-code">
+    <title>Boilerplate code</title>
+
+    <para>
+      In your code, the first step is to <function>#include</function> the
+      needed headers:
+<informalexample><programlisting>
+/*
+ * Copyright information
+ */
+
+#include "viewer-file.h"
+
+/* Private structure definition. */
+typedef struct {
+  gchar *filename;
+  /* stuff */
+} ViewerFilePrivate;
+
+/* 
+ * forward definitions
+ */
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      If the class is being declared as final using
+      <function>G_DECLARE_FINAL_TYPE</function>, its instance structure should
+      be defined in the C file:
+<informalexample><programlisting>
+struct _ViewerFile
+{
+  GObject parent_instance;
+
+  /* Other members, including private data. */
+};
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      Call the <function>G_DEFINE_TYPE</function> macro (or
+      <function>G_DEFINE_TYPE_WITH_PRIVATE</function> if your class needs
+      private data — final types do <emphasis>not</emphasis> need private data)
+      using the name
+      of the type, the prefix of the functions and the parent GType to
+      reduce the amount of boilerplate needed. This macro will:
+
+      <itemizedlist>
+        <listitem><simpara>implement the <function>viewer_file_get_type</function>
+        function</simpara></listitem>
+        <listitem><simpara>define a parent class pointer accessible from
+        the whole .c file</simpara></listitem>
+        <listitem><simpara>add private instance data to the type (if using
+        <function>G_DEFINE_TYPE_WITH_PRIVATE</function>)</simpara></listitem>
+      </itemizedlist>
+    </para>
+
+    <para>
+      If the class has been declared as final using
+      <function>G_DECLARE_FINAL_TYPE</function> (see
+      <xref linkend="howto-gobject-header"/>), private data should be placed in
+      the instance structure, <type>ViewerFile</type>, and
+      <function>G_DEFINE_TYPE</function> should be used instead of
+      <function>G_DEFINE_TYPE_WITH_PRIVATE</function>. The instance structure
+      for a final class is not exposed publicly, and is not embedded in the
+      instance structures of any derived classes (because the class is final);
+      so its size can vary without causing incompatibilities for code which uses
+      the class. Conversely, private data for derivable classes
+      <emphasis>must</emphasis> be included in a private structure, and
+      <function>G_DEFINE_TYPE_WITH_PRIVATE</function> must be used.
+
+<informalexample><programlisting>
+G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
+</programlisting></informalexample>
+or
+<informalexample><programlisting>
+G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      It is also possible to use the
+      <function>G_DEFINE_TYPE_WITH_CODE</function> macro to control the
+      <function>get_type</function> function implementation — for instance, to
+      add a call to the <function>G_IMPLEMENT_INTERFACE</function> macro to
+      implement an interface.
+    </para>
+  </sect1>
+
+  <sect1 id="howto-gobject-construction">
+    <title>Object construction</title>
+
+    <para>
+      People often get confused when trying to construct their GObjects because of the
+      sheer number of different ways to hook into the objects's construction process: it is
+      difficult to figure which is the <emphasis>correct</emphasis>, recommended way.
+    </para>
+
+    <para>
+      <xref linkend="gobject-construction-table"/> shows what user-provided functions
+      are invoked during object instantiation and in which order they are invoked.
+      A user looking for the equivalent of the simple C++ constructor function should use
+      the <function>instance_init</function> method. It will be invoked after
+      all the parents’ <function>instance_init</function>
+      functions have been invoked. It cannot take arbitrary construction parameters 
+      (as in C++) but if your object needs arbitrary parameters to complete initialization,
+      you can use construction properties.
+    </para>
+
+    <para>
+      Construction properties will be set only after all
+      <function>instance_init</function> functions have run.
+      No object reference will be returned to the client of <function><link linkend="g-object-new">g_object_new</link></function>
+      until all the construction properties have been set.
+    </para>
+
+    <para>
+      It is important to note that object construction cannot <emphasis>ever</emphasis>
+      fail. If you require a fallible GObject construction, you can use the
+      <link linkend="GInitable"><type>GInitable</type></link> and
+      <link linkend="GAsyncInitable"><type>GAsyncInitable</type></link>
+      interfaces provided by the GIO library.
+    </para>
+
+    <para>
+      You should write the following code first:
+<informalexample><programlisting>
+G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+}
+
+static void
+viewer_file_init (ViewerFile *self)
+{
+  ViewerFilePrivate *priv = viewer_file_get_instance_private (self);
+
+  /* initialize all public and private members to reasonable default values.
+   * They are all automatically initialized to 0 to begin with. */
+}
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      If you need special construction properties (with
+      <link linkend="G-PARAM-CONSTRUCT-ONLY:CAPS"><function>G_PARAM_CONSTRUCT_ONLY</function></link>
+      set), install the properties in
+      the <function>class_init()</function> function, override the <function>set_property()</function>
+      and <function>get_property()</function> methods of the GObject class,
+      and implement them as described by <xref linkend="gobject-properties"/>.
+    </para>
+
+    <para>
+      Property IDs must start from 1, as 0 is reserved for internal use by
+      GObject.
+<informalexample><programlisting>
+enum
+{
+  PROP_FILENAME = 1,
+  PROP_ZOOM_LEVEL,
+  N_PROPERTIES
+};
+
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = viewer_file_set_property;
+  object_class->get_property = viewer_file_get_property;
+
+  obj_properties[PROP_FILENAME] =
+    g_param_spec_string ("filename",
+                         "Filename",
+                         "Name of the file to load and display from.",
+                         NULL  /* default value */,
+                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  obj_properties[PROP_ZOOM_LEVEL] =
+    g_param_spec_uint ("zoom-level",
+                       "Zoom level",
+                       "Zoom level to view the file at.",
+                       0  /* minimum value */,
+                       10 /* maximum value */,
+                       2  /* default value */,
+                       G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class,
+                                     N_PROPERTIES,
+                                     obj_properties);
+}
+</programlisting></informalexample>
+      If you need this, make sure you can build and run code similar to the
+      code shown above. Also, make sure your construct properties can be set
+      without side effects during construction.
+    </para>
+
+    <para>
+      Some people sometimes need to complete the initialization of an instance
+      of a type only after the properties passed to the constructors have been
+      set. This is possible through the use of the <function>constructor()</function>
+      class method as described in <xref linkend="gobject-instantiation"/> or,
+      more simply, using the <function>constructed()</function> class method.
+      Note that the <function>constructed()</function>
+      virtual function will only be invoked after the properties marked as
+      <function>G_PARAM_CONSTRUCT_ONLY</function> or
+      <function>G_PARAM_CONSTRUCT</function> have been consumed, but
+      before the regular properties passed to <function>g_object_new()</function>
+      have been set.
+    </para>
+  </sect1>
+
+  <sect1 id="howto-gobject-destruction">
+    <title>Object destruction</title>
+
+    <para>
+      Again, it is often difficult to figure out which mechanism to use to
+      hook into the object's destruction process: when the last
+      <function><link linkend="g-object-unref">g_object_unref</link></function>
+      function call is made, a lot of things happen as described in
+      <xref linkend="gobject-destruction-table"/>.
+    </para>
+
+    <para>
+      The destruction process of your object is in two phases: dispose and
+      finalize. This split is necessary to handle
+      potential cycles due to the nature of the reference counting mechanism
+      used by GObject, as well as dealing with temporary revival of
+      instances in case of signal emission during the destruction sequence.
+      See <xref linkend="gobject-memory-cycles"/> for more information.
+<informalexample><programlisting>
+struct _ViewerFilePrivate
+{
+  gchar *filename;
+  guint zoom_level;
+
+  GInputStream *input_stream;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
+
+static void
+viewer_file_dispose (GObject *gobject)
+{
+  ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
+
+  /* In dispose(), you are supposed to free all types referenced from this
+   * object which might themselves hold a reference to self. Generally,
+   * the most simple solution is to unref all members on which you own a 
+   * reference.
+   */
+
+  /* dispose() might be called multiple times, so we must guard against
+   * calling g_object_unref() on an invalid GObject by setting the member
+   * NULL; g_clear_object() does this for us.
+   */
+  g_clear_object (&amp;priv->input_stream);
+
+  /* Always chain up to the parent class; there is no need to check if
+   * the parent class implements the dispose() virtual function: it is
+   * always guaranteed to do so
+   */
+  G_OBJECT_CLASS (viewer_file_parent_class)->dispose (gobject);
+}
+
+static void
+viewer_file_finalize (GObject *gobject)
+{
+  ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
+
+  g_free (priv->filename);
+
+  /* Always chain up to the parent class; as with dispose(), finalize()
+   * is guaranteed to exist on the parent's class virtual function table
+   */
+  G_OBJECT_CLASS (viewer_file_parent_class)->finalize (gobject);
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = viewer_file_dispose;
+  object_class->finalize = viewer_file_finalize;
+}
+
+static void
+viewer_file_init (ViewerFile *self);
+{
+  ViewerFilePrivate *priv = viewer_file_get_instance_private (self);
+
+  priv->input_stream = g_object_new (VIEWER_TYPE_INPUT_STREAM, NULL);
+  priv->filename = /* would be set as a property */;
+}
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      It is possible that object methods might be invoked after dispose is
+      run and before finalize runs. GObject does not consider this to be a
+      program error: you must gracefully detect this and neither crash nor
+      warn the user, by having a disposed instance revert to an inert state.
+    </para>
+  </sect1>
+
+  <sect1 id="howto-gobject-methods">
+    <title>Object methods</title>
+
+    <para>
+      Just as with C++, there are many different ways to define object
+      methods and extend them: the following list and sections draw on
+      C++ vocabulary. (Readers are expected to know basic C++ concepts.
+      Those who have not had to write C++ code recently can refer to e.g.
+      <ulink url="http://www.cplusplus.com/doc/tutorial/"/> to refresh
+      their memories.)
+      <itemizedlist>
+        <listitem><para>
+            non-virtual public methods,
+          </para></listitem>
+        <listitem><para>
+            virtual public methods and
+          </para></listitem>
+        <listitem><para>
+            virtual private methods
+          </para></listitem>
+      </itemizedlist>
+    </para>
+
+    <sect2 id="non-virtual-public-methods">
+      <title>Non-virtual public methods</title>
+
+      <para>
+        These are the simplest, providing a simple method which
+        acts on the object. Provide a function
+        prototype in the header and an implementation of that prototype
+        in the source file.
+<informalexample><programlisting>
+/* declaration in the header. */
+void viewer_file_open (ViewerFile  *self,
+                       GError     **error);
+
+/* implementation in the source file */
+void
+viewer_file_open (ViewerFile  *self,
+                  GError     **error)
+{
+  g_return_if_fail (VIEWER_IS_FILE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  /* do stuff here. */
+}
+</programlisting></informalexample>
+      </para>
+    </sect2>
+
+    <sect2 id="virtual-public-methods">
+      <title>Virtual public methods</title>
+
+      <para>
+        This is the preferred way to create GObjects with overridable methods:
+        <itemizedlist>
+          <listitem><para>
+            Define the common method and its virtual function in the
+            class structure in the public header
+          </para></listitem>
+          <listitem><para>
+            Define the common method in the header file and implement it in the
+            source file
+          </para></listitem>
+          <listitem><para>
+            Implement a base version of the virtual function in the source
+            file and initialize the virtual function pointer to this
+            implementation in the object’s <function>class_init</function>
+            function; or leave it as <constant>NULL</constant> for a ‘pure
+            virtual’ method which must be overridden by derived classes
+          </para></listitem>
+          <listitem><para>
+            Re-implement the virtual function in each derived class which needs
+            to override it
+          </para></listitem>
+        </itemizedlist>
+      </para>
+      <para>
+        Note that virtual functions can only be defined if the class is
+        derivable, declared using
+        <link linkend="G-DECLARE-DERIVABLE-TYPE:CAPS"><function>G_DECLARE_DERIVABLE_TYPE</function></link>
+        so the class structure can be defined.
+<informalexample><programlisting>
+/* declaration in viewer-file.h. */
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
+
+struct _ViewerFileClass
+{
+  GObjectClass parent_class;
+
+  /* stuff */
+  void (*open) (ViewerFile  *self,
+                GError     **error);
+
+  /* Padding to allow adding up to 12 new virtual functions without
+   * breaking ABI. */
+  gpointer padding[12];
+};
+
+void viewer_file_open (ViewerFile  *self,
+                       GError     **error);
+
+/* implementation in viewer-file.c */
+void
+viewer_file_open (ViewerFile  *self,
+                  GError     **error)
+{
+  ViewerFileClass *klass;
+
+  g_return_if_fail (VIEWER_IS_FILE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  klass = VIEWER_FILE_GET_CLASS (self);
+  g_return_if_fail (klass->open != NULL);
+
+  klass->open (self, error);
+}
+</programlisting></informalexample>
+        The code above simply redirects the <function>open</function> call
+        to the relevant virtual function.
+      </para>
+
+      <para>
+        It is possible to provide a default
+        implementation for this class method in the object's
+        <function>class_init</function> function: initialize the
+        <function>klass-&gt;open</function> field to a pointer to the
+        actual implementation.
+        By default, class methods that are not inherited are initialized to
+        <function>NULL</function>, and thus are to be considered "pure virtual".
+<informalexample><programlisting>
+static void
+viewer_file_real_close (ViewerFile  *self,
+                        GError     **error)
+{
+  /* Default implementation for the virtual method. */
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  /* this is not necessary, except for demonstration purposes.
+   *
+   * pure virtual method: mandates implementation in children.
+   */
+  klass->open = NULL;
+
+  /* merely virtual method. */
+  klass->close = viewer_file_real_close;
+}
+
+void
+viewer_file_open (ViewerFile  *self,
+                  GError     **error)
+{
+  ViewerFileClass *klass;
+
+  g_return_if_fail (VIEWER_IS_FILE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  klass = VIEWER_FILE_GET_CLASS (self);
+
+  /* if the method is purely virtual, then it is a good idea to
+   * check that it has been overridden before calling it, and,
+   * depending on the intent of the class, either ignore it silently
+   * or warn the user.
+   */
+  g_return_if_fail (klass->open != NULL);
+  klass->open (self, error);
+}
+
+void
+viewer_file_close (ViewerFile  *self,
+                   GError     **error)
+{
+  ViewerFileClass *klass;
+
+  g_return_if_fail (VIEWER_IS_FILE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  klass = VIEWER_FILE_GET_CLASS (self);
+  if (klass->close != NULL)
+    klass->close (self, error);
+}
+</programlisting></informalexample>
+      </para>
+    </sect2>
+
+    <sect2 id="virtual-private-methods">
+      <title>Virtual private Methods</title>
+
+      <para>
+        These are very similar to <link linkend="virtual-public-methods">virtual
+        public methods</link>. They just don't
+        have a public function to call directly. The header
+        file contains only a declaration of the virtual function:
+<informalexample><programlisting>
+/* declaration in viewer-file.h. */
+struct _ViewerFileClass
+{
+  GObjectClass parent;
+
+  /* Public virtual method as before. */
+  void     (*open)           (ViewerFile  *self,
+                              GError     **error);
+
+  /* Private helper function to work out whether the file can be loaded via
+   * memory mapped I/O, or whether it has to be read as a stream. */
+  gboolean (*can_memory_map) (ViewerFile *self);
+
+  /* Padding to allow adding up to 12 new virtual functions without
+   * breaking ABI. */
+  gpointer padding[12];
+};
+
+void viewer_file_open (ViewerFile *self, GError **error);
+</programlisting></informalexample>
+        These virtual functions are often used to delegate part of the job
+        to child classes:
+<informalexample><programlisting>
+/* this accessor function is static: it is not exported outside of this file. */
+static gboolean 
+viewer_file_can_memory_map (ViewerFile *self)
+{
+  return VIEWER_FILE_GET_CLASS (self)->can_memory_map (self);
+}
+
+void
+viewer_file_open (ViewerFile  *self,
+                  GError     **error)
+{
+  g_return_if_fail (VIEWER_IS_FILE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  /*
+   * Try to load the file using memory mapped I/O, if the implementation of the
+   * class determines that is possible using its private virtual method.
+   */
+  if (viewer_file_can_memory_map (self))
+    {
+      /* Load the file using memory mapped I/O. */
+    }
+  else
+    {
+      /* Fall back to trying to load the file using streaming I/O… */
+    }
+}
+</programlisting></informalexample>
+      </para>
+
+      <para>
+        Again, it is possible to provide a default implementation for this
+        private virtual function:
+<informalexample><programlisting>
+static gboolean
+viewer_file_real_can_memory_map (ViewerFile *self)
+{
+  /* As an example, always return false. Or, potentially return true if the
+   * file is local. */
+  return FALSE;
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  /* non-pure virtual method; does not have to be implemented in children. */
+  klass->can_memory_map = viewer_file_real_can_memory_map;
+}
+</programlisting></informalexample>
+      </para>
+
+      <para>
+        Derived classes can then override the method with code such as:
+<informalexample><programlisting>
+static void
+viewer_audio_file_class_init (ViewerAudioFileClass *klass)
+{
+  ViewerFileClass *file_class = VIEWER_FILE_CLASS (klass);
+
+  /* implement pure virtual function. */
+  file_class->can_memory_map = viewer_audio_file_can_memory_map;
+}
+</programlisting></informalexample>
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="howto-gobject-chainup">
+    <title>Chaining up</title>
+    
+    <para>Chaining up is often loosely defined by the following set of
+    conditions:
+      <itemizedlist>
+        <listitem><para>Parent class A defines a public virtual method named <function>foo</function> and 
+        provides a default implementation.</para></listitem>
+        <listitem><para>Child class B re-implements method <function>foo</function>.</para></listitem>
+        <listitem><para>B’s implementation of <function>foo</function> calls (‘chains up to’) its parent class A’s implementation of <function>foo</function>.</para></listitem>
+      </itemizedlist>
+      There are various uses of this idiom:
+      <itemizedlist>
+        <listitem><para>You need to extend the behaviour of a class without modifying its code. You create
+          a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour
+          and chain up to ensure that the previous behaviour is not really modified, just extended.
+          </para></listitem>
+        <listitem><para>You need to implement the
+          <ulink url="http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern">Chain
+          Of Responsibility pattern</ulink>: each object of the inheritance
+          tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that
+          each handler is run in turn.</para></listitem>
+      </itemizedlist>
+    </para>
+
+    <para>
+      To explicitly chain up to the implementation of the virtual method in the parent class, 
+      you first need a handle to the original parent class structure. This pointer can then be used to 
+      access the original virtual function pointer and invoke it directly.
+      <footnote>
+        <para>
+          The <emphasis>original</emphasis> adjective used in this sentence is not innocuous. To fully 
+          understand its meaning, recall how class structures are initialized: for each object type,
+          the class structure associated with this object is created by first copying the class structure of its
+          parent type (a simple <function>memcpy</function>) and then by invoking the <function>class_init</function> callback on
+          the resulting class structure. Since the <function>class_init</function> callback is responsible for overwriting the class structure
+          with the user re-implementations of the class methods, the modified copy of the parent class
+          structure stored in the derived instance cannot be used. A copy of the class structure of an instance of the parent
+          class is needed.
+        </para>
+      </footnote>
+    </para>
+    
+    <para>
+      Use the <function>parent_class</function> pointer created and initialized
+      by the
+      <link linkend="G-DEFINE-TYPE:CAPS"><function>G_DEFINE_TYPE</function></link>
+      family of macros, for instance:
+<informalexample><programlisting>
+static void
+b_method_to_call (B *obj, gint some_param)
+{
+  /* do stuff before chain up */
+
+  /* call the method_to_call() virtual function on the
+   * parent of BClass, AClass.
+   *
+   * remember the explicit cast to AClass*
+   */
+  A_CLASS (b_parent_class)->method_to_call (obj, some_param);
+
+  /* do stuff after chain up */
+}
+</programlisting></informalexample>
+  </para>
+
+  </sect1>
+
+</chapter>
+<!-- End Howto GObject -->
+
+<chapter id="howto-interface">
+  <title>How to define and implement interfaces</title>
+
+  <sect1 id="howto-interface-define">
+    <title>Defining interfaces</title>
+  
+  <para>
+    The theory behind how GObject interfaces work is given in
+    <xref linkend="gtype-non-instantiable-classed"/>; this section covers how to
+    define and implement an interface.
+  </para>
+
+  <para>
+    The first step is to get the header right. This interface
+    defines three methods:
+<informalexample><programlisting>
+/*
+ * Copyright/Licensing information.
+ */
+
+#ifndef __VIEWER_EDITABLE_H__
+#define __VIEWER_EDITABLE_H__
+
+#include &lt;glib-object.h&gt;
+
+G_BEGIN_DECLS
+
+#define VIEWER_TYPE_EDITABLE viewer_editable_get_type ()
+G_DECLARE_INTERFACE (ViewerEditable, viewer_editable, VIEWER, EDITABLE, GObject)
+
+struct _ViewerEditableInterface
+{
+  GTypeInterface parent_iface;
+
+  void (*save) (ViewerEditable  *self,
+                GError         **error);
+  void (*undo) (ViewerEditable  *self,
+                guint            n_steps);
+  void (*redo) (ViewerEditable  *self,
+                guint            n_steps);
+};
+
+void viewer_editable_save (ViewerEditable  *self,
+                           GError         **error);
+void viewer_editable_undo (ViewerEditable  *self,
+                           guint            n_steps);
+void viewer_editable_redo (ViewerEditable  *self,
+                           guint            n_steps);
+
+G_END_DECLS
+
+#endif /* __VIEWER_EDITABLE_H__ */
+</programlisting></informalexample>
+    This code is the same as the code for a normal <link linkend="GType"><type>GType</type></link>
+    which derives from a <link linkend="GObject"><type>GObject</type></link> except for a few details:
+    <itemizedlist>
+      <listitem><para>
+        The <function>_GET_CLASS</function> function is called
+        <function>_GET_IFACE</function> (and is defined by
+        <link linkend="G-DECLARE-INTERFACE:CAPS"><function>G_DECLARE_INTERFACE</function></link>).
+      </para></listitem>
+      <listitem><para>
+        The instance type, <type>ViewerEditable</type>, is not fully defined: it is
+        used merely as an abstract type which represents an instance of
+        whatever object which implements the interface.
+      </para></listitem>
+      <listitem><para>
+        The parent of the <type>ViewerEditableInterface</type> is
+        <type>GTypeInterface</type>, not <type>GObjectClass</type>.
+      </para></listitem>
+    </itemizedlist>
+  </para>
+
+  <para>
+    The implementation of the <type>ViewerEditable</type> type itself is trivial:
+    <itemizedlist>
+      <listitem><para><function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
+       creates a <function>viewer_editable_get_type</function> function which registers the
+       type in the type system. The third argument is used to define a
+       <link linkend="howto-interface-prerequisite">prerequisite interface</link>
+       (which we'll talk about more later). Just pass <code>0</code> for this
+       argument when an interface has no prerequisite.
+       </para></listitem>
+      <listitem><para><function>viewer_editable_default_init</function> is expected
+      to register the interface's signals if there are any (we will see a bit
+      later how to use them).</para></listitem>
+      <listitem><para>The interface methods <function>viewer_editable_save</function>,
+      <function>viewer_editable_undo</function> and <function>viewer_editable_redo</function> dereference the interface
+      structure to access its associated interface function and call it.
+      </para></listitem>
+    </itemizedlist>
+<informalexample><programlisting>
+G_DEFINE_INTERFACE (ViewerEditable, viewer_editable, G_TYPE_OBJECT)
+
+static void
+viewer_editable_default_init (ViewerEditableInterface *iface)
+{
+    /* add properties and signals to the interface here */
+}
+
+void
+viewer_editable_save (ViewerEditable  *self,
+                      GError         **error)
+{
+  ViewerEditableInterface *iface;
+
+  g_return_if_fail (VIEWER_IS_EDITABLE (self));
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  iface = VIEWER_EDITABLE_GET_IFACE (self);
+  g_return_if_fail (iface->save != NULL);
+  iface->save (self, error);
+}
+
+void
+viewer_editable_undo (ViewerEditable *self,
+                      guint           n_steps)
+{
+  ViewerEditableInterface *iface;
+
+  g_return_if_fail (VIEWER_IS_EDITABLE (self));
+
+  iface = VIEWER_EDITABLE_GET_IFACE (self);
+  g_return_if_fail (iface->undo != NULL);
+  iface->undo (self, n_steps);
+}
+
+void
+viewer_editable_redo (ViewerEditable *self,
+                      guint           n_steps)
+{
+  ViewerEditableInterface *iface;
+
+  g_return_if_fail (VIEWER_IS_EDITABLE (self));
+
+  iface = VIEWER_EDITABLE_GET_IFACE (self);
+  g_return_if_fail (iface->redo != NULL);
+  iface->redo (self, n_steps);
+}
+</programlisting></informalexample>
+    </para>
+  </sect1>
+  
+  <sect1 id="howto-interface-implement">
+    <title>Implementing interfaces</title>
+  
+    <para>
+      Once the interface is defined, implementing it is rather trivial.
+    </para>
+  
+    <para>
+      The first step is to define a normal final GObject class exactly as in
+      <xref linkend="howto-gobject-header"/>.
+    </para>
+  
+    <para>
+      The second step is to implement <type>ViewerFile</type> by defining
+      it using
+      <function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
+      and
+      <function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
+      instead of
+      <function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>:
+<informalexample><programlisting>
+static void viewer_file_editable_interface_init (ViewerEditableInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+                                                viewer_file_editable_interface_init))
+</programlisting></informalexample>
+      This definition is very much like all the similar functions seen
+      previously. The only interface-specific code present here is the use of
+      <function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>.
+    </para>
+
+    <note><para>Classes can implement multiple interfaces by using multiple calls to
+    <function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
+    inside the call to
+    <function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
+    </para></note>
+  
+    <para>
+      <function>viewer_file_editable_interface_init</function>, the interface
+      initialization function: inside it every virtual method of the interface
+      must be assigned to its implementation:
+<informalexample><programlisting>
+static void
+viewer_file_editable_save (ViewerFile  *self,
+                           GError     **error)
+{
+  g_print ("File implementation of editable interface save method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_undo (ViewerFile *self,
+                           guint       n_steps)
+{
+  g_print ("File implementation of editable interface undo method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_redo (ViewerFile *self,
+                           guint       n_steps)
+{
+  g_print ("File implementation of editable interface redo method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_interface_init (ViewerEditableInterface *iface)
+{
+  iface->save = viewer_file_editable_save;
+  iface->undo = viewer_file_editable_undo;
+  iface->redo = viewer_file_editable_redo;
+}
+
+static void
+viewer_file_init (ViewerFile *self)
+{
+  /* Instance variable initialisation code. */
+}
+</programlisting></informalexample>
+    </para>
+    <para>
+      If the object is not of final type, e.g. was declared using
+      <function><link linkend="G-DECLARE-DERIVABLE-TYPE:CAPS">G_DECLARE_DERIVABLE_TYPE</link></function>
+      then
+      <function><link linkend="G-ADD-PRIVATE:CAPS">G_ADD_PRIVATE</link></function>
+      macro should be added. The private structure should be declared exactly
+      as for a normal derivable object, see <xref linkend="howto-gobject-code"/>.
+<informalexample><programlisting>
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
+                         G_ADD_PRIVATE (ViewerFile)
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+                                                viewer_file_editable_interface_init))
+</programlisting></informalexample>
+    </para>
+  </sect1>
+  
+  <sect1 id="howto-interface-prerequisite">
+    <title>Interface definition prerequisites</title>
+  
+    <para>
+      To specify that an interface requires the presence of other interfaces
+      when implemented, GObject introduces the concept of
+      <emphasis>prerequisites</emphasis>: it is possible to associate
+      a list of prerequisite types to an interface. For example, if
+      object A wishes to implement interface I1, and if interface I1 has a
+      prerequisite on interface I2, A has to implement both I1 and I2.
+    </para>
+  
+    <para>
+      The mechanism described above is, in practice, very similar to
+      Java's interface I1 extends interface I2. The example below shows
+      the GObject equivalent:
+<informalexample><programlisting>
+/* Make the ViewerEditableLossy interface require ViewerEditable interface. */
+G_DEFINE_INTERFACE (ViewerEditableLossy, viewer_editable_lossy, VIEWER_TYPE_EDITABLE)
+</programlisting></informalexample>
+      In the <function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
+      call above, the third parameter defines the prerequisite type. This
+      is the GType of either an interface or a class. In this case
+      the <type>ViewerEditable</type> interface is a prerequisite of
+      <type>ViewerEditableLossy</type>. The code
+      below shows how an implementation can implement both interfaces and
+      register their implementations:
+<informalexample><programlisting>
+static void
+viewer_file_editable_lossy_compress (ViewerEditableLossy *editable)
+{
+  ViewerFile *self = VIEWER_FILE (editable);
+
+  g_print ("File implementation of lossy editable interface compress method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_lossy_interface_init (ViewerEditableLossyInterface *iface)
+{
+  iface->compress = viewer_file_editable_lossy_compress;
+}
+
+static void
+viewer_file_editable_save (ViewerEditable  *editable,
+                           GError         **error)
+{
+  ViewerFile *self = VIEWER_FILE (editable);
+
+  g_print ("File implementation of editable interface save method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_undo (ViewerEditable *editable,
+                           guint           n_steps)
+{
+  ViewerFile *self = VIEWER_FILE (editable);
+
+  g_print ("File implementation of editable interface undo method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_redo (ViewerEditable *editable,
+                           guint           n_steps)
+{
+  ViewerFile *self = VIEWER_FILE (editable);
+
+  g_print ("File implementation of editable interface redo method: %s.\n",
+           self->filename);
+}
+
+static void
+viewer_file_editable_interface_init (ViewerEditableInterface *iface)
+{
+  iface->save = viewer_file_editable_save;
+  iface->undo = viewer_file_editable_undo;
+  iface->redo = viewer_file_editable_redo;
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  /* Nothing here. */
+}
+
+static void
+viewer_file_init (ViewerFile *self)
+{
+  /* Instance variable initialisation code. */
+}
+
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+                                                viewer_file_editable_interface_init)
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE_LOSSY,
+                                                viewer_file_editable_lossy_interface_init))
+</programlisting></informalexample>
+      It is very important to notice that the order in which interface
+      implementations are added to the main object is not random:
+      <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function>,
+      which is called by
+      <function><link linkend="G-DEFINE-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>,
+      must be invoked first on the interfaces which have no prerequisites and then on
+      the others.
+    </para>
+  </sect1>
+  
+  <sect1 id="howto-interface-properties">
+    <title>Interface properties</title>
+  
+    <para>
+      GObject interfaces can also have
+      properties. Declaration of the interface properties is similar to
+      declaring the properties of ordinary GObject types as explained in
+      <xref linkend="gobject-properties"/>, except that
+      <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function>
+      is used to declare the properties instead of
+      <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
+    </para>
+  
+    <para>
+      To include a property named 'autosave-frequency' of type <type>gdouble</type> in the 
+      <type>ViewerEditable</type> interface example code above, we only need to
+      add one call in <function>viewer_editable_default_init</function> as shown
+      below:
+<informalexample><programlisting>
+static void
+viewer_editable_default_init (ViewerEditableInterface *iface)
+{
+  g_object_interface_install_property (iface,
+                                       g_param_spec_double ("autosave-frequency",
+                                                            "Autosave frequency",
+                                                            "Frequency (in per-seconds) to autosave backups of the editable content at. "
+                                                            "Or zero to disable autosaves.",
+                                                            0.0,  /* minimum */
+                                                            G_MAXDOUBLE,  /* maximum */
+                                                            0.0,  /* default */
+                                                            G_PARAM_READWRITE));
+}
+</programlisting></informalexample>
+    </para>
+  
+    <para>
+      One point worth noting is that the declared property wasn't assigned an 
+      integer ID. The reason being that integer IDs of properties are used
+      only inside the <function>get_property</function> and
+      <function>set_property</function> virtual methods. Since interfaces
+      declare but do not <emphasis>implement</emphasis> properties, there is no
+      need to assign integer IDs to them.
+    </para>
+    
+    <para>
+      An implementation declares and defines its properties in the usual
+      way as explained in <xref linkend="gobject-properties"/>, except for one
+      small change: it can declare the properties of the interface it
+      implements using <function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function>
+      instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
+      The following code snippet shows the modifications needed in the
+      <type>ViewerFile</type> declaration and implementation above:
+<informalexample><programlisting>
+struct _ViewerFile
+{
+  GObject parent_instance;
+
+  gdouble autosave_frequency;
+};
+
+enum
+{
+  PROP_AUTOSAVE_FREQUENCY = 1,
+  N_PROPERTIES
+};
+
+static void
+viewer_file_set_property (GObject      *object,
+                          guint         prop_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  ViewerFile *file = VIEWER_FILE (object);
+
+  switch (prop_id)
+    {
+    case PROP_AUTOSAVE_FREQUENCY:
+      file->autosave_frequency = g_value_get_double (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+viewer_file_get_property (GObject    *object,
+                          guint       prop_id,
+                          GValue     *value,
+                          GParamSpec *pspec)
+{
+  ViewerFile *file = VIEWER_FILE (object);
+
+  switch (prop_id)
+    {
+    case PROP_AUTOSAVE_FREQUENCY:
+      g_value_set_double (value, file->autosave_frequency);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = viewer_file_set_property;
+  object_class->get_property = viewer_file_get_property;
+
+  g_object_class_override_property (object_class, PROP_AUTOSAVE_FREQUENCY, "autosave-frequency");
+}
+</programlisting></informalexample>
+    </para>
+  
+  </sect1>
+
+  <sect1 id="howto-interface-override">
+    <title>Overriding interface methods</title>
+
+    <para>
+      If a base class already implements an interface and a derived
+      class needs to implement the same interface but needs to override certain
+      methods, you must reimplement the interface and set only the interface
+      methods which need overriding.
+    </para>
+
+    <para>
+      In this example, <type>ViewerAudioFile</type> is derived from
+      <type>ViewerFile</type>. Both implement the <type>ViewerEditable</type>
+      interface. <type>ViewerAudioFile</type> only implements one method of the
+      <type>ViewerEditable</type> interface and uses the base class implementation of
+      the other.
+<informalexample><programlisting>
+static void
+viewer_audio_file_editable_save (ViewerEditable  *editable,
+                                 GError         **error)
+{
+  ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable);
+
+  g_print ("Audio file implementation of editable interface save method.\n");
+}
+
+static void
+viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
+{
+  /* Override the implementation of save(). */
+  iface->save = viewer_audio_file_editable_save;
+
+  /*
+   * Leave iface->undo and ->redo alone, they are already set to the
+   * base class implementation.
+   */
+}
+
+G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+                                                viewer_audio_file_editable_interface_init))
+
+static void
+viewer_audio_file_class_init (ViewerAudioFileClass *klass)
+{
+  /* Nothing here. */
+}
+
+static void
+viewer_audio_file_init (ViewerAudioFile *self)
+{
+  /* Nothing here. */
+}
+</programlisting></informalexample>
+    </para>
+
+    <para>
+      To access the base class interface implementation use
+      <function><link linkend="g-type-interface-peek-parent">g_type_interface_peek_parent</link></function>
+      from within an interface's <function>default_init</function> function.
+    </para>
+
+    <para>
+      To call the base class implementation of an interface
+      method from a derived class where than interface method has been
+      overridden, stash away the pointer returned from
+      <function><link linkend="g-type-interface-peek-parent">g_type_interface_peek_parent</link></function>
+      in a global variable.
+    </para>
+
+    <para>
+      In this example <type>ViewerAudioFile</type> overrides the
+      <function>save</function> interface method. In its overridden method
+      it calls the base class implementation of the same interface method.
+<informalexample><programlisting>
+static ViewerEditableInterface *viewer_editable_parent_interface = NULL;
+
+static void
+viewer_audio_file_editable_save (ViewerEditable  *editable,
+                                 GError         **error)
+{
+  ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable);
+
+  g_print ("Audio file implementation of editable interface save method.\n");
+
+  /* Now call the base implementation */
+  viewer_editable_parent_interface->save (editable, error);
+}
+
+static void
+viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
+{
+  viewer_editable_parent_interface = g_type_interface_peek_parent (iface);
+
+  iface->save = viewer_audio_file_editable_save;
+}
+
+G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
+                         G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+                                                viewer_audio_file_editable_interface_init))
+
+static void
+viewer_audio_file_class_init (ViewerAudioFileClass *klass)
+{
+  /* Nothing here. */
+}
+
+static void
+viewer_audio_file_init (ViewerAudioFile *self)
+{
+  /* Nothing here. */
+}
+</programlisting></informalexample>
+    </para>
+
+  </sect1>
+
+</chapter>
+<!-- End Howto Interfaces -->
+
+<chapter id="howto-signals">
+  <title>How to create and use signals</title>
+
+  <para>
+    The signal system in GType is pretty complex and
+    flexible: it is possible for its users to connect at runtime any
+    number of callbacks (implemented in any language for which a binding
+    exists)
+    <footnote>
+      <para>A Python callback can be connected to any signal on any
+      C-based GObject, and vice versa, assuming that the Python object
+      inherits from GObject.</para>
+    </footnote>
+    to any signal and to stop the emission of any signal at any 
+    state of the signal emission process. This flexibility makes it
+    possible to use GSignal for much more than just emitting signals to
+    multiple clients.
+  </para>
+
+  <sect1 id="howto-simple-signals">
+    <title>Simple use of signals</title>
+
+    <para>
+      The most basic use of signals is to implement event
+      notification. For example, given a <type>ViewerFile</type> object with
+      a <function>write</function> method, a signal could be emitted whenever
+      the file is changed using that method.
+      The code below shows how the user can connect a callback to the
+      "changed" signal.
+<informalexample><programlisting>
+file = g_object_new (VIEWER_FILE_TYPE, NULL);
+
+g_signal_connect (file, "changed", (GCallback) changed_event, NULL);
+
+viewer_file_write (file, buffer, strlen (buffer));
+</programlisting></informalexample>
+    </para>
+    
+    <para>
+      The <type>ViewerFile</type> signal is registered in the
+      <function>class_init</function> function:
+<informalexample><programlisting>
+file_signals[CHANGED] = 
+  g_signal_newv ("changed",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+                 NULL /* closure */,
+                 NULL /* accumulator */,
+                 NULL /* accumulator data */,
+                 NULL /* C marshaller */,
+                 G_TYPE_NONE /* return_type */,
+                 0     /* n_params */,
+                 NULL  /* param_types */);
+</programlisting></informalexample>
+      and the signal is emitted in <function>viewer_file_write</function>:
+<informalexample><programlisting>
+void
+viewer_file_write (ViewerFile   *self,
+                   const guint8 *buffer,
+                   gsize         size)
+{
+  g_return_if_fail (VIEWER_IS_FILE (self));
+  g_return_if_fail (buffer != NULL || size == 0);
+
+  /* First write data. */
+
+  /* Then, notify user of data written. */
+  g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
+}
+</programlisting></informalexample>
+      As shown above, the details parameter can safely be set to zero if no
+      detail needs to be conveyed. For a discussion of what it can be used for,
+      see <xref linkend="signal-detail"/>
+    </para>
+
+    <para>
+      The C signal marshaller should always be <literal>NULL</literal>, in which
+      case the best marshaller for the given closure type will be chosen by
+      GLib. This may be an internal marshaller specific to the closure type, or
+      <function>g_cclosure_marshal_generic</function>, which implements generic
+      conversion of arrays of parameters to C callback invocations. GLib used to
+      require the user to write or generate a type-specific marshaller and pass
+      that, but that has been deprecated in favour of automatic selection of
+      marshallers.
+    </para>
+
+    <para>
+      Note that <function>g_cclosure_marshal_generic</function> is slower than
+      non-generic marshallers, so should be avoided for performance critical
+      code. However, performance critical code should rarely be using signals
+      anyway, as emitting a signal blocks on emitting it to all listeners, which
+      has potentially unbounded cost.
+    </para>
+  </sect1>
+</chapter>
+</part>
diff --git a/docs/reference/gobject/tut_intro.xml b/docs/reference/gobject/tut_intro.xml
new file mode 100644
index 0000000..7614bf0
--- /dev/null
+++ b/docs/reference/gobject/tut_intro.xml
@@ -0,0 +1,185 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<chapter id="chapter-intro">
+  <title>Background</title>
+  
+  <para>
+    GObject, and its lower-level type system, GType, are used by GTK+ and most GNOME libraries to
+    provide:
+    <itemizedlist>
+      <listitem><para>object-oriented C-based APIs and</para></listitem>
+      <listitem><para>automatic transparent API bindings to other compiled 
+      or interpreted languages.</para></listitem>
+    </itemizedlist>
+  </para>
+  
+  <para>
+    A lot of programmers are used to working with compiled-only or dynamically interpreted-only
+    languages and do not understand the challenges associated with cross-language interoperability.
+    This introduction tries to provide an insight into these challenges and briefly describes
+    the solution chosen by GLib.
+  </para>
+  
+  <para>
+    The following chapters go into greater detail into how GType and GObject work and
+    how you can use them as a C programmer. It is useful to keep in mind that
+    allowing access to C objects from other interpreted languages was one of the major design
+    goals: this can often explain the sometimes rather convoluted APIs and features present
+    in this library.
+  </para>
+
+  <sect1>
+    <title>Data types and programming</title>
+    
+    <para>
+      One could say
+      that a programming language is merely a way to create data types and manipulate them. Most languages
+      provide a number of language-native types and a few primitives to create more complex types based
+      on these primitive types.
+    </para>
+    
+    <para>
+      In C, the language provides types such as <emphasis>char</emphasis>, <emphasis>long</emphasis>, 
+      <emphasis>pointer</emphasis>. During compilation of C code, the compiler maps these
+      language types to the compiler's target architecture machine types. If you are using a C interpreter
+      (assuming one exists), the interpreter (the program which interprets 
+      the source code and executes it) maps the language types to the machine types of the target machine at 
+      runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine).
+    </para>
+    
+    <para>
+      Perl and Python are interpreted languages which do not really provide type definitions similar
+      to those used by C. Perl and Python programmers manipulate variables and the type of the variables
+      is decided only upon the first assignment or upon the first use which forces a type on the variable.
+      The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
+      in Perl, a variable which holds an integer can be automatically converted to a string given the
+      required context:
+<informalexample><programlisting>
+my $tmp = 10;
+print "this is an integer converted to a string:" . $tmp . "\n";
+</programlisting></informalexample>
+      Of course, it is also often possible to explicitly specify conversions when the default conversions provided
+      by the language are not intuitive.
+    </para>
+    
+  </sect1>
+
+  <sect1>
+    <title>Exporting a C API</title>
+    
+    <para>
+      C APIs are defined by a set of functions and global variables which are usually exported from a 
+      binary. C functions have an arbitrary number of arguments and one return value. Each function is thus
+      uniquely identified by the function name and the set of C types which describe the function arguments
+      and return value. The global variables exported by the API are similarly identified by their name and 
+      their type.
+    </para>
+    
+    <para>
+      A C API is thus merely defined by a set of names to which a set of types are associated. If you know the
+      function calling convention and the mapping of the C types to the machine types used by the platform you 
+      are on, you can resolve the name of each function to find where the code associated to this function 
+      is located in memory, and then construct a valid argument list for the function. Finally, all you have to 
+      do is trigger a call to the target C function with the argument list.
+    </para>
+    
+    <para>
+      For the sake of discussion, here is a sample C function and the associated 32 bit x86 
+      assembly code generated by GCC on a Linux computer:
+<informalexample><programlisting>
+static void
+function_foo (int foo)
+{
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+	function_foo (10);
+
+	return 0;
+}
+
+push   $0xa
+call   0x80482f4 &lt;function_foo>
+</programlisting></informalexample>
+      The assembly code shown above is pretty straightforward: the first instruction pushes
+      the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls 
+      <function>function_foo</function>. As you can see, C function calls are implemented by
+      GCC as native function calls (this is probably the fastest implementation possible).
+    </para>
+    
+    <para>
+      Now, let's say we want to call the C function <function>function_foo</function> from 
+      a Python program. To do this, the Python interpreter needs to:
+      <itemizedlist>
+        <listitem><para>Find where the function is located. This probably means finding the binary generated by the C compiler
+        which exports this function.</para></listitem>
+        <listitem><para>Load the code of the function in executable memory.</para></listitem>
+        <listitem><para>Convert the Python parameters to C-compatible parameters before calling 
+        the function.</para></listitem>
+        <listitem><para>Call the function with the right calling convention.</para></listitem>
+        <listitem><para>Convert the return values of the C function to Python-compatible
+        variables to return them to the Python code.</para></listitem>
+      </itemizedlist>
+    </para>
+    
+    <para>
+      The process described above is pretty complex and there are a lot of ways to make it entirely automatic
+      and transparent to C and Python programmers:
+      <itemizedlist>
+        <listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported,
+        which does the Python-to-C parameter conversion and the C-to-Python return value conversion. This glue code is then 
+        linked with the interpreter which allows Python programs to call Python functions which delegate work to
+        C functions.</para></listitem>
+        <listitem><para>Another, nicer solution is to automatically generate the glue code, once for each function exported or
+        imported, with a special compiler which
+        reads the original function signature.</para></listitem>
+        <listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of
+        all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis>
+        <footnote>
+          <para>
+            There are numerous different implementations of dynamic type systems: all C++ 
+            compilers have one, Java and .NET have one too. A dynamic type system allows you
+            to get information about every instantiated object at runtime. It can be implemented
+            by a process-specific database: every new object created registers the characteristics 
+            of its associated type in the type system. It can also be implemented by introspection
+            interfaces. The common point between all these different type systems and implementations
+            is that they all allow you to query for object metadata at runtime.
+          </para>
+        </footnote>
+        library is then used by special generic glue code to automatically convert function parameters and
+        function calling conventions between different runtime domains.</para></listitem>
+      </itemizedlist>
+      The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain 
+      boundaries is written once: the figure below states this more clearly.
+      <figure>
+        <mediaobject>
+          <imageobject> <!-- this is for HTML output -->
+            <imagedata fileref="glue.png" format="PNG" align="center"/>
+          </imageobject>
+          <imageobject> <!-- this is for PDF output -->
+            <imagedata fileref="glue.jpg" format="JPG" align="center"/>
+          </imageobject>
+        </mediaobject>
+      </figure>
+      
+      Currently, there exist at least Python and Perl generic glue code which makes it possible to use
+      C objects written with GType directly in Python or Perl, with a minimum amount of work: there
+      is no need to generate huge amounts of glue code either automatically or by hand.
+    </para>
+    
+    <para>
+      Although that goal was arguably laudable, its pursuit has had a major influence on
+      the whole GType/GObject library. C programmers are likely to be puzzled at the complexity 
+      of the features exposed in the following chapters if they forget that the GType/GObject library
+      was not only designed to offer OO-like features to C programmers but also transparent 
+      cross-language interoperability.
+    </para>
+  
+  </sect1>
+
+</chapter>
diff --git a/docs/reference/gobject/tut_tools.xml b/docs/reference/gobject/tut_tools.xml
new file mode 100644
index 0000000..f1076e8
--- /dev/null
+++ b/docs/reference/gobject/tut_tools.xml
@@ -0,0 +1,125 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
+               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<part label="V">
+  <title>Related Tools</title>
+  
+  <partintro>
+    <para>
+      Several useful developer tools have been build around GObject
+      technology.  The next sections briefly introduce them and link to
+      the respective project pages.
+    </para>
+  
+    <para>
+      For example, writing GObjects is often seen as a tedious task. It
+      requires a lot of typing and just doing a copy/paste requires a
+      great deal of care. A lot of projects and scripts have been
+      written to generate GObject skeleton form boilerplate code, or
+      even translating higher-level language into plain C.
+    </para>
+  </partintro>
+  
+  <chapter id="tools-vala">
+    <title>Vala</title>
+    <para>
+      From the <ulink url="https://wiki.gnome.org/Projects/Vala">Vala
+      homepage</ulink> itself: <quote>Vala is a new programming language
+      that aims to bring modern programming language features to GNOME
+      developers without imposing any additional runtime requirements
+      and without using a different ABI compared to applications and
+      libraries written in C.</quote>
+    </para>
+  
+    <para>
+      The syntax of Vala is similar to C#. The available compiler
+      translates Vala into GObject C code. It can also compile
+      non-GObject C, using plain C API.
+    </para>
+  </chapter>
+  
+  <chapter id="tools-gob">
+    <title>GObject builder</title>
+  
+    <para>
+      In order to help a GObject class developer, one obvious idea is
+      to use some sort of templates for the skeletons and then run
+      them through a special tool to generate the real C files.  <ulink
+      url="http://www.5z.com/jirka/gob.html">GOB</ulink> (or GOB2) is
+      such a tool. It is a preprocessor which can be used to build
+      GObjects with inline C code so that there is no need to edit the
+      generated C code.  The syntax is inspired by Java and Yacc or
+      Lex. The implementation is intentionally kept simple: the inline C
+      code provided by the user is not parsed.
+    </para>
+  </chapter>
+  
+  <chapter id="tools-ginspector">
+      <title>Graphical inspection of GObjects</title>
+  
+      <para>
+        Yet another tool that you may find helpful when working with
+        GObjects is <ulink
+        url="http://sourceforge.net/projects/g-inspector">G-Inspector</ulink>. It
+        is able to display GLib/GTK+ objects and their properties.
+      </para>
+  </chapter>
+  
+  <chapter id="tools-refdb">
+    <title>Debugging reference count problems</title>
+  
+    <para>
+      The reference counting scheme used by GObject does solve quite 
+      a few memory management problems but also introduces new sources of bugs.
+      In large applications, finding the exact spot where the reference count
+      of an Object is not properly handled can be very difficult.
+    </para>
+    <para>
+      A useful tool in debugging reference counting problems is to
+      set breakpoints in gdb on g_object_ref() and g_object_unref().
+      Once you know the address of the object you are interested in,
+      you can make the breakpoints conditional:
+      <programlisting>
+break g_object_ref if _object == 0xcafebabe
+break g_object_unref if _object == 0xcafebabe
+      </programlisting>
+    </para>
+  </chapter>
+    
+  <chapter id="tools-gtkdoc">
+    <title>Writing API docs</title>
+  
+    <para>The API documentation for most of the GLib, GObject, GTK+ and GNOME
+    libraries is built with a combination of complex tools. Typically, the part of 
+    the documentation which describes the behavior of each function is extracted
+    from the specially-formatted source code comments by a tool named gtk-doc which
+    generates DocBook XML and merges this DocBook XML with a set of template XML
+    DocBook files. These XML DocBook files are finally processed with xsltproc
+    (a small program part of the libxslt library) to generate the final HTML
+    output. Other tools can be used to generate PDF output from the source XML.
+    The following code excerpt shows what these comments look like.
+      <informalexample><programlisting>
+/**
+ * gtk_widget_freeze_child_notify:
+ * @widget: a #GtkWidget
+ * 
+ * Stops emission of "child-notify" signals on @widget. The signals are
+ * queued until gtk_widget_thaw_child_notify() is called on @widget. 
+ *
+ * This is the analogue of g_object_freeze_notify() for child properties.
+ **/
+void
+gtk_widget_freeze_child_notify (GtkWidget *widget)
+{
+...
+      </programlisting></informalexample>
+    </para>
+    <para>
+    Thorough
+    <ulink url="https://developer.gnome.org/gtk-doc-manual/stable/">documentation</ulink>
+    on how to set up and use gtk-doc in your project is provided on the
+    <ulink url="https://developer.gnome.org/">GNOME developer website</ulink>.
+    </para>
+  </chapter>
+</part>
diff --git a/docs/reference/gobject/version.xml.in b/docs/reference/gobject/version.xml.in
new file mode 100644
index 0000000..af9b9c4
--- /dev/null
+++ b/docs/reference/gobject/version.xml.in
@@ -0,0 +1 @@
+@GLIB_VERSION@
diff --git a/docs/reference/gobject/xml/gtkdocentities.ent.in b/docs/reference/gobject/xml/gtkdocentities.ent.in
new file mode 100644
index 0000000..f12c9ff
--- /dev/null
+++ b/docs/reference/gobject/xml/gtkdocentities.ent.in
@@ -0,0 +1,8 @@
+<!ENTITY package "@PACKAGE@">
+<!ENTITY package_bugreport "@PACKAGE_BUGREPORT@">
+<!ENTITY package_name "@PACKAGE_NAME@">
+<!ENTITY package_string "@PACKAGE_STRING@">
+<!ENTITY package_tarname "@PACKAGE_TARNAME@">
+<!ENTITY package_url "@PACKAGE_URL@">
+<!ENTITY package_version "@PACKAGE_VERSION@">
+<!ENTITY package_api_version "@PACKAGE_API_VERSION@">
diff --git a/docs/reference/gobject/xml/meson.build b/docs/reference/gobject/xml/meson.build
new file mode 100644
index 0000000..6aeb745
--- /dev/null
+++ b/docs/reference/gobject/xml/meson.build
@@ -0,0 +1,14 @@
+ent_conf = configuration_data()
+ent_conf.set('PACKAGE', 'glib')
+ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new')
+ent_conf.set('PACKAGE_NAME', 'glib')
+ent_conf.set('PACKAGE_STRING', 'glib')
+ent_conf.set('PACKAGE_TARNAME', 'glib')
+ent_conf.set('PACKAGE_URL', 'FIXME')
+ent_conf.set('PACKAGE_VERSION', glib_version)
+ent_conf.set('PACKAGE_API_VERSION', glib_api_version)
+configure_file(
+  input: 'gtkdocentities.ent.in',
+  output: 'gtkdocentities.ent',
+  configuration: ent_conf
+)
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
new file mode 100644
index 0000000..a676af1
--- /dev/null
+++ b/docs/reference/meson.build
@@ -0,0 +1,62 @@
+# The list of minor versions in the 2.x.x series which have had
+# GLIB_AVAILABLE_IN_* macros. This should include the current unreleased stable
+# version.
+#
+# FIXME: It would be good to be able to generate this list:
+# https://github.com/mesonbuild/meson/issues/5026
+stable_2_series_versions = [
+  '26', '28', '30', '32', '34', '36', '38',
+  '40', '42', '44', '46', '48', '50', '52', '54', '56', '58',
+  '60', '62', '64', '66',
+]
+
+ignore_decorators = [
+  'GLIB_VAR',
+  'G_GNUC_INTERNAL',
+  'G_GNUC_WARN_UNUSED_RESULT',
+  'GLIB_AVAILABLE_IN_ALL',
+]
+
+foreach version : stable_2_series_versions
+  ignore_decorators += [
+    # Note that gtkdoc is going to use those in regex, and the longest match
+    # must come first. That's why '_FOR()' variant comes first.
+    # gtkdoc special-case '()' and replace it by a regex matching a symbol name.
+    'GLIB_AVAILABLE_IN_2_' + version,
+    'GLIB_DEPRECATED_IN_2_' + version + '_FOR()',
+    'GLIB_DEPRECATED_IN_2_' + version,
+
+    'GLIB_AVAILABLE_STATIC_INLINE_IN_2_' + version,
+
+    'GLIB_AVAILABLE_ENUMERATOR_IN_2_' + version,
+    'GLIB_DEPRECATED_ENUMERATOR_IN_2_' + version + '_FOR()',
+    'GLIB_DEPRECATED_ENUMERATOR_IN_2_' + version,
+
+    'GLIB_AVAILABLE_MACRO_IN_2_' + version,
+    'GLIB_DEPRECATED_MACRO_IN_2_' + version + '_FOR()',
+    'GLIB_DEPRECATED_MACRO_IN_2_' + version,
+
+    'GLIB_AVAILABLE_TYPE_IN_2_' + version,
+    'GLIB_DEPRECATED_TYPE_IN_2_' + version + '_FOR()',
+    'GLIB_DEPRECATED_TYPE_IN_2_' + version,
+  ]
+endforeach
+
+gtkdoc_common_scan_args = [
+  '--ignore-decorators=' + '|'.join(ignore_decorators),
+]
+
+if get_option('gtk_doc')
+  if not meson.version().version_compare('>=0.52.0')
+    error('Building documentation requires Meson >= 0.52.0.')
+  endif
+  # Check we have the minimum gtk-doc version required. Older versions won't
+  # generate correct documentation.
+  dependency('gtk-doc', version : '>=1.32.1',
+    fallback : ['gtk-doc', 'dummy_dep'],
+    default_options : ['tests=false'])
+endif
+
+subdir('gio')
+subdir('glib')
+subdir('gobject')
diff --git a/fuzzing/README.md b/fuzzing/README.md
new file mode 100644
index 0000000..16f5a05
--- /dev/null
+++ b/fuzzing/README.md
@@ -0,0 +1,51 @@
+Fuzz targets used by [oss-fuzz](https://github.com/google/oss-fuzz/).
+
+Useful links: [Dashboard](https://oss-fuzz.com/) _(requires access)_, [Build logs](https://oss-fuzz-build-logs.storage.googleapis.com/index.html), [Coverage](https://oss-fuzz.com/coverage-report/job/libfuzzer_asan_glib/latest)
+
+## How to add new targets
+
+Add **fuzz_target_name.c** and edit `meson.build` accordingly.
+
+New targets are picked up by oss-fuzz automatically within a day. Targets must not be renamed once added.
+
+Add (optional) **fuzz_target_name.dict** containing keywords and magic bytes.
+
+Add (optional) **fuzz_target_name.corpus** with file names on separate lines. Wildcards `?`, `*` and `**` are supported. Examples below.
+
+```bash
+glib/*  # all files in directory glib
+glib/** # all files in directory glib and sub-directories
+**.xbel # all files ending with .xbel in the repository
+```
+
+Recommended reading: [Fuzz Target](https://llvm.org/docs/LibFuzzer.html#fuzz-target), [Dictionaries](https://llvm.org/docs/LibFuzzer.html#dictionaries), [Corpus](https://llvm.org/docs/LibFuzzer.html#corpus)
+
+## How to reproduce oss-fuzz bugs locally
+
+Build with at least the following flags, choosing a sanitizer as needed. A somewhat recent version of [clang](http://clang.llvm.org/) is recommended.
+
+```bash
+$ CC=clang CXX=clang++ meson DIR -Db_sanitize=<address|undefined> -Db_lundef=false
+```
+
+Afterwards run the affected target against the provided test case.
+
+```bash
+$ DIR/fuzzing/fuzz_target_name FILE
+```
+
+#### FAQs
+
+###### What about Memory Sanitizer (MSAN)?
+
+Correct MSAN instrumentation is [difficult to achieve](https://clang.llvm.org/docs/MemorySanitizer.html#handling-external-code) locally, so false positives are very likely to mask the actual bug.
+
+If need be, [you can still reproduce](https://github.com/google/oss-fuzz/blob/master/docs/reproducing.md#building-using-docker) those bugs with the oss-fuzz provided docker images.
+
+###### There are no file/function names in the stack trace.
+
+`llvm-symbolizer` must be in `PATH`.
+
+###### UndefinedBehavior Sanitizer (UBSAN) doesn't provide a stack trace.
+
+Set environment variable `UBSAN_OPTIONS` to `print_stacktrace=1` prior to running the target.
diff --git a/fuzzing/driver.c b/fuzzing/driver.c
new file mode 100644
index 0000000..99e965b
--- /dev/null
+++ b/fuzzing/driver.c
@@ -0,0 +1,32 @@
+/* Simpler gnu89 version of StandaloneFuzzTargetMain.c from LLVM */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size);
+
+int
+main (int argc, char **argv)
+{
+  FILE *f;
+  size_t n_read, len;
+  unsigned char *buf;
+
+  if (argc < 2)
+    return 1;
+
+  f = fopen (argv[1], "r");
+  assert (f);
+  fseek (f, 0, SEEK_END);
+  len = ftell (f);
+  fseek (f, 0, SEEK_SET);
+  buf = (unsigned char*) malloc (len);
+  n_read = fread (buf, 1, len, f);
+  assert (n_read == len);
+  LLVMFuzzerTestOneInput (buf, len);
+
+  free (buf);
+  printf ("Done!\n");
+  return 0;
+}
diff --git a/fuzzing/fuzz.h b/fuzzing/fuzz.h
new file mode 100644
index 0000000..4a87998
--- /dev/null
+++ b/fuzzing/fuzz.h
@@ -0,0 +1,22 @@
+#include "gio/gio.h"
+#include "glib/glib.h"
+
+int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size);
+
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+static GLogWriterOutput
+empty_logging_func (GLogLevelFlags log_level, const GLogField *fields,
+                    gsize n_fields, gpointer user_data)
+{
+  return G_LOG_WRITER_HANDLED;
+}
+#endif
+
+/* Disables logging for oss-fuzz. Must be used with each target. */
+static void
+fuzz_set_logging_func (void)
+{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  g_log_set_writer_func (empty_logging_func, NULL, NULL);
+#endif
+}
diff --git a/fuzzing/fuzz_bookmark.c b/fuzzing/fuzz_bookmark.c
new file mode 100644
index 0000000..4f257fd
--- /dev/null
+++ b/fuzzing/fuzz_bookmark.c
@@ -0,0 +1,15 @@
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+  GBookmarkFile *bookmark = NULL;
+
+  fuzz_set_logging_func ();
+
+  bookmark = g_bookmark_file_new ();
+  g_bookmark_file_load_from_data (bookmark, (const gchar*) data, size, NULL);
+
+  g_bookmark_file_free (bookmark);
+  return 0;
+}
diff --git a/fuzzing/fuzz_bookmark.corpus b/fuzzing/fuzz_bookmark.corpus
new file mode 100644
index 0000000..5c78bc9
--- /dev/null
+++ b/fuzzing/fuzz_bookmark.corpus
@@ -0,0 +1 @@
+glib/tests/**.xbel
diff --git a/fuzzing/fuzz_dbus_message.c b/fuzzing/fuzz_dbus_message.c
new file mode 100644
index 0000000..bccb2ba
--- /dev/null
+++ b/fuzzing/fuzz_dbus_message.c
@@ -0,0 +1,28 @@
+#include "fuzz.h"
+
+const static GDBusCapabilityFlags flags = G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING;
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+  gssize bytes;
+  GDBusMessage *msg = NULL;
+  guchar *blob = NULL;
+  gsize msg_size;
+
+  fuzz_set_logging_func ();
+
+  bytes = g_dbus_message_bytes_needed ((guchar*) data, size, NULL);
+  if (bytes <= 0)
+    return 0;
+
+  msg = g_dbus_message_new_from_blob ((guchar*) data, size, flags, NULL);
+  if (msg == NULL)
+    return 0;
+
+  blob = g_dbus_message_to_blob (msg, &msg_size, flags, NULL);
+
+  g_free (blob);
+  g_object_unref (msg);
+  return 0;
+}
diff --git a/fuzzing/fuzz_key.c b/fuzzing/fuzz_key.c
new file mode 100644
index 0000000..8d0edc5
--- /dev/null
+++ b/fuzzing/fuzz_key.c
@@ -0,0 +1,16 @@
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+  GKeyFile *key = NULL;
+
+  fuzz_set_logging_func ();
+
+  key = g_key_file_new ();
+  g_key_file_load_from_data (key, (const gchar*) data, size, G_KEY_FILE_NONE,
+                             NULL);
+
+  g_key_file_free (key);
+  return 0;
+}
diff --git a/fuzzing/fuzz_key.corpus b/fuzzing/fuzz_key.corpus
new file mode 100644
index 0000000..5a1cb41
--- /dev/null
+++ b/fuzzing/fuzz_key.corpus
@@ -0,0 +1,2 @@
+glib/tests/**.ini
+gio/tests/**.desktop
diff --git a/fuzzing/fuzz_variant_binary.c b/fuzzing/fuzz_variant_binary.c
new file mode 100644
index 0000000..995718c
--- /dev/null
+++ b/fuzzing/fuzz_variant_binary.c
@@ -0,0 +1,21 @@
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+  GVariant *variant = NULL, *normal_variant = NULL;
+
+  fuzz_set_logging_func ();
+
+  variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, FALSE,
+                                     NULL, NULL);
+  if (variant == NULL)
+    return 0;
+
+  normal_variant = g_variant_take_ref (g_variant_get_normal_form (variant));
+  g_variant_get_data (variant);
+
+  g_variant_unref (normal_variant);
+  g_variant_unref (variant);
+  return 0;
+}
diff --git a/fuzzing/fuzz_variant_text.c b/fuzzing/fuzz_variant_text.c
new file mode 100644
index 0000000..a797909
--- /dev/null
+++ b/fuzzing/fuzz_variant_text.c
@@ -0,0 +1,21 @@
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+  const gchar *gdata = (const gchar*) data;
+  GVariant *variant = NULL;
+  gchar *text = NULL;
+
+  fuzz_set_logging_func ();
+
+  variant = g_variant_parse (NULL, gdata, gdata + size, NULL, NULL);
+  if (variant == NULL)
+    return 0;
+
+  text = g_variant_print (variant, TRUE);
+
+  g_free (text);
+  g_variant_unref (variant);
+  return 0;
+}
diff --git a/fuzzing/fuzz_variant_text.dict b/fuzzing/fuzz_variant_text.dict
new file mode 100644
index 0000000..a0e5284
--- /dev/null
+++ b/fuzzing/fuzz_variant_text.dict
@@ -0,0 +1,32 @@
+"'"
+"\""
+"("
+")"
+"<"
+">"
+"["
+"]"
+"{"
+"}"
+"*"
+"?"
+"@"
+"b'"
+"b\""
+"boolean"
+"byte"
+"double"
+"false"
+"handle"
+"int16"
+"int32"
+"int64"
+"just"
+"nothing"
+"objectpath"
+"signature"
+"string"
+"true"
+"uint16"
+"uint32"
+"uint64"
diff --git a/fuzzing/meson.build b/fuzzing/meson.build
new file mode 100644
index 0000000..7fdd8c9
--- /dev/null
+++ b/fuzzing/meson.build
@@ -0,0 +1,28 @@
+fuzz_targets = [
+  'fuzz_bookmark',
+  'fuzz_dbus_message',
+  'fuzz_key',
+  'fuzz_variant_binary',
+  'fuzz_variant_text',
+]
+
+deps = [libgmodule_dep, libgio_dep, libglib_dep, libgobject_dep]
+
+extra_sources = []
+extra_c_args = cc.get_supported_arguments('-Werror=unused-function')
+
+# Links in a static library provided by oss-fuzz, else a standalone driver.
+# https://github.com/google/oss-fuzz/blob/master/docs/new_project_guide.md#buildsh-script-environment
+fuzzing_engine = cxx.find_library('FuzzingEngine', required : get_option('oss_fuzz'))
+if fuzzing_engine.found()
+  deps += fuzzing_engine
+else
+  extra_sources += 'driver.c'
+endif
+
+foreach target_name : fuzz_targets
+  exe = executable(target_name, [extra_sources, target_name + '.c'],
+    c_args : extra_c_args,
+    dependencies : deps,
+  )
+endforeach
diff --git a/gio/completion/.gitignore b/gio/completion/.gitignore
new file mode 100644
index 0000000..6930af9
--- /dev/null
+++ b/gio/completion/.gitignore
@@ -0,0 +1 @@
+!gio
diff --git a/gio/completion/gapplication b/gio/completion/gapplication
new file mode 100644
index 0000000..565025b
--- /dev/null
+++ b/gio/completion/gapplication
@@ -0,0 +1,55 @@
+
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+####################################################################################################
+
+__app() {
+  case "${COMP_CWORD}" in
+    1)
+      COMPREPLY=($(compgen -W "help version list-apps launch action list-actions" -- "${COMP_WORDS[1]}"))
+      return 0
+      ;;
+
+    2)
+      case "${COMP_WORDS[1]}" in
+        launch|action|list-actions)
+          COMPREPLY=($(compgen -W "`gapplication list-apps`" -- "${COMP_WORDS[2]}"))
+          return 0
+          ;;
+
+        *)
+          COMPREPLY=()
+          return 0
+          ;;
+      esac
+      ;;
+  esac
+
+  # Otherwise, what we will do is based on the command in ${COMP_WORDS[1]}
+  case "${COMP_WORDS[1]}" in
+    action)
+      # Word 3 is the action name.  This is the only one we can help with.
+      if [ "${COMP_CWORD}" == 3 ]; then
+        COMPREPLY=($(compgen -W "`gapplication list-actions "${COMP_WORDS[2]}"`" -- "${COMP_WORDS[3]}"))
+        return 0
+      else
+        COMPREPLY=()
+        return 0
+      fi
+      ;;
+    launch)
+      # Filenames...
+      COMPREPLY=($(compgen -A file "${COMP_WORDS[COMP_CWORD]}"))
+      return 0
+      ;;
+    *)
+      # Nothing else should be out this far...
+      COMPREPLY=()
+      return 0
+  esac
+}
+
+####################################################################################################
+
+complete -F __app gapplication
diff --git a/gio/completion/gdbus b/gio/completion/gdbus
new file mode 100644
index 0000000..79f4cb4
--- /dev/null
+++ b/gio/completion/gdbus
@@ -0,0 +1,33 @@
+
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+####################################################################################################
+
+
+__gdbus() {
+    local IFS=$'\n'
+    local cur=`_get_cword :`
+
+    local suggestions=$(gdbus complete "${COMP_LINE}" ${COMP_POINT})
+    COMPREPLY=($(compgen -W "$suggestions" -- "$cur"))
+
+    # Remove colon-word prefix from COMPREPLY items
+    case "$cur" in
+        *:*)
+            case "$COMP_WORDBREAKS" in
+                *:*)
+                    local colon_word=${cur%${cur##*:}}
+                    local i=${#COMPREPLY[*]}
+                    while [ $((--i)) -ge 0 ]; do
+                        COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
+                    done
+                    ;;
+            esac
+            ;;
+    esac
+}
+
+####################################################################################################
+
+complete -o nospace -F __gdbus gdbus
diff --git a/gio/completion/gio b/gio/completion/gio
new file mode 100644
index 0000000..75473d2
--- /dev/null
+++ b/gio/completion/gio
@@ -0,0 +1,119 @@
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# 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
+# licence, or (at your option) any later version.
+#
+# This 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, see <http://www.gnu.org/licenses/>.
+#
+
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+####################################################################################################
+
+# Check whether the suggestions have common prefix (i.e. suggestions won't be
+# shown and prefix will be completed first)
+__has_common_prefix() {
+    for (( i = 1; i < ${#COMPREPLY[@]}; i++ )); do
+        if [[ "${COMPREPLY[i-1]:${#cur}:1}" != "${COMPREPLY[i]:${#cur}:1}" ]]; then
+            return 1 # False
+        fi
+    done
+
+    return 0 # True
+}
+
+# Complete file location
+__gio_location() {
+    # Prevent breaking on colons, we have to work with uris
+    local cur
+    _get_comp_words_by_ref -n : cur
+
+    # Resolve dirname for dir listing
+    local dir=""
+    if [[ $cur =~ "/"$ ]]; then
+        dir="$cur"
+    elif [[ $cur =~ "/" ]]; then
+        # Subtract basename because dirname cmd doesn't work well with schemes
+        dir=${cur%$(basename "$cur")}
+    fi
+
+    # List volumes and mounts
+    local mounts=( )
+    while IFS=$'\n' read mount; do
+        # Do not care about local mounts
+        [[ "$mount" =~ ^"file:" ]] && continue
+
+        # Use only matching mounts
+        [[ "$mount" =~ ^"$cur" && "$mount" != "$cur" ]] && mounts+=("$mount")
+    done < <(gio mount -li | sed -n -r 's/^ *(default_location|activation_root)=(.*)$/\2/p' | sort -u)
+
+    # Workaround to unescape dir name (e.g. "\ " -> " ")
+    declare -a tmp="( ${dir} )"
+    unescaped_dir="${tmp[0]}"
+
+    # List files
+    local files=()
+    local names=()
+    while IFS=$'\t' read name size type; do
+        # Escape name properly
+        local escaped_name="$(printf "%q" "$name")"
+
+        # Append slash for directories and space for files
+        if [[ "$type" == "(directory)" ]]; then
+            escaped_name="$escaped_name/"
+        else
+            escaped_name="$escaped_name "
+        fi
+
+        path="$dir$escaped_name"
+
+        # Use only matching paths
+        if [[ "$path" =~ ^"$cur" ]]; then
+            files+=("$path")
+            names+=("$escaped_name")
+        fi
+    done < <(gio list -hl "$unescaped_dir" 2> /dev/null)
+
+    COMPREPLY=("${files[@]}" "${mounts[@]}")
+
+    # Workaround to show suggestions as basenames only
+    if ! __has_common_prefix; then
+        COMPREPLY=("${mounts[@]} ${names[@]}")
+
+        # Workaround to prevent overwriting suggestions, it adds empty
+        # suggestion, otherwise names with colons will be corrupted
+        COMPREPLY+=(" ")
+
+        return 0
+    fi
+
+    # Workaround to complete names with colons, it removes colon prefix from
+    # COMPREPLY
+    __ltrim_colon_completions "$cur"
+}
+
+__gio() {
+    # Complete subcommands
+    if (( ${COMP_CWORD} == 1 )); then
+        COMPREPLY=($(compgen -W "help version cat copy info list mime mkdir monitor mount move open rename remove save set trash tree" -- "${COMP_WORDS[1]}"))
+        compopt +o nospace
+        return 0
+    fi
+
+    # Complete file locations
+    __gio_location
+}
+
+####################################################################################################
+
+complete -o nospace -F __gio gio
diff --git a/gio/completion/gresource b/gio/completion/gresource
new file mode 100644
index 0000000..ef1145d
--- /dev/null
+++ b/gio/completion/gresource
@@ -0,0 +1,58 @@
+
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+####################################################################################################
+
+__gresource() {
+  local choices coffset section
+
+  if [ ${COMP_CWORD} -gt 2 ]; then
+      if [ ${COMP_WORDS[1]} = --section ]; then
+          section=${COMP_WORDS[2]}
+          coffset=2
+      else
+          coffset=0
+      fi
+  else
+      coffset=0
+  fi
+
+  case "$((${COMP_CWORD}-$coffset))" in
+    1)
+      choices=$'--section \nhelp \nsections \nlist \ndetails \nextract '
+      ;;
+
+    2)
+      case "${COMP_WORDS[$(($coffset+1))]}" in
+        --section)
+          return 0
+          ;;
+
+        help)
+          choices=$'sections\nlist\ndetails\nextract'
+          ;;
+
+        sections|list|details|extract)
+          COMPREPLY=($(compgen -f -- ${COMP_WORDS[${COMP_CWORD}]}))
+          return 0
+          ;;
+      esac
+      ;;
+
+    3)
+      case "${COMP_WORDS[$(($coffset+1))]}" in
+        list|details|extract)
+          choices="$(gresource list ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null | sed -e 's.$. .')"
+          ;;
+      esac
+      ;;
+  esac
+
+  local IFS=$'\n'
+  COMPREPLY=($(compgen -W "${choices}" -- "${COMP_WORDS[${COMP_CWORD}]}"))
+}
+
+####################################################################################################
+
+complete -o nospace -F __gresource gresource
diff --git a/gio/completion/gsettings b/gio/completion/gsettings
new file mode 100644
index 0000000..d509758
--- /dev/null
+++ b/gio/completion/gsettings
@@ -0,0 +1,88 @@
+
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+####################################################################################################
+
+__gsettings() {
+  local choices coffset schemadir
+
+  if [ ${COMP_CWORD} -gt 2 ]; then
+      if [ ${COMP_WORDS[1]} = --schemadir ]; then
+	  # this complexity is needed to perform correct tilde expansion
+	  schemadir=$(eval "echo --schemadir ${COMP_WORDS[2]}")
+	  coffset=2
+      else
+	  coffset=0
+      fi
+  else
+      coffset=0
+  fi
+
+  case "$((${COMP_CWORD}-$coffset))" in
+    1)
+      choices=$'--schemadir\n--version\nhelp \nlist-schemas\nlist-relocatable-schemas\nlist-keys \nlist-children \nlist-recursively \nget \nrange \nset \nreset \nreset-recursively \nwritable \nmonitor \ndescribe '
+      ;;
+
+    2)
+      case "${COMP_WORDS[$(($coffset+1))]}" in
+	--schemadir)
+	  COMPREPLY=($(compgen -o dirnames -- ${COMP_WORDS[${COMP_CWORD}]}))
+	  return 0
+	  ;;
+
+        help)
+          choices=$'list-schemas\nlist-relocatable-schemas\nlist-keys\nlist-children\nlist-recursively\nget\nrange\nset\nreset\nreset-recursively\nwritable\nmonitor'
+          ;;
+        list-keys|list-children|list-recursively|reset-recursively)
+          choices="$(gsettings $schemadir list-schemas 2> /dev/null)"$'\n'"$(gsettings $schemadir list-relocatable-schemas 2> /dev/null | sed -e 's.$.:/.')"
+          ;;
+        list-schemas)
+          COMPREPLY=($(compgen -W "--print-paths" -- ${COMP_WORDS[${COMP_CWORD}]}))
+          return 0
+          ;;
+
+        get|range|set|reset|writable|monitor|describe)
+          choices="$(gsettings $schemadir list-schemas 2> /dev/null | sed -e 's.$. .')"$'\n'"$(gsettings $schemadir list-relocatable-schemas 2> /dev/null | sed -e 's.$.:/.')"
+          ;;
+      esac
+      ;;
+
+    3)
+      case "${COMP_WORDS[$(($coffset+1))]}" in
+        set)
+          choices="$(gsettings $schemadir list-keys ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null | sed -e 's.$. .')"
+          ;;
+
+        get|range|reset|writable|monitor|describe)
+          choices="$(gsettings $schemadir list-keys ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null)"
+          ;;
+      esac
+      ;;
+
+    4)
+      case "${COMP_WORDS[$(($coffset+2))]}" in
+        set)
+          range=($(gsettings $schemadir range ${COMP_WORDS[$(($coffset+2))]} ${COMP_WORDS[$(($coffset+3))]} 2> /dev/null))
+          case "${range[0]}" in
+            enum)
+              unset range[0]
+             ;;
+            *)
+              unset range
+             ;;
+          esac
+          local IFS=$'\n'
+          choices="${range[*]}"
+          ;;
+      esac
+      ;;
+  esac
+
+  local IFS=$'\n'
+  COMPREPLY=($(compgen -W "${choices}" -- "${COMP_WORDS[${COMP_CWORD}]}"))
+}
+
+####################################################################################################
+
+complete -o nospace -F __gsettings gsettings
diff --git a/gio/data-to-c.py b/gio/data-to-c.py
new file mode 100755
index 0000000..f226220
--- /dev/null
+++ b/gio/data-to-c.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+
+import sys
+
+if len(sys.argv) < 4:
+    print('Usage: {0} <filename> <variable> <output>')
+
+with open(sys.argv[1], 'rb') as f:
+    in_data = f.read().decode('utf-8', 'backslashreplace')
+b = [r'\x{:02x}'.format(ord(c)) for c in in_data]
+
+out_data = "const char {0}[] = \"".format(sys.argv[2])
+out_data += "".join(b) + "\";"
+
+with open(sys.argv[3], 'w') as f:
+    f.write(out_data)
diff --git a/gio/dbus-daemon.xml b/gio/dbus-daemon.xml
new file mode 100644
index 0000000..515dd34
--- /dev/null
+++ b/gio/dbus-daemon.xml
@@ -0,0 +1,76 @@
+<node>
+  <interface name="org.freedesktop.DBus">
+    <method name="Hello">
+      <arg direction="out" type="s" name="assigned_name"/>
+    </method>
+    <method name="RequestName">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="in" type="u" name="flags"/>
+      <arg direction="out" type="u" name="value"/>
+    </method>
+    <method name="ReleaseName">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="u" name="value"/>
+    </method>
+    <method name="StartServiceByName">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="in" type="u" name="flags"/>
+      <arg direction="out" type="u" name="value"/>
+    </method>
+    <method name="NameHasOwner">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="b" name="has_owner"/>
+    </method>
+    <method name="ListNames">
+      <arg direction="out" type="as" name="names"/>
+    </method>
+    <method name="ListActivatableNames">
+      <arg direction="out" type="as" name="activatable_names"/>
+    </method>
+    <method name="AddMatch">
+      <arg direction="in" type="s" name="rule"/>
+    </method>
+    <method name="RemoveMatch">
+      <arg direction="in" type="s" name="rule"/>
+    </method>
+    <method name="GetNameOwner">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="s" name="unique_name"/>
+    </method>
+    <method name="ListQueuedOwners">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="as" name="queued_owners"/>
+    </method>
+    <method name="GetConnectionUnixUser">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="u" name="uid"/>
+    </method>
+    <method name="GetConnectionUnixProcessID">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="u" name="pid"/>
+    </method>
+    <method name="GetConnectionSELinuxSecurityContext">
+      <arg direction="in" type="s" name="name"/>
+      <arg direction="out" type="ay" name="security_context"/>
+    </method>
+    <method name="UpdateActivationEnvironment">
+      <arg direction="in" type="a{ss}" name="environment"/>
+    </method>
+    <method name="ReloadConfig">
+    </method>
+    <method name="GetId">
+      <arg direction="out" type="s" name="unique_id"/>
+    </method>
+    <signal name="NameOwnerChanged">
+      <arg type="s" name="name"/>
+      <arg type="s" name="old_owner"/>
+      <arg type="s" name="new_owner"/>
+    </signal>
+    <signal name="NameLost">
+      <arg type="s" name="name"/>
+    </signal>
+    <signal name="NameAcquired">
+      <arg type="s" name="name"/>
+    </signal>
+  </interface>
+</node>
diff --git a/gio/fam/gfamfilemonitor.c b/gio/fam/gfamfilemonitor.c
new file mode 100644
index 0000000..d9518a6
--- /dev/null
+++ b/gio/fam/gfamfilemonitor.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright © 2015 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include <gio/glocalfilemonitor.h>
+#include <gio/giomodule.h>
+#include "glib-private.h"
+#include <glib-unix.h>
+#include <fam.h>
+
+static GMutex         fam_lock;
+static gboolean       fam_initialised;
+static FAMConnection  fam_connection;
+static GSource       *fam_source;
+
+#define G_TYPE_FAM_FILE_MONITOR      (g_fam_file_monitor_get_type ())
+#define G_FAM_FILE_MONITOR(inst)     (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+                                      G_TYPE_FAM_FILE_MONITOR, GFamFileMonitor))
+
+typedef GLocalFileMonitorClass GFamFileMonitorClass;
+
+typedef struct
+{
+  GLocalFileMonitor parent_instance;
+
+  FAMRequest request;
+} GFamFileMonitor;
+
+static GType g_fam_file_monitor_get_type (void);
+G_DEFINE_DYNAMIC_TYPE (GFamFileMonitor, g_fam_file_monitor, G_TYPE_LOCAL_FILE_MONITOR)
+
+static gboolean
+g_fam_file_monitor_callback (gint         fd,
+                             GIOCondition condition,
+                             gpointer     user_data)
+{
+  gint64 now = g_source_get_time (fam_source);
+
+  g_mutex_lock (&fam_lock);
+
+  while (FAMPending (&fam_connection))
+    {
+      const gchar *child;
+      FAMEvent ev;
+
+      if (FAMNextEvent (&fam_connection, &ev) != 1)
+        {
+          /* The daemon died.  We're in a really bad situation now
+           * because we potentially have a bunch of request structures
+           * outstanding which no longer make any sense to anyone.
+           *
+           * The best thing that we can do is do nothing.  Notification
+           * won't work anymore for this process.
+           */
+          g_mutex_unlock (&fam_lock);
+
+          g_warning ("Lost connection to FAM (file monitoring) service.  Expect no further file monitor events.");
+
+          return FALSE;
+        }
+
+      /* We expect ev.filename to be a relative path for children in a
+       * monitored directory, and an absolute path for a monitored file
+       * or the directory itself.
+       */
+      if (ev.filename[0] != '/')
+        child = ev.filename;
+      else
+        child = NULL;
+
+      switch (ev.code)
+        {
+        case FAMAcknowledge:
+          g_source_unref (ev.userdata);
+          break;
+
+        case FAMChanged:
+          g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CHANGED, child, NULL, NULL, now);
+          break;
+
+        case FAMDeleted:
+          g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_DELETED, child, NULL, NULL, now);
+          break;
+
+        case FAMCreated:
+          g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CREATED, child, NULL, NULL, now);
+          break;
+
+        default:
+          /* unknown type */
+          break;
+        }
+    }
+
+  g_mutex_unlock (&fam_lock);
+
+  return TRUE;
+}
+
+static gboolean
+g_fam_file_monitor_is_supported (void)
+{
+  g_mutex_lock (&fam_lock);
+
+  if (!fam_initialised)
+    {
+      fam_initialised = FAMOpen2 (&fam_connection, "GLib GIO") == 0;
+
+      if (fam_initialised)
+        {
+#ifdef HAVE_FAM_NO_EXISTS
+          /* This is a gamin extension that avoids sending all the
+           * Exists event for dir monitors
+           */
+          FAMNoExists (&fam_connection);
+#endif
+
+          fam_source = g_unix_fd_source_new (FAMCONNECTION_GETFD (&fam_connection), G_IO_IN);
+          g_source_set_callback (fam_source, (GSourceFunc) g_fam_file_monitor_callback, NULL, NULL);
+          g_source_attach (fam_source, GLIB_PRIVATE_CALL(g_get_worker_context) ());
+        }
+    }
+
+  g_mutex_unlock (&fam_lock);
+
+  return fam_initialised;
+}
+
+static gboolean
+g_fam_file_monitor_cancel (GFileMonitor *monitor)
+{
+  GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (monitor);
+
+  g_mutex_lock (&fam_lock);
+
+  g_assert (fam_initialised);
+
+  FAMCancelMonitor (&fam_connection, &gffm->request);
+
+  g_mutex_unlock (&fam_lock);
+
+  return TRUE;
+}
+
+static void
+g_fam_file_monitor_start (GLocalFileMonitor  *local_monitor,
+                          const gchar        *dirname,
+                          const gchar        *basename,
+                          const gchar        *filename,
+                          GFileMonitorSource *source)
+{
+  GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (local_monitor);
+
+  g_mutex_lock (&fam_lock);
+
+  g_assert (fam_initialised);
+
+  g_source_ref ((GSource *) source);
+
+  if (dirname)
+    FAMMonitorDirectory (&fam_connection, dirname, &gffm->request, source);
+  else
+    FAMMonitorFile (&fam_connection, filename, &gffm->request, source);
+
+  g_mutex_unlock (&fam_lock);
+}
+
+static void
+g_fam_file_monitor_init (GFamFileMonitor* monitor)
+{
+}
+
+static void
+g_fam_file_monitor_class_init (GFamFileMonitorClass *class)
+{
+  GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (class);
+
+  class->is_supported = g_fam_file_monitor_is_supported;
+  class->start = g_fam_file_monitor_start;
+  file_monitor_class->cancel = g_fam_file_monitor_cancel;
+}
+
+static void
+g_fam_file_monitor_class_finalize (GFamFileMonitorClass *class)
+{
+}
+
+void
+g_io_module_load (GIOModule *module)
+{
+  g_type_module_use (G_TYPE_MODULE (module));
+
+  g_fam_file_monitor_register_type (G_TYPE_MODULE (module));
+
+  g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
+                                 G_TYPE_FAM_FILE_MONITOR, "fam", 10);
+
+  g_io_extension_point_implement (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME,
+                                 G_TYPE_FAM_FILE_MONITOR, "fam", 10);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+  g_assert_not_reached ();
+}
+
+char **
+g_io_module_query (void)
+{
+  char *eps[] = {
+    G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
+    G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME,
+    NULL
+  };
+
+  return g_strdupv (eps);
+}
diff --git a/gio/fam/gfamfilemonitor.map b/gio/fam/gfamfilemonitor.map
new file mode 100644
index 0000000..43ed5a7
--- /dev/null
+++ b/gio/fam/gfamfilemonitor.map
@@ -0,0 +1,8 @@
+{
+global:
+  g_io_module_load;
+  g_io_module_unload;
+  g_io_module_query;
+local:
+  *;
+};
diff --git a/gio/fam/meson.build b/gio/fam/meson.build
new file mode 100644
index 0000000..8019fe5
--- /dev/null
+++ b/gio/fam/meson.build
@@ -0,0 +1,36 @@
+if not get_option('fam')
+  subdir_done()
+endif
+
+fam_dep = cc.find_library('fam')
+fam_c_args = gio_c_args
+if cc.has_function('FAMNoExists', dependencies : fam_dep)
+  fam_c_args += '-DHAVE_FAM_NO_EXISTS=1'
+endif
+
+deps = [
+  fam_dep,
+  libglib_dep,
+  libgobject_dep,
+  libgio_dep,
+]
+
+symbol_map = join_paths(meson.current_source_dir(), 'gfamfilemonitor.map')
+fam_ldflags = cc.get_supported_link_arguments([
+  '-Wl,--version-script,' + symbol_map,
+  '-Wl,-no-undefined',
+])
+
+module = shared_module('giofam', 'gfamfilemonitor.c',
+  include_directories : [gmoduleinc],
+  dependencies : deps,
+  c_args : fam_c_args,
+  link_args : fam_ldflags,
+  link_depends : symbol_map,
+  install_dir : glib_giomodulesdir,
+  install : true,
+)
+
+if not meson.is_cross_build()
+  meson.add_install_script('../gio-querymodules-wrapper.py', gio_querymodules.full_path(), glib_giomodulesdir)
+endif
diff --git a/gio/gaction.c b/gio/gaction.c
new file mode 100644
index 0000000..c3748a9
--- /dev/null
+++ b/gio/gaction.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+#include "gaction.h"
+#include "glibintl.h"
+
+#include <string.h>
+
+G_DEFINE_INTERFACE (GAction, g_action, G_TYPE_OBJECT)
+
+/**
+ * SECTION:gaction
+ * @title: GAction
+ * @short_description: An action interface
+ * @include: gio/gio.h
+ *
+ * #GAction represents a single named action.
+ *
+ * The main interface to an action is that it can be activated with
+ * g_action_activate().  This results in the 'activate' signal being
+ * emitted.  An activation has a #GVariant parameter (which may be
+ * %NULL).  The correct type for the parameter is determined by a static
+ * parameter type (which is given at construction time).
+ *
+ * An action may optionally have a state, in which case the state may be
+ * set with g_action_change_state().  This call takes a #GVariant.  The
+ * correct type for the state is determined by a static state type
+ * (which is given at construction time).
+ *
+ * The state may have a hint associated with it, specifying its valid
+ * range.
+ *
+ * #GAction is merely the interface to the concept of an action, as
+ * described above.  Various implementations of actions exist, including
+ * #GSimpleAction.
+ *
+ * In all cases, the implementing class is responsible for storing the
+ * name of the action, the parameter type, the enabled state, the
+ * optional state type and the state and emitting the appropriate
+ * signals when these change.  The implementor is responsible for filtering
+ * calls to g_action_activate() and g_action_change_state() for type
+ * safety and for the state being enabled.
+ *
+ * Probably the only useful thing to do with a #GAction is to put it
+ * inside of a #GSimpleActionGroup.
+ **/
+
+/**
+ * GAction:
+ *
+ * #GAction is an opaque data structure and can only be accessed
+ * using the following functions.
+ **/
+
+/**
+ * GActionInterface:
+ * @get_name: the virtual function pointer for g_action_get_name()
+ * @get_parameter_type: the virtual function pointer for g_action_get_parameter_type()
+ * @get_state_type: the virtual function pointer for g_action_get_state_type()
+ * @get_state_hint: the virtual function pointer for g_action_get_state_hint()
+ * @get_enabled: the virtual function pointer for g_action_get_enabled()
+ * @get_state: the virtual function pointer for g_action_get_state()
+ * @change_state: the virtual function pointer for g_action_change_state()
+ * @activate: the virtual function pointer for g_action_activate().  Note that #GAction does not have an
+ *            'activate' signal but that implementations of it may have one.
+ *
+ * The virtual function table for #GAction.
+ *
+ * Since: 2.28
+ */
+
+void
+g_action_default_init (GActionInterface *iface)
+{
+  /**
+   * GAction:name:
+   *
+   * The name of the action.  This is mostly meaningful for identifying
+   * the action once it has been added to a #GActionGroup. It is immutable.
+   *
+   * Since: 2.28
+   **/
+  g_object_interface_install_property (iface,
+                                       g_param_spec_string ("name",
+                                                            P_("Action Name"),
+                                                            P_("The name used to invoke the action"),
+                                                            NULL,
+                                                            G_PARAM_READABLE |
+                                                            G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GAction:parameter-type:
+   *
+   * The type of the parameter that must be given when activating the
+   * action. This is immutable, and may be %NULL if no parameter is needed when
+   * activating the action.
+   *
+   * Since: 2.28
+   **/
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boxed ("parameter-type",
+                                                           P_("Parameter Type"),
+                                                           P_("The type of GVariant passed to activate()"),
+                                                           G_TYPE_VARIANT_TYPE,
+                                                           G_PARAM_READABLE |
+                                                           G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GAction:enabled:
+   *
+   * If @action is currently enabled.
+   *
+   * If the action is disabled then calls to g_action_activate() and
+   * g_action_change_state() have no effect.
+   *
+   * Since: 2.28
+   **/
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boolean ("enabled",
+                                                             P_("Enabled"),
+                                                             P_("If the action can be activated"),
+                                                             TRUE,
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GAction:state-type:
+   *
+   * The #GVariantType of the state that the action has, or %NULL if the
+   * action is stateless. This is immutable.
+   *
+   * Since: 2.28
+   **/
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boxed ("state-type",
+                                                           P_("State Type"),
+                                                           P_("The type of the state kept by the action"),
+                                                           G_TYPE_VARIANT_TYPE,
+                                                           G_PARAM_READABLE |
+                                                           G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GAction:state:
+   *
+   * The state of the action, or %NULL if the action is stateless.
+   *
+   * Since: 2.28
+   **/
+  g_object_interface_install_property (iface,
+                                       g_param_spec_variant ("state",
+                                                             P_("State"),
+                                                             P_("The state the action is in"),
+                                                             G_VARIANT_TYPE_ANY,
+                                                             NULL,
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * g_action_change_state:
+ * @action: a #GAction
+ * @value: the new state
+ *
+ * Request for the state of @action to be changed to @value.
+ *
+ * The action must be stateful and @value must be of the correct type.
+ * See g_action_get_state_type().
+ *
+ * This call merely requests a change.  The action may refuse to change
+ * its state or may change its state to something other than @value.
+ * See g_action_get_state_hint().
+ *
+ * If the @value GVariant is floating, it is consumed.
+ *
+ * Since: 2.30
+ **/
+void
+g_action_change_state (GAction  *action,
+                       GVariant *value)
+{
+  const GVariantType *state_type;
+
+  g_return_if_fail (G_IS_ACTION (action));
+  g_return_if_fail (value != NULL);
+  state_type = g_action_get_state_type (action);
+  g_return_if_fail (state_type != NULL);
+  g_return_if_fail (g_variant_is_of_type (value, state_type));
+
+  g_variant_ref_sink (value);
+
+  G_ACTION_GET_IFACE (action)
+    ->change_state (action, value);
+
+  g_variant_unref (value);
+}
+
+/**
+ * g_action_get_state:
+ * @action: a #GAction
+ *
+ * Queries the current state of @action.
+ *
+ * If the action is not stateful then %NULL will be returned.  If the
+ * action is stateful then the type of the return value is the type
+ * given by g_action_get_state_type().
+ *
+ * The return value (if non-%NULL) should be freed with
+ * g_variant_unref() when it is no longer required.
+ *
+ * Returns: (transfer full): the current state of the action
+ *
+ * Since: 2.28
+ **/
+GVariant *
+g_action_get_state (GAction *action)
+{
+  g_return_val_if_fail (G_IS_ACTION (action), NULL);
+
+  return G_ACTION_GET_IFACE (action)
+    ->get_state (action);
+}
+
+/**
+ * g_action_get_name:
+ * @action: a #GAction
+ *
+ * Queries the name of @action.
+ *
+ * Returns: the name of the action
+ *
+ * Since: 2.28
+ **/
+const gchar *
+g_action_get_name (GAction *action)
+{
+  g_return_val_if_fail (G_IS_ACTION (action), NULL);
+
+  return G_ACTION_GET_IFACE (action)
+    ->get_name (action);
+}
+
+/**
+ * g_action_get_parameter_type:
+ * @action: a #GAction
+ *
+ * Queries the type of the parameter that must be given when activating
+ * @action.
+ *
+ * When activating the action using g_action_activate(), the #GVariant
+ * given to that function must be of the type returned by this function.
+ *
+ * In the case that this function returns %NULL, you must not give any
+ * #GVariant, but %NULL instead.
+ *
+ * Returns: (nullable): the parameter type
+ *
+ * Since: 2.28
+ **/
+const GVariantType *
+g_action_get_parameter_type (GAction *action)
+{
+  g_return_val_if_fail (G_IS_ACTION (action), NULL);
+
+  return G_ACTION_GET_IFACE (action)
+    ->get_parameter_type (action);
+}
+
+/**
+ * g_action_get_state_type:
+ * @action: a #GAction
+ *
+ * Queries the type of the state of @action.
+ *
+ * If the action is stateful (e.g. created with
+ * g_simple_action_new_stateful()) then this function returns the
+ * #GVariantType of the state.  This is the type of the initial value
+ * given as the state. All calls to g_action_change_state() must give a
+ * #GVariant of this type and g_action_get_state() will return a
+ * #GVariant of the same type.
+ *
+ * If the action is not stateful (e.g. created with g_simple_action_new())
+ * then this function will return %NULL. In that case, g_action_get_state()
+ * will return %NULL and you must not call g_action_change_state().
+ *
+ * Returns: (nullable): the state type, if the action is stateful
+ *
+ * Since: 2.28
+ **/
+const GVariantType *
+g_action_get_state_type (GAction *action)
+{
+  g_return_val_if_fail (G_IS_ACTION (action), NULL);
+
+  return G_ACTION_GET_IFACE (action)
+    ->get_state_type (action);
+}
+
+/**
+ * g_action_get_state_hint:
+ * @action: a #GAction
+ *
+ * Requests a hint about the valid range of values for the state of
+ * @action.
+ *
+ * If %NULL is returned it either means that the action is not stateful
+ * or that there is no hint about the valid range of values for the
+ * state of the action.
+ *
+ * If a #GVariant array is returned then each item in the array is a
+ * possible value for the state.  If a #GVariant pair (ie: two-tuple) is
+ * returned then the tuple specifies the inclusive lower and upper bound
+ * of valid values for the state.
+ *
+ * In any case, the information is merely a hint.  It may be possible to
+ * have a state value outside of the hinted range and setting a value
+ * within the range may fail.
+ *
+ * The return value (if non-%NULL) should be freed with
+ * g_variant_unref() when it is no longer required.
+ *
+ * Returns: (nullable) (transfer full): the state range hint
+ *
+ * Since: 2.28
+ **/
+GVariant *
+g_action_get_state_hint (GAction *action)
+{
+  g_return_val_if_fail (G_IS_ACTION (action), NULL);
+
+  return G_ACTION_GET_IFACE (action)
+    ->get_state_hint (action);
+}
+
+/**
+ * g_action_get_enabled:
+ * @action: a #GAction
+ *
+ * Checks if @action is currently enabled.
+ *
+ * An action must be enabled in order to be activated or in order to
+ * have its state changed from outside callers.
+ *
+ * Returns: whether the action is enabled
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_action_get_enabled (GAction *action)
+{
+  g_return_val_if_fail (G_IS_ACTION (action), FALSE);
+
+  return G_ACTION_GET_IFACE (action)
+    ->get_enabled (action);
+}
+
+/**
+ * g_action_activate:
+ * @action: a #GAction
+ * @parameter: (nullable): the parameter to the activation
+ *
+ * Activates the action.
+ *
+ * @parameter must be the correct type of parameter for the action (ie:
+ * the parameter type given at construction time).  If the parameter
+ * type was %NULL then @parameter must also be %NULL.
+ *
+ * If the @parameter GVariant is floating, it is consumed.
+ *
+ * Since: 2.28
+ **/
+void
+g_action_activate (GAction  *action,
+                   GVariant *parameter)
+{
+  g_return_if_fail (G_IS_ACTION (action));
+
+  if (parameter != NULL)
+    g_variant_ref_sink (parameter);
+
+  G_ACTION_GET_IFACE (action)
+    ->activate (action, parameter);
+
+  if (parameter != NULL)
+    g_variant_unref (parameter);
+}
+
+/**
+ * g_action_name_is_valid:
+ * @action_name: a potential action name
+ *
+ * Checks if @action_name is valid.
+ *
+ * @action_name is valid if it consists only of alphanumeric characters,
+ * plus '-' and '.'.  The empty string is not a valid action name.
+ *
+ * It is an error to call this function with a non-utf8 @action_name.
+ * @action_name must not be %NULL.
+ *
+ * Returns: %TRUE if @action_name is valid
+ *
+ * Since: 2.38
+ **/
+gboolean
+g_action_name_is_valid (const gchar *action_name)
+{
+  gchar c;
+  gint i;
+
+  g_return_val_if_fail (action_name != NULL, FALSE);
+
+  for (i = 0; (c = action_name[i]); i++)
+    if (!g_ascii_isalnum (c) && c != '.' && c != '-')
+      return FALSE;
+
+  return i > 0;
+}
+
+/**
+ * g_action_parse_detailed_name:
+ * @detailed_name: a detailed action name
+ * @action_name: (out): the action name
+ * @target_value: (out): the target value, or %NULL for no target
+ * @error: a pointer to a %NULL #GError, or %NULL
+ *
+ * Parses a detailed action name into its separate name and target
+ * components.
+ *
+ * Detailed action names can have three formats.
+ *
+ * The first format is used to represent an action name with no target
+ * value and consists of just an action name containing no whitespace
+ * nor the characters ':', '(' or ')'.  For example: "app.action".
+ *
+ * The second format is used to represent an action with a target value
+ * that is a non-empty string consisting only of alphanumerics, plus '-'
+ * and '.'.  In that case, the action name and target value are
+ * separated by a double colon ("::").  For example:
+ * "app.action::target".
+ *
+ * The third format is used to represent an action with any type of
+ * target value, including strings.  The target value follows the action
+ * name, surrounded in parens.  For example: "app.action(42)".  The
+ * target value is parsed using g_variant_parse().  If a tuple-typed
+ * value is desired, it must be specified in the same way, resulting in
+ * two sets of parens, for example: "app.action((1,2,3))".  A string
+ * target can be specified this way as well: "app.action('target')".
+ * For strings, this third format must be used if * target value is
+ * empty or contains characters other than alphanumerics, '-' and '.'.
+ *
+ * Returns: %TRUE if successful, else %FALSE with @error set
+ *
+ * Since: 2.38
+ **/
+gboolean
+g_action_parse_detailed_name (const gchar  *detailed_name,
+                              gchar       **action_name,
+                              GVariant    **target_value,
+                              GError      **error)
+{
+  const gchar *target;
+  gsize target_len;
+  gsize base_len;
+
+  /* For historical (compatibility) reasons, this function accepts some
+   * cases of invalid action names as long as they don't interfere with
+   * the separation of the action from the target value.
+   *
+   * We decide which format we have based on which we see first between
+   * '::' '(' and '\0'.
+   */
+
+  if (*detailed_name == '\0' || *detailed_name == ' ')
+    goto bad_fmt;
+
+  base_len = strcspn (detailed_name, ": ()");
+  target = detailed_name + base_len;
+  target_len = strlen (target);
+
+  switch (target[0])
+    {
+    case ' ':
+    case ')':
+      goto bad_fmt;
+
+    case ':':
+      if (target[1] != ':')
+        goto bad_fmt;
+
+      *target_value = g_variant_ref_sink (g_variant_new_string (target + 2));
+      break;
+
+    case '(':
+      {
+        if (target[target_len - 1] != ')')
+          goto bad_fmt;
+
+        *target_value = g_variant_parse (NULL, target + 1, target + target_len - 1, NULL, error);
+        if (*target_value == NULL)
+          goto bad_fmt;
+      }
+      break;
+
+    case '\0':
+      *target_value = NULL;
+      break;
+    }
+
+  *action_name = g_strndup (detailed_name, base_len);
+
+  return TRUE;
+
+bad_fmt:
+  if (error)
+    {
+      if (*error == NULL)
+        g_set_error (error, G_VARIANT_PARSE_ERROR, G_VARIANT_PARSE_ERROR_FAILED,
+                     "Detailed action name '%s' has invalid format", detailed_name);
+      else
+        g_prefix_error (error, "Detailed action name '%s' has invalid format: ", detailed_name);
+    }
+
+  return FALSE;
+}
+
+/**
+ * g_action_print_detailed_name:
+ * @action_name: a valid action name
+ * @target_value: (nullable): a #GVariant target value, or %NULL
+ *
+ * Formats a detailed action name from @action_name and @target_value.
+ *
+ * It is an error to call this function with an invalid action name.
+ *
+ * This function is the opposite of g_action_parse_detailed_name().
+ * It will produce a string that can be parsed back to the @action_name
+ * and @target_value by that function.
+ *
+ * See that function for the types of strings that will be printed by
+ * this function.
+ *
+ * Returns: a detailed format string
+ *
+ * Since: 2.38
+ **/
+gchar *
+g_action_print_detailed_name (const gchar *action_name,
+                              GVariant    *target_value)
+{
+  g_return_val_if_fail (g_action_name_is_valid (action_name), NULL);
+
+  if (target_value == NULL)
+    return g_strdup (action_name);
+
+  if (g_variant_is_of_type (target_value, G_VARIANT_TYPE_STRING))
+    {
+      const gchar *str = g_variant_get_string (target_value, NULL);
+
+      if (g_action_name_is_valid (str))
+        return g_strconcat (action_name, "::", str, NULL);
+    }
+
+  {
+    GString *result = g_string_new (action_name);
+    g_string_append_c (result, '(');
+    g_variant_print_string (target_value, result, TRUE);
+    g_string_append_c (result, ')');
+
+    return g_string_free (result, FALSE);
+  }
+}
diff --git a/gio/gaction.h b/gio/gaction.h
new file mode 100644
index 0000000..f9f4b38
--- /dev/null
+++ b/gio/gaction.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_ACTION_H__
+#define __G_ACTION_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_ACTION                                       (g_action_get_type ())
+#define G_ACTION(inst)                                      (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
+                                                             G_TYPE_ACTION, GAction))
+#define G_IS_ACTION(inst)                                   (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_ACTION))
+#define G_ACTION_GET_IFACE(inst)                            (G_TYPE_INSTANCE_GET_INTERFACE ((inst),                  \
+                                                             G_TYPE_ACTION, GActionInterface))
+
+typedef struct _GActionInterface                            GActionInterface;
+
+struct _GActionInterface
+{
+  GTypeInterface g_iface;
+
+  /* virtual functions */
+  const gchar *        (* get_name)             (GAction  *action);
+  const GVariantType * (* get_parameter_type)   (GAction  *action);
+  const GVariantType * (* get_state_type)       (GAction  *action);
+  GVariant *           (* get_state_hint)       (GAction  *action);
+
+  gboolean             (* get_enabled)          (GAction  *action);
+  GVariant *           (* get_state)            (GAction  *action);
+
+  void                 (* change_state)         (GAction  *action,
+                                                 GVariant *value);
+  void                 (* activate)             (GAction  *action,
+                                                 GVariant *parameter);
+};
+
+GLIB_AVAILABLE_IN_2_30
+GType                   g_action_get_type                               (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+const gchar *           g_action_get_name                               (GAction            *action);
+GLIB_AVAILABLE_IN_ALL
+const GVariantType *    g_action_get_parameter_type                     (GAction            *action);
+GLIB_AVAILABLE_IN_ALL
+const GVariantType *    g_action_get_state_type                         (GAction            *action);
+GLIB_AVAILABLE_IN_ALL
+GVariant *              g_action_get_state_hint                         (GAction            *action);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_action_get_enabled                            (GAction            *action);
+GLIB_AVAILABLE_IN_ALL
+GVariant *              g_action_get_state                              (GAction            *action);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_change_state                           (GAction            *action,
+                                                                         GVariant           *value);
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_activate                               (GAction            *action,
+                                                                         GVariant           *parameter);
+
+GLIB_AVAILABLE_IN_2_28
+gboolean                g_action_name_is_valid                          (const gchar        *action_name);
+
+GLIB_AVAILABLE_IN_2_38
+gboolean                g_action_parse_detailed_name                    (const gchar        *detailed_name,
+                                                                         gchar             **action_name,
+                                                                         GVariant          **target_value,
+                                                                         GError            **error);
+
+GLIB_AVAILABLE_IN_2_38
+gchar *                 g_action_print_detailed_name                    (const gchar        *action_name,
+                                                                         GVariant           *target_value);
+
+G_END_DECLS
+
+#endif /* __G_ACTION_H__ */
diff --git a/gio/gactiongroup.c b/gio/gactiongroup.c
new file mode 100644
index 0000000..24da353
--- /dev/null
+++ b/gio/gactiongroup.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+#include "gactiongroup.h"
+#include "gaction.h"
+#include "glibintl.h"
+#include "gmarshal-internal.h"
+
+/**
+ * SECTION:gactiongroup
+ * @title: GActionGroup
+ * @short_description: A group of actions
+ * @include: gio/gio.h
+ * @see_also: #GAction
+ *
+ * #GActionGroup represents a group of actions. Actions can be used to
+ * expose functionality in a structured way, either from one part of a
+ * program to another, or to the outside world. Action groups are often
+ * used together with a #GMenuModel that provides additional
+ * representation data for displaying the actions to the user, e.g. in
+ * a menu.
+ *
+ * The main way to interact with the actions in a GActionGroup is to
+ * activate them with g_action_group_activate_action(). Activating an
+ * action may require a #GVariant parameter. The required type of the
+ * parameter can be inquired with g_action_group_get_action_parameter_type().
+ * Actions may be disabled, see g_action_group_get_action_enabled().
+ * Activating a disabled action has no effect.
+ *
+ * Actions may optionally have a state in the form of a #GVariant. The
+ * current state of an action can be inquired with
+ * g_action_group_get_action_state(). Activating a stateful action may
+ * change its state, but it is also possible to set the state by calling
+ * g_action_group_change_action_state().
+ *
+ * As typical example, consider a text editing application which has an
+ * option to change the current font to 'bold'. A good way to represent
+ * this would be a stateful action, with a boolean state. Activating the
+ * action would toggle the state.
+ *
+ * Each action in the group has a unique name (which is a string).  All
+ * method calls, except g_action_group_list_actions() take the name of
+ * an action as an argument.
+ *
+ * The #GActionGroup API is meant to be the 'public' API to the action
+ * group.  The calls here are exactly the interaction that 'external
+ * forces' (eg: UI, incoming D-Bus messages, etc.) are supposed to have
+ * with actions.  'Internal' APIs (ie: ones meant only to be accessed by
+ * the action group implementation) are found on subclasses.  This is
+ * why you will find - for example - g_action_group_get_action_enabled()
+ * but not an equivalent set() call.
+ *
+ * Signals are emitted on the action group in response to state changes
+ * on individual actions.
+ *
+ * Implementations of #GActionGroup should provide implementations for
+ * the virtual functions g_action_group_list_actions() and
+ * g_action_group_query_action().  The other virtual functions should
+ * not be implemented - their "wrappers" are actually implemented with
+ * calls to g_action_group_query_action().
+ */
+
+/**
+ * GActionGroup:
+ *
+ * #GActionGroup is an opaque data structure and can only be accessed
+ * using the following functions.
+ **/
+
+/**
+ * GActionGroupInterface:
+ * @has_action: the virtual function pointer for g_action_group_has_action()
+ * @list_actions: the virtual function pointer for g_action_group_list_actions()
+ * @get_action_parameter_type: the virtual function pointer for g_action_group_get_action_parameter_type()
+ * @get_action_state_type: the virtual function pointer for g_action_group_get_action_state_type()
+ * @get_action_state_hint: the virtual function pointer for g_action_group_get_action_state_hint()
+ * @get_action_enabled: the virtual function pointer for g_action_group_get_action_enabled()
+ * @get_action_state: the virtual function pointer for g_action_group_get_action_state()
+ * @change_action_state: the virtual function pointer for g_action_group_change_action_state()
+ * @query_action: the virtual function pointer for g_action_group_query_action()
+ * @activate_action: the virtual function pointer for g_action_group_activate_action()
+ * @change_action_state: the virtual function pointer for g_action_group_change_action_state()
+ * @action_added: the class closure for the #GActionGroup::action-added signal
+ * @action_removed: the class closure for the #GActionGroup::action-removed signal
+ * @action_enabled_changed: the class closure for the #GActionGroup::action-enabled-changed signal
+ * @action_state_changed: the class closure for the #GActionGroup::action-enabled-changed signal
+ *
+ * The virtual function table for #GActionGroup.
+ *
+ * Since: 2.28
+ **/
+
+G_DEFINE_INTERFACE (GActionGroup, g_action_group, G_TYPE_OBJECT)
+
+enum
+{
+  SIGNAL_ACTION_ADDED,
+  SIGNAL_ACTION_REMOVED,
+  SIGNAL_ACTION_ENABLED_CHANGED,
+  SIGNAL_ACTION_STATE_CHANGED,
+  NR_SIGNALS
+};
+
+static guint g_action_group_signals[NR_SIGNALS];
+
+static gboolean
+g_action_group_real_has_action (GActionGroup *action_group,
+                                const gchar  *action_name)
+{
+  return g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, NULL);
+}
+
+static gboolean
+g_action_group_real_get_action_enabled (GActionGroup *action_group,
+                                        const gchar  *action_name)
+{
+  gboolean enabled = FALSE;
+
+  g_action_group_query_action (action_group, action_name, &enabled, NULL, NULL, NULL, NULL);
+
+  return enabled;
+}
+
+static const GVariantType *
+g_action_group_real_get_action_parameter_type (GActionGroup *action_group,
+                                               const gchar  *action_name)
+{
+  const GVariantType *type = NULL;
+
+  g_action_group_query_action (action_group, action_name, NULL, &type, NULL, NULL, NULL);
+
+  return type;
+}
+
+static const GVariantType *
+g_action_group_real_get_action_state_type (GActionGroup *action_group,
+                                           const gchar  *action_name)
+{
+  const GVariantType *type = NULL;
+
+  g_action_group_query_action (action_group, action_name, NULL, NULL, &type, NULL, NULL);
+
+  return type;
+}
+
+static GVariant *
+g_action_group_real_get_action_state_hint (GActionGroup *action_group,
+                                           const gchar  *action_name)
+{
+  GVariant *hint = NULL;
+
+  g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, &hint, NULL);
+
+  return hint;
+}
+
+static GVariant *
+g_action_group_real_get_action_state (GActionGroup *action_group,
+                                      const gchar  *action_name)
+{
+  GVariant *state = NULL;
+
+  g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, &state);
+
+  return state;
+}
+
+static gboolean
+g_action_group_real_query_action (GActionGroup        *action_group,
+                                  const gchar         *action_name,
+                                  gboolean            *enabled,
+                                  const GVariantType **parameter_type,
+                                  const GVariantType **state_type,
+                                  GVariant           **state_hint,
+                                  GVariant           **state)
+{
+  GActionGroupInterface *iface = G_ACTION_GROUP_GET_IFACE (action_group);
+
+  /* we expect implementations to override this method, but we also
+   * allow for implementations that existed before this method was
+   * introduced to override the individual accessors instead.
+   *
+   * detect the case that neither has happened and report it.
+   */
+  if G_UNLIKELY (iface->has_action == g_action_group_real_has_action ||
+                 iface->get_action_enabled == g_action_group_real_get_action_enabled ||
+                 iface->get_action_parameter_type == g_action_group_real_get_action_parameter_type ||
+                 iface->get_action_state_type == g_action_group_real_get_action_state_type ||
+                 iface->get_action_state_hint == g_action_group_real_get_action_state_hint ||
+                 iface->get_action_state == g_action_group_real_get_action_state)
+    {
+      g_critical ("Class '%s' implements GActionGroup interface without overriding "
+                  "query_action() method -- bailing out to avoid infinite recursion.",
+                  G_OBJECT_TYPE_NAME (action_group));
+      return FALSE;
+    }
+
+  if (!(* iface->has_action) (action_group, action_name))
+    return FALSE;
+
+  if (enabled != NULL)
+    *enabled = (* iface->get_action_enabled) (action_group, action_name);
+
+  if (parameter_type != NULL)
+    *parameter_type = (* iface->get_action_parameter_type) (action_group, action_name);
+
+  if (state_type != NULL)
+    *state_type = (* iface->get_action_state_type) (action_group, action_name);
+
+  if (state_hint != NULL)
+    *state_hint = (* iface->get_action_state_hint) (action_group, action_name);
+
+  if (state != NULL)
+    *state = (* iface->get_action_state) (action_group, action_name);
+
+  return TRUE;
+}
+
+static void
+g_action_group_default_init (GActionGroupInterface *iface)
+{
+  iface->has_action = g_action_group_real_has_action;
+  iface->get_action_enabled = g_action_group_real_get_action_enabled;
+  iface->get_action_parameter_type = g_action_group_real_get_action_parameter_type;
+  iface->get_action_state_type = g_action_group_real_get_action_state_type;
+  iface->get_action_state_hint = g_action_group_real_get_action_state_hint;
+  iface->get_action_state = g_action_group_real_get_action_state;
+  iface->query_action = g_action_group_real_query_action;
+
+  /**
+   * GActionGroup::action-added:
+   * @action_group: the #GActionGroup that changed
+   * @action_name: the name of the action in @action_group
+   *
+   * Signals that a new action was just added to the group.
+   * This signal is emitted after the action has been added
+   * and is now visible.
+   *
+   * Since: 2.28
+   **/
+  g_action_group_signals[SIGNAL_ACTION_ADDED] =
+    g_signal_new (I_("action-added"),
+                  G_TYPE_ACTION_GROUP,
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+                  G_STRUCT_OFFSET (GActionGroupInterface, action_added),
+                  NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_STRING);
+
+  /**
+   * GActionGroup::action-removed:
+   * @action_group: the #GActionGroup that changed
+   * @action_name: the name of the action in @action_group
+   *
+   * Signals that an action is just about to be removed from the group.
+   * This signal is emitted before the action is removed, so the action
+   * is still visible and can be queried from the signal handler.
+   *
+   * Since: 2.28
+   **/
+  g_action_group_signals[SIGNAL_ACTION_REMOVED] =
+    g_signal_new (I_("action-removed"),
+                  G_TYPE_ACTION_GROUP,
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+                  G_STRUCT_OFFSET (GActionGroupInterface, action_removed),
+                  NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_STRING);
+
+
+  /**
+   * GActionGroup::action-enabled-changed:
+   * @action_group: the #GActionGroup that changed
+   * @action_name: the name of the action in @action_group
+   * @enabled: whether the action is enabled or not
+   *
+   * Signals that the enabled status of the named action has changed.
+   *
+   * Since: 2.28
+   **/
+  g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED] =
+    g_signal_new (I_("action-enabled-changed"),
+                  G_TYPE_ACTION_GROUP,
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+                  G_STRUCT_OFFSET (GActionGroupInterface,
+                                   action_enabled_changed),
+                  NULL, NULL,
+                  _g_cclosure_marshal_VOID__STRING_BOOLEAN,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_STRING,
+                  G_TYPE_BOOLEAN);
+  g_signal_set_va_marshaller (g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED],
+                              G_TYPE_FROM_INTERFACE (iface),
+                              _g_cclosure_marshal_VOID__STRING_BOOLEANv);
+
+  /**
+   * GActionGroup::action-state-changed:
+   * @action_group: the #GActionGroup that changed
+   * @action_name: the name of the action in @action_group
+   * @value: the new value of the state
+   *
+   * Signals that the state of the named action has changed.
+   *
+   * Since: 2.28
+   **/
+  g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED] =
+    g_signal_new (I_("action-state-changed"),
+                  G_TYPE_ACTION_GROUP,
+                  G_SIGNAL_RUN_LAST |
+                  G_SIGNAL_DETAILED |
+                  G_SIGNAL_MUST_COLLECT,
+                  G_STRUCT_OFFSET (GActionGroupInterface,
+                                   action_state_changed),
+                  NULL, NULL,
+                  _g_cclosure_marshal_VOID__STRING_VARIANT,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_STRING,
+                  G_TYPE_VARIANT);
+  g_signal_set_va_marshaller (g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED],
+                              G_TYPE_FROM_INTERFACE (iface),
+                              _g_cclosure_marshal_VOID__STRING_VARIANTv);
+}
+
+/**
+ * g_action_group_list_actions:
+ * @action_group: a #GActionGroup
+ *
+ * Lists the actions contained within @action_group.
+ *
+ * The caller is responsible for freeing the list with g_strfreev() when
+ * it is no longer required.
+ *
+ * Returns: (transfer full): a %NULL-terminated array of the names of the
+ * actions in the group
+ *
+ * Since: 2.28
+ **/
+gchar **
+g_action_group_list_actions (GActionGroup *action_group)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->list_actions (action_group);
+}
+
+/**
+ * g_action_group_has_action:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to check for
+ *
+ * Checks if the named action exists within @action_group.
+ *
+ * Returns: whether the named action exists
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_action_group_has_action (GActionGroup *action_group,
+                           const gchar  *action_name)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->has_action (action_group, action_name);
+}
+
+/**
+ * g_action_group_get_action_parameter_type:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to query
+ *
+ * Queries the type of the parameter that must be given when activating
+ * the named action within @action_group.
+ *
+ * When activating the action using g_action_group_activate_action(),
+ * the #GVariant given to that function must be of the type returned
+ * by this function.
+ *
+ * In the case that this function returns %NULL, you must not give any
+ * #GVariant, but %NULL instead.
+ *
+ * The parameter type of a particular action will never change but it is
+ * possible for an action to be removed and for a new action to be added
+ * with the same name but a different parameter type.
+ *
+ * Returns: (nullable): the parameter type
+ *
+ * Since: 2.28
+ **/
+const GVariantType *
+g_action_group_get_action_parameter_type (GActionGroup *action_group,
+                                          const gchar  *action_name)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_action_parameter_type (action_group, action_name);
+}
+
+/**
+ * g_action_group_get_action_state_type:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to query
+ *
+ * Queries the type of the state of the named action within
+ * @action_group.
+ *
+ * If the action is stateful then this function returns the
+ * #GVariantType of the state.  All calls to
+ * g_action_group_change_action_state() must give a #GVariant of this
+ * type and g_action_group_get_action_state() will return a #GVariant
+ * of the same type.
+ *
+ * If the action is not stateful then this function will return %NULL.
+ * In that case, g_action_group_get_action_state() will return %NULL
+ * and you must not call g_action_group_change_action_state().
+ *
+ * The state type of a particular action will never change but it is
+ * possible for an action to be removed and for a new action to be added
+ * with the same name but a different state type.
+ *
+ * Returns: (nullable): the state type, if the action is stateful
+ *
+ * Since: 2.28
+ **/
+const GVariantType *
+g_action_group_get_action_state_type (GActionGroup *action_group,
+                                      const gchar  *action_name)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_action_state_type (action_group, action_name);
+}
+
+/**
+ * g_action_group_get_action_state_hint:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to query
+ *
+ * Requests a hint about the valid range of values for the state of the
+ * named action within @action_group.
+ *
+ * If %NULL is returned it either means that the action is not stateful
+ * or that there is no hint about the valid range of values for the
+ * state of the action.
+ *
+ * If a #GVariant array is returned then each item in the array is a
+ * possible value for the state.  If a #GVariant pair (ie: two-tuple) is
+ * returned then the tuple specifies the inclusive lower and upper bound
+ * of valid values for the state.
+ *
+ * In any case, the information is merely a hint.  It may be possible to
+ * have a state value outside of the hinted range and setting a value
+ * within the range may fail.
+ *
+ * The return value (if non-%NULL) should be freed with
+ * g_variant_unref() when it is no longer required.
+ *
+ * Returns: (nullable) (transfer full): the state range hint
+ *
+ * Since: 2.28
+ **/
+GVariant *
+g_action_group_get_action_state_hint (GActionGroup *action_group,
+                                      const gchar  *action_name)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_action_state_hint (action_group, action_name);
+}
+
+/**
+ * g_action_group_get_action_enabled:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to query
+ *
+ * Checks if the named action within @action_group is currently enabled.
+ *
+ * An action must be enabled in order to be activated or in order to
+ * have its state changed from outside callers.
+ *
+ * Returns: whether or not the action is currently enabled
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_action_group_get_action_enabled (GActionGroup *action_group,
+                                   const gchar  *action_name)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_action_enabled (action_group, action_name);
+}
+
+/**
+ * g_action_group_get_action_state:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to query
+ *
+ * Queries the current state of the named action within @action_group.
+ *
+ * If the action is not stateful then %NULL will be returned.  If the
+ * action is stateful then the type of the return value is the type
+ * given by g_action_group_get_action_state_type().
+ *
+ * The return value (if non-%NULL) should be freed with
+ * g_variant_unref() when it is no longer required.
+ *
+ * Returns: (nullable) (transfer full): the current state of the action
+ *
+ * Since: 2.28
+ **/
+GVariant *
+g_action_group_get_action_state (GActionGroup *action_group,
+                                 const gchar  *action_name)
+{
+  g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
+
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_action_state (action_group, action_name);
+}
+
+/**
+ * g_action_group_change_action_state:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to request the change on
+ * @value: the new state
+ *
+ * Request for the state of the named action within @action_group to be
+ * changed to @value.
+ *
+ * The action must be stateful and @value must be of the correct type.
+ * See g_action_group_get_action_state_type().
+ *
+ * This call merely requests a change.  The action may refuse to change
+ * its state or may change its state to something other than @value.
+ * See g_action_group_get_action_state_hint().
+ *
+ * If the @value GVariant is floating, it is consumed.
+ *
+ * Since: 2.28
+ **/
+void
+g_action_group_change_action_state (GActionGroup *action_group,
+                                    const gchar  *action_name,
+                                    GVariant     *value)
+{
+  g_return_if_fail (G_IS_ACTION_GROUP (action_group));
+  g_return_if_fail (action_name != NULL);
+  g_return_if_fail (value != NULL);
+
+  G_ACTION_GROUP_GET_IFACE (action_group)
+    ->change_action_state (action_group, action_name, value);
+}
+
+/**
+ * g_action_group_activate_action:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of the action to activate
+ * @parameter: (nullable): parameters to the activation
+ *
+ * Activate the named action within @action_group.
+ *
+ * If the action is expecting a parameter, then the correct type of
+ * parameter must be given as @parameter.  If the action is expecting no
+ * parameters then @parameter must be %NULL.  See
+ * g_action_group_get_action_parameter_type().
+ *
+ * Since: 2.28
+ **/
+void
+g_action_group_activate_action (GActionGroup *action_group,
+                                const gchar  *action_name,
+                                GVariant     *parameter)
+{
+  g_return_if_fail (G_IS_ACTION_GROUP (action_group));
+  g_return_if_fail (action_name != NULL);
+
+  G_ACTION_GROUP_GET_IFACE (action_group)
+    ->activate_action (action_group, action_name, parameter);
+}
+
+/**
+ * g_action_group_action_added:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of an action in the group
+ *
+ * Emits the #GActionGroup::action-added signal on @action_group.
+ *
+ * This function should only be called by #GActionGroup implementations.
+ *
+ * Since: 2.28
+ **/
+void
+g_action_group_action_added (GActionGroup *action_group,
+                             const gchar  *action_name)
+{
+  g_return_if_fail (G_IS_ACTION_GROUP (action_group));
+  g_return_if_fail (action_name != NULL);
+
+  g_signal_emit (action_group,
+                 g_action_group_signals[SIGNAL_ACTION_ADDED],
+                 g_quark_try_string (action_name),
+                 action_name);
+}
+
+/**
+ * g_action_group_action_removed:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of an action in the group
+ *
+ * Emits the #GActionGroup::action-removed signal on @action_group.
+ *
+ * This function should only be called by #GActionGroup implementations.
+ *
+ * Since: 2.28
+ **/
+void
+g_action_group_action_removed (GActionGroup *action_group,
+                               const gchar  *action_name)
+{
+  g_return_if_fail (G_IS_ACTION_GROUP (action_group));
+  g_return_if_fail (action_name != NULL);
+
+  g_signal_emit (action_group,
+                 g_action_group_signals[SIGNAL_ACTION_REMOVED],
+                 g_quark_try_string (action_name),
+                 action_name);
+}
+
+/**
+ * g_action_group_action_enabled_changed:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of an action in the group
+ * @enabled: whether or not the action is now enabled
+ *
+ * Emits the #GActionGroup::action-enabled-changed signal on @action_group.
+ *
+ * This function should only be called by #GActionGroup implementations.
+ *
+ * Since: 2.28
+ **/
+void
+g_action_group_action_enabled_changed (GActionGroup *action_group,
+                                       const gchar  *action_name,
+                                       gboolean      enabled)
+{
+  g_return_if_fail (G_IS_ACTION_GROUP (action_group));
+  g_return_if_fail (action_name != NULL);
+
+  enabled = !!enabled;
+
+  g_signal_emit (action_group,
+                 g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED],
+                 g_quark_try_string (action_name),
+                 action_name,
+                 enabled);
+}
+
+/**
+ * g_action_group_action_state_changed:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of an action in the group
+ * @state: the new state of the named action
+ *
+ * Emits the #GActionGroup::action-state-changed signal on @action_group.
+ *
+ * This function should only be called by #GActionGroup implementations.
+ *
+ * Since: 2.28
+ **/
+void
+g_action_group_action_state_changed (GActionGroup *action_group,
+                                     const gchar  *action_name,
+                                     GVariant     *state)
+{
+  g_return_if_fail (G_IS_ACTION_GROUP (action_group));
+  g_return_if_fail (action_name != NULL);
+
+  g_signal_emit (action_group,
+                 g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED],
+                 g_quark_try_string (action_name),
+                 action_name,
+                 state);
+}
+
+/**
+ * g_action_group_query_action:
+ * @action_group: a #GActionGroup
+ * @action_name: the name of an action in the group
+ * @enabled: (out): if the action is presently enabled
+ * @parameter_type: (out) (optional): the parameter type, or %NULL if none needed
+ * @state_type: (out) (optional): the state type, or %NULL if stateless
+ * @state_hint: (out) (optional): the state hint, or %NULL if none
+ * @state: (out) (optional): the current state, or %NULL if stateless
+ *
+ * Queries all aspects of the named action within an @action_group.
+ *
+ * This function acquires the information available from
+ * g_action_group_has_action(), g_action_group_get_action_enabled(),
+ * g_action_group_get_action_parameter_type(),
+ * g_action_group_get_action_state_type(),
+ * g_action_group_get_action_state_hint() and
+ * g_action_group_get_action_state() with a single function call.
+ *
+ * This provides two main benefits.
+ *
+ * The first is the improvement in efficiency that comes with not having
+ * to perform repeated lookups of the action in order to discover
+ * different things about it.  The second is that implementing
+ * #GActionGroup can now be done by only overriding this one virtual
+ * function.
+ *
+ * The interface provides a default implementation of this function that
+ * calls the individual functions, as required, to fetch the
+ * information.  The interface also provides default implementations of
+ * those functions that call this function.  All implementations,
+ * therefore, must override either this function or all of the others.
+ *
+ * If the action exists, %TRUE is returned and any of the requested
+ * fields (as indicated by having a non-%NULL reference passed in) are
+ * filled.  If the action doesn't exist, %FALSE is returned and the
+ * fields may or may not have been modified.
+ *
+ * Returns: %TRUE if the action exists, else %FALSE
+ *
+ * Since: 2.32
+ **/
+gboolean
+g_action_group_query_action (GActionGroup        *action_group,
+                             const gchar         *action_name,
+                             gboolean            *enabled,
+                             const GVariantType **parameter_type,
+                             const GVariantType **state_type,
+                             GVariant           **state_hint,
+                             GVariant           **state)
+{
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->query_action (action_group, action_name, enabled, parameter_type, state_type, state_hint, state);
+}
diff --git a/gio/gactiongroup.h b/gio/gactiongroup.h
new file mode 100644
index 0000000..bba8a23
--- /dev/null
+++ b/gio/gactiongroup.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_ACTION_GROUP_H__
+#define __G_ACTION_GROUP_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+
+#define G_TYPE_ACTION_GROUP                                 (g_action_group_get_type ())
+#define G_ACTION_GROUP(inst)                                (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
+                                                             G_TYPE_ACTION_GROUP, GActionGroup))
+#define G_IS_ACTION_GROUP(inst)                             (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
+                                                             G_TYPE_ACTION_GROUP))
+#define G_ACTION_GROUP_GET_IFACE(inst)                      (G_TYPE_INSTANCE_GET_INTERFACE ((inst),                  \
+                                                             G_TYPE_ACTION_GROUP, GActionGroupInterface))
+
+typedef struct _GActionGroupInterface                       GActionGroupInterface;
+
+struct _GActionGroupInterface
+{
+  GTypeInterface g_iface;
+
+  /* virtual functions */
+  gboolean              (* has_action)                 (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+
+  gchar **              (* list_actions)               (GActionGroup  *action_group);
+
+  gboolean              (* get_action_enabled)         (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+
+  const GVariantType *  (* get_action_parameter_type)  (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+
+  const GVariantType *  (* get_action_state_type)      (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+
+  GVariant *            (* get_action_state_hint)      (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+
+  GVariant *            (* get_action_state)           (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+
+  void                  (* change_action_state)        (GActionGroup  *action_group,
+                                                        const gchar   *action_name,
+                                                        GVariant      *value);
+
+  void                  (* activate_action)            (GActionGroup  *action_group,
+                                                        const gchar   *action_name,
+                                                        GVariant      *parameter);
+
+  /* signals */
+  void                  (* action_added)               (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+  void                  (* action_removed)             (GActionGroup  *action_group,
+                                                        const gchar   *action_name);
+  void                  (* action_enabled_changed)     (GActionGroup  *action_group,
+                                                        const gchar   *action_name,
+                                                        gboolean       enabled);
+  void                  (* action_state_changed)       (GActionGroup   *action_group,
+                                                        const gchar    *action_name,
+                                                        GVariant       *state);
+
+  /* more virtual functions */
+  gboolean              (* query_action)               (GActionGroup        *action_group,
+                                                        const gchar         *action_name,
+                                                        gboolean            *enabled,
+                                                        const GVariantType **parameter_type,
+                                                        const GVariantType **state_type,
+                                                        GVariant           **state_hint,
+                                                        GVariant           **state);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType                   g_action_group_get_type                         (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_action_group_has_action                       (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+GLIB_AVAILABLE_IN_ALL
+gchar **                g_action_group_list_actions                     (GActionGroup *action_group);
+
+GLIB_AVAILABLE_IN_ALL
+const GVariantType *    g_action_group_get_action_parameter_type        (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+GLIB_AVAILABLE_IN_ALL
+const GVariantType *    g_action_group_get_action_state_type            (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+GLIB_AVAILABLE_IN_ALL
+GVariant *              g_action_group_get_action_state_hint            (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_action_group_get_action_enabled               (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+
+GLIB_AVAILABLE_IN_ALL
+GVariant *              g_action_group_get_action_state                 (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_group_change_action_state              (GActionGroup *action_group,
+                                                                         const gchar  *action_name,
+                                                                         GVariant     *value);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_group_activate_action                  (GActionGroup *action_group,
+                                                                         const gchar  *action_name,
+                                                                         GVariant     *parameter);
+
+/* signals */
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_group_action_added                     (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_group_action_removed                   (GActionGroup *action_group,
+                                                                         const gchar  *action_name);
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_group_action_enabled_changed           (GActionGroup *action_group,
+                                                                         const gchar  *action_name,
+                                                                         gboolean      enabled);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_action_group_action_state_changed             (GActionGroup *action_group,
+                                                                         const gchar  *action_name,
+                                                                         GVariant     *state);
+
+GLIB_AVAILABLE_IN_2_32
+gboolean                g_action_group_query_action                     (GActionGroup        *action_group,
+                                                                         const gchar         *action_name,
+                                                                         gboolean            *enabled,
+                                                                         const GVariantType **parameter_type,
+                                                                         const GVariantType **state_type,
+                                                                         GVariant           **state_hint,
+                                                                         GVariant           **state);
+
+G_END_DECLS
+
+#endif /* __G_ACTION_GROUP_H__ */
diff --git a/gio/gactiongroupexporter.c b/gio/gactiongroupexporter.c
new file mode 100644
index 0000000..17111ff
--- /dev/null
+++ b/gio/gactiongroupexporter.c
@@ -0,0 +1,608 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2011 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gactiongroupexporter.h"
+
+#include "gdbusmethodinvocation.h"
+#include "gremoteactiongroup.h"
+#include "gdbusintrospection.h"
+#include "gdbusconnection.h"
+#include "gactiongroup.h"
+#include "gdbuserror.h"
+
+/**
+ * SECTION:gactiongroupexporter
+ * @title: GActionGroup exporter
+ * @include: gio/gio.h
+ * @short_description: Export GActionGroups on D-Bus
+ * @see_also: #GActionGroup, #GDBusActionGroup
+ *
+ * These functions support exporting a #GActionGroup on D-Bus.
+ * The D-Bus interface that is used is a private implementation
+ * detail.
+ *
+ * To access an exported #GActionGroup remotely, use
+ * g_dbus_action_group_get() to obtain a #GDBusActionGroup.
+ */
+
+static GVariant *
+g_action_group_describe_action (GActionGroup *action_group,
+                                const gchar  *name)
+{
+  const GVariantType *type;
+  GVariantBuilder builder;
+  gboolean enabled;
+  GVariant *state;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(bgav)"));
+
+  enabled = g_action_group_get_action_enabled (action_group, name);
+  g_variant_builder_add (&builder, "b", enabled);
+
+  if ((type = g_action_group_get_action_parameter_type (action_group, name)))
+    {
+      gchar *str = g_variant_type_dup_string (type);
+      g_variant_builder_add (&builder, "g", str);
+      g_free (str);
+    }
+  else
+    g_variant_builder_add (&builder, "g", "");
+
+  g_variant_builder_open (&builder, G_VARIANT_TYPE ("av"));
+  if ((state = g_action_group_get_action_state (action_group, name)))
+    {
+      g_variant_builder_add (&builder, "v", state);
+      g_variant_unref (state);
+    }
+  g_variant_builder_close (&builder);
+
+  return g_variant_builder_end (&builder);
+}
+
+/* Using XML saves us dozens of relocations vs. using the introspection
+ * structure types.  We only need to burn cycles and memory if we
+ * actually use the exporter -- not in every single app using GIO.
+ *
+ * It's also a lot easier to read. :)
+ *
+ * For documentation of this interface, see
+ * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI
+ */
+const char org_gtk_Actions_xml[] =
+  "<node>"
+  "  <interface name='org.gtk.Actions'>"
+  "    <method name='List'>"
+  "      <arg type='as' name='list' direction='out'/>"
+  "    </method>"
+  "    <method name='Describe'>"
+  "      <arg type='s' name='action_name' direction='in'/>"
+  "      <arg type='(bgav)' name='description' direction='out'/>"
+  "    </method>"
+  "    <method name='DescribeAll'>"
+  "      <arg type='a{s(bgav)}' name='descriptions' direction='out'/>"
+  "    </method>"
+  "    <method name='Activate'>"
+  "      <arg type='s' name='action_name' direction='in'/>"
+  "      <arg type='av' name='parameter' direction='in'/>"
+  "      <arg type='a{sv}' name='platform_data' direction='in'/>"
+  "    </method>"
+  "    <method name='SetState'>"
+  "      <arg type='s' name='action_name' direction='in'/>"
+  "      <arg type='v' name='value' direction='in'/>"
+  "      <arg type='a{sv}' name='platform_data' direction='in'/>"
+  "    </method>"
+  "    <signal name='Changed'>"
+  "      <arg type='as' name='removals'/>"
+  "      <arg type='a{sb}' name='enable_changes'/>"
+  "      <arg type='a{sv}' name='state_changes'/>"
+  "      <arg type='a{s(bgav)}' name='additions'/>"
+  "    </signal>"
+  "  </interface>"
+  "</node>";
+
+static GDBusInterfaceInfo *org_gtk_Actions;
+
+typedef struct
+{
+  GActionGroup    *action_group;
+  GDBusConnection *connection;
+  GMainContext    *context;
+  gchar           *object_path;
+  GHashTable      *pending_changes;
+  GSource         *pending_source;
+} GActionGroupExporter;
+
+#define ACTION_ADDED_EVENT             (1u<<0)
+#define ACTION_REMOVED_EVENT           (1u<<1)
+#define ACTION_STATE_CHANGED_EVENT     (1u<<2)
+#define ACTION_ENABLED_CHANGED_EVENT   (1u<<3)
+
+static gboolean
+g_action_group_exporter_dispatch_events (gpointer user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+  GVariantBuilder removes;
+  GVariantBuilder enabled_changes;
+  GVariantBuilder state_changes;
+  GVariantBuilder adds;
+  GHashTableIter iter;
+  gpointer value;
+  gpointer key;
+
+  g_variant_builder_init (&removes, G_VARIANT_TYPE_STRING_ARRAY);
+  g_variant_builder_init (&enabled_changes, G_VARIANT_TYPE ("a{sb}"));
+  g_variant_builder_init (&state_changes, G_VARIANT_TYPE ("a{sv}"));
+  g_variant_builder_init (&adds, G_VARIANT_TYPE ("a{s(bgav)}"));
+
+  g_hash_table_iter_init (&iter, exporter->pending_changes);
+  while (g_hash_table_iter_next (&iter, &key, &value))
+    {
+      guint events = GPOINTER_TO_INT (value);
+      const gchar *name = key;
+
+      /* Adds and removes are incompatible with enabled or state
+       * changes, but we must report at least one event.
+       */
+      g_assert (((events & (ACTION_ENABLED_CHANGED_EVENT | ACTION_STATE_CHANGED_EVENT)) == 0) !=
+                ((events & (ACTION_REMOVED_EVENT | ACTION_ADDED_EVENT)) == 0));
+
+      if (events & ACTION_REMOVED_EVENT)
+        g_variant_builder_add (&removes, "s", name);
+
+      if (events & ACTION_ENABLED_CHANGED_EVENT)
+        {
+          gboolean enabled;
+
+          enabled = g_action_group_get_action_enabled (exporter->action_group, name);
+          g_variant_builder_add (&enabled_changes, "{sb}", name, enabled);
+        }
+
+      if (events & ACTION_STATE_CHANGED_EVENT)
+        {
+          GVariant *state;
+
+          state = g_action_group_get_action_state (exporter->action_group, name);
+          g_variant_builder_add (&state_changes, "{sv}", name, state);
+          g_variant_unref (state);
+        }
+
+      if (events & ACTION_ADDED_EVENT)
+        {
+          GVariant *description;
+
+          description = g_action_group_describe_action (exporter->action_group, name);
+          g_variant_builder_add (&adds, "{s@(bgav)}", name, description);
+        }
+    }
+
+  g_hash_table_remove_all (exporter->pending_changes);
+
+  g_dbus_connection_emit_signal (exporter->connection, NULL, exporter->object_path,
+                                 "org.gtk.Actions", "Changed",
+                                 g_variant_new ("(asa{sb}a{sv}a{s(bgav)})",
+                                                &removes, &enabled_changes,
+                                                &state_changes, &adds),
+                                 NULL);
+
+  exporter->pending_source = NULL;
+
+  return FALSE;
+}
+
+static void
+g_action_group_exporter_flush_queue (GActionGroupExporter *exporter)
+{
+  if (exporter->pending_source)
+    {
+      g_source_destroy (exporter->pending_source);
+      g_action_group_exporter_dispatch_events (exporter);
+      g_assert (exporter->pending_source == NULL);
+    }
+}
+
+static guint
+g_action_group_exporter_get_events (GActionGroupExporter *exporter,
+                                    const gchar          *name)
+{
+  return (gsize) g_hash_table_lookup (exporter->pending_changes, name);
+}
+
+static void
+g_action_group_exporter_set_events (GActionGroupExporter *exporter,
+                                    const gchar          *name,
+                                    guint                 events)
+{
+  gboolean have_events;
+  gboolean is_queued;
+
+  if (events != 0)
+    g_hash_table_insert (exporter->pending_changes, g_strdup (name), GINT_TO_POINTER (events));
+  else
+    g_hash_table_remove (exporter->pending_changes, name);
+
+  have_events = g_hash_table_size (exporter->pending_changes) > 0;
+  is_queued = exporter->pending_source != NULL;
+
+  if (have_events && !is_queued)
+    {
+      GSource *source;
+
+      source = g_idle_source_new ();
+      exporter->pending_source = source;
+      g_source_set_callback (source, g_action_group_exporter_dispatch_events, exporter, NULL);
+      g_source_set_name (source, "[gio] g_action_group_exporter_dispatch_events");
+      g_source_attach (source, exporter->context);
+      g_source_unref (source);
+    }
+
+  if (!have_events && is_queued)
+    {
+      g_source_destroy (exporter->pending_source);
+      exporter->pending_source = NULL;
+    }
+}
+
+static void
+g_action_group_exporter_action_added (GActionGroup *action_group,
+                                      const gchar  *action_name,
+                                      gpointer      user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+  guint event_mask;
+
+  event_mask = g_action_group_exporter_get_events (exporter, action_name);
+
+  /* The action is new, so we should not have any pending
+   * enabled-changed or state-changed signals for it.
+   */
+  g_assert (~event_mask & (ACTION_STATE_CHANGED_EVENT |
+                           ACTION_ENABLED_CHANGED_EVENT));
+
+  event_mask |= ACTION_ADDED_EVENT;
+
+  g_action_group_exporter_set_events (exporter, action_name, event_mask);
+}
+
+static void
+g_action_group_exporter_action_removed (GActionGroup *action_group,
+                                        const gchar  *action_name,
+                                        gpointer      user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+  guint event_mask;
+
+  event_mask = g_action_group_exporter_get_events (exporter, action_name);
+
+  /* If the add event for this is still queued then just cancel it since
+   * it's gone now.
+   *
+   * If the event was freshly added, there should not have been any
+   * enabled or state changed events.
+   */
+  if (event_mask & ACTION_ADDED_EVENT)
+    {
+      g_assert (~event_mask & ~(ACTION_STATE_CHANGED_EVENT | ACTION_ENABLED_CHANGED_EVENT));
+      event_mask &= ~ACTION_ADDED_EVENT;
+    }
+
+  /* Otherwise, queue a remove event.  Drop any state or enabled changes
+   * that were queued before the remove. */
+  else
+    {
+      event_mask |= ACTION_REMOVED_EVENT;
+      event_mask &= ~(ACTION_STATE_CHANGED_EVENT | ACTION_ENABLED_CHANGED_EVENT);
+    }
+
+  g_action_group_exporter_set_events (exporter, action_name, event_mask);
+}
+
+static void
+g_action_group_exporter_action_state_changed (GActionGroup *action_group,
+                                              const gchar  *action_name,
+                                              GVariant     *value,
+                                              gpointer      user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+  guint event_mask;
+
+  event_mask = g_action_group_exporter_get_events (exporter, action_name);
+
+  /* If it was removed, it must have been added back.  Otherwise, why
+   * are we hearing about changes?
+   */
+  g_assert (~event_mask & ACTION_REMOVED_EVENT ||
+            event_mask & ACTION_ADDED_EVENT);
+
+  /* If it is freshly added, don't also bother with the state change
+   * signal since the updated state will be sent as part of the pending
+   * add message.
+   */
+  if (~event_mask & ACTION_ADDED_EVENT)
+    event_mask |= ACTION_STATE_CHANGED_EVENT;
+
+  g_action_group_exporter_set_events (exporter, action_name, event_mask);
+}
+
+static void
+g_action_group_exporter_action_enabled_changed (GActionGroup *action_group,
+                                                const gchar  *action_name,
+                                                gboolean      enabled,
+                                                gpointer      user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+  guint event_mask;
+
+  event_mask = g_action_group_exporter_get_events (exporter, action_name);
+
+  /* Reasoning as above. */
+  g_assert (~event_mask & ACTION_REMOVED_EVENT ||
+            event_mask & ACTION_ADDED_EVENT);
+
+  if (~event_mask & ACTION_ADDED_EVENT)
+    event_mask |= ACTION_ENABLED_CHANGED_EVENT;
+
+  g_action_group_exporter_set_events (exporter, action_name, event_mask);
+}
+
+static void
+org_gtk_Actions_method_call (GDBusConnection       *connection,
+                             const gchar           *sender,
+                             const gchar           *object_path,
+                             const gchar           *interface_name,
+                             const gchar           *method_name,
+                             GVariant              *parameters,
+                             GDBusMethodInvocation *invocation,
+                             gpointer               user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+  GVariant *result = NULL;
+
+  g_action_group_exporter_flush_queue (exporter);
+
+  if (g_str_equal (method_name, "List"))
+    {
+      gchar **list;
+
+      list = g_action_group_list_actions (exporter->action_group);
+      result = g_variant_new ("(^as)", list);
+      g_strfreev (list);
+    }
+
+  else if (g_str_equal (method_name, "Describe"))
+    {
+      const gchar *name;
+      GVariant *desc;
+
+      g_variant_get (parameters, "(&s)", &name);
+
+      if (!g_action_group_has_action (exporter->action_group, name))
+        {
+          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+                                                 "The named action ('%s') does not exist.", name);
+          return;
+        }
+
+      desc = g_action_group_describe_action (exporter->action_group, name);
+      result = g_variant_new ("(@(bgav))", desc);
+    }
+
+  else if (g_str_equal (method_name, "DescribeAll"))
+    {
+      GVariantBuilder builder;
+      gchar **list;
+      gint i;
+
+      list = g_action_group_list_actions (exporter->action_group);
+      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{s(bgav)}"));
+      for (i = 0; list[i]; i++)
+        {
+          const gchar *name = list[i];
+          GVariant *description;
+
+          description = g_action_group_describe_action (exporter->action_group, name);
+          g_variant_builder_add (&builder, "{s@(bgav)}", name, description);
+        }
+      result = g_variant_new ("(a{s(bgav)})", &builder);
+      g_strfreev (list);
+    }
+
+  else if (g_str_equal (method_name, "Activate"))
+    {
+      GVariant *parameter = NULL;
+      GVariant *platform_data;
+      GVariantIter *iter;
+      const gchar *name;
+
+      g_variant_get (parameters, "(&sav@a{sv})", &name, &iter, &platform_data);
+      g_variant_iter_next (iter, "v", &parameter);
+      g_variant_iter_free (iter);
+
+      if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group))
+        g_remote_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (exporter->action_group),
+                                                    name, parameter, platform_data);
+      else
+        g_action_group_activate_action (exporter->action_group, name, parameter);
+
+      if (parameter)
+        g_variant_unref (parameter);
+
+      g_variant_unref (platform_data);
+    }
+
+  else if (g_str_equal (method_name, "SetState"))
+    {
+      GVariant *platform_data;
+      const gchar *name;
+      GVariant *state;
+
+      g_variant_get (parameters, "(&sv@a{sv})", &name, &state, &platform_data);
+
+      if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group))
+        g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (exporter->action_group),
+                                                        name, state, platform_data);
+      else
+        g_action_group_change_action_state (exporter->action_group, name, state);
+
+      g_variant_unref (platform_data);
+      g_variant_unref (state);
+    }
+
+  else
+    g_assert_not_reached ();
+
+  g_dbus_method_invocation_return_value (invocation, result);
+}
+
+static void
+g_action_group_exporter_free (gpointer user_data)
+{
+  GActionGroupExporter *exporter = user_data;
+
+  g_signal_handlers_disconnect_by_func (exporter->action_group,
+                                        g_action_group_exporter_action_added, exporter);
+  g_signal_handlers_disconnect_by_func (exporter->action_group,
+                                        g_action_group_exporter_action_enabled_changed, exporter);
+  g_signal_handlers_disconnect_by_func (exporter->action_group,
+                                        g_action_group_exporter_action_state_changed, exporter);
+  g_signal_handlers_disconnect_by_func (exporter->action_group,
+                                        g_action_group_exporter_action_removed, exporter);
+
+  g_hash_table_unref (exporter->pending_changes);
+  if (exporter->pending_source)
+    g_source_destroy (exporter->pending_source);
+
+  g_main_context_unref (exporter->context);
+  g_object_unref (exporter->connection);
+  g_object_unref (exporter->action_group);
+  g_free (exporter->object_path);
+
+  g_slice_free (GActionGroupExporter, exporter);
+}
+
+/**
+ * g_dbus_connection_export_action_group:
+ * @connection: a #GDBusConnection
+ * @object_path: a D-Bus object path
+ * @action_group: a #GActionGroup
+ * @error: a pointer to a %NULL #GError, or %NULL
+ *
+ * Exports @action_group on @connection at @object_path.
+ *
+ * The implemented D-Bus API should be considered private.  It is
+ * subject to change in the future.
+ *
+ * A given object path can only have one action group exported on it.
+ * If this constraint is violated, the export will fail and 0 will be
+ * returned (with @error set accordingly).
+ *
+ * You can unexport the action group using
+ * g_dbus_connection_unexport_action_group() with the return value of
+ * this function.
+ *
+ * The thread default main context is taken at the time of this call.
+ * All incoming action activations and state change requests are
+ * reported from this context.  Any changes on the action group that
+ * cause it to emit signals must also come from this same context.
+ * Since incoming action activations and state change requests are
+ * rather likely to cause changes on the action group, this effectively
+ * limits a given action group to being exported from only one main
+ * context.
+ *
+ * Returns: the ID of the export (never zero), or 0 in case of failure
+ *
+ * Since: 2.32
+ **/
+guint
+g_dbus_connection_export_action_group (GDBusConnection  *connection,
+                                       const gchar      *object_path,
+                                       GActionGroup     *action_group,
+                                       GError          **error)
+{
+  const GDBusInterfaceVTable vtable = {
+    org_gtk_Actions_method_call
+  };
+  GActionGroupExporter *exporter;
+  guint id;
+
+  if G_UNLIKELY (org_gtk_Actions == NULL)
+    {
+      GError *error = NULL;
+      GDBusNodeInfo *info;
+
+      info = g_dbus_node_info_new_for_xml (org_gtk_Actions_xml, &error);
+      if G_UNLIKELY (info == NULL)
+        g_error ("%s", error->message);
+      org_gtk_Actions = g_dbus_node_info_lookup_interface (info, "org.gtk.Actions");
+      g_assert (org_gtk_Actions != NULL);
+      g_dbus_interface_info_ref (org_gtk_Actions);
+      g_dbus_node_info_unref (info);
+    }
+
+  exporter = g_slice_new (GActionGroupExporter);
+  id = g_dbus_connection_register_object (connection, object_path, org_gtk_Actions, &vtable,
+                                          exporter, g_action_group_exporter_free, error);
+
+  if (id == 0)
+    {
+      g_slice_free (GActionGroupExporter, exporter);
+      return 0;
+    }
+
+  exporter->context = g_main_context_ref_thread_default ();
+  exporter->pending_changes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  exporter->pending_source = NULL;
+  exporter->action_group = g_object_ref (action_group);
+  exporter->connection = g_object_ref (connection);
+  exporter->object_path = g_strdup (object_path);
+
+  g_signal_connect (action_group, "action-added",
+                    G_CALLBACK (g_action_group_exporter_action_added), exporter);
+  g_signal_connect (action_group, "action-removed",
+                    G_CALLBACK (g_action_group_exporter_action_removed), exporter);
+  g_signal_connect (action_group, "action-state-changed",
+                    G_CALLBACK (g_action_group_exporter_action_state_changed), exporter);
+  g_signal_connect (action_group, "action-enabled-changed",
+                    G_CALLBACK (g_action_group_exporter_action_enabled_changed), exporter);
+
+  return id;
+}
+
+/**
+ * g_dbus_connection_unexport_action_group:
+ * @connection: a #GDBusConnection
+ * @export_id: the ID from g_dbus_connection_export_action_group()
+ *
+ * Reverses the effect of a previous call to
+ * g_dbus_connection_export_action_group().
+ *
+ * It is an error to call this function with an ID that wasn't returned
+ * from g_dbus_connection_export_action_group() or to call it with the
+ * same ID more than once.
+ *
+ * Since: 2.32
+ **/
+void
+g_dbus_connection_unexport_action_group (GDBusConnection *connection,
+                                         guint            export_id)
+{
+  g_dbus_connection_unregister_object (connection, export_id);
+}
diff --git a/gio/gactiongroupexporter.h b/gio/gactiongroupexporter.h
new file mode 100644
index 0000000..ba28c89
--- /dev/null
+++ b/gio/gactiongroupexporter.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2011 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+
+#ifndef __G_ACTION_GROUP_EXPORTER_H__
+#define __G_ACTION_GROUP_EXPORTER_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+GLIB_AVAILABLE_IN_2_32
+guint                   g_dbus_connection_export_action_group           (GDBusConnection  *connection,
+                                                                         const gchar      *object_path,
+                                                                         GActionGroup     *action_group,
+                                                                         GError          **error);
+
+GLIB_AVAILABLE_IN_2_32
+void                    g_dbus_connection_unexport_action_group         (GDBusConnection  *connection,
+                                                                         guint             export_id);
+
+G_END_DECLS
+
+#endif /* __G_ACTION_GROUP_EXPORTER_H__ */
diff --git a/gio/gactionmap.c b/gio/gactionmap.c
new file mode 100644
index 0000000..bfcda8d
--- /dev/null
+++ b/gio/gactionmap.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gsimpleaction.h"
+#include "gactionmap.h"
+#include "gaction.h"
+
+/**
+ * SECTION:gactionmap
+ * @title: GActionMap
+ * @include: gio/gio.h
+ * @short_description: Interface for action containers
+ *
+ * The GActionMap interface is implemented by #GActionGroup
+ * implementations that operate by containing a number of
+ * named #GAction instances, such as #GSimpleActionGroup.
+ *
+ * One useful application of this interface is to map the
+ * names of actions from various action groups to unique,
+ * prefixed names (e.g. by prepending "app." or "win.").
+ * This is the motivation for the 'Map' part of the interface
+ * name.
+ *
+ * Since: 2.32
+ **/
+
+/**
+ * GActionMap:
+ *
+ * #GActionMap is an opaque data structure and can only be accessed
+ * using the following functions.
+ **/
+
+/**
+ * GActionMapInterface:
+ * @lookup_action: the virtual function pointer for g_action_map_lookup_action()
+ * @add_action: the virtual function pointer for g_action_map_add_action()
+ * @remove_action: the virtual function pointer for g_action_map_remove_action()
+ *
+ * The virtual function table for #GActionMap.
+ *
+ * Since: 2.32
+ **/
+
+G_DEFINE_INTERFACE (GActionMap, g_action_map, G_TYPE_OBJECT)
+
+static void
+g_action_map_default_init (GActionMapInterface *iface)
+{
+}
+
+/**
+ * g_action_map_lookup_action:
+ * @action_map: a #GActionMap
+ * @action_name: the name of an action
+ *
+ * Looks up the action with the name @action_name in @action_map.
+ *
+ * If no such action exists, returns %NULL.
+ *
+ * Returns: (transfer none): a #GAction, or %NULL
+ *
+ * Since: 2.32
+ */
+GAction *
+g_action_map_lookup_action (GActionMap  *action_map,
+                            const gchar *action_name)
+{
+  return G_ACTION_MAP_GET_IFACE (action_map)
+    ->lookup_action (action_map, action_name);
+}
+
+/**
+ * g_action_map_add_action:
+ * @action_map: a #GActionMap
+ * @action: a #GAction
+ *
+ * Adds an action to the @action_map.
+ *
+ * If the action map already contains an action with the same name
+ * as @action then the old action is dropped from the action map.
+ *
+ * The action map takes its own reference on @action.
+ *
+ * Since: 2.32
+ */
+void
+g_action_map_add_action (GActionMap *action_map,
+                         GAction    *action)
+{
+  G_ACTION_MAP_GET_IFACE (action_map)->add_action (action_map, action);
+}
+
+/**
+ * g_action_map_remove_action:
+ * @action_map: a #GActionMap
+ * @action_name: the name of the action
+ *
+ * Removes the named action from the action map.
+ *
+ * If no action of this name is in the map then nothing happens.
+ *
+ * Since: 2.32
+ */
+void
+g_action_map_remove_action (GActionMap  *action_map,
+                            const gchar *action_name)
+{
+  G_ACTION_MAP_GET_IFACE (action_map)->remove_action (action_map, action_name);
+}
+
+/**
+ * GActionEntry:
+ * @name: the name of the action
+ * @activate: the callback to connect to the "activate" signal of the
+ *            action.  Since GLib 2.40, this can be %NULL for stateful
+ *            actions, in which case the default handler is used.  For
+ *            boolean-stated actions with no parameter, this is a
+ *            toggle.  For other state types (and parameter type equal
+ *            to the state type) this will be a function that
+ *            just calls @change_state (which you should provide).
+ * @parameter_type: the type of the parameter that must be passed to the
+ *                  activate function for this action, given as a single
+ *                  GVariant type string (or %NULL for no parameter)
+ * @state: the initial state for this action, given in
+ *         [GVariant text format][gvariant-text].  The state is parsed
+ *         with no extra type information, so type tags must be added to
+ *         the string if they are necessary.  Stateless actions should
+ *         give %NULL here.
+ * @change_state: the callback to connect to the "change-state" signal
+ *                of the action.  All stateful actions should provide a
+ *                handler here; stateless actions should not.
+ *
+ * This struct defines a single action.  It is for use with
+ * g_action_map_add_action_entries().
+ *
+ * The order of the items in the structure are intended to reflect
+ * frequency of use.  It is permissible to use an incomplete initialiser
+ * in order to leave some of the later values as %NULL.  All values
+ * after @name are optional.  Additional optional fields may be added in
+ * the future.
+ *
+ * See g_action_map_add_action_entries() for an example.
+ **/
+
+/**
+ * g_action_map_add_action_entries:
+ * @action_map: a #GActionMap
+ * @entries: (array length=n_entries) (element-type GActionEntry): a pointer to
+ *           the first item in an array of #GActionEntry structs
+ * @n_entries: the length of @entries, or -1 if @entries is %NULL-terminated
+ * @user_data: the user data for signal connections
+ *
+ * A convenience function for creating multiple #GSimpleAction instances
+ * and adding them to a #GActionMap.
+ *
+ * Each action is constructed as per one #GActionEntry.
+ *
+ * |[<!-- language="C" -->
+ * static void
+ * activate_quit (GSimpleAction *simple,
+ *                GVariant      *parameter,
+ *                gpointer       user_data)
+ * {
+ *   exit (0);
+ * }
+ *
+ * static void
+ * activate_print_string (GSimpleAction *simple,
+ *                        GVariant      *parameter,
+ *                        gpointer       user_data)
+ * {
+ *   g_print ("%s\n", g_variant_get_string (parameter, NULL));
+ * }
+ *
+ * static GActionGroup *
+ * create_action_group (void)
+ * {
+ *   const GActionEntry entries[] = {
+ *     { "quit",         activate_quit              },
+ *     { "print-string", activate_print_string, "s" }
+ *   };
+ *   GSimpleActionGroup *group;
+ *
+ *   group = g_simple_action_group_new ();
+ *   g_action_map_add_action_entries (G_ACTION_MAP (group), entries, G_N_ELEMENTS (entries), NULL);
+ *
+ *   return G_ACTION_GROUP (group);
+ * }
+ * ]|
+ *
+ * Since: 2.32
+ */
+void
+g_action_map_add_action_entries (GActionMap         *action_map,
+                                 const GActionEntry *entries,
+                                 gint                n_entries,
+                                 gpointer            user_data)
+{
+  gint i;
+
+  g_return_if_fail (G_IS_ACTION_MAP (action_map));
+  g_return_if_fail (entries != NULL || n_entries == 0);
+
+  for (i = 0; n_entries == -1 ? entries[i].name != NULL : i < n_entries; i++)
+    {
+      const GActionEntry *entry = &entries[i];
+      const GVariantType *parameter_type;
+      GSimpleAction *action;
+
+      if (entry->parameter_type)
+        {
+          if (!g_variant_type_string_is_valid (entry->parameter_type))
+            {
+              g_critical ("g_action_map_add_entries: the type "
+                          "string '%s' given as the parameter type for "
+                          "action '%s' is not a valid GVariant type "
+                          "string.  This action will not be added.",
+                          entry->parameter_type, entry->name);
+              return;
+            }
+
+          parameter_type = G_VARIANT_TYPE (entry->parameter_type);
+        }
+      else
+        parameter_type = NULL;
+
+      if (entry->state)
+        {
+          GError *error = NULL;
+          GVariant *state;
+
+          state = g_variant_parse (NULL, entry->state, NULL, NULL, &error);
+          if (state == NULL)
+            {
+              g_critical ("g_action_map_add_entries: GVariant could "
+                          "not parse the state value given for action '%s' "
+                          "('%s'): %s.  This action will not be added.",
+                          entry->name, entry->state, error->message);
+              g_error_free (error);
+              continue;
+            }
+
+          action = g_simple_action_new_stateful (entry->name,
+                                                 parameter_type,
+                                                 state);
+
+          g_variant_unref (state);
+        }
+      else
+        {
+          action = g_simple_action_new (entry->name,
+                                        parameter_type);
+        }
+
+      if (entry->activate != NULL)
+        g_signal_connect (action, "activate",
+                          G_CALLBACK (entry->activate), user_data);
+
+      if (entry->change_state != NULL)
+        g_signal_connect (action, "change-state",
+                          G_CALLBACK (entry->change_state), user_data);
+
+      g_action_map_add_action (action_map, G_ACTION (action));
+      g_object_unref (action);
+    }
+}
diff --git a/gio/gactionmap.h b/gio/gactionmap.h
new file mode 100644
index 0000000..2a22a27
--- /dev/null
+++ b/gio/gactionmap.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_ACTION_MAP_H__
+#define __G_ACTION_MAP_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+
+#define G_TYPE_ACTION_MAP                                   (g_action_map_get_type ())
+#define G_ACTION_MAP(inst)                                  (G_TYPE_CHECK_INSTANCE_CAST ((inst),                      \
+                                                             G_TYPE_ACTION_MAP, GActionMap))
+#define G_IS_ACTION_MAP(inst)                               (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                      \
+                                                             G_TYPE_ACTION_MAP))
+#define G_ACTION_MAP_GET_IFACE(inst)                        (G_TYPE_INSTANCE_GET_INTERFACE ((inst),                   \
+                                                             G_TYPE_ACTION_MAP, GActionMapInterface))
+
+typedef struct _GActionMapInterface                         GActionMapInterface;
+typedef struct _GActionEntry                                GActionEntry;
+
+struct _GActionMapInterface
+{
+  GTypeInterface g_iface;
+
+  GAction * (* lookup_action) (GActionMap  *action_map,
+                               const gchar *action_name);
+  void      (* add_action)    (GActionMap  *action_map,
+                               GAction     *action);
+  void      (* remove_action) (GActionMap  *action_map,
+                               const gchar *action_name);
+};
+
+struct _GActionEntry
+{
+  const gchar *name;
+
+  void (* activate) (GSimpleAction *action,
+                     GVariant      *parameter,
+                     gpointer       user_data);
+
+  const gchar *parameter_type;
+
+  const gchar *state;
+
+  void (* change_state) (GSimpleAction *action,
+                         GVariant      *value,
+                         gpointer       user_data);
+
+  /*< private >*/
+  gsize padding[3];
+};
+
+GLIB_AVAILABLE_IN_2_32
+GType                   g_action_map_get_type                           (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_2_32
+GAction *               g_action_map_lookup_action                      (GActionMap         *action_map,
+                                                                         const gchar        *action_name);
+GLIB_AVAILABLE_IN_2_32
+void                    g_action_map_add_action                         (GActionMap         *action_map,
+                                                                         GAction            *action);
+GLIB_AVAILABLE_IN_2_32
+void                    g_action_map_remove_action                      (GActionMap         *action_map,
+                                                                         const gchar        *action_name);
+GLIB_AVAILABLE_IN_2_32
+void                    g_action_map_add_action_entries                 (GActionMap         *action_map,
+                                                                         const GActionEntry *entries,
+                                                                         gint                n_entries,
+                                                                         gpointer            user_data);
+
+G_END_DECLS
+
+#endif /* __G_ACTION_MAP_H__ */
diff --git a/gio/gappinfo.c b/gio/gappinfo.c
new file mode 100644
index 0000000..6b00925
--- /dev/null
+++ b/gio/gappinfo.c
@@ -0,0 +1,1470 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gappinfo.h"
+#include "gappinfoprivate.h"
+#include "gcontextspecificgroup.h"
+#include "gtask.h"
+#include "gcancellable.h"
+
+#include "glibintl.h"
+#include "gmarshal-internal.h"
+#include <gioerror.h>
+#include <gfile.h>
+
+#ifdef G_OS_UNIX
+#include "gdbusconnection.h"
+#include "gdbusmessage.h"
+#include "gportalsupport.h"
+#include "gunixfdlist.h"
+#include "gopenuriportal.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
+/**
+ * SECTION:gappinfo
+ * @short_description: Application information and launch contexts
+ * @include: gio/gio.h
+ * @see_also: #GAppInfoMonitor
+ * 
+ * #GAppInfo and #GAppLaunchContext are used for describing and launching
+ * applications installed on the system.
+ *
+ * As of GLib 2.20, URIs will always be converted to POSIX paths
+ * (using g_file_get_path()) when using g_app_info_launch() even if
+ * the application requested an URI and not a POSIX path. For example
+ * for a desktop-file based application with Exec key `totem
+ * %U` and a single URI, `sftp://foo/file.avi`, then
+ * `/home/user/.gvfs/sftp on foo/file.avi` will be passed. This will
+ * only work if a set of suitable GIO extensions (such as gvfs 2.26
+ * compiled with FUSE support), is available and operational; if this
+ * is not the case, the URI will be passed unmodified to the application.
+ * Some URIs, such as `mailto:`, of course cannot be mapped to a POSIX
+ * path (in gvfs there's no FUSE mount for it); such URIs will be
+ * passed unmodified to the application.
+ *
+ * Specifically for gvfs 2.26 and later, the POSIX URI will be mapped
+ * back to the GIO URI in the #GFile constructors (since gvfs
+ * implements the #GVfs extension point). As such, if the application
+ * needs to examine the URI, it needs to use g_file_get_uri() or
+ * similar on #GFile. In other words, an application cannot assume
+ * that the URI passed to e.g. g_file_new_for_commandline_arg() is
+ * equal to the result of g_file_get_uri(). The following snippet
+ * illustrates this:
+ *
+ * |[ 
+ * GFile *f;
+ * char *uri;
+ *
+ * file = g_file_new_for_commandline_arg (uri_from_commandline);
+ *
+ * uri = g_file_get_uri (file);
+ * strcmp (uri, uri_from_commandline) == 0;
+ * g_free (uri);
+ *
+ * if (g_file_has_uri_scheme (file, "cdda"))
+ *   {
+ *     // do something special with uri
+ *   }
+ * g_object_unref (file);
+ * ]|
+ *
+ * This code will work when both `cdda://sr0/Track 1.wav` and
+ * `/home/user/.gvfs/cdda on sr0/Track 1.wav` is passed to the
+ * application. It should be noted that it's generally not safe
+ * for applications to rely on the format of a particular URIs.
+ * Different launcher applications (e.g. file managers) may have
+ * different ideas of what a given URI means.
+ */
+
+struct _GAppLaunchContextPrivate {
+  char **envp;
+};
+
+typedef GAppInfoIface GAppInfoInterface;
+G_DEFINE_INTERFACE (GAppInfo, g_app_info, G_TYPE_OBJECT)
+
+static void
+g_app_info_default_init (GAppInfoInterface *iface)
+{
+}
+
+
+/**
+ * g_app_info_dup:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Creates a duplicate of a #GAppInfo.
+ *
+ * Returns: (transfer full): a duplicate of @appinfo.
+ **/
+GAppInfo *
+g_app_info_dup (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->dup) (appinfo);
+}
+
+/**
+ * g_app_info_equal:
+ * @appinfo1: the first #GAppInfo.
+ * @appinfo2: the second #GAppInfo.
+ *
+ * Checks if two #GAppInfos are equal.
+ *
+ * Note that the check <emphasis>may not</emphasis> compare each individual
+ * field, and only does an identity check. In case detecting changes in the 
+ * contents is needed, program code must additionally compare relevant fields.
+ *
+ * Returns: %TRUE if @appinfo1 is equal to @appinfo2. %FALSE otherwise.
+ **/
+gboolean
+g_app_info_equal (GAppInfo *appinfo1,
+		  GAppInfo *appinfo2)
+{
+  GAppInfoIface *iface;
+
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo1), FALSE);
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo2), FALSE);
+
+  if (G_TYPE_FROM_INSTANCE (appinfo1) != G_TYPE_FROM_INSTANCE (appinfo2))
+    return FALSE;
+  
+  iface = G_APP_INFO_GET_IFACE (appinfo1);
+
+  return (* iface->equal) (appinfo1, appinfo2);
+}
+
+/**
+ * g_app_info_get_id:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Gets the ID of an application. An id is a string that
+ * identifies the application. The exact format of the id is
+ * platform dependent. For instance, on Unix this is the
+ * desktop file id from the xdg menu specification.
+ *
+ * Note that the returned ID may be %NULL, depending on how
+ * the @appinfo has been constructed.
+ *
+ * Returns: a string containing the application's ID.
+ **/
+const char *
+g_app_info_get_id (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->get_id) (appinfo);
+}
+
+/**
+ * g_app_info_get_name:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Gets the installed name of the application. 
+ *
+ * Returns: the name of the application for @appinfo.
+ **/
+const char *
+g_app_info_get_name (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->get_name) (appinfo);
+}
+
+/**
+ * g_app_info_get_display_name:
+ * @appinfo: a #GAppInfo.
+ *
+ * Gets the display name of the application. The display name is often more
+ * descriptive to the user than the name itself.
+ *
+ * Returns: the display name of the application for @appinfo, or the name if
+ * no display name is available.
+ *
+ * Since: 2.24
+ **/
+const char *
+g_app_info_get_display_name (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->get_display_name == NULL)
+    return (* iface->get_name) (appinfo);
+
+  return (* iface->get_display_name) (appinfo);
+}
+
+/**
+ * g_app_info_get_description:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Gets a human-readable description of an installed application.
+ *
+ * Returns: a string containing a description of the 
+ * application @appinfo, or %NULL if none. 
+ **/
+const char *
+g_app_info_get_description (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->get_description) (appinfo);
+}
+
+/**
+ * g_app_info_get_executable:
+ * @appinfo: a #GAppInfo
+ * 
+ * Gets the executable's name for the installed application.
+ *
+ * Returns: (type filename): a string containing the @appinfo's application
+ * binaries name
+ **/
+const char *
+g_app_info_get_executable (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->get_executable) (appinfo);
+}
+
+
+/**
+ * g_app_info_get_commandline:
+ * @appinfo: a #GAppInfo
+ * 
+ * Gets the commandline with which the application will be
+ * started.  
+ *
+ * Returns: (type filename): a string containing the @appinfo's commandline,
+ *     or %NULL if this information is not available
+ *
+ * Since: 2.20
+ **/
+const char *
+g_app_info_get_commandline (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->get_commandline)
+    return (* iface->get_commandline) (appinfo);
+ 
+  return NULL;
+}
+
+/**
+ * g_app_info_set_as_default_for_type:
+ * @appinfo: a #GAppInfo.
+ * @content_type: the content type.
+ * @error: a #GError.
+ * 
+ * Sets the application as the default handler for a given type.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ **/
+gboolean
+g_app_info_set_as_default_for_type (GAppInfo    *appinfo,
+				    const char  *content_type,
+				    GError     **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+  g_return_val_if_fail (content_type != NULL, FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->set_as_default_for_type) (appinfo, content_type, error);
+}
+
+/**
+ * g_app_info_set_as_last_used_for_type:
+ * @appinfo: a #GAppInfo.
+ * @content_type: the content type.
+ * @error: a #GError.
+ *
+ * Sets the application as the last used application for a given type.
+ * This will make the application appear as first in the list returned
+ * by g_app_info_get_recommended_for_type(), regardless of the default
+ * application for that content type.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ **/
+gboolean
+g_app_info_set_as_last_used_for_type (GAppInfo    *appinfo,
+                                      const char  *content_type,
+                                      GError     **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+  g_return_val_if_fail (content_type != NULL, FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->set_as_last_used_for_type) (appinfo, content_type, error);
+}
+
+/**
+ * g_app_info_set_as_default_for_extension:
+ * @appinfo: a #GAppInfo.
+ * @extension: (type filename): a string containing the file extension
+ *     (without the dot).
+ * @error: a #GError.
+ * 
+ * Sets the application as the default handler for the given file extension.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ **/
+gboolean
+g_app_info_set_as_default_for_extension (GAppInfo    *appinfo,
+					 const char  *extension,
+					 GError     **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+  g_return_val_if_fail (extension != NULL, FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->set_as_default_for_extension)
+    return (* iface->set_as_default_for_extension) (appinfo, extension, error);
+
+  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                       "g_app_info_set_as_default_for_extension not supported yet");
+  return FALSE;
+}
+
+
+/**
+ * g_app_info_add_supports_type:
+ * @appinfo: a #GAppInfo.
+ * @content_type: a string.
+ * @error: a #GError.
+ * 
+ * Adds a content type to the application information to indicate the 
+ * application is capable of opening files with the given content type.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ **/
+gboolean
+g_app_info_add_supports_type (GAppInfo    *appinfo,
+			      const char  *content_type,
+			      GError     **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+  g_return_val_if_fail (content_type != NULL, FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->add_supports_type)
+    return (* iface->add_supports_type) (appinfo, content_type, error);
+
+  g_set_error_literal (error, G_IO_ERROR, 
+                       G_IO_ERROR_NOT_SUPPORTED, 
+                       "g_app_info_add_supports_type not supported yet");
+
+  return FALSE;
+}
+
+
+/**
+ * g_app_info_can_remove_supports_type:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Checks if a supported content type can be removed from an application.
+ *
+ * Returns: %TRUE if it is possible to remove supported 
+ *     content types from a given @appinfo, %FALSE if not.
+ **/
+gboolean
+g_app_info_can_remove_supports_type (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->can_remove_supports_type)
+    return (* iface->can_remove_supports_type) (appinfo);
+
+  return FALSE;
+}
+
+
+/**
+ * g_app_info_remove_supports_type:
+ * @appinfo: a #GAppInfo.
+ * @content_type: a string.
+ * @error: a #GError.
+ *
+ * Removes a supported type from an application, if possible.
+ * 
+ * Returns: %TRUE on success, %FALSE on error.
+ **/
+gboolean
+g_app_info_remove_supports_type (GAppInfo    *appinfo,
+				 const char  *content_type,
+				 GError     **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+  g_return_val_if_fail (content_type != NULL, FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->remove_supports_type)
+    return (* iface->remove_supports_type) (appinfo, content_type, error);
+
+  g_set_error_literal (error, G_IO_ERROR, 
+                       G_IO_ERROR_NOT_SUPPORTED, 
+                       "g_app_info_remove_supports_type not supported yet");
+
+  return FALSE;
+}
+
+/**
+ * g_app_info_get_supported_types:
+ * @appinfo: a #GAppInfo that can handle files
+ *
+ * Retrieves the list of content types that @app_info claims to support.
+ * If this information is not provided by the environment, this function
+ * will return %NULL.
+ * This function does not take in consideration associations added with
+ * g_app_info_add_supports_type(), but only those exported directly by
+ * the application.
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type utf8):
+ *    a list of content types.
+ *
+ * Since: 2.34
+ */
+const char **
+g_app_info_get_supported_types (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->get_supported_types)
+    return iface->get_supported_types (appinfo);
+  else
+    return NULL;
+}
+
+
+/**
+ * g_app_info_get_icon:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Gets the icon for the application.
+ *
+ * Returns: (transfer none): the default #GIcon for @appinfo or %NULL
+ * if there is no default icon.
+ **/
+GIcon *
+g_app_info_get_icon (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->get_icon) (appinfo);
+}
+
+
+/**
+ * g_app_info_launch:
+ * @appinfo: a #GAppInfo
+ * @files: (nullable) (element-type GFile): a #GList of #GFile objects
+ * @context: (nullable): a #GAppLaunchContext or %NULL
+ * @error: a #GError
+ * 
+ * Launches the application. Passes @files to the launched application
+ * as arguments, using the optional @context to get information
+ * about the details of the launcher (like what screen it is on).
+ * On error, @error will be set accordingly.
+ *
+ * To launch the application without arguments pass a %NULL @files list.
+ *
+ * Note that even if the launch is successful the application launched
+ * can fail to start if it runs into problems during startup. There is
+ * no way to detect this.
+ *
+ * Some URIs can be changed when passed through a GFile (for instance
+ * unsupported URIs with strange formats like mailto:), so if you have
+ * a textual URI you want to pass in as argument, consider using
+ * g_app_info_launch_uris() instead.
+ *
+ * The launched application inherits the environment of the launching
+ * process, but it can be modified with g_app_launch_context_setenv()
+ * and g_app_launch_context_unsetenv().
+ *
+ * On UNIX, this function sets the `GIO_LAUNCHED_DESKTOP_FILE`
+ * environment variable with the path of the launched desktop file and
+ * `GIO_LAUNCHED_DESKTOP_FILE_PID` to the process id of the launched
+ * process. This can be used to ignore `GIO_LAUNCHED_DESKTOP_FILE`,
+ * should it be inherited by further processes. The `DISPLAY` and
+ * `DESKTOP_STARTUP_ID` environment variables are also set, based
+ * on information provided in @context.
+ *
+ * Returns: %TRUE on successful launch, %FALSE otherwise.
+ **/
+gboolean
+g_app_info_launch (GAppInfo           *appinfo,
+		   GList              *files,
+		   GAppLaunchContext  *launch_context,
+		   GError            **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->launch) (appinfo, files, launch_context, error);
+}
+
+
+/**
+ * g_app_info_supports_uris:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Checks if the application supports reading files and directories from URIs.
+ *
+ * Returns: %TRUE if the @appinfo supports URIs.
+ **/
+gboolean
+g_app_info_supports_uris (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->supports_uris) (appinfo);
+}
+
+
+/**
+ * g_app_info_supports_files:
+ * @appinfo: a #GAppInfo.
+ * 
+ * Checks if the application accepts files as arguments.
+ *
+ * Returns: %TRUE if the @appinfo supports files.
+ **/
+gboolean
+g_app_info_supports_files (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->supports_files) (appinfo);
+}
+
+
+/**
+ * g_app_info_launch_uris:
+ * @appinfo: a #GAppInfo
+ * @uris: (nullable) (element-type utf8): a #GList containing URIs to launch.
+ * @context: (nullable): a #GAppLaunchContext or %NULL
+ * @error: a #GError
+ * 
+ * Launches the application. This passes the @uris to the launched application
+ * as arguments, using the optional @context to get information
+ * about the details of the launcher (like what screen it is on).
+ * On error, @error will be set accordingly.
+ *
+ * To launch the application without arguments pass a %NULL @uris list.
+ *
+ * Note that even if the launch is successful the application launched
+ * can fail to start if it runs into problems during startup. There is
+ * no way to detect this.
+ *
+ * Returns: %TRUE on successful launch, %FALSE otherwise.
+ **/
+gboolean
+g_app_info_launch_uris (GAppInfo           *appinfo,
+			GList              *uris,
+			GAppLaunchContext  *launch_context,
+			GError            **error)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->launch_uris) (appinfo, uris, launch_context, error);
+}
+
+/**
+ * g_app_info_launch_uris_async:
+ * @appinfo: a #GAppInfo
+ * @uris: (nullable) (element-type utf8): a #GList containing URIs to launch.
+ * @context: (nullable): a #GAppLaunchContext or %NULL
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
+ * @user_data: (nullable): data to pass to @callback
+ *
+ * Async version of g_app_info_launch_uris().
+ *
+ * The @callback is invoked immediately after the application launch, but it
+ * waits for activation in case of D-Bus–activated applications and also provides
+ * extended error information for sandboxed applications, see notes for
+ * g_app_info_launch_default_for_uri_async().
+ *
+ * Since: 2.60
+ **/
+void
+g_app_info_launch_uris_async (GAppInfo           *appinfo,
+                              GList              *uris,
+                              GAppLaunchContext  *context,
+                              GCancellable       *cancellable,
+                              GAsyncReadyCallback callback,
+                              gpointer            user_data)
+{
+  GAppInfoIface *iface;
+
+  g_return_if_fail (G_IS_APP_INFO (appinfo));
+  g_return_if_fail (context == NULL || G_IS_APP_LAUNCH_CONTEXT (context));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+  if (iface->launch_uris_async == NULL)
+    {
+      GTask *task;
+
+      task = g_task_new (appinfo, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_app_info_launch_uris_async);
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               "Operation not supported for the current backend.");
+      g_object_unref (task);
+
+      return;
+    }
+
+  (* iface->launch_uris_async) (appinfo, uris, context, cancellable, callback, user_data);
+}
+
+/**
+ * g_app_info_launch_uris_finish:
+ * @appinfo: a #GAppInfo
+ * @result: a #GAsyncResult
+ * @error: (nullable): a #GError
+ *
+ * Finishes a g_app_info_launch_uris_async() operation.
+ *
+ * Returns: %TRUE on successful launch, %FALSE otherwise.
+ *
+ * Since: 2.60
+ */
+gboolean
+g_app_info_launch_uris_finish (GAppInfo     *appinfo,
+                               GAsyncResult *result,
+                               GError      **error)
+{
+  GAppInfoIface *iface;
+
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+  if (iface->launch_uris_finish == NULL)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           "Operation not supported for the current backend.");
+      return FALSE;
+    }
+
+  return (* iface->launch_uris_finish) (appinfo, result, error);
+}
+
+/**
+ * g_app_info_should_show:
+ * @appinfo: a #GAppInfo.
+ *
+ * Checks if the application info should be shown in menus that 
+ * list available applications.
+ * 
+ * Returns: %TRUE if the @appinfo should be shown, %FALSE otherwise.
+ **/
+gboolean
+g_app_info_should_show (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  return (* iface->should_show) (appinfo);
+}
+
+/**
+ * g_app_info_launch_default_for_uri:
+ * @uri: the uri to show
+ * @context: (nullable): an optional #GAppLaunchContext
+ * @error: (nullable): return location for an error, or %NULL
+ *
+ * Utility function that launches the default application
+ * registered to handle the specified uri. Synchronous I/O
+ * is done on the uri to detect the type of the file if
+ * required.
+ *
+ * The D-Bus–activated applications don't have to be started if your application
+ * terminates too soon after this function. To prevent this, use
+ * g_app_info_launch_default_for_uri_async() instead.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ **/
+gboolean
+g_app_info_launch_default_for_uri (const char         *uri,
+                                   GAppLaunchContext  *launch_context,
+                                   GError            **error)
+{
+  char *uri_scheme;
+  GAppInfo *app_info = NULL;
+  gboolean res = FALSE;
+
+  /* g_file_query_default_handler() calls
+   * g_app_info_get_default_for_uri_scheme() too, but we have to do it
+   * here anyway in case GFile can't parse @uri correctly.
+   */
+  uri_scheme = g_uri_parse_scheme (uri);
+  if (uri_scheme && uri_scheme[0] != '\0')
+    app_info = g_app_info_get_default_for_uri_scheme (uri_scheme);
+  g_free (uri_scheme);
+
+  if (!app_info)
+    {
+      GFile *file;
+
+      file = g_file_new_for_uri (uri);
+      app_info = g_file_query_default_handler (file, NULL, error);
+      g_object_unref (file);
+    }
+
+  if (app_info)
+    {
+      GList l;
+
+      l.data = (char *)uri;
+      l.next = l.prev = NULL;
+      res = g_app_info_launch_uris (app_info, &l, launch_context, error);
+      g_object_unref (app_info);
+    }
+
+#ifdef G_OS_UNIX
+  if (!res && glib_should_use_portal ())
+    {
+      const char *parent_window = NULL;
+
+      /* Reset any error previously set by launch_default_for_uri */
+      g_clear_error (error);
+
+      if (launch_context && launch_context->priv->envp)
+        parent_window = g_environ_getenv (launch_context->priv->envp, "PARENT_WINDOW_ID");
+
+      return g_openuri_portal_open_uri (uri, parent_window, error);
+    }
+#endif
+
+  return res;
+}
+
+typedef struct
+{
+  gchar *uri;
+  GAppLaunchContext *context;
+} LaunchDefaultForUriData;
+
+static void
+launch_default_for_uri_data_free (LaunchDefaultForUriData *data)
+{
+  g_free (data->uri);
+  g_clear_object (&data->context);
+  g_free (data);
+}
+
+#ifdef G_OS_UNIX
+static void
+launch_default_for_uri_portal_open_uri_cb (GObject      *object,
+                                           GAsyncResult *result,
+                                           gpointer      user_data)
+{
+  GTask *task = G_TASK (user_data);
+  GError *error = NULL;
+
+  if (g_openuri_portal_open_uri_finish (result, &error))
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, g_steal_pointer (&error));
+  g_object_unref (task);
+}
+#endif
+
+static void
+launch_default_for_uri_portal_open_uri (GTask *task, GError *error)
+{
+#ifdef G_OS_UNIX
+  LaunchDefaultForUriData *data = g_task_get_task_data (task);
+  GCancellable *cancellable = g_task_get_cancellable (task);
+
+  if (glib_should_use_portal ())
+    {
+      const char *parent_window = NULL;
+
+      /* Reset any error previously set by launch_default_for_uri */
+      g_error_free (error);
+
+      if (data->context && data->context->priv->envp)
+        parent_window = g_environ_getenv (data->context->priv->envp,
+                                          "PARENT_WINDOW_ID");
+
+      g_openuri_portal_open_uri_async (data->uri,
+                                       parent_window,
+                                       cancellable,
+                                       launch_default_for_uri_portal_open_uri_cb,
+                                       g_steal_pointer (&task));
+      return;
+    }
+#endif
+
+  g_task_return_error (task, g_steal_pointer (&error));
+  g_object_unref (task);
+}
+
+static void
+launch_default_for_uri_launch_uris_cb (GObject      *object,
+                                       GAsyncResult *result,
+                                       gpointer      user_data)
+{
+  GAppInfo *app_info = G_APP_INFO (object);
+  GTask *task = G_TASK (user_data);
+  GError *error = NULL;
+
+  if (g_app_info_launch_uris_finish (app_info, result, &error))
+    {
+      g_task_return_boolean (task, TRUE);
+      g_object_unref (task);
+    }
+  else
+    launch_default_for_uri_portal_open_uri (g_steal_pointer (&task), g_steal_pointer (&error));
+}
+
+static void
+launch_default_for_uri_launch_uris (GTask *task,
+                                    GAppInfo *app_info)
+{
+  GCancellable *cancellable = g_task_get_cancellable (task);
+  GList l;
+  LaunchDefaultForUriData *data = g_task_get_task_data (task);
+
+  l.data = (char *)data->uri;
+  l.next = l.prev = NULL;
+  g_app_info_launch_uris_async (app_info,
+                                &l,
+                                data->context,
+                                cancellable,
+                                launch_default_for_uri_launch_uris_cb,
+                                g_steal_pointer (&task));
+  g_object_unref (app_info);
+}
+
+static void
+launch_default_for_uri_default_handler_cb (GObject      *object,
+                                           GAsyncResult *result,
+                                           gpointer      user_data)
+{
+  GFile *file = G_FILE (object);
+  GTask *task = G_TASK (user_data);
+  GAppInfo *app_info = NULL;
+  GError *error = NULL;
+
+  app_info = g_file_query_default_handler_finish (file, result, &error);
+  if (app_info)
+    launch_default_for_uri_launch_uris (g_steal_pointer (&task), g_steal_pointer (&app_info));
+  else
+    launch_default_for_uri_portal_open_uri (g_steal_pointer (&task), g_steal_pointer (&error));
+}
+
+/**
+ * g_app_info_launch_default_for_uri_async:
+ * @uri: the uri to show
+ * @context: (nullable): an optional #GAppLaunchContext
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
+ * @user_data: (nullable): data to pass to @callback
+ *
+ * Async version of g_app_info_launch_default_for_uri().
+ *
+ * This version is useful if you are interested in receiving
+ * error information in the case where the application is
+ * sandboxed and the portal may present an application chooser
+ * dialog to the user.
+ *
+ * This is also useful if you want to be sure that the D-Bus–activated
+ * applications are really started before termination and if you are interested
+ * in receiving error information from their activation.
+ *
+ * Since: 2.50
+ */
+void
+g_app_info_launch_default_for_uri_async (const char          *uri,
+                                         GAppLaunchContext   *context,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data)
+{
+  GTask *task;
+  char *uri_scheme;
+  GAppInfo *app_info = NULL;
+  LaunchDefaultForUriData *data;
+
+  g_return_if_fail (uri != NULL);
+
+  task = g_task_new (NULL, cancellable, callback, user_data);
+  g_task_set_source_tag (task, g_app_info_launch_default_for_uri_async);
+
+  data = g_new (LaunchDefaultForUriData, 1);
+  data->uri = g_strdup (uri);
+  data->context = (context != NULL) ? g_object_ref (context) : NULL;
+  g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) launch_default_for_uri_data_free);
+
+  /* g_file_query_default_handler_async() calls
+   * g_app_info_get_default_for_uri_scheme() too, but we have to do it
+   * here anyway in case GFile can't parse @uri correctly.
+   */
+  uri_scheme = g_uri_parse_scheme (uri);
+  if (uri_scheme && uri_scheme[0] != '\0')
+    /* FIXME: The following still uses blocking calls. */
+    app_info = g_app_info_get_default_for_uri_scheme (uri_scheme);
+  g_free (uri_scheme);
+
+  if (!app_info)
+    {
+      GFile *file;
+
+      file = g_file_new_for_uri (uri);
+      g_file_query_default_handler_async (file,
+                                          G_PRIORITY_DEFAULT,
+                                          cancellable,
+                                          launch_default_for_uri_default_handler_cb,
+                                          g_steal_pointer (&task));
+      g_object_unref (file);
+    }
+  else
+    launch_default_for_uri_launch_uris (g_steal_pointer (&task), g_steal_pointer (&app_info));
+}
+
+/**
+ * g_app_info_launch_default_for_uri_finish:
+ * @result: a #GAsyncResult
+ * @error: (nullable): return location for an error, or %NULL
+ *
+ * Finishes an asynchronous launch-default-for-uri operation.
+ *
+ * Returns: %TRUE if the launch was successful, %FALSE if @error is set
+ *
+ * Since: 2.50
+ */
+gboolean
+g_app_info_launch_default_for_uri_finish (GAsyncResult  *result,
+                                          GError       **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+/**
+ * g_app_info_can_delete:
+ * @appinfo: a #GAppInfo
+ *
+ * Obtains the information whether the #GAppInfo can be deleted.
+ * See g_app_info_delete().
+ *
+ * Returns: %TRUE if @appinfo can be deleted
+ *
+ * Since: 2.20
+ */
+gboolean
+g_app_info_can_delete (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->can_delete)
+    return (* iface->can_delete) (appinfo);
+ 
+  return FALSE; 
+}
+
+
+/**
+ * g_app_info_delete:
+ * @appinfo: a #GAppInfo
+ *
+ * Tries to delete a #GAppInfo.
+ *
+ * On some platforms, there may be a difference between user-defined
+ * #GAppInfos which can be deleted, and system-wide ones which cannot.
+ * See g_app_info_can_delete().
+ *
+ * Virtual: do_delete
+ * Returns: %TRUE if @appinfo has been deleted
+ *
+ * Since: 2.20
+ */
+gboolean
+g_app_info_delete (GAppInfo *appinfo)
+{
+  GAppInfoIface *iface;
+  
+  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+  iface = G_APP_INFO_GET_IFACE (appinfo);
+
+  if (iface->do_delete)
+    return (* iface->do_delete) (appinfo);
+ 
+  return FALSE; 
+}
+
+
+enum {
+  LAUNCH_FAILED,
+  LAUNCHED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GAppLaunchContext, g_app_launch_context, G_TYPE_OBJECT)
+
+/**
+ * g_app_launch_context_new:
+ * 
+ * Creates a new application launch context. This is not normally used,
+ * instead you instantiate a subclass of this, such as #GdkAppLaunchContext.
+ *
+ * Returns: a #GAppLaunchContext.
+ **/
+GAppLaunchContext *
+g_app_launch_context_new (void)
+{
+  return g_object_new (G_TYPE_APP_LAUNCH_CONTEXT, NULL);
+}
+
+static void
+g_app_launch_context_finalize (GObject *object)
+{
+  GAppLaunchContext *context = G_APP_LAUNCH_CONTEXT (object);
+
+  g_strfreev (context->priv->envp);
+
+  G_OBJECT_CLASS (g_app_launch_context_parent_class)->finalize (object);
+}
+
+static void
+g_app_launch_context_class_init (GAppLaunchContextClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = g_app_launch_context_finalize;
+
+  /**
+   * GAppLaunchContext::launch-failed:
+   * @context: the object emitting the signal
+   * @startup_notify_id: the startup notification id for the failed launch
+   *
+   * The ::launch-failed signal is emitted when a #GAppInfo launch
+   * fails. The startup notification id is provided, so that the launcher
+   * can cancel the startup notification.
+   *
+   * Since: 2.36
+   */
+  signals[LAUNCH_FAILED] = g_signal_new (I_("launch-failed"),
+                                         G_OBJECT_CLASS_TYPE (object_class),
+                                         G_SIGNAL_RUN_LAST,
+                                         G_STRUCT_OFFSET (GAppLaunchContextClass, launch_failed),
+                                         NULL, NULL, NULL,
+                                         G_TYPE_NONE, 1, G_TYPE_STRING);
+
+  /**
+   * GAppLaunchContext::launched:
+   * @context: the object emitting the signal
+   * @info: the #GAppInfo that was just launched
+   * @platform_data: additional platform-specific data for this launch
+   *
+   * The ::launched signal is emitted when a #GAppInfo is successfully
+   * launched. The @platform_data is an GVariant dictionary mapping
+   * strings to variants (ie a{sv}), which contains additional,
+   * platform-specific data about this launch. On UNIX, at least the
+   * "pid" and "startup-notification-id" keys will be present.
+   *
+   * Since: 2.36
+   */
+  signals[LAUNCHED] = g_signal_new (I_("launched"),
+                                    G_OBJECT_CLASS_TYPE (object_class),
+                                    G_SIGNAL_RUN_LAST,
+                                    G_STRUCT_OFFSET (GAppLaunchContextClass, launched),
+                                    NULL, NULL,
+                                    _g_cclosure_marshal_VOID__OBJECT_VARIANT,
+                                    G_TYPE_NONE, 2,
+                                    G_TYPE_APP_INFO, G_TYPE_VARIANT);
+  g_signal_set_va_marshaller (signals[LAUNCHED],
+                              G_TYPE_FROM_CLASS (klass),
+                              _g_cclosure_marshal_VOID__OBJECT_VARIANTv);
+}
+
+static void
+g_app_launch_context_init (GAppLaunchContext *context)
+{
+  context->priv = g_app_launch_context_get_instance_private (context);
+}
+
+/**
+ * g_app_launch_context_setenv:
+ * @context: a #GAppLaunchContext
+ * @variable: (type filename): the environment variable to set
+ * @value: (type filename): the value for to set the variable to.
+ *
+ * Arranges for @variable to be set to @value in the child's
+ * environment when @context is used to launch an application.
+ *
+ * Since: 2.32
+ */
+void
+g_app_launch_context_setenv (GAppLaunchContext *context,
+                             const char        *variable,
+                             const char        *value)
+{
+  g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context));
+  g_return_if_fail (variable != NULL);
+  g_return_if_fail (value != NULL);
+
+  if (!context->priv->envp)
+    context->priv->envp = g_get_environ ();
+
+  context->priv->envp =
+    g_environ_setenv (context->priv->envp, variable, value, TRUE);
+}
+
+/**
+ * g_app_launch_context_unsetenv:
+ * @context: a #GAppLaunchContext
+ * @variable: (type filename): the environment variable to remove
+ *
+ * Arranges for @variable to be unset in the child's environment
+ * when @context is used to launch an application.
+ *
+ * Since: 2.32
+ */
+void
+g_app_launch_context_unsetenv (GAppLaunchContext *context,
+                               const char        *variable)
+{
+  g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context));
+  g_return_if_fail (variable != NULL);
+
+  if (!context->priv->envp)
+    context->priv->envp = g_get_environ ();
+
+  context->priv->envp =
+    g_environ_unsetenv (context->priv->envp, variable);
+}
+
+/**
+ * g_app_launch_context_get_environment:
+ * @context: a #GAppLaunchContext
+ *
+ * Gets the complete environment variable list to be passed to
+ * the child process when @context is used to launch an application.
+ * This is a %NULL-terminated array of strings, where each string has
+ * the form `KEY=VALUE`.
+ *
+ * Returns: (array zero-terminated=1) (element-type filename) (transfer full):
+ *     the child's environment
+ *
+ * Since: 2.32
+ */
+char **
+g_app_launch_context_get_environment (GAppLaunchContext *context)
+{
+  g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
+
+  if (!context->priv->envp)
+    context->priv->envp = g_get_environ ();
+
+  return g_strdupv (context->priv->envp);
+}
+
+/**
+ * g_app_launch_context_get_display:
+ * @context: a #GAppLaunchContext
+ * @info: a #GAppInfo
+ * @files: (element-type GFile): a #GList of #GFile objects
+ *
+ * Gets the display string for the @context. This is used to ensure new
+ * applications are started on the same display as the launching
+ * application, by setting the `DISPLAY` environment variable.
+ *
+ * Returns: a display string for the display.
+ */
+char *
+g_app_launch_context_get_display (GAppLaunchContext *context,
+				  GAppInfo          *info,
+				  GList             *files)
+{
+  GAppLaunchContextClass *class;
+
+  g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
+  g_return_val_if_fail (G_IS_APP_INFO (info), NULL);
+
+  class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
+
+  if (class->get_display == NULL)
+    return NULL;
+
+  return class->get_display (context, info, files);
+}
+
+/**
+ * g_app_launch_context_get_startup_notify_id:
+ * @context: a #GAppLaunchContext
+ * @info: a #GAppInfo
+ * @files: (element-type GFile): a #GList of of #GFile objects
+ * 
+ * Initiates startup notification for the application and returns the
+ * `DESKTOP_STARTUP_ID` for the launched operation, if supported.
+ *
+ * Startup notification IDs are defined in the 
+ * [FreeDesktop.Org Startup Notifications standard](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt).
+ *
+ * Returns: a startup notification ID for the application, or %NULL if
+ *     not supported.
+ **/
+char *
+g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
+					    GAppInfo          *info,
+					    GList             *files)
+{
+  GAppLaunchContextClass *class;
+
+  g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
+  g_return_val_if_fail (G_IS_APP_INFO (info), NULL);
+
+  class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
+
+  if (class->get_startup_notify_id == NULL)
+    return NULL;
+
+  return class->get_startup_notify_id (context, info, files);
+}
+
+
+/**
+ * g_app_launch_context_launch_failed:
+ * @context: a #GAppLaunchContext.
+ * @startup_notify_id: the startup notification id that was returned by g_app_launch_context_get_startup_notify_id().
+ *
+ * Called when an application has failed to launch, so that it can cancel
+ * the application startup notification started in g_app_launch_context_get_startup_notify_id().
+ * 
+ **/
+void
+g_app_launch_context_launch_failed (GAppLaunchContext *context,
+				    const char        *startup_notify_id)
+{
+  g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context));
+  g_return_if_fail (startup_notify_id != NULL);
+
+  g_signal_emit (context, signals[LAUNCH_FAILED], 0, startup_notify_id);
+}
+
+
+/**
+ * SECTION:gappinfomonitor
+ * @short_description: Monitor application information for changes
+ *
+ * #GAppInfoMonitor is a very simple object used for monitoring the app
+ * info database for changes (ie: newly installed or removed
+ * applications).
+ *
+ * Call g_app_info_monitor_get() to get a #GAppInfoMonitor and connect
+ * to the "changed" signal.
+ *
+ * In the usual case, applications should try to make note of the change
+ * (doing things like invalidating caches) but not act on it.  In
+ * particular, applications should avoid making calls to #GAppInfo APIs
+ * in response to the change signal, deferring these until the time that
+ * the data is actually required.  The exception to this case is when
+ * application information is actually being displayed on the screen
+ * (eg: during a search or when the list of all applications is shown).
+ * The reason for this is that changes to the list of installed
+ * applications often come in groups (like during system updates) and
+ * rescanning the list on every change is pointless and expensive.
+ *
+ * Since: 2.40
+ **/
+
+/**
+ * GAppInfoMonitor:
+ *
+ * The only thing you can do with this is to get it via
+ * g_app_info_monitor_get() and connect to the "changed" signal.
+ *
+ * Since: 2.40
+ **/
+
+typedef struct _GAppInfoMonitorClass GAppInfoMonitorClass;
+
+struct _GAppInfoMonitor
+{
+  GObject parent_instance;
+  GMainContext *context;
+};
+
+struct _GAppInfoMonitorClass
+{
+  GObjectClass parent_class;
+};
+
+static GContextSpecificGroup g_app_info_monitor_group;
+static guint                 g_app_info_monitor_changed_signal;
+
+G_DEFINE_TYPE (GAppInfoMonitor, g_app_info_monitor, G_TYPE_OBJECT)
+
+static void
+g_app_info_monitor_finalize (GObject *object)
+{
+  GAppInfoMonitor *monitor = G_APP_INFO_MONITOR (object);
+
+  g_context_specific_group_remove (&g_app_info_monitor_group, monitor->context, monitor, NULL);
+
+  G_OBJECT_CLASS (g_app_info_monitor_parent_class)->finalize (object);
+}
+
+static void
+g_app_info_monitor_init (GAppInfoMonitor *monitor)
+{
+}
+
+static void
+g_app_info_monitor_class_init (GAppInfoMonitorClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  /**
+   * GAppInfoMonitor::changed:
+   *
+   * Signal emitted when the app info database for changes (ie: newly installed
+   * or removed applications).
+   **/
+  g_app_info_monitor_changed_signal = g_signal_new (I_("changed"), G_TYPE_APP_INFO_MONITOR, G_SIGNAL_RUN_FIRST,
+                                                    0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+  object_class->finalize = g_app_info_monitor_finalize;
+}
+
+/**
+ * g_app_info_monitor_get:
+ *
+ * Gets the #GAppInfoMonitor for the current thread-default main
+ * context.
+ *
+ * The #GAppInfoMonitor will emit a "changed" signal in the
+ * thread-default main context whenever the list of installed
+ * applications (as reported by g_app_info_get_all()) may have changed.
+ *
+ * You must only call g_object_unref() on the return value from under
+ * the same main context as you created it.
+ *
+ * Returns: (transfer full): a reference to a #GAppInfoMonitor
+ *
+ * Since: 2.40
+ **/
+GAppInfoMonitor *
+g_app_info_monitor_get (void)
+{
+  return g_context_specific_group_get (&g_app_info_monitor_group,
+                                       G_TYPE_APP_INFO_MONITOR,
+                                       G_STRUCT_OFFSET (GAppInfoMonitor, context),
+                                       NULL);
+}
+
+void
+g_app_info_monitor_fire (void)
+{
+  g_context_specific_group_emit (&g_app_info_monitor_group, g_app_info_monitor_changed_signal);
+}
diff --git a/gio/gappinfo.h b/gio/gappinfo.h
new file mode 100644
index 0000000..d26d048
--- /dev/null
+++ b/gio/gappinfo.h
@@ -0,0 +1,347 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_APP_INFO_H__
+#define __G_APP_INFO_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_APP_INFO            (g_app_info_get_type ())
+#define G_APP_INFO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_APP_INFO, GAppInfo))
+#define G_IS_APP_INFO(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_APP_INFO))
+#define G_APP_INFO_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_APP_INFO, GAppInfoIface))
+
+#define G_TYPE_APP_LAUNCH_CONTEXT         (g_app_launch_context_get_type ())
+#define G_APP_LAUNCH_CONTEXT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContext))
+#define G_APP_LAUNCH_CONTEXT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContextClass))
+#define G_IS_APP_LAUNCH_CONTEXT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_APP_LAUNCH_CONTEXT))
+#define G_IS_APP_LAUNCH_CONTEXT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_APP_LAUNCH_CONTEXT))
+#define G_APP_LAUNCH_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContextClass))
+
+typedef struct _GAppLaunchContextClass   GAppLaunchContextClass;
+typedef struct _GAppLaunchContextPrivate GAppLaunchContextPrivate;
+
+/**
+ * GAppInfo:
+ *
+ * Information about an installed application and methods to launch
+ * it (with file arguments).
+ */
+
+/**
+ * GAppInfoIface:
+ * @g_iface: The parent interface.
+ * @dup: Copies a #GAppInfo.
+ * @equal: Checks two #GAppInfos for equality.
+ * @get_id: Gets a string identifier for a #GAppInfo.
+ * @get_name: Gets the name of the application for a #GAppInfo.
+ * @get_description: Gets a short description for the application described by the #GAppInfo.
+ * @get_executable: Gets the executable name for the #GAppInfo.
+ * @get_icon: Gets the #GIcon for the #GAppInfo.
+ * @launch: Launches an application specified by the #GAppInfo.
+ * @supports_uris: Indicates whether the application specified supports launching URIs.
+ * @supports_files: Indicates whether the application specified accepts filename arguments.
+ * @launch_uris: Launches an application with a list of URIs.
+ * @should_show: Returns whether an application should be shown (e.g. when getting a list of installed applications).
+ * [FreeDesktop.Org Startup Notification Specification](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt).
+ * @set_as_default_for_type: Sets an application as default for a given content type.
+ * @set_as_default_for_extension: Sets an application as default for a given file extension.
+ * @add_supports_type: Adds to the #GAppInfo information about supported file types.
+ * @can_remove_supports_type: Checks for support for removing supported file types from a #GAppInfo.
+ * @remove_supports_type: Removes a supported application type from a #GAppInfo.
+ * @can_delete: Checks if a #GAppInfo can be deleted. Since 2.20
+ * @do_delete: Deletes a #GAppInfo. Since 2.20
+ * @get_commandline: Gets the commandline for the #GAppInfo. Since 2.20
+ * @get_display_name: Gets the display name for the #GAppInfo. Since 2.24
+ * @set_as_last_used_for_type: Sets the application as the last used. See g_app_info_set_as_last_used_for_type().
+ * @get_supported_types: Retrieves the list of content types that @app_info claims to support.
+ * @launch_uris_async: Asynchronously launches an application with a list of URIs. (Since: 2.60)
+ * @launch_uris_finish: Finishes an operation started with @launch_uris_async. (Since: 2.60)
+
+ * Application Information interface, for operating system portability.
+ */
+typedef struct _GAppInfoIface    GAppInfoIface;
+
+struct _GAppInfoIface
+{
+  GTypeInterface g_iface;
+
+  /* Virtual Table */
+
+  GAppInfo *   (* dup)                          (GAppInfo           *appinfo);
+  gboolean     (* equal)                        (GAppInfo           *appinfo1,
+                                                 GAppInfo           *appinfo2);
+  const char * (* get_id)                       (GAppInfo           *appinfo);
+  const char * (* get_name)                     (GAppInfo           *appinfo);
+  const char * (* get_description)              (GAppInfo           *appinfo);
+  const char * (* get_executable)               (GAppInfo           *appinfo);
+  GIcon *      (* get_icon)                     (GAppInfo           *appinfo);
+  gboolean     (* launch)                       (GAppInfo           *appinfo,
+                                                 GList              *files,
+                                                 GAppLaunchContext  *context,
+                                                 GError            **error);
+  gboolean     (* supports_uris)                (GAppInfo           *appinfo);
+  gboolean     (* supports_files)               (GAppInfo           *appinfo);
+  gboolean     (* launch_uris)                  (GAppInfo           *appinfo,
+                                                 GList              *uris,
+                                                 GAppLaunchContext  *context,
+                                                 GError            **error);
+  gboolean     (* should_show)                  (GAppInfo           *appinfo);
+
+  /* For changing associations */
+  gboolean     (* set_as_default_for_type)      (GAppInfo           *appinfo,
+                                                 const char         *content_type,
+                                                 GError            **error);
+  gboolean     (* set_as_default_for_extension) (GAppInfo           *appinfo,
+                                                 const char         *extension,
+                                                 GError            **error);
+  gboolean     (* add_supports_type)            (GAppInfo           *appinfo,
+                                                 const char         *content_type,
+                                                 GError            **error);
+  gboolean     (* can_remove_supports_type)     (GAppInfo           *appinfo);
+  gboolean     (* remove_supports_type)         (GAppInfo           *appinfo,
+                                                 const char         *content_type,
+                                                 GError            **error);
+  gboolean     (* can_delete)                   (GAppInfo           *appinfo);
+  gboolean     (* do_delete)                    (GAppInfo           *appinfo);
+  const char * (* get_commandline)              (GAppInfo           *appinfo);
+  const char * (* get_display_name)             (GAppInfo           *appinfo);
+  gboolean     (* set_as_last_used_for_type)    (GAppInfo           *appinfo,
+                                                 const char         *content_type,
+                                                 GError            **error);
+  const char ** (* get_supported_types)         (GAppInfo           *appinfo);
+  void         (* launch_uris_async)            (GAppInfo           *appinfo,
+                                                 GList              *uris,
+                                                 GAppLaunchContext  *context,
+                                                 GCancellable       *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer            user_data);
+  gboolean     (* launch_uris_finish)           (GAppInfo           *appinfo,
+                                                 GAsyncResult       *result,
+                                                 GError            **error);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType       g_app_info_get_type                     (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GAppInfo *  g_app_info_create_from_commandline      (const char           *commandline,
+                                                     const char           *application_name,
+                                                     GAppInfoCreateFlags   flags,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_ALL
+GAppInfo *  g_app_info_dup                          (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_equal                        (GAppInfo             *appinfo1,
+                                                     GAppInfo             *appinfo2);
+GLIB_AVAILABLE_IN_ALL
+const char *g_app_info_get_id                       (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+const char *g_app_info_get_name                     (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+const char *g_app_info_get_display_name             (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+const char *g_app_info_get_description              (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+const char *g_app_info_get_executable               (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+const char *g_app_info_get_commandline              (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+GIcon *     g_app_info_get_icon                     (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_launch                       (GAppInfo             *appinfo,
+                                                     GList                *files,
+                                                     GAppLaunchContext    *context,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_supports_uris                (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_supports_files               (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_launch_uris                  (GAppInfo             *appinfo,
+                                                     GList                *uris,
+                                                     GAppLaunchContext    *context,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_2_60
+void        g_app_info_launch_uris_async            (GAppInfo             *appinfo,
+                                                     GList                *uris,
+                                                     GAppLaunchContext    *context,
+                                                     GCancellable         *cancellable,
+                                                     GAsyncReadyCallback   callback,
+                                                     gpointer              user_data);
+GLIB_AVAILABLE_IN_2_60
+gboolean    g_app_info_launch_uris_finish           (GAppInfo             *appinfo,
+                                                     GAsyncResult         *result,
+                                                     GError              **error);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_should_show                  (GAppInfo             *appinfo);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_set_as_default_for_type      (GAppInfo             *appinfo,
+                                                     const char           *content_type,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_set_as_default_for_extension (GAppInfo             *appinfo,
+                                                     const char           *extension,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_add_supports_type            (GAppInfo             *appinfo,
+                                                     const char           *content_type,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_can_remove_supports_type     (GAppInfo             *appinfo);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_remove_supports_type         (GAppInfo             *appinfo,
+                                                     const char           *content_type,
+                                                     GError              **error);
+GLIB_AVAILABLE_IN_2_34
+const char **g_app_info_get_supported_types         (GAppInfo             *appinfo);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_can_delete                   (GAppInfo   *appinfo);
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_delete                       (GAppInfo   *appinfo);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean    g_app_info_set_as_last_used_for_type    (GAppInfo             *appinfo,
+                                                     const char           *content_type,
+                                                     GError              **error);
+
+GLIB_AVAILABLE_IN_ALL
+GList *   g_app_info_get_all                     (void);
+GLIB_AVAILABLE_IN_ALL
+GList *   g_app_info_get_all_for_type            (const char  *content_type);
+GLIB_AVAILABLE_IN_ALL
+GList *   g_app_info_get_recommended_for_type    (const gchar *content_type);
+GLIB_AVAILABLE_IN_ALL
+GList *   g_app_info_get_fallback_for_type       (const gchar *content_type);
+
+GLIB_AVAILABLE_IN_ALL
+void      g_app_info_reset_type_associations     (const char  *content_type);
+GLIB_AVAILABLE_IN_ALL
+GAppInfo *g_app_info_get_default_for_type        (const char  *content_type,
+                                                  gboolean     must_support_uris);
+GLIB_AVAILABLE_IN_ALL
+GAppInfo *g_app_info_get_default_for_uri_scheme  (const char  *uri_scheme);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean  g_app_info_launch_default_for_uri      (const char              *uri,
+                                                  GAppLaunchContext       *context,
+                                                  GError                 **error);
+
+GLIB_AVAILABLE_IN_2_50
+void      g_app_info_launch_default_for_uri_async  (const char           *uri,
+                                                    GAppLaunchContext    *context,
+                                                    GCancellable         *cancellable,
+                                                    GAsyncReadyCallback   callback,
+                                                    gpointer              user_data);
+GLIB_AVAILABLE_IN_2_50
+gboolean  g_app_info_launch_default_for_uri_finish (GAsyncResult         *result,
+                                                    GError              **error);
+
+
+/**
+ * GAppLaunchContext:
+ *
+ * Integrating the launch with the launching application. This is used to
+ * handle for instance startup notification and launching the new application
+ * on the same screen as the launching window.
+ */
+struct _GAppLaunchContext
+{
+  GObject parent_instance;
+
+  /*< private >*/
+  GAppLaunchContextPrivate *priv;
+};
+
+struct _GAppLaunchContextClass
+{
+  GObjectClass parent_class;
+
+  char * (* get_display)           (GAppLaunchContext *context,
+                                    GAppInfo          *info,
+                                    GList             *files);
+  char * (* get_startup_notify_id) (GAppLaunchContext *context,
+                                    GAppInfo          *info,
+                                    GList             *files);
+  void   (* launch_failed)         (GAppLaunchContext *context,
+                                    const char        *startup_notify_id);
+  void   (* launched)              (GAppLaunchContext *context,
+                                    GAppInfo          *info,
+                                    GVariant          *platform_data);
+
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType              g_app_launch_context_get_type              (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GAppLaunchContext *g_app_launch_context_new                   (void);
+
+GLIB_AVAILABLE_IN_2_32
+void               g_app_launch_context_setenv                (GAppLaunchContext *context,
+                                                               const char        *variable,
+                                                               const char        *value);
+GLIB_AVAILABLE_IN_2_32
+void               g_app_launch_context_unsetenv              (GAppLaunchContext *context,
+                                                               const char        *variable);
+GLIB_AVAILABLE_IN_2_32
+char **            g_app_launch_context_get_environment       (GAppLaunchContext *context);
+
+GLIB_AVAILABLE_IN_ALL
+char *             g_app_launch_context_get_display           (GAppLaunchContext *context,
+                                                               GAppInfo          *info,
+                                                               GList             *files);
+GLIB_AVAILABLE_IN_ALL
+char *             g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
+                                                               GAppInfo          *info,
+                                                               GList             *files);
+GLIB_AVAILABLE_IN_ALL
+void               g_app_launch_context_launch_failed         (GAppLaunchContext *context,
+                                                               const char *       startup_notify_id);
+
+#define G_TYPE_APP_INFO_MONITOR                             (g_app_info_monitor_get_type ())
+#define G_APP_INFO_MONITOR(inst)                            (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
+                                                             G_TYPE_APP_INFO_MONITOR, GAppInfoMonitor))
+#define G_IS_APP_INFO_MONITOR(inst)                         (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
+                                                             G_TYPE_APP_INFO_MONITOR))
+
+typedef struct _GAppInfoMonitor                             GAppInfoMonitor;
+
+GLIB_AVAILABLE_IN_2_40
+GType                   g_app_info_monitor_get_type                     (void);
+
+GLIB_AVAILABLE_IN_2_40
+GAppInfoMonitor *       g_app_info_monitor_get                          (void);
+
+G_END_DECLS
+
+#endif /* __G_APP_INFO_H__ */
diff --git a/gio/gappinfoprivate.h b/gio/gappinfoprivate.h
new file mode 100644
index 0000000..f8b0f48
--- /dev/null
+++ b/gio/gappinfoprivate.h
@@ -0,0 +1,26 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2013 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_APP_INFO_PRIVATE_H__
+#define __G_APP_INFO_PRIVATE_H__
+
+void g_app_info_monitor_fire (void);
+
+#endif /* __G_APP_INFO_PRIVATE_H__ */
diff --git a/gio/gapplication-tool.c b/gio/gapplication-tool.c
new file mode 100644
index 0000000..68a7424
--- /dev/null
+++ b/gio/gapplication-tool.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright © 2013 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include <gio/gdesktopappinfo.h>
+
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+
+#include <string.h>
+#include <locale.h>
+
+struct help_topic
+{
+  const gchar *command;
+  const gchar *summary;
+  const gchar *description;
+  const gchar *synopsis;
+};
+
+struct help_substvar
+{
+  const gchar *var;
+  const gchar *description;
+};
+
+static const struct help_topic topics[] = {
+  { "help",         N_("Print help"),
+                    N_("Print help"),
+                    N_("[COMMAND]")
+  },
+  { "version",      N_("Print version"),
+                    N_("Print version information and exit")
+  },
+  { "list-apps",    N_("List applications"),
+                    N_("List the installed D-Bus activatable applications (by .desktop files)")
+  },
+  { "launch",       N_("Launch an application"),
+                    N_("Launch the application (with optional files to open)"),
+                    N_("APPID [FILE…]")
+  },
+  { "action",       N_("Activate an action"),
+                    N_("Invoke an action on the application"),
+                    N_("APPID ACTION [PARAMETER]")
+  },
+  { "list-actions", N_("List available actions"),
+                    N_("List static actions for an application (from .desktop file)"),
+                    N_("APPID")
+  }
+};
+
+static const struct help_substvar substvars[] = {
+  { N_("COMMAND"),   N_("The command to print detailed help for")                             },
+  { N_("APPID"),     N_("Application identifier in D-Bus format (eg: org.example.viewer)")    },
+  { N_("FILE"),      N_("Optional relative or absolute filenames, or URIs to open")           },
+  { N_("ACTION"),    N_("The action name to invoke")                                          },
+  { N_("PARAMETER"), N_("Optional parameter to the action invocation, in GVariant format")    }
+};
+
+static int
+app_help (gboolean     requested,
+          const gchar *command)
+{
+  const struct help_topic *topic = NULL;
+  GString *string;
+
+  string = g_string_new (NULL);
+
+  if (command)
+    {
+      gint i;
+
+      for (i = 0; i < G_N_ELEMENTS (topics); i++)
+        if (g_str_equal (topics[i].command, command))
+          topic = &topics[i];
+
+      if (!topic)
+        {
+          g_string_printf (string, _("Unknown command %s\n\n"), command);
+          requested = FALSE;
+        }
+    }
+
+  g_string_append (string, _("Usage:\n"));
+
+  if (topic)
+    {
+      gint maxwidth;
+      gint i;
+
+      g_string_append_printf (string, "\n  %s %s %s\n\n", "gapplication",
+                              topic->command, topic->synopsis ? _(topic->synopsis) : "");
+      g_string_append_printf (string, "%s\n\n", _(topic->description));
+
+      if (topic->synopsis)
+        {
+          g_string_append (string, _("Arguments:\n"));
+
+          maxwidth = 0;
+          for (i = 0; i < G_N_ELEMENTS (substvars); i++)
+            if (strstr (topic->synopsis, substvars[i].var))
+              maxwidth = MAX(maxwidth, strlen (_(substvars[i].var)));
+
+          for (i = 0; i < G_N_ELEMENTS (substvars); i++)
+            if (strstr (topic->synopsis, substvars[i].var))
+              g_string_append_printf (string, "  %-*.*s   %s\n", maxwidth, maxwidth,
+                                      _(substvars[i].var), _(substvars[i].description));
+          g_string_append (string, "\n");
+        }
+    }
+  else
+    {
+      gint maxwidth;
+      gint i;
+
+      g_string_append_printf (string, "\n  %s %s %s\n\n", "gapplication", _("COMMAND"), _("[ARGS…]"));
+      g_string_append_printf (string, _("Commands:\n"));
+
+      maxwidth = 0;
+      for (i = 0; i < G_N_ELEMENTS (topics); i++)
+        maxwidth = MAX(maxwidth, strlen (topics[i].command));
+
+      for (i = 0; i < G_N_ELEMENTS (topics); i++)
+        g_string_append_printf (string, "  %-*.*s   %s\n", maxwidth, maxwidth,
+                                topics[i].command, _(topics[i].summary));
+
+      g_string_append (string, "\n");
+      /* Translators: do not translate 'help', but please translate 'COMMAND'. */
+      g_string_append_printf (string, _("Use “%s help COMMAND” to get detailed help.\n\n"), "gapplication");
+    }
+
+  if (requested)
+    g_print ("%s", string->str);
+  else
+    g_printerr ("%s\n", string->str);
+
+  g_string_free (string, TRUE);
+
+  return requested ? 0 : 1;
+}
+
+static gboolean
+app_check_name (gchar       **args,
+                const gchar  *command)
+{
+  if (args[0] == NULL)
+    {
+      g_printerr (_("%s command requires an application id to directly follow\n\n"), command);
+      return FALSE;
+    }
+
+  if (!g_dbus_is_name (args[0]))
+    {
+      g_printerr (_("invalid application id: “%s”\n"), args[0]);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static int
+app_no_args (const gchar *command)
+{
+  /* Translators: %s is replaced with a command name like 'list-actions' */
+  g_printerr (_("“%s” takes no arguments\n\n"), command);
+  return app_help (FALSE, command);
+}
+
+static int
+app_version (gchar **args)
+{
+  if (g_strv_length (args))
+    return app_no_args ("version");
+
+  g_print (PACKAGE_VERSION "\n");
+  return 0;
+}
+
+static int
+app_list (gchar **args)
+{
+  GList *apps;
+
+  if (g_strv_length (args))
+    return app_no_args ("list");
+
+  apps = g_app_info_get_all ();
+
+  while (apps)
+    {
+      GDesktopAppInfo *info = apps->data;
+
+      if (G_IS_DESKTOP_APP_INFO (info))
+        if (g_desktop_app_info_get_boolean (info, "DBusActivatable"))
+          {
+            const gchar *filename;
+
+            filename = g_app_info_get_id (G_APP_INFO (info));
+            if (g_str_has_suffix (filename, ".desktop"))
+              {
+                gchar *id;
+
+                id = g_strndup (filename, strlen (filename) - 8);
+                g_print ("%s\n", id);
+                g_free (id);
+              }
+          }
+
+      apps = g_list_delete_link (apps, apps);
+      g_object_unref (info);
+    }
+
+  return 0;
+}
+
+static gchar *
+app_path_for_id (const gchar *app_id)
+{
+  gchar *path;
+  gint i;
+
+  path = g_strconcat ("/", app_id, NULL);
+  for (i = 0; path[i]; i++)
+    {
+      if (path[i] == '.')
+        path[i] = '/';
+      if (path[i] == '-')
+        path[i] = '_';
+    }
+
+  return path;
+}
+
+static int
+app_call (const gchar *app_id,
+          const gchar *method_name,
+          GVariant    *parameters)
+{
+  GDBusConnection *session;
+  GError *error = NULL;
+  gchar *object_path;
+  GVariant *result;
+
+
+  session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+  if (!session)
+    {
+      g_variant_unref (g_variant_ref_sink (parameters));
+      g_printerr (_("unable to connect to D-Bus: %s\n"), error->message);
+      g_error_free (error);
+      return 1;
+    }
+
+  object_path = app_path_for_id (app_id);
+
+  result = g_dbus_connection_call_sync (session, app_id, object_path, "org.freedesktop.Application",
+                                        method_name, parameters, G_VARIANT_TYPE_UNIT,
+                                        G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+  g_free (object_path);
+
+  if (result)
+    {
+      g_variant_unref (result);
+      return 0;
+    }
+  else
+    {
+      g_printerr (_("error sending %s message to application: %s\n"), method_name, error->message);
+      g_error_free (error);
+      return 1;
+    }
+}
+
+static GVariant *
+app_get_platform_data (void)
+{
+  GVariantBuilder builder;
+  const gchar *startup_id;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+
+  if ((startup_id = g_getenv ("DESKTOP_STARTUP_ID")))
+    g_variant_builder_add (&builder, "{sv}", "desktop-startup-id", g_variant_new_string (startup_id));
+
+  return g_variant_builder_end (&builder);
+}
+
+static int
+app_action (gchar **args)
+{
+  GVariantBuilder params;
+  const gchar *name;
+
+  if (!app_check_name (args, "action"))
+    return 1;
+
+  if (args[1] == NULL)
+    {
+      g_printerr (_("action name must be given after application id\n"));
+      return 1;
+    }
+
+  name = args[1];
+
+  if (!g_action_name_is_valid (name))
+    {
+      g_printerr (_("invalid action name: “%s”\n"
+                    "action names must consist of only alphanumerics, “-” and “.”\n"), name);
+      return 1;
+    }
+
+  g_variant_builder_init (&params, G_VARIANT_TYPE ("av"));
+
+  if (args[2])
+    {
+      GError *error = NULL;
+      GVariant *parameter;
+
+      parameter = g_variant_parse (NULL, args[2], NULL, NULL, &error);
+
+      if (!parameter)
+        {
+          gchar *context;
+
+          context = g_variant_parse_error_print_context (error, args[2]);
+          g_printerr (_("error parsing action parameter: %s\n"), context);
+          g_variant_builder_clear (&params);
+          g_error_free (error);
+          g_free (context);
+          return 1;
+        }
+
+      g_variant_builder_add (&params, "v", parameter);
+      g_variant_unref (parameter);
+
+      if (args[3])
+        {
+          g_printerr (_("actions accept a maximum of one parameter\n"));
+          g_variant_builder_clear (&params);
+          return 1;
+        }
+    }
+
+  return app_call (args[0], "ActivateAction", g_variant_new ("(sav@a{sv})", name, &params, app_get_platform_data ()));
+}
+
+static int
+app_activate (const gchar *app_id)
+{
+  return app_call (app_id, "Activate", g_variant_new ("(@a{sv})", app_get_platform_data ()));
+}
+
+static int
+app_launch (gchar **args)
+{
+  GVariantBuilder files;
+  gint i;
+
+  if (!app_check_name (args, "launch"))
+    return 1;
+
+  if (args[1] == NULL)
+    return app_activate (args[0]);
+
+  g_variant_builder_init (&files, G_VARIANT_TYPE_STRING_ARRAY);
+
+  for (i = 1; args[i]; i++)
+    {
+      GFile *file;
+
+      /* "This operation never fails" */
+      file = g_file_new_for_commandline_arg (args[i]);
+      g_variant_builder_add_value (&files, g_variant_new_take_string (g_file_get_uri (file)));
+      g_object_unref (file);
+    }
+
+  return app_call (args[0], "Open", g_variant_new ("(as@a{sv})", &files, app_get_platform_data ()));
+}
+
+static int
+app_list_actions (gchar **args)
+{
+  const gchar * const *actions;
+  GDesktopAppInfo *app_info;
+  gchar *filename;
+  gint i;
+
+  if (!app_check_name (args, "list-actions"))
+    return 1;
+
+  if (args[1])
+    {
+      g_printerr (_("list-actions command takes only the application id"));
+      app_help (FALSE, "list-actions");
+    }
+
+  filename = g_strconcat (args[0], ".desktop", NULL);
+  app_info = g_desktop_app_info_new (filename);
+  g_free (filename);
+
+  if (app_info == NULL)
+    {
+      g_printerr (_("unable to find desktop file for application %s\n"), args[0]);
+      return 1;
+    }
+
+  actions = g_desktop_app_info_list_actions (app_info);
+
+  for (i = 0; actions[i]; i++)
+    g_print ("%s\n", actions[i]);
+
+  g_object_unref (app_info);
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  setlocale (LC_ALL, "");
+  textdomain (GETTEXT_PACKAGE);
+  bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif
+
+  if (argc < 2)
+    return app_help (TRUE, NULL);
+
+  if (g_str_equal (argv[1], "help"))
+    return app_help (TRUE, argv[2]);
+
+  if (g_str_equal (argv[1], "version"))
+    return app_version (argv + 2);
+
+  if (g_str_equal (argv[1], "list-apps"))
+    return app_list (argv + 2);
+
+  if (g_str_equal (argv[1], "launch"))
+    return app_launch (argv + 2);
+
+  if (g_str_equal (argv[1], "action"))
+    return app_action (argv + 2);
+
+  if (g_str_equal (argv[1], "list-actions"))
+    return app_list_actions (argv + 2);
+
+  g_printerr (_("unrecognised command: %s\n\n"), argv[1]);
+
+  return app_help (FALSE, NULL);
+}
diff --git a/gio/gapplication.c b/gio/gapplication.c
new file mode 100644
index 0000000..b78fd9a
--- /dev/null
+++ b/gio/gapplication.c
@@ -0,0 +1,3116 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+/* Prologue {{{1 */
+#include "config.h"
+
+#include "gapplication.h"
+
+#include "gapplicationcommandline.h"
+#include "gsimpleactiongroup.h"
+#include "gremoteactiongroup.h"
+#include "gapplicationimpl.h"
+#include "gactiongroup.h"
+#include "gactionmap.h"
+#include "gsettings.h"
+#include "gnotification-private.h"
+#include "gnotificationbackend.h"
+#include "gdbusutils.h"
+
+#include "gioenumtypes.h"
+#include "gioenums.h"
+#include "gfile.h"
+
+#include "glibintl.h"
+#include "gmarshal-internal.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gapplication
+ * @title: GApplication
+ * @short_description: Core application class
+ * @include: gio/gio.h
+ *
+ * A #GApplication is the foundation of an application.  It wraps some
+ * low-level platform-specific services and is intended to act as the
+ * foundation for higher-level application classes such as
+ * #GtkApplication or #MxApplication.  In general, you should not use
+ * this class outside of a higher level framework.
+ *
+ * GApplication provides convenient life cycle management by maintaining
+ * a "use count" for the primary application instance. The use count can
+ * be changed using g_application_hold() and g_application_release(). If
+ * it drops to zero, the application exits. Higher-level classes such as
+ * #GtkApplication employ the use count to ensure that the application
+ * stays alive as long as it has any opened windows.
+ *
+ * Another feature that GApplication (optionally) provides is process
+ * uniqueness. Applications can make use of this functionality by
+ * providing a unique application ID. If given, only one application
+ * with this ID can be running at a time per session. The session
+ * concept is platform-dependent, but corresponds roughly to a graphical
+ * desktop login. When your application is launched again, its
+ * arguments are passed through platform communication to the already
+ * running program. The already running instance of the program is
+ * called the "primary instance"; for non-unique applications this is
+ * always the current instance. On Linux, the D-Bus session bus
+ * is used for communication.
+ *
+ * The use of #GApplication differs from some other commonly-used
+ * uniqueness libraries (such as libunique) in important ways. The
+ * application is not expected to manually register itself and check
+ * if it is the primary instance. Instead, the main() function of a
+ * #GApplication should do very little more than instantiating the
+ * application instance, possibly connecting signal handlers, then
+ * calling g_application_run(). All checks for uniqueness are done
+ * internally. If the application is the primary instance then the
+ * startup signal is emitted and the mainloop runs. If the application
+ * is not the primary instance then a signal is sent to the primary
+ * instance and g_application_run() promptly returns. See the code
+ * examples below.
+ *
+ * If used, the expected form of an application identifier is the same as
+ * that of of a
+ * [D-Bus well-known bus name](https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus).
+ * Examples include: `com.example.MyApp`, `org.example.internal_apps.Calculator`,
+ * `org._7_zip.Archiver`.
+ * For details on valid application identifiers, see g_application_id_is_valid().
+ *
+ * On Linux, the application identifier is claimed as a well-known bus name
+ * on the user's session bus.  This means that the uniqueness of your
+ * application is scoped to the current session.  It also means that your
+ * application may provide additional services (through registration of other
+ * object paths) at that bus name.  The registration of these object paths
+ * should be done with the shared GDBus session bus.  Note that due to the
+ * internal architecture of GDBus, method calls can be dispatched at any time
+ * (even if a main loop is not running).  For this reason, you must ensure that
+ * any object paths that you wish to register are registered before #GApplication
+ * attempts to acquire the bus name of your application (which happens in
+ * g_application_register()).  Unfortunately, this means that you cannot use
+ * g_application_get_is_remote() to decide if you want to register object paths.
+ *
+ * GApplication also implements the #GActionGroup and #GActionMap
+ * interfaces and lets you easily export actions by adding them with
+ * g_action_map_add_action(). When invoking an action by calling
+ * g_action_group_activate_action() on the application, it is always
+ * invoked in the primary instance. The actions are also exported on
+ * the session bus, and GIO provides the #GDBusActionGroup wrapper to
+ * conveniently access them remotely. GIO provides a #GDBusMenuModel wrapper
+ * for remote access to exported #GMenuModels.
+ *
+ * There is a number of different entry points into a GApplication:
+ *
+ * - via 'Activate' (i.e. just starting the application)
+ *
+ * - via 'Open' (i.e. opening some files)
+ *
+ * - by handling a command-line
+ *
+ * - via activating an action
+ *
+ * The #GApplication::startup signal lets you handle the application
+ * initialization for all of these in a single place.
+ *
+ * Regardless of which of these entry points is used to start the
+ * application, GApplication passes some ‘platform data’ from the
+ * launching instance to the primary instance, in the form of a
+ * #GVariant dictionary mapping strings to variants. To use platform
+ * data, override the @before_emit or @after_emit virtual functions
+ * in your #GApplication subclass. When dealing with
+ * #GApplicationCommandLine objects, the platform data is
+ * directly available via g_application_command_line_get_cwd(),
+ * g_application_command_line_get_environ() and
+ * g_application_command_line_get_platform_data().
+ *
+ * As the name indicates, the platform data may vary depending on the
+ * operating system, but it always includes the current directory (key
+ * "cwd"), and optionally the environment (ie the set of environment
+ * variables and their values) of the calling process (key "environ").
+ * The environment is only added to the platform data if the
+ * %G_APPLICATION_SEND_ENVIRONMENT flag is set. #GApplication subclasses
+ * can add their own platform data by overriding the @add_platform_data
+ * virtual function. For instance, #GtkApplication adds startup notification
+ * data in this way.
+ *
+ * To parse commandline arguments you may handle the
+ * #GApplication::command-line signal or override the local_command_line()
+ * vfunc, to parse them in either the primary instance or the local instance,
+ * respectively.
+ *
+ * For an example of opening files with a GApplication, see
+ * [gapplication-example-open.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-open.c).
+ *
+ * For an example of using actions with GApplication, see
+ * [gapplication-example-actions.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-actions.c).
+ *
+ * For an example of using extra D-Bus hooks with GApplication, see
+ * [gapplication-example-dbushooks.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-dbushooks.c).
+ */
+
+/**
+ * GApplication:
+ *
+ * #GApplication is an opaque data structure and can only be accessed
+ * using the following functions.
+ * Since: 2.28
+ */
+
+/**
+ * GApplicationClass:
+ * @startup: invoked on the primary instance immediately after registration
+ * @shutdown: invoked only on the registered primary instance immediately
+ *      after the main loop terminates
+ * @activate: invoked on the primary instance when an activation occurs
+ * @open: invoked on the primary instance when there are files to open
+ * @command_line: invoked on the primary instance when a command-line is
+ *   not handled locally
+ * @local_command_line: invoked (locally). The virtual function has the chance
+ *     to inspect (and possibly replace) command line arguments. See
+ *     g_application_run() for more information. Also see the
+ *     #GApplication::handle-local-options signal, which is a simpler
+ *     alternative to handling some commandline options locally
+ * @before_emit: invoked on the primary instance before 'activate', 'open',
+ *     'command-line' or any action invocation, gets the 'platform data' from
+ *     the calling instance
+ * @after_emit: invoked on the primary instance after 'activate', 'open',
+ *     'command-line' or any action invocation, gets the 'platform data' from
+ *     the calling instance
+ * @add_platform_data: invoked (locally) to add 'platform data' to be sent to
+ *     the primary instance when activating, opening or invoking actions
+ * @quit_mainloop: Used to be invoked on the primary instance when the use
+ *     count of the application drops to zero (and after any inactivity
+ *     timeout, if requested). Not used anymore since 2.32
+ * @run_mainloop: Used to be invoked on the primary instance from
+ *     g_application_run() if the use-count is non-zero. Since 2.32,
+ *     GApplication is iterating the main context directly and is not
+ *     using @run_mainloop anymore
+ * @dbus_register: invoked locally during registration, if the application is
+ *     using its D-Bus backend. You can use this to export extra objects on the
+ *     bus, that need to exist before the application tries to own the bus name.
+ *     The function is passed the #GDBusConnection to to session bus, and the
+ *     object path that #GApplication will use to export is D-Bus API.
+ *     If this function returns %TRUE, registration will proceed; otherwise
+ *     registration will abort. Since: 2.34
+ * @dbus_unregister: invoked locally during unregistration, if the application
+ *     is using its D-Bus backend. Use this to undo anything done by
+ *     the @dbus_register vfunc. Since: 2.34
+ * @handle_local_options: invoked locally after the parsing of the commandline
+ *  options has occurred. Since: 2.40
+ * @name_lost: invoked when another instance is taking over the name. Since: 2.60
+ *
+ * Virtual function table for #GApplication.
+ *
+ * Since: 2.28
+ */
+
+struct _GApplicationPrivate
+{
+  GApplicationFlags  flags;
+  gchar             *id;
+  gchar             *resource_path;
+
+  GActionGroup      *actions;
+
+  guint              inactivity_timeout_id;
+  guint              inactivity_timeout;
+  guint              use_count;
+  guint              busy_count;
+
+  guint              is_registered : 1;
+  guint              is_remote : 1;
+  guint              did_startup : 1;
+  guint              did_shutdown : 1;
+  guint              must_quit_now : 1;
+
+  GRemoteActionGroup *remote_actions;
+  GApplicationImpl   *impl;
+
+  GNotificationBackend *notifications;
+
+  /* GOptionContext support */
+  GOptionGroup       *main_options;
+  GSList             *option_groups;
+  GHashTable         *packed_options;
+  gboolean            options_parsed;
+  gchar              *parameter_string;
+  gchar              *summary;
+  gchar              *description;
+
+  /* Allocated option strings, from g_application_add_main_option() */
+  GSList             *option_strings;
+};
+
+enum
+{
+  PROP_NONE,
+  PROP_APPLICATION_ID,
+  PROP_FLAGS,
+  PROP_RESOURCE_BASE_PATH,
+  PROP_IS_REGISTERED,
+  PROP_IS_REMOTE,
+  PROP_INACTIVITY_TIMEOUT,
+  PROP_ACTION_GROUP,
+  PROP_IS_BUSY
+};
+
+enum
+{
+  SIGNAL_STARTUP,
+  SIGNAL_SHUTDOWN,
+  SIGNAL_ACTIVATE,
+  SIGNAL_OPEN,
+  SIGNAL_ACTION,
+  SIGNAL_COMMAND_LINE,
+  SIGNAL_HANDLE_LOCAL_OPTIONS,
+  SIGNAL_NAME_LOST,
+  NR_SIGNALS
+};
+
+static guint g_application_signals[NR_SIGNALS];
+
+static void g_application_action_group_iface_init (GActionGroupInterface *);
+static void g_application_action_map_iface_init (GActionMapInterface *);
+G_DEFINE_TYPE_WITH_CODE (GApplication, g_application, G_TYPE_OBJECT,
+ G_ADD_PRIVATE (GApplication)
+ G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_application_action_group_iface_init)
+ G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_MAP, g_application_action_map_iface_init))
+
+/* GApplicationExportedActions {{{1 */
+
+/* We create a subclass of GSimpleActionGroup that implements
+ * GRemoteActionGroup and deals with the platform data using
+ * GApplication's before/after_emit vfuncs.  This is the action group we
+ * will be exporting.
+ *
+ * We could implement GRemoteActionGroup on GApplication directly, but
+ * this would be potentially extremely confusing to have exposed as part
+ * of the public API of GApplication.  We certainly don't want anyone in
+ * the same process to be calling these APIs...
+ */
+typedef GSimpleActionGroupClass GApplicationExportedActionsClass;
+typedef struct
+{
+  GSimpleActionGroup parent_instance;
+  GApplication *application;
+} GApplicationExportedActions;
+
+static GType g_application_exported_actions_get_type   (void);
+static void  g_application_exported_actions_iface_init (GRemoteActionGroupInterface *iface);
+G_DEFINE_TYPE_WITH_CODE (GApplicationExportedActions, g_application_exported_actions, G_TYPE_SIMPLE_ACTION_GROUP,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_REMOTE_ACTION_GROUP, g_application_exported_actions_iface_init))
+
+static void
+g_application_exported_actions_activate_action_full (GRemoteActionGroup *remote,
+                                                     const gchar        *action_name,
+                                                     GVariant           *parameter,
+                                                     GVariant           *platform_data)
+{
+  GApplicationExportedActions *exported = (GApplicationExportedActions *) remote;
+
+  G_APPLICATION_GET_CLASS (exported->application)
+    ->before_emit (exported->application, platform_data);
+
+  g_action_group_activate_action (G_ACTION_GROUP (exported), action_name, parameter);
+
+  G_APPLICATION_GET_CLASS (exported->application)
+    ->after_emit (exported->application, platform_data);
+}
+
+static void
+g_application_exported_actions_change_action_state_full (GRemoteActionGroup *remote,
+                                                         const gchar        *action_name,
+                                                         GVariant           *value,
+                                                         GVariant           *platform_data)
+{
+  GApplicationExportedActions *exported = (GApplicationExportedActions *) remote;
+
+  G_APPLICATION_GET_CLASS (exported->application)
+    ->before_emit (exported->application, platform_data);
+
+  g_action_group_change_action_state (G_ACTION_GROUP (exported), action_name, value);
+
+  G_APPLICATION_GET_CLASS (exported->application)
+    ->after_emit (exported->application, platform_data);
+}
+
+static void
+g_application_exported_actions_init (GApplicationExportedActions *actions)
+{
+}
+
+static void
+g_application_exported_actions_iface_init (GRemoteActionGroupInterface *iface)
+{
+  iface->activate_action_full = g_application_exported_actions_activate_action_full;
+  iface->change_action_state_full = g_application_exported_actions_change_action_state_full;
+}
+
+static void
+g_application_exported_actions_class_init (GApplicationExportedActionsClass *class)
+{
+}
+
+static GActionGroup *
+g_application_exported_actions_new (GApplication *application)
+{
+  GApplicationExportedActions *actions;
+
+  actions = g_object_new (g_application_exported_actions_get_type (), NULL);
+  actions->application = application;
+
+  return G_ACTION_GROUP (actions);
+}
+
+/* Command line option handling {{{1 */
+
+static void
+free_option_entry (gpointer data)
+{
+  GOptionEntry *entry = data;
+
+  switch (entry->arg)
+    {
+    case G_OPTION_ARG_STRING:
+    case G_OPTION_ARG_FILENAME:
+      g_free (*(gchar **) entry->arg_data);
+      break;
+
+    case G_OPTION_ARG_STRING_ARRAY:
+    case G_OPTION_ARG_FILENAME_ARRAY:
+      g_strfreev (*(gchar ***) entry->arg_data);
+      break;
+
+    default:
+      /* most things require no free... */
+      break;
+    }
+
+  /* ...except for the space that we allocated for it ourselves */
+  g_free (entry->arg_data);
+
+  g_slice_free (GOptionEntry, entry);
+}
+
+static void
+g_application_pack_option_entries (GApplication *application,
+                                   GVariantDict *dict)
+{
+  GHashTableIter iter;
+  gpointer item;
+
+  g_hash_table_iter_init (&iter, application->priv->packed_options);
+  while (g_hash_table_iter_next (&iter, NULL, &item))
+    {
+      GOptionEntry *entry = item;
+      GVariant *value = NULL;
+
+      switch (entry->arg)
+        {
+        case G_OPTION_ARG_NONE:
+          if (*(gboolean *) entry->arg_data != 2)
+            value = g_variant_new_boolean (*(gboolean *) entry->arg_data);
+          break;
+
+        case G_OPTION_ARG_STRING:
+          if (*(gchar **) entry->arg_data)
+            value = g_variant_new_string (*(gchar **) entry->arg_data);
+          break;
+
+        case G_OPTION_ARG_INT:
+          if (*(gint32 *) entry->arg_data)
+            value = g_variant_new_int32 (*(gint32 *) entry->arg_data);
+          break;
+
+        case G_OPTION_ARG_FILENAME:
+          if (*(gchar **) entry->arg_data)
+            value = g_variant_new_bytestring (*(gchar **) entry->arg_data);
+          break;
+
+        case G_OPTION_ARG_STRING_ARRAY:
+          if (*(gchar ***) entry->arg_data)
+            value = g_variant_new_strv (*(const gchar ***) entry->arg_data, -1);
+          break;
+
+        case G_OPTION_ARG_FILENAME_ARRAY:
+          if (*(gchar ***) entry->arg_data)
+            value = g_variant_new_bytestring_array (*(const gchar ***) entry->arg_data, -1);
+          break;
+
+        case G_OPTION_ARG_DOUBLE:
+          if (*(gdouble *) entry->arg_data)
+            value = g_variant_new_double (*(gdouble *) entry->arg_data);
+          break;
+
+        case G_OPTION_ARG_INT64:
+          if (*(gint64 *) entry->arg_data)
+            value = g_variant_new_int64 (*(gint64 *) entry->arg_data);
+          break;
+
+        default:
+          g_assert_not_reached ();
+        }
+
+      if (value)
+        g_variant_dict_insert_value (dict, entry->long_name, value);
+    }
+}
+
+static GVariantDict *
+g_application_parse_command_line (GApplication   *application,
+                                  gchar        ***arguments,
+                                  GError        **error)
+{
+  gboolean become_service = FALSE;
+  gchar *app_id = NULL;
+  gboolean replace = FALSE;
+  GVariantDict *dict = NULL;
+  GOptionContext *context;
+  GOptionGroup *gapplication_group;
+
+  /* Due to the memory management of GOptionGroup we can only parse
+   * options once.  That's because once you add a group to the
+   * GOptionContext there is no way to get it back again.  This is fine:
+   * local_command_line() should never get invoked more than once
+   * anyway.  Add a sanity check just to be sure.
+   */
+  g_return_val_if_fail (!application->priv->options_parsed, NULL);
+
+  context = g_option_context_new (application->priv->parameter_string);
+  g_option_context_set_summary (context, application->priv->summary);
+  g_option_context_set_description (context, application->priv->description);
+
+  gapplication_group = g_option_group_new ("gapplication",
+                                           _("GApplication options"), _("Show GApplication options"),
+                                           NULL, NULL);
+  g_option_group_set_translation_domain (gapplication_group, GETTEXT_PACKAGE);
+  g_option_context_add_group (context, gapplication_group);
+
+  /* If the application has not registered local options and it has
+   * G_APPLICATION_HANDLES_COMMAND_LINE then we have to assume that
+   * their primary instance commandline handler may want to deal with
+   * the arguments.  We must therefore ignore them.
+   *
+   * We must also ignore --help in this case since some applications
+   * will try to handle this from the remote side.  See #737869.
+   */
+  if (application->priv->main_options == NULL && (application->priv->flags & G_APPLICATION_HANDLES_COMMAND_LINE))
+    {
+      g_option_context_set_ignore_unknown_options (context, TRUE);
+      g_option_context_set_help_enabled (context, FALSE);
+    }
+
+  /* Add the main option group, if it exists */
+  if (application->priv->main_options)
+    {
+      /* This consumes the main_options */
+      g_option_context_set_main_group (context, application->priv->main_options);
+      application->priv->main_options = NULL;
+    }
+
+  /* Add any other option groups if they exist.  Adding them to the
+   * context will consume them, so we free the list as we go...
+   */
+  while (application->priv->option_groups)
+    {
+      g_option_context_add_group (context, application->priv->option_groups->data);
+      application->priv->option_groups = g_slist_delete_link (application->priv->option_groups,
+                                                              application->priv->option_groups);
+    }
+
+  /* In the case that we are not explicitly marked as a service or a
+   * launcher then we want to add the "--gapplication-service" option to
+   * allow the process to be made into a service.
+   */
+  if ((application->priv->flags & (G_APPLICATION_IS_SERVICE | G_APPLICATION_IS_LAUNCHER)) == 0)
+    {
+      GOptionEntry entries[] = {
+        { "gapplication-service", '\0', 0, G_OPTION_ARG_NONE, &become_service,
+          N_("Enter GApplication service mode (use from D-Bus service files)") },
+        { NULL }
+      };
+
+      g_option_group_add_entries (gapplication_group, entries);
+    }
+
+  /* Allow overriding the ID if the application allows it */
+  if (application->priv->flags & G_APPLICATION_CAN_OVERRIDE_APP_ID)
+    {
+      GOptionEntry entries[] = {
+        { "gapplication-app-id", '\0', 0, G_OPTION_ARG_STRING, &app_id,
+          N_("Override the application’s ID") },
+        { NULL }
+      };
+
+      g_option_group_add_entries (gapplication_group, entries);
+    }
+
+  /* Allow replacing if the application allows it */
+  if (application->priv->flags & G_APPLICATION_ALLOW_REPLACEMENT)
+    {
+      GOptionEntry entries[] = {
+        { "gapplication-replace", '\0', 0, G_OPTION_ARG_NONE, &replace,
+          N_("Replace the running instance") },
+        { NULL }
+      };
+
+      g_option_group_add_entries (gapplication_group, entries);
+    }
+
+  /* Now we parse... */
+  if (!g_option_context_parse_strv (context, arguments, error))
+    goto out;
+
+  /* Check for --gapplication-service */
+  if (become_service)
+    application->priv->flags |= G_APPLICATION_IS_SERVICE;
+
+  /* Check for --gapplication-app-id */
+  if (app_id)
+    g_application_set_application_id (application, app_id);
+
+  /* Check for --gapplication-replace */
+  if (replace)
+    application->priv->flags |= G_APPLICATION_REPLACE;
+
+  dict = g_variant_dict_new (NULL);
+  if (application->priv->packed_options)
+    {
+      g_application_pack_option_entries (application, dict);
+      g_hash_table_unref (application->priv->packed_options);
+      application->priv->packed_options = NULL;
+    }
+
+out:
+  /* Make sure we don't run again */
+  application->priv->options_parsed = TRUE;
+
+  g_option_context_free (context);
+  g_free (app_id);
+
+  return dict;
+}
+
+static void
+add_packed_option (GApplication *application,
+                   GOptionEntry *entry)
+{
+  switch (entry->arg)
+    {
+    case G_OPTION_ARG_NONE:
+      entry->arg_data = g_new (gboolean, 1);
+      *(gboolean *) entry->arg_data = 2;
+      break;
+
+    case G_OPTION_ARG_INT:
+      entry->arg_data = g_new0 (gint, 1);
+      break;
+
+    case G_OPTION_ARG_STRING:
+    case G_OPTION_ARG_FILENAME:
+    case G_OPTION_ARG_STRING_ARRAY:
+    case G_OPTION_ARG_FILENAME_ARRAY:
+      entry->arg_data = g_new0 (gpointer, 1);
+      break;
+
+    case G_OPTION_ARG_INT64:
+      entry->arg_data = g_new0 (gint64, 1);
+      break;
+
+    case G_OPTION_ARG_DOUBLE:
+      entry->arg_data = g_new0 (gdouble, 1);
+      break;
+
+    default:
+      g_return_if_reached ();
+    }
+
+  if (!application->priv->packed_options)
+    application->priv->packed_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_option_entry);
+
+  g_hash_table_insert (application->priv->packed_options,
+                       g_strdup (entry->long_name),
+                       g_slice_dup (GOptionEntry, entry));
+}
+
+/**
+ * g_application_add_main_option_entries:
+ * @application: a #GApplication
+ * @entries: (array zero-terminated=1) (element-type GOptionEntry) a
+ *           %NULL-terminated list of #GOptionEntrys
+ *
+ * Adds main option entries to be handled by @application.
+ *
+ * This function is comparable to g_option_context_add_main_entries().
+ *
+ * After the commandline arguments are parsed, the
+ * #GApplication::handle-local-options signal will be emitted.  At this
+ * point, the application can inspect the values pointed to by @arg_data
+ * in the given #GOptionEntrys.
+ *
+ * Unlike #GOptionContext, #GApplication supports giving a %NULL
+ * @arg_data for a non-callback #GOptionEntry.  This results in the
+ * argument in question being packed into a #GVariantDict which is also
+ * passed to #GApplication::handle-local-options, where it can be
+ * inspected and modified.  If %G_APPLICATION_HANDLES_COMMAND_LINE is
+ * set, then the resulting dictionary is sent to the primary instance,
+ * where g_application_command_line_get_options_dict() will return it.
+ * This "packing" is done according to the type of the argument --
+ * booleans for normal flags, strings for strings, bytestrings for
+ * filenames, etc.  The packing only occurs if the flag is given (ie: we
+ * do not pack a "false" #GVariant in the case that a flag is missing).
+ *
+ * In general, it is recommended that all commandline arguments are
+ * parsed locally.  The options dictionary should then be used to
+ * transmit the result of the parsing to the primary instance, where
+ * g_variant_dict_lookup() can be used.  For local options, it is
+ * possible to either use @arg_data in the usual way, or to consult (and
+ * potentially remove) the option from the options dictionary.
+ *
+ * This function is new in GLib 2.40.  Before then, the only real choice
+ * was to send all of the commandline arguments (options and all) to the
+ * primary instance for handling.  #GApplication ignored them completely
+ * on the local side.  Calling this function "opts in" to the new
+ * behaviour, and in particular, means that unrecognised options will be
+ * treated as errors.  Unrecognised options have never been ignored when
+ * %G_APPLICATION_HANDLES_COMMAND_LINE is unset.
+ *
+ * If #GApplication::handle-local-options needs to see the list of
+ * filenames, then the use of %G_OPTION_REMAINING is recommended.  If
+ * @arg_data is %NULL then %G_OPTION_REMAINING can be used as a key into
+ * the options dictionary.  If you do use %G_OPTION_REMAINING then you
+ * need to handle these arguments for yourself because once they are
+ * consumed, they will no longer be visible to the default handling
+ * (which treats them as filenames to be opened).
+ *
+ * It is important to use the proper GVariant format when retrieving
+ * the options with g_variant_dict_lookup():
+ * - for %G_OPTION_ARG_NONE, use `b`
+ * - for %G_OPTION_ARG_STRING, use `&s`
+ * - for %G_OPTION_ARG_INT, use `i`
+ * - for %G_OPTION_ARG_INT64, use `x`
+ * - for %G_OPTION_ARG_DOUBLE, use `d`
+ * - for %G_OPTION_ARG_FILENAME, use `^&ay`
+ * - for %G_OPTION_ARG_STRING_ARRAY, use `^a&s`
+ * - for %G_OPTION_ARG_FILENAME_ARRAY, use `^a&ay`
+ *
+ * Since: 2.40
+ */
+void
+g_application_add_main_option_entries (GApplication       *application,
+                                       const GOptionEntry *entries)
+{
+  gint i;
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (entries != NULL);
+
+  if (!application->priv->main_options)
+    {
+      application->priv->main_options = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
+      g_option_group_set_translation_domain (application->priv->main_options, NULL);
+    }
+
+  for (i = 0; entries[i].long_name; i++)
+    {
+      GOptionEntry my_entries[2] = { { NULL }, { NULL } };
+      my_entries[0] = entries[i];
+
+      if (!my_entries[0].arg_data)
+        add_packed_option (application, &my_entries[0]);
+
+      g_option_group_add_entries (application->priv->main_options, my_entries);
+    }
+}
+
+/**
+ * g_application_add_main_option:
+ * @application: the #GApplication
+ * @long_name: the long name of an option used to specify it in a commandline
+ * @short_name: the short name of an option
+ * @flags: flags from #GOptionFlags
+ * @arg: the type of the option, as a #GOptionArg
+ * @description: the description for the option in `--help` output
+ * @arg_description: (nullable): the placeholder to use for the extra argument
+ *    parsed by the option in `--help` output
+ *
+ * Add an option to be handled by @application.
+ *
+ * Calling this function is the equivalent of calling
+ * g_application_add_main_option_entries() with a single #GOptionEntry
+ * that has its arg_data member set to %NULL.
+ *
+ * The parsed arguments will be packed into a #GVariantDict which
+ * is passed to #GApplication::handle-local-options. If
+ * %G_APPLICATION_HANDLES_COMMAND_LINE is set, then it will also
+ * be sent to the primary instance. See
+ * g_application_add_main_option_entries() for more details.
+ *
+ * See #GOptionEntry for more documentation of the arguments.
+ *
+ * Since: 2.42
+ **/
+void
+g_application_add_main_option (GApplication *application,
+                               const char   *long_name,
+                               char          short_name,
+                               GOptionFlags  flags,
+                               GOptionArg    arg,
+                               const char   *description,
+                               const char   *arg_description)
+{
+  gchar *dup_string;
+  GOptionEntry my_entry[2] = {
+    { NULL, short_name, flags, arg, NULL, NULL, NULL },
+    { NULL }
+  };
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (long_name != NULL);
+  g_return_if_fail (description != NULL);
+
+  my_entry[0].long_name = dup_string = g_strdup (long_name);
+  application->priv->option_strings = g_slist_prepend (application->priv->option_strings, dup_string);
+
+  my_entry[0].description = dup_string = g_strdup (description);
+  application->priv->option_strings = g_slist_prepend (application->priv->option_strings, dup_string);
+
+  my_entry[0].arg_description = dup_string = g_strdup (arg_description);
+  application->priv->option_strings = g_slist_prepend (application->priv->option_strings, dup_string);
+
+  g_application_add_main_option_entries (application, my_entry);
+}
+
+/**
+ * g_application_add_option_group:
+ * @application: the #GApplication
+ * @group: (transfer full): a #GOptionGroup
+ *
+ * Adds a #GOptionGroup to the commandline handling of @application.
+ *
+ * This function is comparable to g_option_context_add_group().
+ *
+ * Unlike g_application_add_main_option_entries(), this function does
+ * not deal with %NULL @arg_data and never transmits options to the
+ * primary instance.
+ *
+ * The reason for that is because, by the time the options arrive at the
+ * primary instance, it is typically too late to do anything with them.
+ * Taking the GTK option group as an example: GTK will already have been
+ * initialised by the time the #GApplication::command-line handler runs.
+ * In the case that this is not the first-running instance of the
+ * application, the existing instance may already have been running for
+ * a very long time.
+ *
+ * This means that the options from #GOptionGroup are only really usable
+ * in the case that the instance of the application being run is the
+ * first instance.  Passing options like `--display=` or `--gdk-debug=`
+ * on future runs will have no effect on the existing primary instance.
+ *
+ * Calling this function will cause the options in the supplied option
+ * group to be parsed, but it does not cause you to be "opted in" to the
+ * new functionality whereby unrecognised options are rejected even if
+ * %G_APPLICATION_HANDLES_COMMAND_LINE was given.
+ *
+ * Since: 2.40
+ **/
+void
+g_application_add_option_group (GApplication *application,
+                                GOptionGroup *group)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (group != NULL);
+
+  application->priv->option_groups = g_slist_prepend (application->priv->option_groups, group);
+}
+
+/**
+ * g_application_set_option_context_parameter_string:
+ * @application: the #GApplication
+ * @parameter_string: (nullable): a string which is displayed
+ *   in the first line of `--help` output, after the usage summary `programname [OPTION...]`.
+ *
+ * Sets the parameter string to be used by the commandline handling of @application.
+ *
+ * This function registers the argument to be passed to g_option_context_new()
+ * when the internal #GOptionContext of @application is created.
+ *
+ * See g_option_context_new() for more information about @parameter_string.
+ *
+ * Since: 2.56
+ */
+void
+g_application_set_option_context_parameter_string (GApplication *application,
+                                                   const gchar  *parameter_string)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  g_free (application->priv->parameter_string);
+  application->priv->parameter_string = g_strdup (parameter_string);
+}
+
+/**
+ * g_application_set_option_context_summary:
+ * @application: the #GApplication
+ * @summary: (nullable): a string to be shown in `--help` output
+ *  before the list of options, or %NULL
+ *
+ * Adds a summary to the @application option context.
+ *
+ * See g_option_context_set_summary() for more information.
+ *
+ * Since: 2.56
+ */
+void
+g_application_set_option_context_summary (GApplication *application,
+                                          const gchar  *summary)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  g_free (application->priv->summary);
+  application->priv->summary = g_strdup (summary);
+}
+
+/**
+ * g_application_set_option_context_description:
+ * @application: the #GApplication
+ * @description: (nullable): a string to be shown in `--help` output
+ *  after the list of options, or %NULL
+ *
+ * Adds a description to the @application option context.
+ *
+ * See g_option_context_set_description() for more information.
+ *
+ * Since: 2.56
+ */
+void
+g_application_set_option_context_description (GApplication *application,
+                                              const gchar  *description)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  g_free (application->priv->description);
+  application->priv->description = g_strdup (description);
+
+}
+
+
+/* vfunc defaults {{{1 */
+static void
+g_application_real_before_emit (GApplication *application,
+                                GVariant     *platform_data)
+{
+}
+
+static void
+g_application_real_after_emit (GApplication *application,
+                               GVariant     *platform_data)
+{
+}
+
+static void
+g_application_real_startup (GApplication *application)
+{
+  application->priv->did_startup = TRUE;
+}
+
+static void
+g_application_real_shutdown (GApplication *application)
+{
+  application->priv->did_shutdown = TRUE;
+}
+
+static void
+g_application_real_activate (GApplication *application)
+{
+  if (!g_signal_has_handler_pending (application,
+                                     g_application_signals[SIGNAL_ACTIVATE],
+                                     0, TRUE) &&
+      G_APPLICATION_GET_CLASS (application)->activate == g_application_real_activate)
+    {
+      static gboolean warned;
+
+      if (warned)
+        return;
+
+      g_warning ("Your application does not implement "
+                 "g_application_activate() and has no handlers connected "
+                 "to the 'activate' signal.  It should do one of these.");
+      warned = TRUE;
+    }
+}
+
+static void
+g_application_real_open (GApplication  *application,
+                         GFile        **files,
+                         gint           n_files,
+                         const gchar   *hint)
+{
+  if (!g_signal_has_handler_pending (application,
+                                     g_application_signals[SIGNAL_OPEN],
+                                     0, TRUE) &&
+      G_APPLICATION_GET_CLASS (application)->open == g_application_real_open)
+    {
+      static gboolean warned;
+
+      if (warned)
+        return;
+
+      g_warning ("Your application claims to support opening files "
+                 "but does not implement g_application_open() and has no "
+                 "handlers connected to the 'open' signal.");
+      warned = TRUE;
+    }
+}
+
+static int
+g_application_real_command_line (GApplication            *application,
+                                 GApplicationCommandLine *cmdline)
+{
+  if (!g_signal_has_handler_pending (application,
+                                     g_application_signals[SIGNAL_COMMAND_LINE],
+                                     0, TRUE) &&
+      G_APPLICATION_GET_CLASS (application)->command_line == g_application_real_command_line)
+    {
+      static gboolean warned;
+
+      if (warned)
+        return 1;
+
+      g_warning ("Your application claims to support custom command line "
+                 "handling but does not implement g_application_command_line() "
+                 "and has no handlers connected to the 'command-line' signal.");
+
+      warned = TRUE;
+    }
+
+    return 1;
+}
+
+static gint
+g_application_real_handle_local_options (GApplication *application,
+                                         GVariantDict *options)
+{
+  return -1;
+}
+
+static GVariant *
+get_platform_data (GApplication *application,
+                   GVariant     *options)
+{
+  GVariantBuilder *builder;
+  GVariant *result;
+
+  builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+
+  {
+    gchar *cwd = g_get_current_dir ();
+    g_variant_builder_add (builder, "{sv}", "cwd",
+                           g_variant_new_bytestring (cwd));
+    g_free (cwd);
+  }
+
+  if (application->priv->flags & G_APPLICATION_SEND_ENVIRONMENT)
+    {
+      GVariant *array;
+      gchar **envp;
+
+      envp = g_get_environ ();
+      array = g_variant_new_bytestring_array ((const gchar **) envp, -1);
+      g_strfreev (envp);
+
+      g_variant_builder_add (builder, "{sv}", "environ", array);
+    }
+
+  if (options)
+    g_variant_builder_add (builder, "{sv}", "options", options);
+
+  G_APPLICATION_GET_CLASS (application)->
+    add_platform_data (application, builder);
+
+  result = g_variant_builder_end (builder);
+  g_variant_builder_unref (builder);
+
+  return result;
+}
+
+static void
+g_application_call_command_line (GApplication        *application,
+                                 const gchar * const *arguments,
+                                 GVariant            *options,
+                                 gint                *exit_status)
+{
+  if (application->priv->is_remote)
+    {
+      GVariant *platform_data;
+
+      platform_data = get_platform_data (application, options);
+      *exit_status = g_application_impl_command_line (application->priv->impl, arguments, platform_data);
+    }
+  else
+    {
+      GApplicationCommandLine *cmdline;
+      GVariant *v;
+
+      v = g_variant_new_bytestring_array ((const gchar **) arguments, -1);
+      cmdline = g_object_new (G_TYPE_APPLICATION_COMMAND_LINE,
+                              "arguments", v,
+                              "options", options,
+                              NULL);
+      g_signal_emit (application, g_application_signals[SIGNAL_COMMAND_LINE], 0, cmdline, exit_status);
+      g_object_unref (cmdline);
+    }
+}
+
+static gboolean
+g_application_real_local_command_line (GApplication   *application,
+                                       gchar        ***arguments,
+                                       int            *exit_status)
+{
+  GError *error = NULL;
+  GVariantDict *options;
+  gint n_args;
+
+  options = g_application_parse_command_line (application, arguments, &error);
+  if (!options)
+    {
+      g_printerr ("%s\n", error->message);
+      *exit_status = 1;
+      return TRUE;
+    }
+
+  g_signal_emit (application, g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS], 0, options, exit_status);
+
+  if (*exit_status >= 0)
+    {
+      g_variant_dict_unref (options);
+      return TRUE;
+    }
+
+  if (!g_application_register (application, NULL, &error))
+    {
+      g_printerr ("Failed to register: %s\n", error->message);
+      g_variant_dict_unref (options);
+      g_error_free (error);
+      *exit_status = 1;
+      return TRUE;
+    }
+
+  n_args = g_strv_length (*arguments);
+
+  if (application->priv->flags & G_APPLICATION_IS_SERVICE)
+    {
+      if ((*exit_status = n_args > 1))
+        {
+          g_printerr ("GApplication service mode takes no arguments.\n");
+          application->priv->flags &= ~G_APPLICATION_IS_SERVICE;
+          *exit_status = 1;
+        }
+      else
+        *exit_status = 0;
+    }
+  else if (application->priv->flags & G_APPLICATION_HANDLES_COMMAND_LINE)
+    {
+      g_application_call_command_line (application,
+                                       (const gchar **) *arguments,
+                                       g_variant_dict_end (options),
+                                       exit_status);
+    }
+  else
+    {
+      if (n_args <= 1)
+        {
+          g_application_activate (application);
+          *exit_status = 0;
+        }
+
+      else
+        {
+          if (~application->priv->flags & G_APPLICATION_HANDLES_OPEN)
+            {
+              g_critical ("This application can not open files.");
+              *exit_status = 1;
+            }
+          else
+            {
+              GFile **files;
+              gint n_files;
+              gint i;
+
+              n_files = n_args - 1;
+              files = g_new (GFile *, n_files);
+
+              for (i = 0; i < n_files; i++)
+                files[i] = g_file_new_for_commandline_arg ((*arguments)[i + 1]);
+
+              g_application_open (application, files, n_files, "");
+
+              for (i = 0; i < n_files; i++)
+                g_object_unref (files[i]);
+              g_free (files);
+
+              *exit_status = 0;
+            }
+        }
+    }
+
+  g_variant_dict_unref (options);
+
+  return TRUE;
+}
+
+static void
+g_application_real_add_platform_data (GApplication    *application,
+                                      GVariantBuilder *builder)
+{
+}
+
+static gboolean
+g_application_real_dbus_register (GApplication    *application,
+                                  GDBusConnection *connection,
+                                  const gchar     *object_path,
+                                  GError         **error)
+{
+  return TRUE;
+}
+
+static void
+g_application_real_dbus_unregister (GApplication    *application,
+                                    GDBusConnection *connection,
+                                    const gchar     *object_path)
+{
+}
+
+static gboolean
+g_application_real_name_lost (GApplication *application)
+{
+  g_application_quit (application);
+  return TRUE;
+}
+
+/* GObject implementation stuff {{{1 */
+static void
+g_application_set_property (GObject      *object,
+                            guint         prop_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  GApplication *application = G_APPLICATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_APPLICATION_ID:
+      g_application_set_application_id (application,
+                                        g_value_get_string (value));
+      break;
+
+    case PROP_FLAGS:
+      g_application_set_flags (application, g_value_get_flags (value));
+      break;
+
+    case PROP_RESOURCE_BASE_PATH:
+      g_application_set_resource_base_path (application, g_value_get_string (value));
+      break;
+
+    case PROP_INACTIVITY_TIMEOUT:
+      g_application_set_inactivity_timeout (application,
+                                            g_value_get_uint (value));
+      break;
+
+    case PROP_ACTION_GROUP:
+      g_clear_object (&application->priv->actions);
+      application->priv->actions = g_value_dup_object (value);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+/**
+ * g_application_set_action_group:
+ * @application: a #GApplication
+ * @action_group: (nullable): a #GActionGroup, or %NULL
+ *
+ * This used to be how actions were associated with a #GApplication.
+ * Now there is #GActionMap for that.
+ *
+ * Since: 2.28
+ *
+ * Deprecated:2.32:Use the #GActionMap interface instead.  Never ever
+ * mix use of this API with use of #GActionMap on the same @application
+ * or things will go very badly wrong.  This function is known to
+ * introduce buggy behaviour (ie: signals not emitted on changes to the
+ * action group), so you should really use #GActionMap instead.
+ **/
+void
+g_application_set_action_group (GApplication *application,
+                                GActionGroup *action_group)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (!application->priv->is_registered);
+
+  if (application->priv->actions != NULL)
+    g_object_unref (application->priv->actions);
+
+  application->priv->actions = action_group;
+
+  if (application->priv->actions != NULL)
+    g_object_ref (application->priv->actions);
+}
+
+static void
+g_application_get_property (GObject    *object,
+                            guint       prop_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+  GApplication *application = G_APPLICATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_APPLICATION_ID:
+      g_value_set_string (value,
+                          g_application_get_application_id (application));
+      break;
+
+    case PROP_FLAGS:
+      g_value_set_flags (value,
+                         g_application_get_flags (application));
+      break;
+
+    case PROP_RESOURCE_BASE_PATH:
+      g_value_set_string (value, g_application_get_resource_base_path (application));
+      break;
+
+    case PROP_IS_REGISTERED:
+      g_value_set_boolean (value,
+                           g_application_get_is_registered (application));
+      break;
+
+    case PROP_IS_REMOTE:
+      g_value_set_boolean (value,
+                           g_application_get_is_remote (application));
+      break;
+
+    case PROP_INACTIVITY_TIMEOUT:
+      g_value_set_uint (value,
+                        g_application_get_inactivity_timeout (application));
+      break;
+
+    case PROP_IS_BUSY:
+      g_value_set_boolean (value, g_application_get_is_busy (application));
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+g_application_constructed (GObject *object)
+{
+  GApplication *application = G_APPLICATION (object);
+
+  if (g_application_get_default () == NULL)
+    g_application_set_default (application);
+
+  /* People should not set properties from _init... */
+  g_assert (application->priv->resource_path == NULL);
+
+  if (application->priv->id != NULL)
+    {
+      gint i;
+
+      application->priv->resource_path = g_strconcat ("/", application->priv->id, NULL);
+
+      for (i = 1; application->priv->resource_path[i]; i++)
+        if (application->priv->resource_path[i] == '.')
+          application->priv->resource_path[i] = '/';
+    }
+}
+
+static void
+g_application_dispose (GObject *object)
+{
+  GApplication *application = G_APPLICATION (object);
+
+  if (application->priv->impl != NULL &&
+      G_APPLICATION_GET_CLASS (application)->dbus_unregister != g_application_real_dbus_unregister)
+    {
+      static gboolean warned;
+
+      if (!warned)
+        {
+          g_warning ("Your application did not unregister from D-Bus before destruction. "
+                     "Consider using g_application_run().");
+        }
+
+      warned = TRUE;
+    }
+
+  G_OBJECT_CLASS (g_application_parent_class)->dispose (object);
+}
+
+static void
+g_application_finalize (GObject *object)
+{
+  GApplication *application = G_APPLICATION (object);
+
+  if (application->priv->inactivity_timeout_id)
+    g_source_remove (application->priv->inactivity_timeout_id);
+
+  g_slist_free_full (application->priv->option_groups, (GDestroyNotify) g_option_group_unref);
+  if (application->priv->main_options)
+    g_option_group_unref (application->priv->main_options);
+  if (application->priv->packed_options)
+    g_hash_table_unref (application->priv->packed_options);
+
+  g_free (application->priv->parameter_string);
+  g_free (application->priv->summary);
+  g_free (application->priv->description);
+
+  g_slist_free_full (application->priv->option_strings, g_free);
+
+  if (application->priv->impl)
+    g_application_impl_destroy (application->priv->impl);
+  g_free (application->priv->id);
+
+  if (g_application_get_default () == application)
+    g_application_set_default (NULL);
+
+  if (application->priv->actions)
+    g_object_unref (application->priv->actions);
+
+  g_clear_object (&application->priv->remote_actions);
+
+  if (application->priv->notifications)
+    g_object_unref (application->priv->notifications);
+
+  g_free (application->priv->resource_path);
+
+  G_OBJECT_CLASS (g_application_parent_class)
+    ->finalize (object);
+}
+
+static void
+g_application_init (GApplication *application)
+{
+  application->priv = g_application_get_instance_private (application);
+
+  application->priv->actions = g_application_exported_actions_new (application);
+
+  /* application->priv->actions is the one and only ref on the group, so when
+   * we dispose, the action group will die, disconnecting all signals.
+   */
+  g_signal_connect_swapped (application->priv->actions, "action-added",
+                            G_CALLBACK (g_action_group_action_added), application);
+  g_signal_connect_swapped (application->priv->actions, "action-enabled-changed",
+                            G_CALLBACK (g_action_group_action_enabled_changed), application);
+  g_signal_connect_swapped (application->priv->actions, "action-state-changed",
+                            G_CALLBACK (g_action_group_action_state_changed), application);
+  g_signal_connect_swapped (application->priv->actions, "action-removed",
+                            G_CALLBACK (g_action_group_action_removed), application);
+}
+
+static gboolean
+g_application_handle_local_options_accumulator (GSignalInvocationHint *ihint,
+                                                GValue                *return_accu,
+                                                const GValue          *handler_return,
+                                                gpointer               dummy)
+{
+  gint value;
+
+  value = g_value_get_int (handler_return);
+  g_value_set_int (return_accu, value);
+
+  return value < 0;
+}
+
+static void
+g_application_class_init (GApplicationClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->constructed = g_application_constructed;
+  object_class->dispose = g_application_dispose;
+  object_class->finalize = g_application_finalize;
+  object_class->get_property = g_application_get_property;
+  object_class->set_property = g_application_set_property;
+
+  class->before_emit = g_application_real_before_emit;
+  class->after_emit = g_application_real_after_emit;
+  class->startup = g_application_real_startup;
+  class->shutdown = g_application_real_shutdown;
+  class->activate = g_application_real_activate;
+  class->open = g_application_real_open;
+  class->command_line = g_application_real_command_line;
+  class->local_command_line = g_application_real_local_command_line;
+  class->handle_local_options = g_application_real_handle_local_options;
+  class->add_platform_data = g_application_real_add_platform_data;
+  class->dbus_register = g_application_real_dbus_register;
+  class->dbus_unregister = g_application_real_dbus_unregister;
+  class->name_lost = g_application_real_name_lost;
+
+  g_object_class_install_property (object_class, PROP_APPLICATION_ID,
+    g_param_spec_string ("application-id",
+                         P_("Application identifier"),
+                         P_("The unique identifier for the application"),
+                         NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_FLAGS,
+    g_param_spec_flags ("flags",
+                        P_("Application flags"),
+                        P_("Flags specifying the behaviour of the application"),
+                        G_TYPE_APPLICATION_FLAGS, G_APPLICATION_FLAGS_NONE,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_RESOURCE_BASE_PATH,
+    g_param_spec_string ("resource-base-path",
+                         P_("Resource base path"),
+                         P_("The base resource path for the application"),
+                         NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_IS_REGISTERED,
+    g_param_spec_boolean ("is-registered",
+                          P_("Is registered"),
+                          P_("If g_application_register() has been called"),
+                          FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_IS_REMOTE,
+    g_param_spec_boolean ("is-remote",
+                          P_("Is remote"),
+                          P_("If this application instance is remote"),
+                          FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_INACTIVITY_TIMEOUT,
+    g_param_spec_uint ("inactivity-timeout",
+                       P_("Inactivity timeout"),
+                       P_("Time (ms) to stay alive after becoming idle"),
+                       0, G_MAXUINT, 0,
+                       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_ACTION_GROUP,
+    g_param_spec_object ("action-group",
+                         P_("Action group"),
+                         P_("The group of actions that the application exports"),
+                         G_TYPE_ACTION_GROUP,
+                         G_PARAM_DEPRECATED | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GApplication:is-busy:
+   *
+   * Whether the application is currently marked as busy through
+   * g_application_mark_busy() or g_application_bind_busy_property().
+   *
+   * Since: 2.44
+   */
+  g_object_class_install_property (object_class, PROP_IS_BUSY,
+    g_param_spec_boolean ("is-busy",
+                          P_("Is busy"),
+                          P_("If this application is currently marked busy"),
+                          FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GApplication::startup:
+   * @application: the application
+   *
+   * The ::startup signal is emitted on the primary instance immediately
+   * after registration. See g_application_register().
+   */
+  g_application_signals[SIGNAL_STARTUP] =
+    g_signal_new (I_("startup"), G_TYPE_APPLICATION, G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GApplicationClass, startup),
+                  NULL, NULL, NULL, G_TYPE_NONE, 0);
+
+  /**
+   * GApplication::shutdown:
+   * @application: the application
+   *
+   * The ::shutdown signal is emitted only on the registered primary instance
+   * immediately after the main loop terminates.
+   */
+  g_application_signals[SIGNAL_SHUTDOWN] =
+    g_signal_new (I_("shutdown"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GApplicationClass, shutdown),
+                  NULL, NULL, NULL, G_TYPE_NONE, 0);
+
+  /**
+   * GApplication::activate:
+   * @application: the application
+   *
+   * The ::activate signal is emitted on the primary instance when an
+   * activation occurs. See g_application_activate().
+   */
+  g_application_signals[SIGNAL_ACTIVATE] =
+    g_signal_new (I_("activate"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GApplicationClass, activate),
+                  NULL, NULL, NULL, G_TYPE_NONE, 0);
+
+
+  /**
+   * GApplication::open:
+   * @application: the application
+   * @files: (array length=n_files) (element-type GFile): an array of #GFiles
+   * @n_files: the length of @files
+   * @hint: a hint provided by the calling instance
+   *
+   * The ::open signal is emitted on the primary instance when there are
+   * files to open. See g_application_open() for more information.
+   */
+  g_application_signals[SIGNAL_OPEN] =
+    g_signal_new (I_("open"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GApplicationClass, open),
+                  NULL, NULL,
+                  _g_cclosure_marshal_VOID__POINTER_INT_STRING,
+                  G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING);
+  g_signal_set_va_marshaller (g_application_signals[SIGNAL_OPEN],
+                              G_TYPE_FROM_CLASS (class),
+                              _g_cclosure_marshal_VOID__POINTER_INT_STRINGv);
+
+  /**
+   * GApplication::command-line:
+   * @application: the application
+   * @command_line: a #GApplicationCommandLine representing the
+   *     passed commandline
+   *
+   * The ::command-line signal is emitted on the primary instance when
+   * a commandline is not handled locally. See g_application_run() and
+   * the #GApplicationCommandLine documentation for more information.
+   *
+   * Returns: An integer that is set as the exit status for the calling
+   *   process. See g_application_command_line_set_exit_status().
+   */
+  g_application_signals[SIGNAL_COMMAND_LINE] =
+    g_signal_new (I_("command-line"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GApplicationClass, command_line),
+                  g_signal_accumulator_first_wins, NULL,
+                  _g_cclosure_marshal_INT__OBJECT,
+                  G_TYPE_INT, 1, G_TYPE_APPLICATION_COMMAND_LINE);
+  g_signal_set_va_marshaller (g_application_signals[SIGNAL_COMMAND_LINE],
+                              G_TYPE_FROM_CLASS (class),
+                              _g_cclosure_marshal_INT__OBJECTv);
+
+  /**
+   * GApplication::handle-local-options:
+   * @application: the application
+   * @options: the options dictionary
+   *
+   * The ::handle-local-options signal is emitted on the local instance
+   * after the parsing of the commandline options has occurred.
+   *
+   * You can add options to be recognised during commandline option
+   * parsing using g_application_add_main_option_entries() and
+   * g_application_add_option_group().
+   *
+   * Signal handlers can inspect @options (along with values pointed to
+   * from the @arg_data of an installed #GOptionEntrys) in order to
+   * decide to perform certain actions, including direct local handling
+   * (which may be useful for options like --version).
+   *
+   * In the event that the application is marked
+   * %G_APPLICATION_HANDLES_COMMAND_LINE the "normal processing" will
+   * send the @options dictionary to the primary instance where it can be
+   * read with g_application_command_line_get_options_dict().  The signal
+   * handler can modify the dictionary before returning, and the
+   * modified dictionary will be sent.
+   *
+   * In the event that %G_APPLICATION_HANDLES_COMMAND_LINE is not set,
+   * "normal processing" will treat the remaining uncollected command
+   * line arguments as filenames or URIs.  If there are no arguments,
+   * the application is activated by g_application_activate().  One or
+   * more arguments results in a call to g_application_open().
+   *
+   * If you want to handle the local commandline arguments for yourself
+   * by converting them to calls to g_application_open() or
+   * g_action_group_activate_action() then you must be sure to register
+   * the application first.  You should probably not call
+   * g_application_activate() for yourself, however: just return -1 and
+   * allow the default handler to do it for you.  This will ensure that
+   * the `--gapplication-service` switch works properly (i.e. no activation
+   * in that case).
+   *
+   * Note that this signal is emitted from the default implementation of
+   * local_command_line().  If you override that function and don't
+   * chain up then this signal will never be emitted.
+   *
+   * You can override local_command_line() if you need more powerful
+   * capabilities than what is provided here, but this should not
+   * normally be required.
+   *
+   * Returns: an exit code. If you have handled your options and want
+   * to exit the process, return a non-negative option, 0 for success,
+   * and a positive value for failure. To continue, return -1 to let
+   * the default option processing continue.
+   *
+   * Since: 2.40
+   **/
+  g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS] =
+    g_signal_new (I_("handle-local-options"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GApplicationClass, handle_local_options),
+                  g_application_handle_local_options_accumulator, NULL,
+                  _g_cclosure_marshal_INT__BOXED,
+                  G_TYPE_INT, 1, G_TYPE_VARIANT_DICT);
+  g_signal_set_va_marshaller (g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS],
+                              G_TYPE_FROM_CLASS (class),
+                              _g_cclosure_marshal_INT__BOXEDv);
+
+  /**
+   * GApplication::name-lost:
+   * @application: the application
+   *
+   * The ::name-lost signal is emitted only on the registered primary instance
+   * when a new instance has taken over. This can only happen if the application
+   * is using the %G_APPLICATION_ALLOW_REPLACEMENT flag.
+   *
+   * The default handler for this signal calls g_application_quit().
+   *
+   * Returns: %TRUE if the signal has been handled
+   *
+   * Since: 2.60
+   */
+  g_application_signals[SIGNAL_NAME_LOST] =
+    g_signal_new (I_("name-lost"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GApplicationClass, name_lost),
+                  g_signal_accumulator_true_handled, NULL,
+                  _g_cclosure_marshal_BOOLEAN__VOID,
+                  G_TYPE_BOOLEAN, 0);
+  g_signal_set_va_marshaller (g_application_signals[SIGNAL_NAME_LOST],
+                              G_TYPE_FROM_CLASS (class),
+                              _g_cclosure_marshal_BOOLEAN__VOIDv);
+}
+
+/* Application ID validity {{{1 */
+
+/**
+ * g_application_id_is_valid:
+ * @application_id: a potential application identifier
+ *
+ * Checks if @application_id is a valid application identifier.
+ *
+ * A valid ID is required for calls to g_application_new() and
+ * g_application_set_application_id().
+ *
+ * Application identifiers follow the same format as
+ * [D-Bus well-known bus names](https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus).
+ * For convenience, the restrictions on application identifiers are
+ * reproduced here:
+ *
+ * - Application identifiers are composed of 1 or more elements separated by a
+ *   period (`.`) character. All elements must contain at least one character.
+ *
+ * - Each element must only contain the ASCII characters `[A-Z][a-z][0-9]_-`,
+ *   with `-` discouraged in new application identifiers. Each element must not
+ *   begin with a digit.
+ *
+ * - Application identifiers must contain at least one `.` (period) character
+ *   (and thus at least two elements).
+ *
+ * - Application identifiers must not begin with a `.` (period) character.
+ *
+ * - Application identifiers must not exceed 255 characters.
+ *
+ * Note that the hyphen (`-`) character is allowed in application identifiers,
+ * but is problematic or not allowed in various specifications and APIs that
+ * refer to D-Bus, such as
+ * [Flatpak application IDs](http://docs.flatpak.org/en/latest/introduction.html#identifiers),
+ * the
+ * [`DBusActivatable` interface in the Desktop Entry Specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#dbus),
+ * and the convention that an application's "main" interface and object path
+ * resemble its application identifier and bus name. To avoid situations that
+ * require special-case handling, it is recommended that new application
+ * identifiers consistently replace hyphens with underscores.
+ *
+ * Like D-Bus interface names, application identifiers should start with the
+ * reversed DNS domain name of the author of the interface (in lower-case), and
+ * it is conventional for the rest of the application identifier to consist of
+ * words run together, with initial capital letters.
+ *
+ * As with D-Bus interface names, if the author's DNS domain name contains
+ * hyphen/minus characters they should be replaced by underscores, and if it
+ * contains leading digits they should be escaped by prepending an underscore.
+ * For example, if the owner of 7-zip.org used an application identifier for an
+ * archiving application, it might be named `org._7_zip.Archiver`.
+ *
+ * Returns: %TRUE if @application_id is valid
+ */
+gboolean
+g_application_id_is_valid (const gchar *application_id)
+{
+  return g_dbus_is_name (application_id) &&
+         !g_dbus_is_unique_name (application_id);
+}
+
+/* Public Constructor {{{1 */
+/**
+ * g_application_new:
+ * @application_id: (nullable): the application id
+ * @flags: the application flags
+ *
+ * Creates a new #GApplication instance.
+ *
+ * If non-%NULL, the application id must be valid.  See
+ * g_application_id_is_valid().
+ *
+ * If no application ID is given then some features of #GApplication
+ * (most notably application uniqueness) will be disabled.
+ *
+ * Returns: a new #GApplication instance
+ **/
+GApplication *
+g_application_new (const gchar       *application_id,
+                   GApplicationFlags  flags)
+{
+  g_return_val_if_fail (application_id == NULL || g_application_id_is_valid (application_id), NULL);
+
+  return g_object_new (G_TYPE_APPLICATION,
+                       "application-id", application_id,
+                       "flags", flags,
+                       NULL);
+}
+
+/* Simple get/set: application id, flags, inactivity timeout {{{1 */
+/**
+ * g_application_get_application_id:
+ * @application: a #GApplication
+ *
+ * Gets the unique identifier for @application.
+ *
+ * Returns: the identifier for @application, owned by @application
+ *
+ * Since: 2.28
+ **/
+const gchar *
+g_application_get_application_id (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
+
+  return application->priv->id;
+}
+
+/**
+ * g_application_set_application_id:
+ * @application: a #GApplication
+ * @application_id: (nullable): the identifier for @application
+ *
+ * Sets the unique identifier for @application.
+ *
+ * The application id can only be modified if @application has not yet
+ * been registered.
+ *
+ * If non-%NULL, the application id must be valid.  See
+ * g_application_id_is_valid().
+ *
+ * Since: 2.28
+ **/
+void
+g_application_set_application_id (GApplication *application,
+                                  const gchar  *application_id)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  if (g_strcmp0 (application->priv->id, application_id) != 0)
+    {
+      g_return_if_fail (application_id == NULL || g_application_id_is_valid (application_id));
+      g_return_if_fail (!application->priv->is_registered);
+
+      g_free (application->priv->id);
+      application->priv->id = g_strdup (application_id);
+
+      g_object_notify (G_OBJECT (application), "application-id");
+    }
+}
+
+/**
+ * g_application_get_flags:
+ * @application: a #GApplication
+ *
+ * Gets the flags for @application.
+ *
+ * See #GApplicationFlags.
+ *
+ * Returns: the flags for @application
+ *
+ * Since: 2.28
+ **/
+GApplicationFlags
+g_application_get_flags (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), 0);
+
+  return application->priv->flags;
+}
+
+/**
+ * g_application_set_flags:
+ * @application: a #GApplication
+ * @flags: the flags for @application
+ *
+ * Sets the flags for @application.
+ *
+ * The flags can only be modified if @application has not yet been
+ * registered.
+ *
+ * See #GApplicationFlags.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_set_flags (GApplication      *application,
+                         GApplicationFlags  flags)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  if (application->priv->flags != flags)
+    {
+      g_return_if_fail (!application->priv->is_registered);
+
+      application->priv->flags = flags;
+
+      g_object_notify (G_OBJECT (application), "flags");
+    }
+}
+
+/**
+ * g_application_get_resource_base_path:
+ * @application: a #GApplication
+ *
+ * Gets the resource base path of @application.
+ *
+ * See g_application_set_resource_base_path() for more information.
+ *
+ * Returns: (nullable): the base resource path, if one is set
+ *
+ * Since: 2.42
+ */
+const gchar *
+g_application_get_resource_base_path (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
+
+  return application->priv->resource_path;
+}
+
+/**
+ * g_application_set_resource_base_path:
+ * @application: a #GApplication
+ * @resource_path: (nullable): the resource path to use
+ *
+ * Sets (or unsets) the base resource path of @application.
+ *
+ * The path is used to automatically load various [application
+ * resources][gresource] such as menu layouts and action descriptions.
+ * The various types of resources will be found at fixed names relative
+ * to the given base path.
+ *
+ * By default, the resource base path is determined from the application
+ * ID by prefixing '/' and replacing each '.' with '/'.  This is done at
+ * the time that the #GApplication object is constructed.  Changes to
+ * the application ID after that point will not have an impact on the
+ * resource base path.
+ *
+ * As an example, if the application has an ID of "org.example.app" then
+ * the default resource base path will be "/org/example/app".  If this
+ * is a #GtkApplication (and you have not manually changed the path)
+ * then Gtk will then search for the menus of the application at
+ * "/org/example/app/gtk/menus.ui".
+ *
+ * See #GResource for more information about adding resources to your
+ * application.
+ *
+ * You can disable automatic resource loading functionality by setting
+ * the path to %NULL.
+ *
+ * Changing the resource base path once the application is running is
+ * not recommended.  The point at which the resource path is consulted
+ * for forming paths for various purposes is unspecified.  When writing
+ * a sub-class of #GApplication you should either set the
+ * #GApplication:resource-base-path property at construction time, or call
+ * this function during the instance initialization. Alternatively, you
+ * can call this function in the #GApplicationClass.startup virtual function,
+ * before chaining up to the parent implementation.
+ *
+ * Since: 2.42
+ */
+void
+g_application_set_resource_base_path (GApplication *application,
+                                      const gchar  *resource_path)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (resource_path == NULL || g_str_has_prefix (resource_path, "/"));
+
+  if (g_strcmp0 (application->priv->resource_path, resource_path) != 0)
+    {
+      g_free (application->priv->resource_path);
+
+      application->priv->resource_path = g_strdup (resource_path);
+
+      g_object_notify (G_OBJECT (application), "resource-base-path");
+    }
+}
+
+/**
+ * g_application_get_inactivity_timeout:
+ * @application: a #GApplication
+ *
+ * Gets the current inactivity timeout for the application.
+ *
+ * This is the amount of time (in milliseconds) after the last call to
+ * g_application_release() before the application stops running.
+ *
+ * Returns: the timeout, in milliseconds
+ *
+ * Since: 2.28
+ **/
+guint
+g_application_get_inactivity_timeout (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), 0);
+
+  return application->priv->inactivity_timeout;
+}
+
+/**
+ * g_application_set_inactivity_timeout:
+ * @application: a #GApplication
+ * @inactivity_timeout: the timeout, in milliseconds
+ *
+ * Sets the current inactivity timeout for the application.
+ *
+ * This is the amount of time (in milliseconds) after the last call to
+ * g_application_release() before the application stops running.
+ *
+ * This call has no side effects of its own.  The value set here is only
+ * used for next time g_application_release() drops the use count to
+ * zero.  Any timeouts currently in progress are not impacted.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_set_inactivity_timeout (GApplication *application,
+                                      guint         inactivity_timeout)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  if (application->priv->inactivity_timeout != inactivity_timeout)
+    {
+      application->priv->inactivity_timeout = inactivity_timeout;
+
+      g_object_notify (G_OBJECT (application), "inactivity-timeout");
+    }
+}
+/* Read-only property getters (is registered, is remote, dbus stuff) {{{1 */
+/**
+ * g_application_get_is_registered:
+ * @application: a #GApplication
+ *
+ * Checks if @application is registered.
+ *
+ * An application is registered if g_application_register() has been
+ * successfully called.
+ *
+ * Returns: %TRUE if @application is registered
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_application_get_is_registered (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
+
+  return application->priv->is_registered;
+}
+
+/**
+ * g_application_get_is_remote:
+ * @application: a #GApplication
+ *
+ * Checks if @application is remote.
+ *
+ * If @application is remote then it means that another instance of
+ * application already exists (the 'primary' instance).  Calls to
+ * perform actions on @application will result in the actions being
+ * performed by the primary instance.
+ *
+ * The value of this property cannot be accessed before
+ * g_application_register() has been called.  See
+ * g_application_get_is_registered().
+ *
+ * Returns: %TRUE if @application is remote
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_application_get_is_remote (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
+  g_return_val_if_fail (application->priv->is_registered, FALSE);
+
+  return application->priv->is_remote;
+}
+
+/**
+ * g_application_get_dbus_connection:
+ * @application: a #GApplication
+ *
+ * Gets the #GDBusConnection being used by the application, or %NULL.
+ *
+ * If #GApplication is using its D-Bus backend then this function will
+ * return the #GDBusConnection being used for uniqueness and
+ * communication with the desktop environment and other instances of the
+ * application.
+ *
+ * If #GApplication is not using D-Bus then this function will return
+ * %NULL.  This includes the situation where the D-Bus backend would
+ * normally be in use but we were unable to connect to the bus.
+ *
+ * This function must not be called before the application has been
+ * registered.  See g_application_get_is_registered().
+ *
+ * Returns: (transfer none): a #GDBusConnection, or %NULL
+ *
+ * Since: 2.34
+ **/
+GDBusConnection *
+g_application_get_dbus_connection (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
+  g_return_val_if_fail (application->priv->is_registered, FALSE);
+
+  return g_application_impl_get_dbus_connection (application->priv->impl);
+}
+
+/**
+ * g_application_get_dbus_object_path:
+ * @application: a #GApplication
+ *
+ * Gets the D-Bus object path being used by the application, or %NULL.
+ *
+ * If #GApplication is using its D-Bus backend then this function will
+ * return the D-Bus object path that #GApplication is using.  If the
+ * application is the primary instance then there is an object published
+ * at this path.  If the application is not the primary instance then
+ * the result of this function is undefined.
+ *
+ * If #GApplication is not using D-Bus then this function will return
+ * %NULL.  This includes the situation where the D-Bus backend would
+ * normally be in use but we were unable to connect to the bus.
+ *
+ * This function must not be called before the application has been
+ * registered.  See g_application_get_is_registered().
+ *
+ * Returns: the object path, or %NULL
+ *
+ * Since: 2.34
+ **/
+const gchar *
+g_application_get_dbus_object_path (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
+  g_return_val_if_fail (application->priv->is_registered, FALSE);
+
+  return g_application_impl_get_dbus_object_path (application->priv->impl);
+}
+
+
+/* Register {{{1 */
+/**
+ * g_application_register:
+ * @application: a #GApplication
+ * @cancellable: (nullable): a #GCancellable, or %NULL
+ * @error: a pointer to a NULL #GError, or %NULL
+ *
+ * Attempts registration of the application.
+ *
+ * This is the point at which the application discovers if it is the
+ * primary instance or merely acting as a remote for an already-existing
+ * primary instance.  This is implemented by attempting to acquire the
+ * application identifier as a unique bus name on the session bus using
+ * GDBus.
+ *
+ * If there is no application ID or if %G_APPLICATION_NON_UNIQUE was
+ * given, then this process will always become the primary instance.
+ *
+ * Due to the internal architecture of GDBus, method calls can be
+ * dispatched at any time (even if a main loop is not running).  For
+ * this reason, you must ensure that any object paths that you wish to
+ * register are registered before calling this function.
+ *
+ * If the application has already been registered then %TRUE is
+ * returned with no work performed.
+ *
+ * The #GApplication::startup signal is emitted if registration succeeds
+ * and @application is the primary instance (including the non-unique
+ * case).
+ *
+ * In the event of an error (such as @cancellable being cancelled, or a
+ * failure to connect to the session bus), %FALSE is returned and @error
+ * is set appropriately.
+ *
+ * Note: the return value of this function is not an indicator that this
+ * instance is or is not the primary instance of the application.  See
+ * g_application_get_is_remote() for that.
+ *
+ * Returns: %TRUE if registration succeeded
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_application_register (GApplication  *application,
+                        GCancellable  *cancellable,
+                        GError       **error)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
+
+  if (!application->priv->is_registered)
+    {
+      if (application->priv->id == NULL)
+        application->priv->flags |= G_APPLICATION_NON_UNIQUE;
+
+      application->priv->impl =
+        g_application_impl_register (application, application->priv->id,
+                                     application->priv->flags,
+                                     application->priv->actions,
+                                     &application->priv->remote_actions,
+                                     cancellable, error);
+
+      if (application->priv->impl == NULL)
+        return FALSE;
+
+      application->priv->is_remote = application->priv->remote_actions != NULL;
+      application->priv->is_registered = TRUE;
+
+      g_object_notify (G_OBJECT (application), "is-registered");
+
+      if (!application->priv->is_remote)
+        {
+          g_signal_emit (application, g_application_signals[SIGNAL_STARTUP], 0);
+
+          if (!application->priv->did_startup)
+            g_critical ("GApplication subclass '%s' failed to chain up on"
+                        " ::startup (from start of override function)",
+                        G_OBJECT_TYPE_NAME (application));
+        }
+    }
+
+  return TRUE;
+}
+
+/* Hold/release {{{1 */
+/**
+ * g_application_hold:
+ * @application: a #GApplication
+ *
+ * Increases the use count of @application.
+ *
+ * Use this function to indicate that the application has a reason to
+ * continue to run.  For example, g_application_hold() is called by GTK+
+ * when a toplevel window is on the screen.
+ *
+ * To cancel the hold, call g_application_release().
+ **/
+void
+g_application_hold (GApplication *application)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  if (application->priv->inactivity_timeout_id)
+    {
+      g_source_remove (application->priv->inactivity_timeout_id);
+      application->priv->inactivity_timeout_id = 0;
+    }
+
+  application->priv->use_count++;
+}
+
+static gboolean
+inactivity_timeout_expired (gpointer data)
+{
+  GApplication *application = G_APPLICATION (data);
+
+  application->priv->inactivity_timeout_id = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
+
+/**
+ * g_application_release:
+ * @application: a #GApplication
+ *
+ * Decrease the use count of @application.
+ *
+ * When the use count reaches zero, the application will stop running.
+ *
+ * Never call this function except to cancel the effect of a previous
+ * call to g_application_hold().
+ **/
+void
+g_application_release (GApplication *application)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (application->priv->use_count > 0);
+
+  application->priv->use_count--;
+
+  if (application->priv->use_count == 0 && application->priv->inactivity_timeout)
+    application->priv->inactivity_timeout_id = g_timeout_add (application->priv->inactivity_timeout,
+                                                              inactivity_timeout_expired, application);
+}
+
+/* Activate, Open {{{1 */
+/**
+ * g_application_activate:
+ * @application: a #GApplication
+ *
+ * Activates the application.
+ *
+ * In essence, this results in the #GApplication::activate signal being
+ * emitted in the primary instance.
+ *
+ * The application must be registered before calling this function.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_activate (GApplication *application)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (application->priv->is_registered);
+
+  if (application->priv->is_remote)
+    g_application_impl_activate (application->priv->impl,
+                                 get_platform_data (application, NULL));
+
+  else
+    g_signal_emit (application, g_application_signals[SIGNAL_ACTIVATE], 0);
+}
+
+/**
+ * g_application_open:
+ * @application: a #GApplication
+ * @files: (array length=n_files): an array of #GFiles to open
+ * @n_files: the length of the @files array
+ * @hint: a hint (or ""), but never %NULL
+ *
+ * Opens the given files.
+ *
+ * In essence, this results in the #GApplication::open signal being emitted
+ * in the primary instance.
+ *
+ * @n_files must be greater than zero.
+ *
+ * @hint is simply passed through to the ::open signal.  It is
+ * intended to be used by applications that have multiple modes for
+ * opening files (eg: "view" vs "edit", etc).  Unless you have a need
+ * for this functionality, you should use "".
+ *
+ * The application must be registered before calling this function
+ * and it must have the %G_APPLICATION_HANDLES_OPEN flag set.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_open (GApplication  *application,
+                    GFile        **files,
+                    gint           n_files,
+                    const gchar   *hint)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (application->priv->flags &
+                    G_APPLICATION_HANDLES_OPEN);
+  g_return_if_fail (application->priv->is_registered);
+
+  if (application->priv->is_remote)
+    g_application_impl_open (application->priv->impl,
+                             files, n_files, hint,
+                             get_platform_data (application, NULL));
+
+  else
+    g_signal_emit (application, g_application_signals[SIGNAL_OPEN],
+                   0, files, n_files, hint);
+}
+
+/* Run {{{1 */
+/**
+ * g_application_run:
+ * @application: a #GApplication
+ * @argc: the argc from main() (or 0 if @argv is %NULL)
+ * @argv: (array length=argc) (element-type filename) (nullable):
+ *     the argv from main(), or %NULL
+ *
+ * Runs the application.
+ *
+ * This function is intended to be run from main() and its return value
+ * is intended to be returned by main(). Although you are expected to pass
+ * the @argc, @argv parameters from main() to this function, it is possible
+ * to pass %NULL if @argv is not available or commandline handling is not
+ * required.  Note that on Windows, @argc and @argv are ignored, and
+ * g_win32_get_command_line() is called internally (for proper support
+ * of Unicode commandline arguments).
+ *
+ * #GApplication will attempt to parse the commandline arguments.  You
+ * can add commandline flags to the list of recognised options by way of
+ * g_application_add_main_option_entries().  After this, the
+ * #GApplication::handle-local-options signal is emitted, from which the
+ * application can inspect the values of its #GOptionEntrys.
+ *
+ * #GApplication::handle-local-options is a good place to handle options
+ * such as `--version`, where an immediate reply from the local process is
+ * desired (instead of communicating with an already-running instance).
+ * A #GApplication::handle-local-options handler can stop further processing
+ * by returning a non-negative value, which then becomes the exit status of
+ * the process.
+ *
+ * What happens next depends on the flags: if
+ * %G_APPLICATION_HANDLES_COMMAND_LINE was specified then the remaining
+ * commandline arguments are sent to the primary instance, where a
+ * #GApplication::command-line signal is emitted.  Otherwise, the
+ * remaining commandline arguments are assumed to be a list of files.
+ * If there are no files listed, the application is activated via the
+ * #GApplication::activate signal.  If there are one or more files, and
+ * %G_APPLICATION_HANDLES_OPEN was specified then the files are opened
+ * via the #GApplication::open signal.
+ *
+ * If you are interested in doing more complicated local handling of the
+ * commandline then you should implement your own #GApplication subclass
+ * and override local_command_line(). In this case, you most likely want
+ * to return %TRUE from your local_command_line() implementation to
+ * suppress the default handling. See
+ * [gapplication-example-cmdline2.c][gapplication-example-cmdline2]
+ * for an example.
+ *
+ * If, after the above is done, the use count of the application is zero
+ * then the exit status is returned immediately.  If the use count is
+ * non-zero then the default main context is iterated until the use count
+ * falls to zero, at which point 0 is returned.
+ *
+ * If the %G_APPLICATION_IS_SERVICE flag is set, then the service will
+ * run for as much as 10 seconds with a use count of zero while waiting
+ * for the message that caused the activation to arrive.  After that,
+ * if the use count falls to zero the application will exit immediately,
+ * except in the case that g_application_set_inactivity_timeout() is in
+ * use.
+ *
+ * This function sets the prgname (g_set_prgname()), if not already set,
+ * to the basename of argv[0].
+ *
+ * Much like g_main_loop_run(), this function will acquire the main context
+ * for the duration that the application is running.
+ *
+ * Since 2.40, applications that are not explicitly flagged as services
+ * or launchers (ie: neither %G_APPLICATION_IS_SERVICE or
+ * %G_APPLICATION_IS_LAUNCHER are given as flags) will check (from the
+ * default handler for local_command_line) if "--gapplication-service"
+ * was given in the command line.  If this flag is present then normal
+ * commandline processing is interrupted and the
+ * %G_APPLICATION_IS_SERVICE flag is set.  This provides a "compromise"
+ * solution whereby running an application directly from the commandline
+ * will invoke it in the normal way (which can be useful for debugging)
+ * while still allowing applications to be D-Bus activated in service
+ * mode.  The D-Bus service file should invoke the executable with
+ * "--gapplication-service" as the sole commandline argument.  This
+ * approach is suitable for use by most graphical applications but
+ * should not be used from applications like editors that need precise
+ * control over when processes invoked via the commandline will exit and
+ * what their exit status will be.
+ *
+ * Returns: the exit status
+ *
+ * Since: 2.28
+ **/
+int
+g_application_run (GApplication  *application,
+                   int            argc,
+                   char         **argv)
+{
+  gchar **arguments;
+  int status;
+  GMainContext *context;
+  gboolean acquired_context;
+
+  g_return_val_if_fail (G_IS_APPLICATION (application), 1);
+  g_return_val_if_fail (argc == 0 || argv != NULL, 1);
+  g_return_val_if_fail (!application->priv->must_quit_now, 1);
+
+#ifdef G_OS_WIN32
+  {
+    gint new_argc = 0;
+
+    arguments = g_win32_get_command_line ();
+
+    /*
+     * CommandLineToArgvW(), which is called by g_win32_get_command_line(),
+     * pulls in the whole command line that is used to call the program.  This is
+     * fine in cases where the program is a .exe program, but in the cases where the
+     * program is a called via a script, such as PyGObject's gtk-demo.py, which is normally
+     * called using 'python gtk-demo.py' on Windows, the program name (argv[0])
+     * returned by g_win32_get_command_line() will not be the argv[0] that ->local_command_line()
+     * would expect, causing the program to fail with "This application can not open files."
+     */
+    new_argc = g_strv_length (arguments);
+
+    if (new_argc > argc)
+      {
+        gint i;
+
+        for (i = 0; i < new_argc - argc; i++)
+          g_free (arguments[i]);
+
+        memmove (&arguments[0],
+                 &arguments[new_argc - argc],
+                 sizeof (arguments[0]) * (argc + 1));
+      }
+  }
+#elif defined(__APPLE__)
+  {
+    gint i, j;
+
+    /*
+     * OSX adds an unexpected parameter on the format -psn_X_XXXXXX
+     * when opening the application using Launch Services. In order
+     * to avoid that GOption fails to parse this parameter we just
+     * skip it if it was provided.
+     * See: https://gitlab.gnome.org/GNOME/glib/issues/1784
+     */
+    arguments = g_new (gchar *, argc + 1);
+    for (i = 0, j = 0; i < argc; i++)
+      {
+        if (!g_str_has_prefix (argv[i], "-psn_"))
+          {
+            arguments[j] = g_strdup (argv[i]);
+            j++;
+          }
+      }
+    arguments[j] = NULL;
+  }
+#else
+  {
+    gint i;
+
+    arguments = g_new (gchar *, argc + 1);
+    for (i = 0; i < argc; i++)
+      arguments[i] = g_strdup (argv[i]);
+    arguments[i] = NULL;
+  }
+#endif
+
+  if (g_get_prgname () == NULL && argc > 0)
+    {
+      gchar *prgname;
+
+      prgname = g_path_get_basename (argv[0]);
+      g_set_prgname (prgname);
+      g_free (prgname);
+    }
+
+  context = g_main_context_default ();
+  acquired_context = g_main_context_acquire (context);
+  g_return_val_if_fail (acquired_context, 0);
+
+  if (!G_APPLICATION_GET_CLASS (application)
+        ->local_command_line (application, &arguments, &status))
+    {
+      GError *error = NULL;
+
+      if (!g_application_register (application, NULL, &error))
+        {
+          g_printerr ("Failed to register: %s\n", error->message);
+          g_error_free (error);
+          return 1;
+        }
+
+      g_application_call_command_line (application, (const gchar **) arguments, NULL, &status);
+    }
+
+  g_strfreev (arguments);
+
+  if (application->priv->flags & G_APPLICATION_IS_SERVICE &&
+      application->priv->is_registered &&
+      !application->priv->use_count &&
+      !application->priv->inactivity_timeout_id)
+    {
+      application->priv->inactivity_timeout_id =
+        g_timeout_add (10000, inactivity_timeout_expired, application);
+    }
+
+  while (application->priv->use_count || application->priv->inactivity_timeout_id)
+    {
+      if (application->priv->must_quit_now)
+        break;
+
+      g_main_context_iteration (context, TRUE);
+      status = 0;
+    }
+
+  if (application->priv->is_registered && !application->priv->is_remote)
+    {
+      g_signal_emit (application, g_application_signals[SIGNAL_SHUTDOWN], 0);
+
+      if (!application->priv->did_shutdown)
+        g_critical ("GApplication subclass '%s' failed to chain up on"
+                    " ::shutdown (from end of override function)",
+                    G_OBJECT_TYPE_NAME (application));
+    }
+
+  if (application->priv->impl)
+    {
+      g_application_impl_flush (application->priv->impl);
+      g_application_impl_destroy (application->priv->impl);
+      application->priv->impl = NULL;
+    }
+
+  g_settings_sync ();
+
+  if (!application->priv->must_quit_now)
+    while (g_main_context_iteration (context, FALSE))
+      ;
+
+  g_main_context_release (context);
+
+  return status;
+}
+
+static gchar **
+g_application_list_actions (GActionGroup *action_group)
+{
+  GApplication *application = G_APPLICATION (action_group);
+
+  g_return_val_if_fail (application->priv->is_registered, NULL);
+
+  if (application->priv->remote_actions != NULL)
+    return g_action_group_list_actions (G_ACTION_GROUP (application->priv->remote_actions));
+
+  else if (application->priv->actions != NULL)
+    return g_action_group_list_actions (application->priv->actions);
+
+  else
+    /* empty string array */
+    return g_new0 (gchar *, 1);
+}
+
+static gboolean
+g_application_query_action (GActionGroup        *group,
+                            const gchar         *action_name,
+                            gboolean            *enabled,
+                            const GVariantType **parameter_type,
+                            const GVariantType **state_type,
+                            GVariant           **state_hint,
+                            GVariant           **state)
+{
+  GApplication *application = G_APPLICATION (group);
+
+  g_return_val_if_fail (application->priv->is_registered, FALSE);
+
+  if (application->priv->remote_actions != NULL)
+    return g_action_group_query_action (G_ACTION_GROUP (application->priv->remote_actions),
+                                        action_name,
+                                        enabled,
+                                        parameter_type,
+                                        state_type,
+                                        state_hint,
+                                        state);
+
+  if (application->priv->actions != NULL)
+    return g_action_group_query_action (application->priv->actions,
+                                        action_name,
+                                        enabled,
+                                        parameter_type,
+                                        state_type,
+                                        state_hint,
+                                        state);
+
+  return FALSE;
+}
+
+static void
+g_application_change_action_state (GActionGroup *action_group,
+                                   const gchar  *action_name,
+                                   GVariant     *value)
+{
+  GApplication *application = G_APPLICATION (action_group);
+
+  g_return_if_fail (application->priv->is_remote ||
+                    application->priv->actions != NULL);
+  g_return_if_fail (application->priv->is_registered);
+
+  if (application->priv->remote_actions)
+    g_remote_action_group_change_action_state_full (application->priv->remote_actions,
+                                                    action_name, value, get_platform_data (application, NULL));
+
+  else
+    g_action_group_change_action_state (application->priv->actions, action_name, value);
+}
+
+static void
+g_application_activate_action (GActionGroup *action_group,
+                               const gchar  *action_name,
+                               GVariant     *parameter)
+{
+  GApplication *application = G_APPLICATION (action_group);
+
+  g_return_if_fail (application->priv->is_remote ||
+                    application->priv->actions != NULL);
+  g_return_if_fail (application->priv->is_registered);
+
+  if (application->priv->remote_actions)
+    g_remote_action_group_activate_action_full (application->priv->remote_actions,
+                                                action_name, parameter, get_platform_data (application, NULL));
+
+  else
+    g_action_group_activate_action (application->priv->actions, action_name, parameter);
+}
+
+static GAction *
+g_application_lookup_action (GActionMap  *action_map,
+                             const gchar *action_name)
+{
+  GApplication *application = G_APPLICATION (action_map);
+
+  g_return_val_if_fail (G_IS_ACTION_MAP (application->priv->actions), NULL);
+
+  return g_action_map_lookup_action (G_ACTION_MAP (application->priv->actions), action_name);
+}
+
+static void
+g_application_add_action (GActionMap *action_map,
+                          GAction    *action)
+{
+  GApplication *application = G_APPLICATION (action_map);
+
+  g_return_if_fail (G_IS_ACTION_MAP (application->priv->actions));
+
+  g_action_map_add_action (G_ACTION_MAP (application->priv->actions), action);
+}
+
+static void
+g_application_remove_action (GActionMap  *action_map,
+                             const gchar *action_name)
+{
+  GApplication *application = G_APPLICATION (action_map);
+
+  g_return_if_fail (G_IS_ACTION_MAP (application->priv->actions));
+
+  g_action_map_remove_action (G_ACTION_MAP (application->priv->actions), action_name);
+}
+
+static void
+g_application_action_group_iface_init (GActionGroupInterface *iface)
+{
+  iface->list_actions = g_application_list_actions;
+  iface->query_action = g_application_query_action;
+  iface->change_action_state = g_application_change_action_state;
+  iface->activate_action = g_application_activate_action;
+}
+
+static void
+g_application_action_map_iface_init (GActionMapInterface *iface)
+{
+  iface->lookup_action = g_application_lookup_action;
+  iface->add_action = g_application_add_action;
+  iface->remove_action = g_application_remove_action;
+}
+
+/* Default Application {{{1 */
+
+static GApplication *default_app;
+
+/**
+ * g_application_get_default:
+ *
+ * Returns the default #GApplication instance for this process.
+ *
+ * Normally there is only one #GApplication per process and it becomes
+ * the default when it is created.  You can exercise more control over
+ * this by using g_application_set_default().
+ *
+ * If there is no default application then %NULL is returned.
+ *
+ * Returns: (transfer none): the default application for this process, or %NULL
+ *
+ * Since: 2.32
+ **/
+GApplication *
+g_application_get_default (void)
+{
+  return default_app;
+}
+
+/**
+ * g_application_set_default:
+ * @application: (nullable): the application to set as default, or %NULL
+ *
+ * Sets or unsets the default application for the process, as returned
+ * by g_application_get_default().
+ *
+ * This function does not take its own reference on @application.  If
+ * @application is destroyed then the default application will revert
+ * back to %NULL.
+ *
+ * Since: 2.32
+ **/
+void
+g_application_set_default (GApplication *application)
+{
+  default_app = application;
+}
+
+/**
+ * g_application_quit:
+ * @application: a #GApplication
+ *
+ * Immediately quits the application.
+ *
+ * Upon return to the mainloop, g_application_run() will return,
+ * calling only the 'shutdown' function before doing so.
+ *
+ * The hold count is ignored.
+ * Take care if your code has called g_application_hold() on the application and
+ * is therefore still expecting it to exist.
+ * (Note that you may have called g_application_hold() indirectly, for example
+ * through gtk_application_add_window().)
+ *
+ * The result of calling g_application_run() again after it returns is
+ * unspecified.
+ *
+ * Since: 2.32
+ **/
+void
+g_application_quit (GApplication *application)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  application->priv->must_quit_now = TRUE;
+}
+
+/**
+ * g_application_mark_busy:
+ * @application: a #GApplication
+ *
+ * Increases the busy count of @application.
+ *
+ * Use this function to indicate that the application is busy, for instance
+ * while a long running operation is pending.
+ *
+ * The busy state will be exposed to other processes, so a session shell will
+ * use that information to indicate the state to the user (e.g. with a
+ * spinner).
+ *
+ * To cancel the busy indication, use g_application_unmark_busy().
+ *
+ * Since: 2.38
+ **/
+void
+g_application_mark_busy (GApplication *application)
+{
+  gboolean was_busy;
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  was_busy = (application->priv->busy_count > 0);
+  application->priv->busy_count++;
+
+  if (!was_busy)
+    {
+      g_application_impl_set_busy_state (application->priv->impl, TRUE);
+      g_object_notify (G_OBJECT (application), "is-busy");
+    }
+}
+
+/**
+ * g_application_unmark_busy:
+ * @application: a #GApplication
+ *
+ * Decreases the busy count of @application.
+ *
+ * When the busy count reaches zero, the new state will be propagated
+ * to other processes.
+ *
+ * This function must only be called to cancel the effect of a previous
+ * call to g_application_mark_busy().
+ *
+ * Since: 2.38
+ **/
+void
+g_application_unmark_busy (GApplication *application)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (application->priv->busy_count > 0);
+
+  application->priv->busy_count--;
+
+  if (application->priv->busy_count == 0)
+    {
+      g_application_impl_set_busy_state (application->priv->impl, FALSE);
+      g_object_notify (G_OBJECT (application), "is-busy");
+    }
+}
+
+/**
+ * g_application_get_is_busy:
+ * @application: a #GApplication
+ *
+ * Gets the application's current busy state, as set through
+ * g_application_mark_busy() or g_application_bind_busy_property().
+ *
+ * Returns: %TRUE if @application is currently marked as busy
+ *
+ * Since: 2.44
+ */
+gboolean
+g_application_get_is_busy (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
+
+  return application->priv->busy_count > 0;
+}
+
+/* Notifications {{{1 */
+
+/**
+ * g_application_send_notification:
+ * @application: a #GApplication
+ * @id: (nullable): id of the notification, or %NULL
+ * @notification: the #GNotification to send
+ *
+ * Sends a notification on behalf of @application to the desktop shell.
+ * There is no guarantee that the notification is displayed immediately,
+ * or even at all.
+ *
+ * Notifications may persist after the application exits. It will be
+ * D-Bus-activated when the notification or one of its actions is
+ * activated.
+ *
+ * Modifying @notification after this call has no effect. However, the
+ * object can be reused for a later call to this function.
+ *
+ * @id may be any string that uniquely identifies the event for the
+ * application. It does not need to be in any special format. For
+ * example, "new-message" might be appropriate for a notification about
+ * new messages.
+ *
+ * If a previous notification was sent with the same @id, it will be
+ * replaced with @notification and shown again as if it was a new
+ * notification. This works even for notifications sent from a previous
+ * execution of the application, as long as @id is the same string.
+ *
+ * @id may be %NULL, but it is impossible to replace or withdraw
+ * notifications without an id.
+ *
+ * If @notification is no longer relevant, it can be withdrawn with
+ * g_application_withdraw_notification().
+ *
+ * Since: 2.40
+ */
+void
+g_application_send_notification (GApplication  *application,
+                                 const gchar   *id,
+                                 GNotification *notification)
+{
+  gchar *generated_id = NULL;
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (G_IS_NOTIFICATION (notification));
+  g_return_if_fail (g_application_get_is_registered (application));
+  g_return_if_fail (!g_application_get_is_remote (application));
+
+  if (application->priv->notifications == NULL)
+    application->priv->notifications = g_notification_backend_new_default (application);
+
+  if (id == NULL)
+    {
+      generated_id = g_dbus_generate_guid ();
+      id = generated_id;
+    }
+
+  g_notification_backend_send_notification (application->priv->notifications, id, notification);
+
+  g_free (generated_id);
+}
+
+/**
+ * g_application_withdraw_notification:
+ * @application: a #GApplication
+ * @id: id of a previously sent notification
+ *
+ * Withdraws a notification that was sent with
+ * g_application_send_notification().
+ *
+ * This call does nothing if a notification with @id doesn't exist or
+ * the notification was never sent.
+ *
+ * This function works even for notifications sent in previous
+ * executions of this application, as long @id is the same as it was for
+ * the sent notification.
+ *
+ * Note that notifications are dismissed when the user clicks on one
+ * of the buttons in a notification or triggers its default action, so
+ * there is no need to explicitly withdraw the notification in that case.
+ *
+ * Since: 2.40
+ */
+void
+g_application_withdraw_notification (GApplication *application,
+                                     const gchar  *id)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (id != NULL);
+
+  if (application->priv->notifications == NULL)
+    application->priv->notifications = g_notification_backend_new_default (application);
+
+  g_notification_backend_withdraw_notification (application->priv->notifications, id);
+}
+
+/* Busy binding {{{1 */
+
+typedef struct
+{
+  GApplication *app;
+  gboolean is_busy;
+} GApplicationBusyBinding;
+
+static void
+g_application_busy_binding_destroy (gpointer  data,
+                                    GClosure *closure)
+{
+  GApplicationBusyBinding *binding = data;
+
+  if (binding->is_busy)
+    g_application_unmark_busy (binding->app);
+
+  g_object_unref (binding->app);
+  g_slice_free (GApplicationBusyBinding, binding);
+}
+
+static void
+g_application_notify_busy_binding (GObject    *object,
+                                   GParamSpec *pspec,
+                                   gpointer    user_data)
+{
+  GApplicationBusyBinding *binding = user_data;
+  gboolean is_busy;
+
+  g_object_get (object, pspec->name, &is_busy, NULL);
+
+  if (is_busy && !binding->is_busy)
+    g_application_mark_busy (binding->app);
+  else if (!is_busy && binding->is_busy)
+    g_application_unmark_busy (binding->app);
+
+  binding->is_busy = is_busy;
+}
+
+/**
+ * g_application_bind_busy_property:
+ * @application: a #GApplication
+ * @object: (type GObject.Object): a #GObject
+ * @property: the name of a boolean property of @object
+ *
+ * Marks @application as busy (see g_application_mark_busy()) while
+ * @property on @object is %TRUE.
+ *
+ * The binding holds a reference to @application while it is active, but
+ * not to @object. Instead, the binding is destroyed when @object is
+ * finalized.
+ *
+ * Since: 2.44
+ */
+void
+g_application_bind_busy_property (GApplication *application,
+                                  gpointer      object,
+                                  const gchar  *property)
+{
+  guint notify_id;
+  GQuark property_quark;
+  GParamSpec *pspec;
+  GApplicationBusyBinding *binding;
+  GClosure *closure;
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (property != NULL);
+
+  notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
+  property_quark = g_quark_from_string (property);
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
+
+  g_return_if_fail (pspec != NULL && pspec->value_type == G_TYPE_BOOLEAN);
+
+  if (g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC,
+                             notify_id, property_quark, NULL, g_application_notify_busy_binding, NULL) > 0)
+    {
+      g_critical ("%s: '%s' is already bound to the busy state of the application", G_STRFUNC, property);
+      return;
+    }
+
+  binding = g_slice_new (GApplicationBusyBinding);
+  binding->app = g_object_ref (application);
+  binding->is_busy = FALSE;
+
+  closure = g_cclosure_new (G_CALLBACK (g_application_notify_busy_binding), binding,
+                            g_application_busy_binding_destroy);
+  g_signal_connect_closure_by_id (object, notify_id, property_quark, closure, FALSE);
+
+  /* fetch the initial value */
+  g_application_notify_busy_binding (object, pspec, binding);
+}
+
+/**
+ * g_application_unbind_busy_property:
+ * @application: a #GApplication
+ * @object: (type GObject.Object): a #GObject
+ * @property: the name of a boolean property of @object
+ *
+ * Destroys a binding between @property and the busy state of
+ * @application that was previously created with
+ * g_application_bind_busy_property().
+ *
+ * Since: 2.44
+ */
+void
+g_application_unbind_busy_property (GApplication *application,
+                                    gpointer      object,
+                                    const gchar  *property)
+{
+  guint notify_id;
+  GQuark property_quark;
+  gulong handler_id;
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (property != NULL);
+
+  notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
+  property_quark = g_quark_from_string (property);
+
+  handler_id = g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC,
+                                      notify_id, property_quark, NULL, g_application_notify_busy_binding, NULL);
+  if (handler_id == 0)
+    {
+      g_critical ("%s: '%s' is not bound to the busy state of the application", G_STRFUNC, property);
+      return;
+    }
+
+  g_signal_handler_disconnect (object, handler_id);
+}
+
+/* Epilogue {{{1 */
+/* vim:set foldmethod=marker: */
diff --git a/gio/gapplication.h b/gio/gapplication.h
new file mode 100644
index 0000000..adc32ed
--- /dev/null
+++ b/gio/gapplication.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_APPLICATION_H__
+#define __G_APPLICATION_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_APPLICATION                                  (g_application_get_type ())
+#define G_APPLICATION(inst)                                 (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
+                                                             G_TYPE_APPLICATION, GApplication))
+#define G_APPLICATION_CLASS(class)                          (G_TYPE_CHECK_CLASS_CAST ((class),                       \
+                                                             G_TYPE_APPLICATION, GApplicationClass))
+#define G_IS_APPLICATION(inst)                              (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_APPLICATION))
+#define G_IS_APPLICATION_CLASS(class)                       (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_APPLICATION))
+#define G_APPLICATION_GET_CLASS(inst)                       (G_TYPE_INSTANCE_GET_CLASS ((inst),                      \
+                                                             G_TYPE_APPLICATION, GApplicationClass))
+
+typedef struct _GApplicationPrivate                         GApplicationPrivate;
+typedef struct _GApplicationClass                           GApplicationClass;
+
+struct _GApplication
+{
+  /*< private >*/
+  GObject parent_instance;
+
+  GApplicationPrivate *priv;
+};
+
+struct _GApplicationClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+
+  /*< public >*/
+  /* signals */
+  void                      (* startup)             (GApplication              *application);
+
+  void                      (* activate)            (GApplication              *application);
+
+  void                      (* open)                (GApplication              *application,
+                                                     GFile                    **files,
+                                                     gint                       n_files,
+                                                     const gchar               *hint);
+
+  int                       (* command_line)        (GApplication              *application,
+                                                     GApplicationCommandLine   *command_line);
+
+  /* vfuncs */
+
+  /**
+   * GApplicationClass::local_command_line:
+   * @application: a #GApplication
+   * @arguments: (inout) (array zero-terminated=1): array of command line arguments
+   * @exit_status: (out): exit status to fill after processing the command line.
+   *
+   * This virtual function is always invoked in the local instance. It
+   * gets passed a pointer to a %NULL-terminated copy of @argv and is
+   * expected to remove arguments that it handled (shifting up remaining
+   * arguments).
+   *
+   * The last argument to local_command_line() is a pointer to the @status
+   * variable which can used to set the exit status that is returned from
+   * g_application_run().
+   *
+   * See g_application_run() for more details on #GApplication startup.
+   *
+   * Returns: %TRUE if the commandline has been completely handled
+   */
+  gboolean                  (* local_command_line)  (GApplication              *application,
+                                                     gchar                   ***arguments,
+                                                     int                       *exit_status);
+
+  void                      (* before_emit)         (GApplication              *application,
+                                                     GVariant                  *platform_data);
+  void                      (* after_emit)          (GApplication              *application,
+                                                     GVariant                  *platform_data);
+  void                      (* add_platform_data)   (GApplication              *application,
+                                                     GVariantBuilder           *builder);
+  void                      (* quit_mainloop)       (GApplication              *application);
+  void                      (* run_mainloop)        (GApplication              *application);
+  void                      (* shutdown)            (GApplication              *application);
+
+  gboolean                  (* dbus_register)       (GApplication              *application,
+                                                     GDBusConnection           *connection,
+                                                     const gchar               *object_path,
+                                                     GError                   **error);
+  void                      (* dbus_unregister)     (GApplication              *application,
+                                                     GDBusConnection           *connection,
+                                                     const gchar               *object_path);
+  gint                      (* handle_local_options)(GApplication              *application,
+                                                     GVariantDict              *options);
+  gboolean                  (* name_lost)           (GApplication              *application);
+
+  /*< private >*/
+  gpointer padding[7];
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType                   g_application_get_type                          (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_application_id_is_valid                       (const gchar              *application_id);
+
+GLIB_AVAILABLE_IN_ALL
+GApplication *          g_application_new                               (const gchar              *application_id,
+                                                                         GApplicationFlags         flags);
+
+GLIB_AVAILABLE_IN_ALL
+const gchar *           g_application_get_application_id                (GApplication             *application);
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_set_application_id                (GApplication             *application,
+                                                                         const gchar              *application_id);
+
+GLIB_AVAILABLE_IN_2_34
+GDBusConnection *       g_application_get_dbus_connection               (GApplication             *application);
+GLIB_AVAILABLE_IN_2_34
+const gchar *           g_application_get_dbus_object_path              (GApplication             *application);
+
+GLIB_AVAILABLE_IN_ALL
+guint                   g_application_get_inactivity_timeout            (GApplication             *application);
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_set_inactivity_timeout            (GApplication             *application,
+                                                                         guint                     inactivity_timeout);
+
+GLIB_AVAILABLE_IN_ALL
+GApplicationFlags       g_application_get_flags                         (GApplication             *application);
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_set_flags                         (GApplication             *application,
+                                                                         GApplicationFlags         flags);
+
+GLIB_AVAILABLE_IN_2_42
+const gchar *           g_application_get_resource_base_path            (GApplication             *application);
+GLIB_AVAILABLE_IN_2_42
+void                    g_application_set_resource_base_path            (GApplication             *application,
+                                                                         const gchar              *resource_path);
+
+GLIB_DEPRECATED
+void                    g_application_set_action_group                  (GApplication             *application,
+                                                                         GActionGroup             *action_group);
+
+GLIB_AVAILABLE_IN_2_40
+void                    g_application_add_main_option_entries           (GApplication             *application,
+                                                                         const GOptionEntry       *entries);
+
+GLIB_AVAILABLE_IN_2_42
+void                    g_application_add_main_option                   (GApplication             *application,
+                                                                         const char               *long_name,
+                                                                         char                      short_name,
+                                                                         GOptionFlags              flags,
+                                                                         GOptionArg                arg,
+                                                                         const char               *description,
+                                                                         const char               *arg_description);
+GLIB_AVAILABLE_IN_2_40
+void                    g_application_add_option_group                  (GApplication             *application,
+                                                                         GOptionGroup             *group);
+GLIB_AVAILABLE_IN_2_56
+void                    g_application_set_option_context_parameter_string (GApplication             *application,
+                                                                           const gchar              *parameter_string);
+GLIB_AVAILABLE_IN_2_56
+void                    g_application_set_option_context_summary        (GApplication             *application,
+                                                                         const gchar              *summary);
+GLIB_AVAILABLE_IN_2_56
+void                    g_application_set_option_context_description    (GApplication             *application,
+                                                                         const gchar              *description);
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_application_get_is_registered                 (GApplication             *application);
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_application_get_is_remote                     (GApplication             *application);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_application_register                          (GApplication             *application,
+                                                                         GCancellable             *cancellable,
+                                                                         GError                  **error);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_hold                              (GApplication             *application);
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_release                           (GApplication             *application);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_activate                          (GApplication             *application);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_open                              (GApplication             *application,
+                                                                         GFile                   **files,
+                                                                         gint                      n_files,
+                                                                         const gchar              *hint);
+
+GLIB_AVAILABLE_IN_ALL
+int                     g_application_run                               (GApplication             *application,
+                                                                         int                       argc,
+                                                                         char                    **argv);
+
+GLIB_AVAILABLE_IN_2_32
+void                    g_application_quit                              (GApplication             *application);
+
+GLIB_AVAILABLE_IN_2_32
+GApplication *          g_application_get_default                       (void);
+GLIB_AVAILABLE_IN_2_32
+void                    g_application_set_default                       (GApplication             *application);
+
+GLIB_AVAILABLE_IN_2_38
+void                    g_application_mark_busy                         (GApplication             *application);
+GLIB_AVAILABLE_IN_2_38
+void                    g_application_unmark_busy                       (GApplication             *application);
+GLIB_AVAILABLE_IN_2_44
+gboolean                g_application_get_is_busy                       (GApplication             *application);
+
+GLIB_AVAILABLE_IN_2_40
+void                    g_application_send_notification                 (GApplication             *application,
+                                                                         const gchar              *id,
+                                                                         GNotification            *notification);
+GLIB_AVAILABLE_IN_2_40
+void                    g_application_withdraw_notification             (GApplication             *application,
+                                                                         const gchar              *id);
+
+GLIB_AVAILABLE_IN_2_44
+void                    g_application_bind_busy_property                (GApplication             *application,
+                                                                         gpointer                  object,
+                                                                         const gchar              *property);
+
+GLIB_AVAILABLE_IN_2_44
+void                    g_application_unbind_busy_property              (GApplication             *application,
+                                                                         gpointer                  object,
+                                                                         const gchar              *property);
+
+G_END_DECLS
+
+#endif /* __G_APPLICATION_H__ */
diff --git a/gio/gapplicationcommandline.c b/gio/gapplicationcommandline.c
new file mode 100644
index 0000000..d6c5c45
--- /dev/null
+++ b/gio/gapplicationcommandline.c
@@ -0,0 +1,834 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gapplicationcommandline.h"
+
+#include "glibintl.h"
+#include "gfile.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#ifdef G_OS_UNIX
+#include "gunixinputstream.h"
+#endif
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#undef environ
+#include "gwin32inputstream.h"
+#endif
+
+/**
+ * SECTION:gapplicationcommandline
+ * @title: GApplicationCommandLine
+ * @short_description: A command-line invocation of an application
+ * @include: gio/gio.h
+ * @see_also: #GApplication
+ *
+ * #GApplicationCommandLine represents a command-line invocation of
+ * an application.  It is created by #GApplication and emitted
+ * in the #GApplication::command-line signal and virtual function.
+ *
+ * The class contains the list of arguments that the program was invoked
+ * with.  It is also possible to query if the commandline invocation was
+ * local (ie: the current process is running in direct response to the
+ * invocation) or remote (ie: some other process forwarded the
+ * commandline to this process).
+ *
+ * The GApplicationCommandLine object can provide the @argc and @argv
+ * parameters for use with the #GOptionContext command-line parsing API,
+ * with the g_application_command_line_get_arguments() function. See
+ * [gapplication-example-cmdline3.c][gapplication-example-cmdline3]
+ * for an example.
+ *
+ * The exit status of the originally-invoked process may be set and
+ * messages can be printed to stdout or stderr of that process.  The
+ * lifecycle of the originally-invoked process is tied to the lifecycle
+ * of this object (ie: the process exits when the last reference is
+ * dropped).
+ *
+ * The main use for #GApplicationCommandLine (and the
+ * #GApplication::command-line signal) is 'Emacs server' like use cases:
+ * You can set the `EDITOR` environment variable to have e.g. git use
+ * your favourite editor to edit commit messages, and if you already
+ * have an instance of the editor running, the editing will happen
+ * in the running instance, instead of opening a new one. An important
+ * aspect of this use case is that the process that gets started by git
+ * does not return until the editing is done.
+ *
+ * Normally, the commandline is completely handled in the
+ * #GApplication::command-line handler. The launching instance exits
+ * once the signal handler in the primary instance has returned, and
+ * the return value of the signal handler becomes the exit status
+ * of the launching instance.
+ * |[<!-- language="C" -->
+ * static int
+ * command_line (GApplication            *application,
+ *               GApplicationCommandLine *cmdline)
+ * {
+ *   gchar **argv;
+ *   gint argc;
+ *   gint i;
+ *
+ *   argv = g_application_command_line_get_arguments (cmdline, &argc);
+ *
+ *   g_application_command_line_print (cmdline,
+ *                                     "This text is written back\n"
+ *                                     "to stdout of the caller\n");
+ *
+ *   for (i = 0; i < argc; i++)
+ *     g_print ("argument %d: %s\n", i, argv[i]);
+ *
+ *   g_strfreev (argv);
+ *
+ *   return 0;
+ * }
+ * ]|
+ * The complete example can be found here: 
+ * [gapplication-example-cmdline.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline.c)
+ *
+ * In more complicated cases, the handling of the comandline can be
+ * split between the launcher and the primary instance.
+ * |[<!-- language="C" -->
+ * static gboolean
+ *  test_local_cmdline (GApplication   *application,
+ *                      gchar        ***arguments,
+ *                      gint           *exit_status)
+ * {
+ *   gint i, j;
+ *   gchar **argv;
+ *
+ *   argv = *arguments;
+ *
+ *   i = 1;
+ *   while (argv[i])
+ *     {
+ *       if (g_str_has_prefix (argv[i], "--local-"))
+ *         {
+ *           g_print ("handling argument %s locally\n", argv[i]);
+ *           g_free (argv[i]);
+ *           for (j = i; argv[j]; j++)
+ *             argv[j] = argv[j + 1];
+ *         }
+ *       else
+ *         {
+ *           g_print ("not handling argument %s locally\n", argv[i]);
+ *           i++;
+ *         }
+ *     }
+ *
+ *   *exit_status = 0;
+ *
+ *   return FALSE;
+ * }
+ *
+ * static void
+ * test_application_class_init (TestApplicationClass *class)
+ * {
+ *   G_APPLICATION_CLASS (class)->local_command_line = test_local_cmdline;
+ *
+ *   ...
+ * }
+ * ]|
+ * In this example of split commandline handling, options that start
+ * with `--local-` are handled locally, all other options are passed
+ * to the #GApplication::command-line handler which runs in the primary
+ * instance.
+ *
+ * The complete example can be found here:
+ * [gapplication-example-cmdline2.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline2.c)
+ *
+ * If handling the commandline requires a lot of work, it may
+ * be better to defer it.
+ * |[<!-- language="C" -->
+ * static gboolean
+ * my_cmdline_handler (gpointer data)
+ * {
+ *   GApplicationCommandLine *cmdline = data;
+ *
+ *   // do the heavy lifting in an idle
+ *
+ *   g_application_command_line_set_exit_status (cmdline, 0);
+ *   g_object_unref (cmdline); // this releases the application
+ *
+ *   return G_SOURCE_REMOVE;
+ * }
+ *
+ * static int
+ * command_line (GApplication            *application,
+ *               GApplicationCommandLine *cmdline)
+ * {
+ *   // keep the application running until we are done with this commandline
+ *   g_application_hold (application);
+ *
+ *   g_object_set_data_full (G_OBJECT (cmdline),
+ *                           "application", application,
+ *                           (GDestroyNotify)g_application_release);
+ *
+ *   g_object_ref (cmdline);
+ *   g_idle_add (my_cmdline_handler, cmdline);
+ *
+ *   return 0;
+ * }
+ * ]|
+ * In this example the commandline is not completely handled before
+ * the #GApplication::command-line handler returns. Instead, we keep
+ * a reference to the #GApplicationCommandLine object and handle it
+ * later (in this example, in an idle). Note that it is necessary to
+ * hold the application until you are done with the commandline.
+ *
+ * The complete example can be found here:
+ * [gapplication-example-cmdline3.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline3.c)
+ */
+
+/**
+ * GApplicationCommandLine:
+ *
+ * #GApplicationCommandLine is an opaque data structure and can only be accessed
+ * using the following functions.
+ */
+
+/**
+ * GApplicationCommandLineClass:
+ *
+ * The #GApplicationCommandLineClass-struct 
+ * contains private data only.
+ *
+ * Since: 2.28
+ **/
+enum
+{
+  PROP_NONE,
+  PROP_ARGUMENTS,
+  PROP_OPTIONS,
+  PROP_PLATFORM_DATA,
+  PROP_IS_REMOTE
+};
+
+struct _GApplicationCommandLinePrivate
+{
+  GVariant *platform_data;
+  GVariant *arguments;
+  GVariant *options;
+  GVariantDict *options_dict;
+  gchar *cwd;  /* in GLib filename encoding, not UTF-8 */
+
+  gchar **environ;
+  gint exit_status;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
+
+/* All subclasses represent remote invocations of some kind. */
+#define IS_REMOTE(cmdline) (G_TYPE_FROM_INSTANCE (cmdline) != \
+                            G_TYPE_APPLICATION_COMMAND_LINE)
+
+static void
+grok_platform_data (GApplicationCommandLine *cmdline)
+{
+  GVariantIter iter;
+  const gchar *key;
+  GVariant *value;
+
+  g_variant_iter_init (&iter, cmdline->priv->platform_data);
+
+  while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+    if (strcmp (key, "cwd") == 0)
+      {
+        if (!cmdline->priv->cwd)
+          cmdline->priv->cwd = g_variant_dup_bytestring (value, NULL);
+      }
+
+    else if (strcmp (key, "environ") == 0)
+      {
+        if (!cmdline->priv->environ)
+          cmdline->priv->environ =
+            g_variant_dup_bytestring_array (value, NULL);
+      }
+
+    else if (strcmp (key, "options") == 0)
+      {
+        if (!cmdline->priv->options)
+          cmdline->priv->options = g_variant_ref (value);
+      }
+}
+
+static void
+g_application_command_line_real_print_literal (GApplicationCommandLine *cmdline,
+                                               const gchar             *message)
+{
+  g_print ("%s", message);
+}
+
+static void
+g_application_command_line_real_printerr_literal (GApplicationCommandLine *cmdline,
+                                                  const gchar             *message)
+{
+  g_printerr ("%s", message);
+}
+
+static GInputStream *
+g_application_command_line_real_get_stdin (GApplicationCommandLine *cmdline)
+{
+#ifdef G_OS_UNIX
+  return g_unix_input_stream_new (0, FALSE);
+#else
+  return g_win32_input_stream_new (GetStdHandle (STD_INPUT_HANDLE), FALSE);
+#endif
+}
+
+static void
+g_application_command_line_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
+
+  switch (prop_id)
+    {
+    case PROP_ARGUMENTS:
+      g_value_set_variant (value, cmdline->priv->arguments);
+      break;
+
+    case PROP_PLATFORM_DATA:
+      g_value_set_variant (value, cmdline->priv->platform_data);
+      break;
+
+    case PROP_IS_REMOTE:
+      g_value_set_boolean (value, IS_REMOTE (cmdline));
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+g_application_command_line_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
+
+  switch (prop_id)
+    {
+    case PROP_ARGUMENTS:
+      g_assert (cmdline->priv->arguments == NULL);
+      cmdline->priv->arguments = g_value_dup_variant (value);
+      break;
+
+    case PROP_OPTIONS:
+      g_assert (cmdline->priv->options == NULL);
+      cmdline->priv->options = g_value_dup_variant (value);
+      break;
+
+    case PROP_PLATFORM_DATA:
+      g_assert (cmdline->priv->platform_data == NULL);
+      cmdline->priv->platform_data = g_value_dup_variant (value);
+      if (cmdline->priv->platform_data != NULL)
+        grok_platform_data (cmdline);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+g_application_command_line_finalize (GObject *object)
+{
+  GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
+
+  if (cmdline->priv->options_dict)
+    g_variant_dict_unref (cmdline->priv->options_dict);
+
+  if (cmdline->priv->options)
+      g_variant_unref (cmdline->priv->options);
+
+  if (cmdline->priv->platform_data)
+    g_variant_unref (cmdline->priv->platform_data);
+  if (cmdline->priv->arguments)
+    g_variant_unref (cmdline->priv->arguments);
+
+  g_free (cmdline->priv->cwd);
+  g_strfreev (cmdline->priv->environ);
+
+  G_OBJECT_CLASS (g_application_command_line_parent_class)
+    ->finalize (object);
+}
+
+static void
+g_application_command_line_init (GApplicationCommandLine *cmdline)
+{
+  cmdline->priv = g_application_command_line_get_instance_private (cmdline);
+}
+
+static void
+g_application_command_line_constructed (GObject *object)
+{
+  GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
+
+  if (IS_REMOTE (cmdline))
+    return;
+
+  /* In the local case, set cmd and environ */
+  if (!cmdline->priv->cwd)
+    cmdline->priv->cwd = g_get_current_dir ();
+
+  if (!cmdline->priv->environ)
+    cmdline->priv->environ = g_get_environ ();
+}
+
+static void
+g_application_command_line_class_init (GApplicationCommandLineClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->get_property = g_application_command_line_get_property;
+  object_class->set_property = g_application_command_line_set_property;
+  object_class->finalize = g_application_command_line_finalize;
+  object_class->constructed = g_application_command_line_constructed;
+
+  class->printerr_literal = g_application_command_line_real_printerr_literal;
+  class->print_literal = g_application_command_line_real_print_literal;
+  class->get_stdin = g_application_command_line_real_get_stdin;
+
+  g_object_class_install_property (object_class, PROP_ARGUMENTS,
+    g_param_spec_variant ("arguments",
+                          P_("Commandline arguments"),
+                          P_("The commandline that caused this ::command-line signal emission"),
+                          G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL,
+                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_OPTIONS,
+    g_param_spec_variant ("options",
+                          P_("Options"),
+                          P_("The options sent along with the commandline"),
+                          G_VARIANT_TYPE_VARDICT, NULL, G_PARAM_WRITABLE |
+                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
+    g_param_spec_variant ("platform-data",
+                          P_("Platform data"),
+                          P_("Platform-specific data for the commandline"),
+                          G_VARIANT_TYPE ("a{sv}"), NULL,
+                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_IS_REMOTE,
+    g_param_spec_boolean ("is-remote",
+                          P_("Is remote"),
+                          P_("TRUE if this is a remote commandline"),
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+}
+
+
+/**
+ * g_application_command_line_get_arguments:
+ * @cmdline: a #GApplicationCommandLine
+ * @argc: (out) (optional): the length of the arguments array, or %NULL
+ *
+ * Gets the list of arguments that was passed on the command line.
+ *
+ * The strings in the array may contain non-UTF-8 data on UNIX (such as
+ * filenames or arguments given in the system locale) but are always in
+ * UTF-8 on Windows.
+ *
+ * If you wish to use the return value with #GOptionContext, you must
+ * use g_option_context_parse_strv().
+ *
+ * The return value is %NULL-terminated and should be freed using
+ * g_strfreev().
+ *
+ * Returns: (array length=argc) (element-type filename) (transfer full)
+ *      the string array containing the arguments (the argv)
+ *
+ * Since: 2.28
+ **/
+gchar **
+g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
+                                          int                     *argc)
+{
+  gchar **argv;
+  gsize len;
+
+  g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
+
+  argv = g_variant_dup_bytestring_array (cmdline->priv->arguments, &len);
+
+  if (argc)
+    *argc = len;
+
+  return argv;
+}
+
+/**
+ * g_application_command_line_get_options_dict:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Gets the options there were passed to g_application_command_line().
+ *
+ * If you did not override local_command_line() then these are the same
+ * options that were parsed according to the #GOptionEntrys added to the
+ * application with g_application_add_main_option_entries() and possibly
+ * modified from your GApplication::handle-local-options handler.
+ *
+ * If no options were sent then an empty dictionary is returned so that
+ * you don't need to check for %NULL.
+ *
+ * Returns: (transfer none): a #GVariantDict with the options
+ *
+ * Since: 2.40
+ **/
+GVariantDict *
+g_application_command_line_get_options_dict (GApplicationCommandLine *cmdline)
+{
+  g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
+
+  if (!cmdline->priv->options_dict)
+    cmdline->priv->options_dict = g_variant_dict_new (cmdline->priv->options);
+
+  return cmdline->priv->options_dict;
+}
+
+/**
+ * g_application_command_line_get_stdin:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Gets the stdin of the invoking process.
+ *
+ * The #GInputStream can be used to read data passed to the standard
+ * input of the invoking process.
+ * This doesn't work on all platforms.  Presently, it is only available
+ * on UNIX when using a DBus daemon capable of passing file descriptors.
+ * If stdin is not available then %NULL will be returned.  In the
+ * future, support may be expanded to other platforms.
+ *
+ * You must only call this function once per commandline invocation.
+ *
+ * Returns: (transfer full): a #GInputStream for stdin
+ *
+ * Since: 2.34
+ **/
+GInputStream *
+g_application_command_line_get_stdin (GApplicationCommandLine *cmdline)
+{
+  return G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)->get_stdin (cmdline);
+}
+
+/**
+ * g_application_command_line_get_cwd:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Gets the working directory of the command line invocation.
+ * The string may contain non-utf8 data.
+ *
+ * It is possible that the remote application did not send a working
+ * directory, so this may be %NULL.
+ *
+ * The return value should not be modified or freed and is valid for as
+ * long as @cmdline exists.
+ *
+ * Returns: (nullable) (type filename): the current directory, or %NULL
+ *
+ * Since: 2.28
+ **/
+const gchar *
+g_application_command_line_get_cwd (GApplicationCommandLine *cmdline)
+{
+  return cmdline->priv->cwd;
+}
+
+/**
+ * g_application_command_line_get_environ:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Gets the contents of the 'environ' variable of the command line
+ * invocation, as would be returned by g_get_environ(), ie as a
+ * %NULL-terminated list of strings in the form 'NAME=VALUE'.
+ * The strings may contain non-utf8 data.
+ *
+ * The remote application usually does not send an environment.  Use
+ * %G_APPLICATION_SEND_ENVIRONMENT to affect that.  Even with this flag
+ * set it is possible that the environment is still not available (due
+ * to invocation messages from other applications).
+ *
+ * The return value should not be modified or freed and is valid for as
+ * long as @cmdline exists.
+ *
+ * See g_application_command_line_getenv() if you are only interested
+ * in the value of a single environment variable.
+ *
+ * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
+ *     the environment strings, or %NULL if they were not sent
+ *
+ * Since: 2.28
+ **/
+const gchar * const *
+g_application_command_line_get_environ (GApplicationCommandLine *cmdline)
+{
+  return (const gchar **)cmdline->priv->environ;
+}
+
+/**
+ * g_application_command_line_getenv:
+ * @cmdline: a #GApplicationCommandLine
+ * @name: (type filename): the environment variable to get
+ *
+ * Gets the value of a particular environment variable of the command
+ * line invocation, as would be returned by g_getenv().  The strings may
+ * contain non-utf8 data.
+ *
+ * The remote application usually does not send an environment.  Use
+ * %G_APPLICATION_SEND_ENVIRONMENT to affect that.  Even with this flag
+ * set it is possible that the environment is still not available (due
+ * to invocation messages from other applications).
+ *
+ * The return value should not be modified or freed and is valid for as
+ * long as @cmdline exists.
+ *
+ * Returns: the value of the variable, or %NULL if unset or unsent
+ *
+ * Since: 2.28
+ **/
+const gchar *
+g_application_command_line_getenv (GApplicationCommandLine *cmdline,
+                                   const gchar             *name)
+{
+  gint length = strlen (name);
+  gint i;
+
+  /* TODO: expand on windows */
+  if (cmdline->priv->environ)
+    for (i = 0; cmdline->priv->environ[i]; i++)
+      if (strncmp (cmdline->priv->environ[i], name, length) == 0 &&
+          cmdline->priv->environ[i][length] == '=')
+        return cmdline->priv->environ[i] + length + 1;
+
+  return NULL;
+}
+
+/**
+ * g_application_command_line_get_is_remote:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Determines if @cmdline represents a remote invocation.
+ *
+ * Returns: %TRUE if the invocation was remote
+ *
+ * Since: 2.28
+ **/
+gboolean
+g_application_command_line_get_is_remote (GApplicationCommandLine *cmdline)
+{
+  return IS_REMOTE (cmdline);
+}
+
+/**
+ * g_application_command_line_print:
+ * @cmdline: a #GApplicationCommandLine
+ * @format: a printf-style format string
+ * @...: arguments, as per @format
+ *
+ * Formats a message and prints it using the stdout print handler in the
+ * invoking process.
+ *
+ * If @cmdline is a local invocation then this is exactly equivalent to
+ * g_print().  If @cmdline is remote then this is equivalent to calling
+ * g_print() in the invoking process.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_command_line_print (GApplicationCommandLine *cmdline,
+                                  const gchar             *format,
+                                  ...)
+{
+  gchar *message;
+  va_list ap;
+
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
+  g_return_if_fail (format != NULL);
+
+  va_start (ap, format);
+  message = g_strdup_vprintf (format, ap);
+  va_end (ap);
+
+  G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
+    ->print_literal (cmdline, message);
+  g_free (message);
+}
+
+/**
+ * g_application_command_line_printerr:
+ * @cmdline: a #GApplicationCommandLine
+ * @format: a printf-style format string
+ * @...: arguments, as per @format
+ *
+ * Formats a message and prints it using the stderr print handler in the
+ * invoking process.
+ *
+ * If @cmdline is a local invocation then this is exactly equivalent to
+ * g_printerr().  If @cmdline is remote then this is equivalent to
+ * calling g_printerr() in the invoking process.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_command_line_printerr (GApplicationCommandLine *cmdline,
+                                     const gchar             *format,
+                                     ...)
+{
+  gchar *message;
+  va_list ap;
+
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
+  g_return_if_fail (format != NULL);
+
+  va_start (ap, format);
+  message = g_strdup_vprintf (format, ap);
+  va_end (ap);
+
+  G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
+    ->printerr_literal (cmdline, message);
+  g_free (message);
+}
+
+/**
+ * g_application_command_line_set_exit_status:
+ * @cmdline: a #GApplicationCommandLine
+ * @exit_status: the exit status
+ *
+ * Sets the exit status that will be used when the invoking process
+ * exits.
+ *
+ * The return value of the #GApplication::command-line signal is
+ * passed to this function when the handler returns.  This is the usual
+ * way of setting the exit status.
+ *
+ * In the event that you want the remote invocation to continue running
+ * and want to decide on the exit status in the future, you can use this
+ * call.  For the case of a remote invocation, the remote process will
+ * typically exit when the last reference is dropped on @cmdline.  The
+ * exit status of the remote process will be equal to the last value
+ * that was set with this function.
+ *
+ * In the case that the commandline invocation is local, the situation
+ * is slightly more complicated.  If the commandline invocation results
+ * in the mainloop running (ie: because the use-count of the application
+ * increased to a non-zero value) then the application is considered to
+ * have been 'successful' in a certain sense, and the exit status is
+ * always zero.  If the application use count is zero, though, the exit
+ * status of the local #GApplicationCommandLine is used.
+ *
+ * Since: 2.28
+ **/
+void
+g_application_command_line_set_exit_status (GApplicationCommandLine *cmdline,
+                                            int                      exit_status)
+{
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
+
+  cmdline->priv->exit_status = exit_status;
+}
+
+/**
+ * g_application_command_line_get_exit_status:
+ * @cmdline: a #GApplicationCommandLine
+ *
+ * Gets the exit status of @cmdline.  See
+ * g_application_command_line_set_exit_status() for more information.
+ *
+ * Returns: the exit status
+ *
+ * Since: 2.28
+ **/
+int
+g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline)
+{
+  g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), -1);
+
+  return cmdline->priv->exit_status;
+}
+
+/**
+ * g_application_command_line_get_platform_data:
+ * @cmdline: #GApplicationCommandLine
+ *
+ * Gets the platform data associated with the invocation of @cmdline.
+ *
+ * This is a #GVariant dictionary containing information about the
+ * context in which the invocation occurred.  It typically contains
+ * information like the current working directory and the startup
+ * notification ID.
+ *
+ * For local invocation, it will be %NULL.
+ *
+ * Returns: (nullable): the platform data, or %NULL
+ *
+ * Since: 2.28
+ **/
+GVariant *
+g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline)
+{
+  g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
+
+  if (cmdline->priv->platform_data)
+    return g_variant_ref (cmdline->priv->platform_data);
+  else
+      return NULL;
+}
+
+/**
+ * g_application_command_line_create_file_for_arg:
+ * @cmdline: a #GApplicationCommandLine
+ * @arg: (type filename): an argument from @cmdline
+ *
+ * Creates a #GFile corresponding to a filename that was given as part
+ * of the invocation of @cmdline.
+ *
+ * This differs from g_file_new_for_commandline_arg() in that it
+ * resolves relative pathnames using the current working directory of
+ * the invoking process rather than the local process.
+ *
+ * Returns: (transfer full): a new #GFile
+ *
+ * Since: 2.36
+ **/
+GFile *
+g_application_command_line_create_file_for_arg (GApplicationCommandLine *cmdline,
+                                                const gchar             *arg)
+{
+  g_return_val_if_fail (arg != NULL, NULL);
+
+  if (cmdline->priv->cwd)
+    return g_file_new_for_commandline_arg_and_cwd (arg, cmdline->priv->cwd);
+
+  g_warning ("Requested creation of GFile for commandline invocation that did not send cwd. "
+             "Using cwd of local process to resolve relative path names.");
+
+  return g_file_new_for_commandline_arg (arg);
+}
diff --git a/gio/gapplicationcommandline.h b/gio/gapplicationcommandline.h
new file mode 100644
index 0000000..6610e86
--- /dev/null
+++ b/gio/gapplicationcommandline.h
@@ -0,0 +1,122 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_APPLICATION_COMMAND_LINE_H__
+#define __G_APPLICATION_COMMAND_LINE_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_APPLICATION_COMMAND_LINE                     (g_application_command_line_get_type ())
+#define G_APPLICATION_COMMAND_LINE(inst)                    (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE,                        \
+                                                             GApplicationCommandLine))
+#define G_APPLICATION_COMMAND_LINE_CLASS(class)             (G_TYPE_CHECK_CLASS_CAST ((class),                       \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE,                        \
+                                                             GApplicationCommandLineClass))
+#define G_IS_APPLICATION_COMMAND_LINE(inst)                 (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE))
+#define G_IS_APPLICATION_COMMAND_LINE_CLASS(class)          (G_TYPE_CHECK_CLASS_TYPE ((class),                       \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE))
+#define G_APPLICATION_COMMAND_LINE_GET_CLASS(inst)          (G_TYPE_INSTANCE_GET_CLASS ((inst),                      \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE,                        \
+                                                             GApplicationCommandLineClass))
+
+typedef struct _GApplicationCommandLinePrivate               GApplicationCommandLinePrivate;
+typedef struct _GApplicationCommandLineClass                 GApplicationCommandLineClass;
+
+struct _GApplicationCommandLine
+{
+  /*< private >*/
+  GObject parent_instance;
+
+  GApplicationCommandLinePrivate *priv;
+};
+
+struct _GApplicationCommandLineClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+
+  void                  (* print_literal)       (GApplicationCommandLine *cmdline,
+                                                 const gchar             *message);
+  void                  (* printerr_literal)    (GApplicationCommandLine *cmdline,
+                                                 const gchar             *message);
+  GInputStream *        (* get_stdin)           (GApplicationCommandLine *cmdline);
+
+  gpointer padding[11];
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType                   g_application_command_line_get_type             (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+gchar **                g_application_command_line_get_arguments        (GApplicationCommandLine   *cmdline,
+                                                                         int                       *argc);
+
+GLIB_AVAILABLE_IN_2_40
+GVariantDict *          g_application_command_line_get_options_dict     (GApplicationCommandLine   *cmdline);
+
+GLIB_AVAILABLE_IN_2_36
+GInputStream *          g_application_command_line_get_stdin            (GApplicationCommandLine   *cmdline);
+
+GLIB_AVAILABLE_IN_ALL
+const gchar * const *   g_application_command_line_get_environ          (GApplicationCommandLine   *cmdline);
+
+GLIB_AVAILABLE_IN_ALL
+const gchar *           g_application_command_line_getenv               (GApplicationCommandLine   *cmdline,
+                                                                         const gchar               *name);
+
+GLIB_AVAILABLE_IN_ALL
+const gchar *           g_application_command_line_get_cwd              (GApplicationCommandLine   *cmdline);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean                g_application_command_line_get_is_remote        (GApplicationCommandLine   *cmdline);
+
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_command_line_print                (GApplicationCommandLine   *cmdline,
+                                                                         const gchar               *format,
+                                                                         ...) G_GNUC_PRINTF(2, 3);
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_command_line_printerr             (GApplicationCommandLine   *cmdline,
+                                                                         const gchar               *format,
+                                                                         ...) G_GNUC_PRINTF(2, 3);
+
+GLIB_AVAILABLE_IN_ALL
+int                     g_application_command_line_get_exit_status      (GApplicationCommandLine   *cmdline);
+GLIB_AVAILABLE_IN_ALL
+void                    g_application_command_line_set_exit_status      (GApplicationCommandLine   *cmdline,
+                                                                         int                        exit_status);
+
+GLIB_AVAILABLE_IN_ALL
+GVariant *              g_application_command_line_get_platform_data    (GApplicationCommandLine   *cmdline);
+
+GLIB_AVAILABLE_IN_2_36
+GFile *                 g_application_command_line_create_file_for_arg  (GApplicationCommandLine   *cmdline,
+                                                                         const gchar               *arg);
+
+G_END_DECLS
+
+#endif /* __G_APPLICATION_COMMAND_LINE_H__ */
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
new file mode 100644
index 0000000..fd9d046
--- /dev/null
+++ b/gio/gapplicationimpl-dbus.c
@@ -0,0 +1,995 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gapplicationimpl.h"
+
+#include "gactiongroup.h"
+#include "gactiongroupexporter.h"
+#include "gremoteactiongroup.h"
+#include "gdbusactiongroup-private.h"
+#include "gapplication.h"
+#include "gfile.h"
+#include "gdbusconnection.h"
+#include "gdbusintrospection.h"
+#include "gdbuserror.h"
+#include "glib/gstdio.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "gapplicationcommandline.h"
+#include "gdbusmethodinvocation.h"
+
+#ifdef G_OS_UNIX
+#include "gunixinputstream.h"
+#include "gunixfdlist.h"
+#endif
+
+/* DBus Interface definition {{{1 */
+
+/* For documentation of these interfaces, see
+ * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI
+ */
+static const gchar org_gtk_Application_xml[] =
+  "<node>"
+    "<interface name='org.gtk.Application'>"
+      "<method name='Activate'>"
+        "<arg type='a{sv}' name='platform-data' direction='in'/>"
+      "</method>"
+      "<method name='Open'>"
+        "<arg type='as' name='uris' direction='in'/>"
+        "<arg type='s' name='hint' direction='in'/>"
+        "<arg type='a{sv}' name='platform-data' direction='in'/>"
+      "</method>"
+      "<method name='CommandLine'>"
+        "<arg type='o' name='path' direction='in'/>"
+        "<arg type='aay' name='arguments' direction='in'/>"
+        "<arg type='a{sv}' name='platform-data' direction='in'/>"
+        "<arg type='i' name='exit-status' direction='out'/>"
+      "</method>"
+    "<property name='Busy' type='b' access='read'/>"
+    "</interface>"
+  "</node>";
+
+static GDBusInterfaceInfo *org_gtk_Application;
+
+static const gchar org_freedesktop_Application_xml[] =
+  "<node>"
+    "<interface name='org.freedesktop.Application'>"
+      "<method name='Activate'>"
+        "<arg type='a{sv}' name='platform-data' direction='in'/>"
+      "</method>"
+      "<method name='Open'>"
+        "<arg type='as' name='uris' direction='in'/>"
+        "<arg type='a{sv}' name='platform-data' direction='in'/>"
+      "</method>"
+      "<method name='ActivateAction'>"
+        "<arg type='s' name='action-name' direction='in'/>"
+        "<arg type='av' name='parameter' direction='in'/>"
+        "<arg type='a{sv}' name='platform-data' direction='in'/>"
+      "</method>"
+    "</interface>"
+  "</node>";
+
+static GDBusInterfaceInfo *org_freedesktop_Application;
+
+static const gchar org_gtk_private_CommandLine_xml[] =
+  "<node>"
+    "<interface name='org.gtk.private.CommandLine'>"
+      "<method name='Print'>"
+        "<arg type='s' name='message' direction='in'/>"
+      "</method>"
+      "<method name='PrintError'>"
+        "<arg type='s' name='message' direction='in'/>"
+      "</method>"
+    "</interface>"
+  "</node>";
+
+static GDBusInterfaceInfo *org_gtk_private_CommandLine;
+
+/* GApplication implementation {{{1 */
+struct _GApplicationImpl
+{
+  GDBusConnection *session_bus;
+  GActionGroup    *exported_actions;
+  const gchar     *bus_name;
+  guint            name_lost_signal;
+
+  gchar           *object_path;
+  guint            object_id;
+  guint            fdo_object_id;
+  guint            actions_id;
+
+  gboolean         properties_live;
+  gboolean         primary;
+  gboolean         busy;
+  gboolean         registered;
+  GApplication    *app;
+};
+
+
+static GApplicationCommandLine *
+g_dbus_command_line_new (GDBusMethodInvocation *invocation);
+
+static GVariant *
+g_application_impl_get_property (GDBusConnection *connection,
+                                 const gchar  *sender,
+                                 const gchar  *object_path,
+                                 const gchar  *interface_name,
+                                 const gchar  *property_name,
+                                 GError      **error,
+                                 gpointer      user_data)
+{
+  GApplicationImpl *impl = user_data;
+
+  if (strcmp (property_name, "Busy") == 0)
+    return g_variant_new_boolean (impl->busy);
+
+  g_assert_not_reached ();
+
+  return NULL;
+}
+
+static void
+send_property_change (GApplicationImpl *impl)
+{
+  GVariantBuilder builder;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+  g_variant_builder_add (&builder,
+                         "{sv}",
+                         "Busy", g_variant_new_boolean (impl->busy));
+
+  g_dbus_connection_emit_signal (impl->session_bus,
+                                 NULL,
+                                 impl->object_path,
+                                 "org.freedesktop.DBus.Properties",
+                                 "PropertiesChanged",
+                                 g_variant_new ("(sa{sv}as)",
+                                                "org.gtk.Application",
+                                                &builder,
+                                                NULL),
+                                 NULL);
+}
+
+static void
+g_application_impl_method_call (GDBusConnection       *connection,
+                                const gchar           *sender,
+                                const gchar           *object_path,
+                                const gchar           *interface_name,
+                                const gchar           *method_name,
+                                GVariant              *parameters,
+                                GDBusMethodInvocation *invocation,
+                                gpointer               user_data)
+{
+  GApplicationImpl *impl = user_data;
+  GApplicationClass *class;
+
+  class = G_APPLICATION_GET_CLASS (impl->app);
+
+  if (strcmp (method_name, "Activate") == 0)
+    {
+      GVariant *platform_data;
+
+      /* Completely the same for both freedesktop and gtk interfaces */
+
+      g_variant_get (parameters, "(@a{sv})", &platform_data);
+
+      class->before_emit (impl->app, platform_data);
+      g_signal_emit_by_name (impl->app, "activate");
+      class->after_emit (impl->app, platform_data);
+      g_variant_unref (platform_data);
+
+      g_dbus_method_invocation_return_value (invocation, NULL);
+    }
+
+  else if (strcmp (method_name, "Open") == 0)
+    {
+      GApplicationFlags flags;
+      GVariant *platform_data;
+      const gchar *hint;
+      GVariant *array;
+      GFile **files;
+      gint n, i;
+
+      flags = g_application_get_flags (impl->app);
+      if ((flags & G_APPLICATION_HANDLES_OPEN) == 0)
+        {
+          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "Application does not open files");
+          return;
+        }
+
+      /* freedesktop interface has no hint parameter */
+      if (g_str_equal (interface_name, "org.freedesktop.Application"))
+        {
+          g_variant_get (parameters, "(@as@a{sv})", &array, &platform_data);
+          hint = "";
+        }
+      else
+        g_variant_get (parameters, "(@as&s@a{sv})", &array, &hint, &platform_data);
+
+      n = g_variant_n_children (array);
+      files = g_new (GFile *, n + 1);
+
+      for (i = 0; i < n; i++)
+        {
+          const gchar *uri;
+
+          g_variant_get_child (array, i, "&s", &uri);
+          files[i] = g_file_new_for_uri (uri);
+        }
+      g_variant_unref (array);
+      files[n] = NULL;
+
+      class->before_emit (impl->app, platform_data);
+      g_signal_emit_by_name (impl->app, "open", files, n, hint);
+      class->after_emit (impl->app, platform_data);
+
+      g_variant_unref (platform_data);
+
+      for (i = 0; i < n; i++)
+        g_object_unref (files[i]);
+      g_free (files);
+
+      g_dbus_method_invocation_return_value (invocation, NULL);
+    }
+
+  else if (strcmp (method_name, "CommandLine") == 0)
+    {
+      GApplicationFlags flags;
+      GApplicationCommandLine *cmdline;
+      GVariant *platform_data;
+      int status;
+
+      flags = g_application_get_flags (impl->app);
+      if ((flags & G_APPLICATION_HANDLES_COMMAND_LINE) == 0)
+        {
+          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED,
+                                                 "Application does not handle command line arguments");
+          return;
+        }
+
+      /* Only on the GtkApplication interface */
+
+      cmdline = g_dbus_command_line_new (invocation);
+      platform_data = g_variant_get_child_value (parameters, 2);
+      class->before_emit (impl->app, platform_data);
+      g_signal_emit_by_name (impl->app, "command-line", cmdline, &status);
+      g_application_command_line_set_exit_status (cmdline, status);
+      class->after_emit (impl->app, platform_data);
+      g_variant_unref (platform_data);
+      g_object_unref (cmdline);
+    }
+  else if (g_str_equal (method_name, "ActivateAction"))
+    {
+      GVariant *parameter = NULL;
+      GVariant *platform_data;
+      GVariantIter *iter;
+      const gchar *name;
+
+      /* Only on the freedesktop interface */
+
+      g_variant_get (parameters, "(&sav@a{sv})", &name, &iter, &platform_data);
+      g_variant_iter_next (iter, "v", &parameter);
+      g_variant_iter_free (iter);
+
+      class->before_emit (impl->app, platform_data);
+      g_action_group_activate_action (impl->exported_actions, name, parameter);
+      class->after_emit (impl->app, platform_data);
+
+      if (parameter)
+        g_variant_unref (parameter);
+
+      g_variant_unref (platform_data);
+
+      g_dbus_method_invocation_return_value (invocation, NULL);
+    }
+  else
+    g_assert_not_reached ();
+}
+
+static gchar *
+application_path_from_appid (const gchar *appid)
+{
+  gchar *appid_path, *iter;
+
+  if (appid == NULL)
+    /* this is a private implementation detail */
+    return g_strdup ("/org/gtk/Application/anonymous");
+
+  appid_path = g_strconcat ("/", appid, NULL);
+  for (iter = appid_path; *iter; iter++)
+    {
+      if (*iter == '.')
+        *iter = '/';
+
+      if (*iter == '-')
+        *iter = '_';
+    }
+
+  return appid_path;
+}
+
+static void g_application_impl_stop_primary (GApplicationImpl *impl);
+
+static void
+name_lost (GDBusConnection *bus,
+           const char      *sender_name,
+           const char      *object_path,
+           const char      *interface_name,
+           const char      *signal_name,
+           GVariant        *parameters,
+           gpointer         user_data)
+{
+  GApplicationImpl *impl = user_data;
+  gboolean handled;
+
+  impl->primary = FALSE;
+  g_application_impl_stop_primary (impl);
+  g_signal_emit_by_name (impl->app, "name-lost", &handled);
+}
+
+/* Attempt to become the primary instance.
+ *
+ * Returns %TRUE if everything went OK, regardless of if we became the
+ * primary instance or not.  %FALSE is reserved for when something went
+ * seriously wrong (and @error will be set too, in that case).
+ *
+ * After a %TRUE return, impl->primary will be TRUE if we were
+ * successful.
+ */
+static gboolean
+g_application_impl_attempt_primary (GApplicationImpl  *impl,
+                                    GCancellable      *cancellable,
+                                    GError           **error)
+{
+  const static GDBusInterfaceVTable vtable = {
+    g_application_impl_method_call,
+    g_application_impl_get_property,
+    NULL /* set_property */
+  };
+  GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
+  GBusNameOwnerFlags name_owner_flags;
+  GApplicationFlags app_flags;
+  GVariant *reply;
+  guint32 rval;
+
+  if (org_gtk_Application == NULL)
+    {
+      GError *error = NULL;
+      GDBusNodeInfo *info;
+
+      info = g_dbus_node_info_new_for_xml (org_gtk_Application_xml, &error);
+      if G_UNLIKELY (info == NULL)
+        g_error ("%s", error->message);
+      org_gtk_Application = g_dbus_node_info_lookup_interface (info, "org.gtk.Application");
+      g_assert (org_gtk_Application != NULL);
+      g_dbus_interface_info_ref (org_gtk_Application);
+      g_dbus_node_info_unref (info);
+
+      info = g_dbus_node_info_new_for_xml (org_freedesktop_Application_xml, &error);
+      if G_UNLIKELY (info == NULL)
+        g_error ("%s", error->message);
+      org_freedesktop_Application = g_dbus_node_info_lookup_interface (info, "org.freedesktop.Application");
+      g_assert (org_freedesktop_Application != NULL);
+      g_dbus_interface_info_ref (org_freedesktop_Application);
+      g_dbus_node_info_unref (info);
+    }
+
+  /* We could possibly have been D-Bus activated as a result of incoming
+   * requests on either the application or actiongroup interfaces.
+   * Because of how GDBus dispatches messages, we need to ensure that
+   * both of those things are registered before we attempt to request
+   * our name.
+   *
+   * The action group need not be populated yet, as long as it happens
+   * before we return to the mainloop.  The reason for that is because
+   * GDBus does the check to make sure the object exists from the worker
+   * thread but doesn't actually dispatch the action invocation until we
+   * hit the mainloop in this thread.  There is also no danger of
+   * receiving 'activate' or 'open' signals until after 'startup' runs,
+   * for the same reason.
+   */
+  impl->object_id = g_dbus_connection_register_object (impl->session_bus, impl->object_path,
+                                                       org_gtk_Application, &vtable, impl, NULL, error);
+
+  if (impl->object_id == 0)
+    return FALSE;
+
+  impl->fdo_object_id = g_dbus_connection_register_object (impl->session_bus, impl->object_path,
+                                                           org_freedesktop_Application, &vtable, impl, NULL, error);
+
+  if (impl->fdo_object_id == 0)
+    return FALSE;
+
+  impl->actions_id = g_dbus_connection_export_action_group (impl->session_bus, impl->object_path,
+                                                            impl->exported_actions, error);
+
+  if (impl->actions_id == 0)
+    return FALSE;
+
+  impl->registered = TRUE;
+  if (!app_class->dbus_register (impl->app,
+                                 impl->session_bus,
+                                 impl->object_path,
+                                 error))
+    return FALSE;
+
+  if (impl->bus_name == NULL)
+    {
+      /* If this is a non-unique application then it is sufficient to
+       * have our object paths registered. We can return now.
+       *
+       * Note: non-unique applications always act as primary-instance.
+       */
+      impl->primary = TRUE;
+      return TRUE;
+    }
+
+  /* If this is a unique application then we need to attempt to own
+   * the well-known name and fall back to remote mode (!is_primary)
+   * in the case that we can't do that.
+   */
+  name_owner_flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE;
+  app_flags = g_application_get_flags (impl->app);
+
+  if (app_flags & G_APPLICATION_ALLOW_REPLACEMENT)
+    {
+      impl->name_lost_signal = g_dbus_connection_signal_subscribe (impl->session_bus,
+                                                                   "org.freedesktop.DBus",
+                                                                   "org.freedesktop.DBus",
+                                                                   "NameLost",
+                                                                   "/org/freedesktop/DBus",
+                                                                   impl->bus_name,
+                                                                   G_DBUS_SIGNAL_FLAGS_NONE,
+                                                                   name_lost,
+                                                                   impl,
+                                                                   NULL);
+
+      name_owner_flags |= G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
+    }
+  if (app_flags & G_APPLICATION_REPLACE)
+    name_owner_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
+  reply = g_dbus_connection_call_sync (impl->session_bus,
+                                       "org.freedesktop.DBus",
+                                       "/org/freedesktop/DBus",
+                                       "org.freedesktop.DBus",
+                                       "RequestName",
+                                       g_variant_new ("(su)", impl->bus_name, name_owner_flags),
+                                       G_VARIANT_TYPE ("(u)"),
+                                       0, -1, cancellable, error);
+
+  if (reply == NULL)
+    return FALSE;
+
+  g_variant_get (reply, "(u)", &rval);
+  g_variant_unref (reply);
+
+  /* DBUS_REQUEST_NAME_REPLY_EXISTS: 3 */
+  impl->primary = (rval != 3);
+
+  if (!impl->primary && impl->name_lost_signal)
+    {
+      g_dbus_connection_signal_unsubscribe (impl->session_bus, impl->name_lost_signal);
+      impl->name_lost_signal = 0;
+    }
+
+  return TRUE;
+}
+
+/* Stop doing the things that the primary instance does.
+ *
+ * This should be called if attempting to become the primary instance
+ * failed (in order to clean up any partial success) and should also
+ * be called when freeing the GApplication.
+ *
+ * It is safe to call this multiple times.
+ */
+static void
+g_application_impl_stop_primary (GApplicationImpl *impl)
+{
+  GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
+
+  if (impl->registered)
+    {
+      app_class->dbus_unregister (impl->app,
+                                  impl->session_bus,
+                                  impl->object_path);
+      impl->registered = FALSE;
+    }
+
+  if (impl->object_id)
+    {
+      g_dbus_connection_unregister_object (impl->session_bus, impl->object_id);
+      impl->object_id = 0;
+    }
+
+  if (impl->fdo_object_id)
+    {
+      g_dbus_connection_unregister_object (impl->session_bus, impl->fdo_object_id);
+      impl->fdo_object_id = 0;
+    }
+
+  if (impl->actions_id)
+    {
+      g_dbus_connection_unexport_action_group (impl->session_bus, impl->actions_id);
+      impl->actions_id = 0;
+    }
+
+  if (impl->name_lost_signal)
+    {
+      g_dbus_connection_signal_unsubscribe (impl->session_bus, impl->name_lost_signal);
+      impl->name_lost_signal = 0;
+    }
+
+  if (impl->primary && impl->bus_name)
+    {
+      g_dbus_connection_call (impl->session_bus, "org.freedesktop.DBus",
+                              "/org/freedesktop/DBus", "org.freedesktop.DBus",
+                              "ReleaseName", g_variant_new ("(s)", impl->bus_name),
+                              NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+      impl->primary = FALSE;
+    }
+}
+
+void
+g_application_impl_set_busy_state (GApplicationImpl *impl,
+                                   gboolean          busy)
+{
+  if (impl->busy != busy)
+    {
+      impl->busy = busy;
+      send_property_change (impl);
+    }
+}
+
+void
+g_application_impl_destroy (GApplicationImpl *impl)
+{
+  g_application_impl_stop_primary (impl);
+
+  if (impl->session_bus)
+    g_object_unref (impl->session_bus);
+
+  g_free (impl->object_path);
+
+  g_slice_free (GApplicationImpl, impl);
+}
+
+GApplicationImpl *
+g_application_impl_register (GApplication        *application,
+                             const gchar         *appid,
+                             GApplicationFlags    flags,
+                             GActionGroup        *exported_actions,
+                             GRemoteActionGroup **remote_actions,
+                             GCancellable        *cancellable,
+                             GError             **error)
+{
+  GDBusActionGroup *actions;
+  GApplicationImpl *impl;
+
+  g_assert ((flags & G_APPLICATION_NON_UNIQUE) || appid != NULL);
+
+  impl = g_slice_new0 (GApplicationImpl);
+
+  impl->app = application;
+  impl->exported_actions = exported_actions;
+
+  /* non-unique applications do not attempt to acquire a bus name */
+  if (~flags & G_APPLICATION_NON_UNIQUE)
+    impl->bus_name = appid;
+
+  impl->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, NULL);
+
+  if (impl->session_bus == NULL)
+    {
+      /* If we can't connect to the session bus, proceed as a normal
+       * non-unique application.
+       */
+      *remote_actions = NULL;
+      return impl;
+    }
+
+  impl->object_path = application_path_from_appid (appid);
+
+  /* Only try to be the primary instance if
+   * G_APPLICATION_IS_LAUNCHER was not specified.
+   */
+  if (~flags & G_APPLICATION_IS_LAUNCHER)
+    {
+      if (!g_application_impl_attempt_primary (impl, cancellable, error))
+        {
+          g_application_impl_destroy (impl);
+          return NULL;
+        }
+
+      if (impl->primary)
+        return impl;
+
+      /* We didn't make it.  Drop our service-side stuff. */
+      g_application_impl_stop_primary (impl);
+
+      if (flags & G_APPLICATION_IS_SERVICE)
+        {
+          g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+                       "Unable to acquire bus name '%s'", appid);
+          g_application_impl_destroy (impl);
+
+          return NULL;
+        }
+    }
+
+  /* We are non-primary.  Try to get the primary's list of actions.
+   * This also serves as a mechanism to ensure that the primary exists
+   * (ie: DBus service files installed correctly, etc).
+   */
+  actions = g_dbus_action_group_get (impl->session_bus, impl->bus_name, impl->object_path);
+  if (!g_dbus_action_group_sync (actions, cancellable, error))
+    {
+      /* The primary appears not to exist.  Fail the registration. */
+      g_application_impl_destroy (impl);
+      g_object_unref (actions);
+
+      return NULL;
+    }
+
+  *remote_actions = G_REMOTE_ACTION_GROUP (actions);
+
+  return impl;
+}
+
+void
+g_application_impl_activate (GApplicationImpl *impl,
+                             GVariant         *platform_data)
+{
+  g_dbus_connection_call (impl->session_bus,
+                          impl->bus_name,
+                          impl->object_path,
+                          "org.gtk.Application",
+                          "Activate",
+                          g_variant_new ("(@a{sv})", platform_data),
+                          NULL, 0, -1, NULL, NULL, NULL);
+}
+
+void
+g_application_impl_open (GApplicationImpl  *impl,
+                         GFile            **files,
+                         gint               n_files,
+                         const gchar       *hint,
+                         GVariant          *platform_data)
+{
+  GVariantBuilder builder;
+  gint i;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(assa{sv})"));
+  g_variant_builder_open (&builder, G_VARIANT_TYPE_STRING_ARRAY);
+  for (i = 0; i < n_files; i++)
+    {
+      gchar *uri = g_file_get_uri (files[i]);
+      g_variant_builder_add (&builder, "s", uri);
+      g_free (uri);
+    }
+  g_variant_builder_close (&builder);
+  g_variant_builder_add (&builder, "s", hint);
+  g_variant_builder_add_value (&builder, platform_data);
+
+  g_dbus_connection_call (impl->session_bus,
+                          impl->bus_name,
+                          impl->object_path,
+                          "org.gtk.Application",
+                          "Open",
+                          g_variant_builder_end (&builder),
+                          NULL, 0, -1, NULL, NULL, NULL);
+}
+
+static void
+g_application_impl_cmdline_method_call (GDBusConnection       *connection,
+                                        const gchar           *sender,
+                                        const gchar           *object_path,
+                                        const gchar           *interface_name,
+                                        const gchar           *method_name,
+                                        GVariant              *parameters,
+                                        GDBusMethodInvocation *invocation,
+                                        gpointer               user_data)
+{
+  const gchar *message;
+
+  g_variant_get_child (parameters, 0, "&s", &message);
+
+  if (strcmp (method_name, "Print") == 0)
+    g_print ("%s", message);
+  else if (strcmp (method_name, "PrintError") == 0)
+    g_printerr ("%s", message);
+  else
+    g_assert_not_reached ();
+
+  g_dbus_method_invocation_return_value (invocation, NULL);
+}
+
+typedef struct
+{
+  GMainLoop *loop;
+  int status;
+} CommandLineData;
+
+static void
+g_application_impl_cmdline_done (GObject      *source,
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
+{
+  CommandLineData *data = user_data;
+  GError *error = NULL;
+  GVariant *reply;
+
+#ifdef G_OS_UNIX
+  reply = g_dbus_connection_call_with_unix_fd_list_finish (G_DBUS_CONNECTION (source), NULL, result, &error);
+#else
+  reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+#endif
+
+
+  if (reply != NULL)
+    {
+      g_variant_get (reply, "(i)", &data->status);
+      g_variant_unref (reply);
+    }
+
+  else
+    {
+      g_printerr ("%s\n", error->message);
+      g_error_free (error);
+      data->status = 1;
+    }
+
+  g_main_loop_quit (data->loop);
+}
+
+int
+g_application_impl_command_line (GApplicationImpl    *impl,
+                                 const gchar * const *arguments,
+                                 GVariant            *platform_data)
+{
+  const static GDBusInterfaceVTable vtable = {
+    g_application_impl_cmdline_method_call
+  };
+  const gchar *object_path = "/org/gtk/Application/CommandLine";
+  GMainContext *context;
+  CommandLineData data;
+  guint object_id G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
+
+  context = g_main_context_new ();
+  data.loop = g_main_loop_new (context, FALSE);
+  g_main_context_push_thread_default (context);
+
+  if (org_gtk_private_CommandLine == NULL)
+    {
+      GError *error = NULL;
+      GDBusNodeInfo *info;
+
+      info = g_dbus_node_info_new_for_xml (org_gtk_private_CommandLine_xml, &error);
+      if G_UNLIKELY (info == NULL)
+        g_error ("%s", error->message);
+      org_gtk_private_CommandLine = g_dbus_node_info_lookup_interface (info, "org.gtk.private.CommandLine");
+      g_assert (org_gtk_private_CommandLine != NULL);
+      g_dbus_interface_info_ref (org_gtk_private_CommandLine);
+      g_dbus_node_info_unref (info);
+    }
+
+  object_id = g_dbus_connection_register_object (impl->session_bus, object_path,
+                                                 org_gtk_private_CommandLine,
+                                                 &vtable, &data, NULL, NULL);
+  /* In theory we should try other paths... */
+  g_assert (object_id != 0);
+
+#ifdef G_OS_UNIX
+  {
+    GError *error = NULL;
+    GUnixFDList *fd_list;
+
+    /* send along the stdin in case
+     * g_application_command_line_get_stdin_data() is called
+     */
+    fd_list = g_unix_fd_list_new ();
+    g_unix_fd_list_append (fd_list, 0, &error);
+    g_assert_no_error (error);
+
+    g_dbus_connection_call_with_unix_fd_list (impl->session_bus, impl->bus_name, impl->object_path,
+                                              "org.gtk.Application", "CommandLine",
+                                              g_variant_new ("(o^aay@a{sv})", object_path, arguments, platform_data),
+                                              G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, fd_list, NULL,
+                                              g_application_impl_cmdline_done, &data);
+    g_object_unref (fd_list);
+  }
+#else
+  g_dbus_connection_call (impl->session_bus, impl->bus_name, impl->object_path,
+                          "org.gtk.Application", "CommandLine",
+                          g_variant_new ("(o^aay@a{sv})", object_path, arguments, platform_data),
+                          G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, NULL,
+                          g_application_impl_cmdline_done, &data);
+#endif
+
+  g_main_loop_run (data.loop);
+
+  g_main_context_pop_thread_default (context);
+  g_main_context_unref (context);
+  g_main_loop_unref (data.loop);
+
+  return data.status;
+}
+
+void
+g_application_impl_flush (GApplicationImpl *impl)
+{
+  if (impl->session_bus)
+    g_dbus_connection_flush_sync (impl->session_bus, NULL, NULL);
+}
+
+GDBusConnection *
+g_application_impl_get_dbus_connection (GApplicationImpl *impl)
+{
+  return impl->session_bus;
+}
+
+const gchar *
+g_application_impl_get_dbus_object_path (GApplicationImpl *impl)
+{
+  return impl->object_path;
+}
+
+/* GDBusCommandLine implementation {{{1 */
+
+typedef GApplicationCommandLineClass GDBusCommandLineClass;
+static GType g_dbus_command_line_get_type (void);
+typedef struct
+{
+  GApplicationCommandLine  parent_instance;
+  GDBusMethodInvocation   *invocation;
+
+  GDBusConnection *connection;
+  const gchar     *bus_name;
+  const gchar     *object_path;
+} GDBusCommandLine;
+
+
+G_DEFINE_TYPE (GDBusCommandLine,
+               g_dbus_command_line,
+               G_TYPE_APPLICATION_COMMAND_LINE)
+
+static void
+g_dbus_command_line_print_literal (GApplicationCommandLine *cmdline,
+                                   const gchar             *message)
+{
+  GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
+
+  g_dbus_connection_call (gdbcl->connection,
+                          gdbcl->bus_name,
+                          gdbcl->object_path,
+                          "org.gtk.private.CommandLine", "Print",
+                          g_variant_new ("(s)", message),
+                          NULL, 0, -1, NULL, NULL, NULL);
+}
+
+static void
+g_dbus_command_line_printerr_literal (GApplicationCommandLine *cmdline,
+                                      const gchar             *message)
+{
+  GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
+
+  g_dbus_connection_call (gdbcl->connection,
+                          gdbcl->bus_name,
+                          gdbcl->object_path,
+                          "org.gtk.private.CommandLine", "PrintError",
+                          g_variant_new ("(s)", message),
+                          NULL, 0, -1, NULL, NULL, NULL);
+}
+
+static GInputStream *
+g_dbus_command_line_get_stdin (GApplicationCommandLine *cmdline)
+{
+#ifdef G_OS_UNIX
+  GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
+  GInputStream *result = NULL;
+  GDBusMessage *message;
+  GUnixFDList *fd_list;
+
+  message = g_dbus_method_invocation_get_message (gdbcl->invocation);
+  fd_list = g_dbus_message_get_unix_fd_list (message);
+
+  if (fd_list && g_unix_fd_list_get_length (fd_list))
+    {
+      gint *fds, n_fds, i;
+
+      fds = g_unix_fd_list_steal_fds (fd_list, &n_fds);
+      result = g_unix_input_stream_new (fds[0], TRUE);
+      for (i = 1; i < n_fds; i++)
+        (void) g_close (fds[i], NULL);
+      g_free (fds);
+    }
+
+  return result;
+#else
+  return NULL;
+#endif
+}
+
+static void
+g_dbus_command_line_finalize (GObject *object)
+{
+  GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
+  GDBusCommandLine *gdbcl = (GDBusCommandLine *) object;
+  gint status;
+
+  status = g_application_command_line_get_exit_status (cmdline);
+
+  g_dbus_method_invocation_return_value (gdbcl->invocation,
+                                         g_variant_new ("(i)", status));
+  g_object_unref (gdbcl->invocation);
+
+  G_OBJECT_CLASS (g_dbus_command_line_parent_class)
+    ->finalize (object);
+}
+
+static void
+g_dbus_command_line_init (GDBusCommandLine *gdbcl)
+{
+}
+
+static void
+g_dbus_command_line_class_init (GApplicationCommandLineClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = g_dbus_command_line_finalize;
+  class->printerr_literal = g_dbus_command_line_printerr_literal;
+  class->print_literal = g_dbus_command_line_print_literal;
+  class->get_stdin = g_dbus_command_line_get_stdin;
+}
+
+static GApplicationCommandLine *
+g_dbus_command_line_new (GDBusMethodInvocation *invocation)
+{
+  GDBusCommandLine *gdbcl;
+  GVariant *args;
+  GVariant *arguments, *platform_data;
+
+  args = g_dbus_method_invocation_get_parameters (invocation);
+
+  arguments = g_variant_get_child_value (args, 1);
+  platform_data = g_variant_get_child_value (args, 2);
+  gdbcl = g_object_new (g_dbus_command_line_get_type (),
+                        "arguments", arguments,
+                        "platform-data", platform_data,
+                        NULL);
+  g_variant_unref (arguments);
+  g_variant_unref (platform_data);
+
+  gdbcl->connection = g_dbus_method_invocation_get_connection (invocation);
+  gdbcl->bus_name = g_dbus_method_invocation_get_sender (invocation);
+  g_variant_get_child (args, 0, "&o", &gdbcl->object_path);
+  gdbcl->invocation = g_object_ref (invocation);
+
+  return G_APPLICATION_COMMAND_LINE (gdbcl);
+}
+
+/* Epilogue {{{1 */
+
+/* vim:set foldmethod=marker: */
diff --git a/gio/gapplicationimpl.h b/gio/gapplicationimpl.h
new file mode 100644
index 0000000..1e6a718
--- /dev/null
+++ b/gio/gapplicationimpl.h
@@ -0,0 +1,44 @@
+#include "giotypes.h"
+
+typedef struct _GApplicationImpl GApplicationImpl;
+
+typedef struct
+{
+  gchar *name;
+
+  GVariantType *parameter_type;
+  gboolean      enabled;
+  GVariant     *state;
+} RemoteActionInfo;
+
+void                    g_application_impl_destroy                      (GApplicationImpl   *impl);
+
+GApplicationImpl *      g_application_impl_register                     (GApplication        *application,
+                                                                         const gchar         *appid,
+                                                                         GApplicationFlags    flags,
+                                                                         GActionGroup        *exported_actions,
+                                                                         GRemoteActionGroup **remote_actions,
+                                                                         GCancellable        *cancellable,
+                                                                         GError             **error);
+
+void                    g_application_impl_activate                     (GApplicationImpl   *impl,
+                                                                         GVariant           *platform_data);
+
+void                    g_application_impl_open                         (GApplicationImpl   *impl,
+                                                                         GFile             **files,
+                                                                         gint                n_files,
+                                                                         const gchar        *hint,
+                                                                         GVariant           *platform_data);
+
+int                     g_application_impl_command_line                 (GApplicationImpl   *impl,
+                                                                         const gchar *const *arguments,
+                                                                         GVariant           *platform_data);
+
+void                    g_application_impl_flush                        (GApplicationImpl   *impl);
+
+GDBusConnection *       g_application_impl_get_dbus_connection          (GApplicationImpl   *impl);
+
+const gchar *           g_application_impl_get_dbus_object_path         (GApplicationImpl   *impl);
+
+void                    g_application_impl_set_busy_state               (GApplicationImpl   *impl,
+                                                                         gboolean            busy);
diff --git a/gio/gasynchelper.c b/gio/gasynchelper.c
new file mode 100644
index 0000000..8b18835
--- /dev/null
+++ b/gio/gasynchelper.c
@@ -0,0 +1,87 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gasynchelper.h"
+
+
+/*< private >
+ * SECTION:gasynchelper
+ * @short_description: Asynchronous Helper Functions
+ * @include: gio/gio.h
+ * @see_also: #GAsyncResult
+ * 
+ * Provides helper functions for asynchronous operations.
+ *
+ **/
+
+#ifdef G_OS_WIN32
+gboolean
+_g_win32_overlap_wait_result (HANDLE           hfile,
+                              OVERLAPPED      *overlap,
+                              DWORD           *transferred,
+                              GCancellable    *cancellable)
+{
+  GPollFD pollfd[2];
+  gboolean result = FALSE;
+  gint num, npoll;
+
+#if GLIB_SIZEOF_VOID_P == 8
+  pollfd[0].fd = (gint64)overlap->hEvent;
+#else
+  pollfd[0].fd = (gint)overlap->hEvent;
+#endif
+  pollfd[0].events = G_IO_IN;
+  num = 1;
+
+  if (g_cancellable_make_pollfd (cancellable, &pollfd[1]))
+    num++;
+
+loop:
+  npoll = g_poll (pollfd, num, -1);
+  if (npoll <= 0)
+    /* error out, should never happen */
+    goto end;
+
+  if (g_cancellable_is_cancelled (cancellable))
+    {
+      /* CancelIO only cancels pending operations issued by the
+       * current thread and since we're doing only sync operations,
+       * this is safe.... */
+      /* CancelIoEx is only Vista+. Since we have only one overlap
+       * operation on this thread, we can just use: */
+      result = CancelIo (hfile);
+      g_warn_if_fail (result);
+    }
+
+  result = GetOverlappedResult (overlap->hEvent, overlap, transferred, FALSE);
+  if (result == FALSE &&
+      GetLastError () == ERROR_IO_INCOMPLETE &&
+      !g_cancellable_is_cancelled (cancellable))
+    goto loop;
+
+end:
+  if (num > 1)
+    g_cancellable_release_fd (cancellable);
+
+  return result;
+}
+#endif
diff --git a/gio/gasynchelper.h b/gio/gasynchelper.h
new file mode 100644
index 0000000..ded5a22
--- /dev/null
+++ b/gio/gasynchelper.h
@@ -0,0 +1,41 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_ASYNC_HELPER_H__
+#define __G_ASYNC_HELPER_H__
+
+#include <gio/gio.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+
+G_BEGIN_DECLS
+
+#ifdef G_OS_WIN32
+gboolean _g_win32_overlap_wait_result (HANDLE           hfile,
+                                       OVERLAPPED      *overlap,
+                                       DWORD           *transferred,
+                                       GCancellable    *cancellable);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_ASYNC_HELPER_H__ */
diff --git a/gio/gasyncinitable.c b/gio/gasyncinitable.c
new file mode 100644
index 0000000..8936f98
--- /dev/null
+++ b/gio/gasyncinitable.c
@@ -0,0 +1,463 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include "gasyncinitable.h"
+#include "gasyncresult.h"
+#include "gsimpleasyncresult.h"
+#include "gtask.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gasyncinitable
+ * @short_description: Asynchronously failable object initialization interface
+ * @include: gio/gio.h
+ * @see_also: #GInitable
+ *
+ * This is the asynchronous version of #GInitable; it behaves the same
+ * in all ways except that initialization is asynchronous. For more details
+ * see the descriptions on #GInitable.
+ *
+ * A class may implement both the #GInitable and #GAsyncInitable interfaces.
+ *
+ * Users of objects implementing this are not intended to use the interface
+ * method directly; instead it will be used automatically in various ways.
+ * For C applications you generally just call g_async_initable_new_async()
+ * directly, or indirectly via a foo_thing_new_async() wrapper. This will call
+ * g_async_initable_init_async() under the cover, calling back with %NULL and
+ * a set %GError on failure.
+ *
+ * A typical implementation might look something like this:
+ *
+ * |[<!-- language="C" -->
+ * enum {
+ *    NOT_INITIALIZED,
+ *    INITIALIZING,
+ *    INITIALIZED
+ * };
+ *
+ * static void
+ * _foo_ready_cb (Foo *self)
+ * {
+ *   GList *l;
+ *
+ *   self->priv->state = INITIALIZED;
+ *
+ *   for (l = self->priv->init_results; l != NULL; l = l->next)
+ *     {
+ *       GTask *task = l->data;
+ *
+ *       if (self->priv->success)
+ *         g_task_return_boolean (task, TRUE);
+ *       else
+ *         g_task_return_new_error (task, ...);
+ *       g_object_unref (task);
+ *     }
+ *
+ *   g_list_free (self->priv->init_results);
+ *   self->priv->init_results = NULL;
+ * }
+ *
+ * static void
+ * foo_init_async (GAsyncInitable       *initable,
+ *                 int                   io_priority,
+ *                 GCancellable         *cancellable,
+ *                 GAsyncReadyCallback   callback,
+ *                 gpointer              user_data)
+ * {
+ *   Foo *self = FOO (initable);
+ *   GTask *task;
+ *
+ *   task = g_task_new (initable, cancellable, callback, user_data);
+ *
+ *   switch (self->priv->state)
+ *     {
+ *       case NOT_INITIALIZED:
+ *         _foo_get_ready (self);
+ *         self->priv->init_results = g_list_append (self->priv->init_results,
+ *                                                   task);
+ *         self->priv->state = INITIALIZING;
+ *         break;
+ *       case INITIALIZING:
+ *         self->priv->init_results = g_list_append (self->priv->init_results,
+ *                                                   task);
+ *         break;
+ *       case INITIALIZED:
+ *         if (!self->priv->success)
+ *           g_task_return_new_error (task, ...);
+ *         else
+ *           g_task_return_boolean (task, TRUE);
+ *         g_object_unref (task);
+ *         break;
+ *     }
+ * }
+ *
+ * static gboolean
+ * foo_init_finish (GAsyncInitable       *initable,
+ *                  GAsyncResult         *result,
+ *                  GError              **error)
+ * {
+ *   g_return_val_if_fail (g_task_is_valid (result, initable), FALSE);
+ *
+ *   return g_task_propagate_boolean (G_TASK (result), error);
+ * }
+ *
+ * static void
+ * foo_async_initable_iface_init (gpointer g_iface,
+ *                                gpointer data)
+ * {
+ *   GAsyncInitableIface *iface = g_iface;
+ *
+ *   iface->init_async = foo_init_async;
+ *   iface->init_finish = foo_init_finish;
+ * }
+ * ]|
+ */
+
+static void     g_async_initable_real_init_async  (GAsyncInitable       *initable,
+						   int                   io_priority,
+						   GCancellable         *cancellable,
+						   GAsyncReadyCallback   callback,
+						   gpointer              user_data);
+static gboolean g_async_initable_real_init_finish (GAsyncInitable       *initable,
+						   GAsyncResult         *res,
+						   GError              **error);
+
+
+typedef GAsyncInitableIface GAsyncInitableInterface;
+G_DEFINE_INTERFACE (GAsyncInitable, g_async_initable, G_TYPE_OBJECT)
+
+
+static void
+g_async_initable_default_init (GAsyncInitableInterface *iface)
+{
+  iface->init_async = g_async_initable_real_init_async;
+  iface->init_finish = g_async_initable_real_init_finish;
+}
+
+/**
+ * g_async_initable_init_async:
+ * @initable: a #GAsyncInitable.
+ * @io_priority: the [I/O priority][io-priority] of the operation
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to callback function
+ *
+ * Starts asynchronous initialization of the object implementing the
+ * interface. This must be done before any real use of the object after
+ * initial construction. If the object also implements #GInitable you can
+ * optionally call g_initable_init() instead.
+ *
+ * This method is intended for language bindings. If writing in C,
+ * g_async_initable_new_async() should typically be used instead.
+ *
+ * When the initialization is finished, @callback will be called. You can
+ * then call g_async_initable_init_finish() to get the result of the
+ * initialization.
+ *
+ * Implementations may also support cancellation. If @cancellable is not
+ * %NULL, then initialization can be cancelled by triggering the cancellable
+ * object from another thread. If the operation was cancelled, the error
+ * %G_IO_ERROR_CANCELLED will be returned. If @cancellable is not %NULL, and
+ * the object doesn't support cancellable initialization, the error
+ * %G_IO_ERROR_NOT_SUPPORTED will be returned.
+ *
+ * As with #GInitable, if the object is not initialized, or initialization
+ * returns with an error, then all operations on the object except
+ * g_object_ref() and g_object_unref() are considered to be invalid, and
+ * have undefined behaviour. They will often fail with g_critical() or
+ * g_warning(), but this must not be relied on.
+ *
+ * Callers should not assume that a class which implements #GAsyncInitable can
+ * be initialized multiple times; for more information, see g_initable_init().
+ * If a class explicitly supports being initialized multiple times,
+ * implementation requires yielding all subsequent calls to init_async() on the
+ * results of the first call.
+ *
+ * For classes that also support the #GInitable interface, the default
+ * implementation of this method will run the g_initable_init() function
+ * in a thread, so if you want to support asynchronous initialization via
+ * threads, just implement the #GAsyncInitable interface without overriding
+ * any interface methods.
+ *
+ * Since: 2.22
+ */
+void
+g_async_initable_init_async (GAsyncInitable      *initable,
+			     int                  io_priority,
+			     GCancellable        *cancellable,
+			     GAsyncReadyCallback  callback,
+			     gpointer             user_data)
+{
+  GAsyncInitableIface *iface;
+
+  g_return_if_fail (G_IS_ASYNC_INITABLE (initable));
+
+  iface = G_ASYNC_INITABLE_GET_IFACE (initable);
+
+  (* iface->init_async) (initable, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * g_async_initable_init_finish:
+ * @initable: a #GAsyncInitable.
+ * @res: a #GAsyncResult.
+ * @error: a #GError location to store the error occurring, or %NULL to
+ * ignore.
+ *
+ * Finishes asynchronous initialization and returns the result.
+ * See g_async_initable_init_async().
+ *
+ * Returns: %TRUE if successful. If an error has occurred, this function
+ * will return %FALSE and set @error appropriately if present.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_async_initable_init_finish (GAsyncInitable  *initable,
+			      GAsyncResult    *res,
+			      GError         **error)
+{
+  GAsyncInitableIface *iface;
+
+  g_return_val_if_fail (G_IS_ASYNC_INITABLE (initable), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
+
+  if (g_async_result_legacy_propagate_error (res, error))
+    return FALSE;
+
+  iface = G_ASYNC_INITABLE_GET_IFACE (initable);
+
+  return (* iface->init_finish) (initable, res, error);
+}
+
+static void
+async_init_thread (GTask        *task,
+                   gpointer      source_object,
+                   gpointer      task_data,
+                   GCancellable *cancellable)
+{
+  GError *error = NULL;
+
+  if (g_initable_init (G_INITABLE (source_object), cancellable, &error))
+    g_task_return_boolean (task, TRUE);
+  else
+    g_task_return_error (task, error);
+}
+
+static void
+g_async_initable_real_init_async (GAsyncInitable      *initable,
+				  int                  io_priority,
+				  GCancellable        *cancellable,
+				  GAsyncReadyCallback  callback,
+				  gpointer             user_data)
+{
+  GTask *task;
+
+  g_return_if_fail (G_IS_INITABLE (initable));
+
+  task = g_task_new (initable, cancellable, callback, user_data);
+  g_task_set_source_tag (task, g_async_initable_real_init_async);
+  g_task_set_priority (task, io_priority);
+  g_task_run_in_thread (task, async_init_thread);
+  g_object_unref (task);
+}
+
+static gboolean
+g_async_initable_real_init_finish (GAsyncInitable  *initable,
+				   GAsyncResult    *res,
+				   GError         **error)
+{
+  /* For backward compatibility we have to process GSimpleAsyncResults
+   * even though g_async_initable_real_init_async doesn't generate
+   * them any more.
+   */
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  if (G_IS_SIMPLE_ASYNC_RESULT (res))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+      if (g_simple_async_result_propagate_error (simple, error))
+        return FALSE;
+      else
+        return TRUE;
+    }
+  G_GNUC_END_IGNORE_DEPRECATIONS
+
+  g_return_val_if_fail (g_task_is_valid (res, initable), FALSE);
+
+  return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+/**
+ * g_async_initable_new_async:
+ * @object_type: a #GType supporting #GAsyncInitable.
+ * @io_priority: the [I/O priority][io-priority] of the operation
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the initialization is
+ *     finished
+ * @user_data: the data to pass to callback function
+ * @first_property_name: (nullable): the name of the first property, or %NULL if no
+ *     properties
+ * @...:  the value of the first property, followed by other property
+ *    value pairs, and ended by %NULL.
+ *
+ * Helper function for constructing #GAsyncInitable object. This is
+ * similar to g_object_new() but also initializes the object asynchronously.
+ *
+ * When the initialization is finished, @callback will be called. You can
+ * then call g_async_initable_new_finish() to get the new object and check
+ * for any errors.
+ *
+ * Since: 2.22
+ */
+void
+g_async_initable_new_async (GType                object_type,
+			    int                  io_priority,
+			    GCancellable        *cancellable,
+			    GAsyncReadyCallback  callback,
+			    gpointer             user_data,
+			    const gchar         *first_property_name,
+			    ...)
+{
+  va_list var_args;
+
+  va_start (var_args, first_property_name);
+  g_async_initable_new_valist_async (object_type,
+				     first_property_name, var_args,
+				     io_priority, cancellable,
+				     callback, user_data);
+  va_end (var_args);
+}
+
+/**
+ * g_async_initable_newv_async:
+ * @object_type: a #GType supporting #GAsyncInitable.
+ * @n_parameters: the number of parameters in @parameters
+ * @parameters: the parameters to use to construct the object
+ * @io_priority: the [I/O priority][io-priority] of the operation
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the initialization is
+ *     finished
+ * @user_data: the data to pass to callback function
+ *
+ * Helper function for constructing #GAsyncInitable object. This is
+ * similar to g_object_newv() but also initializes the object asynchronously.
+ *
+ * When the initialization is finished, @callback will be called. You can
+ * then call g_async_initable_new_finish() to get the new object and check
+ * for any errors.
+ *
+ * Since: 2.22
+ * Deprecated: 2.54: Use g_object_new_with_properties() and
+ * g_async_initable_init_async() instead. See #GParameter for more information.
+ */
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+void
+g_async_initable_newv_async (GType                object_type,
+			     guint                n_parameters,
+			     GParameter          *parameters,
+			     int                  io_priority,
+			     GCancellable        *cancellable,
+			     GAsyncReadyCallback  callback,
+			     gpointer             user_data)
+{
+  GObject *obj;
+
+  g_return_if_fail (G_TYPE_IS_ASYNC_INITABLE (object_type));
+
+  obj = g_object_newv (object_type, n_parameters, parameters);
+
+  g_async_initable_init_async (G_ASYNC_INITABLE (obj),
+			       io_priority, cancellable,
+			       callback, user_data);
+  g_object_unref (obj); /* Passed ownership to async call */
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+/**
+ * g_async_initable_new_valist_async:
+ * @object_type: a #GType supporting #GAsyncInitable.
+ * @first_property_name: the name of the first property, followed by
+ * the value, and other property value pairs, and ended by %NULL.
+ * @var_args: The var args list generated from @first_property_name.
+ * @io_priority: the [I/O priority][io-priority] of the operation
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the initialization is
+ *     finished
+ * @user_data: the data to pass to callback function
+ *
+ * Helper function for constructing #GAsyncInitable object. This is
+ * similar to g_object_new_valist() but also initializes the object
+ * asynchronously.
+ *
+ * When the initialization is finished, @callback will be called. You can
+ * then call g_async_initable_new_finish() to get the new object and check
+ * for any errors.
+ *
+ * Since: 2.22
+ */
+void
+g_async_initable_new_valist_async (GType                object_type,
+				   const gchar         *first_property_name,
+				   va_list              var_args,
+				   int                  io_priority,
+				   GCancellable        *cancellable,
+				   GAsyncReadyCallback  callback,
+				   gpointer             user_data)
+{
+  GObject *obj;
+
+  g_return_if_fail (G_TYPE_IS_ASYNC_INITABLE (object_type));
+
+  obj = g_object_new_valist (object_type,
+			     first_property_name,
+			     var_args);
+
+  g_async_initable_init_async (G_ASYNC_INITABLE (obj),
+			       io_priority, cancellable,
+			       callback, user_data);
+  g_object_unref (obj); /* Passed ownership to async call */
+}
+
+/**
+ * g_async_initable_new_finish:
+ * @initable: the #GAsyncInitable from the callback
+ * @res: the #GAsyncResult from the callback
+ * @error: return location for errors, or %NULL to ignore
+ *
+ * Finishes the async construction for the various g_async_initable_new
+ * calls, returning the created object or %NULL on error.
+ *
+ * Returns: (type GObject.Object) (transfer full): a newly created #GObject,
+ *      or %NULL on error. Free with g_object_unref().
+ *
+ * Since: 2.22
+ */
+GObject *
+g_async_initable_new_finish (GAsyncInitable  *initable,
+			     GAsyncResult    *res,
+			     GError         **error)
+{
+  if (g_async_initable_init_finish (initable, res, error))
+    return g_object_ref (G_OBJECT (initable));
+  else
+    return NULL;
+}
diff --git a/gio/gasyncinitable.h b/gio/gasyncinitable.h
new file mode 100644
index 0000000..f30d2ce
--- /dev/null
+++ b/gio/gasyncinitable.h
@@ -0,0 +1,130 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_ASYNC_INITABLE_H__
+#define __G_ASYNC_INITABLE_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+#include <gio/ginitable.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_ASYNC_INITABLE            (g_async_initable_get_type ())
+#define G_ASYNC_INITABLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ASYNC_INITABLE, GAsyncInitable))
+#define G_IS_ASYNC_INITABLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ASYNC_INITABLE))
+#define G_ASYNC_INITABLE_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ASYNC_INITABLE, GAsyncInitableIface))
+#define G_TYPE_IS_ASYNC_INITABLE(type)   (g_type_is_a ((type), G_TYPE_ASYNC_INITABLE))
+
+/**
+ * GAsyncInitable:
+ *
+ * Interface for asynchronously initializable objects.
+ *
+ * Since: 2.22
+ **/
+typedef struct _GAsyncInitableIface GAsyncInitableIface;
+
+/**
+ * GAsyncInitableIface:
+ * @g_iface: The parent interface.
+ * @init_async: Starts initialization of the object.
+ * @init_finish: Finishes initialization of the object.
+ *
+ * Provides an interface for asynchronous initializing object such that
+ * initialization may fail.
+ *
+ * Since: 2.22
+ **/
+struct _GAsyncInitableIface
+{
+  GTypeInterface g_iface;
+
+  /* Virtual Table */
+
+  void     (* init_async)  (GAsyncInitable      *initable,
+			    int                  io_priority,
+			    GCancellable        *cancellable,
+			    GAsyncReadyCallback  callback,
+			    gpointer             user_data);
+  gboolean (* init_finish) (GAsyncInitable      *initable,
+			    GAsyncResult        *res,
+			    GError             **error);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType    g_async_initable_get_type    (void) G_GNUC_CONST;
+
+
+GLIB_AVAILABLE_IN_ALL
+void     g_async_initable_init_async       (GAsyncInitable       *initable,
+					    int                   io_priority,
+					    GCancellable         *cancellable,
+					    GAsyncReadyCallback   callback,
+					    gpointer              user_data);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_async_initable_init_finish      (GAsyncInitable       *initable,
+					    GAsyncResult         *res,
+					    GError              **error);
+
+GLIB_AVAILABLE_IN_ALL
+void     g_async_initable_new_async        (GType                 object_type,
+					    int                   io_priority,
+					    GCancellable         *cancellable,
+					    GAsyncReadyCallback   callback,
+					    gpointer              user_data,
+					    const gchar          *first_property_name,
+					    ...);
+
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
+GLIB_DEPRECATED_IN_2_54_FOR(g_object_new_with_properties and g_async_initable_init_async)
+void     g_async_initable_newv_async       (GType                 object_type,
+					    guint                 n_parameters,
+					    GParameter           *parameters,
+					    int                   io_priority,
+					    GCancellable         *cancellable,
+					    GAsyncReadyCallback   callback,
+					    gpointer              user_data);
+
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+GLIB_AVAILABLE_IN_ALL
+void     g_async_initable_new_valist_async (GType                 object_type,
+					    const gchar          *first_property_name,
+					    va_list               var_args,
+					    int                   io_priority,
+					    GCancellable         *cancellable,
+					    GAsyncReadyCallback   callback,
+					    gpointer              user_data);
+GLIB_AVAILABLE_IN_ALL
+GObject *g_async_initable_new_finish       (GAsyncInitable       *initable,
+					    GAsyncResult         *res,
+					    GError              **error);
+
+
+
+G_END_DECLS
+
+
+#endif /* __G_ASYNC_INITABLE_H__ */
diff --git a/gio/gasyncresult.c b/gio/gasyncresult.c
new file mode 100644
index 0000000..b96f1ee
--- /dev/null
+++ b/gio/gasyncresult.c
@@ -0,0 +1,237 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include "gasyncresult.h"
+#include "gsimpleasyncresult.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gasyncresult
+ * @short_description: Asynchronous Function Results
+ * @include: gio/gio.h
+ * @see_also: #GTask
+ *
+ * Provides a base class for implementing asynchronous function results.
+ *
+ * Asynchronous operations are broken up into two separate operations
+ * which are chained together by a #GAsyncReadyCallback. To begin
+ * an asynchronous operation, provide a #GAsyncReadyCallback to the
+ * asynchronous function. This callback will be triggered when the
+ * operation has completed, and must be run in a later iteration of
+ * the [thread-default main context][g-main-context-push-thread-default]
+ * from where the operation was initiated. It will be passed a
+ * #GAsyncResult instance filled with the details of the operation's
+ * success or failure, the object the asynchronous function was
+ * started for and any error codes returned. The asynchronous callback
+ * function is then expected to call the corresponding "_finish()"
+ * function, passing the object the function was called for, the
+ * #GAsyncResult instance, and (optionally) an @error to grab any
+ * error conditions that may have occurred.
+ *
+ * The "_finish()" function for an operation takes the generic result
+ * (of type #GAsyncResult) and returns the specific result that the
+ * operation in question yields (e.g. a #GFileEnumerator for a
+ * "enumerate children" operation). If the result or error status of the
+ * operation is not needed, there is no need to call the "_finish()"
+ * function; GIO will take care of cleaning up the result and error
+ * information after the #GAsyncReadyCallback returns. You can pass
+ * %NULL for the #GAsyncReadyCallback if you don't need to take any
+ * action at all after the operation completes. Applications may also
+ * take a reference to the #GAsyncResult and call "_finish()" later;
+ * however, the "_finish()" function may be called at most once.
+ *
+ * Example of a typical asynchronous operation flow:
+ * |[<!-- language="C" -->
+ * void _theoretical_frobnitz_async (Theoretical         *t,
+ *                                   GCancellable        *c,
+ *                                   GAsyncReadyCallback  cb,
+ *                                   gpointer             u);
+ *
+ * gboolean _theoretical_frobnitz_finish (Theoretical   *t,
+ *                                        GAsyncResult  *res,
+ *                                        GError       **e);
+ *
+ * static void
+ * frobnitz_result_func (GObject      *source_object,
+ *			 GAsyncResult *res,
+ *			 gpointer      user_data)
+ * {
+ *   gboolean success = FALSE;
+ *
+ *   success = _theoretical_frobnitz_finish (source_object, res, NULL);
+ *
+ *   if (success)
+ *     g_printf ("Hurray!\n");
+ *   else
+ *     g_printf ("Uh oh!\n");
+ *
+ *   ...
+ *
+ * }
+ *
+ * int main (int argc, void *argv[])
+ * {
+ *    ...
+ *
+ *    _theoretical_frobnitz_async (theoretical_data,
+ *                                 NULL,
+ *                                 frobnitz_result_func,
+ *                                 NULL);
+ *
+ *    ...
+ * }
+ * ]|
+ *
+ * The callback for an asynchronous operation is called only once, and is
+ * always called, even in the case of a cancelled operation. On cancellation
+ * the result is a %G_IO_ERROR_CANCELLED error.
+ *
+ * ## I/O Priority # {#io-priority}
+ *
+ * Many I/O-related asynchronous operations have a priority parameter,
+ * which is used in certain cases to determine the order in which
+ * operations are executed. They are not used to determine system-wide
+ * I/O scheduling. Priorities are integers, with lower numbers indicating
+ * higher priority. It is recommended to choose priorities between
+ * %G_PRIORITY_LOW and %G_PRIORITY_HIGH, with %G_PRIORITY_DEFAULT
+ * as a default.
+ */
+
+typedef GAsyncResultIface GAsyncResultInterface;
+G_DEFINE_INTERFACE (GAsyncResult, g_async_result, G_TYPE_OBJECT)
+
+static void
+g_async_result_default_init (GAsyncResultInterface *iface)
+{
+}
+
+/**
+ * g_async_result_get_user_data:
+ * @res: a #GAsyncResult.
+ *
+ * Gets the user data from a #GAsyncResult.
+ *
+ * Returns: (transfer full): the user data for @res.
+ **/
+gpointer
+g_async_result_get_user_data (GAsyncResult *res)
+{
+  GAsyncResultIface *iface;
+
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
+
+  iface = G_ASYNC_RESULT_GET_IFACE (res);
+
+  return (* iface->get_user_data) (res);
+}
+
+/**
+ * g_async_result_get_source_object:
+ * @res: a #GAsyncResult
+ *
+ * Gets the source object from a #GAsyncResult.
+ *
+ * Returns: (transfer full) (nullable): a new reference to the source
+ *    object for the @res, or %NULL if there is none.
+ */
+GObject *
+g_async_result_get_source_object (GAsyncResult *res)
+{
+  GAsyncResultIface *iface;
+
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
+
+  iface = G_ASYNC_RESULT_GET_IFACE (res);
+
+  return (* iface->get_source_object) (res);
+}
+
+/**
+ * g_async_result_legacy_propagate_error:
+ * @res: a #GAsyncResult
+ * @error: (out): a location to propagate the error to.
+ *
+ * If @res is a #GSimpleAsyncResult, this is equivalent to
+ * g_simple_async_result_propagate_error(). Otherwise it returns
+ * %FALSE.
+ *
+ * This can be used for legacy error handling in async *_finish()
+ * wrapper functions that traditionally handled #GSimpleAsyncResult
+ * error returns themselves rather than calling into the virtual method.
+ * This should not be used in new code; #GAsyncResult errors that are
+ * set by virtual methods should also be extracted by virtual methods,
+ * to enable subclasses to chain up correctly.
+ *
+ * Returns: %TRUE if @error is has been filled in with an error from
+ *   @res, %FALSE if not.
+ *
+ * Since: 2.34
+ **/
+gboolean
+g_async_result_legacy_propagate_error (GAsyncResult  *res,
+				       GError       **error)
+{
+  /* This doesn't use a vmethod, because it's only for code that used
+   * to use GSimpleAsyncResult. (But it's a GAsyncResult method so
+   * that callers don't need to worry about GSimpleAsyncResult
+   * deprecation warnings in the future.)
+   */
+
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  if (G_IS_SIMPLE_ASYNC_RESULT (res))
+    {
+      return g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res),
+						    error);
+    }
+  else
+    return FALSE;
+  G_GNUC_END_IGNORE_DEPRECATIONS
+}
+
+/**
+ * g_async_result_is_tagged:
+ * @res: a #GAsyncResult
+ * @source_tag: an application-defined tag
+ *
+ * Checks if @res has the given @source_tag (generally a function
+ * pointer indicating the function @res was created by).
+ *
+ * Returns: %TRUE if @res has the indicated @source_tag, %FALSE if
+ *   not.
+ *
+ * Since: 2.34
+ **/
+gboolean
+g_async_result_is_tagged (GAsyncResult  *res,
+			  gpointer       source_tag)
+{
+  GAsyncResultIface *iface;
+
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
+
+  iface = G_ASYNC_RESULT_GET_IFACE (res);
+
+  if (!iface->is_tagged)
+    return FALSE;
+
+  return (* iface->is_tagged) (res, source_tag);
+}
diff --git a/gio/gasyncresult.h b/gio/gasyncresult.h
new file mode 100644
index 0000000..956cbc4
--- /dev/null
+++ b/gio/gasyncresult.h
@@ -0,0 +1,85 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_ASYNC_RESULT_H__
+#define __G_ASYNC_RESULT_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_ASYNC_RESULT            (g_async_result_get_type ())
+#define G_ASYNC_RESULT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ASYNC_RESULT, GAsyncResult))
+#define G_IS_ASYNC_RESULT(obj)	       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ASYNC_RESULT))
+#define G_ASYNC_RESULT_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ASYNC_RESULT, GAsyncResultIface))
+
+/**
+ * GAsyncResult:
+ *
+ * Holds results information for an asynchronous operation,
+ * usually passed directly to an asynchronous _finish() operation.
+ **/
+typedef struct _GAsyncResultIface    GAsyncResultIface;
+
+
+/**
+ * GAsyncResultIface:
+ * @g_iface: The parent interface.
+ * @get_user_data: Gets the user data passed to the callback.
+ * @get_source_object: Gets the source object that issued the asynchronous operation.
+ * @is_tagged: Checks if a result is tagged with a particular source.
+ *
+ * Interface definition for #GAsyncResult.
+ **/
+struct _GAsyncResultIface
+{
+  GTypeInterface g_iface;
+
+  /* Virtual Table */
+
+  gpointer  (* get_user_data)     (GAsyncResult *res);
+  GObject * (* get_source_object) (GAsyncResult *res);
+
+  gboolean  (* is_tagged)         (GAsyncResult *res,
+				   gpointer      source_tag);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType    g_async_result_get_type          (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+gpointer g_async_result_get_user_data     (GAsyncResult *res);
+GLIB_AVAILABLE_IN_ALL
+GObject *g_async_result_get_source_object (GAsyncResult *res);
+
+GLIB_AVAILABLE_IN_2_34
+gboolean g_async_result_legacy_propagate_error (GAsyncResult  *res,
+						GError       **error);
+GLIB_AVAILABLE_IN_2_34
+gboolean g_async_result_is_tagged              (GAsyncResult  *res,
+						gpointer       source_tag);
+
+G_END_DECLS
+
+#endif /* __G_ASYNC_RESULT_H__ */
diff --git a/gio/gbufferedinputstream.c b/gio/gbufferedinputstream.c
new file mode 100644
index 0000000..f5090d0
--- /dev/null
+++ b/gio/gbufferedinputstream.c
@@ -0,0 +1,1270 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2007 Jürg Billeter
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Christian Kellner <gicmo@gnome.org>
+ */
+
+#include "config.h"
+#include "gbufferedinputstream.h"
+#include "ginputstream.h"
+#include "gcancellable.h"
+#include "gasyncresult.h"
+#include "gtask.h"
+#include "gseekable.h"
+#include "gioerror.h"
+#include <string.h>
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gbufferedinputstream
+ * @short_description: Buffered Input Stream
+ * @include: gio/gio.h
+ * @see_also: #GFilterInputStream, #GInputStream
+ *
+ * Buffered input stream implements #GFilterInputStream and provides
+ * for buffered reads.
+ *
+ * By default, #GBufferedInputStream's buffer size is set at 4 kilobytes.
+ *
+ * To create a buffered input stream, use g_buffered_input_stream_new(),
+ * or g_buffered_input_stream_new_sized() to specify the buffer's size at
+ * construction.
+ *
+ * To get the size of a buffer within a buffered input stream, use
+ * g_buffered_input_stream_get_buffer_size(). To change the size of a
+ * buffered input stream's buffer, use
+ * g_buffered_input_stream_set_buffer_size(). Note that the buffer's size
+ * cannot be reduced below the size of the data within the buffer.
+ */
+
+
+#define DEFAULT_BUFFER_SIZE 4096
+
+struct _GBufferedInputStreamPrivate {
+  guint8 *buffer;
+  gsize   len;
+  gsize   pos;
+  gsize   end;
+  GAsyncReadyCallback outstanding_callback;
+};
+
+enum {
+  PROP_0,
+  PROP_BUFSIZE
+};
+
+static void g_buffered_input_stream_set_property  (GObject      *object,
+                                                   guint         prop_id,
+                                                   const GValue *value,
+                                                   GParamSpec   *pspec);
+
+static void g_buffered_input_stream_get_property  (GObject      *object,
+                                                   guint         prop_id,
+                                                   GValue       *value,
+                                                   GParamSpec   *pspec);
+static void g_buffered_input_stream_finalize      (GObject *object);
+
+
+static gssize g_buffered_input_stream_skip             (GInputStream          *stream,
+                                                        gsize                  count,
+                                                        GCancellable          *cancellable,
+                                                        GError               **error);
+static void   g_buffered_input_stream_skip_async       (GInputStream          *stream,
+                                                        gsize                  count,
+                                                        int                    io_priority,
+                                                        GCancellable          *cancellable,
+                                                        GAsyncReadyCallback    callback,
+                                                        gpointer               user_data);
+static gssize g_buffered_input_stream_skip_finish      (GInputStream          *stream,
+                                                        GAsyncResult          *result,
+                                                        GError               **error);
+static gssize g_buffered_input_stream_read             (GInputStream          *stream,
+                                                        void                  *buffer,
+                                                        gsize                  count,
+                                                        GCancellable          *cancellable,
+                                                        GError               **error);
+static gssize g_buffered_input_stream_real_fill        (GBufferedInputStream  *stream,
+                                                        gssize                 count,
+                                                        GCancellable          *cancellable,
+                                                        GError               **error);
+static void   g_buffered_input_stream_real_fill_async  (GBufferedInputStream  *stream,
+                                                        gssize                 count,
+                                                        int                    io_priority,
+                                                        GCancellable          *cancellable,
+                                                        GAsyncReadyCallback    callback,
+                                                        gpointer               user_data);
+static gssize g_buffered_input_stream_real_fill_finish (GBufferedInputStream  *stream,
+                                                        GAsyncResult          *result,
+                                                        GError               **error);
+
+static void     g_buffered_input_stream_seekable_iface_init (GSeekableIface  *iface);
+static goffset  g_buffered_input_stream_tell                (GSeekable       *seekable);
+static gboolean g_buffered_input_stream_can_seek            (GSeekable       *seekable);
+static gboolean g_buffered_input_stream_seek                (GSeekable       *seekable,
+							     goffset          offset,
+							     GSeekType        type,
+							     GCancellable    *cancellable,
+							     GError         **error);
+static gboolean g_buffered_input_stream_can_truncate        (GSeekable       *seekable);
+static gboolean g_buffered_input_stream_truncate            (GSeekable       *seekable,
+							     goffset          offset,
+							     GCancellable    *cancellable,
+							     GError         **error);
+
+static void compact_buffer (GBufferedInputStream *stream);
+
+G_DEFINE_TYPE_WITH_CODE (GBufferedInputStream,
+			 g_buffered_input_stream,
+			 G_TYPE_FILTER_INPUT_STREAM,
+                         G_ADD_PRIVATE (GBufferedInputStream)
+			 G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
+						g_buffered_input_stream_seekable_iface_init))
+
+static void
+g_buffered_input_stream_class_init (GBufferedInputStreamClass *klass)
+{
+  GObjectClass *object_class;
+  GInputStreamClass *istream_class;
+  GBufferedInputStreamClass *bstream_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = g_buffered_input_stream_get_property;
+  object_class->set_property = g_buffered_input_stream_set_property;
+  object_class->finalize     = g_buffered_input_stream_finalize;
+
+  istream_class = G_INPUT_STREAM_CLASS (klass);
+  istream_class->skip = g_buffered_input_stream_skip;
+  istream_class->skip_async  = g_buffered_input_stream_skip_async;
+  istream_class->skip_finish = g_buffered_input_stream_skip_finish;
+  istream_class->read_fn = g_buffered_input_stream_read;
+
+  bstream_class = G_BUFFERED_INPUT_STREAM_CLASS (klass);
+  bstream_class->fill = g_buffered_input_stream_real_fill;
+  bstream_class->fill_async = g_buffered_input_stream_real_fill_async;
+  bstream_class->fill_finish = g_buffered_input_stream_real_fill_finish;
+
+  g_object_class_install_property (object_class,
+                                   PROP_BUFSIZE,
+                                   g_param_spec_uint ("buffer-size",
+                                                      P_("Buffer Size"),
+                                                      P_("The size of the backend buffer"),
+                                                      1,
+                                                      G_MAXUINT,
+                                                      DEFAULT_BUFFER_SIZE,
+                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+                                                      G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+
+}
+
+/**
+ * g_buffered_input_stream_get_buffer_size:
+ * @stream: a #GBufferedInputStream
+ *
+ * Gets the size of the input buffer.
+ *
+ * Returns: the current buffer size.
+ */
+gsize
+g_buffered_input_stream_get_buffer_size (GBufferedInputStream  *stream)
+{
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), 0);
+
+  return stream->priv->len;
+}
+
+/**
+ * g_buffered_input_stream_set_buffer_size:
+ * @stream: a #GBufferedInputStream
+ * @size: a #gsize
+ *
+ * Sets the size of the internal buffer of @stream to @size, or to the
+ * size of the contents of the buffer. The buffer can never be resized
+ * smaller than its current contents.
+ */
+void
+g_buffered_input_stream_set_buffer_size (GBufferedInputStream *stream,
+                                         gsize                 size)
+{
+  GBufferedInputStreamPrivate *priv;
+  gsize in_buffer;
+  guint8 *buffer;
+
+  g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
+
+  priv = stream->priv;
+
+  if (priv->len == size)
+    return;
+
+  if (priv->buffer)
+    {
+      in_buffer = priv->end - priv->pos;
+
+      /* Never resize smaller than current buffer contents */
+      size = MAX (size, in_buffer);
+
+      buffer = g_malloc (size);
+      memcpy (buffer, priv->buffer + priv->pos, in_buffer);
+      priv->len = size;
+      priv->pos = 0;
+      priv->end = in_buffer;
+      g_free (priv->buffer);
+      priv->buffer = buffer;
+    }
+  else
+    {
+      priv->len = size;
+      priv->pos = 0;
+      priv->end = 0;
+      priv->buffer = g_malloc (size);
+    }
+
+  g_object_notify (G_OBJECT (stream), "buffer-size");
+}
+
+static void
+g_buffered_input_stream_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  GBufferedInputStream        *bstream;
+
+  bstream = G_BUFFERED_INPUT_STREAM (object);
+
+  switch (prop_id)
+    {
+    case PROP_BUFSIZE:
+      g_buffered_input_stream_set_buffer_size (bstream, g_value_get_uint (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_buffered_input_stream_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  GBufferedInputStreamPrivate *priv;
+  GBufferedInputStream        *bstream;
+
+  bstream = G_BUFFERED_INPUT_STREAM (object);
+  priv = bstream->priv;
+
+  switch (prop_id)
+    {
+    case PROP_BUFSIZE:
+      g_value_set_uint (value, priv->len);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_buffered_input_stream_finalize (GObject *object)
+{
+  GBufferedInputStreamPrivate *priv;
+  GBufferedInputStream        *stream;
+
+  stream = G_BUFFERED_INPUT_STREAM (object);
+  priv = stream->priv;
+
+  g_free (priv->buffer);
+
+  G_OBJECT_CLASS (g_buffered_input_stream_parent_class)->finalize (object);
+}
+
+static void
+g_buffered_input_stream_seekable_iface_init (GSeekableIface *iface)
+{
+  iface->tell         = g_buffered_input_stream_tell;
+  iface->can_seek     = g_buffered_input_stream_can_seek;
+  iface->seek         = g_buffered_input_stream_seek;
+  iface->can_truncate = g_buffered_input_stream_can_truncate;
+  iface->truncate_fn  = g_buffered_input_stream_truncate;
+}
+
+static void
+g_buffered_input_stream_init (GBufferedInputStream *stream)
+{
+  stream->priv = g_buffered_input_stream_get_instance_private (stream);
+}
+
+
+/**
+ * g_buffered_input_stream_new:
+ * @base_stream: a #GInputStream
+ *
+ * Creates a new #GInputStream from the given @base_stream, with
+ * a buffer set to the default size (4 kilobytes).
+ *
+ * Returns: a #GInputStream for the given @base_stream.
+ */
+GInputStream *
+g_buffered_input_stream_new (GInputStream *base_stream)
+{
+  GInputStream *stream;
+
+  g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_BUFFERED_INPUT_STREAM,
+                         "base-stream", base_stream,
+                         NULL);
+
+  return stream;
+}
+
+/**
+ * g_buffered_input_stream_new_sized:
+ * @base_stream: a #GInputStream
+ * @size: a #gsize
+ *
+ * Creates a new #GBufferedInputStream from the given @base_stream,
+ * with a buffer set to @size.
+ *
+ * Returns: a #GInputStream.
+ */
+GInputStream *
+g_buffered_input_stream_new_sized (GInputStream *base_stream,
+                                   gsize         size)
+{
+  GInputStream *stream;
+
+  g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_BUFFERED_INPUT_STREAM,
+                         "base-stream", base_stream,
+                         "buffer-size", (guint)size,
+                         NULL);
+
+  return stream;
+}
+
+/**
+ * g_buffered_input_stream_fill:
+ * @stream: a #GBufferedInputStream
+ * @count: the number of bytes that will be read from the stream
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
+ * @error: location to store the error occurring, or %NULL to ignore
+ *
+ * Tries to read @count bytes from the stream into the buffer.
+ * Will block during this read.
+ *
+ * If @count is zero, returns zero and does nothing. A value of @count
+ * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
+ *
+ * On success, the number of bytes read into the buffer is returned.
+ * It is not an error if this is not the same as the requested size, as it
+ * can happen e.g. near the end of a file. Zero is returned on end of file
+ * (or if @count is zero),  but never otherwise.
+ *
+ * If @count is -1 then the attempted read size is equal to the number of
+ * bytes that are required to fill the buffer.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
+ * operation was partially finished when the operation was cancelled the
+ * partial result will be returned, without an error.
+ *
+ * On error -1 is returned and @error is set accordingly.
+ *
+ * For the asynchronous, non-blocking, version of this function, see
+ * g_buffered_input_stream_fill_async().
+ *
+ * Returns: the number of bytes read into @stream's buffer, up to @count,
+ *     or -1 on error.
+ */
+gssize
+g_buffered_input_stream_fill (GBufferedInputStream  *stream,
+                              gssize                 count,
+                              GCancellable          *cancellable,
+                              GError               **error)
+{
+  GBufferedInputStreamClass *class;
+  GInputStream *input_stream;
+  gssize res;
+
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
+
+  input_stream = G_INPUT_STREAM (stream);
+
+  if (count < -1)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                   _("Too large count value passed to %s"), G_STRFUNC);
+      return -1;
+    }
+
+  if (!g_input_stream_set_pending (input_stream, error))
+    return -1;
+
+  if (cancellable)
+    g_cancellable_push_current (cancellable);
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  res = class->fill (stream, count, cancellable, error);
+
+  if (cancellable)
+    g_cancellable_pop_current (cancellable);
+
+  g_input_stream_clear_pending (input_stream);
+
+  return res;
+}
+
+static void
+async_fill_callback_wrapper (GObject      *source_object,
+                             GAsyncResult *res,
+                             gpointer      user_data)
+{
+  GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (source_object);
+
+  g_input_stream_clear_pending (G_INPUT_STREAM (stream));
+  (*stream->priv->outstanding_callback) (source_object, res, user_data);
+  g_object_unref (stream);
+}
+
+/**
+ * g_buffered_input_stream_fill_async:
+ * @stream: a #GBufferedInputStream
+ * @count: the number of bytes that will be read from the stream
+ * @io_priority: the [I/O priority][io-priority] of the request
+ * @cancellable: (nullable): optional #GCancellable object
+ * @callback: (scope async): a #GAsyncReadyCallback
+ * @user_data: (closure): a #gpointer
+ *
+ * Reads data into @stream's buffer asynchronously, up to @count size.
+ * @io_priority can be used to prioritize reads. For the synchronous
+ * version of this function, see g_buffered_input_stream_fill().
+ *
+ * If @count is -1 then the attempted read size is equal to the number
+ * of bytes that are required to fill the buffer.
+ */
+void
+g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
+                                    gssize                count,
+                                    int                   io_priority,
+                                    GCancellable         *cancellable,
+                                    GAsyncReadyCallback   callback,
+                                    gpointer              user_data)
+{
+  GBufferedInputStreamClass *class;
+  GError *error = NULL;
+
+  g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
+
+  if (count == 0)
+    {
+      GTask *task;
+
+      task = g_task_new (stream, cancellable, callback, user_data);
+      g_task_set_source_tag (task, g_buffered_input_stream_fill_async);
+      g_task_return_int (task, 0);
+      g_object_unref (task);
+      return;
+    }
+
+  if (count < -1)
+    {
+      g_task_report_new_error (stream, callback, user_data,
+                               g_buffered_input_stream_fill_async,
+                               G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+			       _("Too large count value passed to %s"),
+			       G_STRFUNC);
+      return;
+    }
+
+  if (!g_input_stream_set_pending (G_INPUT_STREAM (stream), &error))
+    {
+      g_task_report_error (stream, callback, user_data,
+                           g_buffered_input_stream_fill_async,
+                           error);
+      return;
+    }
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+
+  stream->priv->outstanding_callback = callback;
+  g_object_ref (stream);
+  class->fill_async (stream, count, io_priority, cancellable,
+                     async_fill_callback_wrapper, user_data);
+}
+
+/**
+ * g_buffered_input_stream_fill_finish:
+ * @stream: a #GBufferedInputStream
+ * @result: a #GAsyncResult
+ * @error: a #GError
+ *
+ * Finishes an asynchronous read.
+ *
+ * Returns: a #gssize of the read stream, or `-1` on an error.
+ */
+gssize
+g_buffered_input_stream_fill_finish (GBufferedInputStream  *stream,
+                                     GAsyncResult          *result,
+                                     GError               **error)
+{
+  GBufferedInputStreamClass *class;
+
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
+
+  if (g_async_result_legacy_propagate_error (result, error))
+    return -1;
+  else if (g_async_result_is_tagged (result, g_buffered_input_stream_fill_async))
+    return g_task_propagate_int (G_TASK (result), error);
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  return class->fill_finish (stream, result, error);
+}
+
+/**
+ * g_buffered_input_stream_get_available:
+ * @stream: #GBufferedInputStream
+ *
+ * Gets the size of the available data within the stream.
+ *
+ * Returns: size of the available stream.
+ */
+gsize
+g_buffered_input_stream_get_available (GBufferedInputStream *stream)
+{
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
+
+  return stream->priv->end - stream->priv->pos;
+}
+
+/**
+ * g_buffered_input_stream_peek:
+ * @stream: a #GBufferedInputStream
+ * @buffer: (array length=count) (element-type guint8): a pointer to
+ *   an allocated chunk of memory
+ * @offset: a #gsize
+ * @count: a #gsize
+ *
+ * Peeks in the buffer, copying data of size @count into @buffer,
+ * offset @offset bytes.
+ *
+ * Returns: a #gsize of the number of bytes peeked, or -1 on error.
+ */
+gsize
+g_buffered_input_stream_peek (GBufferedInputStream *stream,
+                              void                 *buffer,
+                              gsize                 offset,
+                              gsize                 count)
+{
+  gsize available;
+  gsize end;
+
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
+  g_return_val_if_fail (buffer != NULL, -1);
+
+  available = g_buffered_input_stream_get_available (stream);
+
+  if (offset > available)
+    return 0;
+
+  end = MIN (offset + count, available);
+  count = end - offset;
+
+  memcpy (buffer, stream->priv->buffer + stream->priv->pos + offset, count);
+  return count;
+}
+
+/**
+ * g_buffered_input_stream_peek_buffer:
+ * @stream: a #GBufferedInputStream
+ * @count: (out): a #gsize to get the number of bytes available in the buffer
+ *
+ * Returns the buffer with the currently available bytes. The returned
+ * buffer must not be modified and will become invalid when reading from
+ * the stream or filling the buffer.
+ *
+ * Returns: (array length=count) (element-type guint8) (transfer none):
+ *          read-only buffer
+ */
+const void*
+g_buffered_input_stream_peek_buffer (GBufferedInputStream *stream,
+                                     gsize                *count)
+{
+  GBufferedInputStreamPrivate *priv;
+
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), NULL);
+
+  priv = stream->priv;
+
+  if (count)
+    *count = priv->end - priv->pos;
+
+  return priv->buffer + priv->pos;
+}
+
+static void
+compact_buffer (GBufferedInputStream *stream)
+{
+  GBufferedInputStreamPrivate *priv;
+  gsize current_size;
+
+  priv = stream->priv;
+
+  current_size = priv->end - priv->pos;
+
+  memmove (priv->buffer, priv->buffer + priv->pos, current_size);
+
+  priv->pos = 0;
+  priv->end = current_size;
+}
+
+static gssize
+g_buffered_input_stream_real_fill (GBufferedInputStream  *stream,
+                                   gssize                 count,
+                                   GCancellable          *cancellable,
+                                   GError               **error)
+{
+  GBufferedInputStreamPrivate *priv;
+  GInputStream *base_stream;
+  gssize nread;
+  gsize in_buffer;
+
+  priv = stream->priv;
+
+  if (count == -1)
+    count = priv->len;
+
+  in_buffer = priv->end - priv->pos;
+
+  /* Never fill more than can fit in the buffer */
+  count = MIN (count, priv->len - in_buffer);
+
+  /* If requested length does not fit at end, compact */
+  if (priv->len - priv->end < count)
+    compact_buffer (stream);
+
+  base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+  nread = g_input_stream_read (base_stream,
+                               priv->buffer + priv->end,
+                               count,
+                               cancellable,
+                               error);
+
+  if (nread > 0)
+    priv->end += nread;
+
+  return nread;
+}
+
+static gssize
+g_buffered_input_stream_skip (GInputStream  *stream,
+                              gsize          count,
+                              GCancellable  *cancellable,
+                              GError       **error)
+{
+  GBufferedInputStream        *bstream;
+  GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
+  GInputStream *base_stream;
+  gsize available, bytes_skipped;
+  gssize nread;
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+  priv = bstream->priv;
+
+  available = priv->end - priv->pos;
+
+  if (count <= available)
+    {
+      priv->pos += count;
+      return count;
+    }
+
+  /* Full request not available, skip all currently available and
+   * request refill for more
+   */
+
+  priv->pos = 0;
+  priv->end = 0;
+  bytes_skipped = available;
+  count -= available;
+
+  if (bytes_skipped > 0)
+    error = NULL; /* Ignore further errors if we already read some data */
+
+  if (count > priv->len)
+    {
+      /* Large request, shortcut buffer */
+
+      base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+
+      nread = g_input_stream_skip (base_stream,
+                                   count,
+                                   cancellable,
+                                   error);
+
+      if (nread < 0 && bytes_skipped == 0)
+        return -1;
+
+      if (nread > 0)
+        bytes_skipped += nread;
+
+      return bytes_skipped;
+    }
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  nread = class->fill (bstream, priv->len, cancellable, error);
+
+  if (nread < 0)
+    {
+      if (bytes_skipped == 0)
+        return -1;
+      else
+        return bytes_skipped;
+    }
+
+  available = priv->end - priv->pos;
+  count = MIN (count, available);
+
+  bytes_skipped += count;
+  priv->pos += count;
+
+  return bytes_skipped;
+}
+
+static gssize
+g_buffered_input_stream_read (GInputStream *stream,
+                              void         *buffer,
+                              gsize         count,
+                              GCancellable *cancellable,
+                              GError      **error)
+{
+  GBufferedInputStream        *bstream;
+  GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
+  GInputStream *base_stream;
+  gsize available, bytes_read;
+  gssize nread;
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+  priv = bstream->priv;
+
+  available = priv->end - priv->pos;
+
+  if (count <= available)
+    {
+      memcpy (buffer, priv->buffer + priv->pos, count);
+      priv->pos += count;
+      return count;
+    }
+
+  /* Full request not available, read all currently available and
+   * request refill for more
+   */
+
+  memcpy (buffer, priv->buffer + priv->pos, available);
+  priv->pos = 0;
+  priv->end = 0;
+  bytes_read = available;
+  count -= available;
+
+  if (bytes_read > 0)
+    error = NULL; /* Ignore further errors if we already read some data */
+
+  if (count > priv->len)
+    {
+      /* Large request, shortcut buffer */
+
+      base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+
+      nread = g_input_stream_read (base_stream,
+                                   (char *)buffer + bytes_read,
+                                   count,
+                                   cancellable,
+                                   error);
+
+      if (nread < 0 && bytes_read == 0)
+        return -1;
+
+      if (nread > 0)
+        bytes_read += nread;
+
+      return bytes_read;
+    }
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  nread = class->fill (bstream, priv->len, cancellable, error);
+  if (nread < 0)
+    {
+      if (bytes_read == 0)
+        return -1;
+      else
+        return bytes_read;
+    }
+
+  available = priv->end - priv->pos;
+  count = MIN (count, available);
+
+  memcpy ((char *)buffer + bytes_read, (char *)priv->buffer + priv->pos, count);
+  bytes_read += count;
+  priv->pos += count;
+
+  return bytes_read;
+}
+
+static goffset
+g_buffered_input_stream_tell (GSeekable *seekable)
+{
+  GBufferedInputStream        *bstream;
+  GBufferedInputStreamPrivate *priv;
+  GInputStream *base_stream;
+  GSeekable    *base_stream_seekable;
+  gsize available;
+  goffset base_offset;
+  
+  bstream = G_BUFFERED_INPUT_STREAM (seekable);
+  priv = bstream->priv;
+
+  base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    return 0;
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  
+  available = priv->end - priv->pos;
+  base_offset = g_seekable_tell (base_stream_seekable);
+
+  return base_offset - available;
+}
+
+static gboolean
+g_buffered_input_stream_can_seek (GSeekable *seekable)
+{
+  GInputStream *base_stream;
+  
+  base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_buffered_input_stream_seek (GSeekable     *seekable,
+			      goffset        offset,
+			      GSeekType      type,
+			      GCancellable  *cancellable,
+			      GError       **error)
+{
+  GBufferedInputStream        *bstream;
+  GBufferedInputStreamPrivate *priv;
+  GInputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  bstream = G_BUFFERED_INPUT_STREAM (seekable);
+  priv = bstream->priv;
+
+  base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Seek not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  
+  if (type == G_SEEK_CUR)
+    {
+      if (offset <= priv->end - priv->pos && offset >= -priv->pos)
+	{
+	  priv->pos += offset;
+	  return TRUE;
+	}
+      else
+	{
+	  offset -= priv->end - priv->pos;
+	}
+    }
+
+  if (g_seekable_seek (base_stream_seekable, offset, type, cancellable, error))
+    {
+      priv->pos = 0;
+      priv->end = 0;
+      return TRUE;
+    }
+  else
+    {
+      return FALSE;
+    }
+}
+
+static gboolean
+g_buffered_input_stream_can_truncate (GSeekable *seekable)
+{
+  return FALSE;
+}
+
+static gboolean
+g_buffered_input_stream_truncate (GSeekable     *seekable,
+				  goffset        offset,
+				  GCancellable  *cancellable,
+				  GError       **error)
+{
+  g_set_error_literal (error,
+		       G_IO_ERROR,
+		       G_IO_ERROR_NOT_SUPPORTED,
+		       _("Cannot truncate GBufferedInputStream"));
+  return FALSE;
+}
+
+/**
+ * g_buffered_input_stream_read_byte:
+ * @stream: a #GBufferedInputStream
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
+ * @error: location to store the error occurring, or %NULL to ignore
+ *
+ * Tries to read a single byte from the stream or the buffer. Will block
+ * during this read.
+ *
+ * On success, the byte read from the stream is returned. On end of stream
+ * -1 is returned but it's not an exceptional error and @error is not set.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
+ * operation was partially finished when the operation was cancelled the
+ * partial result will be returned, without an error.
+ *
+ * On error -1 is returned and @error is set accordingly.
+ *
+ * Returns: the byte read from the @stream, or -1 on end of stream or error.
+ */
+int
+g_buffered_input_stream_read_byte (GBufferedInputStream  *stream,
+                                   GCancellable          *cancellable,
+                                   GError               **error)
+{
+  GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
+  GInputStream *input_stream;
+  gsize available;
+  gssize nread;
+
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
+
+  priv = stream->priv;
+  input_stream = G_INPUT_STREAM (stream);
+
+  if (g_input_stream_is_closed (input_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
+                           _("Stream is already closed"));
+      return -1;
+    }
+
+  if (!g_input_stream_set_pending (input_stream, error))
+    return -1;
+
+  available = priv->end - priv->pos;
+
+  if (available != 0)
+    {
+      g_input_stream_clear_pending (input_stream);
+      return priv->buffer[priv->pos++];
+    }
+
+  /* Byte not available, request refill for more */
+
+  if (cancellable)
+    g_cancellable_push_current (cancellable);
+
+  priv->pos = 0;
+  priv->end = 0;
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  nread = class->fill (stream, priv->len, cancellable, error);
+
+  if (cancellable)
+    g_cancellable_pop_current (cancellable);
+
+  g_input_stream_clear_pending (input_stream);
+
+  if (nread <= 0)
+    return -1; /* error or end of stream */
+
+  return priv->buffer[priv->pos++];
+}
+
+/* ************************** */
+/* Async stuff implementation */
+/* ************************** */
+
+static void
+fill_async_callback (GObject      *source_object,
+                     GAsyncResult *result,
+                     gpointer      user_data)
+{
+  GError *error;
+  gssize res;
+  GTask *task = user_data;
+
+  error = NULL;
+  res = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
+                                    result, &error);
+  if (res == -1)
+    g_task_return_error (task, error);
+  else
+    {
+      GBufferedInputStream *stream;
+      GBufferedInputStreamPrivate *priv;
+
+      stream = g_task_get_source_object (task);
+      priv = G_BUFFERED_INPUT_STREAM (stream)->priv;
+
+      g_assert_cmpint (priv->end + res, <=, priv->len);
+      priv->end += res;
+
+      g_task_return_int (task, res);
+    }
+
+  g_object_unref (task);
+}
+
+static void
+g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
+                                         gssize                count,
+                                         int                   io_priority,
+                                         GCancellable         *cancellable,
+                                         GAsyncReadyCallback   callback,
+                                         gpointer              user_data)
+{
+  GBufferedInputStreamPrivate *priv;
+  GInputStream *base_stream;
+  GTask *task;
+  gsize in_buffer;
+
+  priv = stream->priv;
+
+  if (count == -1)
+    count = priv->len;
+
+  in_buffer = priv->end - priv->pos;
+
+  /* Never fill more than can fit in the buffer */
+  count = MIN (count, priv->len - in_buffer);
+
+  /* If requested length does not fit at end, compact */
+  if (priv->len - priv->end < count)
+    compact_buffer (stream);
+
+  task = g_task_new (stream, cancellable, callback, user_data);
+  g_task_set_source_tag (task, g_buffered_input_stream_real_fill_async);
+
+  base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+  g_input_stream_read_async (base_stream,
+                             priv->buffer + priv->end,
+                             count,
+                             io_priority,
+                             cancellable,
+                             fill_async_callback,
+                             task);
+}
+
+static gssize
+g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream,
+                                          GAsyncResult         *result,
+                                          GError              **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), -1);
+
+  return g_task_propagate_int (G_TASK (result), error);
+}
+
+typedef struct
+{
+  gssize bytes_skipped;
+  gssize count;
+} SkipAsyncData;
+
+static void
+free_skip_async_data (gpointer _data)
+{
+  SkipAsyncData *data = _data;
+  g_slice_free (SkipAsyncData, data);
+}
+
+static void
+large_skip_callback (GObject      *source_object,
+                     GAsyncResult *result,
+                     gpointer      user_data)
+{
+  GTask *task = G_TASK (user_data);
+  SkipAsyncData *data;
+  GError *error;
+  gssize nread;
+
+  data = g_task_get_task_data (task);
+
+  error = NULL;
+  nread = g_input_stream_skip_finish (G_INPUT_STREAM (source_object),
+                                      result, &error);
+
+  /* Only report the error if we've not already read some data */
+  if (nread < 0 && data->bytes_skipped == 0)
+    g_task_return_error (task, error);
+  else
+    {
+      if (error)
+	g_error_free (error);
+
+      if (nread > 0)
+	data->bytes_skipped += nread;
+
+      g_task_return_int (task, data->bytes_skipped);
+    }
+
+  g_object_unref (task);
+}
+
+static void
+skip_fill_buffer_callback (GObject      *source_object,
+                           GAsyncResult *result,
+                           gpointer      user_data)
+{
+  GTask *task = G_TASK (user_data);
+  GBufferedInputStream *bstream;
+  GBufferedInputStreamPrivate *priv;
+  SkipAsyncData *data;
+  GError *error;
+  gssize nread;
+  gsize available;
+
+  bstream = G_BUFFERED_INPUT_STREAM (source_object);
+  priv = bstream->priv;
+
+  data = g_task_get_task_data (task);
+
+  error = NULL;
+  nread = g_buffered_input_stream_fill_finish (bstream,
+                                               result, &error);
+
+  if (nread < 0 && data->bytes_skipped == 0)
+    g_task_return_error (task, error);
+  else
+    {
+      if (error)
+	g_error_free (error);
+
+      if (nread > 0)
+	{
+	  available = priv->end - priv->pos;
+	  data->count = MIN (data->count, available);
+
+	  data->bytes_skipped += data->count;
+	  priv->pos += data->count;
+	}
+
+      g_task_return_int (task, data->bytes_skipped);
+    }
+
+  g_object_unref (task);
+}
+
+static void
+g_buffered_input_stream_skip_async (GInputStream        *stream,
+                                    gsize                count,
+                                    int                  io_priority,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
+{
+  GBufferedInputStream *bstream;
+  GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
+  GInputStream *base_stream;
+  gsize available;
+  GTask *task;
+  SkipAsyncData *data;
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+  priv = bstream->priv;
+
+  data = g_slice_new (SkipAsyncData);
+  data->bytes_skipped = 0;
+  task = g_task_new (stream, cancellable, callback, user_data);
+  g_task_set_source_tag (task, g_buffered_input_stream_skip_async);
+  g_task_set_task_data (task, data, free_skip_async_data);
+
+  available = priv->end - priv->pos;
+
+  if (count <= available)
+    {
+      priv->pos += count;
+
+      g_task_return_int (task, count);
+      g_object_unref (task);
+      return;
+    }
+
+  /* Full request not available, skip all currently available
+   * and request refill for more
+   */
+
+  priv->pos = 0;
+  priv->end = 0;
+
+  count -= available;
+
+  data->bytes_skipped = available;
+  data->count = count;
+
+  if (count > priv->len)
+    {
+      /* Large request, shortcut buffer */
+
+      base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+
+      g_input_stream_skip_async (base_stream,
+                                 count,
+                                 io_priority, cancellable,
+                                 large_skip_callback,
+                                 task);
+    }
+  else
+    {
+      class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+      class->fill_async (bstream, priv->len, io_priority, cancellable,
+                         skip_fill_buffer_callback, task);
+    }
+}
+
+static gssize
+g_buffered_input_stream_skip_finish (GInputStream   *stream,
+                                     GAsyncResult   *result,
+                                     GError        **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), -1);
+
+  return g_task_propagate_int (G_TASK (result), error);
+}
diff --git a/gio/gbufferedinputstream.h b/gio/gbufferedinputstream.h
new file mode 100644
index 0000000..19c4214
--- /dev/null
+++ b/gio/gbufferedinputstream.h
@@ -0,0 +1,133 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Christian Kellner <gicmo@gnome.org>
+ */
+
+#ifndef __G_BUFFERED_INPUT_STREAM_H__
+#define __G_BUFFERED_INPUT_STREAM_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gfilterinputstream.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_BUFFERED_INPUT_STREAM         (g_buffered_input_stream_get_type ())
+#define G_BUFFERED_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStream))
+#define G_BUFFERED_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStreamClass))
+#define G_IS_BUFFERED_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_BUFFERED_INPUT_STREAM))
+#define G_IS_BUFFERED_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_BUFFERED_INPUT_STREAM))
+#define G_BUFFERED_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStreamClass))
+
+/**
+ * GBufferedInputStream:
+ *
+ * Implements #GFilterInputStream with a sized input buffer.
+ **/
+typedef struct _GBufferedInputStreamClass    GBufferedInputStreamClass;
+typedef struct _GBufferedInputStreamPrivate  GBufferedInputStreamPrivate;
+
+struct _GBufferedInputStream
+{
+  GFilterInputStream parent_instance;
+
+  /*< private >*/
+  GBufferedInputStreamPrivate *priv;
+};
+
+struct _GBufferedInputStreamClass
+{
+  GFilterInputStreamClass parent_class;
+
+  gssize   (* fill)        (GBufferedInputStream *stream,
+			    gssize                count,
+			    GCancellable         *cancellable,
+			    GError              **error);
+
+  /* Async ops: (optional in derived classes) */
+  void     (* fill_async)  (GBufferedInputStream *stream,
+			    gssize                count,
+			    int                   io_priority,
+			    GCancellable         *cancellable,
+			    GAsyncReadyCallback   callback,
+			    gpointer              user_data);
+  gssize   (* fill_finish) (GBufferedInputStream *stream,
+			    GAsyncResult         *result,
+			    GError              **error);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+};
+
+
+GLIB_AVAILABLE_IN_ALL
+GType         g_buffered_input_stream_get_type        (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GInputStream* g_buffered_input_stream_new             (GInputStream          *base_stream);
+GLIB_AVAILABLE_IN_ALL
+GInputStream* g_buffered_input_stream_new_sized       (GInputStream          *base_stream,
+						       gsize                  size);
+
+GLIB_AVAILABLE_IN_ALL
+gsize         g_buffered_input_stream_get_buffer_size (GBufferedInputStream  *stream);
+GLIB_AVAILABLE_IN_ALL
+void          g_buffered_input_stream_set_buffer_size (GBufferedInputStream  *stream,
+						       gsize                  size);
+GLIB_AVAILABLE_IN_ALL
+gsize         g_buffered_input_stream_get_available   (GBufferedInputStream  *stream);
+GLIB_AVAILABLE_IN_ALL
+gsize         g_buffered_input_stream_peek            (GBufferedInputStream  *stream,
+						       void                  *buffer,
+						       gsize                  offset,
+						       gsize                  count);
+GLIB_AVAILABLE_IN_ALL
+const void*   g_buffered_input_stream_peek_buffer     (GBufferedInputStream  *stream,
+						       gsize                 *count);
+
+GLIB_AVAILABLE_IN_ALL
+gssize        g_buffered_input_stream_fill            (GBufferedInputStream  *stream,
+						       gssize                 count,
+						       GCancellable          *cancellable,
+						       GError               **error);
+GLIB_AVAILABLE_IN_ALL
+void          g_buffered_input_stream_fill_async      (GBufferedInputStream  *stream,
+						       gssize                 count,
+						       int                    io_priority,
+						       GCancellable          *cancellable,
+						       GAsyncReadyCallback    callback,
+						       gpointer               user_data);
+GLIB_AVAILABLE_IN_ALL
+gssize        g_buffered_input_stream_fill_finish     (GBufferedInputStream  *stream,
+						       GAsyncResult          *result,
+						       GError               **error);
+
+GLIB_AVAILABLE_IN_ALL
+int           g_buffered_input_stream_read_byte       (GBufferedInputStream  *stream,
+						       GCancellable          *cancellable,
+						       GError               **error);
+
+G_END_DECLS
+
+#endif /* __G_BUFFERED_INPUT_STREAM_H__ */
diff --git a/gio/gbufferedoutputstream.c b/gio/gbufferedoutputstream.c
new file mode 100644
index 0000000..98bda50
--- /dev/null
+++ b/gio/gbufferedoutputstream.c
@@ -0,0 +1,755 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Christian Kellner <gicmo@gnome.org> 
+ */
+
+#include "config.h"
+#include "gbufferedoutputstream.h"
+#include "goutputstream.h"
+#include "gseekable.h"
+#include "gtask.h"
+#include "string.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+/**
+ * SECTION:gbufferedoutputstream
+ * @short_description: Buffered Output Stream
+ * @include: gio/gio.h
+ * @see_also: #GFilterOutputStream, #GOutputStream
+ * 
+ * Buffered output stream implements #GFilterOutputStream and provides 
+ * for buffered writes. 
+ * 
+ * By default, #GBufferedOutputStream's buffer size is set at 4 kilobytes.
+ * 
+ * To create a buffered output stream, use g_buffered_output_stream_new(), 
+ * or g_buffered_output_stream_new_sized() to specify the buffer's size 
+ * at construction.
+ * 
+ * To get the size of a buffer within a buffered input stream, use 
+ * g_buffered_output_stream_get_buffer_size(). To change the size of a 
+ * buffered output stream's buffer, use 
+ * g_buffered_output_stream_set_buffer_size(). Note that the buffer's 
+ * size cannot be reduced below the size of the data within the buffer.
+ **/
+
+#define DEFAULT_BUFFER_SIZE 4096
+
+struct _GBufferedOutputStreamPrivate {
+  guint8 *buffer; 
+  gsize   len;
+  goffset pos;
+  gboolean auto_grow;
+};
+
+enum {
+  PROP_0,
+  PROP_BUFSIZE,
+  PROP_AUTO_GROW
+};
+
+static void     g_buffered_output_stream_set_property (GObject      *object,
+                                                       guint         prop_id,
+                                                       const GValue *value,
+                                                       GParamSpec   *pspec);
+
+static void     g_buffered_output_stream_get_property (GObject    *object,
+                                                       guint       prop_id,
+                                                       GValue     *value,
+                                                       GParamSpec *pspec);
+static void     g_buffered_output_stream_finalize     (GObject *object);
+
+
+static gssize   g_buffered_output_stream_write        (GOutputStream *stream,
+                                                       const void    *buffer,
+                                                       gsize          count,
+                                                       GCancellable  *cancellable,
+                                                       GError       **error);
+static gboolean g_buffered_output_stream_flush        (GOutputStream    *stream,
+                                                       GCancellable  *cancellable,
+                                                       GError          **error);
+static gboolean g_buffered_output_stream_close        (GOutputStream  *stream,
+                                                       GCancellable   *cancellable,
+                                                       GError        **error);
+
+static void     g_buffered_output_stream_flush_async  (GOutputStream        *stream,
+                                                       int                   io_priority,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              data);
+static gboolean g_buffered_output_stream_flush_finish (GOutputStream        *stream,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+static void     g_buffered_output_stream_close_async  (GOutputStream        *stream,
+                                                       int                   io_priority,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              data);
+static gboolean g_buffered_output_stream_close_finish (GOutputStream        *stream,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+
+static void     g_buffered_output_stream_seekable_iface_init (GSeekableIface  *iface);
+static goffset  g_buffered_output_stream_tell                (GSeekable       *seekable);
+static gboolean g_buffered_output_stream_can_seek            (GSeekable       *seekable);
+static gboolean g_buffered_output_stream_seek                (GSeekable       *seekable,
+							      goffset          offset,
+							      GSeekType        type,
+							      GCancellable    *cancellable,
+							      GError         **error);
+static gboolean g_buffered_output_stream_can_truncate        (GSeekable       *seekable);
+static gboolean g_buffered_output_stream_truncate            (GSeekable       *seekable,
+							      goffset          offset,
+							      GCancellable    *cancellable,
+							      GError         **error);
+
+G_DEFINE_TYPE_WITH_CODE (GBufferedOutputStream,
+			 g_buffered_output_stream,
+			 G_TYPE_FILTER_OUTPUT_STREAM,
+                         G_ADD_PRIVATE (GBufferedOutputStream)
+			 G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
+						g_buffered_output_stream_seekable_iface_init))
+
+
+static void
+g_buffered_output_stream_class_init (GBufferedOutputStreamClass *klass)
+{
+  GObjectClass *object_class;
+  GOutputStreamClass *ostream_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = g_buffered_output_stream_get_property;
+  object_class->set_property = g_buffered_output_stream_set_property;
+  object_class->finalize     = g_buffered_output_stream_finalize;
+
+  ostream_class = G_OUTPUT_STREAM_CLASS (klass);
+  ostream_class->write_fn = g_buffered_output_stream_write;
+  ostream_class->flush = g_buffered_output_stream_flush;
+  ostream_class->close_fn = g_buffered_output_stream_close;
+  ostream_class->flush_async  = g_buffered_output_stream_flush_async;
+  ostream_class->flush_finish = g_buffered_output_stream_flush_finish;
+  ostream_class->close_async  = g_buffered_output_stream_close_async;
+  ostream_class->close_finish = g_buffered_output_stream_close_finish;
+
+  g_object_class_install_property (object_class,
+                                   PROP_BUFSIZE,
+                                   g_param_spec_uint ("buffer-size",
+                                                      P_("Buffer Size"),
+                                                      P_("The size of the backend buffer"),
+                                                      1,
+                                                      G_MAXUINT,
+                                                      DEFAULT_BUFFER_SIZE,
+                                                      G_PARAM_READWRITE|G_PARAM_CONSTRUCT|
+                                                      G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_AUTO_GROW,
+                                   g_param_spec_boolean ("auto-grow",
+                                                         P_("Auto-grow"),
+                                                         P_("Whether the buffer should automatically grow"),
+                                                         FALSE,
+                                                         G_PARAM_READWRITE|
+                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+}
+
+/**
+ * g_buffered_output_stream_get_buffer_size:
+ * @stream: a #GBufferedOutputStream.
+ * 
+ * Gets the size of the buffer in the @stream.
+ * 
+ * Returns: the current size of the buffer.
+ **/
+gsize
+g_buffered_output_stream_get_buffer_size (GBufferedOutputStream *stream)
+{
+  g_return_val_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream), -1);
+
+  return stream->priv->len;
+}
+
+/**
+ * g_buffered_output_stream_set_buffer_size:
+ * @stream: a #GBufferedOutputStream.
+ * @size: a #gsize.
+ *
+ * Sets the size of the internal buffer to @size.
+ **/    
+void
+g_buffered_output_stream_set_buffer_size (GBufferedOutputStream *stream,
+                                          gsize                  size)
+{
+  GBufferedOutputStreamPrivate *priv;
+  guint8 *buffer;
+  
+  g_return_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream));
+
+  priv = stream->priv;
+  
+  if (size == priv->len)
+    return;
+
+  if (priv->buffer)
+    {
+      size = MAX (size, priv->pos);
+
+      buffer = g_malloc (size);
+      memcpy (buffer, priv->buffer, priv->pos);
+      g_free (priv->buffer);
+      priv->buffer = buffer;
+      priv->len = size;
+      /* Keep old pos */
+    }
+  else
+    {
+      priv->buffer = g_malloc (size);
+      priv->len = size;
+      priv->pos = 0;
+    }
+
+  g_object_notify (G_OBJECT (stream), "buffer-size");
+}
+
+/**
+ * g_buffered_output_stream_get_auto_grow:
+ * @stream: a #GBufferedOutputStream.
+ * 
+ * Checks if the buffer automatically grows as data is added.
+ * 
+ * Returns: %TRUE if the @stream's buffer automatically grows,
+ * %FALSE otherwise.
+ **/  
+gboolean
+g_buffered_output_stream_get_auto_grow (GBufferedOutputStream *stream)
+{
+  g_return_val_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream), FALSE);
+
+  return stream->priv->auto_grow;
+}
+
+/**
+ * g_buffered_output_stream_set_auto_grow:
+ * @stream: a #GBufferedOutputStream.
+ * @auto_grow: a #gboolean.
+ *
+ * Sets whether or not the @stream's buffer should automatically grow.
+ * If @auto_grow is true, then each write will just make the buffer
+ * larger, and you must manually flush the buffer to actually write out
+ * the data to the underlying stream.
+ **/
+void
+g_buffered_output_stream_set_auto_grow (GBufferedOutputStream *stream,
+                                        gboolean               auto_grow)
+{
+  GBufferedOutputStreamPrivate *priv;
+  g_return_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream));
+  priv = stream->priv;
+  auto_grow = auto_grow != FALSE;
+  if (priv->auto_grow != auto_grow)
+    {
+      priv->auto_grow = auto_grow;
+      g_object_notify (G_OBJECT (stream), "auto-grow");
+    }
+}
+
+static void
+g_buffered_output_stream_set_property (GObject      *object,
+                                       guint         prop_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+  GBufferedOutputStream *stream;
+
+  stream = G_BUFFERED_OUTPUT_STREAM (object);
+
+  switch (prop_id) 
+    {
+    case PROP_BUFSIZE:
+      g_buffered_output_stream_set_buffer_size (stream, g_value_get_uint (value));
+      break;    
+
+    case PROP_AUTO_GROW:
+      g_buffered_output_stream_set_auto_grow (stream, g_value_get_boolean (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+
+static void
+g_buffered_output_stream_get_property (GObject    *object,
+                                       guint       prop_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+  GBufferedOutputStream *buffered_stream;
+  GBufferedOutputStreamPrivate *priv;
+
+  buffered_stream = G_BUFFERED_OUTPUT_STREAM (object);
+  priv = buffered_stream->priv;
+
+  switch (prop_id)
+    {
+    case PROP_BUFSIZE:
+      g_value_set_uint (value, priv->len);
+      break;
+
+    case PROP_AUTO_GROW:
+      g_value_set_boolean (value, priv->auto_grow);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+
+static void
+g_buffered_output_stream_finalize (GObject *object)
+{
+  GBufferedOutputStream *stream;
+  GBufferedOutputStreamPrivate *priv;
+
+  stream = G_BUFFERED_OUTPUT_STREAM (object);
+  priv = stream->priv;
+
+  g_free (priv->buffer);
+
+  G_OBJECT_CLASS (g_buffered_output_stream_parent_class)->finalize (object);
+}
+
+static void
+g_buffered_output_stream_init (GBufferedOutputStream *stream)
+{
+  stream->priv = g_buffered_output_stream_get_instance_private (stream);
+}
+
+static void
+g_buffered_output_stream_seekable_iface_init (GSeekableIface *iface)
+{
+  iface->tell         = g_buffered_output_stream_tell;
+  iface->can_seek     = g_buffered_output_stream_can_seek;
+  iface->seek         = g_buffered_output_stream_seek;
+  iface->can_truncate = g_buffered_output_stream_can_truncate;
+  iface->truncate_fn  = g_buffered_output_stream_truncate;
+}
+
+/**
+ * g_buffered_output_stream_new:
+ * @base_stream: a #GOutputStream.
+ * 
+ * Creates a new buffered output stream for a base stream.
+ * 
+ * Returns: a #GOutputStream for the given @base_stream.
+ **/  
+GOutputStream *
+g_buffered_output_stream_new (GOutputStream *base_stream)
+{
+  GOutputStream *stream;
+
+  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_BUFFERED_OUTPUT_STREAM,
+                         "base-stream", base_stream,
+                         NULL);
+
+  return stream;
+}
+
+/**
+ * g_buffered_output_stream_new_sized:
+ * @base_stream: a #GOutputStream.
+ * @size: a #gsize.
+ * 
+ * Creates a new buffered output stream with a given buffer size.
+ * 
+ * Returns: a #GOutputStream with an internal buffer set to @size.
+ **/  
+GOutputStream *
+g_buffered_output_stream_new_sized (GOutputStream *base_stream,
+                                    gsize          size)
+{
+  GOutputStream *stream;
+
+  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_BUFFERED_OUTPUT_STREAM,
+                         "base-stream", base_stream,
+                         "buffer-size", size,
+                         NULL);
+
+  return stream;
+}
+
+static gboolean
+flush_buffer (GBufferedOutputStream  *stream,
+              GCancellable           *cancellable,
+              GError                 **error)
+{
+  GBufferedOutputStreamPrivate *priv;
+  GOutputStream                *base_stream;
+  gboolean                      res;
+  gsize                         bytes_written;
+  gsize                         count;
+
+  priv = stream->priv;
+  bytes_written = 0;
+  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+
+  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), FALSE);
+
+  res = g_output_stream_write_all (base_stream,
+                                   priv->buffer,
+                                   priv->pos,
+                                   &bytes_written,
+                                   cancellable,
+                                   error);
+
+  count = priv->pos - bytes_written;
+
+  if (count > 0)
+    memmove (priv->buffer, priv->buffer + bytes_written, count);
+  
+  priv->pos -= bytes_written;
+
+  return res;
+}
+
+static gssize
+g_buffered_output_stream_write  (GOutputStream *stream,
+                                 const void    *buffer,
+                                 gsize          count,
+                                 GCancellable  *cancellable,
+                                 GError       **error)
+{
+  GBufferedOutputStream        *bstream;
+  GBufferedOutputStreamPrivate *priv;
+  gboolean res;
+  gsize    n;
+  gsize new_size;
+
+  bstream = G_BUFFERED_OUTPUT_STREAM (stream);
+  priv = bstream->priv;
+
+  n = priv->len - priv->pos;
+
+  if (priv->auto_grow && n < count)
+    {
+      new_size = MAX (priv->len * 2, priv->len + count);
+      g_buffered_output_stream_set_buffer_size (bstream, new_size);
+    }
+  else if (n == 0)
+    {
+      res = flush_buffer (bstream, cancellable, error);
+      
+      if (res == FALSE)
+	return -1;
+    }
+
+  n = priv->len - priv->pos;
+  
+  count = MIN (count, n);
+  memcpy (priv->buffer + priv->pos, buffer, count);
+  priv->pos += count;
+
+  return count;
+}
+
+static gboolean
+g_buffered_output_stream_flush (GOutputStream  *stream,
+                                GCancellable   *cancellable,
+                                GError        **error)
+{
+  GBufferedOutputStream *bstream;
+  GOutputStream                *base_stream;
+  gboolean res;
+
+  bstream = G_BUFFERED_OUTPUT_STREAM (stream);
+  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+
+  res = flush_buffer (bstream, cancellable, error);
+
+  if (res == FALSE)
+    return FALSE;
+
+  res = g_output_stream_flush (base_stream, cancellable, error);
+
+  return res;
+}
+
+static gboolean
+g_buffered_output_stream_close (GOutputStream  *stream,
+                                GCancellable   *cancellable,
+                                GError        **error)
+{
+  GBufferedOutputStream        *bstream;
+  GOutputStream                *base_stream;
+  gboolean                      res;
+
+  bstream = G_BUFFERED_OUTPUT_STREAM (stream);
+  base_stream = G_FILTER_OUTPUT_STREAM (bstream)->base_stream;
+  res = flush_buffer (bstream, cancellable, error);
+
+  if (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (stream)))
+    {
+      /* report the first error but still close the stream */
+      if (res)
+        res = g_output_stream_close (base_stream, cancellable, error);
+      else
+        g_output_stream_close (base_stream, cancellable, NULL);
+    }
+
+  return res;
+}
+
+static goffset
+g_buffered_output_stream_tell (GSeekable *seekable)
+{
+  GBufferedOutputStream        *bstream;
+  GBufferedOutputStreamPrivate *priv;
+  GOutputStream *base_stream;
+  GSeekable    *base_stream_seekable;
+  goffset base_offset;
+  
+  bstream = G_BUFFERED_OUTPUT_STREAM (seekable);
+  priv = bstream->priv;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    return 0;
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  
+  base_offset = g_seekable_tell (base_stream_seekable);
+  return base_offset + priv->pos;
+}
+
+static gboolean
+g_buffered_output_stream_can_seek (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_buffered_output_stream_seek (GSeekable     *seekable,
+			       goffset        offset,
+			       GSeekType      type,
+			       GCancellable  *cancellable,
+			       GError       **error)
+{
+  GBufferedOutputStream *bstream;
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+  gboolean flushed;
+
+  bstream = G_BUFFERED_OUTPUT_STREAM (seekable);
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Seek not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  flushed = flush_buffer (bstream, cancellable, error);
+  if (!flushed)
+    return FALSE;
+
+  return g_seekable_seek (base_stream_seekable, offset, type, cancellable, error);
+}
+
+static gboolean
+g_buffered_output_stream_can_truncate (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_truncate (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_buffered_output_stream_truncate (GSeekable     *seekable,
+				   goffset        offset,
+				   GCancellable  *cancellable,
+				   GError       **error)
+{
+  GBufferedOutputStream        *bstream;
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+  gboolean flushed;
+
+  bstream = G_BUFFERED_OUTPUT_STREAM (seekable);
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Truncate not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+
+  flushed = flush_buffer (bstream, cancellable, error);
+  if (!flushed)
+    return FALSE;
+  return g_seekable_truncate (base_stream_seekable, offset, cancellable, error);
+}
+
+/* ************************** */
+/* Async stuff implementation */
+/* ************************** */
+
+/* TODO: This should be using the base class async ops, not threads */
+
+typedef struct {
+
+  guint flush_stream : 1;
+  guint close_stream : 1;
+
+} FlushData;
+
+static void
+free_flush_data (gpointer data)
+{
+  g_slice_free (FlushData, data);
+}
+
+/* This function is used by all three (i.e. 
+ * _write, _flush, _close) functions since
+ * all of them will need to flush the buffer
+ * and so closing and writing is just a special
+ * case of flushing + some addition stuff */
+static void
+flush_buffer_thread (GTask        *task,
+                     gpointer      object,
+                     gpointer      task_data,
+                     GCancellable *cancellable)
+{
+  GBufferedOutputStream *stream;
+  GOutputStream *base_stream;
+  FlushData     *fdata;
+  gboolean       res;
+  GError        *error = NULL;
+
+  stream = G_BUFFERED_OUTPUT_STREAM (object);
+  fdata = task_data;
+  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+
+  res = flush_buffer (stream, cancellable, &error);
+
+  /* if flushing the buffer didn't work don't even bother
+   * to flush the stream but just report that error */
+  if (res && fdata->flush_stream)
+    res = g_output_stream_flush (base_stream, cancellable, &error);
+
+  if (fdata->close_stream) 
+    {
+     
+      /* if flushing the buffer or the stream returned 
+       * an error report that first error but still try 
+       * close the stream */
+      if (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (stream)))
+        {
+          if (res == FALSE)
+            g_output_stream_close (base_stream, cancellable, NULL);
+          else 
+            res = g_output_stream_close (base_stream, cancellable, &error);
+        }
+    }
+
+  if (res == FALSE)
+    g_task_return_error (task, error);
+  else
+    g_task_return_boolean (task, TRUE);
+}
+
+static void
+g_buffered_output_stream_flush_async (GOutputStream        *stream,
+                                      int                   io_priority,
+                                      GCancellable         *cancellable,
+                                      GAsyncReadyCallback   callback,
+                                      gpointer              data)
+{
+  GTask *task;
+  FlushData *fdata;
+
+  fdata = g_slice_new0 (FlushData);
+  fdata->flush_stream = TRUE;
+  fdata->close_stream = FALSE;
+
+  task = g_task_new (stream, cancellable, callback, data);
+  g_task_set_source_tag (task, g_buffered_output_stream_flush_async);
+  g_task_set_task_data (task, fdata, free_flush_data);
+  g_task_set_priority (task, io_priority);
+
+  g_task_run_in_thread (task, flush_buffer_thread);
+  g_object_unref (task);
+}
+
+static gboolean
+g_buffered_output_stream_flush_finish (GOutputStream        *stream,
+                                       GAsyncResult         *result,
+                                       GError              **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+g_buffered_output_stream_close_async (GOutputStream        *stream,
+                                      int                   io_priority,
+                                      GCancellable         *cancellable,
+                                      GAsyncReadyCallback   callback,
+                                      gpointer              data)
+{
+  GTask *task;
+  FlushData *fdata;
+
+  fdata = g_slice_new0 (FlushData);
+  fdata->close_stream = TRUE;
+
+  task = g_task_new (stream, cancellable, callback, data);
+  g_task_set_source_tag (task, g_buffered_output_stream_close_async);
+  g_task_set_task_data (task, fdata, free_flush_data);
+  g_task_set_priority (task, io_priority);
+
+  g_task_run_in_thread (task, flush_buffer_thread);
+  g_object_unref (task);
+}
+
+static gboolean
+g_buffered_output_stream_close_finish (GOutputStream        *stream,
+                                       GAsyncResult         *result,
+                                       GError              **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
diff --git a/gio/gbufferedoutputstream.h b/gio/gbufferedoutputstream.h
new file mode 100644
index 0000000..f88f279
--- /dev/null
+++ b/gio/gbufferedoutputstream.h
@@ -0,0 +1,86 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Christian Kellner <gicmo@gnome.org>
+ */
+
+#ifndef __G_BUFFERED_OUTPUT_STREAM_H__
+#define __G_BUFFERED_OUTPUT_STREAM_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gfilteroutputstream.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_BUFFERED_OUTPUT_STREAM         (g_buffered_output_stream_get_type ())
+#define G_BUFFERED_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStream))
+#define G_BUFFERED_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStreamClass))
+#define G_IS_BUFFERED_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_BUFFERED_OUTPUT_STREAM))
+#define G_IS_BUFFERED_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_BUFFERED_OUTPUT_STREAM))
+#define G_BUFFERED_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStreamClass))
+
+/**
+ * GBufferedOutputStream:
+ *
+ * An implementation of #GFilterOutputStream with a sized buffer.
+ **/
+typedef struct _GBufferedOutputStreamClass    GBufferedOutputStreamClass;
+typedef struct _GBufferedOutputStreamPrivate  GBufferedOutputStreamPrivate;
+
+struct _GBufferedOutputStream
+{
+  GFilterOutputStream parent_instance;
+
+  /*< protected >*/
+  GBufferedOutputStreamPrivate *priv;
+};
+
+struct _GBufferedOutputStreamClass
+{
+  GFilterOutputStreamClass parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+};
+
+
+GLIB_AVAILABLE_IN_ALL
+GType          g_buffered_output_stream_get_type        (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GOutputStream* g_buffered_output_stream_new             (GOutputStream         *base_stream);
+GLIB_AVAILABLE_IN_ALL
+GOutputStream* g_buffered_output_stream_new_sized       (GOutputStream         *base_stream,
+							 gsize                  size);
+GLIB_AVAILABLE_IN_ALL
+gsize          g_buffered_output_stream_get_buffer_size (GBufferedOutputStream *stream);
+GLIB_AVAILABLE_IN_ALL
+void           g_buffered_output_stream_set_buffer_size (GBufferedOutputStream *stream,
+							 gsize                  size);
+GLIB_AVAILABLE_IN_ALL
+gboolean       g_buffered_output_stream_get_auto_grow   (GBufferedOutputStream *stream);
+GLIB_AVAILABLE_IN_ALL
+void           g_buffered_output_stream_set_auto_grow   (GBufferedOutputStream *stream,
+							 gboolean               auto_grow);
+
+G_END_DECLS
+
+#endif /* __G_BUFFERED_OUTPUT_STREAM_H__ */
diff --git a/gio/gbytesicon.c b/gio/gbytesicon.c
new file mode 100644
index 0000000..ca78be1
--- /dev/null
+++ b/gio/gbytesicon.c
@@ -0,0 +1,266 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2013 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gbytesicon.h"
+#include "gbytes.h"
+#include "gicon.h"
+#include "glibintl.h"
+#include "gloadableicon.h"
+#include "gmemoryinputstream.h"
+#include "gtask.h"
+#include "gioerror.h"
+
+
+/**
+ * SECTION:gbytesicon
+ * @short_description: An icon stored in memory as a GBytes
+ * @include: gio/gio.h
+ * @see_also: #GIcon, #GLoadableIcon, #GBytes
+ *
+ * #GBytesIcon specifies an image held in memory in a common format (usually
+ * png) to be used as icon.
+ *
+ * Since: 2.38
+ **/
+
+typedef GObjectClass GBytesIconClass;
+
+struct _GBytesIcon
+{
+  GObject parent_instance;
+
+  GBytes *bytes;
+};
+
+enum
+{
+  PROP_0,
+  PROP_BYTES
+};
+
+static void g_bytes_icon_icon_iface_init          (GIconIface          *iface);
+static void g_bytes_icon_loadable_icon_iface_init (GLoadableIconIface  *iface);
+G_DEFINE_TYPE_WITH_CODE (GBytesIcon, g_bytes_icon, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ICON, g_bytes_icon_icon_iface_init)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, g_bytes_icon_loadable_icon_iface_init))
+
+static void
+g_bytes_icon_get_property (GObject    *object,
+                           guint       prop_id,
+                           GValue     *value,
+                           GParamSpec *pspec)
+{
+  GBytesIcon *icon = G_BYTES_ICON (object);
+
+  switch (prop_id)
+    {
+      case PROP_BYTES:
+        g_value_set_boxed (value, icon->bytes);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+g_bytes_icon_set_property (GObject      *object,
+                          guint         prop_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  GBytesIcon *icon = G_BYTES_ICON (object);
+
+  switch (prop_id)
+    {
+      case PROP_BYTES:
+        icon->bytes = g_value_dup_boxed (value);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+g_bytes_icon_finalize (GObject *object)
+{
+  GBytesIcon *icon;
+
+  icon = G_BYTES_ICON (object);
+
+  g_bytes_unref (icon->bytes);
+
+  G_OBJECT_CLASS (g_bytes_icon_parent_class)->finalize (object);
+}
+
+static void
+g_bytes_icon_class_init (GBytesIconClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->get_property = g_bytes_icon_get_property;
+  gobject_class->set_property = g_bytes_icon_set_property;
+  gobject_class->finalize = g_bytes_icon_finalize;
+
+  /**
+   * GBytesIcon:bytes:
+   *
+   * The bytes containing the icon.
+   */
+  g_object_class_install_property (gobject_class, PROP_BYTES,
+                                   g_param_spec_boxed ("bytes",
+                                                       P_("bytes"),
+                                                       P_("The bytes containing the icon"),
+                                                       G_TYPE_BYTES,
+                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+g_bytes_icon_init (GBytesIcon *bytes)
+{
+}
+
+/**
+ * g_bytes_icon_new:
+ * @bytes: a #GBytes.
+ *
+ * Creates a new icon for a bytes.
+ *
+ * Returns: (transfer full) (type GBytesIcon): a #GIcon for the given
+ *   @bytes, or %NULL on error.
+ *
+ * Since: 2.38
+ **/
+GIcon *
+g_bytes_icon_new (GBytes *bytes)
+{
+  g_return_val_if_fail (bytes != NULL, NULL);
+
+  return g_object_new (G_TYPE_BYTES_ICON, "bytes", bytes, NULL);
+}
+
+/**
+ * g_bytes_icon_get_bytes:
+ * @icon: a #GIcon.
+ *
+ * Gets the #GBytes associated with the given @icon.
+ *
+ * Returns: (transfer none): a #GBytes, or %NULL.
+ *
+ * Since: 2.38
+ **/
+GBytes *
+g_bytes_icon_get_bytes (GBytesIcon *icon)
+{
+  g_return_val_if_fail (G_IS_BYTES_ICON (icon), NULL);
+
+  return icon->bytes;
+}
+
+static guint
+g_bytes_icon_hash (GIcon *icon)
+{
+  GBytesIcon *bytes_icon = G_BYTES_ICON (icon);
+
+  return g_bytes_hash (bytes_icon->bytes);
+}
+
+static gboolean
+g_bytes_icon_equal (GIcon *icon1,
+                    GIcon *icon2)
+{
+  GBytesIcon *bytes1 = G_BYTES_ICON (icon1);
+  GBytesIcon *bytes2 = G_BYTES_ICON (icon2);
+
+  return g_bytes_equal (bytes1->bytes, bytes2->bytes);
+}
+
+static GVariant *
+g_bytes_icon_serialize (GIcon *icon)
+{
+  GBytesIcon *bytes_icon = G_BYTES_ICON (icon);
+
+  return g_variant_new ("(sv)", "bytes",
+                        g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes_icon->bytes, TRUE));
+}
+
+static void
+g_bytes_icon_icon_iface_init (GIconIface *iface)
+{
+  iface->hash = g_bytes_icon_hash;
+  iface->equal = g_bytes_icon_equal;
+  iface->serialize = g_bytes_icon_serialize;
+}
+
+static GInputStream *
+g_bytes_icon_load (GLoadableIcon  *icon,
+                   int            size,
+                   char          **type,
+                   GCancellable   *cancellable,
+                   GError        **error)
+{
+  GBytesIcon *bytes_icon = G_BYTES_ICON (icon);
+
+  if (type)
+    *type = NULL;
+
+  return g_memory_input_stream_new_from_bytes (bytes_icon->bytes);
+}
+
+static void
+g_bytes_icon_load_async (GLoadableIcon       *icon,
+                         int                  size,
+                         GCancellable        *cancellable,
+                         GAsyncReadyCallback  callback,
+                         gpointer             user_data)
+{
+  GBytesIcon *bytes_icon = G_BYTES_ICON (icon);
+  GTask *task;
+
+  task = g_task_new (icon, cancellable, callback, user_data);
+  g_task_set_source_tag (task, g_bytes_icon_load_async);
+  g_task_return_pointer (task, g_memory_input_stream_new_from_bytes (bytes_icon->bytes), g_object_unref);
+  g_object_unref (task);
+}
+
+static GInputStream *
+g_bytes_icon_load_finish (GLoadableIcon  *icon,
+                          GAsyncResult   *res,
+                          char          **type,
+                          GError        **error)
+{
+  g_return_val_if_fail (g_task_is_valid (res, icon), NULL);
+
+  if (type)
+    *type = NULL;
+
+  return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+g_bytes_icon_loadable_icon_iface_init (GLoadableIconIface *iface)
+{
+  iface->load = g_bytes_icon_load;
+  iface->load_async = g_bytes_icon_load_async;
+  iface->load_finish = g_bytes_icon_load_finish;
+}
diff --git a/gio/gbytesicon.h b/gio/gbytesicon.h
new file mode 100644
index 0000000..5661044
--- /dev/null
+++ b/gio/gbytesicon.h
@@ -0,0 +1,52 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_BYTES_ICON_H__
+#define __G_BYTES_ICON_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_BYTES_ICON         (g_bytes_icon_get_type ())
+#define G_BYTES_ICON(inst)        (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_BYTES_ICON, GBytesIcon))
+#define G_IS_BYTES_ICON(inst)     (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_BYTES_ICON))
+
+/**
+ * GBytesIcon:
+ *
+ * Gets an icon for a #GBytes. Implements #GLoadableIcon.
+ **/
+GLIB_AVAILABLE_IN_2_38
+GType   g_bytes_icon_get_type   (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_2_38
+GIcon * g_bytes_icon_new        (GBytes     *bytes);
+
+GLIB_AVAILABLE_IN_2_38
+GBytes * g_bytes_icon_get_bytes (GBytesIcon *icon);
+
+G_END_DECLS
+
+#endif /* __G_BYTES_ICON_H__ */
diff --git a/gio/gcancellable.c b/gio/gcancellable.c
new file mode 100644
index 0000000..e687cca
--- /dev/null
+++ b/gio/gcancellable.c
@@ -0,0 +1,816 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include "glib.h"
+#include <gioerror.h>
+#include "glib-private.h"
+#include "gcancellable.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gcancellable
+ * @short_description: Thread-safe Operation Cancellation Stack
+ * @include: gio/gio.h
+ *
+ * GCancellable is a thread-safe operation cancellation stack used 
+ * throughout GIO to allow for cancellation of synchronous and
+ * asynchronous operations.
+ */
+
+enum {
+  CANCELLED,
+  LAST_SIGNAL
+};
+
+struct _GCancellablePrivate
+{
+  /* Atomic so that g_cancellable_is_cancelled does not require holding the mutex. */
+  gboolean cancelled;
+  /* Access to fields below is protected by cancellable_mutex. */
+  guint cancelled_running : 1;
+  guint cancelled_running_waiting : 1;
+
+  guint fd_refcount;
+  GWakeup *wakeup;
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_PRIVATE (GCancellable, g_cancellable, G_TYPE_OBJECT)
+
+static GPrivate current_cancellable;
+static GMutex cancellable_mutex;
+static GCond cancellable_cond;
+
+static void
+g_cancellable_finalize (GObject *object)
+{
+  GCancellable *cancellable = G_CANCELLABLE (object);
+
+  if (cancellable->priv->wakeup)
+    GLIB_PRIVATE_CALL (g_wakeup_free) (cancellable->priv->wakeup);
+
+  G_OBJECT_CLASS (g_cancellable_parent_class)->finalize (object);
+}
+
+static void
+g_cancellable_class_init (GCancellableClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = g_cancellable_finalize;
+
+  /**
+   * GCancellable::cancelled:
+   * @cancellable: a #GCancellable.
+   * 
+   * Emitted when the operation has been cancelled.
+   * 
+   * Can be used by implementations of cancellable operations. If the
+   * operation is cancelled from another thread, the signal will be
+   * emitted in the thread that cancelled the operation, not the
+   * thread that is running the operation.
+   *
+   * Note that disconnecting from this signal (or any signal) in a
+   * multi-threaded program is prone to race conditions. For instance
+   * it is possible that a signal handler may be invoked even after
+   * a call to g_signal_handler_disconnect() for that handler has
+   * already returned.
+   * 
+   * There is also a problem when cancellation happens right before
+   * connecting to the signal. If this happens the signal will
+   * unexpectedly not be emitted, and checking before connecting to
+   * the signal leaves a race condition where this is still happening.
+   *
+   * In order to make it safe and easy to connect handlers there
+   * are two helper functions: g_cancellable_connect() and
+   * g_cancellable_disconnect() which protect against problems
+   * like this.
+   *
+   * An example of how to us this:
+   * |[<!-- language="C" -->
+   *     // Make sure we don't do unnecessary work if already cancelled
+   *     if (g_cancellable_set_error_if_cancelled (cancellable, error))
+   *       return;
+   *
+   *     // Set up all the data needed to be able to handle cancellation
+   *     // of the operation
+   *     my_data = my_data_new (...);
+   *
+   *     id = 0;
+   *     if (cancellable)
+   *       id = g_cancellable_connect (cancellable,
+   *     			      G_CALLBACK (cancelled_handler)
+   *     			      data, NULL);
+   *
+   *     // cancellable operation here...
+   *
+   *     g_cancellable_disconnect (cancellable, id);
+   *
+   *     // cancelled_handler is never called after this, it is now safe
+   *     // to free the data
+   *     my_data_free (my_data);  
+   * ]|
+   *
+   * Note that the cancelled signal is emitted in the thread that
+   * the user cancelled from, which may be the main thread. So, the
+   * cancellable signal should not do something that can block.
+   */
+  signals[CANCELLED] =
+    g_signal_new (I_("cancelled"),
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GCancellableClass, cancelled),
+		  NULL, NULL,
+		  NULL,
+		  G_TYPE_NONE, 0);
+  
+}
+
+static void
+g_cancellable_init (GCancellable *cancellable)
+{
+  cancellable->priv = g_cancellable_get_instance_private (cancellable);
+}
+
+/**
+ * g_cancellable_new:
+ * 
+ * Creates a new #GCancellable object.
+ *
+ * Applications that want to start one or more operations
+ * that should be cancellable should create a #GCancellable
+ * and pass it to the operations.
+ *
+ * One #GCancellable can be used in multiple consecutive
+ * operations or in multiple concurrent operations.
+ *  
+ * Returns: a #GCancellable.
+ **/
+GCancellable *
+g_cancellable_new (void)
+{
+  return g_object_new (G_TYPE_CANCELLABLE, NULL);
+}
+
+/**
+ * g_cancellable_push_current:
+ * @cancellable: a #GCancellable object
+ *
+ * Pushes @cancellable onto the cancellable stack. The current
+ * cancellable can then be received using g_cancellable_get_current().
+ *
+ * This is useful when implementing cancellable operations in
+ * code that does not allow you to pass down the cancellable object.
+ *
+ * This is typically called automatically by e.g. #GFile operations,
+ * so you rarely have to call this yourself.
+ **/
+void
+g_cancellable_push_current (GCancellable *cancellable)
+{
+  GSList *l;
+
+  g_return_if_fail (cancellable != NULL);
+
+  l = g_private_get (&current_cancellable);
+  l = g_slist_prepend (l, cancellable);
+  g_private_set (&current_cancellable, l);
+}
+
+/**
+ * g_cancellable_pop_current:
+ * @cancellable: a #GCancellable object
+ *
+ * Pops @cancellable off the cancellable stack (verifying that @cancellable
+ * is on the top of the stack).
+ **/
+void
+g_cancellable_pop_current (GCancellable *cancellable)
+{
+  GSList *l;
+
+  l = g_private_get (&current_cancellable);
+
+  g_return_if_fail (l != NULL);
+  g_return_if_fail (l->data == cancellable);
+
+  l = g_slist_delete_link (l, l);
+  g_private_set (&current_cancellable, l);
+}
+
+/**
+ * g_cancellable_get_current:
+ *
+ * Gets the top cancellable from the stack.
+ *
+ * Returns: (nullable) (transfer none): a #GCancellable from the top
+ * of the stack, or %NULL if the stack is empty.
+ **/
+GCancellable *
+g_cancellable_get_current  (void)
+{
+  GSList *l;
+
+  l = g_private_get (&current_cancellable);
+  if (l == NULL)
+    return NULL;
+
+  return G_CANCELLABLE (l->data);
+}
+
+/**
+ * g_cancellable_reset:
+ * @cancellable: a #GCancellable object.
+ * 
+ * Resets @cancellable to its uncancelled state.
+ *
+ * If cancellable is currently in use by any cancellable operation
+ * then the behavior of this function is undefined.
+ *
+ * Note that it is generally not a good idea to reuse an existing
+ * cancellable for more operations after it has been cancelled once,
+ * as this function might tempt you to do. The recommended practice
+ * is to drop the reference to a cancellable after cancelling it,
+ * and let it die with the outstanding async operations. You should
+ * create a fresh cancellable for further async operations.
+ **/
+void 
+g_cancellable_reset (GCancellable *cancellable)
+{
+  GCancellablePrivate *priv;
+
+  g_return_if_fail (G_IS_CANCELLABLE (cancellable));
+
+  g_mutex_lock (&cancellable_mutex);
+
+  priv = cancellable->priv;
+
+  while (priv->cancelled_running)
+    {
+      priv->cancelled_running_waiting = TRUE;
+      g_cond_wait (&cancellable_cond, &cancellable_mutex);
+    }
+
+  if (g_atomic_int_get (&priv->cancelled))
+    {
+      if (priv->wakeup)
+        GLIB_PRIVATE_CALL (g_wakeup_acknowledge) (priv->wakeup);
+
+      g_atomic_int_set (&priv->cancelled, FALSE);
+    }
+
+  g_mutex_unlock (&cancellable_mutex);
+}
+
+/**
+ * g_cancellable_is_cancelled:
+ * @cancellable: (nullable): a #GCancellable or %NULL
+ *
+ * Checks if a cancellable job has been cancelled.
+ *
+ * Returns: %TRUE if @cancellable is cancelled,
+ * FALSE if called with %NULL or if item is not cancelled.
+ **/
+gboolean
+g_cancellable_is_cancelled (GCancellable *cancellable)
+{
+  return cancellable != NULL && g_atomic_int_get (&cancellable->priv->cancelled);
+}
+
+/**
+ * g_cancellable_set_error_if_cancelled:
+ * @cancellable: (nullable): a #GCancellable or %NULL
+ * @error: #GError to append error state to
+ *
+ * If the @cancellable is cancelled, sets the error to notify
+ * that the operation was cancelled.
+ *
+ * Returns: %TRUE if @cancellable was cancelled, %FALSE if it was not
+ */
+gboolean
+g_cancellable_set_error_if_cancelled (GCancellable  *cancellable,
+                                      GError       **error)
+{
+  if (g_cancellable_is_cancelled (cancellable))
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_CANCELLED,
+                           _("Operation was cancelled"));
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/**
+ * g_cancellable_get_fd:
+ * @cancellable: a #GCancellable.
+ * 
+ * Gets the file descriptor for a cancellable job. This can be used to
+ * implement cancellable operations on Unix systems. The returned fd will
+ * turn readable when @cancellable is cancelled.
+ *
+ * You are not supposed to read from the fd yourself, just check for
+ * readable status. Reading to unset the readable status is done
+ * with g_cancellable_reset().
+ * 
+ * After a successful return from this function, you should use 
+ * g_cancellable_release_fd() to free up resources allocated for 
+ * the returned file descriptor.
+ *
+ * See also g_cancellable_make_pollfd().
+ *
+ * Returns: A valid file descriptor. `-1` if the file descriptor
+ * is not supported, or on errors. 
+ **/
+int
+g_cancellable_get_fd (GCancellable *cancellable)
+{
+  GPollFD pollfd;
+
+  if (cancellable == NULL)
+	  return -1;
+
+#ifdef G_OS_WIN32
+  pollfd.fd = -1;
+#else
+  g_cancellable_make_pollfd (cancellable, &pollfd);
+#endif
+
+  return pollfd.fd;
+}
+
+/**
+ * g_cancellable_make_pollfd:
+ * @cancellable: (nullable): a #GCancellable or %NULL
+ * @pollfd: a pointer to a #GPollFD
+ * 
+ * Creates a #GPollFD corresponding to @cancellable; this can be passed
+ * to g_poll() and used to poll for cancellation. This is useful both
+ * for unix systems without a native poll and for portability to
+ * windows.
+ *
+ * When this function returns %TRUE, you should use 
+ * g_cancellable_release_fd() to free up resources allocated for the 
+ * @pollfd. After a %FALSE return, do not call g_cancellable_release_fd().
+ *
+ * If this function returns %FALSE, either no @cancellable was given or
+ * resource limits prevent this function from allocating the necessary 
+ * structures for polling. (On Linux, you will likely have reached 
+ * the maximum number of file descriptors.) The suggested way to handle
+ * these cases is to ignore the @cancellable.
+ *
+ * You are not supposed to read from the fd yourself, just check for
+ * readable status. Reading to unset the readable status is done
+ * with g_cancellable_reset().
+ *
+ * Returns: %TRUE if @pollfd was successfully initialized, %FALSE on 
+ *          failure to prepare the cancellable.
+ * 
+ * Since: 2.22
+ **/
+gboolean
+g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
+{
+  g_return_val_if_fail (pollfd != NULL, FALSE);
+  if (cancellable == NULL)
+    return FALSE;
+  g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE);
+
+  g_mutex_lock (&cancellable_mutex);
+
+  cancellable->priv->fd_refcount++;
+
+  if (cancellable->priv->wakeup == NULL)
+    {
+      cancellable->priv->wakeup = GLIB_PRIVATE_CALL (g_wakeup_new) ();
+
+      if (g_atomic_int_get (&cancellable->priv->cancelled))
+        GLIB_PRIVATE_CALL (g_wakeup_signal) (cancellable->priv->wakeup);
+    }
+
+  GLIB_PRIVATE_CALL (g_wakeup_get_pollfd) (cancellable->priv->wakeup, pollfd);
+
+  g_mutex_unlock (&cancellable_mutex);
+
+  return TRUE;
+}
+
+/**
+ * g_cancellable_release_fd:
+ * @cancellable: a #GCancellable
+ *
+ * Releases a resources previously allocated by g_cancellable_get_fd()
+ * or g_cancellable_make_pollfd().
+ *
+ * For compatibility reasons with older releases, calling this function 
+ * is not strictly required, the resources will be automatically freed
+ * when the @cancellable is finalized. However, the @cancellable will
+ * block scarce file descriptors until it is finalized if this function
+ * is not called. This can cause the application to run out of file 
+ * descriptors when many #GCancellables are used at the same time.
+ * 
+ * Since: 2.22
+ **/
+void
+g_cancellable_release_fd (GCancellable *cancellable)
+{
+  GCancellablePrivate *priv;
+
+  if (cancellable == NULL)
+    return;
+
+  g_return_if_fail (G_IS_CANCELLABLE (cancellable));
+
+  priv = cancellable->priv;
+
+  g_mutex_lock (&cancellable_mutex);
+  g_assert (priv->fd_refcount > 0);
+
+  priv->fd_refcount--;
+  if (priv->fd_refcount == 0)
+    {
+      GLIB_PRIVATE_CALL (g_wakeup_free) (priv->wakeup);
+      priv->wakeup = NULL;
+    }
+
+  g_mutex_unlock (&cancellable_mutex);
+}
+
+/**
+ * g_cancellable_cancel:
+ * @cancellable: (nullable): a #GCancellable object.
+ * 
+ * Will set @cancellable to cancelled, and will emit the
+ * #GCancellable::cancelled signal. (However, see the warning about
+ * race conditions in the documentation for that signal if you are
+ * planning to connect to it.)
+ *
+ * This function is thread-safe. In other words, you can safely call
+ * it from a thread other than the one running the operation that was
+ * passed the @cancellable.
+ *
+ * If @cancellable is %NULL, this function returns immediately for convenience.
+ *
+ * The convention within GIO is that cancelling an asynchronous
+ * operation causes it to complete asynchronously. That is, if you
+ * cancel the operation from the same thread in which it is running,
+ * then the operation's #GAsyncReadyCallback will not be invoked until
+ * the application returns to the main loop.
+ **/
+void
+g_cancellable_cancel (GCancellable *cancellable)
+{
+  GCancellablePrivate *priv;
+
+  if (cancellable == NULL || g_cancellable_is_cancelled (cancellable))
+    return;
+
+  priv = cancellable->priv;
+
+  g_mutex_lock (&cancellable_mutex);
+
+  if (g_atomic_int_get (&priv->cancelled))
+    {
+      g_mutex_unlock (&cancellable_mutex);
+      return;
+    }
+
+  g_atomic_int_set (&priv->cancelled, TRUE);
+  priv->cancelled_running = TRUE;
+
+  if (priv->wakeup)
+    GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
+
+  g_mutex_unlock (&cancellable_mutex);
+
+  g_object_ref (cancellable);
+  g_signal_emit (cancellable, signals[CANCELLED], 0);
+
+  g_mutex_lock (&cancellable_mutex);
+
+  priv->cancelled_running = FALSE;
+  if (priv->cancelled_running_waiting)
+    g_cond_broadcast (&cancellable_cond);
+  priv->cancelled_running_waiting = FALSE;
+
+  g_mutex_unlock (&cancellable_mutex);
+
+  g_object_unref (cancellable);
+}
+
+/**
+ * g_cancellable_connect:
+ * @cancellable: A #GCancellable.
+ * @callback: The #GCallback to connect.
+ * @data: Data to pass to @callback.
+ * @data_destroy_func: (nullable): Free function for @data or %NULL.
+ *
+ * Convenience function to connect to the #GCancellable::cancelled
+ * signal. Also handles the race condition that may happen
+ * if the cancellable is cancelled right before connecting.
+ *
+ * @callback is called at most once, either directly at the
+ * time of the connect if @cancellable is already cancelled,
+ * or when @cancellable is cancelled in some thread.
+ *
+ * @data_destroy_func will be called when the handler is
+ * disconnected, or immediately if the cancellable is already
+ * cancelled.
+ *
+ * See #GCancellable::cancelled for details on how to use this.
+ *
+ * Since GLib 2.40, the lock protecting @cancellable is not held when
+ * @callback is invoked.  This lifts a restriction in place for
+ * earlier GLib versions which now makes it easier to write cleanup
+ * code that unconditionally invokes e.g. g_cancellable_cancel().
+ *
+ * Returns: The id of the signal handler or 0 if @cancellable has already
+ *          been cancelled.
+ *
+ * Since: 2.22
+ */
+gulong
+g_cancellable_connect (GCancellable   *cancellable,
+		       GCallback       callback,
+		       gpointer        data,
+		       GDestroyNotify  data_destroy_func)
+{
+  gulong id;
+
+  g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), 0);
+
+  g_mutex_lock (&cancellable_mutex);
+
+  if (g_atomic_int_get (&cancellable->priv->cancelled))
+    {
+      void (*_callback) (GCancellable *cancellable,
+                         gpointer      user_data);
+
+      g_mutex_unlock (&cancellable_mutex);
+
+      _callback = (void *)callback;
+      id = 0;
+
+      _callback (cancellable, data);
+
+      if (data_destroy_func)
+        data_destroy_func (data);
+    }
+  else
+    {
+      id = g_signal_connect_data (cancellable, "cancelled",
+                                  callback, data,
+                                  (GClosureNotify) data_destroy_func,
+                                  0);
+
+      g_mutex_unlock (&cancellable_mutex);
+    }
+
+
+  return id;
+}
+
+/**
+ * g_cancellable_disconnect:
+ * @cancellable: (nullable): A #GCancellable or %NULL.
+ * @handler_id: Handler id of the handler to be disconnected, or `0`.
+ *
+ * Disconnects a handler from a cancellable instance similar to
+ * g_signal_handler_disconnect().  Additionally, in the event that a
+ * signal handler is currently running, this call will block until the
+ * handler has finished.  Calling this function from a
+ * #GCancellable::cancelled signal handler will therefore result in a
+ * deadlock.
+ *
+ * This avoids a race condition where a thread cancels at the
+ * same time as the cancellable operation is finished and the
+ * signal handler is removed. See #GCancellable::cancelled for
+ * details on how to use this.
+ *
+ * If @cancellable is %NULL or @handler_id is `0` this function does
+ * nothing.
+ *
+ * Since: 2.22
+ */
+void
+g_cancellable_disconnect (GCancellable  *cancellable,
+			  gulong         handler_id)
+{
+  GCancellablePrivate *priv;
+
+  if (handler_id == 0 ||  cancellable == NULL)
+    return;
+
+  g_mutex_lock (&cancellable_mutex);
+
+  priv = cancellable->priv;
+
+  while (priv->cancelled_running)
+    {
+      priv->cancelled_running_waiting = TRUE;
+      g_cond_wait (&cancellable_cond, &cancellable_mutex);
+    }
+
+  g_signal_handler_disconnect (cancellable, handler_id);
+
+  g_mutex_unlock (&cancellable_mutex);
+}
+
+typedef struct {
+  GSource       source;
+
+  GCancellable *cancellable;
+  gulong        cancelled_handler;
+  /* Protected by cancellable_mutex: */
+  gboolean      resurrected_during_cancellation;
+} GCancellableSource;
+
+/*
+ * The reference count of the GSource might be 0 at this point but it is not
+ * finalized yet and its dispose function did not run yet, or otherwise we
+ * would have disconnected the signal handler already and due to the signal
+ * emission lock it would be impossible to call the signal handler at that
+ * point. That is: at this point we either have a fully valid GSource, or
+ * it's not disposed or finalized yet and we can still resurrect it as needed.
+ *
+ * As such we first ensure that we have a strong reference to the GSource in
+ * here before calling any other GSource API.
+ */
+static void
+cancellable_source_cancelled (GCancellable *cancellable,
+			      gpointer      user_data)
+{
+  GSource *source = user_data;
+  GCancellableSource *cancellable_source = (GCancellableSource *) source;
+
+  g_mutex_lock (&cancellable_mutex);
+
+  /* Drop the reference added in cancellable_source_dispose(); see the comment there.
+   * The reference must be dropped after unlocking @cancellable_mutex since
+   * it could be the final reference, and the dispose function takes
+   * @cancellable_mutex. */
+  if (cancellable_source->resurrected_during_cancellation)
+    {
+      cancellable_source->resurrected_during_cancellation = FALSE;
+      g_mutex_unlock (&cancellable_mutex);
+      g_source_unref (source);
+      return;
+    }
+
+  g_source_ref (source);
+  g_mutex_unlock (&cancellable_mutex);
+  g_source_set_ready_time (source, 0);
+  g_source_unref (source);
+}
+
+static gboolean
+cancellable_source_dispatch (GSource     *source,
+			     GSourceFunc  callback,
+			     gpointer     user_data)
+{
+  GCancellableSourceFunc func = (GCancellableSourceFunc)callback;
+  GCancellableSource *cancellable_source = (GCancellableSource *)source;
+
+  g_source_set_ready_time (source, -1);
+  return (*func) (cancellable_source->cancellable, user_data);
+}
+
+static void
+cancellable_source_dispose (GSource *source)
+{
+  GCancellableSource *cancellable_source = (GCancellableSource *)source;
+
+  g_mutex_lock (&cancellable_mutex);
+
+  if (cancellable_source->cancellable)
+    {
+      if (cancellable_source->cancellable->priv->cancelled_running)
+        {
+          /* There can be a race here: if thread A has called
+           * g_cancellable_cancel() and has got as far as committing to call
+           * cancellable_source_cancelled(), then thread B drops the final
+           * ref on the GCancellableSource before g_source_ref() is called in
+           * cancellable_source_cancelled(), then cancellable_source_dispose()
+           * will run through and the GCancellableSource will be finalised
+           * before cancellable_source_cancelled() gets to g_source_ref(). It
+           * will then be left in a state where it’s committed to using a
+           * dangling GCancellableSource pointer.
+           *
+           * Eliminate that race by resurrecting the #GSource temporarily, and
+           * then dropping that reference in cancellable_source_cancelled(),
+           * which should be guaranteed to fire because we’re inside a
+           * @cancelled_running block.
+           */
+          g_source_ref (source);
+          cancellable_source->resurrected_during_cancellation = TRUE;
+        }
+
+      g_clear_signal_handler (&cancellable_source->cancelled_handler,
+                              cancellable_source->cancellable);
+      g_clear_object (&cancellable_source->cancellable);
+    }
+
+  g_mutex_unlock (&cancellable_mutex);
+}
+
+static gboolean
+cancellable_source_closure_callback (GCancellable *cancellable,
+				     gpointer      data)
+{
+  GClosure *closure = data;
+
+  GValue params = G_VALUE_INIT;
+  GValue result_value = G_VALUE_INIT;
+  gboolean result;
+
+  g_value_init (&result_value, G_TYPE_BOOLEAN);
+
+  g_value_init (&params, G_TYPE_CANCELLABLE);
+  g_value_set_object (&params, cancellable);
+
+  g_closure_invoke (closure, &result_value, 1, &params, NULL);
+
+  result = g_value_get_boolean (&result_value);
+  g_value_unset (&result_value);
+  g_value_unset (&params);
+
+  return result;
+}
+
+static GSourceFuncs cancellable_source_funcs =
+{
+  NULL,
+  NULL,
+  cancellable_source_dispatch,
+  NULL,
+  (GSourceFunc)cancellable_source_closure_callback,
+};
+
+/**
+ * g_cancellable_source_new:
+ * @cancellable: (nullable): a #GCancellable, or %NULL
+ *
+ * Creates a source that triggers if @cancellable is cancelled and
+ * calls its callback of type #GCancellableSourceFunc. This is
+ * primarily useful for attaching to another (non-cancellable) source
+ * with g_source_add_child_source() to add cancellability to it.
+ *
+ * For convenience, you can call this with a %NULL #GCancellable,
+ * in which case the source will never trigger.
+ *
+ * The new #GSource will hold a reference to the #GCancellable.
+ *
+ * Returns: (transfer full): the new #GSource.
+ *
+ * Since: 2.28
+ */
+GSource *
+g_cancellable_source_new (GCancellable *cancellable)
+{
+  GSource *source;
+  GCancellableSource *cancellable_source;
+
+  source = g_source_new (&cancellable_source_funcs, sizeof (GCancellableSource));
+  g_source_set_name (source, "GCancellable");
+  g_source_set_dispose_function (source, cancellable_source_dispose);
+  cancellable_source = (GCancellableSource *)source;
+
+  if (cancellable)
+    {
+      cancellable_source->cancellable = g_object_ref (cancellable);
+
+      /* We intentionally don't use g_cancellable_connect() here,
+       * because we don't want the "at most once" behavior.
+       */
+      cancellable_source->cancelled_handler =
+        g_signal_connect (cancellable, "cancelled",
+                          G_CALLBACK (cancellable_source_cancelled),
+                          source);
+      if (g_cancellable_is_cancelled (cancellable))
+        g_source_set_ready_time (source, 0);
+    }
+
+  return source;
+}
diff --git a/gio/gcancellable.h b/gio/gcancellable.h
new file mode 100644
index 0000000..45b9a5a
--- /dev/null
+++ b/gio/gcancellable.h
@@ -0,0 +1,118 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CANCELLABLE_H__
+#define __G_CANCELLABLE_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_CANCELLABLE         (g_cancellable_get_type ())
+#define G_CANCELLABLE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CANCELLABLE, GCancellable))
+#define G_CANCELLABLE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CANCELLABLE, GCancellableClass))
+#define G_IS_CANCELLABLE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CANCELLABLE))
+#define G_IS_CANCELLABLE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CANCELLABLE))
+#define G_CANCELLABLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CANCELLABLE, GCancellableClass))
+
+/**
+ * GCancellable:
+ *
+ * Allows actions to be cancelled.
+ */
+typedef struct _GCancellableClass   GCancellableClass;
+typedef struct _GCancellablePrivate GCancellablePrivate;
+
+struct _GCancellable
+{
+  GObject parent_instance;
+
+  /*< private >*/
+  GCancellablePrivate *priv;
+};
+
+struct _GCancellableClass
+{
+  GObjectClass parent_class;
+
+  void (* cancelled) (GCancellable *cancellable);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType         g_cancellable_get_type               (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+GCancellable *g_cancellable_new                    (void);
+
+/* These are only safe to call inside a cancellable op */
+GLIB_AVAILABLE_IN_ALL
+gboolean      g_cancellable_is_cancelled           (GCancellable  *cancellable);
+GLIB_AVAILABLE_IN_ALL
+gboolean      g_cancellable_set_error_if_cancelled (GCancellable  *cancellable,
+						    GError       **error);
+
+GLIB_AVAILABLE_IN_ALL
+int           g_cancellable_get_fd                 (GCancellable  *cancellable);
+GLIB_AVAILABLE_IN_ALL
+gboolean      g_cancellable_make_pollfd            (GCancellable  *cancellable,
+						    GPollFD       *pollfd);
+GLIB_AVAILABLE_IN_ALL
+void          g_cancellable_release_fd             (GCancellable  *cancellable);
+
+GLIB_AVAILABLE_IN_ALL
+GSource *     g_cancellable_source_new             (GCancellable  *cancellable);
+
+GLIB_AVAILABLE_IN_ALL
+GCancellable *g_cancellable_get_current            (void);
+GLIB_AVAILABLE_IN_ALL
+void          g_cancellable_push_current           (GCancellable  *cancellable);
+GLIB_AVAILABLE_IN_ALL
+void          g_cancellable_pop_current            (GCancellable  *cancellable);
+GLIB_AVAILABLE_IN_ALL
+void          g_cancellable_reset                  (GCancellable  *cancellable);
+GLIB_AVAILABLE_IN_ALL
+gulong        g_cancellable_connect                (GCancellable  *cancellable,
+						    GCallback      callback,
+						    gpointer       data,
+						    GDestroyNotify data_destroy_func);
+GLIB_AVAILABLE_IN_ALL
+void          g_cancellable_disconnect             (GCancellable  *cancellable,
+						    gulong         handler_id);
+
+
+/* This is safe to call from another thread */
+GLIB_AVAILABLE_IN_ALL
+void          g_cancellable_cancel       (GCancellable  *cancellable);
+
+G_END_DECLS
+
+#endif /* __G_CANCELLABLE_H__ */
diff --git a/gio/gcharsetconverter.c b/gio/gcharsetconverter.c
new file mode 100644
index 0000000..d529cbc
--- /dev/null
+++ b/gio/gcharsetconverter.c
@@ -0,0 +1,472 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gcharsetconverter.h"
+
+#include <errno.h>
+
+#include "ginitable.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+
+enum {
+  PROP_0,
+  PROP_FROM_CHARSET,
+  PROP_TO_CHARSET,
+  PROP_USE_FALLBACK
+};
+
+/**
+ * SECTION:gcharsetconverter
+ * @short_description: Convert between charsets
+ * @include: gio/gio.h
+ *
+ * #GCharsetConverter is an implementation of #GConverter based on
+ * GIConv.
+ */
+
+static void g_charset_converter_iface_init          (GConverterIface *iface);
+static void g_charset_converter_initable_iface_init (GInitableIface  *iface);
+
+/**
+ * GCharsetConverter:
+ *
+ * Conversions between character sets.
+ */
+struct _GCharsetConverter
+{
+  GObject parent_instance;
+
+  char *from;
+  char *to;
+  GIConv iconv;
+  gboolean use_fallback;
+  guint n_fallback_errors;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GCharsetConverter, g_charset_converter, G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
+						g_charset_converter_iface_init);
+			 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+						g_charset_converter_initable_iface_init))
+
+static void
+g_charset_converter_finalize (GObject *object)
+{
+  GCharsetConverter *conv;
+
+  conv = G_CHARSET_CONVERTER (object);
+
+  g_free (conv->from);
+  g_free (conv->to);
+  if (conv->iconv)
+    g_iconv_close (conv->iconv);
+
+  G_OBJECT_CLASS (g_charset_converter_parent_class)->finalize (object);
+}
+
+static void
+g_charset_converter_set_property (GObject      *object,
+				  guint         prop_id,
+				  const GValue *value,
+				  GParamSpec   *pspec)
+{
+  GCharsetConverter *conv;
+
+  conv = G_CHARSET_CONVERTER (object);
+
+  switch (prop_id)
+    {
+    case PROP_TO_CHARSET:
+      g_free (conv->to);
+      conv->to = g_value_dup_string (value);
+      break;
+
+    case PROP_FROM_CHARSET:
+      g_free (conv->from);
+      conv->from = g_value_dup_string (value);
+      break;
+
+    case PROP_USE_FALLBACK:
+      conv->use_fallback = g_value_get_boolean (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+
+static void
+g_charset_converter_get_property (GObject    *object,
+				  guint       prop_id,
+				  GValue     *value,
+				  GParamSpec *pspec)
+{
+  GCharsetConverter *conv;
+
+  conv = G_CHARSET_CONVERTER (object);
+
+  switch (prop_id)
+    {
+    case PROP_TO_CHARSET:
+      g_value_set_string (value, conv->to);
+      break;
+
+    case PROP_FROM_CHARSET:
+      g_value_set_string (value, conv->from);
+      break;
+
+    case PROP_USE_FALLBACK:
+      g_value_set_boolean (value, conv->use_fallback);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_charset_converter_class_init (GCharsetConverterClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = g_charset_converter_finalize;
+  gobject_class->get_property = g_charset_converter_get_property;
+  gobject_class->set_property = g_charset_converter_set_property;
+
+  g_object_class_install_property (gobject_class,
+				   PROP_TO_CHARSET,
+				   g_param_spec_string ("to-charset",
+							P_("To Charset"),
+							P_("The character encoding to convert to"),
+							NULL,
+							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+							G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class,
+				   PROP_FROM_CHARSET,
+				   g_param_spec_string ("from-charset",
+							P_("From Charset"),
+							P_("The character encoding to convert from"),
+							NULL,
+							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+							G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class,
+				   PROP_USE_FALLBACK,
+				   g_param_spec_boolean ("use-fallback",
+							 P_("Fallback enabled"),
+							 P_("Use fallback (of form \\<hexval>) for invalid bytes"),
+							 FALSE,
+							 G_PARAM_READWRITE |
+							 G_PARAM_CONSTRUCT |
+							 G_PARAM_STATIC_STRINGS));
+}
+
+static void
+g_charset_converter_init (GCharsetConverter *local)
+{
+}
+
+
+/**
+ * g_charset_converter_new:
+ * @to_charset: destination charset
+ * @from_charset: source charset
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Creates a new #GCharsetConverter.
+ *
+ * Returns: a new #GCharsetConverter or %NULL on error.
+ *
+ * Since: 2.24
+ **/
+GCharsetConverter *
+g_charset_converter_new (const gchar *to_charset,
+			 const gchar *from_charset,
+			 GError      **error)
+{
+  GCharsetConverter *conv;
+
+  conv = g_initable_new (G_TYPE_CHARSET_CONVERTER,
+			 NULL, error,
+			 "to-charset", to_charset,
+			 "from-charset", from_charset,
+			 NULL);
+
+  return conv;
+}
+
+static void
+g_charset_converter_reset (GConverter *converter)
+{
+  GCharsetConverter *conv = G_CHARSET_CONVERTER (converter);
+
+  if (conv->iconv == NULL)
+    {
+      g_warning ("Invalid object, not initialized");
+      return;
+    }
+
+  g_iconv (conv->iconv, NULL, NULL, NULL, NULL);
+  conv->n_fallback_errors = 0;
+}
+
+static GConverterResult
+g_charset_converter_convert (GConverter       *converter,
+			     const void       *inbuf,
+			     gsize             inbuf_size,
+			     void             *outbuf,
+			     gsize             outbuf_size,
+			     GConverterFlags   flags,
+			     gsize            *bytes_read,
+			     gsize            *bytes_written,
+			     GError          **error)
+{
+  GCharsetConverter  *conv;
+  gsize res;
+  GConverterResult ret;
+  gchar *inbufp, *outbufp;
+  gsize in_left, out_left;
+  int errsv;
+  gboolean reset;
+
+  conv = G_CHARSET_CONVERTER (converter);
+
+  if (conv->iconv == NULL)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
+			   _("Invalid object, not initialized"));
+      return G_CONVERTER_ERROR;
+    }
+
+  inbufp = (char *)inbuf;
+  outbufp = (char *)outbuf;
+  in_left = inbuf_size;
+  out_left = outbuf_size;
+  reset = FALSE;
+
+  /* if there is not input try to flush the data */
+  if (inbuf_size == 0)
+    {
+      if (flags & G_CONVERTER_INPUT_AT_END ||
+          flags & G_CONVERTER_FLUSH)
+        {
+          reset = TRUE;
+        }
+      else
+        {
+          g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT,
+                               _("Incomplete multibyte sequence in input"));
+          return G_CONVERTER_ERROR;
+        }
+    }
+
+  if (reset)
+    /* call g_iconv with NULL inbuf to cleanup shift state */
+    res = g_iconv (conv->iconv,
+                   NULL, &in_left,
+                   &outbufp, &out_left);
+  else
+    res = g_iconv (conv->iconv,
+                   &inbufp, &in_left,
+                   &outbufp, &out_left);
+
+  *bytes_read = inbufp - (char *)inbuf;
+  *bytes_written = outbufp - (char *)outbuf;
+
+  /* Don't report error if we converted anything */
+  if (res == (gsize) -1 && *bytes_read == 0)
+    {
+      errsv = errno;
+
+      switch (errsv)
+	{
+	case EINVAL:
+	  /* Incomplete input text */
+	  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT,
+			       _("Incomplete multibyte sequence in input"));
+	  break;
+
+	case E2BIG:
+	  /* Not enough destination space */
+	  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
+			       _("Not enough space in destination"));
+	  break;
+
+	case EILSEQ:
+	  /* Invalid code sequence */
+	  if (conv->use_fallback)
+	    {
+	      if (outbuf_size < 3)
+		g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
+				     _("Not enough space in destination"));
+	      else
+		{
+		  const char hex[] = "0123456789ABCDEF";
+		  guint8 v = *(guint8 *)inbuf;
+		  guint8 *out = (guint8 *)outbuf;
+		  out[0] = '\\';
+		  out[1] = hex[(v & 0xf0) >> 4];
+		  out[2] = hex[(v & 0x0f) >> 0];
+		  *bytes_read = 1;
+		  *bytes_written = 3;
+		  in_left--;
+		  conv->n_fallback_errors++;
+		  goto ok;
+		}
+	    }
+	  else
+	    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+				 _("Invalid byte sequence in conversion input"));
+	  break;
+
+	default:
+	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+		       _("Error during conversion: %s"),
+		       g_strerror (errsv));
+	  break;
+	}
+      ret = G_CONVERTER_ERROR;
+    }
+  else
+    {
+    ok:
+      ret = G_CONVERTER_CONVERTED;
+
+      if (reset &&
+	  (flags & G_CONVERTER_INPUT_AT_END))
+        ret = G_CONVERTER_FINISHED;
+      else if (reset &&
+	       (flags & G_CONVERTER_FLUSH))
+        ret = G_CONVERTER_FLUSHED;
+    }
+
+  return ret;
+}
+
+/**
+ * g_charset_converter_set_use_fallback:
+ * @converter: a #GCharsetConverter
+ * @use_fallback: %TRUE to use fallbacks
+ *
+ * Sets the #GCharsetConverter:use-fallback property.
+ *
+ * Since: 2.24
+ */
+void
+g_charset_converter_set_use_fallback (GCharsetConverter *converter,
+				      gboolean           use_fallback)
+{
+  use_fallback = !!use_fallback;
+
+  if (converter->use_fallback != use_fallback)
+    {
+      converter->use_fallback = use_fallback;
+      g_object_notify (G_OBJECT (converter), "use-fallback");
+    }
+}
+
+/**
+ * g_charset_converter_get_use_fallback:
+ * @converter: a #GCharsetConverter
+ *
+ * Gets the #GCharsetConverter:use-fallback property.
+ *
+ * Returns: %TRUE if fallbacks are used by @converter
+ *
+ * Since: 2.24
+ */
+gboolean
+g_charset_converter_get_use_fallback (GCharsetConverter *converter)
+{
+  return converter->use_fallback;
+}
+
+/**
+ * g_charset_converter_get_num_fallbacks:
+ * @converter: a #GCharsetConverter
+ *
+ * Gets the number of fallbacks that @converter has applied so far.
+ *
+ * Returns: the number of fallbacks that @converter has applied
+ *
+ * Since: 2.24
+ */
+guint
+g_charset_converter_get_num_fallbacks (GCharsetConverter *converter)
+{
+  return converter->n_fallback_errors;
+}
+
+static void
+g_charset_converter_iface_init (GConverterIface *iface)
+{
+  iface->convert = g_charset_converter_convert;
+  iface->reset = g_charset_converter_reset;
+}
+
+static gboolean
+g_charset_converter_initable_init (GInitable     *initable,
+				   GCancellable  *cancellable,
+				   GError       **error)
+{
+  GCharsetConverter  *conv;
+  int errsv;
+
+  g_return_val_if_fail (G_IS_CHARSET_CONVERTER (initable), FALSE);
+
+  conv = G_CHARSET_CONVERTER (initable);
+
+  if (cancellable != NULL)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+			   _("Cancellable initialization not supported"));
+      return FALSE;
+    }
+
+  conv->iconv = g_iconv_open (conv->to, conv->from);
+  errsv = errno;
+
+  if (conv->iconv == (GIConv)-1)
+    {
+      if (errsv == EINVAL)
+	g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		     _("Conversion from character set “%s” to “%s” is not supported"),
+		     conv->from, conv->to);
+      else
+	g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+		     _("Could not open converter from “%s” to “%s”"),
+		     conv->from, conv->to);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+g_charset_converter_initable_iface_init (GInitableIface *iface)
+{
+  iface->init = g_charset_converter_initable_init;
+}
diff --git a/gio/gcharsetconverter.h b/gio/gcharsetconverter.h
new file mode 100644
index 0000000..610f774
--- /dev/null
+++ b/gio/gcharsetconverter.h
@@ -0,0 +1,63 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CHARSET_CONVERTER_H__
+#define __G_CHARSET_CONVERTER_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gconverter.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_CHARSET_CONVERTER         (g_charset_converter_get_type ())
+#define G_CHARSET_CONVERTER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CHARSET_CONVERTER, GCharsetConverter))
+#define G_CHARSET_CONVERTER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CHARSET_CONVERTER, GCharsetConverterClass))
+#define G_IS_CHARSET_CONVERTER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CHARSET_CONVERTER))
+#define G_IS_CHARSET_CONVERTER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CHARSET_CONVERTER))
+#define G_CHARSET_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CHARSET_CONVERTER, GCharsetConverterClass))
+
+typedef struct _GCharsetConverterClass   GCharsetConverterClass;
+
+struct _GCharsetConverterClass
+{
+  GObjectClass parent_class;
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType              g_charset_converter_get_type      (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+GCharsetConverter *g_charset_converter_new            (const gchar  *to_charset,
+						       const gchar  *from_charset,
+						       GError **error);
+GLIB_AVAILABLE_IN_ALL
+void               g_charset_converter_set_use_fallback (GCharsetConverter *converter,
+							 gboolean use_fallback);
+GLIB_AVAILABLE_IN_ALL
+gboolean           g_charset_converter_get_use_fallback (GCharsetConverter *converter);
+GLIB_AVAILABLE_IN_ALL
+guint              g_charset_converter_get_num_fallbacks (GCharsetConverter *converter);
+
+G_END_DECLS
+
+#endif /* __G_CHARSET_CONVERTER_H__ */
diff --git a/gio/gcocoanotificationbackend.m b/gio/gcocoanotificationbackend.m
new file mode 100644
index 0000000..42cf8ab
--- /dev/null
+++ b/gio/gcocoanotificationbackend.m
@@ -0,0 +1,277 @@
+/*
+ * Copyright © 2015 Patrick Griffis
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Patrick Griffis
+ */
+
+#include "config.h"
+
+#import <Cocoa/Cocoa.h>
+#include "gnotificationbackend.h"
+#include "gapplication.h"
+#include "gaction.h"
+#include "gactiongroup.h"
+#include "giomodule-priv.h"
+#include "gnotification-private.h"
+#include "gthemedicon.h"
+#include "gfileicon.h"
+#include "gfile.h"
+
+#define G_TYPE_COCOA_NOTIFICATION_BACKEND  (g_cocoa_notification_backend_get_type ())
+#define G_COCOA_NOTIFICATION_BACKEND(o)    (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_COCOA_NOTIFICATION_BACKEND, GCocoaNotificationBackend))
+
+typedef struct _GCocoaNotificationBackend GCocoaNotificationBackend;
+typedef GNotificationBackendClass            GCocoaNotificationBackendClass;
+struct _GCocoaNotificationBackend
+{
+  GNotificationBackend parent;
+};
+
+GType g_cocoa_notification_backend_get_type (void);
+
+G_DEFINE_TYPE_WITH_CODE (GCocoaNotificationBackend, g_cocoa_notification_backend, G_TYPE_NOTIFICATION_BACKEND,
+  _g_io_modules_ensure_extension_points_registered ();
+  g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, g_define_type_id, "cocoa", 200));
+
+static NSString *
+nsstring_from_cstr (const char *cstr)
+{
+  if (!cstr)
+    return nil;
+
+  return [[NSString alloc] initWithUTF8String:cstr];
+}
+
+static NSImage*
+nsimage_from_gicon (GIcon *icon)
+{
+  if (G_IS_FILE_ICON (icon))
+    {
+      NSImage *image = nil;
+      GFile *file;
+      char *path;
+
+      file = g_file_icon_get_file (G_FILE_ICON (icon));
+      path = g_file_get_path (file);
+      if (path)
+        {
+          NSString *str_path = nsstring_from_cstr (path);
+          image = [[NSImage alloc] initByReferencingFile:str_path];
+
+          [str_path release];
+          g_free (path);
+        }
+      return image;
+    }
+  else
+    {
+      g_warning ("This icon type is not handled by this NotificationBackend");
+      return nil;
+    }
+}
+
+static void
+activate_detailed_action (const char * action)
+{
+  char *name;
+  GVariant *target;
+
+  if (!g_str_has_prefix (action, "app."))
+    {
+      g_warning ("Notification action does not have \"app.\" prefix");
+      return;
+    }
+
+  if (g_action_parse_detailed_name (action, &name, &target, NULL))
+    {
+      g_action_group_activate_action (G_ACTION_GROUP (g_application_get_default()), name + 4, target);
+      g_free (name);
+      if (target)
+        g_variant_unref (target);
+    }
+}
+
+@interface GNotificationCenterDelegate : NSObject<NSUserNotificationCenterDelegate> @end
+@implementation GNotificationCenterDelegate
+
+-(void) userNotificationCenter:(NSUserNotificationCenter*) center
+       didActivateNotification:(NSUserNotification*)       notification
+{
+  if ([notification activationType] == NSUserNotificationActivationTypeContentsClicked)
+    {
+      const char *action = [[notification userInfo][@"default"] UTF8String];
+      if (action)
+        activate_detailed_action (action);
+      /* OSX Always activates the front window */
+    }
+  else if ([notification activationType] == NSUserNotificationActivationTypeActionButtonClicked)
+    {
+      const char *action = [[notification userInfo][@"button0"] UTF8String];
+      if (action)
+        activate_detailed_action (action);
+    }
+
+  [center removeDeliveredNotification:notification];
+}
+
+@end
+
+static GNotificationCenterDelegate *cocoa_notification_delegate;
+
+static gboolean
+g_cocoa_notification_backend_is_supported (void)
+{
+  NSBundle *bundle = [NSBundle mainBundle];
+
+  /* This is always actually supported, but without a bundle it does nothing */
+  if (![bundle bundleIdentifier])
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+add_actions_to_notification (NSUserNotification   *userNotification,
+                             GNotification        *notification)
+{
+  guint n_buttons = g_notification_get_n_buttons (notification);
+  char *action = NULL, *label = NULL;
+  GVariant *target = NULL;
+  NSMutableDictionary *user_info = nil;
+
+  if (g_notification_get_default_action (notification, &action, &target))
+    {
+      char *detailed_name = g_action_print_detailed_name (action, target);
+      NSString *action_name = nsstring_from_cstr (detailed_name);
+      user_info = [[NSMutableDictionary alloc] init];
+
+      user_info[@"default"] = action_name;
+
+      [action_name release];
+      g_free (detailed_name);
+      g_clear_pointer (&action, g_free);
+      g_clear_pointer (&target, g_variant_unref);
+    }
+
+  if (n_buttons)
+    {
+      g_notification_get_button (notification, 0, &label, &action, &target);
+      if (label)
+        {
+          NSString *str_label = nsstring_from_cstr (label);
+          char *detailed_name = g_action_print_detailed_name (action, target);
+          NSString *action_name = nsstring_from_cstr (detailed_name);
+
+          if (!user_info)
+            user_info = [[NSMutableDictionary alloc] init];
+
+          user_info[@"button0"] = action_name;
+          userNotification.actionButtonTitle = str_label;
+
+          [str_label release];
+          [action_name release];
+          g_free (label);
+          g_free (action);
+          g_free (detailed_name);
+          g_clear_pointer (&target, g_variant_unref);
+        }
+
+      if (n_buttons > 1)
+        g_warning ("Only a single button is currently supported by this NotificationBackend");
+    }
+
+    userNotification.userInfo = user_info;
+    [user_info release];
+}
+
+static void
+g_cocoa_notification_backend_send_notification (GNotificationBackend *backend,
+                                                const gchar          *cstr_id,
+                                                GNotification        *notification)
+{
+  NSString *str_title = nil, *str_text = nil, *str_id = nil;
+  NSImage *content = nil;
+  const char *cstr;
+  GIcon *icon;
+  NSUserNotification *userNotification;
+  NSUserNotificationCenter *center;
+
+  if ((cstr = g_notification_get_title (notification)))
+    str_title = nsstring_from_cstr (cstr);
+  if ((cstr = g_notification_get_body (notification)))
+    str_text = nsstring_from_cstr (cstr);
+  if (cstr_id != NULL)
+    str_id = nsstring_from_cstr (cstr_id);
+  if ((icon = g_notification_get_icon (notification)))
+    content = nsimage_from_gicon (icon);
+  /* NOTE: There is no priority */
+
+  userNotification = [NSUserNotification new];
+  userNotification.title = str_title;
+  userNotification.informativeText = str_text;
+  userNotification.identifier = str_id;
+  userNotification.contentImage = content;
+  /* NOTE: Buttons only show up if your bundle has NSUserNotificationAlertStyle set to "alerts" */
+  add_actions_to_notification (userNotification, notification);
+
+  if (!cocoa_notification_delegate)
+    cocoa_notification_delegate = [[GNotificationCenterDelegate alloc] init];
+
+  center = [NSUserNotificationCenter defaultUserNotificationCenter];
+  center.delegate = cocoa_notification_delegate;
+  [center deliverNotification:userNotification];
+
+  [str_title release];
+  [str_text release];
+  [str_id release];
+  [content release];
+  [userNotification release];
+}
+
+static void
+g_cocoa_notification_backend_withdraw_notification (GNotificationBackend *backend,
+                                                    const gchar          *cstr_id)
+{
+  NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
+  NSArray *notifications = [center deliveredNotifications];
+  NSString *str_id = nsstring_from_cstr (cstr_id);
+
+  for (NSUserNotification *notification in notifications)
+    {
+      if ([notification.identifier compare:str_id] == NSOrderedSame)
+        {
+          [center removeDeliveredNotification:notification];
+          break;
+        }
+    }
+
+  [str_id release];
+}
+
+static void
+g_cocoa_notification_backend_init (GCocoaNotificationBackend *backend)
+{
+}
+
+static void
+g_cocoa_notification_backend_class_init (GCocoaNotificationBackendClass *klass)
+{
+  GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (klass);
+
+  backend_class->is_supported = g_cocoa_notification_backend_is_supported;
+  backend_class->send_notification = g_cocoa_notification_backend_send_notification;
+  backend_class->withdraw_notification = g_cocoa_notification_backend_withdraw_notification;
+}
diff --git a/gio/gcontenttype-win32.c b/gio/gcontenttype-win32.c
new file mode 100644
index 0000000..2f07fa3
--- /dev/null
+++ b/gio/gcontenttype-win32.c
@@ -0,0 +1,426 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gcontenttype.h"
+#include "gthemedicon.h"
+#include "gicon.h"
+#include "glibintl.h"
+
+#include <windows.h>
+
+static char *
+get_registry_classes_key (const char    *subdir,
+                          const wchar_t *key_name)
+{
+  wchar_t *wc_key;
+  HKEY reg_key = NULL;
+  DWORD key_type;
+  DWORD nbytes;
+  char *value_utf8;
+
+  value_utf8 = NULL;
+  
+  nbytes = 0;
+  wc_key = g_utf8_to_utf16 (subdir, -1, NULL, NULL, NULL);
+  if (RegOpenKeyExW (HKEY_CLASSES_ROOT, wc_key, 0,
+                     KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS &&
+      RegQueryValueExW (reg_key, key_name, 0,
+                        &key_type, NULL, &nbytes) == ERROR_SUCCESS &&
+      (key_type == REG_SZ || key_type == REG_EXPAND_SZ))
+    {
+      wchar_t *wc_temp = g_new (wchar_t, (nbytes+1)/2 + 1);
+      RegQueryValueExW (reg_key, key_name, 0,
+                        &key_type, (LPBYTE) wc_temp, &nbytes);
+      wc_temp[nbytes/2] = '\0';
+      if (key_type == REG_EXPAND_SZ)
+        {
+          wchar_t dummy[1];
+          int len = ExpandEnvironmentStringsW (wc_temp, dummy, 1);
+          if (len > 0)
+            {
+              wchar_t *wc_temp_expanded = g_new (wchar_t, len);
+              if (ExpandEnvironmentStringsW (wc_temp, wc_temp_expanded, len) == len)
+                value_utf8 = g_utf16_to_utf8 (wc_temp_expanded, -1, NULL, NULL, NULL);
+              g_free (wc_temp_expanded);
+            }
+        }
+      else
+        {
+          value_utf8 = g_utf16_to_utf8 (wc_temp, -1, NULL, NULL, NULL);
+        }
+      g_free (wc_temp);
+      
+    }
+  g_free (wc_key);
+  
+  if (reg_key != NULL)
+    RegCloseKey (reg_key);
+
+  return value_utf8;
+}
+
+/*< private >*/
+void
+g_content_type_set_mime_dirs (const gchar * const *dirs)
+{
+  /* noop on Windows */
+}
+
+/*< private >*/
+const gchar * const *
+g_content_type_get_mime_dirs (void)
+{
+  const gchar * const *mime_dirs = { NULL };
+  return mime_dirs;
+}
+
+gboolean
+g_content_type_equals (const gchar *type1,
+                       const gchar *type2)
+{
+  char *progid1, *progid2;
+  gboolean res;
+  
+  g_return_val_if_fail (type1 != NULL, FALSE);
+  g_return_val_if_fail (type2 != NULL, FALSE);
+
+  if (g_ascii_strcasecmp (type1, type2) == 0)
+    return TRUE;
+
+  res = FALSE;
+  progid1 = get_registry_classes_key (type1, NULL);
+  progid2 = get_registry_classes_key (type2, NULL);
+  if (progid1 != NULL && progid2 != NULL &&
+      strcmp (progid1, progid2) == 0)
+    res = TRUE;
+  g_free (progid1);
+  g_free (progid2);
+  
+  return res;
+}
+
+gboolean
+g_content_type_is_a (const gchar *type,
+                     const gchar *supertype)
+{
+  gboolean res;
+  char *value_utf8;
+
+  g_return_val_if_fail (type != NULL, FALSE);
+  g_return_val_if_fail (supertype != NULL, FALSE);
+
+  if (g_content_type_equals (type, supertype))
+    return TRUE;
+
+  res = FALSE;
+  value_utf8 = get_registry_classes_key (type, L"PerceivedType");
+  if (value_utf8 && strcmp (value_utf8, supertype) == 0)
+    res = TRUE;
+  g_free (value_utf8);
+  
+  return res;
+}
+
+gboolean
+g_content_type_is_mime_type (const gchar *type,
+                             const gchar *mime_type)
+{
+  gchar *content_type;
+  gboolean ret;
+
+  g_return_val_if_fail (type != NULL, FALSE);
+  g_return_val_if_fail (mime_type != NULL, FALSE);
+
+  content_type = g_content_type_from_mime_type (mime_type);
+  ret = g_content_type_is_a (type, content_type);
+  g_free (content_type);
+
+  return ret;
+}
+
+gboolean
+g_content_type_is_unknown (const gchar *type)
+{
+  g_return_val_if_fail (type != NULL, FALSE);
+
+  return strcmp ("*", type) == 0;
+}
+
+gchar *
+g_content_type_get_description (const gchar *type)
+{
+  char *progid;
+  char *description;
+
+  g_return_val_if_fail (type != NULL, NULL);
+
+  progid = get_registry_classes_key (type, NULL);
+  if (progid)
+    {
+      description = get_registry_classes_key (progid, NULL);
+      g_free (progid);
+
+      if (description)
+        return description;
+    }
+
+  if (g_content_type_is_unknown (type))
+    return g_strdup (_("Unknown type"));
+
+  return g_strdup_printf (_("%s filetype"), type);
+}
+
+gchar *
+g_content_type_get_mime_type (const gchar *type)
+{
+  char *mime;
+
+  g_return_val_if_fail (type != NULL, NULL);
+
+  mime = get_registry_classes_key (type, L"Content Type");
+  if (mime)
+    return mime;
+  else if (g_content_type_is_unknown (type))
+    return g_strdup ("application/octet-stream");
+  else if (*type == '.')
+    return g_strdup_printf ("application/x-ext-%s", type+1);
+  else if (strcmp ("inode/directory", type) == 0)
+    return g_strdup (type);
+  /* TODO: Map "image" to "image/ *", etc? */
+
+  return g_strdup ("application/octet-stream");
+}
+
+G_LOCK_DEFINE_STATIC (_type_icons);
+static GHashTable *_type_icons = NULL;
+
+GIcon *
+g_content_type_get_icon (const gchar *type)
+{
+  GIcon *themed_icon;
+  char *name = NULL;
+
+  g_return_val_if_fail (type != NULL, NULL);
+
+  /* In the Registry icons are the default value of
+     HKEY_CLASSES_ROOT\<progid>\DefaultIcon with typical values like:
+     <type>: <value>
+     REG_EXPAND_SZ: %SystemRoot%\System32\Wscript.exe,3
+     REG_SZ: shimgvw.dll,3
+  */
+  G_LOCK (_type_icons);
+  if (!_type_icons)
+    _type_icons = g_hash_table_new (g_str_hash, g_str_equal);
+  name = g_hash_table_lookup (_type_icons, type);
+  if (!name && type[0] == '.')
+    {
+      /* double lookup by extension */
+      gchar *key = get_registry_classes_key (type, NULL);
+      if (!key)
+        key = g_strconcat (type+1, "file\\DefaultIcon", NULL);
+      else
+        {
+          gchar *key2 = g_strconcat (key, "\\DefaultIcon", NULL);
+          g_free (key);
+          key = key2;
+        }
+      name = get_registry_classes_key (key, NULL);
+      if (name && strcmp (name, "%1") == 0)
+        {
+          g_free (name);
+          name = NULL;
+        }
+      if (name)
+        g_hash_table_insert (_type_icons, g_strdup (type), g_strdup (name));
+      g_free (key);
+    }
+
+  if (!name)
+    {
+      /* if no icon found, fall back to standard generic names */
+      if (strcmp (type, "inode/directory") == 0)
+        name = "folder";
+      else if (g_content_type_can_be_executable (type))
+        name = "system-run";
+      else
+        name = "text-x-generic";
+      g_hash_table_insert (_type_icons, g_strdup (type), g_strdup (name));
+    }
+  themed_icon = g_themed_icon_new (name);
+  G_UNLOCK (_type_icons);
+
+  return G_ICON (themed_icon);
+}
+
+GIcon *
+g_content_type_get_symbolic_icon (const gchar *type)
+{
+  return g_content_type_get_icon (type);
+}
+
+gchar *
+g_content_type_get_generic_icon_name (const gchar *type)
+{
+  return NULL;
+}
+
+gboolean
+g_content_type_can_be_executable (const gchar *type)
+{
+  g_return_val_if_fail (type != NULL, FALSE);
+
+  if (strcmp (type, ".exe") == 0 ||
+      strcmp (type, ".com") == 0 ||
+      strcmp (type, ".bat") == 0)
+    return TRUE;
+
+  /* TODO: Also look at PATHEXT, which lists the extensions for
+   * "scripts" in addition to those for true binary executables.
+   *
+   * (PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH for me
+   * right now, for instance). And in a sense, all associated file
+   * types are "executable" on Windows... You can just type foo.jpg as
+   * a command name in cmd.exe, and it will run the application
+   * associated with .jpg. Hard to say what this API actually means
+   * with "executable".
+   */
+
+  return FALSE;
+}
+
+static gboolean
+looks_like_text (const guchar *data, 
+                 gsize         data_size)
+{
+  gsize i;
+  guchar c;
+  for (i = 0; i < data_size; i++)
+    {
+      c = data[i];
+      if (g_ascii_iscntrl (c) && !g_ascii_isspace (c) && c != '\b')
+        return FALSE;
+    }
+  return TRUE;
+}
+
+gchar *
+g_content_type_from_mime_type (const gchar *mime_type)
+{
+  char *key, *content_type;
+
+  g_return_val_if_fail (mime_type != NULL, NULL);
+
+  /* This is a hack to allow directories to have icons in filechooser */
+  if (strcmp ("inode/directory", mime_type) == 0)
+    return g_strdup (mime_type);
+
+  key = g_strconcat ("MIME\\DataBase\\Content Type\\", mime_type, NULL);
+  content_type = get_registry_classes_key (key, L"Extension");
+  g_free (key);
+
+  return content_type;
+}
+
+gchar *
+g_content_type_guess (const gchar  *filename,
+                      const guchar *data,
+                      gsize         data_size,
+                      gboolean     *result_uncertain)
+{
+  char *basename;
+  char *type;
+  char *dot;
+
+  type = NULL;
+
+  if (result_uncertain)
+    *result_uncertain = FALSE;
+
+  /* our test suite and potentially other code used -1 in the past, which is
+   * not documented and not allowed; guard against that */
+  g_return_val_if_fail (data_size != (gsize) -1, g_strdup ("*"));
+
+  if (filename)
+    {
+      basename = g_path_get_basename (filename);
+      dot = strrchr (basename, '.');
+      if (dot)
+        type = g_strdup (dot);
+      g_free (basename);
+    }
+
+  if (type)
+    return type;
+
+  if (data && looks_like_text (data, data_size))
+    return g_strdup (".txt");
+
+  return g_strdup ("*");
+}
+
+GList *
+g_content_types_get_registered (void)
+{
+  DWORD index;
+  wchar_t keyname[256];
+  DWORD key_len;
+  char *key_utf8;
+  GList *types;
+
+  types = NULL;
+  index = 0;
+  key_len = 256;
+  while (RegEnumKeyExW(HKEY_CLASSES_ROOT,
+                       index,
+                       keyname,
+                       &key_len,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL) == ERROR_SUCCESS)
+    {
+      key_utf8 = g_utf16_to_utf8 (keyname, -1, NULL, NULL, NULL);
+      if (key_utf8)
+        {
+          if (*key_utf8 == '.')
+            types = g_list_prepend (types, key_utf8);
+          else
+            g_free (key_utf8);
+        }
+      index++;
+      key_len = 256;
+    }
+  
+  return g_list_reverse (types);
+}
+
+gchar **
+g_content_type_guess_for_tree (GFile *root)
+{
+  /* FIXME: implement */
+  return NULL;
+}
diff --git a/gio/gcontenttype.c b/gio/gcontenttype.c
new file mode 100644
index 0000000..2716c89
--- /dev/null
+++ b/gio/gcontenttype.c
@@ -0,0 +1,1526 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gcontenttypeprivate.h"
+#include "gthemedicon.h"
+#include "gicon.h"
+#include "gfile.h"
+#include "gfileenumerator.h"
+#include "gfileinfo.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gcontenttype
+ * @short_description: Platform-specific content typing
+ * @include: gio/gio.h
+ *
+ * A content type is a platform specific string that defines the type
+ * of a file. On UNIX it is a
+ * [MIME type](http://www.wikipedia.org/wiki/Internet_media_type)
+ * like `text/plain` or `image/png`.
+ * On Win32 it is an extension string like `.doc`, `.txt` or a perceived
+ * string like `audio`. Such strings can be looked up in the registry at
+ * `HKEY_CLASSES_ROOT`.
+ * On macOS it is a [Uniform Type Identifier](https://en.wikipedia.org/wiki/Uniform_Type_Identifier)
+ * such as `com.apple.application`.
+ **/
+
+#include <dirent.h>
+
+#define XDG_PREFIX _gio_xdg
+#include "xdgmime/xdgmime.h"
+
+static void tree_magic_schedule_reload (void);
+
+/* We lock this mutex whenever we modify global state in this module.  */
+G_LOCK_DEFINE_STATIC (gio_xdgmime);
+
+gsize
+_g_unix_content_type_get_sniff_len (void)
+{
+  gsize size;
+
+  G_LOCK (gio_xdgmime);
+  size = xdg_mime_get_max_buffer_extents ();
+  G_UNLOCK (gio_xdgmime);
+
+  return size;
+}
+
+gchar *
+_g_unix_content_type_unalias (const gchar *type)
+{
+  gchar *res;
+
+  G_LOCK (gio_xdgmime);
+  res = g_strdup (xdg_mime_unalias_mime_type (type));
+  G_UNLOCK (gio_xdgmime);
+
+  return res;
+}
+
+gchar **
+_g_unix_content_type_get_parents (const gchar *type)
+{
+  const gchar *umime;
+  gchar **parents;
+  GPtrArray *array;
+  int i;
+
+  array = g_ptr_array_new ();
+
+  G_LOCK (gio_xdgmime);
+
+  umime = xdg_mime_unalias_mime_type (type);
+
+  g_ptr_array_add (array, g_strdup (umime));
+
+  parents = xdg_mime_list_mime_parents (umime);
+  for (i = 0; parents && parents[i] != NULL; i++)
+    g_ptr_array_add (array, g_strdup (parents[i]));
+
+  free (parents);
+
+  G_UNLOCK (gio_xdgmime);
+
+  g_ptr_array_add (array, NULL);
+
+  return (gchar **)g_ptr_array_free (array, FALSE);
+}
+
+G_LOCK_DEFINE_STATIC (global_mime_dirs);
+static gchar **global_mime_dirs = NULL;
+
+static void
+_g_content_type_set_mime_dirs_locked (const char * const *dirs)
+{
+  g_clear_pointer (&global_mime_dirs, g_strfreev);
+
+  if (dirs != NULL)
+    {
+      global_mime_dirs = g_strdupv ((gchar **) dirs);
+    }
+  else
+    {
+      GPtrArray *mime_dirs = g_ptr_array_new_with_free_func (g_free);
+      const gchar * const *system_dirs = g_get_system_data_dirs ();
+
+      g_ptr_array_add (mime_dirs, g_build_filename (g_get_user_data_dir (), "mime", NULL));
+      for (; *system_dirs != NULL; system_dirs++)
+        g_ptr_array_add (mime_dirs, g_build_filename (*system_dirs, "mime", NULL));
+      g_ptr_array_add (mime_dirs, NULL);  /* NULL terminator */
+
+      global_mime_dirs = (gchar **) g_ptr_array_free (mime_dirs, FALSE);
+    }
+
+  xdg_mime_set_dirs ((const gchar * const *) global_mime_dirs);
+  tree_magic_schedule_reload ();
+}
+
+/**
+ * g_content_type_set_mime_dirs:
+ * @dirs: (array zero-terminated=1) (nullable): %NULL-terminated list of
+ *    directories to load MIME data from, including any `mime/` subdirectory,
+ *    and with the first directory to try listed first
+ *
+ * Set the list of directories used by GIO to load the MIME database.
+ * If @dirs is %NULL, the directories used are the default:
+ *
+ *  - the `mime` subdirectory of the directory in `$XDG_DATA_HOME`
+ *  - the `mime` subdirectory of every directory in `$XDG_DATA_DIRS`
+ *
+ * This function is intended to be used when writing tests that depend on
+ * information stored in the MIME database, in order to control the data.
+ *
+ * Typically, in case your tests use %G_TEST_OPTION_ISOLATE_DIRS, but they
+ * depend on the system’s MIME database, you should call this function
+ * with @dirs set to %NULL before calling g_test_init(), for instance:
+ *
+ * |[<!-- language="C" -->
+ *   // Load MIME data from the system
+ *   g_content_type_set_mime_dirs (NULL);
+ *   // Isolate the environment
+ *   g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
+ *
+ *   …
+ *
+ *   return g_test_run ();
+ * ]|
+ *
+ * Since: 2.60
+ */
+/*< private >*/
+void
+g_content_type_set_mime_dirs (const gchar * const *dirs)
+{
+  G_LOCK (global_mime_dirs);
+  _g_content_type_set_mime_dirs_locked (dirs);
+  G_UNLOCK (global_mime_dirs);
+}
+
+/**
+ * g_content_type_get_mime_dirs:
+ *
+ * Get the list of directories which MIME data is loaded from. See
+ * g_content_type_set_mime_dirs() for details.
+ *
+ * Returns: (transfer none) (array zero-terminated=1): %NULL-terminated list of
+ *    directories to load MIME data from, including any `mime/` subdirectory,
+ *    and with the first directory to try listed first
+ * Since: 2.60
+ */
+/*< private >*/
+const gchar * const *
+g_content_type_get_mime_dirs (void)
+{
+  const gchar * const *mime_dirs;
+
+  G_LOCK (global_mime_dirs);
+
+  if (global_mime_dirs == NULL)
+    _g_content_type_set_mime_dirs_locked (NULL);
+
+  mime_dirs = (const gchar * const *) global_mime_dirs;
+
+  G_UNLOCK (global_mime_dirs);
+
+  g_assert (mime_dirs != NULL);
+  return mime_dirs;
+}
+
+/**
+ * g_content_type_equals:
+ * @type1: a content type string
+ * @type2: a content type string
+ *
+ * Compares two content types for equality.
+ *
+ * Returns: %TRUE if the two strings are identical or equivalent,
+ *     %FALSE otherwise.
+ */
+gboolean
+g_content_type_equals (const gchar *type1,
+                       const gchar *type2)
+{
+  gboolean res;
+
+  g_return_val_if_fail (type1 != NULL, FALSE);
+  g_return_val_if_fail (type2 != NULL, FALSE);
+
+  G_LOCK (gio_xdgmime);
+  res = xdg_mime_mime_type_equal (type1, type2);
+  G_UNLOCK (gio_xdgmime);
+
+  return res;
+}
+
+/**
+ * g_content_type_is_a:
+ * @type: a content type string
+ * @supertype: a content type string
+ *
+ * Determines if @type is a subset of @supertype.
+ *
+ * Returns: %TRUE if @type is a kind of @supertype,
+ *     %FALSE otherwise.
+ */
+gboolean
+g_content_type_is_a (const gchar *type,
+                     const gchar *supertype)
+{
+  gboolean res;
+
+  g_return_val_if_fail (type != NULL, FALSE);
+  g_return_val_if_fail (supertype != NULL, FALSE);
+
+  G_LOCK (gio_xdgmime);
+  res = xdg_mime_mime_type_subclass (type, supertype);
+  G_UNLOCK (gio_xdgmime);
+
+  return res;
+}
+
+/**
+ * g_content_type_is_mime_type:
+ * @type: a content type string
+ * @mime_type: a mime type string
+ *
+ * Determines if @type is a subset of @mime_type.
+ * Convenience wrapper around g_content_type_is_a().
+ *
+ * Returns: %TRUE if @type is a kind of @mime_type,
+ *     %FALSE otherwise.
+ *
+ * Since: 2.52
+ */
+gboolean
+g_content_type_is_mime_type (const gchar *type,
+                             const gchar *mime_type)
+{
+  return g_content_type_is_a (type, mime_type);
+}
+
+/**
+ * g_content_type_is_unknown:
+ * @type: a content type string
+ *
+ * Checks if the content type is the generic "unknown" type.
+ * On UNIX this is the "application/octet-stream" mimetype,
+ * while on win32 it is "*" and on OSX it is a dynamic type
+ * or octet-stream.
+ *
+ * Returns: %TRUE if the type is the unknown type.
+ */
+gboolean
+g_content_type_is_unknown (const gchar *type)
+{
+  g_return_val_if_fail (type != NULL, FALSE);
+
+  return strcmp (XDG_MIME_TYPE_UNKNOWN, type) == 0;
+}
+
+
+typedef enum {
+  MIME_TAG_TYPE_OTHER,
+  MIME_TAG_TYPE_COMMENT
+} MimeTagType;
+
+typedef struct {
+  int current_type;
+  int current_lang_level;
+  int comment_lang_level;
+  char *comment;
+} MimeParser;
+
+
+static int
+language_level (const char *lang)
+{
+  const char * const *lang_list;
+  int i;
+
+  /* The returned list is sorted from most desirable to least
+     desirable and always contains the default locale "C". */
+  lang_list = g_get_language_names ();
+
+  for (i = 0; lang_list[i]; i++)
+    if (strcmp (lang_list[i], lang) == 0)
+      return 1000-i;
+
+  return 0;
+}
+
+static void
+mime_info_start_element (GMarkupParseContext  *context,
+                         const gchar          *element_name,
+                         const gchar         **attribute_names,
+                         const gchar         **attribute_values,
+                         gpointer              user_data,
+                         GError              **error)
+{
+  int i;
+  const char *lang;
+  MimeParser *parser = user_data;
+
+  if (strcmp (element_name, "comment") == 0)
+    {
+      lang = "C";
+      for (i = 0; attribute_names[i]; i++)
+        if (strcmp (attribute_names[i], "xml:lang") == 0)
+          {
+            lang = attribute_values[i];
+            break;
+          }
+
+      parser->current_lang_level = language_level (lang);
+      parser->current_type = MIME_TAG_TYPE_COMMENT;
+    }
+  else
+    parser->current_type = MIME_TAG_TYPE_OTHER;
+}
+
+static void
+mime_info_end_element (GMarkupParseContext  *context,
+                       const gchar          *element_name,
+                       gpointer              user_data,
+                       GError              **error)
+{
+  MimeParser *parser = user_data;
+
+  parser->current_type = MIME_TAG_TYPE_OTHER;
+}
+
+static void
+mime_info_text (GMarkupParseContext  *context,
+                const gchar          *text,
+                gsize                 text_len,
+                gpointer              user_data,
+                GError              **error)
+{
+  MimeParser *parser = user_data;
+
+  if (parser->current_type == MIME_TAG_TYPE_COMMENT &&
+      parser->current_lang_level > parser->comment_lang_level)
+    {
+      g_free (parser->comment);
+      parser->comment = g_strndup (text, text_len);
+      parser->comment_lang_level = parser->current_lang_level;
+    }
+}
+
+static char *
+load_comment_for_mime_helper (const char *dir,
+                              const char *basename)
+{
+  GMarkupParseContext *context;
+  char *filename, *data;
+  gsize len;
+  gboolean res;
+  MimeParser parse_data = {0};
+  GMarkupParser parser = {
+    mime_info_start_element,
+    mime_info_end_element,
+    mime_info_text
+  };
+
+  filename = g_build_filename (dir, basename, NULL);
+
+  res = g_file_get_contents (filename,  &data,  &len,  NULL);
+  g_free (filename);
+  if (!res)
+    return NULL;
+
+  context = g_markup_parse_context_new   (&parser, 0, &parse_data, NULL);
+  res = g_markup_parse_context_parse (context, data, len, NULL);
+  g_free (data);
+  g_markup_parse_context_free (context);
+
+  if (!res)
+    return NULL;
+
+  return parse_data.comment;
+}
+
+
+static char *
+load_comment_for_mime (const char *mimetype)
+{
+  const char * const *dirs;
+  char *basename;
+  char *comment;
+  gsize i;
+
+  basename = g_strdup_printf ("%s.xml", mimetype);
+
+  dirs = g_content_type_get_mime_dirs ();
+  for (i = 0; dirs[i] != NULL; i++)
+    {
+      comment = load_comment_for_mime_helper (dirs[i], basename);
+      if (comment)
+        {
+          g_free (basename);
+          return comment;
+        }
+    }
+  g_free (basename);
+
+  return g_strdup_printf (_("%s type"), mimetype);
+}
+
+/**
+ * g_content_type_get_description:
+ * @type: a content type string
+ *
+ * Gets the human readable description of the content type.
+ *
+ * Returns: a short description of the content type @type. Free the
+ *     returned string with g_free()
+ */
+gchar *
+g_content_type_get_description (const gchar *type)
+{
+  static GHashTable *type_comment_cache = NULL;
+  gchar *comment;
+
+  g_return_val_if_fail (type != NULL, NULL);
+
+  G_LOCK (gio_xdgmime);
+  type = xdg_mime_unalias_mime_type (type);
+
+  if (type_comment_cache == NULL)
+    type_comment_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+  comment = g_hash_table_lookup (type_comment_cache, type);
+  comment = g_strdup (comment);
+  G_UNLOCK (gio_xdgmime);
+
+  if (comment != NULL)
+    return comment;
+
+  comment = load_comment_for_mime (type);
+
+  G_LOCK (gio_xdgmime);
+  g_hash_table_insert (type_comment_cache,
+                       g_strdup (type),
+                       g_strdup (comment));
+  G_UNLOCK (gio_xdgmime);
+
+  return comment;
+}
+
+/**
+ * g_content_type_get_mime_type:
+ * @type: a content type string
+ *
+ * Gets the mime type for the content type, if one is registered.
+ *
+ * Returns: (nullable) (transfer full): the registered mime type for the
+ *     given @type, or %NULL if unknown; free with g_free().
+ */
+char *
+g_content_type_get_mime_type (const char *type)
+{
+  g_return_val_if_fail (type != NULL, NULL);
+
+  return g_strdup (type);
+}
+
+static GIcon *
+g_content_type_get_icon_internal (const gchar *type,
+                                  gboolean     symbolic)
+{
+  char *mimetype_icon;
+  char *generic_mimetype_icon = NULL;
+  char *q;
+  char *icon_names[6];
+  int n = 0;
+  GIcon *themed_icon;
+  const char  *xdg_icon;
+  int i;
+
+  g_return_val_if_fail (type != NULL, NULL);
+
+  G_LOCK (gio_xdgmime);
+  xdg_icon = xdg_mime_get_icon (type);
+  G_UNLOCK (gio_xdgmime);
+
+  if (xdg_icon)
+    icon_names[n++] = g_strdup (xdg_icon);
+
+  mimetype_icon = g_strdup (type);
+  while ((q = strchr (mimetype_icon, '/')) != NULL)
+    *q = '-';
+
+  icon_names[n++] = mimetype_icon;
+
+  generic_mimetype_icon = g_content_type_get_generic_icon_name (type);
+  if (generic_mimetype_icon)
+    icon_names[n++] = generic_mimetype_icon;
+
+  if (symbolic)
+    {
+      for (i = 0; i < n; i++)
+        {
+          icon_names[n + i] = icon_names[i];
+          icon_names[i] = g_strconcat (icon_names[i], "-symbolic", NULL);
+        }
+
+      n += n;
+    }
+
+  themed_icon = g_themed_icon_new_from_names (icon_names, n);
+
+  for (i = 0; i < n; i++)
+    g_free (icon_names[i]);
+
+  return themed_icon;
+}
+
+/**
+ * g_content_type_get_icon:
+ * @type: a content type string
+ *
+ * Gets the icon for a content type.
+ *
+ * Returns: (transfer full): #GIcon corresponding to the content type. Free the returned
+ *     object with g_object_unref()
+ */
+GIcon *
+g_content_type_get_icon (const gchar *type)
+{
+  return g_content_type_get_icon_internal (type, FALSE);
+}
+
+/**
+ * g_content_type_get_symbolic_icon:
+ * @type: a content type string
+ *
+ * Gets the symbolic icon for a content type.
+ *
+ * Returns: (transfer full): symbolic #GIcon corresponding to the content type.
+ *     Free the returned object with g_object_unref()
+ *
+ * Since: 2.34
+ */
+GIcon *
+g_content_type_get_symbolic_icon (const gchar *type)
+{
+  return g_content_type_get_icon_internal (type, TRUE);
+}
+
+/**
+ * g_content_type_get_generic_icon_name:
+ * @type: a content type string
+ *
+ * Gets the generic icon name for a content type.
+ *
+ * See the
+ * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec)
+ * specification for more on the generic icon name.
+ *
+ * Returns: (nullable): the registered generic icon name for the given @type,
+ *     or %NULL if unknown. Free with g_free()
+ *
+ * Since: 2.34
+ */
+gchar *
+g_content_type_get_generic_icon_name (const gchar *type)
+{
+  const gchar *xdg_icon_name;
+  gchar *icon_name;
+
+  g_return_val_if_fail (type != NULL, NULL);
+
+  G_LOCK (gio_xdgmime);
+  xdg_icon_name = xdg_mime_get_generic_icon (type);
+  G_UNLOCK (gio_xdgmime);
+
+  if (!xdg_icon_name)
+    {
+      const char *p;
+      const char *suffix = "-x-generic";
+
+      p = strchr (type, '/');
+      if (p == NULL)
+        p = type + strlen (type);
+
+      icon_name = g_malloc (p - type + strlen (suffix) + 1);
+      memcpy (icon_name, type, p - type);
+      memcpy (icon_name + (p - type), suffix, strlen (suffix));
+      icon_name[(p - type) + strlen (suffix)] = 0;
+    }
+  else
+    {
+      icon_name = g_strdup (xdg_icon_name);
+    }
+
+  return icon_name;
+}
+
+/**
+ * g_content_type_can_be_executable:
+ * @type: a content type string
+ *
+ * Checks if a content type can be executable. Note that for instance
+ * things like text files can be executables (i.e. scripts and batch files).
+ *
+ * Returns: %TRUE if the file type corresponds to a type that
+ *     can be executable, %FALSE otherwise.
+ */
+gboolean
+g_content_type_can_be_executable (const gchar *type)
+{
+  g_return_val_if_fail (type != NULL, FALSE);
+
+  if (g_content_type_is_a (type, "application/x-executable")  ||
+      g_content_type_is_a (type, "text/plain"))
+    return TRUE;
+
+  return FALSE;
+}
+
+static gboolean
+looks_like_text (const guchar *data, gsize data_size)
+{
+  gsize i;
+  char c;
+
+  for (i = 0; i < data_size; i++)
+    {
+      c = data[i];
+
+      if (g_ascii_iscntrl (c) &&
+          !g_ascii_isspace (c) &&
+          c != '\b')
+        return FALSE;
+    }
+  return TRUE;
+}
+
+/**
+ * g_content_type_from_mime_type:
+ * @mime_type: a mime type string
+ *
+ * Tries to find a content type based on the mime type name.
+ *
+ * Returns: (nullable): Newly allocated string with content type or
+ *     %NULL. Free with g_free()
+ *
+ * Since: 2.18
+ **/
+gchar *
+g_content_type_from_mime_type (const gchar *mime_type)
+{
+  char *umime;
+
+  g_return_val_if_fail (mime_type != NULL, NULL);
+
+  G_LOCK (gio_xdgmime);
+  /* mime type and content type are same on unixes */
+  umime = g_strdup (xdg_mime_unalias_mime_type (mime_type));
+  G_UNLOCK (gio_xdgmime);
+
+  return umime;
+}
+
+/**
+ * g_content_type_guess:
+ * @filename: (nullable): a string, or %NULL
+ * @data: (nullable) (array length=data_size): a stream of data, or %NULL
+ * @data_size: the size of @data
+ * @result_uncertain: (out) (optional): return location for the certainty
+ *     of the result, or %NULL
+ *
+ * Guesses the content type based on example data. If the function is
+ * uncertain, @result_uncertain will be set to %TRUE. Either @filename
+ * or @data may be %NULL, in which case the guess will be based solely
+ * on the other argument.
+ *
+ * Returns: a string indicating a guessed content type for the
+ *     given data. Free with g_free()
+ */
+gchar *
+g_content_type_guess (const gchar  *filename,
+                      const guchar *data,
+                      gsize         data_size,
+                      gboolean     *result_uncertain)
+{
+  char *basename;
+  const char *name_mimetypes[10], *sniffed_mimetype;
+  char *mimetype;
+  int i;
+  int n_name_mimetypes;
+  int sniffed_prio;
+
+  sniffed_prio = 0;
+  n_name_mimetypes = 0;
+  sniffed_mimetype = XDG_MIME_TYPE_UNKNOWN;
+
+  if (result_uncertain)
+    *result_uncertain = FALSE;
+
+  /* our test suite and potentially other code used -1 in the past, which is
+   * not documented and not allowed; guard against that */
+  g_return_val_if_fail (data_size != (gsize) -1, g_strdup (XDG_MIME_TYPE_UNKNOWN));
+
+  G_LOCK (gio_xdgmime);
+
+  if (filename)
+    {
+      i = strlen (filename);
+      if (filename[i - 1] == '/')
+        {
+          name_mimetypes[0] = "inode/directory";
+          name_mimetypes[1] = NULL;
+          n_name_mimetypes = 1;
+          if (result_uncertain)
+            *result_uncertain = TRUE;
+        }
+      else
+        {
+          basename = g_path_get_basename (filename);
+          n_name_mimetypes = xdg_mime_get_mime_types_from_file_name (basename, name_mimetypes, 10);
+          g_free (basename);
+        }
+    }
+
+  /* Got an extension match, and no conflicts. This is it. */
+  if (n_name_mimetypes == 1)
+    {
+      gchar *s = g_strdup (name_mimetypes[0]);
+      G_UNLOCK (gio_xdgmime);
+      return s;
+    }
+
+  if (data)
+    {
+      sniffed_mimetype = xdg_mime_get_mime_type_for_data (data, data_size, &sniffed_prio);
+      if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN &&
+          data &&
+          looks_like_text (data, data_size))
+        sniffed_mimetype = "text/plain";
+
+      /* For security reasons we don't ever want to sniff desktop files
+       * where we know the filename and it doesn't have a .desktop extension.
+       * This is because desktop files allow executing any application and
+       * we don't want to make it possible to hide them looking like something
+       * else.
+       */
+      if (filename != NULL &&
+          strcmp (sniffed_mimetype, "application/x-desktop") == 0)
+        sniffed_mimetype = "text/plain";
+    }
+
+  if (n_name_mimetypes == 0)
+    {
+      if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN &&
+          result_uncertain)
+        *result_uncertain = TRUE;
+
+      mimetype = g_strdup (sniffed_mimetype);
+    }
+  else
+    {
+      mimetype = NULL;
+      if (sniffed_mimetype != XDG_MIME_TYPE_UNKNOWN)
+        {
+          if (sniffed_prio >= 80) /* High priority sniffing match, use that */
+            mimetype = g_strdup (sniffed_mimetype);
+          else
+            {
+              /* There are conflicts between the name matches and we
+               * have a sniffed type, use that as a tie breaker.
+               */
+              for (i = 0; i < n_name_mimetypes; i++)
+                {
+                  if ( xdg_mime_mime_type_subclass (name_mimetypes[i], sniffed_mimetype))
+                    {
+                      /* This nametype match is derived from (or the same as)
+                       * the sniffed type). This is probably it.
+                       */
+                      mimetype = g_strdup (name_mimetypes[i]);
+                      break;
+                    }
+                }
+            }
+        }
+
+      if (mimetype == NULL)
+        {
+          /* Conflicts, and sniffed type was no help or not there.
+           * Guess on the first one
+           */
+          mimetype = g_strdup (name_mimetypes[0]);
+          if (result_uncertain)
+            *result_uncertain = TRUE;
+        }
+    }
+
+  G_UNLOCK (gio_xdgmime);
+
+  return mimetype;
+}
+
+static void
+enumerate_mimetypes_subdir (const char *dir,
+                            const char *prefix,
+                            GHashTable *mimetypes)
+{
+  DIR *d;
+  struct dirent *ent;
+  char *mimetype;
+
+  d = opendir (dir);
+  if (d)
+    {
+      while ((ent = readdir (d)) != NULL)
+        {
+          if (g_str_has_suffix (ent->d_name, ".xml"))
+            {
+              mimetype = g_strdup_printf ("%s/%.*s", prefix, (int) strlen (ent->d_name) - 4, ent->d_name);
+              g_hash_table_replace (mimetypes, mimetype, NULL);
+            }
+        }
+      closedir (d);
+    }
+}
+
+static void
+enumerate_mimetypes_dir (const char *dir,
+                         GHashTable *mimetypes)
+{
+  DIR *d;
+  struct dirent *ent;
+  const char *mimedir;
+  char *name;
+
+  mimedir = dir;
+
+  d = opendir (mimedir);
+  if (d)
+    {
+      while ((ent = readdir (d)) != NULL)
+        {
+          if (strcmp (ent->d_name, "packages") != 0)
+            {
+              name = g_build_filename (mimedir, ent->d_name, NULL);
+              if (g_file_test (name, G_FILE_TEST_IS_DIR))
+                enumerate_mimetypes_subdir (name, ent->d_name, mimetypes);
+              g_free (name);
+            }
+        }
+      closedir (d);
+    }
+}
+
+/**
+ * g_content_types_get_registered:
+ *
+ * Gets a list of strings containing all the registered content types
+ * known to the system. The list and its data should be freed using
+ * `g_list_free_full (list, g_free)`.
+ *
+ * Returns: (element-type utf8) (transfer full): list of the registered
+ *     content types
+ */
+GList *
+g_content_types_get_registered (void)
+{
+  const char * const *dirs;
+  GHashTable *mimetypes;
+  GHashTableIter iter;
+  gpointer key;
+  gsize i;
+  GList *l;
+
+  mimetypes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+  dirs = g_content_type_get_mime_dirs ();
+  for (i = 0; dirs[i] != NULL; i++)
+    enumerate_mimetypes_dir (dirs[i], mimetypes);
+
+  l = NULL;
+  g_hash_table_iter_init (&iter, mimetypes);
+  while (g_hash_table_iter_next (&iter, &key, NULL))
+    {
+      l = g_list_prepend (l, key);
+      g_hash_table_iter_steal (&iter);
+    }
+
+  g_hash_table_destroy (mimetypes);
+
+  return l;
+}
+
+
+/* tree magic data */
+static GList *tree_matches = NULL;
+static gboolean need_reload = FALSE;
+
+G_LOCK_DEFINE_STATIC (gio_treemagic);
+
+typedef struct
+{
+  gchar *path;
+  GFileType type;
+  guint match_case : 1;
+  guint executable : 1;
+  guint non_empty  : 1;
+  guint on_disc    : 1;
+  gchar *mimetype;
+  GList *matches;
+} TreeMatchlet;
+
+typedef struct
+{
+  gchar *contenttype;
+  gint priority;
+  GList *matches;
+} TreeMatch;
+
+
+static void
+tree_matchlet_free (TreeMatchlet *matchlet)
+{
+  g_list_free_full (matchlet->matches, (GDestroyNotify) tree_matchlet_free);
+  g_free (matchlet->path);
+  g_free (matchlet->mimetype);
+  g_slice_free (TreeMatchlet, matchlet);
+}
+
+static void
+tree_match_free (TreeMatch *match)
+{
+  g_list_free_full (match->matches, (GDestroyNotify) tree_matchlet_free);
+  g_free (match->contenttype);
+  g_slice_free (TreeMatch, match);
+}
+
+static TreeMatch *
+parse_header (gchar *line)
+{
+  gint len;
+  gchar *s;
+  TreeMatch *match;
+
+  len = strlen (line);
+
+  if (line[0] != '[' || line[len - 1] != ']')
+    return NULL;
+
+  line[len - 1] = 0;
+  s = strchr (line, ':');
+
+  match = g_slice_new0 (TreeMatch);
+  match->priority = atoi (line + 1);
+  match->contenttype = g_strdup (s + 1);
+
+  return match;
+}
+
+static TreeMatchlet *
+parse_match_line (gchar *line,
+                  gint  *depth)
+{
+  gchar *s, *p;
+  TreeMatchlet *matchlet;
+  gchar **parts;
+  gint i;
+
+  matchlet = g_slice_new0 (TreeMatchlet);
+
+  if (line[0] == '>')
+    {
+      *depth = 0;
+      s = line;
+    }
+  else
+    {
+      *depth = atoi (line);
+      s = strchr (line, '>');
+    }
+  s += 2;
+  p = strchr (s, '"');
+  *p = 0;
+
+  matchlet->path = g_strdup (s);
+  s = p + 1;
+  parts = g_strsplit (s, ",", 0);
+  if (strcmp (parts[0], "=file") == 0)
+    matchlet->type = G_FILE_TYPE_REGULAR;
+  else if (strcmp (parts[0], "=directory") == 0)
+    matchlet->type = G_FILE_TYPE_DIRECTORY;
+  else if (strcmp (parts[0], "=link") == 0)
+    matchlet->type = G_FILE_TYPE_SYMBOLIC_LINK;
+  else
+    matchlet->type = G_FILE_TYPE_UNKNOWN;
+  for (i = 1; parts[i]; i++)
+    {
+      if (strcmp (parts[i], "executable") == 0)
+        matchlet->executable = 1;
+      else if (strcmp (parts[i], "match-case") == 0)
+        matchlet->match_case = 1;
+      else if (strcmp (parts[i], "non-empty") == 0)
+        matchlet->non_empty = 1;
+      else if (strcmp (parts[i], "on-disc") == 0)
+        matchlet->on_disc = 1;
+      else
+        matchlet->mimetype = g_strdup (parts[i]);
+    }
+
+  g_strfreev (parts);
+
+  return matchlet;
+}
+
+static gint
+cmp_match (gconstpointer a, gconstpointer b)
+{
+  const TreeMatch *aa = (const TreeMatch *)a;
+  const TreeMatch *bb = (const TreeMatch *)b;
+
+  return bb->priority - aa->priority;
+}
+
+static void
+insert_match (TreeMatch *match)
+{
+  tree_matches = g_list_insert_sorted (tree_matches, match, cmp_match);
+}
+
+static void
+insert_matchlet (TreeMatch    *match,
+                 TreeMatchlet *matchlet,
+                 gint          depth)
+{
+  if (depth == 0)
+    match->matches = g_list_append (match->matches, matchlet);
+  else
+    {
+      GList *last;
+      TreeMatchlet *m;
+
+      last = g_list_last (match->matches);
+      if (!last)
+        {
+          tree_matchlet_free (matchlet);
+          g_warning ("can't insert tree matchlet at depth %d", depth);
+          return;
+        }
+
+      m = (TreeMatchlet *) last->data;
+      while (--depth > 0)
+        {
+          last = g_list_last (m->matches);
+          if (!last)
+            {
+              tree_matchlet_free (matchlet);
+              g_warning ("can't insert tree matchlet at depth %d", depth);
+              return;
+            }
+
+          m = (TreeMatchlet *) last->data;
+        }
+      m->matches = g_list_append (m->matches, matchlet);
+    }
+}
+
+static void
+read_tree_magic_from_directory (const gchar *prefix)
+{
+  gchar *filename;
+  gchar *text;
+  gsize len;
+  gchar **lines;
+  gint i;
+  TreeMatch *match;
+  TreeMatchlet *matchlet;
+  gint depth;
+
+  filename = g_build_filename (prefix, "treemagic", NULL);
+
+  if (g_file_get_contents (filename, &text, &len, NULL))
+    {
+      if (strcmp (text, "MIME-TreeMagic") == 0)
+        {
+          lines = g_strsplit (text + strlen ("MIME-TreeMagic") + 2, "\n", 0);
+          match = NULL;
+          for (i = 0; lines[i] && lines[i][0]; i++)
+            {
+              if (lines[i][0] == '[')
+                {
+                  match = parse_header (lines[i]);
+                  insert_match (match);
+                }
+              else if (match != NULL)
+                {
+                  matchlet = parse_match_line (lines[i], &depth);
+                  insert_matchlet (match, matchlet, depth);
+                }
+              else
+                {
+                  g_warning ("%s: header corrupt; skipping", filename);
+                  break;
+                }
+            }
+
+          g_strfreev (lines);
+        }
+      else
+        g_warning ("%s: header not found, skipping", filename);
+
+      g_free (text);
+    }
+
+  g_free (filename);
+}
+
+static void
+tree_magic_schedule_reload (void)
+{
+  need_reload = TRUE;
+}
+
+static void
+xdg_mime_reload (void *user_data)
+{
+  tree_magic_schedule_reload ();
+}
+
+static void
+tree_magic_shutdown (void)
+{
+  g_list_free_full (tree_matches, (GDestroyNotify) tree_match_free);
+  tree_matches = NULL;
+}
+
+static void
+tree_magic_init (void)
+{
+  static gboolean initialized = FALSE;
+  gsize i;
+
+  if (!initialized)
+    {
+      initialized = TRUE;
+
+      xdg_mime_register_reload_callback (xdg_mime_reload, NULL, NULL);
+      need_reload = TRUE;
+    }
+
+  if (need_reload)
+    {
+      const char * const *dirs;
+
+      need_reload = FALSE;
+
+      tree_magic_shutdown ();
+
+      dirs = g_content_type_get_mime_dirs ();
+      for (i = 0; dirs[i] != NULL; i++)
+        read_tree_magic_from_directory (dirs[i]);
+    }
+}
+
+/* a filtering enumerator */
+
+typedef struct
+{
+  gchar *path;
+  gint depth;
+  gboolean ignore_case;
+  gchar **components;
+  gchar **case_components;
+  GFileEnumerator **enumerators;
+  GFile **children;
+} Enumerator;
+
+static gboolean
+component_match (Enumerator  *e,
+                 gint         depth,
+                 const gchar *name)
+{
+  gchar *case_folded, *key;
+  gboolean found;
+
+  if (strcmp (name, e->components[depth]) == 0)
+    return TRUE;
+
+  if (!e->ignore_case)
+    return FALSE;
+
+  case_folded = g_utf8_casefold (name, -1);
+  key = g_utf8_collate_key (case_folded, -1);
+
+  found = strcmp (key, e->case_components[depth]) == 0;
+
+  g_free (case_folded);
+  g_free (key);
+
+  return found;
+}
+
+static GFile *
+next_match_recurse (Enumerator *e,
+                    gint        depth)
+{
+  GFile *file;
+  GFileInfo *info;
+  const gchar *name;
+
+  while (TRUE)
+    {
+      if (e->enumerators[depth] == NULL)
+        {
+          if (depth > 0)
+            {
+              file = next_match_recurse (e, depth - 1);
+              if (file)
+                {
+                  e->children[depth] = file;
+                  e->enumerators[depth] = g_file_enumerate_children (file,
+                                                                     G_FILE_ATTRIBUTE_STANDARD_NAME,
+                                                                     G_FILE_QUERY_INFO_NONE,
+                                                                     NULL,
+                                                                     NULL);
+                }
+            }
+          if (e->enumerators[depth] == NULL)
+            return NULL;
+        }
+
+      while ((info = g_file_enumerator_next_file (e->enumerators[depth], NULL, NULL)))
+        {
+          name = g_file_info_get_name (info);
+          if (component_match (e, depth, name))
+            {
+              file = g_file_get_child (e->children[depth], name);
+              g_object_unref (info);
+              return file;
+            }
+          g_object_unref (info);
+        }
+
+      g_object_unref (e->enumerators[depth]);
+      e->enumerators[depth] = NULL;
+      g_object_unref (e->children[depth]);
+      e->children[depth] = NULL;
+    }
+}
+
+static GFile *
+enumerator_next (Enumerator *e)
+{
+  return next_match_recurse (e, e->depth - 1);
+}
+
+static Enumerator *
+enumerator_new (GFile      *root,
+                const char *path,
+                gboolean    ignore_case)
+{
+  Enumerator *e;
+  gint i;
+  gchar *case_folded;
+
+  e = g_new0 (Enumerator, 1);
+  e->path = g_strdup (path);
+  e->ignore_case = ignore_case;
+
+  e->components = g_strsplit (e->path, G_DIR_SEPARATOR_S, -1);
+  e->depth = g_strv_length (e->components);
+  if (e->ignore_case)
+    {
+      e->case_components = g_new0 (char *, e->depth + 1);
+      for (i = 0; e->components[i]; i++)
+        {
+          case_folded = g_utf8_casefold (e->components[i], -1);
+          e->case_components[i] = g_utf8_collate_key (case_folded, -1);
+          g_free (case_folded);
+        }
+    }
+
+  e->children = g_new0 (GFile *, e->depth);
+  e->children[0] = g_object_ref (root);
+  e->enumerators = g_new0 (GFileEnumerator *, e->depth);
+  e->enumerators[0] = g_file_enumerate_children (root,
+                                                 G_FILE_ATTRIBUTE_STANDARD_NAME,
+                                                 G_FILE_QUERY_INFO_NONE,
+                                                 NULL,
+                                                 NULL);
+
+  return e;
+}
+
+static void
+enumerator_free (Enumerator *e)
+{
+  gint i;
+
+  for (i = 0; i < e->depth; i++)
+    {
+      if (e->enumerators[i])
+        g_object_unref (e->enumerators[i]);
+      if (e->children[i])
+        g_object_unref (e->children[i]);
+    }
+
+  g_free (e->enumerators);
+  g_free (e->children);
+  g_strfreev (e->components);
+  if (e->case_components)
+    g_strfreev (e->case_components);
+  g_free (e->path);
+  g_free (e);
+}
+
+static gboolean
+matchlet_match (TreeMatchlet *matchlet,
+                GFile        *root)
+{
+  GFile *file;
+  GFileInfo *info;
+  gboolean result;
+  const gchar *attrs;
+  Enumerator *e;
+  GList *l;
+
+  e = enumerator_new (root, matchlet->path, !matchlet->match_case);
+
+  do
+    {
+      file = enumerator_next (e);
+      if (!file)
+        {
+          enumerator_free (e);
+          return FALSE;
+        }
+
+      if (matchlet->mimetype)
+        attrs = G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+                G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE ","
+                G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE;
+      else
+        attrs = G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+                G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE;
+      info = g_file_query_info (file,
+                                attrs,
+                                G_FILE_QUERY_INFO_NONE,
+                                NULL,
+                                NULL);
+      if (info)
+        {
+          result = TRUE;
+
+          if (matchlet->type != G_FILE_TYPE_UNKNOWN &&
+              g_file_info_get_file_type (info) != matchlet->type)
+            result = FALSE;
+
+          if (matchlet->executable &&
+              !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE))
+            result = FALSE;
+        }
+      else
+        result = FALSE;
+
+      if (result && matchlet->non_empty)
+        {
+          GFileEnumerator *child_enum;
+          GFileInfo *child_info;
+
+          child_enum = g_file_enumerate_children (file,
+                                                  G_FILE_ATTRIBUTE_STANDARD_NAME,
+                                                  G_FILE_QUERY_INFO_NONE,
+                                                  NULL,
+                                                  NULL);
+
+          if (child_enum)
+            {
+              child_info = g_file_enumerator_next_file (child_enum, NULL, NULL);
+              if (child_info)
+                g_object_unref (child_info);
+              else
+                result = FALSE;
+              g_object_unref (child_enum);
+            }
+          else
+            result = FALSE;
+        }
+
+      if (result && matchlet->mimetype)
+        {
+          if (strcmp (matchlet->mimetype, g_file_info_get_content_type (info)) != 0)
+            result = FALSE;
+        }
+
+      if (info)
+        g_object_unref (info);
+      g_object_unref (file);
+    }
+  while (!result);
+
+  enumerator_free (e);
+
+  if (!matchlet->matches)
+    return TRUE;
+
+  for (l = matchlet->matches; l; l = l->next)
+    {
+      TreeMatchlet *submatchlet;
+
+      submatchlet = l->data;
+      if (matchlet_match (submatchlet, root))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+match_match (TreeMatch    *match,
+             GFile        *root,
+             GPtrArray    *types)
+{
+  GList *l;
+
+  for (l = match->matches; l; l = l->next)
+    {
+      TreeMatchlet *matchlet = l->data;
+      if (matchlet_match (matchlet, root))
+        {
+          g_ptr_array_add (types, g_strdup (match->contenttype));
+          break;
+        }
+    }
+}
+
+/**
+ * g_content_type_guess_for_tree:
+ * @root: the root of the tree to guess a type for
+ *
+ * Tries to guess the type of the tree with root @root, by
+ * looking at the files it contains. The result is an array
+ * of content types, with the best guess coming first.
+ *
+ * The types returned all have the form x-content/foo, e.g.
+ * x-content/audio-cdda (for audio CDs) or x-content/image-dcf
+ * (for a camera memory card). See the
+ * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec)
+ * specification for more on x-content types.
+ *
+ * This function is useful in the implementation of
+ * g_mount_guess_content_type().
+ *
+ * Returns: (transfer full) (array zero-terminated=1): an %NULL-terminated
+ *     array of zero or more content types. Free with g_strfreev()
+ *
+ * Since: 2.18
+ */
+gchar **
+g_content_type_guess_for_tree (GFile *root)
+{
+  GPtrArray *types;
+  GList *l;
+
+  types = g_ptr_array_new ();
+
+  G_LOCK (gio_treemagic);
+
+  tree_magic_init ();
+  for (l = tree_matches; l; l = l->next)
+    {
+      TreeMatch *match = l->data;
+      match_match (match, root, types);
+    }
+
+  G_UNLOCK (gio_treemagic);
+
+  g_ptr_array_add (types, NULL);
+
+  return (gchar **)g_ptr_array_free (types, FALSE);
+}
diff --git a/gio/gcontenttype.h b/gio/gcontenttype.h
new file mode 100644
index 0000000..db2c974
--- /dev/null
+++ b/gio/gcontenttype.h
@@ -0,0 +1,82 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CONTENT_TYPE_H__
+#define __G_CONTENT_TYPE_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+GLIB_AVAILABLE_IN_ALL
+gboolean g_content_type_equals            (const gchar  *type1,
+                                           const gchar  *type2);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_content_type_is_a              (const gchar  *type,
+                                           const gchar  *supertype);
+GLIB_AVAILABLE_IN_2_52
+gboolean g_content_type_is_mime_type      (const gchar *type,
+                                           const gchar *mime_type);
+GLIB_AVAILABLE_IN_ALL
+gboolean g_content_type_is_unknown        (const gchar  *type);
+GLIB_AVAILABLE_IN_ALL
+gchar *  g_content_type_get_description   (const gchar  *type);
+GLIB_AVAILABLE_IN_ALL
+gchar *  g_content_type_get_mime_type     (const gchar  *type);
+GLIB_AVAILABLE_IN_ALL
+GIcon *  g_content_type_get_icon          (const gchar  *type);
+GLIB_AVAILABLE_IN_2_34
+GIcon *  g_content_type_get_symbolic_icon (const gchar  *type);
+GLIB_AVAILABLE_IN_2_34
+gchar *  g_content_type_get_generic_icon_name (const gchar  *type);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean g_content_type_can_be_executable (const gchar  *type);
+
+GLIB_AVAILABLE_IN_ALL
+gchar *  g_content_type_from_mime_type    (const gchar  *mime_type);
+
+GLIB_AVAILABLE_IN_ALL
+gchar *  g_content_type_guess             (const gchar  *filename,
+                                           const guchar *data,
+                                           gsize         data_size,
+                                           gboolean     *result_uncertain);
+
+GLIB_AVAILABLE_IN_ALL
+gchar ** g_content_type_guess_for_tree    (GFile        *root);
+
+GLIB_AVAILABLE_IN_ALL
+GList *  g_content_types_get_registered   (void);
+
+/*< private >*/
+#ifndef __GTK_DOC_IGNORE__
+GLIB_AVAILABLE_IN_2_60
+const gchar * const *g_content_type_get_mime_dirs (void);
+GLIB_AVAILABLE_IN_2_60
+void                 g_content_type_set_mime_dirs (const gchar * const *dirs);
+#endif /* __GTK_DOC_IGNORE__ */
+
+G_END_DECLS
+
+#endif /* __G_CONTENT_TYPE_H__ */
diff --git a/gio/gcontenttypeprivate.h b/gio/gcontenttypeprivate.h
new file mode 100644
index 0000000..768a647
--- /dev/null
+++ b/gio/gcontenttypeprivate.h
@@ -0,0 +1,34 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CONTENT_TYPE_PRIVATE_H__
+#define __G_CONTENT_TYPE_PRIVATE_H__
+
+#include "gcontenttype.h"
+
+G_BEGIN_DECLS
+
+gsize  _g_unix_content_type_get_sniff_len (void);
+char * _g_unix_content_type_unalias       (const char *type);
+char **_g_unix_content_type_get_parents   (const char *type);
+
+G_END_DECLS
+
+#endif /* __G_CONTENT_TYPE_PRIVATE_H__ */
diff --git a/gio/gcontextspecificgroup.c b/gio/gcontextspecificgroup.c
new file mode 100644
index 0000000..ffd1307
--- /dev/null
+++ b/gio/gcontextspecificgroup.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright © 2015 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gcontextspecificgroup.h"
+
+#include <glib-object.h>
+#include "glib-private.h"
+
+typedef struct
+{
+  GSource   source;
+
+  GMutex    lock;
+  gpointer  instance;
+  GQueue    pending;
+} GContextSpecificSource;
+
+static gboolean
+g_context_specific_source_dispatch (GSource     *source,
+                                    GSourceFunc  callback,
+                                    gpointer     user_data)
+{
+  GContextSpecificSource *css = (GContextSpecificSource *) source;
+  guint signal_id;
+
+  g_mutex_lock (&css->lock);
+
+  g_assert (!g_queue_is_empty (&css->pending));
+  signal_id = GPOINTER_TO_UINT (g_queue_pop_head (&css->pending));
+
+  if (g_queue_is_empty (&css->pending))
+    g_source_set_ready_time (source, -1);
+
+  g_mutex_unlock (&css->lock);
+
+  g_signal_emit (css->instance, signal_id, 0);
+
+  return TRUE;
+}
+
+static void
+g_context_specific_source_finalize (GSource *source)
+{
+  GContextSpecificSource *css = (GContextSpecificSource *) source;
+
+  g_mutex_clear (&css->lock);
+  g_queue_clear (&css->pending);
+}
+
+static GContextSpecificSource *
+g_context_specific_source_new (const gchar *name,
+                               gpointer     instance)
+{
+  static GSourceFuncs source_funcs = {
+    NULL,
+    NULL,
+    g_context_specific_source_dispatch,
+    g_context_specific_source_finalize
+  };
+  GContextSpecificSource *css;
+  GSource *source;
+
+  source = g_source_new (&source_funcs, sizeof (GContextSpecificSource));
+  css = (GContextSpecificSource *) source;
+
+  g_source_set_name (source, name);
+
+  g_mutex_init (&css->lock);
+  g_queue_init (&css->pending);
+  css->instance = instance;
+
+  return css;
+}
+
+static gboolean
+g_context_specific_group_change_state (gpointer user_data)
+{
+  GContextSpecificGroup *group = user_data;
+
+  g_mutex_lock (&group->lock);
+
+  if (group->requested_state != group->effective_state)
+    {
+      (* group->requested_func) ();
+
+      group->effective_state = group->requested_state;
+      group->requested_func = NULL;
+
+      g_cond_broadcast (&group->cond);
+    }
+
+  g_mutex_unlock (&group->lock);
+
+  return FALSE;
+}
+
+/* this is not the most elegant way to deal with this, but it's probably
+ * the best.  there are only two other things we could do, really:
+ *
+ *  - run the start function (but not the stop function) from the user's
+ *    thread under some sort of lock.  we don't run the stop function
+ *    from the user's thread to avoid the destroy-while-emitting problem
+ *
+ *  - have some check-and-compare functionality similar to what
+ *    gsettings does where we send an artificial event in case we notice
+ *    a change during the potential race period (using stat, for
+ *    example)
+ */
+static void
+g_context_specific_group_request_state (GContextSpecificGroup *group,
+                                        gboolean               requested_state,
+                                        GCallback              requested_func)
+{
+  if (requested_state != group->requested_state)
+    {
+      if (group->effective_state != group->requested_state)
+        {
+          /* abort the currently pending state transition */
+          g_assert (group->effective_state == requested_state);
+
+          group->requested_state = requested_state;
+          group->requested_func = NULL;
+        }
+      else
+        {
+          /* start a new state transition */
+          group->requested_state = requested_state;
+          group->requested_func = requested_func;
+
+          g_main_context_invoke (GLIB_PRIVATE_CALL(g_get_worker_context) (),
+                                 g_context_specific_group_change_state, group);
+        }
+    }
+
+  /* we only block for positive transitions */
+  if (requested_state)
+    {
+      while (group->requested_state != group->effective_state)
+        g_cond_wait (&group->cond, &group->lock);
+
+      /* there is no way this could go back to FALSE because the object
+       * that we just created in this thread would have to have been
+       * destroyed again (from this thread) before that could happen.
+       */
+      g_assert (group->effective_state);
+    }
+}
+
+gpointer
+g_context_specific_group_get (GContextSpecificGroup *group,
+                              GType                  type,
+                              goffset                context_offset,
+                              GCallback              start_func)
+{
+  GContextSpecificSource *css;
+  GMainContext *context;
+
+  context = g_main_context_get_thread_default ();
+  if (!context)
+    context = g_main_context_default ();
+
+  g_mutex_lock (&group->lock);
+
+  if (!group->table)
+    group->table = g_hash_table_new (NULL, NULL);
+
+  css = g_hash_table_lookup (group->table, context);
+
+  if (!css)
+    {
+      gpointer instance;
+
+      instance = g_object_new (type, NULL);
+      css = g_context_specific_source_new (g_type_name (type), instance);
+      G_STRUCT_MEMBER (GMainContext *, instance, context_offset) = g_main_context_ref (context);
+      g_source_attach ((GSource *) css, context);
+
+      g_hash_table_insert (group->table, context, css);
+    }
+  else
+    g_object_ref (css->instance);
+
+  if (start_func)
+    g_context_specific_group_request_state (group, TRUE, start_func);
+
+  g_mutex_unlock (&group->lock);
+
+  return css->instance;
+}
+
+void
+g_context_specific_group_remove (GContextSpecificGroup *group,
+                                 GMainContext          *context,
+                                 gpointer               instance,
+                                 GCallback              stop_func)
+{
+  GContextSpecificSource *css;
+
+  if (!context)
+    {
+      g_critical ("Removing %s with NULL context.  This object was probably directly constructed from a "
+                  "dynamic language.  This is not a valid use of the API.", G_OBJECT_TYPE_NAME (instance));
+      return;
+    }
+
+  g_mutex_lock (&group->lock);
+  css = g_hash_table_lookup (group->table, context);
+  g_hash_table_remove (group->table, context);
+  g_assert (css);
+
+  /* stop only if we were the last one */
+  if (stop_func && g_hash_table_size (group->table) == 0)
+    g_context_specific_group_request_state (group, FALSE, stop_func);
+
+  g_mutex_unlock (&group->lock);
+
+  g_assert (css->instance == instance);
+
+  g_source_destroy ((GSource *) css);
+  g_source_unref ((GSource *) css);
+  g_main_context_unref (context);
+}
+
+void
+g_context_specific_group_emit (GContextSpecificGroup *group,
+                               guint                  signal_id)
+{
+  g_mutex_lock (&group->lock);
+
+  if (group->table)
+    {
+      GHashTableIter iter;
+      gpointer value;
+      gpointer ptr;
+
+      ptr = GUINT_TO_POINTER (signal_id);
+
+      g_hash_table_iter_init (&iter, group->table);
+      while (g_hash_table_iter_next (&iter, NULL, &value))
+        {
+          GContextSpecificSource *css = value;
+
+          g_mutex_lock (&css->lock);
+
+          g_queue_remove (&css->pending, ptr);
+          g_queue_push_tail (&css->pending, ptr);
+
+          g_source_set_ready_time ((GSource *) css, 0);
+
+          g_mutex_unlock (&css->lock);
+        }
+    }
+
+  g_mutex_unlock (&group->lock);
+}
diff --git a/gio/gcontextspecificgroup.h b/gio/gcontextspecificgroup.h
new file mode 100644
index 0000000..74d22a4
--- /dev/null
+++ b/gio/gcontextspecificgroup.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2015 Canonical Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_CONTEXT_SPECIFIC_GROUP_H__
+#define __G_CONTEXT_SPECIFIC_GROUP_H__
+
+#include <glib-object.h>
+
+typedef struct
+{
+  GHashTable *table;
+  GMutex      lock;
+  GCond       cond;
+  gboolean    requested_state;
+  GCallback   requested_func;
+  gboolean    effective_state;
+} GContextSpecificGroup;
+
+gpointer
+g_context_specific_group_get (GContextSpecificGroup *group,
+                              GType                  type,
+                              goffset                context_offset,
+                              GCallback              start_func);
+
+void
+g_context_specific_group_remove (GContextSpecificGroup *group,
+                                 GMainContext          *context,
+                                 gpointer               instance,
+                                 GCallback              stop_func);
+
+void
+g_context_specific_group_emit (GContextSpecificGroup *group,
+                               guint                  signal_id);
+
+#endif /* __G_CONTEXT_SPECIFIC_GROUP_H__ */
diff --git a/gio/gconverter.c b/gio/gconverter.c
new file mode 100644
index 0000000..7e5d308
--- /dev/null
+++ b/gio/gconverter.c
@@ -0,0 +1,201 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include "gconverter.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gconverter
+ * @short_description: Data conversion interface
+ * @include: gio/gio.h
+ * @see_also: #GInputStream, #GOutputStream
+ *
+ * #GConverter is implemented by objects that convert
+ * binary data in various ways. The conversion can be
+ * stateful and may fail at any place.
+ *
+ * Some example conversions are: character set conversion,
+ * compression, decompression and regular expression
+ * replace.
+ *
+ * Since: 2.24
+ **/
+
+
+typedef GConverterIface GConverterInterface;
+G_DEFINE_INTERFACE (GConverter, g_converter, G_TYPE_OBJECT)
+
+static void
+g_converter_default_init (GConverterInterface *iface)
+{
+}
+
+/**
+ * g_converter_convert:
+ * @converter: a #GConverter.
+ * @inbuf: (array length=inbuf_size) (element-type guint8): the buffer
+ *         containing the data to convert.
+ * @inbuf_size: the number of bytes in @inbuf
+ * @outbuf: (element-type guint8) (array length=outbuf_size): a buffer to write
+ *    converted data in.
+ * @outbuf_size: the number of bytes in @outbuf, must be at least one
+ * @flags: a #GConverterFlags controlling the conversion details
+ * @bytes_read: (out): will be set to the number of bytes read from @inbuf on success
+ * @bytes_written: (out): will be set to the number of bytes written to @outbuf on success
+ * @error: location to store the error occurring, or %NULL to ignore
+ *
+ * This is the main operation used when converting data. It is to be called
+ * multiple times in a loop, and each time it will do some work, i.e.
+ * producing some output (in @outbuf) or consuming some input (from @inbuf) or
+ * both. If its not possible to do any work an error is returned.
+ *
+ * Note that a single call may not consume all input (or any input at all).
+ * Also a call may produce output even if given no input, due to state stored
+ * in the converter producing output.
+ *
+ * If any data was either produced or consumed, and then an error happens, then
+ * only the successful conversion is reported and the error is returned on the
+ * next call.
+ *
+ * A full conversion loop involves calling this method repeatedly, each time
+ * giving it new input and space output space. When there is no more input
+ * data after the data in @inbuf, the flag %G_CONVERTER_INPUT_AT_END must be set.
+ * The loop will be (unless some error happens) returning %G_CONVERTER_CONVERTED
+ * each time until all data is consumed and all output is produced, then
+ * %G_CONVERTER_FINISHED is returned instead. Note, that %G_CONVERTER_FINISHED
+ * may be returned even if %G_CONVERTER_INPUT_AT_END is not set, for instance
+ * in a decompression converter where the end of data is detectable from the
+ * data (and there might even be other data after the end of the compressed data).
+ *
+ * When some data has successfully been converted @bytes_read and is set to
+ * the number of bytes read from @inbuf, and @bytes_written is set to indicate
+ * how many bytes was written to @outbuf. If there are more data to output
+ * or consume (i.e. unless the %G_CONVERTER_INPUT_AT_END is specified) then
+ * %G_CONVERTER_CONVERTED is returned, and if no more data is to be output
+ * then %G_CONVERTER_FINISHED is returned.
+ *
+ * On error %G_CONVERTER_ERROR is returned and @error is set accordingly.
+ * Some errors need special handling:
+ *
+ * %G_IO_ERROR_NO_SPACE is returned if there is not enough space
+ * to write the resulting converted data, the application should
+ * call the function again with a larger @outbuf to continue.
+ *
+ * %G_IO_ERROR_PARTIAL_INPUT is returned if there is not enough
+ * input to fully determine what the conversion should produce,
+ * and the %G_CONVERTER_INPUT_AT_END flag is not set. This happens for
+ * example with an incomplete multibyte sequence when converting text,
+ * or when a regexp matches up to the end of the input (and may match
+ * further input). It may also happen when @inbuf_size is zero and
+ * there is no more data to produce.
+ *
+ * When this happens the application should read more input and then
+ * call the function again. If further input shows that there is no
+ * more data call the function again with the same data but with
+ * the %G_CONVERTER_INPUT_AT_END flag set. This may cause the conversion
+ * to finish as e.g. in the regexp match case (or, to fail again with
+ * %G_IO_ERROR_PARTIAL_INPUT in e.g. a charset conversion where the
+ * input is actually partial).
+ *
+ * After g_converter_convert() has returned %G_CONVERTER_FINISHED the
+ * converter object is in an invalid state where its not allowed
+ * to call g_converter_convert() anymore. At this time you can only
+ * free the object or call g_converter_reset() to reset it to the
+ * initial state.
+ *
+ * If the flag %G_CONVERTER_FLUSH is set then conversion is modified
+ * to try to write out all internal state to the output. The application
+ * has to call the function multiple times with the flag set, and when
+ * the available input has been consumed and all internal state has
+ * been produced then %G_CONVERTER_FLUSHED (or %G_CONVERTER_FINISHED if
+ * really at the end) is returned instead of %G_CONVERTER_CONVERTED.
+ * This is somewhat similar to what happens at the end of the input stream,
+ * but done in the middle of the data.
+ *
+ * This has different meanings for different conversions. For instance
+ * in a compression converter it would mean that we flush all the
+ * compression state into output such that if you uncompress the
+ * compressed data you get back all the input data. Doing this may
+ * make the final file larger due to padding though. Another example
+ * is a regexp conversion, where if you at the end of the flushed data
+ * have a match, but there is also a potential longer match. In the
+ * non-flushed case we would ask for more input, but when flushing we
+ * treat this as the end of input and do the match.
+ *
+ * Flushing is not always possible (like if a charset converter flushes
+ * at a partial multibyte sequence). Converters are supposed to try
+ * to produce as much output as possible and then return an error
+ * (typically %G_IO_ERROR_PARTIAL_INPUT).
+ *
+ * Returns: a #GConverterResult, %G_CONVERTER_ERROR on error.
+ *
+ * Since: 2.24
+ **/
+GConverterResult
+g_converter_convert (GConverter *converter,
+		     const void *inbuf,
+		     gsize       inbuf_size,
+		     void       *outbuf,
+		     gsize       outbuf_size,
+		     GConverterFlags flags,
+		     gsize      *bytes_read,
+		     gsize      *bytes_written,
+		     GError    **error)
+{
+  GConverterIface *iface;
+
+  g_return_val_if_fail (G_IS_CONVERTER (converter), G_CONVERTER_ERROR);
+  g_return_val_if_fail (outbuf_size > 0, G_CONVERTER_ERROR);
+
+  *bytes_read = 0;
+  *bytes_written = 0;
+
+  iface = G_CONVERTER_GET_IFACE (converter);
+
+  return (* iface->convert) (converter,
+			     inbuf, inbuf_size,
+			     outbuf, outbuf_size,
+			     flags,
+			     bytes_read, bytes_written, error);
+}
+
+/**
+ * g_converter_reset:
+ * @converter: a #GConverter.
+ *
+ * Resets all internal state in the converter, making it behave
+ * as if it was just created. If the converter has any internal
+ * state that would produce output then that output is lost.
+ *
+ * Since: 2.24
+ **/
+void
+g_converter_reset (GConverter *converter)
+{
+  GConverterIface *iface;
+
+  g_return_if_fail (G_IS_CONVERTER (converter));
+
+  iface = G_CONVERTER_GET_IFACE (converter);
+
+  (* iface->reset) (converter);
+}
diff --git a/gio/gconverter.h b/gio/gconverter.h
new file mode 100644
index 0000000..8716453
--- /dev/null
+++ b/gio/gconverter.h
@@ -0,0 +1,96 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CONVERTER_H__
+#define __G_CONVERTER_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_CONVERTER            (g_converter_get_type ())
+#define G_CONVERTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_CONVERTER, GConverter))
+#define G_IS_CONVERTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_CONVERTER))
+#define G_CONVERTER_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_CONVERTER, GConverterIface))
+
+/**
+ * GConverter:
+ *
+ * Seek object for streaming operations.
+ *
+ * Since: 2.24
+ **/
+typedef struct _GConverterIface   GConverterIface;
+
+/**
+ * GConverterIface:
+ * @g_iface: The parent interface.
+ * @convert: Converts data.
+ * @reset: Reverts the internal state of the converter to its initial state.
+ *
+ * Provides an interface for converting data from one type
+ * to another type. The conversion can be stateful
+ * and may fail at any place.
+ *
+ * Since: 2.24
+ **/
+struct _GConverterIface
+{
+  GTypeInterface g_iface;
+
+  /* Virtual Table */
+
+  GConverterResult (* convert) (GConverter *converter,
+				const void *inbuf,
+				gsize       inbuf_size,
+				void       *outbuf,
+				gsize       outbuf_size,
+				GConverterFlags flags,
+				gsize      *bytes_read,
+				gsize      *bytes_written,
+				GError    **error);
+  void  (* reset)   (GConverter *converter);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType            g_converter_get_type     (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+GConverterResult g_converter_convert (GConverter       *converter,
+				      const void       *inbuf,
+				      gsize             inbuf_size,
+				      void             *outbuf,
+				      gsize             outbuf_size,
+				      GConverterFlags   flags,
+				      gsize            *bytes_read,
+				      gsize            *bytes_written,
+				      GError          **error);
+GLIB_AVAILABLE_IN_ALL
+void             g_converter_reset   (GConverter       *converter);
+
+
+G_END_DECLS
+
+
+#endif /* __G_CONVERTER_H__ */
diff --git a/gio/gconverterinputstream.c b/gio/gconverterinputstream.c
new file mode 100644
index 0000000..dd84b34
--- /dev/null
+++ b/gio/gconverterinputstream.c
@@ -0,0 +1,651 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gconverterinputstream.h"
+#include "gpollableinputstream.h"
+#include "gcancellable.h"
+#include "gioenumtypes.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gconverterinputstream
+ * @short_description: Converter Input Stream
+ * @include: gio/gio.h
+ * @see_also: #GInputStream, #GConverter
+ *
+ * Converter input stream implements #GInputStream and allows
+ * conversion of data of various types during reading.
+ *
+ * As of GLib 2.34, #GConverterInputStream implements
+ * #GPollableInputStream.
+ **/
+
+#define INITIAL_BUFFER_SIZE 4096
+
+typedef struct {
+  char *data;
+  gsize start;
+  gsize end;
+  gsize size;
+} Buffer;
+
+struct _GConverterInputStreamPrivate {
+  gboolean at_input_end;
+  gboolean finished;
+  gboolean need_input;
+  GConverter *converter;
+  Buffer input_buffer;
+  Buffer converted_buffer;
+};
+
+enum {
+  PROP_0,
+  PROP_CONVERTER
+};
+
+static void   g_converter_input_stream_set_property (GObject       *object,
+						     guint          prop_id,
+						     const GValue  *value,
+						     GParamSpec    *pspec);
+static void   g_converter_input_stream_get_property (GObject       *object,
+						     guint          prop_id,
+						     GValue        *value,
+						     GParamSpec    *pspec);
+static void   g_converter_input_stream_finalize     (GObject       *object);
+static gssize g_converter_input_stream_read         (GInputStream  *stream,
+						     void          *buffer,
+						     gsize          count,
+						     GCancellable  *cancellable,
+						     GError       **error);
+
+static gboolean g_converter_input_stream_can_poll         (GPollableInputStream *stream);
+static gboolean g_converter_input_stream_is_readable      (GPollableInputStream *stream);
+static gssize   g_converter_input_stream_read_nonblocking (GPollableInputStream  *stream,
+							   void                  *buffer,
+							   gsize                  size,
+							   GError               **error);
+
+static GSource *g_converter_input_stream_create_source    (GPollableInputStream *stream,
+							   GCancellable          *cancellable);
+
+static void g_converter_input_stream_pollable_iface_init  (GPollableInputStreamInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GConverterInputStream,
+			 g_converter_input_stream,
+			 G_TYPE_FILTER_INPUT_STREAM,
+                         G_ADD_PRIVATE (GConverterInputStream)
+			 G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM,
+						g_converter_input_stream_pollable_iface_init))
+
+static void
+g_converter_input_stream_class_init (GConverterInputStreamClass *klass)
+{
+  GObjectClass *object_class;
+  GInputStreamClass *istream_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = g_converter_input_stream_get_property;
+  object_class->set_property = g_converter_input_stream_set_property;
+  object_class->finalize     = g_converter_input_stream_finalize;
+
+  istream_class = G_INPUT_STREAM_CLASS (klass);
+  istream_class->read_fn = g_converter_input_stream_read;
+
+  g_object_class_install_property (object_class,
+				   PROP_CONVERTER,
+				   g_param_spec_object ("converter",
+							P_("Converter"),
+							P_("The converter object"),
+							G_TYPE_CONVERTER,
+							G_PARAM_READWRITE|
+							G_PARAM_CONSTRUCT_ONLY|
+							G_PARAM_STATIC_STRINGS));
+
+}
+
+static void
+g_converter_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface)
+{
+  iface->can_poll = g_converter_input_stream_can_poll;
+  iface->is_readable = g_converter_input_stream_is_readable;
+  iface->read_nonblocking = g_converter_input_stream_read_nonblocking;
+  iface->create_source = g_converter_input_stream_create_source;
+}
+
+static void
+g_converter_input_stream_finalize (GObject *object)
+{
+  GConverterInputStreamPrivate *priv;
+  GConverterInputStream        *stream;
+
+  stream = G_CONVERTER_INPUT_STREAM (object);
+  priv = stream->priv;
+
+  g_free (priv->input_buffer.data);
+  g_free (priv->converted_buffer.data);
+  if (priv->converter)
+    g_object_unref (priv->converter);
+
+  G_OBJECT_CLASS (g_converter_input_stream_parent_class)->finalize (object);
+}
+
+static void
+g_converter_input_stream_set_property (GObject      *object,
+				       guint         prop_id,
+				       const GValue *value,
+				       GParamSpec   *pspec)
+{
+  GConverterInputStream *cstream;
+
+  cstream = G_CONVERTER_INPUT_STREAM (object);
+
+   switch (prop_id)
+    {
+    case PROP_CONVERTER:
+      cstream->priv->converter = g_value_dup_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+
+static void
+g_converter_input_stream_get_property (GObject    *object,
+				       guint       prop_id,
+				       GValue     *value,
+				       GParamSpec *pspec)
+{
+  GConverterInputStreamPrivate *priv;
+  GConverterInputStream        *cstream;
+
+  cstream = G_CONVERTER_INPUT_STREAM (object);
+  priv = cstream->priv;
+
+  switch (prop_id)
+    {
+    case PROP_CONVERTER:
+      g_value_set_object (value, priv->converter);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+static void
+g_converter_input_stream_init (GConverterInputStream *stream)
+{
+  stream->priv = g_converter_input_stream_get_instance_private (stream);
+}
+
+/**
+ * g_converter_input_stream_new:
+ * @base_stream: a #GInputStream
+ * @converter: a #GConverter
+ *
+ * Creates a new converter input stream for the @base_stream.
+ *
+ * Returns: a new #GInputStream.
+ **/
+GInputStream *
+g_converter_input_stream_new (GInputStream *base_stream,
+                              GConverter   *converter)
+{
+  GInputStream *stream;
+
+  g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_CONVERTER_INPUT_STREAM,
+                         "base-stream", base_stream,
+			 "converter", converter,
+			 NULL);
+
+  return stream;
+}
+
+static gsize
+buffer_data_size (Buffer *buffer)
+{
+  return buffer->end - buffer->start;
+}
+
+static gsize
+buffer_tailspace (Buffer *buffer)
+{
+  return buffer->size - buffer->end;
+}
+
+static char *
+buffer_data (Buffer *buffer)
+{
+  return buffer->data + buffer->start;
+}
+
+static void
+buffer_consumed (Buffer *buffer,
+		 gsize count)
+{
+  buffer->start += count;
+  if (buffer->start == buffer->end)
+    buffer->start = buffer->end = 0;
+}
+
+static void
+buffer_read (Buffer *buffer,
+	     char *dest,
+	     gsize count)
+{
+  if (count != 0)
+    memcpy (dest, buffer->data + buffer->start, count);
+
+  buffer_consumed (buffer, count);
+}
+
+static void
+compact_buffer (Buffer *buffer)
+{
+  gsize in_buffer;
+
+  in_buffer = buffer_data_size (buffer);
+  memmove (buffer->data,
+	   buffer->data + buffer->start,
+	   in_buffer);
+  buffer->end -= buffer->start;
+  buffer->start = 0;
+}
+
+static void
+grow_buffer (Buffer *buffer)
+{
+  char *data;
+  gsize size, in_buffer;
+
+  if (buffer->size == 0)
+    size = INITIAL_BUFFER_SIZE;
+  else
+    size = buffer->size * 2;
+
+  data = g_malloc (size);
+  in_buffer = buffer_data_size (buffer);
+
+  if (in_buffer != 0)
+    memcpy (data,
+            buffer->data + buffer->start,
+            in_buffer);
+
+  g_free (buffer->data);
+  buffer->data = data;
+  buffer->end -= buffer->start;
+  buffer->start = 0;
+  buffer->size = size;
+}
+
+/* Ensures that the buffer can fit at_least_size bytes,
+ * *including* the current in-buffer data */
+static void
+buffer_ensure_space (Buffer *buffer,
+		     gsize at_least_size)
+{
+  gsize in_buffer, left_to_fill;
+
+  in_buffer = buffer_data_size (buffer);
+
+  if (in_buffer >= at_least_size)
+    return;
+
+  left_to_fill = buffer_tailspace (buffer);
+
+  if (in_buffer + left_to_fill >= at_least_size)
+    {
+      /* We fit in remaining space at end */
+      /* If the copy is small, compact now anyway so we can fill more */
+      if (in_buffer < 256)
+	compact_buffer (buffer);
+    }
+  else if (buffer->size >= at_least_size)
+    {
+      /* We fit, but only if we compact */
+      compact_buffer (buffer);
+    }
+  else
+    {
+      /* Need to grow buffer */
+      while (buffer->size < at_least_size)
+	grow_buffer (buffer);
+    }
+}
+
+static gssize
+fill_input_buffer (GConverterInputStream  *stream,
+		   gsize                   at_least_size,
+		   gboolean                blocking,
+		   GCancellable           *cancellable,
+		   GError                **error)
+{
+  GConverterInputStreamPrivate *priv;
+  GInputStream *base_stream;
+  gssize nread;
+
+  priv = stream->priv;
+
+  buffer_ensure_space (&priv->input_buffer, at_least_size);
+
+  base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+  nread = g_pollable_stream_read (base_stream,
+				  priv->input_buffer.data + priv->input_buffer.end,
+				  buffer_tailspace (&priv->input_buffer),
+				  blocking,
+				  cancellable,
+				  error);
+
+  if (nread > 0)
+    {
+      priv->input_buffer.end += nread;
+      priv->need_input = FALSE;
+    }
+
+  return nread;
+}
+
+
+static gssize
+read_internal (GInputStream *stream,
+	       void         *buffer,
+	       gsize         count,
+	       gboolean      blocking,
+	       GCancellable *cancellable,
+	       GError      **error)
+{
+  GConverterInputStream *cstream;
+  GConverterInputStreamPrivate *priv;
+  gsize available, total_bytes_read;
+  gssize nread;
+  GConverterResult res;
+  gsize bytes_read;
+  gsize bytes_written;
+  GError *my_error;
+  GError *my_error2;
+
+  cstream = G_CONVERTER_INPUT_STREAM (stream);
+  priv = cstream->priv;
+
+  available = buffer_data_size (&priv->converted_buffer);
+
+  if (available > 0 &&
+      count <= available)
+    {
+      /* Converted data available, return that */
+      buffer_read (&priv->converted_buffer, buffer, count);
+      return count;
+    }
+
+  /* Full request not available, read all currently available and request
+     refill/conversion for more */
+
+  buffer_read (&priv->converted_buffer, buffer, available);
+
+  total_bytes_read = available;
+  buffer = (char *) buffer + available;
+  count -= available;
+
+  /* If there is no data to convert, and no pre-converted data,
+     do some i/o for more input */
+  if (buffer_data_size (&priv->input_buffer) == 0 &&
+      total_bytes_read == 0 &&
+      !priv->at_input_end)
+    {
+      nread = fill_input_buffer (cstream, count, blocking, cancellable, error);
+      if (nread < 0)
+	return -1;
+      if (nread == 0)
+	priv->at_input_end = TRUE;
+    }
+
+  /* First try to convert any available data (or state) directly to the user buffer: */
+  if (!priv->finished)
+    {
+      my_error = NULL;
+      res = g_converter_convert (priv->converter,
+				 buffer_data (&priv->input_buffer),
+				 buffer_data_size (&priv->input_buffer),
+				 buffer, count,
+				 priv->at_input_end ? G_CONVERTER_INPUT_AT_END : 0,
+				 &bytes_read,
+				 &bytes_written,
+				 &my_error);
+      if (res != G_CONVERTER_ERROR)
+	{
+	  total_bytes_read += bytes_written;
+	  buffer_consumed (&priv->input_buffer, bytes_read);
+	  if (res == G_CONVERTER_FINISHED)
+	    priv->finished = TRUE; /* We're done converting */
+	}
+      else if (total_bytes_read == 0 &&
+	       !g_error_matches (my_error,
+				 G_IO_ERROR,
+				 G_IO_ERROR_PARTIAL_INPUT) &&
+	       !g_error_matches (my_error,
+				 G_IO_ERROR,
+				 G_IO_ERROR_NO_SPACE))
+	{
+	  /* No previously read data and no "special" error, return error */
+	  g_propagate_error (error, my_error);
+	  return -1;
+	}
+      else
+	g_error_free (my_error);
+    }
+
+  /* We had some pre-converted data and/or we converted directly to the
+     user buffer */
+  if (total_bytes_read > 0)
+    return total_bytes_read;
+
+  /* If there is no more to convert, return EOF */
+  if (priv->finished)
+    {
+      g_assert (buffer_data_size (&priv->converted_buffer) == 0);
+      return 0;
+    }
+
+  /* There was "complexity" in the straight-to-buffer conversion,
+   * convert to our own buffer and write from that.
+   * At this point we didn't produce any data into @buffer.
+   */
+
+  /* Ensure we have *some* initial target space */
+  buffer_ensure_space (&priv->converted_buffer, count);
+
+  while (TRUE)
+    {
+      g_assert (!priv->finished);
+
+      /* Try to convert to our buffer */
+      my_error = NULL;
+      res = g_converter_convert (priv->converter,
+				 buffer_data (&priv->input_buffer),
+				 buffer_data_size (&priv->input_buffer),
+				 buffer_data (&priv->converted_buffer),
+				 buffer_tailspace (&priv->converted_buffer),
+				 priv->at_input_end ? G_CONVERTER_INPUT_AT_END : 0,
+				 &bytes_read,
+				 &bytes_written,
+				 &my_error);
+      if (res != G_CONVERTER_ERROR)
+	{
+	  priv->converted_buffer.end += bytes_written;
+	  buffer_consumed (&priv->input_buffer, bytes_read);
+
+	  /* Maybe we consumed without producing any output */
+	  if (buffer_data_size (&priv->converted_buffer) == 0 && res != G_CONVERTER_FINISHED)
+	    continue; /* Convert more */
+
+	  if (res == G_CONVERTER_FINISHED)
+	    priv->finished = TRUE;
+
+	  total_bytes_read = MIN (count, buffer_data_size (&priv->converted_buffer));
+	  buffer_read (&priv->converted_buffer, buffer, total_bytes_read);
+
+	  g_assert (priv->finished || total_bytes_read > 0);
+
+	  return total_bytes_read;
+	}
+
+      /* There was some kind of error filling our buffer */
+
+      if (g_error_matches (my_error,
+			   G_IO_ERROR,
+			   G_IO_ERROR_PARTIAL_INPUT) &&
+	  !priv->at_input_end)
+	{
+	  /* Need more data */
+	  my_error2 = NULL;
+	  nread = fill_input_buffer (cstream,
+				     buffer_data_size (&priv->input_buffer) + 4096,
+				     blocking,
+				     cancellable,
+				     &my_error2);
+	  if (nread < 0)
+	    {
+	      /* Can't read any more data, return that error */
+	      g_error_free (my_error);
+	      g_propagate_error (error, my_error2);
+	      priv->need_input = TRUE;
+	      return -1;
+	    }
+	  else if (nread == 0)
+	    {
+	      /* End of file, try INPUT_AT_END */
+	      priv->at_input_end = TRUE;
+	    }
+	  g_error_free (my_error);
+	  continue;
+	}
+
+      if (g_error_matches (my_error,
+			   G_IO_ERROR,
+			   G_IO_ERROR_NO_SPACE))
+	{
+	  /* Need more destination space, grow it
+	   * Note: if we actually grow the buffer (as opposed to compacting it),
+	   * this will double the size, not just add one byte. */
+	  buffer_ensure_space (&priv->converted_buffer,
+			       priv->converted_buffer.size + 1);
+	  g_error_free (my_error);
+	  continue;
+	}
+
+      /* Any other random error, return it */
+      g_propagate_error (error, my_error);
+      return -1;
+    }
+
+  g_assert_not_reached ();
+}
+
+static gssize
+g_converter_input_stream_read (GInputStream *stream,
+			       void         *buffer,
+			       gsize         count,
+			       GCancellable *cancellable,
+			       GError      **error)
+{
+  return read_internal (stream, buffer, count, TRUE, cancellable, error);
+}
+
+static gboolean
+g_converter_input_stream_can_poll (GPollableInputStream *stream)
+{
+  GInputStream *base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+
+  return (G_IS_POLLABLE_INPUT_STREAM (base_stream) &&
+	  g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (base_stream)));
+}
+
+static gboolean
+g_converter_input_stream_is_readable (GPollableInputStream *stream)
+{
+  GInputStream *base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+  GConverterInputStream *cstream = G_CONVERTER_INPUT_STREAM (stream);
+
+  if (buffer_data_size (&cstream->priv->converted_buffer))
+    return TRUE;
+  else if (buffer_data_size (&cstream->priv->input_buffer) &&
+	   !cstream->priv->need_input)
+    return TRUE;
+  else
+    return g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (base_stream));
+}
+
+static gssize
+g_converter_input_stream_read_nonblocking (GPollableInputStream  *stream,
+					   void                  *buffer,
+					   gsize                  count,
+					   GError               **error)
+{
+  return read_internal (G_INPUT_STREAM (stream), buffer, count,
+			FALSE, NULL, error);
+}
+
+static GSource *
+g_converter_input_stream_create_source (GPollableInputStream *stream,
+					GCancellable         *cancellable)
+{
+  GInputStream *base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+  GSource *base_source, *pollable_source;
+
+  if (g_pollable_input_stream_is_readable (stream))
+    base_source = g_timeout_source_new (0);
+  else
+    base_source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (base_stream), NULL);
+
+  pollable_source = g_pollable_source_new_full (stream, base_source,
+						cancellable);
+  g_source_unref (base_source);
+
+  return pollable_source;
+}
+
+
+/**
+ * g_converter_input_stream_get_converter:
+ * @converter_stream: a #GConverterInputStream
+ *
+ * Gets the #GConverter that is used by @converter_stream.
+ *
+ * Returns: (transfer none): the converter of the converter input stream
+ *
+ * Since: 2.24
+ */
+GConverter *
+g_converter_input_stream_get_converter (GConverterInputStream *converter_stream)
+{
+  return converter_stream->priv->converter;
+}
diff --git a/gio/gconverterinputstream.h b/gio/gconverterinputstream.h
new file mode 100644
index 0000000..48cc102
--- /dev/null
+++ b/gio/gconverterinputstream.h
@@ -0,0 +1,80 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CONVERTER_INPUT_STREAM_H__
+#define __G_CONVERTER_INPUT_STREAM_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gfilterinputstream.h>
+#include <gio/gconverter.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_CONVERTER_INPUT_STREAM         (g_converter_input_stream_get_type ())
+#define G_CONVERTER_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CONVERTER_INPUT_STREAM, GConverterInputStream))
+#define G_CONVERTER_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CONVERTER_INPUT_STREAM, GConverterInputStreamClass))
+#define G_IS_CONVERTER_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CONVERTER_INPUT_STREAM))
+#define G_IS_CONVERTER_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CONVERTER_INPUT_STREAM))
+#define G_CONVERTER_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CONVERTER_INPUT_STREAM, GConverterInputStreamClass))
+
+/**
+ * GConverterInputStream:
+ *
+ * An implementation of #GFilterInputStream that allows data
+ * conversion.
+ **/
+typedef struct _GConverterInputStreamClass    GConverterInputStreamClass;
+typedef struct _GConverterInputStreamPrivate  GConverterInputStreamPrivate;
+
+struct _GConverterInputStream
+{
+  GFilterInputStream parent_instance;
+
+  /*< private >*/
+  GConverterInputStreamPrivate *priv;
+};
+
+struct _GConverterInputStreamClass
+{
+  GFilterInputStreamClass parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType                  g_converter_input_stream_get_type      (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GInputStream          *g_converter_input_stream_new           (GInputStream          *base_stream,
+                                                               GConverter            *converter);
+GLIB_AVAILABLE_IN_ALL
+GConverter            *g_converter_input_stream_get_converter (GConverterInputStream *converter_stream);
+
+G_END_DECLS
+
+#endif /* __G_CONVERTER_INPUT_STREAM_H__ */
diff --git a/gio/gconverteroutputstream.c b/gio/gconverteroutputstream.c
new file mode 100644
index 0000000..c1fa29e
--- /dev/null
+++ b/gio/gconverteroutputstream.c
@@ -0,0 +1,689 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gconverteroutputstream.h"
+#include "gpollableoutputstream.h"
+#include "gcancellable.h"
+#include "gioenumtypes.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gconverteroutputstream
+ * @short_description: Converter Output Stream
+ * @include: gio/gio.h
+ * @see_also: #GOutputStream, #GConverter
+ *
+ * Converter output stream implements #GOutputStream and allows
+ * conversion of data of various types during reading.
+ *
+ * As of GLib 2.34, #GConverterOutputStream implements
+ * #GPollableOutputStream.
+ **/
+
+#define INITIAL_BUFFER_SIZE 4096
+
+typedef struct {
+  char *data;
+  gsize start;
+  gsize end;
+  gsize size;
+} Buffer;
+
+struct _GConverterOutputStreamPrivate {
+  gboolean at_output_end;
+  gboolean finished;
+  GConverter *converter;
+  Buffer output_buffer; /* To be converted and written */
+  Buffer converted_buffer; /* Already converted */
+};
+
+/* Buffering strategy:
+ *
+ * Each time we write we must at least consume some input, or
+ * return an error. Thus we start with writing all already
+ * converted data and *then* we start converting (reporting
+ * an error at any point in this).
+ *
+ * Its possible that what the user wrote is not enough data
+ * for the converter, so we must then buffer it in output_buffer
+ * and ask for more data, but we want to avoid this as much as
+ * possible, converting directly from the users buffer.
+ */
+
+enum {
+  PROP_0,
+  PROP_CONVERTER
+};
+
+static void   g_converter_output_stream_set_property (GObject        *object,
+						      guint           prop_id,
+						      const GValue   *value,
+						      GParamSpec     *pspec);
+static void   g_converter_output_stream_get_property (GObject        *object,
+						      guint           prop_id,
+						      GValue         *value,
+						      GParamSpec     *pspec);
+static void   g_converter_output_stream_finalize     (GObject        *object);
+static gssize g_converter_output_stream_write        (GOutputStream  *stream,
+						      const void     *buffer,
+						      gsize           count,
+						      GCancellable   *cancellable,
+						      GError        **error);
+static gboolean g_converter_output_stream_flush      (GOutputStream  *stream,
+						      GCancellable   *cancellable,
+						      GError        **error);
+
+static gboolean g_converter_output_stream_can_poll          (GPollableOutputStream *stream);
+static gboolean g_converter_output_stream_is_writable       (GPollableOutputStream *stream);
+static gssize   g_converter_output_stream_write_nonblocking (GPollableOutputStream  *stream,
+							     const void             *buffer,
+							     gsize                  size,
+							     GError               **error);
+
+static GSource *g_converter_output_stream_create_source     (GPollableOutputStream *stream,
+							     GCancellable          *cancellable);
+
+static void g_converter_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GConverterOutputStream,
+			 g_converter_output_stream,
+			 G_TYPE_FILTER_OUTPUT_STREAM,
+                         G_ADD_PRIVATE (GConverterOutputStream)
+			 G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM,
+						g_converter_output_stream_pollable_iface_init))
+
+static void
+g_converter_output_stream_class_init (GConverterOutputStreamClass *klass)
+{
+  GObjectClass *object_class;
+  GOutputStreamClass *istream_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = g_converter_output_stream_get_property;
+  object_class->set_property = g_converter_output_stream_set_property;
+  object_class->finalize     = g_converter_output_stream_finalize;
+
+  istream_class = G_OUTPUT_STREAM_CLASS (klass);
+  istream_class->write_fn = g_converter_output_stream_write;
+  istream_class->flush = g_converter_output_stream_flush;
+
+  g_object_class_install_property (object_class,
+				   PROP_CONVERTER,
+				   g_param_spec_object ("converter",
+							P_("Converter"),
+							P_("The converter object"),
+							G_TYPE_CONVERTER,
+							G_PARAM_READWRITE|
+							G_PARAM_CONSTRUCT_ONLY|
+							G_PARAM_STATIC_STRINGS));
+
+}
+
+static void
+g_converter_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface)
+{
+  iface->can_poll = g_converter_output_stream_can_poll;
+  iface->is_writable = g_converter_output_stream_is_writable;
+  iface->write_nonblocking = g_converter_output_stream_write_nonblocking;
+  iface->create_source = g_converter_output_stream_create_source;
+}
+
+static void
+g_converter_output_stream_finalize (GObject *object)
+{
+  GConverterOutputStreamPrivate *priv;
+  GConverterOutputStream        *stream;
+
+  stream = G_CONVERTER_OUTPUT_STREAM (object);
+  priv = stream->priv;
+
+  g_free (priv->output_buffer.data);
+  g_free (priv->converted_buffer.data);
+  if (priv->converter)
+    g_object_unref (priv->converter);
+
+  G_OBJECT_CLASS (g_converter_output_stream_parent_class)->finalize (object);
+}
+
+static void
+g_converter_output_stream_set_property (GObject      *object,
+				       guint         prop_id,
+				       const GValue *value,
+				       GParamSpec   *pspec)
+{
+  GConverterOutputStream *cstream;
+
+  cstream = G_CONVERTER_OUTPUT_STREAM (object);
+
+   switch (prop_id)
+    {
+    case PROP_CONVERTER:
+      cstream->priv->converter = g_value_dup_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+
+static void
+g_converter_output_stream_get_property (GObject    *object,
+				       guint       prop_id,
+				       GValue     *value,
+				       GParamSpec *pspec)
+{
+  GConverterOutputStreamPrivate *priv;
+  GConverterOutputStream        *cstream;
+
+  cstream = G_CONVERTER_OUTPUT_STREAM (object);
+  priv = cstream->priv;
+
+  switch (prop_id)
+    {
+    case PROP_CONVERTER:
+      g_value_set_object (value, priv->converter);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_converter_output_stream_init (GConverterOutputStream *stream)
+{
+  stream->priv = g_converter_output_stream_get_instance_private (stream);
+}
+
+/**
+ * g_converter_output_stream_new:
+ * @base_stream: a #GOutputStream
+ * @converter: a #GConverter
+ *
+ * Creates a new converter output stream for the @base_stream.
+ *
+ * Returns: a new #GOutputStream.
+ **/
+GOutputStream *
+g_converter_output_stream_new (GOutputStream *base_stream,
+                               GConverter    *converter)
+{
+  GOutputStream *stream;
+
+  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_CONVERTER_OUTPUT_STREAM,
+                         "base-stream", base_stream,
+			 "converter", converter,
+			 NULL);
+
+  return stream;
+}
+
+static gsize
+buffer_data_size (Buffer *buffer)
+{
+  return buffer->end - buffer->start;
+}
+
+static gsize
+buffer_tailspace (Buffer *buffer)
+{
+  return buffer->size - buffer->end;
+}
+
+static char *
+buffer_data (Buffer *buffer)
+{
+  return buffer->data + buffer->start;
+}
+
+static void
+buffer_consumed (Buffer *buffer,
+		 gsize count)
+{
+  buffer->start += count;
+  if (buffer->start == buffer->end)
+    buffer->start = buffer->end = 0;
+}
+
+static void
+compact_buffer (Buffer *buffer)
+{
+  gsize in_buffer;
+
+  in_buffer = buffer_data_size (buffer);
+  memmove (buffer->data,
+	   buffer->data + buffer->start,
+	   in_buffer);
+  buffer->end -= buffer->start;
+  buffer->start = 0;
+}
+
+static void
+grow_buffer (Buffer *buffer)
+{
+  char *data;
+  gsize size, in_buffer;
+
+  if (buffer->size == 0)
+    size = INITIAL_BUFFER_SIZE;
+  else
+    size = buffer->size * 2;
+
+  data = g_malloc (size);
+  in_buffer = buffer_data_size (buffer);
+
+  if (in_buffer != 0)
+    memcpy (data,
+            buffer->data + buffer->start,
+            in_buffer);
+
+  g_free (buffer->data);
+  buffer->data = data;
+  buffer->end -= buffer->start;
+  buffer->start = 0;
+  buffer->size = size;
+}
+
+/* Ensures that the buffer can fit at_least_size bytes,
+ * *including* the current in-buffer data */
+static void
+buffer_ensure_space (Buffer *buffer,
+		     gsize at_least_size)
+{
+  gsize in_buffer, left_to_fill;
+
+  in_buffer = buffer_data_size (buffer);
+
+  if (in_buffer >= at_least_size)
+    return;
+
+  left_to_fill = buffer_tailspace (buffer);
+
+  if (in_buffer + left_to_fill >= at_least_size)
+    {
+      /* We fit in remaining space at end */
+      /* If the copy is small, compact now anyway so we can fill more */
+      if (in_buffer < 256)
+	compact_buffer (buffer);
+    }
+  else if (buffer->size >= at_least_size)
+    {
+      /* We fit, but only if we compact */
+      compact_buffer (buffer);
+    }
+  else
+    {
+      /* Need to grow buffer */
+      while (buffer->size < at_least_size)
+	grow_buffer (buffer);
+    }
+}
+
+static void
+buffer_append (Buffer *buffer,
+	       const char *data,
+	       gsize data_size)
+{
+  buffer_ensure_space (buffer,
+		       buffer_data_size (buffer) + data_size);
+  memcpy (buffer->data + buffer->end, data, data_size);
+  buffer->end += data_size;
+}
+
+
+static gboolean
+flush_buffer (GConverterOutputStream *stream,
+	      gboolean                blocking,
+	      GCancellable           *cancellable,
+	      GError                **error)
+{
+  GConverterOutputStreamPrivate *priv;
+  GOutputStream *base_stream;
+  gsize nwritten;
+  gsize available;
+  gboolean res;
+
+  priv = stream->priv;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+
+  available = buffer_data_size (&priv->converted_buffer);
+  if (available > 0)
+    {
+      res = g_pollable_stream_write_all (base_stream,
+					 buffer_data (&priv->converted_buffer),
+					 available,
+					 blocking,
+					 &nwritten,
+					 cancellable,
+					 error);
+      buffer_consumed (&priv->converted_buffer, nwritten);
+      return res;
+    }
+  return TRUE;
+}
+
+
+static gssize
+write_internal (GOutputStream  *stream,
+		const void     *buffer,
+		gsize           count,
+		gboolean        blocking,
+		GCancellable   *cancellable,
+		GError        **error)
+{
+  GConverterOutputStream *cstream;
+  GConverterOutputStreamPrivate *priv;
+  gssize retval;
+  GConverterResult res;
+  gsize bytes_read;
+  gsize bytes_written;
+  GError *my_error;
+  const char *to_convert;
+  gsize to_convert_size, converted_bytes;
+  gboolean converting_from_buffer;
+
+  cstream = G_CONVERTER_OUTPUT_STREAM (stream);
+  priv = cstream->priv;
+
+  /* Write out all available pre-converted data and fail if
+     not possible */
+  if (!flush_buffer (cstream, blocking, cancellable, error))
+    return -1;
+
+  if (priv->finished)
+    return 0;
+
+  /* Convert as much as possible */
+  if (buffer_data_size (&priv->output_buffer) > 0)
+    {
+      converting_from_buffer = TRUE;
+      buffer_append (&priv->output_buffer, buffer, count);
+      to_convert = buffer_data (&priv->output_buffer);
+      to_convert_size = buffer_data_size (&priv->output_buffer);
+    }
+  else
+    {
+      converting_from_buffer = FALSE;
+      to_convert = buffer;
+      to_convert_size = count;
+    }
+
+  /* Ensure we have *some* initial target space */
+  buffer_ensure_space (&priv->converted_buffer, to_convert_size);
+
+  converted_bytes = 0;
+  while (!priv->finished && converted_bytes < to_convert_size)
+    {
+      /* Ensure we have *some* target space */
+      if (buffer_tailspace (&priv->converted_buffer) == 0)
+	grow_buffer (&priv->converted_buffer);
+
+      /* Try to convert to our buffer */
+      my_error = NULL;
+      res = g_converter_convert (priv->converter,
+				 to_convert + converted_bytes,
+				 to_convert_size - converted_bytes,
+				 buffer_data (&priv->converted_buffer) + buffer_data_size (&priv->converted_buffer),
+				 buffer_tailspace (&priv->converted_buffer),
+				 0,
+				 &bytes_read,
+				 &bytes_written,
+				 &my_error);
+
+      if (res != G_CONVERTER_ERROR)
+	{
+	  priv->converted_buffer.end += bytes_written;
+	  converted_bytes += bytes_read;
+
+	  if (res == G_CONVERTER_FINISHED)
+	    priv->finished = TRUE;
+	}
+      else
+	{
+	  /* No-space errors can be handled locally: */
+	  if (g_error_matches (my_error,
+			       G_IO_ERROR,
+			       G_IO_ERROR_NO_SPACE))
+	    {
+	      /* Need more destination space, grow it
+	       * Note: if we actually grow the buffer (as opposed to compacting it),
+	       * this will double the size, not just add one byte. */
+	      buffer_ensure_space (&priv->converted_buffer,
+				   priv->converted_buffer.size + 1);
+	      g_error_free (my_error);
+	      continue;
+	    }
+
+	  if (converted_bytes > 0)
+	    {
+	      /* We got a conversion error, but we did convert some bytes before
+		 that, so handle those before reporting the error */
+	      g_error_free (my_error);
+	      break;
+	    }
+
+	  if (g_error_matches (my_error,
+			       G_IO_ERROR,
+			       G_IO_ERROR_PARTIAL_INPUT))
+	    {
+	      /* Consume everything to buffer that we append to next time
+		 we write */
+	      if (!converting_from_buffer)
+		buffer_append (&priv->output_buffer, buffer, count);
+	      /* in the converting_from_buffer case we already appended this */
+
+              g_error_free (my_error);
+	      return count; /* consume everything */
+	    }
+
+	  /* Converted no data and got a normal error, return it */
+	  g_propagate_error (error, my_error);
+	  return -1;
+	}
+    }
+
+  if (converting_from_buffer)
+    {
+      buffer_consumed (&priv->output_buffer, converted_bytes);
+      retval = count;
+    }
+  else
+    retval = converted_bytes;
+
+  /* We now successfully consumed retval bytes, so we can't return an error,
+     even if writing this to the base stream fails. If it does we'll just
+     stop early and report this error when we try again on the next
+     write call. */
+  flush_buffer (cstream, blocking, cancellable, NULL);
+
+  return retval;
+}
+
+static gssize
+g_converter_output_stream_write (GOutputStream  *stream,
+				 const void     *buffer,
+				 gsize           count,
+				 GCancellable   *cancellable,
+				 GError        **error)
+{
+  return write_internal (stream, buffer, count, TRUE, cancellable, error);
+}
+
+static gboolean
+g_converter_output_stream_flush (GOutputStream  *stream,
+				 GCancellable   *cancellable,
+				 GError        **error)
+{
+  GConverterOutputStream *cstream;
+  GConverterOutputStreamPrivate *priv;
+  GConverterResult res;
+  GError *my_error;
+  gboolean is_closing;
+  gboolean flushed;
+  gsize bytes_read;
+  gsize bytes_written;
+
+  cstream = G_CONVERTER_OUTPUT_STREAM (stream);
+  priv = cstream->priv;
+
+  is_closing = g_output_stream_is_closing (stream);
+
+  /* Write out all available pre-converted data and fail if
+     not possible */
+  if (!flush_buffer (cstream, TRUE, cancellable, error))
+    return FALSE;
+
+  /* Ensure we have *some* initial target space */
+  buffer_ensure_space (&priv->converted_buffer, 1);
+
+  /* Convert whole buffer */
+  flushed = FALSE;
+  while (!priv->finished && !flushed)
+    {
+      /* Ensure we have *some* target space */
+      if (buffer_tailspace (&priv->converted_buffer) == 0)
+	grow_buffer (&priv->converted_buffer);
+
+      /* Try to convert to our buffer */
+      my_error = NULL;
+      res = g_converter_convert (priv->converter,
+				 buffer_data (&priv->output_buffer),
+				 buffer_data_size (&priv->output_buffer),
+				 buffer_data (&priv->converted_buffer) + buffer_data_size (&priv->converted_buffer),
+				 buffer_tailspace (&priv->converted_buffer),
+				 is_closing ? G_CONVERTER_INPUT_AT_END : G_CONVERTER_FLUSH,
+				 &bytes_read,
+				 &bytes_written,
+				 &my_error);
+
+      if (res != G_CONVERTER_ERROR)
+	{
+	  priv->converted_buffer.end += bytes_written;
+	  buffer_consumed (&priv->output_buffer, bytes_read);
+
+	  if (res == G_CONVERTER_FINISHED)
+	    priv->finished = TRUE;
+	  if (!is_closing &&
+	      res == G_CONVERTER_FLUSHED)
+	    {
+	      /* Should not have returned FLUSHED with input left */
+	      g_assert (buffer_data_size (&priv->output_buffer) == 0);
+	      flushed = TRUE;
+	    }
+	}
+      else
+	{
+	  /* No-space errors can be handled locally: */
+	  if (g_error_matches (my_error,
+			       G_IO_ERROR,
+			       G_IO_ERROR_NO_SPACE))
+	    {
+	      /* Need more destination space, grow it
+	       * Note: if we actually grow the buffer (as opposed to compacting it),
+	       * this will double the size, not just add one byte. */
+	      buffer_ensure_space (&priv->converted_buffer,
+				   priv->converted_buffer.size + 1);
+	      g_error_free (my_error);
+	      continue;
+	    }
+
+	  /* Any other error, including PARTIAL_INPUT can't be fixed by now
+	     and is an error */
+	  g_propagate_error (error, my_error);
+	  return FALSE;
+	}
+    }
+
+  /* Now write all converted data to base stream */
+  if (!flush_buffer (cstream, TRUE, cancellable, error))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+g_converter_output_stream_can_poll (GPollableOutputStream *stream)
+{
+  GOutputStream *base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+
+  return (G_IS_POLLABLE_OUTPUT_STREAM (base_stream) &&
+	  g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (base_stream)));
+}
+
+static gboolean
+g_converter_output_stream_is_writable (GPollableOutputStream *stream)
+{
+  GOutputStream *base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+
+  return g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (base_stream));
+}
+
+static gssize
+g_converter_output_stream_write_nonblocking (GPollableOutputStream  *stream,
+					     const void             *buffer,
+					     gsize                   count,
+					     GError                **error)
+{
+  return write_internal (G_OUTPUT_STREAM (stream), buffer, count, FALSE,
+			 NULL, error);
+}
+
+static GSource *
+g_converter_output_stream_create_source (GPollableOutputStream *stream,
+					 GCancellable          *cancellable)
+{
+  GOutputStream *base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
+  GSource *base_source, *pollable_source;
+
+  base_source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (base_stream), NULL);
+  pollable_source = g_pollable_source_new_full (stream, base_source,
+						cancellable);
+  g_source_unref (base_source);
+
+  return pollable_source;
+}
+
+/**
+ * g_converter_output_stream_get_converter:
+ * @converter_stream: a #GConverterOutputStream
+ *
+ * Gets the #GConverter that is used by @converter_stream.
+ *
+ * Returns: (transfer none): the converter of the converter output stream
+ *
+ * Since: 2.24
+ */
+GConverter *
+g_converter_output_stream_get_converter (GConverterOutputStream *converter_stream)
+{
+  return converter_stream->priv->converter;
+}
diff --git a/gio/gconverteroutputstream.h b/gio/gconverteroutputstream.h
new file mode 100644
index 0000000..b9a1e5d
--- /dev/null
+++ b/gio/gconverteroutputstream.h
@@ -0,0 +1,80 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_CONVERTER_OUTPUT_STREAM_H__
+#define __G_CONVERTER_OUTPUT_STREAM_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gfilteroutputstream.h>
+#include <gio/gconverter.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_CONVERTER_OUTPUT_STREAM         (g_converter_output_stream_get_type ())
+#define G_CONVERTER_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CONVERTER_OUTPUT_STREAM, GConverterOutputStream))
+#define G_CONVERTER_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CONVERTER_OUTPUT_STREAM, GConverterOutputStreamClass))
+#define G_IS_CONVERTER_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CONVERTER_OUTPUT_STREAM))
+#define G_IS_CONVERTER_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CONVERTER_OUTPUT_STREAM))
+#define G_CONVERTER_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CONVERTER_OUTPUT_STREAM, GConverterOutputStreamClass))
+
+/**
+ * GConverterOutputStream:
+ *
+ * An implementation of #GFilterOutputStream that allows data
+ * conversion.
+ **/
+typedef struct _GConverterOutputStreamClass    GConverterOutputStreamClass;
+typedef struct _GConverterOutputStreamPrivate  GConverterOutputStreamPrivate;
+
+struct _GConverterOutputStream
+{
+  GFilterOutputStream parent_instance;
+
+  /*< private >*/
+  GConverterOutputStreamPrivate *priv;
+};
+
+struct _GConverterOutputStreamClass
+{
+  GFilterOutputStreamClass parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType                   g_converter_output_stream_get_type      (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GOutputStream          *g_converter_output_stream_new           (GOutputStream         *base_stream,
+                                                                 GConverter            *converter);
+GLIB_AVAILABLE_IN_ALL
+GConverter             *g_converter_output_stream_get_converter (GConverterOutputStream *converter_stream);
+
+G_END_DECLS
+
+#endif /* __G_CONVERTER_OUTPUT_STREAM_H__ */
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
new file mode 100644
index 0000000..146829e
--- /dev/null
+++ b/gio/gcredentials.c
@@ -0,0 +1,674 @@
+/* GDBus - GLib D-Bus Library
+ *
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gobject/gvaluecollector.h>
+
+#include "gcredentials.h"
+#include "gcredentialsprivate.h"
+#include "gnetworking.h"
+#include "gioerror.h"
+#include "gioenumtypes.h"
+
+#include "glibintl.h"
+
+/**
+ * SECTION:gcredentials
+ * @short_description: An object containing credentials
+ * @include: gio/gio.h
+ *
+ * The #GCredentials type is a reference-counted wrapper for native
+ * credentials. This information is typically used for identifying,
+ * authenticating and authorizing other processes.
+ *
+ * Some operating systems supports looking up the credentials of the
+ * remote peer of a communication endpoint - see e.g.
+ * g_socket_get_credentials().
+ *
+ * Some operating systems supports securely sending and receiving
+ * credentials over a Unix Domain Socket, see
+ * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
+ * g_unix_connection_receive_credentials() for details.
+ *
+ * On Linux, the native credential type is a `struct ucred` - see the
+ * unix(7) man page for details. This corresponds to
+ * %G_CREDENTIALS_TYPE_LINUX_UCRED.
+ *
+ * On Apple operating systems (including iOS, tvOS, and macOS),
+ * the native credential type is a `struct xucred`.
+ * This corresponds to %G_CREDENTIALS_TYPE_APPLE_XUCRED.
+ *
+ * On FreeBSD, Debian GNU/kFreeBSD, and GNU/Hurd, the native
+ * credential type is a `struct cmsgcred`. This corresponds
+ * to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
+ *
+ * On NetBSD, the native credential type is a `struct unpcbid`.
+ * This corresponds to %G_CREDENTIALS_TYPE_NETBSD_UNPCBID.
+ *
+ * On OpenBSD, the native credential type is a `struct sockpeercred`.
+ * This corresponds to %G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED.
+ *
+ * On Solaris (including OpenSolaris and its derivatives), the native
+ * credential type is a `ucred_t`. This corresponds to
+ * %G_CREDENTIALS_TYPE_SOLARIS_UCRED.
+ */
+
+/**
+ * GCredentials:
+ *
+ * The #GCredentials structure contains only private data and
+ * should only be accessed using the provided API.
+ *
+ * Since: 2.26
+ */
+struct _GCredentials
+{
+  /*< private >*/
+  GObject parent_instance;
+
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  struct ucred native;
+#elif G_CREDENTIALS_USE_APPLE_XUCRED
+  struct xucred native;
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  struct cmsgcred native;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  struct unpcbid native;
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  struct sockpeercred native;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  ucred_t *native;
+#else
+  #ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic warning "-Wcpp"
+  #warning Please add GCredentials support for your OS
+  #pragma GCC diagnostic pop
+  #endif
+#endif
+};
+
+/**
+ * GCredentialsClass:
+ *
+ * Class structure for #GCredentials.
+ *
+ * Since: 2.26
+ */
+struct _GCredentialsClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT)
+
+static void
+g_credentials_finalize (GObject *object)
+{
+#if G_CREDENTIALS_USE_SOLARIS_UCRED
+  GCredentials *credentials = G_CREDENTIALS (object);
+
+  ucred_free (credentials->native);
+#endif
+
+  if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object);
+}
+
+
+static void
+g_credentials_class_init (GCredentialsClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = g_credentials_finalize;
+}
+
+static void
+g_credentials_init (GCredentials *credentials)
+{
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  credentials->native.pid = getpid ();
+  credentials->native.uid = geteuid ();
+  credentials->native.gid = getegid ();
+#elif G_CREDENTIALS_USE_APPLE_XUCRED
+  gsize i;
+
+  credentials->native.cr_version = XUCRED_VERSION;
+  credentials->native.cr_uid = geteuid ();
+  credentials->native.cr_ngroups = 1;
+  credentials->native.cr_groups[0] = getegid ();
+
+  /* FIXME: In principle this could use getgroups() to fill in the rest
+   * of cr_groups, but then we'd have to handle the case where a process
+   * can have more than NGROUPS groups, if that's even possible. A macOS
+   * user would have to develop and test this.
+   *
+   * For now we fill it with -1 (meaning "no data"). */
+  for (i = 1; i < NGROUPS; i++)
+    credentials->native.cr_groups[i] = -1;
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  memset (&credentials->native, 0, sizeof (struct cmsgcred));
+  credentials->native.cmcred_pid  = getpid ();
+  credentials->native.cmcred_euid = geteuid ();
+  credentials->native.cmcred_gid  = getegid ();
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  credentials->native.unp_pid = getpid ();
+  credentials->native.unp_euid = geteuid ();
+  credentials->native.unp_egid = getegid ();
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  credentials->native.pid = getpid ();
+  credentials->native.uid = geteuid ();
+  credentials->native.gid = getegid ();
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  credentials->native = ucred_get (P_MYID);
+#endif
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_credentials_new:
+ *
+ * Creates a new #GCredentials object with credentials matching the
+ * the current process.
+ *
+ * Returns: A #GCredentials. Free with g_object_unref().
+ *
+ * Since: 2.26
+ */
+GCredentials *
+g_credentials_new (void)
+{
+  return g_object_new (G_TYPE_CREDENTIALS, NULL);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_credentials_to_string:
+ * @credentials: A #GCredentials object.
+ *
+ * Creates a human-readable textual representation of @credentials
+ * that can be used in logging and debug messages. The format of the
+ * returned string may change in future GLib release.
+ *
+ * Returns: A string that should be freed with g_free().
+ *
+ * Since: 2.26
+ */
+gchar *
+g_credentials_to_string (GCredentials *credentials)
+{
+  GString *ret;
+#if G_CREDENTIALS_USE_APPLE_XUCRED
+  __typeof__(credentials->native.cr_ngroups) i;
+#endif
+
+  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
+
+  ret = g_string_new ("GCredentials:");
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  g_string_append (ret, "linux-ucred:");
+  if (credentials->native.pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
+  if (credentials->native.uid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
+  if (credentials->native.gid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
+  if (ret->str[ret->len - 1] == ',')
+    ret->str[ret->len - 1] = '\0';
+#elif G_CREDENTIALS_USE_APPLE_XUCRED
+  g_string_append (ret, "apple-xucred:");
+  g_string_append_printf (ret, "version=%u,", credentials->native.cr_version);
+  if (credentials->native.cr_uid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_uid);
+  for (i = 0; i < credentials->native.cr_ngroups; i++)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_groups[i]);
+  if (ret->str[ret->len - 1] == ',')
+    ret->str[ret->len - 1] = '\0';
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  g_string_append (ret, "freebsd-cmsgcred:");
+  if (credentials->native.cmcred_pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
+  if (credentials->native.cmcred_euid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid);
+  if (credentials->native.cmcred_gid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid);
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  g_string_append (ret, "netbsd-unpcbid:");
+  if (credentials->native.unp_pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_pid);
+  if (credentials->native.unp_euid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_euid);
+  if (credentials->native.unp_egid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_egid);
+  ret->str[ret->len - 1] = '\0';
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  g_string_append (ret, "openbsd-sockpeercred:");
+  if (credentials->native.pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
+  if (credentials->native.uid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
+  if (credentials->native.gid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
+  if (ret->str[ret->len - 1] == ',')
+    ret->str[ret->len - 1] = '\0';
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  g_string_append (ret, "solaris-ucred:");
+  {
+    id_t id;
+    if ((id = ucred_getpid (credentials->native)) != -1)
+      g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) id);
+    if ((id = ucred_geteuid (credentials->native)) != -1)
+      g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) id);
+    if ((id = ucred_getegid (credentials->native)) != -1)
+      g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) id);
+    if (ret->str[ret->len - 1] == ',')
+      ret->str[ret->len - 1] = '\0';
+  }
+#else
+  g_string_append (ret, "unknown");
+#endif
+
+  return g_string_free (ret, FALSE);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+#if G_CREDENTIALS_USE_LINUX_UCRED
+/*
+ * Check whether @native contains invalid data. If getsockopt SO_PEERCRED
+ * is used on a TCP socket, it succeeds but yields a credentials structure
+ * with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a
+ * receiving Unix socket when the sending socket did not also enable
+ * SO_PASSCRED, it can succeed but yield a credentials structure with
+ * pid 0, uid /proc/sys/kernel/overflowuid and gid
+ * /proc/sys/kernel/overflowgid.
+ */
+static gboolean
+linux_ucred_check_valid (struct ucred  *native,
+                         GError       **error)
+{
+  if (native->pid == 0
+      || native->uid == -1
+      || native->gid == -1)
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_INVALID_DATA,
+                           _("GCredentials contains invalid data"));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+#endif
+
+/**
+ * g_credentials_is_same_user:
+ * @credentials: A #GCredentials.
+ * @other_credentials: A #GCredentials.
+ * @error: Return location for error or %NULL.
+ *
+ * Checks if @credentials and @other_credentials is the same user.
+ *
+ * This operation can fail if #GCredentials is not supported on the
+ * the OS.
+ *
+ * Returns: %TRUE if @credentials and @other_credentials has the same
+ * user, %FALSE otherwise or if @error is set.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_credentials_is_same_user (GCredentials  *credentials,
+                            GCredentials  *other_credentials,
+                            GError       **error)
+{
+  gboolean ret;
+
+  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
+  g_return_val_if_fail (G_IS_CREDENTIALS (other_credentials), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  ret = FALSE;
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  if (linux_ucred_check_valid (&credentials->native, NULL)
+      && credentials->native.uid == other_credentials->native.uid)
+    ret = TRUE;
+#elif G_CREDENTIALS_USE_APPLE_XUCRED
+  if (credentials->native.cr_version == other_credentials->native.cr_version &&
+      credentials->native.cr_uid == other_credentials->native.cr_uid)
+    ret = TRUE;
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
+    ret = TRUE;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  if (credentials->native.unp_euid == other_credentials->native.unp_euid)
+    ret = TRUE;
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  if (credentials->native.uid == other_credentials->native.uid)
+    ret = TRUE;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  if (ucred_geteuid (credentials->native) == ucred_geteuid (other_credentials->native))
+    ret = TRUE;
+#else
+  g_set_error_literal (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_NOT_SUPPORTED,
+                       _("GCredentials is not implemented on this OS"));
+#endif
+
+  return ret;
+}
+
+static gboolean
+credentials_native_type_check (GCredentialsType  requested_type,
+                               const char       *op)
+{
+  GEnumClass *enum_class;
+  GEnumValue *requested;
+#if G_CREDENTIALS_SUPPORTED
+  GEnumValue *supported;
+#endif
+
+#if G_CREDENTIALS_SUPPORTED
+  if (requested_type == G_CREDENTIALS_NATIVE_TYPE)
+    return TRUE;
+#endif
+
+  enum_class = g_type_class_ref (g_credentials_type_get_type ());
+  requested = g_enum_get_value (enum_class, requested_type);
+
+#if G_CREDENTIALS_SUPPORTED
+  supported = g_enum_get_value (enum_class, G_CREDENTIALS_NATIVE_TYPE);
+  g_assert (supported);
+  g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
+             "but only %s is supported on this platform.",
+             op, op,
+             requested ? requested->value_name : "(unknown)",
+             supported->value_name);
+#else
+  g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
+             "but there is no support for GCredentials on this platform.",
+             op, op,
+             requested ? requested->value_name : "(unknown)");
+#endif
+
+  g_type_class_unref (enum_class);
+  return FALSE;
+}
+
+/**
+ * g_credentials_get_native: (skip)
+ * @credentials: A #GCredentials.
+ * @native_type: The type of native credentials to get.
+ *
+ * Gets a pointer to native credentials of type @native_type from
+ * @credentials.
+ *
+ * It is a programming error (which will cause a warning to be
+ * logged) to use this method if there is no #GCredentials support for
+ * the OS or if @native_type isn't supported by the OS.
+ *
+ * Returns: The pointer to native credentials or %NULL if the
+ * operation there is no #GCredentials support for the OS or if
+ * @native_type isn't supported by the OS. Do not free the returned
+ * data, it is owned by @credentials.
+ *
+ * Since: 2.26
+ */
+gpointer
+g_credentials_get_native (GCredentials     *credentials,
+                          GCredentialsType  native_type)
+{
+  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
+
+  if (!credentials_native_type_check (native_type, "get"))
+    return NULL;
+
+#if G_CREDENTIALS_USE_SOLARIS_UCRED
+  return credentials->native;
+#elif G_CREDENTIALS_SUPPORTED
+  return &credentials->native;
+#else
+  g_assert_not_reached ();
+#endif
+}
+
+/**
+ * g_credentials_set_native:
+ * @credentials: A #GCredentials.
+ * @native_type: The type of native credentials to set.
+ * @native: (not nullable): A pointer to native credentials.
+ *
+ * Copies the native credentials of type @native_type from @native
+ * into @credentials.
+ *
+ * It is a programming error (which will cause a warning to be
+ * logged) to use this method if there is no #GCredentials support for
+ * the OS or if @native_type isn't supported by the OS.
+ *
+ * Since: 2.26
+ */
+void
+g_credentials_set_native (GCredentials     *credentials,
+                          GCredentialsType  native_type,
+                          gpointer          native)
+{
+  if (!credentials_native_type_check (native_type, "set"))
+    return;
+
+#if G_CREDENTIALS_USE_SOLARIS_UCRED
+  memcpy (credentials->native, native, ucred_size ());
+#elif G_CREDENTIALS_SUPPORTED
+  memcpy (&credentials->native, native, sizeof (credentials->native));
+#else
+  g_assert_not_reached ();
+#endif
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+#ifdef G_OS_UNIX
+/**
+ * g_credentials_get_unix_user:
+ * @credentials: A #GCredentials
+ * @error: Return location for error or %NULL.
+ *
+ * Tries to get the UNIX user identifier from @credentials. This
+ * method is only available on UNIX platforms.
+ *
+ * This operation can fail if #GCredentials is not supported on the
+ * OS or if the native credentials type does not contain information
+ * about the UNIX user.
+ *
+ * Returns: The UNIX user identifier or -1 if @error is set.
+ *
+ * Since: 2.26
+ */
+uid_t
+g_credentials_get_unix_user (GCredentials    *credentials,
+                             GError         **error)
+{
+  uid_t ret;
+
+  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
+  g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  if (linux_ucred_check_valid (&credentials->native, error))
+    ret = credentials->native.uid;
+  else
+    ret = -1;
+#elif G_CREDENTIALS_USE_APPLE_XUCRED
+  if (credentials->native.cr_version == XUCRED_VERSION)
+    {
+      ret = credentials->native.cr_uid;
+    }
+  else
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                   /* No point in translating the part in parentheses... */
+                   "%s (struct xucred cr_version %u != %u)",
+                   _("There is no GCredentials support for your platform"),
+                   credentials->native.cr_version,
+                   XUCRED_VERSION);
+      ret = -1;
+    }
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  ret = credentials->native.cmcred_euid;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  ret = credentials->native.unp_euid;
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  ret = credentials->native.uid;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  ret = ucred_geteuid (credentials->native);
+#else
+  ret = -1;
+  g_set_error_literal (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_NOT_SUPPORTED,
+                       _("There is no GCredentials support for your platform"));
+#endif
+
+  return ret;
+}
+
+/**
+ * g_credentials_get_unix_pid:
+ * @credentials: A #GCredentials
+ * @error: Return location for error or %NULL.
+ *
+ * Tries to get the UNIX process identifier from @credentials. This
+ * method is only available on UNIX platforms.
+ *
+ * This operation can fail if #GCredentials is not supported on the
+ * OS or if the native credentials type does not contain information
+ * about the UNIX process ID (for example this is the case for
+ * %G_CREDENTIALS_TYPE_APPLE_XUCRED).
+ *
+ * Returns: The UNIX process ID, or -1 if @error is set.
+ *
+ * Since: 2.36
+ */
+pid_t
+g_credentials_get_unix_pid (GCredentials    *credentials,
+                            GError         **error)
+{
+  pid_t ret;
+
+  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
+  g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  if (linux_ucred_check_valid (&credentials->native, error))
+    ret = credentials->native.pid;
+  else
+    ret = -1;
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  ret = credentials->native.cmcred_pid;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  ret = credentials->native.unp_pid;
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  ret = credentials->native.pid;
+#elif G_CREDENTIALS_USE_SOLARIS_UCRED
+  ret = ucred_getpid (credentials->native);
+#else
+  /* this case includes G_CREDENTIALS_USE_APPLE_XUCRED */
+  ret = -1;
+  g_set_error_literal (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_NOT_SUPPORTED,
+                       _("GCredentials does not contain a process ID on this OS"));
+#endif
+
+  return ret;
+}
+
+/**
+ * g_credentials_set_unix_user:
+ * @credentials: A #GCredentials.
+ * @uid: The UNIX user identifier to set.
+ * @error: Return location for error or %NULL.
+ *
+ * Tries to set the UNIX user identifier on @credentials. This method
+ * is only available on UNIX platforms.
+ *
+ * This operation can fail if #GCredentials is not supported on the
+ * OS or if the native credentials type does not contain information
+ * about the UNIX user. It can also fail if the OS does not allow the
+ * use of "spoofed" credentials.
+ *
+ * Returns: %TRUE if @uid was set, %FALSE if error is set.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_credentials_set_unix_user (GCredentials    *credentials,
+                             uid_t            uid,
+                             GError         **error)
+{
+  gboolean ret = FALSE;
+
+  g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
+  g_return_val_if_fail (uid != -1, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  credentials->native.uid = uid;
+  ret = TRUE;
+#elif G_CREDENTIALS_USE_APPLE_XUCRED
+  credentials->native.cr_uid = uid;
+  ret = TRUE;
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+  credentials->native.cmcred_euid = uid;
+  ret = TRUE;
+#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+  credentials->native.unp_euid = uid;
+  ret = TRUE;
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+  credentials->native.uid = uid;
+  ret = TRUE;
+#elif !G_CREDENTIALS_SPOOFING_SUPPORTED
+  g_set_error_literal (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_PERMISSION_DENIED,
+                       _("Credentials spoofing is not possible on this OS"));
+  ret = FALSE;
+#else
+  g_set_error_literal (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_NOT_SUPPORTED,
+                       _("GCredentials is not implemented on this OS"));
+  ret = FALSE;
+#endif
+
+  return ret;
+}
+
+#endif /* G_OS_UNIX */
diff --git a/gio/gcredentials.h b/gio/gcredentials.h
new file mode 100644
index 0000000..25cebf2
--- /dev/null
+++ b/gio/gcredentials.h
@@ -0,0 +1,85 @@
+/* GDBus - GLib D-Bus Library
+ *
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ */
+
+#ifndef __G_CREDENTIALS_H__
+#define __G_CREDENTIALS_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+#ifdef G_OS_UNIX
+/* To get the uid_t type */
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+G_BEGIN_DECLS
+
+#define G_TYPE_CREDENTIALS         (g_credentials_get_type ())
+#define G_CREDENTIALS(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CREDENTIALS, GCredentials))
+#define G_CREDENTIALS_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CREDENTIALS, GCredentialsClass))
+#define G_CREDENTIALS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CREDENTIALS, GCredentialsClass))
+#define G_IS_CREDENTIALS(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CREDENTIALS))
+#define G_IS_CREDENTIALS_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CREDENTIALS))
+
+typedef struct _GCredentialsClass   GCredentialsClass;
+
+GLIB_AVAILABLE_IN_ALL
+GType            g_credentials_get_type           (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_ALL
+GCredentials    *g_credentials_new                (void);
+
+GLIB_AVAILABLE_IN_ALL
+gchar           *g_credentials_to_string          (GCredentials    *credentials);
+
+GLIB_AVAILABLE_IN_ALL
+gpointer         g_credentials_get_native         (GCredentials    *credentials,
+                                                   GCredentialsType native_type);
+
+GLIB_AVAILABLE_IN_ALL
+void             g_credentials_set_native         (GCredentials    *credentials,
+                                                   GCredentialsType native_type,
+                                                   gpointer         native);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean         g_credentials_is_same_user       (GCredentials    *credentials,
+                                                   GCredentials    *other_credentials,
+                                                   GError         **error);
+
+#ifdef G_OS_UNIX
+GLIB_AVAILABLE_IN_2_36
+pid_t            g_credentials_get_unix_pid       (GCredentials    *credentials,
+                                                   GError         **error);
+GLIB_AVAILABLE_IN_ALL
+uid_t            g_credentials_get_unix_user      (GCredentials    *credentials,
+                                                   GError         **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean         g_credentials_set_unix_user      (GCredentials    *credentials,
+                                                   uid_t           uid,
+                                                   GError         **error);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_DBUS_PROXY_H__ */
diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
new file mode 100644
index 0000000..13d3bf3
--- /dev/null
+++ b/gio/gcredentialsprivate.h
@@ -0,0 +1,173 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __G_CREDENTIALS_PRIVATE_H__
+#define __G_CREDENTIALS_PRIVATE_H__
+
+#include "gio/gcredentials.h"
+#include "gio/gnetworking.h"
+
+/*
+ * G_CREDENTIALS_SUPPORTED:
+ *
+ * Defined to 1 if GCredentials works.
+ */
+#undef G_CREDENTIALS_SUPPORTED
+
+/*
+ * G_CREDENTIALS_USE_LINUX_UCRED, etc.:
+ *
+ * Defined to 1 if GCredentials uses Linux `struct ucred`, etc.
+ */
+#undef G_CREDENTIALS_USE_LINUX_UCRED
+#undef G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
+#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+#undef G_CREDENTIALS_USE_SOLARIS_UCRED
+#undef G_CREDENTIALS_USE_APPLE_XUCRED
+
+/*
+ * G_CREDENTIALS_NATIVE_TYPE:
+ *
+ * Defined to one of G_CREDENTIALS_TYPE_LINUX_UCRED, etc.
+ */
+#undef G_CREDENTIALS_NATIVE_TYPE
+
+/*
+ * G_CREDENTIALS_NATIVE_SIZE:
+ *
+ * Defined to the size of the %G_CREDENTIALS_NATIVE_TYPE
+ */
+#undef G_CREDENTIALS_NATIVE_SIZE
+
+/*
+ * G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED:
+ *
+ * Defined to 1 if we have a message-passing API in which credentials
+ * are attached to a particular message, such as `SCM_CREDENTIALS` on Linux
+ * or `SCM_CREDS` on FreeBSD.
+ */
+#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
+
+/*
+ * G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED:
+ *
+ * Defined to 1 if we have a `getsockopt()`-style API in which one end of
+ * a socket connection can directly query the credentials of the process
+ * that initiated the other end, such as `getsockopt SO_PEERCRED` on Linux
+ * or `getpeereid()` on multiple operating systems.
+ */
+#undef G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
+
+/*
+ * G_CREDENTIALS_SPOOFING_SUPPORTED:
+ *
+ * Defined to 1 if privileged processes can spoof their credentials when
+ * using the message-passing API.
+ */
+#undef G_CREDENTIALS_SPOOFING_SUPPORTED
+
+/*
+ * G_CREDENTIALS_PREFER_MESSAGE_PASSING:
+ *
+ * Defined to 1 if the data structure transferred by the message-passing
+ * API is strictly more informative than the one transferred by the
+ * `getsockopt()`-style API, and hence should be preferred, even for
+ * protocols like D-Bus that are defined in terms of the credentials of
+ * the (process that opened the) socket, as opposed to the credentials
+ * of an individual message.
+ */
+#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING
+
+/*
+ * G_CREDENTIALS_HAS_PID:
+ *
+ * Defined to 1 if the %G_CREDENTIALS_NATIVE_TYPE contains the process ID.
+ */
+#undef G_CREDENTIALS_HAS_PID
+
+#ifdef __linux__
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_LINUX_UCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_LINUX_UCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct ucred))
+#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+#define G_CREDENTIALS_HAS_PID 1
+
+#elif defined(__FreeBSD__)                                  || \
+      defined(__FreeBSD_kernel__) /* Debian GNU/kFreeBSD */ || \
+      defined(__GNU__)            /* GNU Hurd */            || \
+      defined(__DragonFly__)      /* DragonFly BSD */
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_FREEBSD_CMSGCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred))
+#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API
+ * is getpeereid(), which is not as informative as struct cmsgcred -
+ * it does not tell us the PID. As a result, libdbus prefers to use
+ * SCM_CREDS, and if we implement getpeereid() in future, we should
+ * do the same. */
+#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1
+#define G_CREDENTIALS_HAS_PID 1
+
+#elif defined(__NetBSD__)
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_NETBSD_UNPCBID 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_NETBSD_UNPCBID
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct unpcbid))
+/* #undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED */
+#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+#define G_CREDENTIALS_HAS_PID 1
+
+#elif defined(__OpenBSD__)
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct sockpeercred))
+#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+#define G_CREDENTIALS_HAS_PID 1
+
+#elif defined(__sun__) || defined(__illumos__) || defined (__OpenSolaris_kernel__)
+#include <ucred.h>
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_SOLARIS_UCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_SOLARIS_UCRED
+#define G_CREDENTIALS_NATIVE_SIZE (ucred_size ())
+#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_HAS_PID 1
+
+#elif defined(__APPLE__)
+#include <sys/ucred.h>
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_APPLE_XUCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_APPLE_XUCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct xucred))
+#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
+#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+#define G_CREDENTIALS_HAS_PID 0
+
+#endif
+
+#endif /* __G_CREDENTIALS_PRIVATE_H__ */
diff --git a/gio/gdatagrambased.c b/gio/gdatagrambased.c
new file mode 100644
index 0000000..1e1c051
--- /dev/null
+++ b/gio/gdatagrambased.c
@@ -0,0 +1,474 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2015 Collabora Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Philip Withnall <philip.withnall@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gdatagrambased.h"
+
+#include "gcancellable.h"
+#include "gioenumtypes.h"
+#include "gioerror.h"
+#include "gnetworkingprivate.h"
+#include "gsocketaddress.h"
+#include "glibintl.h"
+
+/**
+ * SECTION:gdatagrambased
+ * @short_description: Low-level datagram communications interface
+ * @include: gio/gio.h
+ * @see_also: #GSocket, [<gnetworking.h>][gio-gnetworking.h]
+ *
+ * A #GDatagramBased is a networking interface for representing datagram-based
+ * communications. It is a more or less direct mapping of the core parts of the
+ * BSD socket API in a portable GObject interface. It is implemented by
+ * #GSocket, which wraps the UNIX socket API on UNIX and winsock2 on Windows.
+ *
+ * #GDatagramBased is entirely platform independent, and is intended to be used
+ * alongside higher-level networking APIs such as #GIOStream.
+ *
+ * It uses vectored scatter/gather I/O by default, allowing for many messages
+ * to be sent or received in a single call. Where possible, implementations of
+ * the interface should take advantage of vectored I/O to minimise processing
+ * or system calls. For example, #GSocket uses recvmmsg() and sendmmsg() where
+ * possible. Callers should take advantage of scatter/gather I/O (the use of
+ * multiple buffers per message) to avoid unnecessary copying of data to
+ * assemble or disassemble a message.
+ *
+ * Each #GDatagramBased operation has a timeout parameter which may be negative
+ * for blocking behaviour, zero for non-blocking behaviour, or positive for
+ * timeout behaviour. A blocking operation blocks until finished or there is an
+ * error. A non-blocking operation will return immediately with a
+ * %G_IO_ERROR_WOULD_BLOCK error if it cannot make progress. A timeout operation
+ * will block until the operation is complete or the timeout expires; if the
+ * timeout expires it will return what progress it made, or
+ * %G_IO_ERROR_TIMED_OUT if no progress was made. To know when a call would
+ * successfully run you can call g_datagram_based_condition_check() or
+ * g_datagram_based_condition_wait(). You can also use
+ * g_datagram_based_create_source() and attach it to a #GMainContext to get
+ * callbacks when I/O is possible.
+ *
+ * When running a non-blocking operation applications should always be able to
+ * handle getting a %G_IO_ERROR_WOULD_BLOCK error even when some other function
+ * said that I/O was possible. This can easily happen in case of a race
+ * condition in the application, but it can also happen for other reasons. For
+ * instance, on Windows a socket is always seen as writable until a write
+ * returns %G_IO_ERROR_WOULD_BLOCK.
+ *
+ * As with #GSocket, #GDatagramBaseds can be either connection oriented (for
+ * example, SCTP) or connectionless (for example, UDP). #GDatagramBaseds must be
+ * datagram-based, not stream-based. The interface does not cover connection
+ * establishment — use methods on the underlying type to establish a connection
+ * before sending and receiving data through the #GDatagramBased API. For
+ * connectionless socket types the target/source address is specified or
+ * received in each I/O operation.
+ *
+ * Like most other APIs in GLib, #GDatagramBased is not inherently thread safe.
+ * To use a #GDatagramBased concurrently from multiple threads, you must
+ * implement your own locking.
+ *
+ * Since: 2.48
+ */
+
+G_DEFINE_INTERFACE (GDatagramBased, g_datagram_based, G_TYPE_OBJECT)
+
+static void
+g_datagram_based_default_init (GDatagramBasedInterface *iface)
+{
+  /* Nothing here. */
+}
+
+/**
+ * g_datagram_based_receive_messages:
+ * @datagram_based: a #GDatagramBased
+ * @messages: (array length=num_messages): an array of #GInputMessage structs
+ * @num_messages: the number of elements in @messages
+ * @flags: an int containing #GSocketMsgFlags flags for the overall operation
+ * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1
+ *   to block indefinitely
+ * @cancellable: (nullable): a %GCancellable
+ * @error: return location for a #GError
+ *
+ * Receive one or more data messages from @datagram_based in one go.
+ *
+ * @messages must point to an array of #GInputMessage structs and
+ * @num_messages must be the length of this array. Each #GInputMessage
+ * contains a pointer to an array of #GInputVector structs describing the
+ * buffers that the data received in each message will be written to.
+ *
+ * @flags modify how all messages are received. The commonly available
+ * arguments for this are available in the #GSocketMsgFlags enum, but the
+ * values there are the same as the system values, and the flags
+ * are passed in as-is, so you can pass in system-specific flags too. These
+ * flags affect the overall receive operation. Flags affecting individual
+ * messages are returned in #GInputMessage.flags.
+ *
+ * The other members of #GInputMessage are treated as described in its
+ * documentation.
+ *
+ * If @timeout is negative the call will block until @num_messages have been
+ * received, the connection is closed remotely (EOS), @cancellable is cancelled,
+ * or an error occurs.
+ *
+ * If @timeout is 0 the call will return up to @num_messages without blocking,
+ * or %G_IO_ERROR_WOULD_BLOCK if no messages are queued in the operating system
+ * to be received.
+ *
+ * If @timeout is positive the call will block on the same conditions as if
+ * @timeout were negative. If the timeout is reached
+ * before any messages are received, %G_IO_ERROR_TIMED_OUT is returned,
+ * otherwise it will return the number of messages received before timing out.
+ * (Note: This is effectively the behaviour of `MSG_WAITFORONE` with
+ * recvmmsg().)
+ *
+ * To be notified when messages are available, wait for the %G_IO_IN condition.
+ * Note though that you may still receive %G_IO_ERROR_WOULD_BLOCK from
+ * g_datagram_based_receive_messages() even if you were previously notified of a
+ * %G_IO_IN condition.
+ *
+ * If the remote peer closes the connection, any messages queued in the
+ * underlying receive buffer will be returned, and subsequent calls to
+ * g_datagram_based_receive_messages() will return 0 (with no error set).
+ *
+ * If the connection is shut down or closed (by calling g_socket_close() or
+ * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket, for
+ * example), all calls to this function will return %G_IO_ERROR_CLOSED.
+ *
+ * On error -1 is returned and @error is set accordingly. An error will only
+ * be returned if zero messages could be received; otherwise the number of
+ * messages successfully received before the error will be returned. If
+ * @cancellable is cancelled, %G_IO_ERROR_CANCELLED is returned as with any
+ * other error.
+ *
+ * Returns: number of messages received, or -1 on error. Note that the number
+ *     of messages received may be smaller than @num_messages if @timeout is
+ *     zero or positive, if the peer closed the connection, or if @num_messages
+ *     was larger than `UIO_MAXIOV` (1024), in which case the caller may re-try
+ *     to receive the remaining messages.
+ *
+ * Since: 2.48
+ */
+gint
+g_datagram_based_receive_messages (GDatagramBased  *datagram_based,
+                                   GInputMessage   *messages,
+                                   guint            num_messages,
+                                   gint             flags,
+                                   gint64           timeout,
+                                   GCancellable    *cancellable,
+                                   GError         **error)
+{
+  GDatagramBasedInterface *iface;
+  gint retval;
+  GError *child_error = NULL;
+
+  g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), -1);
+  g_return_val_if_fail (num_messages == 0 || messages != NULL, -1);
+  g_return_val_if_fail (cancellable == NULL ||
+                        G_IS_CANCELLABLE (cancellable), -1);
+  g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+  iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
+  g_assert (iface->receive_messages != NULL);
+
+  retval = iface->receive_messages (datagram_based, messages, num_messages,
+                                    flags, timeout, cancellable, &child_error);
+
+  /* Postconditions. */
+  g_return_val_if_fail ((retval < 0) == (child_error != NULL), -1);
+  g_return_val_if_fail (timeout == 0 ||
+                        !g_error_matches (child_error, G_IO_ERROR,
+                                          G_IO_ERROR_WOULD_BLOCK), -1);
+  g_return_val_if_fail (timeout > 0 ||
+                        !g_error_matches (child_error, G_IO_ERROR,
+                                          G_IO_ERROR_TIMED_OUT), -1);
+  g_return_val_if_fail (retval < 0 || (guint) retval <= num_messages, -1);
+
+  if (child_error != NULL)
+      g_propagate_error (error, child_error);
+
+  return retval;
+}
+
+/**
+ * g_datagram_based_send_messages:
+ * @datagram_based: a #GDatagramBased
+ * @messages: (array length=num_messages): an array of #GOutputMessage structs
+ * @num_messages: the number of elements in @messages
+ * @flags: an int containing #GSocketMsgFlags flags
+ * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1
+ *   to block indefinitely
+ * @cancellable: (nullable): a %GCancellable
+ * @error: return location for a #GError
+ *
+ * Send one or more data messages from @datagram_based in one go.
+ *
+ * @messages must point to an array of #GOutputMessage structs and
+ * @num_messages must be the length of this array. Each #GOutputMessage
+ * contains an address to send the data to, and a pointer to an array of
+ * #GOutputVector structs to describe the buffers that the data to be sent
+ * for each message will be gathered from.
+ *
+ * @flags modify how the message is sent. The commonly available arguments
+ * for this are available in the #GSocketMsgFlags enum, but the
+ * values there are the same as the system values, and the flags
+ * are passed in as-is, so you can pass in system-specific flags too.
+ *
+ * The other members of #GOutputMessage are treated as described in its
+ * documentation.
+ *
+ * If @timeout is negative the call will block until @num_messages have been
+ * sent, @cancellable is cancelled, or an error occurs.
+ *
+ * If @timeout is 0 the call will send up to @num_messages without blocking,
+ * or will return %G_IO_ERROR_WOULD_BLOCK if there is no space to send messages.
+ *
+ * If @timeout is positive the call will block on the same conditions as if
+ * @timeout were negative. If the timeout is reached before any messages are
+ * sent, %G_IO_ERROR_TIMED_OUT is returned, otherwise it will return the number
+ * of messages sent before timing out.
+ *
+ * To be notified when messages can be sent, wait for the %G_IO_OUT condition.
+ * Note though that you may still receive %G_IO_ERROR_WOULD_BLOCK from
+ * g_datagram_based_send_messages() even if you were previously notified of a
+ * %G_IO_OUT condition. (On Windows in particular, this is very common due to
+ * the way the underlying APIs work.)
+ *
+ * If the connection is shut down or closed (by calling g_socket_close() or
+ * g_socket_shutdown() with @shutdown_write set, if it’s a #GSocket, for
+ * example), all calls to this function will return %G_IO_ERROR_CLOSED.
+ *
+ * On error -1 is returned and @error is set accordingly. An error will only
+ * be returned if zero messages could be sent; otherwise the number of messages
+ * successfully sent before the error will be returned. If @cancellable is
+ * cancelled, %G_IO_ERROR_CANCELLED is returned as with any other error.
+ *
+ * Returns: number of messages sent, or -1 on error. Note that the number of
+ *     messages sent may be smaller than @num_messages if @timeout is zero
+ *     or positive, or if @num_messages was larger than `UIO_MAXIOV` (1024), in
+ *     which case the caller may re-try to send the remaining messages.
+ *
+ * Since: 2.48
+ */
+gint
+g_datagram_based_send_messages (GDatagramBased   *datagram_based,
+                                GOutputMessage   *messages,
+                                guint             num_messages,
+                                gint              flags,
+                                gint64            timeout,
+                                GCancellable     *cancellable,
+                                GError          **error)
+{
+  GDatagramBasedInterface *iface;
+  gint retval;
+  GError *child_error = NULL;
+
+  g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), -1);
+  g_return_val_if_fail (num_messages == 0 || messages != NULL, -1);
+  g_return_val_if_fail (cancellable == NULL ||
+                        G_IS_CANCELLABLE (cancellable), -1);
+  g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+  iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
+  g_assert (iface->send_messages != NULL);
+
+  retval = iface->send_messages (datagram_based, messages, num_messages, flags,
+                                 timeout, cancellable, &child_error);
+
+  /* Postconditions. */
+  g_return_val_if_fail ((retval < 0) == (child_error != NULL), -1);
+  g_return_val_if_fail (timeout == 0 ||
+                        !g_error_matches (child_error, G_IO_ERROR,
+                                          G_IO_ERROR_WOULD_BLOCK), -1);
+  g_return_val_if_fail (timeout > 0 ||
+                        !g_error_matches (child_error, G_IO_ERROR,
+                                          G_IO_ERROR_TIMED_OUT), -1);
+  g_return_val_if_fail (retval < 0 || (guint) retval <= num_messages, -1);
+  g_return_val_if_fail (!(timeout < 0 && num_messages > 0) || retval != 0, -1);
+
+  if (child_error != NULL)
+      g_propagate_error (error, child_error);
+
+  return retval;
+}
+
+/**
+ * g_datagram_based_create_source:
+ * @datagram_based: a #GDatagramBased
+ * @condition: a #GIOCondition mask to monitor
+ * @cancellable: (nullable): a #GCancellable
+ *
+ * Creates a #GSource that can be attached to a #GMainContext to monitor for
+ * the availability of the specified @condition on the #GDatagramBased. The
+ * #GSource keeps a reference to the @datagram_based.
+ *
+ * The callback on the source is of the #GDatagramBasedSourceFunc type.
+ *
+ * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; these
+ * conditions will always be reported in the callback if they are true.
+ *
+ * If non-%NULL, @cancellable can be used to cancel the source, which will
+ * cause the source to trigger, reporting the current condition (which is
+ * likely 0 unless cancellation happened at the same time as a condition
+ * change). You can check for this in the callback using
+ * g_cancellable_is_cancelled().
+ *
+ * Returns: (transfer full): a newly allocated #GSource
+ *
+ * Since: 2.48
+ */
+GSource *
+g_datagram_based_create_source (GDatagramBased *datagram_based,
+                                GIOCondition    condition,
+                                GCancellable   *cancellable)
+{
+  GDatagramBasedInterface *iface;
+
+  g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), NULL);
+  g_return_val_if_fail (cancellable == NULL ||
+                        G_IS_CANCELLABLE (cancellable), NULL);
+
+  iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
+  g_assert (iface->create_source != NULL);
+
+  return iface->create_source (datagram_based, condition, cancellable);
+}
+
+/**
+ * g_datagram_based_condition_check:
+ * @datagram_based: a #GDatagramBased
+ * @condition: a #GIOCondition mask to check
+ *
+ * Checks on the readiness of @datagram_based to perform operations. The
+ * operations specified in @condition are checked for and masked against the
+ * currently-satisfied conditions on @datagram_based. The result is returned.
+ *
+ * %G_IO_IN will be set in the return value if data is available to read with
+ * g_datagram_based_receive_messages(), or if the connection is closed remotely
+ * (EOS); and if the datagram_based has not been closed locally using some
+ * implementation-specific method (such as g_socket_close() or
+ * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket).
+ *
+ * If the connection is shut down or closed (by calling g_socket_close() or
+ * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket, for
+ * example), all calls to this function will return %G_IO_ERROR_CLOSED.
+ *
+ * %G_IO_OUT will be set if it is expected that at least one byte can be sent
+ * using g_datagram_based_send_messages() without blocking. It will not be set
+ * if the datagram_based has been closed locally.
+ *
+ * %G_IO_HUP will be set if the connection has been closed locally.
+ *
+ * %G_IO_ERR will be set if there was an asynchronous error in transmitting data
+ * previously enqueued using g_datagram_based_send_messages().
+ *
+ * Note that on Windows, it is possible for an operation to return
+ * %G_IO_ERROR_WOULD_BLOCK even immediately after
+ * g_datagram_based_condition_check() has claimed that the #GDatagramBased is
+ * ready for writing. Rather than calling g_datagram_based_condition_check() and
+ * then writing to the #GDatagramBased if it succeeds, it is generally better to
+ * simply try writing right away, and try again later if the initial attempt
+ * returns %G_IO_ERROR_WOULD_BLOCK.
+ *
+ * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; these
+ * conditions will always be set in the output if they are true. Apart from
+ * these flags, the output is guaranteed to be masked by @condition.
+ *
+ * This call never blocks.
+ *
+ * Returns: the #GIOCondition mask of the current state
+ *
+ * Since: 2.48
+ */
+GIOCondition
+g_datagram_based_condition_check (GDatagramBased *datagram_based,
+                                  GIOCondition    condition)
+{
+  GDatagramBasedInterface *iface;
+  GIOCondition out;
+
+  g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), 0);
+
+  iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
+  g_assert (iface->condition_check != NULL);
+
+  out = iface->condition_check (datagram_based, condition);
+
+  /* Postconditions. G_IO_OUT and G_IO_HUP are mutually exclusive. G_IO_IN and
+   * G_IO_HUP are mutually exclusive. The return value must be a subset of
+   * (condition | G_IO_ERR | G_IO_HUP). */
+  g_return_val_if_fail ((out & (G_IO_OUT | G_IO_HUP)) != (G_IO_OUT | G_IO_HUP),
+                        out & ~G_IO_OUT);
+  g_return_val_if_fail ((out & (G_IO_IN | G_IO_HUP)) != (G_IO_IN | G_IO_HUP),
+                        out & ~G_IO_IN);
+  g_return_val_if_fail ((out & ~(condition | G_IO_ERR | G_IO_HUP)) == 0,
+                        out & (condition | G_IO_ERR | G_IO_HUP));
+
+  return out;
+}
+
+/**
+ * g_datagram_based_condition_wait:
+ * @datagram_based: a #GDatagramBased
+ * @condition: a #GIOCondition mask to wait for
+ * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1
+ *   to block indefinitely
+ * @cancellable: (nullable): a #GCancellable
+ * @error: return location for a #GError
+ *
+ * Waits for up to @timeout microseconds for condition to become true on
+ * @datagram_based. If the condition is met, %TRUE is returned.
+ *
+ * If @cancellable is cancelled before the condition is met, or if @timeout is
+ * reached before the condition is met, then %FALSE is returned and @error is
+ * set appropriately (%G_IO_ERROR_CANCELLED or %G_IO_ERROR_TIMED_OUT).
+ *
+ * Returns: %TRUE if the condition was met, %FALSE otherwise
+ *
+ * Since: 2.48
+ */
+gboolean
+g_datagram_based_condition_wait (GDatagramBased  *datagram_based,
+                                 GIOCondition     condition,
+                                 gint64           timeout,
+                                 GCancellable    *cancellable,
+                                 GError         **error)
+{
+  GDatagramBasedInterface *iface;
+  gboolean out;
+  GError *child_error = NULL;
+
+  g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), FALSE);
+  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable),
+                        FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
+  g_assert (iface->condition_wait != NULL);
+
+  out = iface->condition_wait (datagram_based, condition, timeout,
+                               cancellable, &child_error);
+
+  /* Postconditions. */
+  g_return_val_if_fail (out == (child_error == NULL), FALSE);
+
+  if (child_error != NULL)
+    g_propagate_error (error, child_error);
+
+  return out;
+}
diff --git a/gio/gdatagrambased.h b/gio/gdatagrambased.h
new file mode 100644
index 0000000..838b485
--- /dev/null
+++ b/gio/gdatagrambased.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2015 Collabora Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Philip Withnall <philip.withnall@collabora.co.uk>
+ */
+
+#ifndef __G_DATAGRAM_BASED_H__
+#define __G_DATAGRAM_BASED_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_DATAGRAM_BASED             (g_datagram_based_get_type ())
+#define G_DATAGRAM_BASED(inst)            (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+                                           G_TYPE_DATAGRAM_BASED, GDatagramBased))
+#define G_IS_DATAGRAM_BASED(inst)         (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+                                           G_TYPE_DATAGRAM_BASED))
+#define G_DATAGRAM_BASED_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
+                                           G_TYPE_DATAGRAM_BASED, \
+                                           GDatagramBasedInterface))
+#define G_TYPE_IS_DATAGRAM_BASED(type)    (g_type_is_a ((type), \
+                                           G_TYPE_DATAGRAM_BASED))
+
+/**
+ * GDatagramBased:
+ *
+ * Interface for socket-like objects with datagram semantics.
+ *
+ * Since: 2.48
+ */
+typedef struct _GDatagramBasedInterface GDatagramBasedInterface;
+
+/**
+ * GDatagramBasedInterface:
+ * @g_iface: The parent interface.
+ * @receive_messages: Virtual method for g_datagram_based_receive_messages().
+ * @send_messages: Virtual method for g_datagram_based_send_messages().
+ * @create_source: Virtual method for g_datagram_based_create_source().
+ * @condition_check: Virtual method for g_datagram_based_condition_check().
+ * @condition_wait: Virtual method for
+ *   g_datagram_based_condition_wait().
+ *
+ * Provides an interface for socket-like objects which have datagram semantics,
+ * following the Berkeley sockets API. The interface methods are thin wrappers
+ * around the corresponding virtual methods, and no pre-processing of inputs is
+ * implemented — so implementations of this API must handle all functionality
+ * documented in the interface methods.
+ *
+ * Since: 2.48
+ */
+struct _GDatagramBasedInterface
+{
+  GTypeInterface g_iface;
+
+  /* Virtual table */
+  gint          (*receive_messages)     (GDatagramBased       *datagram_based,
+                                         GInputMessage        *messages,
+                                         guint                 num_messages,
+                                         gint                  flags,
+                                         gint64                timeout,
+                                         GCancellable         *cancellable,
+                                         GError              **error);
+  gint          (*send_messages)        (GDatagramBased       *datagram_based,
+                                         GOutputMessage       *messages,
+                                         guint                 num_messages,
+                                         gint                  flags,
+                                         gint64                timeout,
+                                         GCancellable         *cancellable,
+                                         GError              **error);
+
+  GSource      *(*create_source)        (GDatagramBased       *datagram_based,
+                                         GIOCondition          condition,
+                                         GCancellable         *cancellable);
+  GIOCondition  (*condition_check)      (GDatagramBased       *datagram_based,
+                                         GIOCondition          condition);
+  gboolean      (*condition_wait)       (GDatagramBased       *datagram_based,
+                                         GIOCondition          condition,
+                                         gint64                timeout,
+                                         GCancellable         *cancellable,
+                                         GError              **error);
+};
+
+GLIB_AVAILABLE_IN_2_48
+GType
+g_datagram_based_get_type             (void);
+
+GLIB_AVAILABLE_IN_2_48
+gint
+g_datagram_based_receive_messages     (GDatagramBased       *datagram_based,
+                                       GInputMessage        *messages,
+                                       guint                 num_messages,
+                                       gint                  flags,
+                                       gint64                timeout,
+                                       GCancellable         *cancellable,
+                                       GError              **error);
+
+GLIB_AVAILABLE_IN_2_48
+gint
+g_datagram_based_send_messages        (GDatagramBased       *datagram_based,
+                                       GOutputMessage       *messages,
+                                       guint                 num_messages,
+                                       gint                  flags,
+                                       gint64                timeout,
+                                       GCancellable         *cancellable,
+                                       GError              **error);
+
+GLIB_AVAILABLE_IN_2_48
+GSource *
+g_datagram_based_create_source        (GDatagramBased       *datagram_based,
+                                       GIOCondition          condition,
+                                       GCancellable         *cancellable);
+GLIB_AVAILABLE_IN_2_48
+GIOCondition
+g_datagram_based_condition_check      (GDatagramBased       *datagram_based,
+                                       GIOCondition          condition);
+GLIB_AVAILABLE_IN_2_48
+gboolean
+g_datagram_based_condition_wait       (GDatagramBased       *datagram_based,
+                                       GIOCondition          condition,
+                                       gint64                timeout,
+                                       GCancellable         *cancellable,
+                                       GError              **error);
+
+G_END_DECLS
+
+#endif /* __G_DATAGRAM_BASED_H__ */
diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c
new file mode 100644
index 0000000..2e7750c
--- /dev/null
+++ b/gio/gdatainputstream.c
@@ -0,0 +1,1469 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2007 Jürg Billeter
+ * Copyright © 2009 Codethink Limited
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include "gdatainputstream.h"
+#include "gtask.h"
+#include "gcancellable.h"
+#include "gioenumtypes.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gdatainputstream
+ * @short_description: Data Input Stream
+ * @include: gio/gio.h
+ * @see_also: #GInputStream
+ * 
+ * Data input stream implements #GInputStream and includes functions for 
+ * reading structured data directly from a binary input stream.
+ *
+ **/
+
+struct _GDataInputStreamPrivate {
+  GDataStreamByteOrder byte_order;
+  GDataStreamNewlineType newline_type;
+};
+
+enum {
+  PROP_0,
+  PROP_BYTE_ORDER,
+  PROP_NEWLINE_TYPE
+};
+
+static void g_data_input_stream_set_property (GObject      *object,
+					      guint         prop_id,
+					      const GValue *value,
+					      GParamSpec   *pspec);
+static void g_data_input_stream_get_property (GObject      *object,
+					      guint         prop_id,
+					      GValue       *value,
+					      GParamSpec   *pspec);
+
+G_DEFINE_TYPE_WITH_PRIVATE (GDataInputStream,
+                            g_data_input_stream,
+                            G_TYPE_BUFFERED_INPUT_STREAM)
+
+
+static void
+g_data_input_stream_class_init (GDataInputStreamClass *klass)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = g_data_input_stream_get_property;
+  object_class->set_property = g_data_input_stream_set_property;
+
+  /**
+   * GDataStream:byte-order:
+   *
+   * The ::byte-order property determines the byte ordering that
+   * is used when reading multi-byte entities (such as integers)
+   * from the stream.
+   */ 
+  g_object_class_install_property (object_class,
+                                   PROP_BYTE_ORDER,
+                                   g_param_spec_enum ("byte-order",
+                                                      P_("Byte order"),
+                                                      P_("The byte order"),
+                                                      G_TYPE_DATA_STREAM_BYTE_ORDER,
+                                                      G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
+                                                      G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
+
+  /**
+   * GDataStream:newline-type:
+   *
+   * The :newline-type property determines what is considered
+   * as a line ending when reading complete lines from the stream.
+   */ 
+  g_object_class_install_property (object_class,
+                                   PROP_NEWLINE_TYPE,
+                                   g_param_spec_enum ("newline-type",
+                                                      P_("Newline type"),
+                                                      P_("The accepted types of line ending"),
+                                                      G_TYPE_DATA_STREAM_NEWLINE_TYPE,
+                                                      G_DATA_STREAM_NEWLINE_TYPE_LF,
+                                                      G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
+}
+
+static void
+g_data_input_stream_set_property (GObject      *object,
+				  guint         prop_id,
+				  const GValue *value,
+				  GParamSpec   *pspec)
+{
+  GDataInputStream        *dstream;
+
+  dstream = G_DATA_INPUT_STREAM (object);
+
+   switch (prop_id)
+    {
+    case PROP_BYTE_ORDER:
+      g_data_input_stream_set_byte_order (dstream, g_value_get_enum (value));
+      break;
+
+    case PROP_NEWLINE_TYPE:
+      g_data_input_stream_set_newline_type (dstream, g_value_get_enum (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+
+static void
+g_data_input_stream_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+  GDataInputStreamPrivate *priv;
+  GDataInputStream        *dstream;
+
+  dstream = G_DATA_INPUT_STREAM (object);
+  priv = dstream->priv;
+
+  switch (prop_id)
+    { 
+    case PROP_BYTE_ORDER:
+      g_value_set_enum (value, priv->byte_order);
+      break;
+
+    case PROP_NEWLINE_TYPE:
+      g_value_set_enum (value, priv->newline_type);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+}
+static void
+g_data_input_stream_init (GDataInputStream *stream)
+{
+  stream->priv = g_data_input_stream_get_instance_private (stream);
+  stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
+  stream->priv->newline_type = G_DATA_STREAM_NEWLINE_TYPE_LF;
+}
+
+/**
+ * g_data_input_stream_new:
+ * @base_stream: a #GInputStream.
+ * 
+ * Creates a new data input stream for the @base_stream.
+ * 
+ * Returns: a new #GDataInputStream.
+ **/
+GDataInputStream *
+g_data_input_stream_new (GInputStream *base_stream)
+{
+  GDataInputStream *stream;
+
+  g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_DATA_INPUT_STREAM,
+                         "base-stream", base_stream,
+                         NULL);
+
+  return stream;
+}
+
+/**
+ * g_data_input_stream_set_byte_order:
+ * @stream: a given #GDataInputStream.
+ * @order: a #GDataStreamByteOrder to set.
+ * 
+ * This function sets the byte order for the given @stream. All subsequent
+ * reads from the @stream will be read in the given @order.
+ *  
+ **/
+void
+g_data_input_stream_set_byte_order (GDataInputStream     *stream,
+				    GDataStreamByteOrder  order)
+{
+  GDataInputStreamPrivate *priv;
+
+  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
+
+  priv = stream->priv;
+
+  if (priv->byte_order != order)
+    {
+      priv->byte_order = order;
+      
+      g_object_notify (G_OBJECT (stream), "byte-order");
+    }
+}
+
+/**
+ * g_data_input_stream_get_byte_order:
+ * @stream: a given #GDataInputStream.
+ * 
+ * Gets the byte order for the data input stream.
+ * 
+ * Returns: the @stream's current #GDataStreamByteOrder. 
+ **/
+GDataStreamByteOrder
+g_data_input_stream_get_byte_order (GDataInputStream *stream)
+{
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
+
+  return stream->priv->byte_order;
+}
+
+/**
+ * g_data_input_stream_set_newline_type:
+ * @stream: a #GDataInputStream.
+ * @type: the type of new line return as #GDataStreamNewlineType.
+ * 
+ * Sets the newline type for the @stream.
+ * 
+ * Note that using G_DATA_STREAM_NEWLINE_TYPE_ANY is slightly unsafe. If a read
+ * chunk ends in "CR" we must read an additional byte to know if this is "CR" or
+ * "CR LF", and this might block if there is no more data available.
+ *  
+ **/
+void
+g_data_input_stream_set_newline_type (GDataInputStream       *stream,
+				      GDataStreamNewlineType  type)
+{
+  GDataInputStreamPrivate *priv;
+
+  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
+
+  priv = stream->priv;
+  
+  if (priv->newline_type != type)
+    {
+      priv->newline_type = type;
+
+      g_object_notify (G_OBJECT (stream), "newline-type");
+    }
+}
+
+/**
+ * g_data_input_stream_get_newline_type:
+ * @stream: a given #GDataInputStream.
+ * 
+ * Gets the current newline type for the @stream.
+ * 
+ * Returns: #GDataStreamNewlineType for the given @stream.
+ **/
+GDataStreamNewlineType
+g_data_input_stream_get_newline_type (GDataInputStream *stream)
+{
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_NEWLINE_TYPE_ANY);
+
+  return stream->priv->newline_type;
+}
+
+static gboolean
+read_data (GDataInputStream  *stream,
+           void              *buffer,
+           gsize              size,
+           GCancellable      *cancellable,
+           GError           **error)
+{
+  gsize available;
+  gssize res;
+
+  while ((available = g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (stream))) < size)
+    {
+      res = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (stream),
+					  size - available,
+					  cancellable, error);
+      if (res < 0)
+	return FALSE;
+      if (res == 0)
+	{
+	  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               _("Unexpected early end-of-stream"));
+	  return FALSE;
+	}
+    }
+  
+  /* This should always succeed, since it's in the buffer */
+  res = g_input_stream_read (G_INPUT_STREAM (stream),
+			     buffer, size,
+			     NULL, NULL);
+  g_warn_if_fail (res == size);
+  return TRUE;
+}
+
+
+/**
+ * g_data_input_stream_read_byte:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ * 
+ * Reads an unsigned 8-bit/1-byte value from @stream.
+ *
+ * Returns: an unsigned 8-bit/1-byte value read from the @stream or `0`
+ * if an error occurred.
+ **/
+guchar
+g_data_input_stream_read_byte (GDataInputStream  *stream,
+			       GCancellable       *cancellable,
+			       GError            **error)
+{
+  guchar c;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), '\0');
+  
+  if (read_data (stream, &c, 1, cancellable, error))
+      return c;
+  
+  return 0;
+}
+
+
+/**
+ * g_data_input_stream_read_int16:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ * 
+ * Reads a 16-bit/2-byte value from @stream.
+ *
+ * In order to get the correct byte order for this read operation, 
+ * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
+ * 
+ * Returns: a signed 16-bit/2-byte value read from @stream or `0` if
+ * an error occurred.
+ **/
+gint16
+g_data_input_stream_read_int16 (GDataInputStream  *stream,
+			       GCancellable       *cancellable,
+			       GError            **error)
+{
+  gint16 v;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
+  
+  if (read_data (stream, &v, 2, cancellable, error))
+    {
+      switch (stream->priv->byte_order)
+	{
+	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+	  v = GINT16_FROM_BE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+	  v = GINT16_FROM_LE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+	default:
+	  break;
+	}
+      return v;
+    }
+  
+  return 0;
+}
+
+
+/**
+ * g_data_input_stream_read_uint16:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ *
+ * Reads an unsigned 16-bit/2-byte value from @stream.
+ *
+ * In order to get the correct byte order for this read operation, 
+ * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). 
+ * 
+ * Returns: an unsigned 16-bit/2-byte value read from the @stream or `0` if
+ * an error occurred. 
+ **/
+guint16
+g_data_input_stream_read_uint16 (GDataInputStream  *stream,
+				 GCancellable       *cancellable,
+				 GError            **error)
+{
+  guint16 v;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
+  
+  if (read_data (stream, &v, 2, cancellable, error))
+    {
+      switch (stream->priv->byte_order)
+	{
+	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+	  v = GUINT16_FROM_BE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+	  v = GUINT16_FROM_LE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+	default:
+	  break;
+	}
+      return v;
+    }
+  
+  return 0;
+}
+
+
+/**
+ * g_data_input_stream_read_int32:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ * 
+ * Reads a signed 32-bit/4-byte value from @stream.
+ *
+ * In order to get the correct byte order for this read operation, 
+ * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
+ *   
+ * Returns: a signed 32-bit/4-byte value read from the @stream or `0` if
+ * an error occurred. 
+ **/
+gint32
+g_data_input_stream_read_int32 (GDataInputStream  *stream,
+				GCancellable       *cancellable,
+				GError            **error)
+{
+  gint32 v;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
+  
+  if (read_data (stream, &v, 4, cancellable, error))
+    {
+      switch (stream->priv->byte_order)
+	{
+	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+	  v = GINT32_FROM_BE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+	  v = GINT32_FROM_LE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+	default:
+	  break;
+	}
+      return v;
+    }
+  
+  return 0;
+}
+
+
+/**
+ * g_data_input_stream_read_uint32:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ * 
+ * Reads an unsigned 32-bit/4-byte value from @stream.
+ *
+ * In order to get the correct byte order for this read operation, 
+ * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
+ * 
+ * Returns: an unsigned 32-bit/4-byte value read from the @stream or `0` if
+ * an error occurred. 
+ **/
+guint32
+g_data_input_stream_read_uint32 (GDataInputStream  *stream,
+				 GCancellable       *cancellable,
+				 GError            **error)
+{
+  guint32 v;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
+  
+  if (read_data (stream, &v, 4, cancellable, error))
+    {
+      switch (stream->priv->byte_order)
+	{
+	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+	  v = GUINT32_FROM_BE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+	  v = GUINT32_FROM_LE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+	default:
+	  break;
+	}
+      return v;
+    }
+  
+  return 0;
+}
+
+
+/**
+ * g_data_input_stream_read_int64:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ * 
+ * Reads a 64-bit/8-byte value from @stream.
+ *
+ * In order to get the correct byte order for this read operation, 
+ * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
+ * 
+ * Returns: a signed 64-bit/8-byte value read from @stream or `0` if
+ * an error occurred.  
+ **/
+gint64
+g_data_input_stream_read_int64 (GDataInputStream  *stream,
+			       GCancellable       *cancellable,
+			       GError            **error)
+{
+  gint64 v;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
+  
+  if (read_data (stream, &v, 8, cancellable, error))
+    {
+      switch (stream->priv->byte_order)
+	{
+	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+	  v = GINT64_FROM_BE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+	  v = GINT64_FROM_LE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+	default:
+	  break;
+	}
+      return v;
+    }
+  
+  return 0;
+}
+
+
+/**
+ * g_data_input_stream_read_uint64:
+ * @stream: a given #GDataInputStream.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ * 
+ * Reads an unsigned 64-bit/8-byte value from @stream.
+ *
+ * In order to get the correct byte order for this read operation, 
+ * see g_data_input_stream_get_byte_order().
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
+ * 
+ * Returns: an unsigned 64-bit/8-byte read from @stream or `0` if
+ * an error occurred. 
+ **/
+guint64
+g_data_input_stream_read_uint64 (GDataInputStream  *stream,
+				GCancellable       *cancellable,
+				GError            **error)
+{
+  guint64 v;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
+  
+  if (read_data (stream, &v, 8, cancellable, error))
+    {
+      switch (stream->priv->byte_order)
+	{
+	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+	  v = GUINT64_FROM_BE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+	  v = GUINT64_FROM_LE (v);
+	  break;
+	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+	default:
+	  break;
+	}
+      return v;
+    }
+  
+  return 0;
+}
+
+static gssize
+scan_for_newline (GDataInputStream *stream,
+		  gsize            *checked_out,
+		  gboolean         *last_saw_cr_out,
+		  int              *newline_len_out)
+{
+  GBufferedInputStream *bstream;
+  GDataInputStreamPrivate *priv;
+  const char *buffer;
+  gsize start, end, peeked;
+  int i;
+  gssize found_pos;
+  int newline_len;
+  gsize available, checked;
+  gboolean last_saw_cr;
+
+  priv = stream->priv;
+  
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+
+  checked = *checked_out;
+  last_saw_cr = *last_saw_cr_out;
+  found_pos = -1;
+  newline_len = 0;
+  
+  start = checked;
+  buffer = (const char*)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
+  end = available;
+  peeked = end - start;
+
+  for (i = 0; checked < available && i < peeked; i++)
+    {
+      switch (priv->newline_type)
+	{
+	case G_DATA_STREAM_NEWLINE_TYPE_LF:
+	  if (buffer[i] == 10)
+	    {
+	      found_pos = start + i;
+	      newline_len = 1;
+	    }
+	  break;
+	case G_DATA_STREAM_NEWLINE_TYPE_CR:
+	  if (buffer[i] == 13)
+	    {
+	      found_pos = start + i;
+	      newline_len = 1;
+	    }
+	  break;
+	case G_DATA_STREAM_NEWLINE_TYPE_CR_LF:
+	  if (last_saw_cr && buffer[i] == 10)
+	    {
+	      found_pos = start + i - 1;
+	      newline_len = 2;
+	    }
+	  break;
+	default:
+	case G_DATA_STREAM_NEWLINE_TYPE_ANY:
+	  if (buffer[i] == 10) /* LF */
+	    {
+	      if (last_saw_cr)
+		{
+		  /* CR LF */
+		  found_pos = start + i - 1;
+		  newline_len = 2;
+		}
+	      else
+		{
+		  /* LF */
+		  found_pos = start + i;
+		  newline_len = 1;
+		}
+	    }
+	  else if (last_saw_cr)
+	    {
+	      /* Last was cr, this is not LF, end is CR */
+	      found_pos = start + i - 1;
+	      newline_len = 1;
+	    }
+	  /* Don't check for CR here, instead look at last_saw_cr on next byte */
+	  break;
+	}
+	
+      last_saw_cr = (buffer[i] == 13);
+
+      if (found_pos != -1)
+	{
+	  *newline_len_out = newline_len;
+	  return found_pos;
+	}
+    }
+
+  checked = end;
+
+  *checked_out = checked;
+  *last_saw_cr_out = last_saw_cr;
+  return -1;
+}
+		  
+
+/**
+ * g_data_input_stream_read_line:
+ * @stream: a given #GDataInputStream.
+ * @length: (out) (optional): a #gsize to get the length of the data read in.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ *
+ * Reads a line from the data input stream.  Note that no encoding
+ * checks or conversion is performed; the input is not guaranteed to
+ * be UTF-8, and may in fact have embedded NUL characters.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
+ *
+ * Returns: (nullable) (transfer full) (array zero-terminated=1) (element-type guint8):
+ *  a NUL terminated byte array with the line that was read in
+ *  (without the newlines).  Set @length to a #gsize to get the length
+ *  of the read line.  On an error, it will return %NULL and @error
+ *  will be set. If there's no content to read, it will still return
+ *  %NULL, but @error won't be set.
+ **/
+char *
+g_data_input_stream_read_line (GDataInputStream  *stream,
+			       gsize             *length,
+			       GCancellable      *cancellable,
+			       GError           **error)
+{
+  GBufferedInputStream *bstream;
+  gsize checked;
+  gboolean last_saw_cr;
+  gssize found_pos;
+  gssize res;
+  int newline_len;
+  char *line;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);  
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+
+  newline_len = 0;
+  checked = 0;
+  last_saw_cr = FALSE;
+
+  while ((found_pos = scan_for_newline (stream, &checked, &last_saw_cr, &newline_len)) == -1)
+    {
+      if (g_buffered_input_stream_get_available (bstream) ==
+	  g_buffered_input_stream_get_buffer_size (bstream))
+	g_buffered_input_stream_set_buffer_size (bstream,
+						 2 * g_buffered_input_stream_get_buffer_size (bstream));
+
+      res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
+      if (res < 0)
+	return NULL;
+      if (res == 0)
+	{
+	  /* End of stream */
+	  if (g_buffered_input_stream_get_available (bstream) == 0)
+	    {
+	      if (length)
+		*length = 0;
+	      return NULL;
+	    }
+	  else
+	    {
+	      found_pos = checked;
+	      newline_len = 0;
+	      break;
+	    }
+	}
+    }
+
+  line = g_malloc (found_pos + newline_len + 1);
+
+  res = g_input_stream_read (G_INPUT_STREAM (stream),
+			     line,
+			     found_pos + newline_len,
+			     NULL, NULL);
+  if (length)
+    *length = (gsize)found_pos;
+  g_warn_if_fail (res == found_pos + newline_len);
+  line[found_pos] = 0;
+  
+  return line;
+}
+
+/**
+ * g_data_input_stream_read_line_utf8:
+ * @stream: a given #GDataInputStream.
+ * @length: (out) (optional): a #gsize to get the length of the data read in.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ *
+ * Reads a UTF-8 encoded line from the data input stream.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
+ *
+ * Returns: (nullable) (transfer full): a NUL terminated UTF-8 string
+ *  with the line that was read in (without the newlines).  Set
+ *  @length to a #gsize to get the length of the read line.  On an
+ *  error, it will return %NULL and @error will be set.  For UTF-8
+ *  conversion errors, the set error domain is %G_CONVERT_ERROR.  If
+ *  there's no content to read, it will still return %NULL, but @error
+ *  won't be set.
+ *
+ * Since: 2.30
+ **/
+char *
+g_data_input_stream_read_line_utf8 (GDataInputStream  *stream,
+				    gsize             *length,
+				    GCancellable      *cancellable,
+				    GError           **error)
+{
+  char *res;
+
+  res = g_data_input_stream_read_line (stream, length, cancellable, error);
+  if (!res)
+    return NULL;
+  
+  if (!g_utf8_validate (res, -1, NULL))
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR,
+			   G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+			   _("Invalid byte sequence in conversion input"));
+      g_free (res);
+      return NULL;
+    }
+  return res;
+}
+
+static gssize
+scan_for_chars (GDataInputStream *stream,
+		gsize            *checked_out,
+		const char       *stop_chars,
+                gssize            stop_chars_len)
+{
+  GBufferedInputStream *bstream;
+  const char *buffer;
+  gsize start, end, peeked;
+  int i;
+  gsize available, checked;
+  const char *stop_char;
+  const char *stop_end;
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+  stop_end = stop_chars + stop_chars_len;
+
+  checked = *checked_out;
+
+  start = checked;
+  buffer = (const char *)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
+  end = available;
+  peeked = end - start;
+
+  for (i = 0; checked < available && i < peeked; i++)
+    {
+      for (stop_char = stop_chars; stop_char != stop_end; stop_char++)
+	{
+	  if (buffer[i] == *stop_char)
+	    return (start + i);
+	}
+    }
+
+  checked = end;
+
+  *checked_out = checked;
+  return -1;
+}
+
+/**
+ * g_data_input_stream_read_until:
+ * @stream: a given #GDataInputStream.
+ * @stop_chars: characters to terminate the read.
+ * @length: (out) (optional): a #gsize to get the length of the data read in.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting.
+ *
+ * Reads a string from the data input stream, up to the first
+ * occurrence of any of the stop characters.
+ *
+ * Note that, in contrast to g_data_input_stream_read_until_async(),
+ * this function consumes the stop character that it finds.
+ *
+ * Don't use this function in new code.  Its functionality is
+ * inconsistent with g_data_input_stream_read_until_async().  Both
+ * functions will be marked as deprecated in a future release.  Use
+ * g_data_input_stream_read_upto() instead, but note that that function
+ * does not consume the stop character.
+ *
+ * Returns: (transfer full): a string with the data that was read
+ *     before encountering any of the stop characters. Set @length to
+ *     a #gsize to get the length of the string. This function will
+ *     return %NULL on an error.
+ * Deprecated: 2.56: Use g_data_input_stream_read_upto() instead, which has more
+ *     consistent behaviour regarding the stop character.
+ */
+char *
+g_data_input_stream_read_until (GDataInputStream  *stream,
+			       const gchar        *stop_chars,
+			       gsize              *length,
+			       GCancellable       *cancellable,
+			       GError            **error)
+{
+  GBufferedInputStream *bstream;
+  gchar *result;
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+
+  result = g_data_input_stream_read_upto (stream, stop_chars, -1,
+                                          length, cancellable, error);
+
+  /* If we're not at end of stream then we have a stop_char to consume. */
+  if (result != NULL && g_buffered_input_stream_get_available (bstream) > 0)
+    {
+      gsize res G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
+      gchar b;
+
+      res = g_input_stream_read (G_INPUT_STREAM (stream), &b, 1, NULL, NULL);
+      g_assert (res == 1);
+    }
+
+  return result;
+}
+
+typedef struct
+{
+  gboolean last_saw_cr;
+  gsize checked;
+
+  gchar *stop_chars;
+  gssize stop_chars_len;
+  gsize length;
+} GDataInputStreamReadData;
+
+static void
+g_data_input_stream_read_complete (GTask *task,
+                                   gsize  read_length,
+                                   gsize  skip_length)
+{
+  GDataInputStreamReadData *data = g_task_get_task_data (task);
+  GInputStream *stream = g_task_get_source_object (task);
+  char *line = NULL;
+
+  if (read_length || skip_length)
+    {
+      gssize bytes;
+
+      data->length = read_length;
+      line = g_malloc (read_length + 1);
+      line[read_length] = '\0';
+
+      /* we already checked the buffer.  this shouldn't fail. */
+      bytes = g_input_stream_read (stream, line, read_length, NULL, NULL);
+      g_assert_cmpint (bytes, ==, read_length);
+
+      bytes = g_input_stream_skip (stream, skip_length, NULL, NULL);
+      g_assert_cmpint (bytes, ==, skip_length);
+    }
+
+  g_task_return_pointer (task, line, g_free);
+  g_object_unref (task);
+}
+
+static void
+g_data_input_stream_read_line_ready (GObject      *object,
+                                     GAsyncResult *result,
+                                     gpointer      user_data)
+{
+  GTask *task = user_data;
+  GDataInputStreamReadData *data = g_task_get_task_data (task);
+  GBufferedInputStream *buffer = g_task_get_source_object (task);
+  gssize found_pos;
+  gint newline_len;
+
+  if (result)
+    /* this is a callback.  finish the async call. */
+    {
+      GError *error = NULL;
+      gssize bytes;
+
+      bytes = g_buffered_input_stream_fill_finish (buffer, result, &error);
+
+      if (bytes <= 0)
+        {
+          if (bytes < 0)
+            /* stream error. */
+            {
+              g_task_return_error (task, error);
+              g_object_unref (task);
+              return;
+            }
+
+          g_data_input_stream_read_complete (task, data->checked, 0);
+          return;
+        }
+
+      /* only proceed if we got more bytes... */
+    }
+
+  if (data->stop_chars)
+    {
+      found_pos = scan_for_chars (G_DATA_INPUT_STREAM (buffer),
+                                  &data->checked,
+                                  data->stop_chars,
+                                  data->stop_chars_len);
+      newline_len = 0;
+    }
+  else
+    found_pos = scan_for_newline (G_DATA_INPUT_STREAM (buffer), &data->checked,
+                                  &data->last_saw_cr, &newline_len);
+
+  if (found_pos == -1)
+    /* didn't find a full line; need to buffer some more bytes */
+    {
+      gsize size;
+
+      size = g_buffered_input_stream_get_buffer_size (buffer);
+
+      if (g_buffered_input_stream_get_available (buffer) == size)
+        /* need to grow the buffer */
+        g_buffered_input_stream_set_buffer_size (buffer, size * 2);
+
+      /* try again */
+      g_buffered_input_stream_fill_async (buffer, -1,
+                                          g_task_get_priority (task),
+                                          g_task_get_cancellable (task),
+                                          g_data_input_stream_read_line_ready,
+                                          user_data);
+    }
+  else
+    {
+      /* read the line and the EOL.  no error is possible. */
+      g_data_input_stream_read_complete (task, found_pos, newline_len);
+    }
+}
+
+static void
+g_data_input_stream_read_data_free (gpointer user_data)
+{
+  GDataInputStreamReadData *data = user_data;
+
+  g_free (data->stop_chars);
+  g_slice_free (GDataInputStreamReadData, data);
+}
+
+static void
+g_data_input_stream_read_async (GDataInputStream    *stream,
+                                const gchar         *stop_chars,
+                                gssize               stop_chars_len,
+                                gint                 io_priority,
+                                GCancellable        *cancellable,
+                                GAsyncReadyCallback  callback,
+                                gpointer             user_data)
+{
+  GDataInputStreamReadData *data;
+  GTask *task;
+
+  data = g_slice_new0 (GDataInputStreamReadData);
+  if (stop_chars_len == -1)
+    stop_chars_len = strlen (stop_chars);
+  data->stop_chars = g_memdup (stop_chars, stop_chars_len);
+  data->stop_chars_len = stop_chars_len;
+  data->last_saw_cr = FALSE;
+
+  task = g_task_new (stream, cancellable, callback, user_data);
+  g_task_set_source_tag (task, g_data_input_stream_read_async);
+  g_task_set_task_data (task, data, g_data_input_stream_read_data_free);
+  g_task_set_priority (task, io_priority);
+
+  g_data_input_stream_read_line_ready (NULL, NULL, task);
+}
+
+static gchar *
+g_data_input_stream_read_finish (GDataInputStream  *stream,
+                                 GAsyncResult      *result,
+                                 gsize             *length,
+                                 GError           **error)
+{
+  GTask *task = G_TASK (result);
+  gchar *line;
+
+  line = g_task_propagate_pointer (task, error);
+
+  if (length && line)
+    {
+      GDataInputStreamReadData *data = g_task_get_task_data (task);
+
+      *length = data->length;
+    }
+
+  return line;
+}
+
+/**
+ * g_data_input_stream_read_line_async:
+ * @stream: a given #GDataInputStream.
+ * @io_priority: the [I/O priority][io-priority] of the request
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @callback: (scope async): callback to call when the request is satisfied.
+ * @user_data: (closure): the data to pass to callback function.
+ *
+ * The asynchronous version of g_data_input_stream_read_line().  It is
+ * an error to have two outstanding calls to this function.
+ *
+ * When the operation is finished, @callback will be called. You
+ * can then call g_data_input_stream_read_line_finish() to get
+ * the result of the operation.
+ *
+ * Since: 2.20
+ */
+void
+g_data_input_stream_read_line_async (GDataInputStream    *stream,
+                                     gint                 io_priority,
+                                     GCancellable        *cancellable,
+                                     GAsyncReadyCallback  callback,
+                                     gpointer             user_data)
+{
+  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+  g_data_input_stream_read_async (stream, NULL, 0, io_priority,
+                                  cancellable, callback, user_data);
+}
+
+/**
+ * g_data_input_stream_read_until_async:
+ * @stream: a given #GDataInputStream.
+ * @stop_chars: characters to terminate the read.
+ * @io_priority: the [I/O priority][io-priority] of the request
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @callback: (scope async): callback to call when the request is satisfied.
+ * @user_data: (closure): the data to pass to callback function.
+ *
+ * The asynchronous version of g_data_input_stream_read_until().
+ * It is an error to have two outstanding calls to this function.
+ *
+ * Note that, in contrast to g_data_input_stream_read_until(),
+ * this function does not consume the stop character that it finds.  You
+ * must read it for yourself.
+ *
+ * When the operation is finished, @callback will be called. You
+ * can then call g_data_input_stream_read_until_finish() to get
+ * the result of the operation.
+ *
+ * Don't use this function in new code.  Its functionality is
+ * inconsistent with g_data_input_stream_read_until().  Both functions
+ * will be marked as deprecated in a future release.  Use
+ * g_data_input_stream_read_upto_async() instead.
+ *
+ * Since: 2.20
+ * Deprecated: 2.56: Use g_data_input_stream_read_upto_async() instead, which
+ *     has more consistent behaviour regarding the stop character.
+ */
+void
+g_data_input_stream_read_until_async (GDataInputStream    *stream,
+                                      const gchar         *stop_chars,
+                                      gint                 io_priority,
+                                      GCancellable        *cancellable,
+                                      GAsyncReadyCallback  callback,
+                                      gpointer             user_data)
+{
+  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (stop_chars != NULL);
+
+  g_data_input_stream_read_async (stream, stop_chars, -1, io_priority,
+                                  cancellable, callback, user_data);
+}
+
+/**
+ * g_data_input_stream_read_line_finish:
+ * @stream: a given #GDataInputStream.
+ * @result: the #GAsyncResult that was provided to the callback.
+ * @length: (out) (optional): a #gsize to get the length of the data read in.
+ * @error: #GError for error reporting.
+ *
+ * Finish an asynchronous call started by
+ * g_data_input_stream_read_line_async().  Note the warning about
+ * string encoding in g_data_input_stream_read_line() applies here as
+ * well.
+ *
+ * Returns: (nullable) (transfer full) (array zero-terminated=1) (element-type guint8):
+ *  a NUL-terminated byte array with the line that was read in
+ *  (without the newlines).  Set @length to a #gsize to get the length
+ *  of the read line.  On an error, it will return %NULL and @error
+ *  will be set. If there's no content to read, it will still return
+ *  %NULL, but @error won't be set.
+ *
+ * Since: 2.20
+ */
+gchar *
+g_data_input_stream_read_line_finish (GDataInputStream  *stream,
+                                      GAsyncResult      *result,
+                                      gsize             *length,
+                                      GError           **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
+
+  return g_data_input_stream_read_finish (stream, result, length, error);
+}
+
+/**
+ * g_data_input_stream_read_line_finish_utf8:
+ * @stream: a given #GDataInputStream.
+ * @result: the #GAsyncResult that was provided to the callback.
+ * @length: (out) (optional): a #gsize to get the length of the data read in.
+ * @error: #GError for error reporting.
+ *
+ * Finish an asynchronous call started by
+ * g_data_input_stream_read_line_async().
+ *
+ * Returns: (nullable) (transfer full): a string with the line that
+ *  was read in (without the newlines).  Set @length to a #gsize to
+ *  get the length of the read line.  On an error, it will return
+ *  %NULL and @error will be set. For UTF-8 conversion errors, the set
+ *  error domain is %G_CONVERT_ERROR.  If there's no content to read,
+ *  it will still return %NULL, but @error won't be set.
+ *
+ * Since: 2.30
+ */
+gchar *
+g_data_input_stream_read_line_finish_utf8 (GDataInputStream  *stream,
+					   GAsyncResult      *result,
+					   gsize             *length,
+					   GError           **error)
+{
+  gchar *res;
+
+  res = g_data_input_stream_read_line_finish (stream, result, length, error);
+  if (!res)
+    return NULL;
+
+  if (!g_utf8_validate (res, -1, NULL))
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR,
+			   G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+			   _("Invalid byte sequence in conversion input"));
+      g_free (res);
+      return NULL;
+    }
+  return res;
+}
+
+/**
+ * g_data_input_stream_read_until_finish:
+ * @stream: a given #GDataInputStream.
+ * @result: the #GAsyncResult that was provided to the callback.
+ * @length: (out) (optional): a #gsize to get the length of the data read in.
+ * @error: #GError for error reporting.
+ *
+ * Finish an asynchronous call started by
+ * g_data_input_stream_read_until_async().
+ *
+ * Since: 2.20
+ *
+ * Returns: (transfer full): a string with the data that was read
+ *     before encountering any of the stop characters. Set @length to
+ *     a #gsize to get the length of the string. This function will
+ *     return %NULL on an error.
+ * Deprecated: 2.56: Use g_data_input_stream_read_upto_finish() instead, which
+ *     has more consistent behaviour regarding the stop character.
+ */
+gchar *
+g_data_input_stream_read_until_finish (GDataInputStream  *stream,
+                                       GAsyncResult      *result,
+                                       gsize             *length,
+                                       GError           **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
+
+  return g_data_input_stream_read_finish (stream, result, length, error);
+}
+
+/**
+ * g_data_input_stream_read_upto:
+ * @stream: a #GDataInputStream
+ * @stop_chars: characters to terminate the read
+ * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is
+ *     nul-terminated
+ * @length: (out) (optional): a #gsize to get the length of the data read in
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
+ * @error: #GError for error reporting
+ *
+ * Reads a string from the data input stream, up to the first
+ * occurrence of any of the stop characters.
+ *
+ * In contrast to g_data_input_stream_read_until(), this function
+ * does not consume the stop character. You have to use
+ * g_data_input_stream_read_byte() to get it before calling
+ * g_data_input_stream_read_upto() again.
+ *
+ * Note that @stop_chars may contain '\0' if @stop_chars_len is
+ * specified.
+ *
+ * The returned string will always be nul-terminated on success.
+ *
+ * Returns: (transfer full): a string with the data that was read
+ *     before encountering any of the stop characters. Set @length to
+ *     a #gsize to get the length of the string. This function will
+ *     return %NULL on an error
+ *
+ * Since: 2.26
+ */
+char *
+g_data_input_stream_read_upto (GDataInputStream  *stream,
+                               const gchar       *stop_chars,
+                               gssize             stop_chars_len,
+                               gsize             *length,
+                               GCancellable      *cancellable,
+                               GError           **error)
+{
+  GBufferedInputStream *bstream;
+  gsize checked;
+  gssize found_pos;
+  gssize res;
+  char *data_until;
+
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
+
+  if (stop_chars_len < 0)
+    stop_chars_len = strlen (stop_chars);
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+
+  checked = 0;
+
+  while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1)
+    {
+      if (g_buffered_input_stream_get_available (bstream) ==
+          g_buffered_input_stream_get_buffer_size (bstream))
+        g_buffered_input_stream_set_buffer_size (bstream,
+                                                 2 * g_buffered_input_stream_get_buffer_size (bstream));
+
+      res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
+      if (res < 0)
+        return NULL;
+      if (res == 0)
+        {
+          /* End of stream */
+          if (g_buffered_input_stream_get_available (bstream) == 0)
+            {
+              if (length)
+                *length = 0;
+              return NULL;
+            }
+          else
+            {
+              found_pos = checked;
+              break;
+            }
+        }
+    }
+
+  data_until = g_malloc (found_pos + 1);
+
+  res = g_input_stream_read (G_INPUT_STREAM (stream),
+                             data_until,
+                             found_pos,
+                             NULL, NULL);
+  if (length)
+    *length = (gsize)found_pos;
+  g_warn_if_fail (res == found_pos);
+  data_until[found_pos] = 0;
+
+  return data_until;
+}
+
+/**
+ * g_data_input_stream_read_upto_async:
+ * @stream: a #GDataInputStream
+ * @stop_chars: characters to terminate the read
+ * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is
+ *     nul-terminated
+ * @io_priority: the [I/O priority][io-priority] of the request
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
+ * @callback: (scope async): callback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * The asynchronous version of g_data_input_stream_read_upto().
+ * It is an error to have two outstanding calls to this function.
+ *
+ * In contrast to g_data_input_stream_read_until(), this function
+ * does not consume the stop character. You have to use
+ * g_data_input_stream_read_byte() to get it before calling
+ * g_data_input_stream_read_upto() again.
+ *
+ * Note that @stop_chars may contain '\0' if @stop_chars_len is
+ * specified.
+ *
+ * When the operation is finished, @callback will be called. You
+ * can then call g_data_input_stream_read_upto_finish() to get
+ * the result of the operation.
+ *
+ * Since: 2.26
+ */
+void
+g_data_input_stream_read_upto_async (GDataInputStream    *stream,
+                                     const gchar         *stop_chars,
+                                     gssize               stop_chars_len,
+                                     gint                 io_priority,
+                                     GCancellable        *cancellable,
+                                     GAsyncReadyCallback  callback,
+                                     gpointer             user_data)
+{
+  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (stop_chars != NULL);
+
+  g_data_input_stream_read_async (stream, stop_chars, stop_chars_len, io_priority,
+                                  cancellable, callback, user_data);
+}
+
+/**
+ * g_data_input_stream_read_upto_finish:
+ * @stream: a #GDataInputStream
+ * @result: the #GAsyncResult that was provided to the callback
+ * @length: (out) (optional): a #gsize to get the length of the data read in
+ * @error: #GError for error reporting
+ *
+ * Finish an asynchronous call started by
+ * g_data_input_stream_read_upto_async().
+ *
+ * Note that this function does not consume the stop character. You
+ * have to use g_data_input_stream_read_byte() to get it before calling
+ * g_data_input_stream_read_upto_async() again.
+ *
+ * The returned string will always be nul-terminated on success.
+ *
+ * Returns: (transfer full): a string with the data that was read
+ *     before encountering any of the stop characters. Set @length to
+ *     a #gsize to get the length of the string. This function will
+ *     return %NULL on an error.
+ *
+ * Since: 2.24
+ */
+gchar *
+g_data_input_stream_read_upto_finish (GDataInputStream  *stream,
+                                      GAsyncResult      *result,
+                                      gsize             *length,
+                                      GError           **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
+
+  return g_data_input_stream_read_finish (stream, result, length, error);
+}
diff --git a/gio/gdatainputstream.h b/gio/gdatainputstream.h
new file mode 100644
index 0000000..3ad3b82
--- /dev/null
+++ b/gio/gdatainputstream.h
@@ -0,0 +1,180 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_DATA_INPUT_STREAM_H__
+#define __G_DATA_INPUT_STREAM_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gbufferedinputstream.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_DATA_INPUT_STREAM         (g_data_input_stream_get_type ())
+#define G_DATA_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DATA_INPUT_STREAM, GDataInputStream))
+#define G_DATA_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DATA_INPUT_STREAM, GDataInputStreamClass))
+#define G_IS_DATA_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DATA_INPUT_STREAM))
+#define G_IS_DATA_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DATA_INPUT_STREAM))
+#define G_DATA_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DATA_INPUT_STREAM, GDataInputStreamClass))
+
+/**
+ * GDataInputStream:
+ *
+ * An implementation of #GBufferedInputStream that allows for high-level
+ * data manipulation of arbitrary data (including binary operations).
+ **/
+typedef struct _GDataInputStreamClass    GDataInputStreamClass;
+typedef struct _GDataInputStreamPrivate  GDataInputStreamPrivate;
+
+struct _GDataInputStream
+{
+  GBufferedInputStream parent_instance;
+
+  /*< private >*/
+  GDataInputStreamPrivate *priv;
+};
+
+struct _GDataInputStreamClass
+{
+  GBufferedInputStreamClass parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+};
+
+GLIB_AVAILABLE_IN_ALL
+GType                  g_data_input_stream_get_type             (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GDataInputStream *     g_data_input_stream_new                  (GInputStream            *base_stream);
+
+GLIB_AVAILABLE_IN_ALL
+void                   g_data_input_stream_set_byte_order       (GDataInputStream        *stream,
+                                                                 GDataStreamByteOrder     order);
+GLIB_AVAILABLE_IN_ALL
+GDataStreamByteOrder   g_data_input_stream_get_byte_order       (GDataInputStream        *stream);
+GLIB_AVAILABLE_IN_ALL
+void                   g_data_input_stream_set_newline_type     (GDataInputStream        *stream,
+                                                                 GDataStreamNewlineType   type);
+GLIB_AVAILABLE_IN_ALL
+GDataStreamNewlineType g_data_input_stream_get_newline_type     (GDataInputStream        *stream);
+GLIB_AVAILABLE_IN_ALL
+guchar                 g_data_input_stream_read_byte            (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+gint16                 g_data_input_stream_read_int16           (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+guint16                g_data_input_stream_read_uint16          (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+gint32                 g_data_input_stream_read_int32           (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+guint32                g_data_input_stream_read_uint32          (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+gint64                 g_data_input_stream_read_int64           (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+guint64                g_data_input_stream_read_uint64          (GDataInputStream        *stream,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+char *                 g_data_input_stream_read_line            (GDataInputStream        *stream,
+                                                                 gsize                   *length,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_2_30
+char *                 g_data_input_stream_read_line_utf8       (GDataInputStream        *stream,
+								 gsize                   *length,
+								 GCancellable            *cancellable,
+								 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+void                   g_data_input_stream_read_line_async      (GDataInputStream        *stream,
+                                                                 gint                     io_priority,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+GLIB_AVAILABLE_IN_ALL
+char *                 g_data_input_stream_read_line_finish     (GDataInputStream        *stream,
+                                                                 GAsyncResult            *result,
+                                                                 gsize                   *length,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_2_30
+char *                 g_data_input_stream_read_line_finish_utf8(GDataInputStream        *stream,
+                                                                 GAsyncResult            *result,
+                                                                 gsize                   *length,
+                                                                 GError                 **error);
+GLIB_DEPRECATED_IN_2_56_FOR (g_data_input_stream_read_upto)
+char *                 g_data_input_stream_read_until           (GDataInputStream        *stream,
+                                                                 const gchar             *stop_chars,
+                                                                 gsize                   *length,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_DEPRECATED_IN_2_56_FOR (g_data_input_stream_read_upto_async)
+void                   g_data_input_stream_read_until_async     (GDataInputStream        *stream,
+                                                                 const gchar             *stop_chars,
+                                                                 gint                     io_priority,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+GLIB_DEPRECATED_IN_2_56_FOR (g_data_input_stream_read_upto_finish)
+char *                 g_data_input_stream_read_until_finish    (GDataInputStream        *stream,
+                                                                 GAsyncResult            *result,
+                                                                 gsize                   *length,
+                                                                 GError                 **error);
+
+GLIB_AVAILABLE_IN_ALL
+char *                 g_data_input_stream_read_upto            (GDataInputStream        *stream,
+                                                                 const gchar             *stop_chars,
+                                                                 gssize                   stop_chars_len,
+                                                                 gsize                   *length,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+GLIB_AVAILABLE_IN_ALL
+void                   g_data_input_stream_read_upto_async      (GDataInputStream        *stream,
+                                                                 const gchar             *stop_chars,
+                                                                 gssize                   stop_chars_len,
+                                                                 gint                     io_priority,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+GLIB_AVAILABLE_IN_ALL
+char *                 g_data_input_stream_read_upto_finish     (GDataInputStream        *stream,
+                                                                 GAsyncResult            *result,
+                                                                 gsize                   *length,
+                                                                 GError                 **error);
+
+G_END_DECLS
+
+#endif /* __G_DATA_INPUT_STREAM_H__ */
diff --git a/gio/gdataoutputstream.c b/gio/gdataoutputstream.c
new file mode 100644
index 0000000..4c2d251
--- /dev/null
+++ b/gio/gdataoutputstream.c
@@ -0,0 +1,598 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+#include <string.h>
+#include "gdataoutputstream.h"
+#include "gseekable.h"
+#include "gioenumtypes.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gdataoutputstream
+ * @short_description: Data Output Stream
+ * @include: gio/gio.h
+ * @see_also: #GOutputStream
+ * 
+ * Data output stream implements #GOutputStream and includes functions for 
+ * writing data directly to an output stream.
+ *
+ **/
+
+
+
+struct _GDataOutputStreamPrivate {
+  GDataStreamByteOrder byte_order;
+};
+
+enum {
+  PROP_0,
+  PROP_BYTE_ORDER
+};
+
+static void g_data_output_stream_set_property (GObject      *object,
+					       guint         prop_id,
+					       const GValue *value,
+					       GParamSpec   *pspec);
+static void g_data_output_stream_get_property (GObject      *object,
+					       guint         prop_id,
+					       GValue       *value,
+					       GParamSpec   *pspec);
+
+static void     g_data_output_stream_seekable_iface_init (GSeekableIface  *iface);
+static goffset  g_data_output_stream_tell                (GSeekable       *seekable);
+static gboolean g_data_output_stream_can_seek            (GSeekable       *seekable);
+static gboolean g_data_output_stream_seek                (GSeekable       *seekable,
+							  goffset          offset,
+							  GSeekType        type,
+							  GCancellable    *cancellable,
+							  GError         **error);
+static gboolean g_data_output_stream_can_truncate        (GSeekable       *seekable);
+static gboolean g_data_output_stream_truncate            (GSeekable       *seekable,
+							  goffset          offset,
+							  GCancellable    *cancellable,
+							  GError         **error);
+
+G_DEFINE_TYPE_WITH_CODE (GDataOutputStream,
+			 g_data_output_stream,
+			 G_TYPE_FILTER_OUTPUT_STREAM,
+                         G_ADD_PRIVATE (GDataOutputStream)
+			 G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
+						g_data_output_stream_seekable_iface_init))
+
+
+static void
+g_data_output_stream_class_init (GDataOutputStreamClass *klass)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->get_property = g_data_output_stream_get_property;
+  object_class->set_property = g_data_output_stream_set_property;
+
+  /**
+   * GDataOutputStream:byte-order:
+   *
+   * Determines the byte ordering that is used when writing 
+   * multi-byte entities (such as integers) to the stream.
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_BYTE_ORDER,
+                                   g_param_spec_enum ("byte-order",
+                                                      P_("Byte order"),
+                                                      P_("The byte order"),
+                                                      G_TYPE_DATA_STREAM_BYTE_ORDER,
+                                                      G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
+                                                      G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
+
+}
+
+static void
+g_data_output_stream_set_property (GObject     *object,
+				  guint         prop_id,
+				  const GValue *value,
+				  GParamSpec   *pspec)
+{
+  GDataOutputStream *dstream;
+
+  dstream = G_DATA_OUTPUT_STREAM (object);
+
+  switch (prop_id) 
+    {
+    case PROP_BYTE_ORDER:
+      g_data_output_stream_set_byte_order (dstream, g_value_get_enum (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_data_output_stream_get_property (GObject    *object,
+				   guint       prop_id,
+				   GValue     *value,
+				   GParamSpec *pspec)
+{
+  GDataOutputStreamPrivate *priv;
+  GDataOutputStream        *dstream;
+
+  dstream = G_DATA_OUTPUT_STREAM (object);
+  priv = dstream->priv;
+
+  switch (prop_id)
+    {
+    case PROP_BYTE_ORDER:
+      g_value_set_enum (value, priv->byte_order);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_data_output_stream_init (GDataOutputStream *stream)
+{
+  stream->priv = g_data_output_stream_get_instance_private (stream);
+  stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
+}
+
+static void
+g_data_output_stream_seekable_iface_init (GSeekableIface *iface)
+{
+  iface->tell         = g_data_output_stream_tell;
+  iface->can_seek     = g_data_output_stream_can_seek;
+  iface->seek         = g_data_output_stream_seek;
+  iface->can_truncate = g_data_output_stream_can_truncate;
+  iface->truncate_fn  = g_data_output_stream_truncate;
+}
+
+/**
+ * g_data_output_stream_new:
+ * @base_stream: a #GOutputStream.
+ * 
+ * Creates a new data output stream for @base_stream.
+ * 
+ * Returns: #GDataOutputStream.
+ **/
+GDataOutputStream *
+g_data_output_stream_new (GOutputStream *base_stream)
+{
+  GDataOutputStream *stream;
+
+  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
+
+  stream = g_object_new (G_TYPE_DATA_OUTPUT_STREAM,
+                         "base-stream", base_stream,
+                         NULL);
+
+  return stream;
+}
+
+/**
+ * g_data_output_stream_set_byte_order:
+ * @stream: a #GDataOutputStream.
+ * @order: a %GDataStreamByteOrder.
+ * 
+ * Sets the byte order of the data output stream to @order.
+ **/
+void
+g_data_output_stream_set_byte_order (GDataOutputStream    *stream,
+                                     GDataStreamByteOrder  order)
+{
+  GDataOutputStreamPrivate *priv;
+  g_return_if_fail (G_IS_DATA_OUTPUT_STREAM (stream));
+  priv = stream->priv;
+  if (priv->byte_order != order)
+    {
+      priv->byte_order = order;
+      g_object_notify (G_OBJECT (stream), "byte-order");
+    }
+}
+
+/**
+ * g_data_output_stream_get_byte_order:
+ * @stream: a #GDataOutputStream.
+ * 
+ * Gets the byte order for the stream.
+ * 
+ * Returns: the #GDataStreamByteOrder for the @stream.
+ **/
+GDataStreamByteOrder
+g_data_output_stream_get_byte_order (GDataOutputStream *stream)
+{
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
+
+  return stream->priv->byte_order;
+}
+
+/**
+ * g_data_output_stream_put_byte:
+ * @stream: a #GDataOutputStream.
+ * @data: a #guchar.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts a byte into the output stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_byte (GDataOutputStream  *stream,
+			       guchar              data,
+			       GCancellable       *cancellable,
+			       GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 1,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_int16:
+ * @stream: a #GDataOutputStream.
+ * @data: a #gint16.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts a signed 16-bit integer into the output stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_int16 (GDataOutputStream  *stream,
+				gint16              data,
+				GCancellable       *cancellable,
+				GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  switch (stream->priv->byte_order)
+    {
+    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+      data = GINT16_TO_BE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+      data = GINT16_TO_LE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+    default:
+      break;
+    }
+  
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 2,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_uint16:
+ * @stream: a #GDataOutputStream.
+ * @data: a #guint16.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts an unsigned 16-bit integer into the output stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_uint16 (GDataOutputStream  *stream,
+				 guint16             data,
+				 GCancellable       *cancellable,
+				 GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  switch (stream->priv->byte_order)
+    {
+    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+      data = GUINT16_TO_BE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+      data = GUINT16_TO_LE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+    default:
+      break;
+    }
+  
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 2,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_int32:
+ * @stream: a #GDataOutputStream.
+ * @data: a #gint32.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts a signed 32-bit integer into the output stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_int32 (GDataOutputStream  *stream,
+				gint32              data,
+				GCancellable       *cancellable,
+				GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  switch (stream->priv->byte_order)
+    {
+    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+      data = GINT32_TO_BE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+      data = GINT32_TO_LE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+    default:
+      break;
+    }
+  
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 4,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_uint32:
+ * @stream: a #GDataOutputStream.
+ * @data: a #guint32.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts an unsigned 32-bit integer into the stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_uint32 (GDataOutputStream  *stream,
+				 guint32             data,
+				 GCancellable       *cancellable,
+				 GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  switch (stream->priv->byte_order)
+    {
+    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+      data = GUINT32_TO_BE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+      data = GUINT32_TO_LE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+    default:
+      break;
+    }
+  
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 4,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_int64:
+ * @stream: a #GDataOutputStream.
+ * @data: a #gint64.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts a signed 64-bit integer into the stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_int64 (GDataOutputStream  *stream,
+				gint64              data,
+				GCancellable       *cancellable,
+				GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  switch (stream->priv->byte_order)
+    {
+    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+      data = GINT64_TO_BE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+      data = GINT64_TO_LE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+    default:
+      break;
+    }
+  
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 8,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_uint64:
+ * @stream: a #GDataOutputStream.
+ * @data: a #guint64.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts an unsigned 64-bit integer into the stream.
+ * 
+ * Returns: %TRUE if @data was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_uint64 (GDataOutputStream  *stream,
+				 guint64             data,
+				 GCancellable       *cancellable,
+				 GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+
+  switch (stream->priv->byte_order)
+    {
+    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
+      data = GUINT64_TO_BE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
+      data = GUINT64_TO_LE (data);
+      break;
+    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
+    default:
+      break;
+    }
+  
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    &data, 8,
+				    &bytes_written,
+				    cancellable, error);
+}
+
+/**
+ * g_data_output_stream_put_string:
+ * @stream: a #GDataOutputStream.
+ * @str: a string.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Puts a string into the output stream. 
+ * 
+ * Returns: %TRUE if @string was successfully added to the @stream.
+ **/
+gboolean
+g_data_output_stream_put_string (GDataOutputStream  *stream,
+				 const char         *str,
+				 GCancellable       *cancellable,
+				 GError            **error)
+{
+  gsize bytes_written;
+  
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
+  g_return_val_if_fail (str != NULL, FALSE);
+
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+				    str, strlen (str),
+				    &bytes_written,
+				    cancellable, error);
+}
+
+static goffset
+g_data_output_stream_tell (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    return 0;
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  return g_seekable_tell (base_stream_seekable);
+}
+
+static gboolean
+g_data_output_stream_can_seek (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_data_output_stream_seek (GSeekable     *seekable,
+			   goffset        offset,
+			   GSeekType      type,
+			   GCancellable  *cancellable,
+			   GError       **error)
+{
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Seek not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  return g_seekable_seek (base_stream_seekable, offset, type, cancellable, error);
+}
+
+static gboolean
+g_data_output_stream_can_truncate (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_truncate (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_data_output_stream_truncate (GSeekable     *seekable,
+				   goffset        offset,
+				   GCancellable  *cancellable,
+				   GError       **error)
+{
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Truncate not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  return g_seekable_truncate (base_stream_seekable, offset, cancellable, error);
+}
diff --git a/gio/gdataoutputstream.h b/gio/gdataoutputstream.h
new file mode 100644
index 0000000..62cf7b5
--- /dev/null
+++ b/gio/gdataoutputstream.h
@@ -0,0 +1,125 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __G_DATA_OUTPUT_STREAM_H__
+#define __G_DATA_OUTPUT_STREAM_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#include <gio/gfilteroutputstream.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_DATA_OUTPUT_STREAM         (g_data_output_stream_get_type ())
+#define G_DATA_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStream))
+#define G_DATA_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStreamClass))
+#define G_IS_DATA_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DATA_OUTPUT_STREAM))
+#define G_IS_DATA_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DATA_OUTPUT_STREAM))
+#define G_DATA_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStreamClass))
+
+/**
+ * GDataOutputStream:
+ *
+ * An implementation of #GBufferedOutputStream that allows for high-level
+ * data manipulation of arbitrary data (including binary operations).
+ **/
+typedef struct _GDataOutputStream         GDataOutputStream;
+typedef struct _GDataOutputStreamClass    GDataOutputStreamClass;
+typedef struct _GDataOutputStreamPrivate  GDataOutputStreamPrivate;
+
+struct _GDataOutputStream
+{
+  GFilterOutputStream parent_instance;
+
+  /*< private >*/
+  GDataOutputStreamPrivate *priv;
+};
+
+struct _GDataOutputStreamClass
+{
+  GFilterOutputStreamClass parent_class;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+};
+
+
+GLIB_AVAILABLE_IN_ALL
+GType                g_data_output_stream_get_type       (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_ALL
+GDataOutputStream *  g_data_output_stream_new            (GOutputStream         *base_stream);
+
+GLIB_AVAILABLE_IN_ALL
+void                 g_data_output_stream_set_byte_order (GDataOutputStream     *stream,
+							  GDataStreamByteOrder   order);
+GLIB_AVAILABLE_IN_ALL
+GDataStreamByteOrder g_data_output_stream_get_byte_order (GDataOutputStream     *stream);
+
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_byte       (GDataOutputStream     *stream,
+							  guchar                 data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_int16      (GDataOutputStream     *stream,
+							  gint16                 data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_uint16     (GDataOutputStream     *stream,
+							  guint16                data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_int32      (GDataOutputStream     *stream,
+							  gint32                 data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_uint32     (GDataOutputStream     *stream,
+							  guint32                data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_int64      (GDataOutputStream     *stream,
+							  gint64                 data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_uint64     (GDataOutputStream     *stream,
+							  guint64                data,
+							  GCancellable          *cancellable,
+							  GError               **error);
+GLIB_AVAILABLE_IN_ALL
+gboolean             g_data_output_stream_put_string     (GDataOutputStream     *stream,
+							  const char            *str,
+							  GCancellable          *cancellable,
+							  GError               **error);
+
+G_END_DECLS
+
+#endif /* __G_DATA_OUTPUT_STREAM_H__ */
diff --git a/gio/gdbus-2.0/codegen/.gitignore b/gio/gdbus-2.0/codegen/.gitignore
new file mode 100644
index 0000000..0015c09
--- /dev/null
+++ b/gio/gdbus-2.0/codegen/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+config.py
+gdbus-codegen
diff --git a/gio/gdbus-2.0/codegen/__init__.py b/gio/gdbus-2.0/codegen/__init__.py
new file mode 100644
index 0000000..f876f04
--- /dev/null
+++ b/gio/gdbus-2.0/codegen/__init__.py
@@ -0,0 +1,27 @@
+# -*- Mode: Python -*-
+
+# GDBus - GLib D-Bus Library
+#
+# Copyright (C) 2008-2011 Red Hat, Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Zeuthen <davidz@redhat.com>
+
+import os
+
+builddir = os.environ.get('UNINSTALLED_GLIB_BUILDDIR')
+
+if builddir is not None:
+    __path__.append(os.path.abspath(os.path.join(builddir, 'gio', 'gdbus-2.0', 'codegen')))
diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py
new file mode 100644
index 0000000..5234b38
--- /dev/null
+++ b/gio/gdbus-2.0/codegen/codegen.py
@@ -0,0 +1,3899 @@
+# -*- Mode: Python -*-
+# coding=utf-8
+
+# GDBus - GLib D-Bus Library
+#
+# Copyright (C) 2008-2018 Red Hat, Inc.
+# Copyright (C) 2018 Iñigo Martínez <inigomartinez@gmail.com>
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Zeuthen <davidz@redhat.com>
+
+import sys
+
+from . import config
+from . import utils
+from . import dbustypes
+from .utils import print_error
+
+LICENSE_STR = '''/*
+ * This file is generated by gdbus-codegen, do not modify it.
+ *
+ * The license of this code is the same as for the D-Bus interface description
+ * it was derived from. Note that it links to GLib, so must comply with the
+ * LGPL linking clauses.
+ */\n'''
+
+def generate_namespace(namespace):
+    ns = namespace
+    if len(namespace) > 0:
+        if utils.is_ugly_case(namespace):
+            ns = namespace.replace('_', '')
+            ns_upper = namespace.upper() + '_'
+            ns_lower = namespace.lower() + '_'
+        else:
+            ns_upper = utils.camel_case_to_uscore(namespace).upper() + '_'
+            ns_lower = utils.camel_case_to_uscore(namespace).lower() + '_'
+    else:
+        ns_upper = ''
+        ns_lower = ''
+
+    return (ns, ns_upper, ns_lower)
+
+def generate_header_guard(header_name):
+    # There might be more characters that are safe to use than these, but lets
+    # stay conservative.
+    safe_valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    return ''.join(map(lambda c: c if c in safe_valid_chars else '_',
+                       header_name.upper()))
+
+class HeaderCodeGenerator:
+    def __init__(self, ifaces, namespace, generate_objmanager,
+                 generate_autocleanup, header_name, input_files_basenames,
+                 use_pragma, glib_min_required,
+                 symbol_decorator, symbol_decorator_header, outfile):
+        self.ifaces = ifaces
+        self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
+        self.generate_objmanager = generate_objmanager
+        self.generate_autocleanup = generate_autocleanup
+        self.header_guard = generate_header_guard(header_name)
+        self.input_files_basenames = input_files_basenames
+        self.use_pragma = use_pragma
+        self.glib_min_required = glib_min_required
+        self.symbol_decorator = symbol_decorator
+        self.symbol_decorator_header = symbol_decorator_header
+        self.outfile = outfile
+
+    # ----------------------------------------------------------------------------------------------------
+
+    def generate_header_preamble(self):
+        basenames = ', '.join(self.input_files_basenames)
+        self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
+        self.outfile.write('\n')
+
+        if self.use_pragma:
+            self.outfile.write('#pragma once\n')
+        else:
+            self.outfile.write('#ifndef __{!s}__\n'.format(self.header_guard))
+            self.outfile.write('#define __{!s}__\n'.format(self.header_guard))
+
+        if self.symbol_decorator_header is not None:
+            self.outfile.write('\n')
+            self.outfile.write('#include "%s"\n' % self.symbol_decorator_header)
+
+        self.outfile.write('\n')
+        self.outfile.write('#include <gio/gio.h>\n')
+        self.outfile.write('\n')
+        self.outfile.write('G_BEGIN_DECLS\n')
+        self.outfile.write('\n')
+
+    # ----------------------------------------------------------------------------------------------------
+
+    def declare_types(self):
+        for i in self.ifaces:
+            self.outfile.write('\n')
+            self.outfile.write('/* ------------------------------------------------------------------------ */\n')
+            self.outfile.write('/* Declarations for %s */\n'%i.name)
+            self.outfile.write('\n')
+
+            # First the GInterface
+            self.outfile.write('#define %sTYPE_%s (%s_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
+            self.outfile.write('#define %s%s(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s, %s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %sIS_%s(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
+            self.outfile.write('#define %s%s_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_%s, %sIface))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%s;\n'%(i.camel_name))
+            self.outfile.write('typedef struct _%s %s;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('typedef struct _%sIface %sIface;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sIface\n'%(i.camel_name))
+            self.outfile.write('{\n')
+            self.outfile.write('  GTypeInterface parent_iface;\n')
+
+            function_pointers = {}
+
+            # vfuncs for methods
+            if len(i.methods) > 0:
+                self.outfile.write('\n')
+                for m in i.methods:
+                    key = (m.since, '_method_%s'%m.name_lower)
+                    value  = '  gboolean (*handle_%s) (\n'%(m.name_lower)
+                    value += '    %s *object,\n'%(i.camel_name)
+                    value += '    GDBusMethodInvocation *invocation'%()
+                    if m.unix_fd:
+                        value += ',\n    GUnixFDList *fd_list'
+                    for a in m.in_args:
+                        value += ',\n    %sarg_%s'%(a.ctype_in, a.name)
+                    value += ');\n\n'
+                    function_pointers[key] = value
+
+            # vfuncs for signals
+            if len(i.signals) > 0:
+                self.outfile.write('\n')
+                for s in i.signals:
+                    key = (s.since, '_signal_%s'%s.name_lower)
+                    value  = '  void (*%s) (\n'%(s.name_lower)
+                    value += '    %s *object'%(i.camel_name)
+                    for a in s.args:
+                        value += ',\n    %sarg_%s'%(a.ctype_in, a.name)
+                    value += ');\n\n'
+                    function_pointers[key] = value
+
+            # vfuncs for properties
+            if len(i.properties) > 0:
+                self.outfile.write('\n')
+                for p in i.properties:
+                    key = (p.since, '_prop_get_%s'%p.name_lower)
+                    value = '  %s (*get_%s) (%s *object);\n\n'%(p.arg.ctype_in, p.name_lower, i.camel_name)
+                    function_pointers[key] = value
+
+            # Sort according to @since tag, then name.. this ensures
+            # that the function pointers don't change order assuming
+            # judicious use of @since
+            #
+            # Also use a proper version comparison function so e.g.
+            # 10.0 comes after 2.0.
+            #
+            # See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5
+            # for discussion
+            for key in sorted(function_pointers.keys(), key=utils.version_cmp_key):
+                self.outfile.write('%s'%function_pointers[key])
+
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            if self.generate_autocleanup == 'all':
+                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
+                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%s, g_object_unref)\n' % (i.camel_name))
+                self.outfile.write('#endif\n')
+                self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GType %s_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
+            self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GDBusInterfaceInfo *%s_interface_info (void);\n'%(i.name_lower))
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n'%(i.name_lower))
+            self.outfile.write('\n')
+
+            # Then method call completion functions
+            if len(i.methods) > 0:
+                self.outfile.write('\n')
+                self.outfile.write('/* D-Bus method call completion functions: */\n')
+                for m in i.methods:
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if m.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('void %s_complete_%s (\n'
+                                       '    %s *object,\n'
+                                       '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
+                    if m.unix_fd:
+                        self.outfile.write(',\n    GUnixFDList *fd_list')
+                    for a in m.out_args:
+                        self.outfile.write(',\n    %s%s'%(a.ctype_in, a.name))
+                    self.outfile.write(');\n')
+                    self.outfile.write('\n')
+                self.outfile.write('\n')
+
+            # Then signal emission functions
+            if len(i.signals) > 0:
+                self.outfile.write('\n')
+                self.outfile.write('/* D-Bus signal emissions functions: */\n')
+                for s in i.signals:
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if s.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('void %s_emit_%s (\n'
+                                       '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
+                    for a in s.args:
+                        self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                    self.outfile.write(');\n')
+                    self.outfile.write('\n')
+                self.outfile.write('\n')
+
+            # Then method call declarations
+            if len(i.methods) > 0:
+                self.outfile.write('\n')
+                self.outfile.write('/* D-Bus method calls: */\n')
+                for m in i.methods:
+                    # async begin
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if m.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('void %s_call_%s (\n'
+                                       '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+                    for a in m.in_args:
+                        self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                    if self.glib_min_required >= (2, 64):
+                        self.outfile.write(',\n    GDBusCallFlags call_flags'
+                                           ',\n    gint timeout_msec')
+                    if m.unix_fd:
+                        self.outfile.write(',\n    GUnixFDList *fd_list')
+                    self.outfile.write(',\n'
+                                       '    GCancellable *cancellable,\n'
+                                       '    GAsyncReadyCallback callback,\n'
+                                       '    gpointer user_data);\n')
+                    self.outfile.write('\n')
+                    # async finish
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if m.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('gboolean %s_call_%s_finish (\n'
+                                       '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+                    for a in m.out_args:
+                        self.outfile.write(',\n    %sout_%s'%(a.ctype_out, a.name))
+                    if m.unix_fd:
+                        self.outfile.write(',\n    GUnixFDList **out_fd_list')
+                    self.outfile.write(',\n'
+                                       '    GAsyncResult *res,\n'
+                                       '    GError **error);\n')
+                    self.outfile.write('\n')
+                    # sync
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if m.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('gboolean %s_call_%s_sync (\n'
+                                       '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
+                    for a in m.in_args:
+                        self.outfile.write(',\n    %sarg_%s'%(a.ctype_in, a.name))
+                    if self.glib_min_required >= (2, 64):
+                        self.outfile.write(',\n    GDBusCallFlags call_flags'
+                                           ',\n    gint timeout_msec')
+                    if m.unix_fd:
+                        self.outfile.write(',\n    GUnixFDList  *fd_list')
+                    for a in m.out_args:
+                        self.outfile.write(',\n    %sout_%s'%(a.ctype_out, a.name))
+                    if m.unix_fd:
+                        self.outfile.write(',\n    GUnixFDList **out_fd_list')
+                    self.outfile.write(',\n'
+                                       '    GCancellable *cancellable,\n'
+                                       '    GError **error);\n')
+                    self.outfile.write('\n')
+                self.outfile.write('\n')
+
+            # Then the property accessor declarations
+            if len(i.properties) > 0:
+                self.outfile.write('\n')
+                self.outfile.write('/* D-Bus property accessors: */\n')
+                for p in i.properties:
+                    # getter
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if p.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('%s%s_get_%s (%s *object);\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name))
+                    if p.arg.free_func != None:
+                        if self.symbol_decorator is not None:
+                            self.outfile.write('%s\n' % self.symbol_decorator)
+                        if p.deprecated:
+                            self.outfile.write('G_GNUC_DEPRECATED ')
+                        self.outfile.write('%s%s_dup_%s (%s *object);\n'%(p.arg.ctype_in_dup, i.name_lower, p.name_lower, i.camel_name))
+                    # setter
+                    if self.symbol_decorator is not None:
+                        self.outfile.write('%s\n' % self.symbol_decorator)
+                    if p.deprecated:
+                        self.outfile.write('G_GNUC_DEPRECATED ')
+                    self.outfile.write('void %s_set_%s (%s *object, %svalue);\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
+                    self.outfile.write('\n')
+
+            # Then the proxy
+            self.outfile.write('\n')
+            self.outfile.write('/* ---- */\n')
+            self.outfile.write('\n')
+            self.outfile.write('#define %sTYPE_%s_PROXY (%s_proxy_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
+            self.outfile.write('#define %s%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_PROXY, %sProxy))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %s%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_PROXY, %sProxyClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %s%s_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_PROXY, %sProxyClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %sIS_%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_PROXY))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
+            self.outfile.write('#define %sIS_%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_PROXY))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
+            self.outfile.write('\n')
+            self.outfile.write('typedef struct _%sProxy %sProxy;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('typedef struct _%sProxyClass %sProxyClass;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('typedef struct _%sProxyPrivate %sProxyPrivate;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sProxy\n'%(i.camel_name))
+            self.outfile.write('{\n')
+            self.outfile.write('  /*< private >*/\n')
+            self.outfile.write('  GDBusProxy parent_instance;\n')
+            self.outfile.write('  %sProxyPrivate *priv;\n'%(i.camel_name))
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sProxyClass\n'%(i.camel_name))
+            self.outfile.write('{\n')
+            self.outfile.write('  GDBusProxyClass parent_class;\n')
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GType %s_proxy_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
+            self.outfile.write('\n')
+            if self.generate_autocleanup in ('objects', 'all'):
+                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
+                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sProxy, g_object_unref)\n' % (i.camel_name))
+                self.outfile.write('#endif\n')
+                self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('void %s_proxy_new (\n'
+                               '    GDBusConnection     *connection,\n'
+                               '    GDBusProxyFlags      flags,\n'
+                               '    const gchar         *name,\n'
+                               '    const gchar         *object_path,\n'
+                               '    GCancellable        *cancellable,\n'
+                               '    GAsyncReadyCallback  callback,\n'
+                               '    gpointer             user_data);\n'
+                               %(i.name_lower))
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('%s *%s_proxy_new_finish (\n'
+                               '    GAsyncResult        *res,\n'
+                               '    GError             **error);\n'
+                               %(i.camel_name, i.name_lower))
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('%s *%s_proxy_new_sync (\n'
+                               '    GDBusConnection     *connection,\n'
+                               '    GDBusProxyFlags      flags,\n'
+                               '    const gchar         *name,\n'
+                               '    const gchar         *object_path,\n'
+                               '    GCancellable        *cancellable,\n'
+                               '    GError             **error);\n'
+                               %(i.camel_name, i.name_lower))
+            self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('void %s_proxy_new_for_bus (\n'
+                               '    GBusType             bus_type,\n'
+                               '    GDBusProxyFlags      flags,\n'
+                               '    const gchar         *name,\n'
+                               '    const gchar         *object_path,\n'
+                               '    GCancellable        *cancellable,\n'
+                               '    GAsyncReadyCallback  callback,\n'
+                               '    gpointer             user_data);\n'
+                               %(i.name_lower))
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('%s *%s_proxy_new_for_bus_finish (\n'
+                               '    GAsyncResult        *res,\n'
+                               '    GError             **error);\n'
+                               %(i.camel_name, i.name_lower))
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('%s *%s_proxy_new_for_bus_sync (\n'
+                               '    GBusType             bus_type,\n'
+                               '    GDBusProxyFlags      flags,\n'
+                               '    const gchar         *name,\n'
+                               '    const gchar         *object_path,\n'
+                               '    GCancellable        *cancellable,\n'
+                               '    GError             **error);\n'
+                               %(i.camel_name, i.name_lower))
+            self.outfile.write('\n')
+
+            # Then the skeleton
+            self.outfile.write('\n')
+            self.outfile.write('/* ---- */\n')
+            self.outfile.write('\n')
+            self.outfile.write('#define %sTYPE_%s_SKELETON (%s_skeleton_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
+            self.outfile.write('#define %s%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_SKELETON, %sSkeleton))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %s%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_SKELETON, %sSkeletonClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %s%s_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_SKELETON, %sSkeletonClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
+            self.outfile.write('#define %sIS_%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_SKELETON))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
+            self.outfile.write('#define %sIS_%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_SKELETON))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
+            self.outfile.write('\n')
+            self.outfile.write('typedef struct _%sSkeleton %sSkeleton;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('typedef struct _%sSkeletonClass %sSkeletonClass;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('typedef struct _%sSkeletonPrivate %sSkeletonPrivate;\n'%(i.camel_name, i.camel_name))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sSkeleton\n'%(i.camel_name))
+            self.outfile.write('{\n')
+            self.outfile.write('  /*< private >*/\n')
+            self.outfile.write('  GDBusInterfaceSkeleton parent_instance;\n')
+            self.outfile.write('  %sSkeletonPrivate *priv;\n'%(i.camel_name))
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sSkeletonClass\n'%(i.camel_name))
+            self.outfile.write('{\n')
+            self.outfile.write('  GDBusInterfaceSkeletonClass parent_class;\n')
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GType %s_skeleton_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
+            self.outfile.write('\n')
+            if self.generate_autocleanup in ('objects', 'all'):
+                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
+                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sSkeleton, g_object_unref)\n' % (i.camel_name))
+                self.outfile.write('#endif\n')
+                self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            if i.deprecated:
+                self.outfile.write('G_GNUC_DEPRECATED ')
+            self.outfile.write('%s *%s_skeleton_new (void);\n'%(i.camel_name, i.name_lower))
+
+            self.outfile.write('\n')
+
+        # Finally, the Object, ObjectProxy, ObjectSkeleton and ObjectManagerClient
+        if self.generate_objmanager:
+            self.outfile.write('\n')
+            self.outfile.write('/* ---- */\n')
+            self.outfile.write('\n')
+            self.outfile.write('#define %sTYPE_OBJECT (%sobject_get_type ())\n'%(self.ns_upper, self.ns_lower))
+            self.outfile.write('#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sObject;\n'%(self.namespace))
+            self.outfile.write('typedef struct _%sObject %sObject;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectIface %sObjectIface;\n'%(self.namespace, self.namespace))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sObjectIface\n'%(self.namespace))
+            self.outfile.write('{\n'
+                               '  GTypeInterface parent_iface;\n'
+                               '};\n'
+                               '\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GType %sobject_get_type (void) G_GNUC_CONST;\n'
+                               '\n'
+                               %(self.ns_lower))
+            if self.generate_autocleanup == 'all':
+                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
+                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObject, g_object_unref)\n' % (self.namespace))
+                self.outfile.write('#endif\n')
+                self.outfile.write('\n')
+            for i in self.ifaces:
+                if self.symbol_decorator is not None:
+                    self.outfile.write('%s\n' % self.symbol_decorator)
+                if i.deprecated:
+                    self.outfile.write('G_GNUC_DEPRECATED ')
+                self.outfile.write('%s *%sobject_get_%s (%sObject *object);\n'
+                                   %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
+            for i in self.ifaces:
+                if self.symbol_decorator is not None:
+                    self.outfile.write('%s\n' % self.symbol_decorator)
+                if i.deprecated:
+                    self.outfile.write('G_GNUC_DEPRECATED ')
+                self.outfile.write('%s *%sobject_peek_%s (%sObject *object);\n'
+                                   %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
+            self.outfile.write('\n')
+            self.outfile.write('#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n'%(self.ns_upper, self.ns_lower))
+            self.outfile.write('#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('\n')
+            self.outfile.write('typedef struct _%sObjectProxy %sObjectProxy;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectProxyClass %sObjectProxyClass;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n'%(self.namespace, self.namespace))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sObjectProxy\n'%(self.namespace))
+            self.outfile.write('{\n')
+            self.outfile.write('  /*< private >*/\n')
+            self.outfile.write('  GDBusObjectProxy parent_instance;\n')
+            self.outfile.write('  %sObjectProxyPrivate *priv;\n'%(self.namespace))
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sObjectProxyClass\n'%(self.namespace))
+            self.outfile.write('{\n')
+            self.outfile.write('  GDBusObjectProxyClass parent_class;\n')
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
+            self.outfile.write('\n')
+            if self.generate_autocleanup in ('objects', 'all'):
+                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
+                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectProxy, g_object_unref)\n' % (self.namespace))
+                self.outfile.write('#endif\n')
+                self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n'%(self.namespace, self.ns_lower))
+            self.outfile.write('\n')
+            self.outfile.write('#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n'%(self.ns_upper, self.ns_lower))
+            self.outfile.write('#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('\n')
+            self.outfile.write('typedef struct _%sObjectSkeleton %sObjectSkeleton;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n'%(self.namespace, self.namespace))
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sObjectSkeleton\n'%(self.namespace))
+            self.outfile.write('{\n')
+            self.outfile.write('  /*< private >*/\n')
+            self.outfile.write('  GDBusObjectSkeleton parent_instance;\n')
+            self.outfile.write('  %sObjectSkeletonPrivate *priv;\n'%(self.namespace))
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            self.outfile.write('struct _%sObjectSkeletonClass\n'%(self.namespace))
+            self.outfile.write('{\n')
+            self.outfile.write('  GDBusObjectSkeletonClass parent_class;\n')
+            self.outfile.write('};\n')
+            self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
+            self.outfile.write('\n')
+            if self.generate_autocleanup in ('objects', 'all'):
+                self.outfile.write('#if GLIB_CHECK_VERSION(2, 44, 0)\n')
+                self.outfile.write('G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectSkeleton, g_object_unref)\n' % (self.namespace))
+                self.outfile.write('#endif\n')
+                self.outfile.write('\n')
+            if self.symbol_decorator is not None:
+                self.outfile.write('%s\n' % self.symbol_decorator)
+            self.outfile.write('%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n'
+                               %(self.namespace, self.ns_lower))
+            for i in self.ifaces:
+                if self.symbol_decorator is not None:
+                    self.outfile.write('%s\n' % self.symbol_decorator)
+                if i.deprecated:
+                    self.outfile.write('G_GNUC_DEPRECATED ')
+                self.outfile.write('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n'
+                                   %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name))
+            self.outfile.write('\n')
+
+            self.outfile.write('/* ---- */\n')
+            self.outfile.write('\n')
+            self.outfile.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n'%(self.ns_upper, self.ns_lower))
+            self.outfile.write('#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.outfile.write('#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
+            self.outfile.write('\n')
+            self.outfile.write('typedef struct _%sObjectManagerClient %sObjectManagerClient;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n'%(self.namespace, self.namespace))
+            self.outfile.write('typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n'%(self.namespace, self.namespace))
+            self.outfile.write('\n')
+            self.outfile