diff --git a/content/guidelines/api_documentation.md b/content/guidelines/api_documentation.md
deleted file mode 100644
index 61aad140e5d75f8c09c77740d208ce7c39b62560..0000000000000000000000000000000000000000
--- a/content/guidelines/api_documentation.md
+++ /dev/null
@@ -1,279 +0,0 @@
-+++
-date = "2015-03-03"
-weight = 100
-
-title = "API Documentation"
-
-aliases = [
-    "/old-wiki/Guidelines/API_documentation"
-]
-+++
-
-# API documentation
-
-## Summary
-
-  - Use gtk-doc with up-to-date settings for API documentation.
-    ([gtk-doc](#gtk-doc))
-  - Use XML entities for including external symbols into the
-    documentation. ([Build system](#build-system))
-  - Use a consistent, standard, table of contents for all API
-    documentation to maintain familiarity. ([Standard
-    layout](#standard-layout))
-  - Use `gdbus-codegen` to generate D-Bus API documentation to include
-    in the gtk-doc build. ([D-Bus APIs](#d-bus-apis))
-  - Add introspection annotations to all API documentation.
-    ([Introspection
-    annotations](#introspection-annotations))
-  - Add `Since` lines to all API documentation. ([Symbol
-    versioning](#symbol-versioning))
-  - Enable gtk-doc tests. ([Keeping documentation up to
-    date](#keeping-documentation-up-to-date))
-
-## gtk-doc
-
-API documentation should be generated by gtk-doc, which collects
-specially formatted documentation comments from C and header files, and
-reformats them to generate [DocBook](http://www.docbook.org/) and HTML
-output. The DocBook output can be used by
-[Devhelp](https://wiki.gnome.org/Apps/Devhelp).
-
-Using gtk-doc requires two things:
-
-  - The gtk-doc build system code to be integrated, which is a one-time
-    operation.
-  - Documentation comments to be added to all public APIs, and kept up
-    to date.
-
-## Build system
-
-To integrate gtk-doc into a project’s build system, follow the
-[instructions in the gtk-doc
-manual](https://developer.gnome.org/gtk-doc-manual/stable/settingup.html.en).
-Note that while the `sections.txt` file is automatically generated the
-first time gtk-doc is run, it is not generated subsequently, and should
-be kept up to date manually. It should also be [in version
-control](https://developer.gnome.org/gtk-doc-manual/stable/settingup_vcs.html.en).
-
-gtk-doc’s `no-tmpl` flavour should be used, and XML mode should be used
-instead of SGML. (tmpl mode and SGML are both outdated and slower than
-XML.)
-
-If the package version is needed to be substituted into the
-documentation, create a file named `docs/version.xml.in`, containing:
-
-    @PACKAGE_VERSION@
-
-Add it to `AC_CONFIG_FILES` in `configure.ac`, then include it into the
-main documentation file (`*-docs.xml`) using:
-
-    <!ENTITY version SYSTEM "version.xml">
-
-in the `DOCTYPE` at the top of the document. The package version can
-then be used inline as `&version;`.
-
-## Standard layout
-
-Using a standard layout for the table of contents, sections, appendices,
-etc. means the same `*-docs.xml` template can be reused with few changes
-between projects. It also means the documentation layout is similar
-across all projects, making it more familiar to developers.
-
-The following layout is suggested:
-
-    <?xml version="1.0"?>
-    <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
-                   "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
-    [
-        <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
-        <!ENTITY version SYSTEM "version.xml">
-    ]>
-    <book id="index">
-        <bookinfo>
-            <title>[project] Reference Manual</title>
-            <releaseinfo>
-                For [project] &version;. The latest version of this documentation can be found on-line at
-                <ulink role="online-location" url="http://[server]/[project]/index.html">http://[server]/[project]/</ulink>.
-            </releaseinfo>
-        </bookinfo>
-
-        <part>
-            <title>[project] Overview</title>
-
-            <xi:include href="xml/SomeObject.xml"/>
-            <xi:include href="xml/OtherObject.xml"/>
-            <xi:include href="xml/Utilities.xml"/>
-
-            <chapter>
-                <title>Object Hierarchy</title>
-                <xi:include href="xml/tree_index.sgml"/>
-            </chapter>
-        </part>
-
-        <part>
-            <title>D-Bus Interfaces</title>
-
-            <chapter>
-                <title>D-Bus Interfaces</title>
-
-                <partintro>
-                    <para>D-Bus interface definitions for the project.</para>
-                </partintro>
-
-                <xi:include href="xml/docs-Some.Interface.xml"/>
-                <xi:include href="xml/docs-Other.Interface.xml"/>
-            </chapter>
-
-            <chapter>
-                <title>C Interfaces</title>
-
-                <partintro>
-                    <para>C wrappers for the project D-Bus interfaces.</para>
-                </partintro>
-
-                <xi:include href="xml/SomeInterface.xml"/>
-                <xi:include href="xml/OtherInterface.xml"/>
-            </chapter>
-        </part>
-
-        <part>
-            <title>Appendices</title>
-            <index id="api-index-full">
-                <title>API Index</title>
-                <xi:include href="xml/api-index-full.xml"><xi:fallback/></xi:include>
-            </index>
-            <index id="api-index-deprecated">
-                <title>Index of deprecated symbols</title>
-                <xi:include href="xml/api-index-deprecated.xml"><xi:fallback/></xi:include>
-            </index>
-            <index role="1.0.0">
-                <title>Index of new symbols in 1.0.0</title>
-                <xi:include href="xml/api-index-1.0.0.xml"><xi:fallback/></xi:include>
-            </index>
-            <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
-        </part>
-
-        <xi:include href="xml/license.xml"/>
-    </book>
-
-## D-Bus APIs
-
-D-Bus interface descriptions contain documentation comments, and these
-can be extracted from the XML using `gdbus-codegen`, and turned into
-DocBook files to be included by gtk-doc. Generate the documentation
-using the rules described in the [D-Bus services
-guidelines]( {{< ref "d-bus_services.md" >}} ).
-
-The DocBook files can be included in the main `*-docs.xml` file using:
-
-    <chapter>
-        <title>C Interfaces</title>
-        <partintro>
-            <para>C wrappers for the D-Bus interfaces.</para>
-        </partintro>
-
-        <xi:include href="xml/SomeDBusService.xml"/>
-        <xi:include href="xml/SomeOtherService.xml"/>
-    </chapter>
-
-The generated XML files must be included in the `content_files` variable
-in `docs/reference/Makefile.am`, otherwise the build will fail. (This is
-to fix situations where the `builddir` does not equal the `srcdir`.)
-
-## Introspection annotations
-
-Each gtk-doc comment should have appropriate [GObject introspection
-annotations](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations).
-These are useful for two reasons:
-
-1.  They add important information about parameter types, nullability
-    and memory management to the C API documentation generated by
-    gtk-doc.
-2.  They allow public APIs to be automatically bound in other languages,
-    such as Python.
-
-Introspection annotations add information to APIs (functions, function
-parameters, function return values, structures, GObject properties,
-GObject signals) which is otherwise not present in the machine readable
-C API and only exists in the form of human readable documentation or
-convention. They are very important.
-
-In gtk-doc comments, annotations should be preferred over human-readable
-equivalents. For example, when documenting a function parameter which
-may be `NULL`, use the `(nullable)` annotation rather than some text:
-
-    /**
-     * my_function:
-     * @parameter: (nullable): some parameter which affects something
-     *
-     * Body of the function documentation.
-     */
-
-Instead of:
-
-    /**
-     * my_bad_function:
-     * @parameter: some parameter which affects something, or %NULL to ignore
-     *
-     * Bad body of the function documentation.
-     */
-
-For more information on introspection, see the [introspection
-guidelines]( {{< ref "/guidelines/introspection.md" >}} ).
-
-## Symbol versioning
-
-Whenever a symbol is added to the public API, it should have a
-documentation comment added. This comment should always contain a
-`Since` line with the package version number of the release which will
-first contain the new API. This should be the number currently in
-`configure.ac` if [post-release version
-incrementing]( {{< ref "/guidelines/howtoreleasepackages.md#release-process" >}} ) is
-being used.
-
-e.g.
-
-    /**
-     * my_function:
-     * @param: some parameter
-     *
-     * Body of the function documentation.
-     *
-     * Since: 0.5.0
-     */
-
-gtk-doc uses this information to generate indexes of the APIs added in
-each release. These should be added to the main `*-docs.xml` as an
-appendix:
-
-    <part>
-        <title>Appendices</title>
-        <index id="api-index-full">
-            <title>API Index</title>
-            <xi:include href="xml/api-index-full.xml"><xi:fallback/></xi:include>
-        </index>
-        <index id="api-index-deprecated">
-            <title>Index of deprecated symbols</title>
-            <xi:include href="xml/api-index-deprecated.xml"><xi:fallback/></xi:include>
-        </index>
-        <index role="0.1.0">
-            <title>Index of new symbols in 0.1.0</title>
-            <xi:include href="xml/api-index-0.1.0.xml"><xi:fallback/></xi:include>
-        </index>
-        <!-- More versions here. -->
-        <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
-    </part>
-
-## Keeping documentation up to date
-
-gtk-doc comes with support for checking the documentation with some
-basic tests. These check that all version indexes are included in the
-main `*-docs.xml` file and that all symbols are documented, amongst
-other things.
-
-These tests should always be enabled, by adding the following to
-`docs/Makefile.am`:
-
-    TESTS = $(GTKDOC_CHECK)
-
-They will then be run as part of `make check`.
diff --git a/content/guidelines/api_stability.md b/content/guidelines/api_stability.md
index aeacfc4db3e26e0a5acbb7523701148d1c1374e8..9c843cfdf7bf873aff17dc45afc6d46a57d36c0d 100644
--- a/content/guidelines/api_stability.md
+++ b/content/guidelines/api_stability.md
@@ -9,121 +9,112 @@ aliases = [
 ]
 +++
 
-# API and ABI stability
-
-## Summary
-
-  - Define API stability guarantees for your project
-    ([Stability](#stability))
-  - Ensure version numbers are changed as appropriate when API changes
-    ([Versioning](#versioning))
-
-## API and ABI
-
-At a high level, an API – Application Programming Interface – is the
-boundary between two components when developing against them. It is
-closely related to an ABI – Application Binary Interface – which is the
-boundary at runtime. It defines the possible ways in which other
-components can interact with a component. More concretely, this normally
-means the C headers of a library form its API, and compiled library
-symbols its ABI. The difference between an API and ABI is given by
-compilation of the code: there are certain things in a C header, such as
-\#defines, which can cause a library's API to change without changing
-its ABI. But these differences are mostly academic, and for all
+# Summary
+
+- Define API stability guarantees for your project
+  ([Stability](#stability))
+- Ensure version numbers are changed as appropriate when API changes
+  ([Versioning](#versioning))
+
+# API and ABI
+
+At a high level, an API – Application Programming Interface – is the boundary
+between two components when developing against them. It is closely related to
+an ABI – Application Binary Interface – which is the boundary at runtime. It
+defines the possible ways in which other components can interact with a
+component. More concretely, this normally means the C headers of a library form
+its API, and compiled library symbols its ABI. The difference between an API
+and ABI is given by compilation of the code: there are certain things in a C
+header, such as \#defines, which can cause a library's API to change without
+changing its ABI. But these differences are mostly academic, and for all
 practical purposes, API and ABI can be treated interchangeably.
 
-Examples of API-incompatible changes to a C function would be to add a
-new parameter, change the function's return type, or remove a parameter.
+Examples of API-incompatible changes to a C function would be to add a new
+parameter, change the function's return type, or remove a parameter.
 
-However, many other parts of a project can form an API. If a daemon
-exposes itself on D-Bus, the interfaces exported there form an API.
-Similarly, if a C API is exposed in higher level languages by use of
-GIR, the GIR file forms another API — if it changes, any higher level
-code using it must also change.
+However, many other parts of a project can form an API. If a daemon exposes
+itself on D-Bus, the interfaces exported there form an API.  Similarly, if a C
+API is exposed in higher level languages by use of GIR, the GIR file forms
+another API — if it changes, any higher level code using it must also change.
 
 Other examples of more unusual APIs are configuration file locations and
-formats, and GSettings schemas. Any changes to these could require code
-using your library to change.
-
-## Stability
-
-API stability refers to some level of guarantee from a project that its
-API will only change in defined ways in the future, or will not change
-at all. Generally, an API is considered 'stable' if it commits to
-backwards-compatibility (defined below); but APIs could also commit to
-being unstable or even forwards-compatible. The purpose of API stability
-guarantees is to allow people to use your project from their own code
-without worrying about constantly updating their code to keep up with
-API changes. Typical API stability guarantees mean that code which is
-compiled against one version of a library will run without problems
-against all future versions of that library with the same minor version
-number — or similarly that code which runs against a daemon will
-continue to run against all future versions of that daemon with the same
-minor version number.
-
-It is possible to apply different levels of API stability to components
-within a project. For example, the core functions in a library could be
-stable, and hence their API left unchanged in future; while the newer,
-less core functions could be left unstable and allowed to change wildly
-until the right design is found, at which point they could be marked as
-stable.
+formats, and GSettings schemas. Any changes to these could require code using
+your library to change.
+
+# Stability
+
+API stability refers to some level of guarantee from a project that its API
+will only change in defined ways in the future, or will not change at all.
+Generally, an API is considered 'stable' if it commits to
+backwards-compatibility (defined below); but APIs could also commit to being
+unstable or even forwards-compatible. The purpose of API stability guarantees
+is to allow people to use your project from their own code without worrying
+about constantly updating their code to keep up with API changes. Typical API
+stability guarantees mean that code which is compiled against one version of a
+library will run without problems against all future versions of that library
+with the same minor version number — or similarly that code which runs against
+a daemon will continue to run against all future versions of that daemon with
+the same minor version number.
+
+It is possible to apply different levels of API stability to components within
+a project. For example, the core functions in a library could be stable, and
+hence their API left unchanged in future; while the newer, less core functions
+could be left unstable and allowed to change wildly until the right design is
+found, at which point they could be marked as stable.
 
 Several types of stability commonly considered:
 
-  - *Unstable*: the API could change or be removed in future
-  - *Backwards-compatible*: only changes which permit code compiled
-    against the unmodified API to continue running against the modified
-    API are allowed (for example, functions cannot be removed)
-  - *Forwards-compatible*: only changes which permit code compiled
-    against the modified API to run against the unmodified API are
-    allowed (for example, functions cannot be added)
-  - *Totally stable*: no changes are allowed to the API, only to the
-    implementation
+- *Unstable*: the API could change or be removed in future
+- *Backwards-compatible*: only changes which permit code compiled against the
+  unmodified API to continue running against the modified API are allowed (for
+example, functions cannot be removed)
+- *Forwards-compatible*: only changes which permit code compiled against the
+  modified API to run against the unmodified API are allowed (for example,
+functions cannot be added)
+- *Totally stable*: no changes are allowed to the API, only to the
+  implementation
 
-Typically, projects commit to backwards-compatibility when they say an
-API is 'stable'. Very few projects commit to total stability because it
-would prevent almost all further development of the project.
+Typically, projects commit to backwards-compatibility when they say an API is
+'stable'. Very few projects commit to total stability because it would prevent
+almost all further development of the project.
 
-## Versioning
+# Versioning
 
 API stability guarantees are strongly linked to project versioning; both
-package versioning and libtool versioning. Libtool versioning exists
-entirely for the purpose of tracking ABI stability, and is explained in
-detail on the [Autotools
-Mythbuster](https://autotools.io/libtool/version.html) or the
+package versioning and libtool versioning. Libtool versioning exists entirely
+for the purpose of tracking ABI stability, and is explained in detail on the
+[Autotools Mythbuster](https://autotools.io/libtool/version.html) or the
 [Versioning page]( {{< ref "/guidelines/howtoreleasepackages.md" >}} ).
 
-Package versioning (*major.minor.micro*) is strongly linked to API
-stability: typically, the major version number is incremented when
-backwards-incompatible changes are made (for example, when functions are
-renamed, parameters are changed, or functions are removed). The minor
-version number is incremented when forwards-incompatible changes are
-made (for example, when new public API is added). The micro version
-number is incremented when code changes are made without modifying API.
-See the [Versioning page]( {{< ref "/guidelines/howtoreleasepackages.md" >}} ) for more
-information.
-
-API versioning is just as important for D-Bus APIs and GSettings schemas
-(if they are likely to change) as for C APIs. See the [documentation on
-D-Bus API
+Package versioning (*major.minor.micro*) is strongly linked to API stability:
+typically, the major version number is incremented when backwards-incompatible
+changes are made (for example, when functions are renamed, parameters are
+changed, or functions are removed). The minor version number is incremented
+when forwards-incompatible changes are made (for example, when new public API
+is added). The micro version number is incremented when code changes are made
+without modifying API.  See the [Versioning page]( {{< ref
+"/guidelines/howtoreleasepackages.md" >}} ) for more information.
+
+API versioning is just as important for D-Bus APIs and GSettings schemas (if
+they are likely to change) as for C APIs. See the [documentation on D-Bus API
 versioning](http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning)
 for details.
 
-For GIR APIs, their stability typically follows the C API stability, as
-they are generated from the C API. One complexity is that their
-stability additionally depends on the version of gobject-introspection
-used in generating the GIR, but recent versions have not changed much so
-this is not a major concern.
+For GIR APIs, their stability typically follows the C API stability, as they
+are generated from the C API. One complexity is that their stability
+additionally depends on the version of gobject-introspection used in generating
+the GIR, but recent versions have not changed much so this is not a major
+concern.
 
-## Checking for API users
+# Checking for API users
 
 If you are carrying out an API or ABI break, it can be useful to find
 everything that depends or build-depends on a particular library. One
 convenient way to do this is by using the `grep-dctrl` command.
 
-For example, a developer considering an API or ABI break in the
-Ribchester volume-mounting service might use commands like this to
-determine which packages they need to inspect more closely:
+For example, a developer considering an API or ABI break in the Ribchester
+volume-mounting service might use commands like this to determine which
+packages they need to inspect more closely:
 
     $ grep-dctrl -s Filename -F Pre-Depends,Depends,Recommends ribchester /var/lib/apt/lists/*_Packages
     Filename: pool/development/a/apertis-dev-tools/apertis-dev-tools_0.1703.4bu1_all.deb
@@ -148,11 +139,8 @@ determine which packages they need to inspect more closely:
     $ grep-dctrl -s Directory -F Build-Depends,Build-Depends-Arch,Build-Depends-Indep ribchester /var/lib/apt/lists/*_Sources
     Directory: pool/target/f/frome
 
-## External links
+# External links
 
-  - [Wikipedia page on
-    APIs](http://en.wikipedia.org/wiki/Application_programming_interface)
-  - [Wikipedia page on
-    ABIs](http://en.wikipedia.org/wiki/Application_binary_interface)
-  - [D-Bus API versioning
-    documentation](http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning)
+- [Wikipedia page on APIs](http://en.wikipedia.org/wiki/Application_programming_interface)
+- [Wikipedia page on ABIs](http://en.wikipedia.org/wiki/Application_binary_interface)
+- [D-Bus API versioning documentation](http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning)
diff --git a/content/guidelines/apparmor.md b/content/guidelines/apparmor.md
deleted file mode 100644
index c275001b19727cc21e9de23cee29e4ba802bd1c3..0000000000000000000000000000000000000000
--- a/content/guidelines/apparmor.md
+++ /dev/null
@@ -1,71 +0,0 @@
-+++
-date = "2015-09-08"
-weight = 100
-
-title = "AppArmor"
-
-aliases = [
-    "/old-wiki/Guidelines/AppArmor"
-]
-+++
-
-# AppArmor
-
-AppArmor is a security layer which enforces access control on the
-filesystem resources applications can access, and the permissions they
-can access them with. It comprises a kernel module and user space
-profiles for each application, which define the resources an application
-expects to access. For more information, see the [AppArmor home
-page](http://wiki.apparmor.net/index.php/Main_Page). Apertis uses
-AppArmor for all applications and services.
-
-## Summary
-
-  - Write AppArmor profiles to be as constrained as possible.
-    ([Profiles](#profiles))
-  - Validate the profiles manually before release, and during testing.
-    ([Validation](#validation))
-
-## Profiles
-
-For application development, the only work which needs to be done for
-AppArmor integration is to write and install a profile for the
-application. See the [AppArmor
-website](http://wiki.apparmor.net/index.php/Profiles) for information on
-writing profiles. Profiles should be as constrained as possible,
-following the [principle of least
-privilege](http://en.wikipedia.org/wiki/Principle_of_least_privilege).
-
-To install a profile, use the following `Makefile.am` snippet:
-
-    aaprofiledir = $(sysconfdir)/apparmor.d
-    aaprofile_DATA = usr.bin.application-name
-    EXTRA_DIST = $(aaprofile_DATA)
-
-## Validation
-
-AppArmor profiles can be validated in two ways: manually, and at
-runtime. Manual verification should be performed before each release,
-manually inspecting the profile against the list of changes made to the
-application since the last release, and checking that each entry is
-still relevant and correct, and that no new entries are needed.
-
-Runtime verification is automatic: AppArmor will deny access to files
-which violate the profile, emitting a message in the audit logs
-(`audit.log`), for example:
-
-    Feb 23 18:54:07 my-host kernel: [   24.610703] type=1400 audit(1393181647.872:15): apparmor="DENIED" operation="open" parent=1 profile="/usr/sbin/ntpd" name="/etc/ldap/ldap.conf" pid=1526 comm="ntpd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
-
-Such messages should be investigated, and may result in changes to the
-application (to prevent it making such accesses) or to the profile (to
-allow them).
-
-Manual and runtime verification are complementary: manual verification
-ensures the profile is as small as possible; runtime verification
-ensures the profile is as big as it needs to be.
-
-## External links
-
-  - [AppArmor home page](http://wiki.apparmor.net/index.php/Main_Page)
-  - [AppArmor profile wiki
-    page](http://wiki.apparmor.net/index.php/Profiles)
diff --git a/content/guidelines/filesystem_access.md b/content/guidelines/filesystem_access.md
deleted file mode 100644
index 21240fd40034b631e72d8c0ae9ce9e5cfd251a31..0000000000000000000000000000000000000000
--- a/content/guidelines/filesystem_access.md
+++ /dev/null
@@ -1,108 +0,0 @@
-+++
-date = "2015-01-14"
-weight = 100
-
-title = "Filesystem Access"
-
-aliases = [
-    "/old-wiki/Guidelines/Filesystem_access"
-]
-+++
-
-# Filesystem access
-
-There are a few anti-patterns to consider when accessing the filesystem.
-This article assumes knowledge of the standard
-[`GFile`](https://developer.gnome.org/gio/stable/GFile.html),
-[`GInputStream`](https://developer.gnome.org/gio/stable/GInputStream.html)
-and
-[`GOutputStream`](https://developer.gnome.org/gio/stable/GOutputStream.html)
-APIs.
-
-## Summary
-
-  - Always use asynchronous I/O for file access. ([Asynchronous
-    I/O](#asynchronous-i/o))
-  - Always use appropriate functions to construct file names and paths.
-    ([File path construction](#file-path-construction))
-  - Validate file paths are in the expected directories before using
-    them. ([Path validation and
-    sandboxing](#path-validation-and-sandboxing))
-  - Use AppArmor profiles to enforce constraints on file access.
-    ([Path validation and
-    sandboxing](#path-validation-and-sandboxing))
-
-## Asynchronous I/O
-
-All I/O should be performed asynchronously. That is, without blocking
-the [GLib main
-context](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html).
-This can be achieved by always using the `*_async()` and `*_finish()`
-variants of each I/O function. For example,
-[`g_input_stream_read_async()`](https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async)
-rather than
-[`g_input_stream_read()`](https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read).
-
-Synchronous I/O blocks the main loop, which means that other events,
-such as user input, incoming networking packets, timeouts and idle
-callbacks, are not handled until the blocking function returns.
-
-Note that the alternative – running synchronous I/O in a separate thread
-– is highly discouraged; see the [threading
-guidelines]( {{< ref "/guidelines/threading.md#when-to-use-threading" >}} ) for
-more information.
-
-## File path construction
-
-File names and paths are not normal strings: on some systems, they can
-use a character encoding other than UTF-8, while normal strings in GLib
-are guaranteed to always use UTF-8. For this reason, special functions
-should be used to build and handle file names and paths. (Modern Linux
-systems almost universally use UTF-8 for filename encoding, so this is
-not an issue in practice, but the file path functions should still be
-used.)
-
-For example, file paths should be built using
-[`g_build_filename()`](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-build-filename)
-rather than
-[`g_strconcat()`](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strconcat).
-Doing so makes it clearer what the code is meant to do, and also
-eliminates duplicate directory separators, so the returned path is
-canonical (though not necessarily absolute).
-
-As another example, paths should be disassembled using
-[`g_path_get_basename()`](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-basename)
-and
-[`g_path_get_dirname()`](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-dirname)
-rather than
-[`g_strrstr()`](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strrstr)
-and other manual searching functions.
-
-## Path validation and sandboxing
-
-If a filename or path comes from external input, such as a web page or
-user input, it should be validated to ensure that putting it into a file
-path will not produce an arbitrary path. For example if a filename is
-constructed from the constant string `~/` plus some user input, if the
-user inputs `../../etc/passwd`, they can (potentially) gain access to
-sensitive account information, depending on which user the program is
-running as, and what it does with data loaded from the constructed path.
-
-This can be avoided by validating constructed paths before using them,
-using
-[`g_file_resolve_relative_path()`](https://developer.gnome.org/gio/stable/GFile.html#g-file-resolve-relative-path)
-to convert any relative paths to absolute ones, and then validating that
-the path is beneath a given root sandboxing directory appropriate for
-the operation. For example, if code downloads a file, it could validate
-that all paths are beneath `~/Downloads`, using
-[`g_file_has_parent()`](https://developer.gnome.org/gio/stable/GFile.html#g-file-has-parent).
-
-As a second line of defence, all projects which access the filesystem
-should provide an AppArmor profile which limits the directories they can
-read from and write to. See the [AppArmor
-guidelines]( {{< ref "/guidelines/apparmor.md" >}} ) for more information.
-
-## External links
-
-  - [GFile
-    documentation](https://developer.gnome.org/gio/stable/GFile.html)
diff --git a/content/guidelines/introspection.md b/content/guidelines/introspection.md
deleted file mode 100644
index 42f4ca96d969b77f3d291b9a9c02cd20c215a14d..0000000000000000000000000000000000000000
--- a/content/guidelines/introspection.md
+++ /dev/null
@@ -1,114 +0,0 @@
-+++
-date = "2015-01-15"
-weight = 100
-
-title = "Introspection"
-
-aliases = [
-    "/old-wiki/Guidelines/Introspection"
-]
-+++
-
-# Introspection
-
-[GObject
-introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
-(abbreviated ‘GIR’) is a system which extracts APIs from C code and
-produces binary type libraries which can be used by non-C language
-bindings, and other tools, to
-[introspect](http://en.wikipedia.org/wiki/Type_introspection) or
-[wrap](http://en.wikipedia.org/wiki/Language_binding) the original C
-libraries. It uses a system of annotations in documentation comments in
-the C code to expose extra information about the APIs which is not
-machine readable from the code itself.
-
-It should be enabled for all public APIs: so all libraries. It cannot be
-enabled for programs, since they expose no APIs. However, it is still
-recommended to [add introspection annotations to documentation
-comments]( {{< ref "/guidelines/api_documentation.md#introspection-annotations" >}} )
-in program code, as they clarify the documentation.
-
-## Summary
-
-  - Enable introspection for all libraries. ([Using
-    introspection](#using-introspection))
-  - Pay attention to warnings from `g-ir-scanner` and
-    `introspectable="0"` attributes in GIR files. ([Using
-    introspection](#using-introspection))
-  - Add introspection annotations to all documentation comments.
-    ([Using introspection](#using-introspection))
-  - Design APIs to be introspectable from the start. ([API
-    design](#api-design))
-
-## Using introspection
-
-The first step for using introspection is to add it to the build system,
-following the instructions
-[here](https://wiki.gnome.org/Projects/GObjectIntrospection/AutotoolsIntegration#Method_1_-_Recommended_-_most_portable),
-following method 1. This should be done early in the life of a project,
-as introspectability affects [API design](#api-design).
-
-This should result in a `.gir` and `.typelib` file being generated for
-the project. The `.gir` file is human readable, and can be inspected
-manually to see if the API has been introspected correctly (although the
-GIR compilation process will print error messages and warnings for any
-missing annotations or other problems). APIs with `introspectable="0"`
-will not be exposed to language bindings as they are missing annotations
-or are otherwise not representable in the GIR file.
-
-The next step is to [add annotations to the documentation comments for
-every piece of public
-API]( {{< ref "/guidelines/api_documentation.md#introspection-annotations" >}} ).
-If a particular piece of API should not be exposed in the GIR file, use
-the `(skip)` annotation. Documentation on the available annotations is
-[here](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations).
-
-Annotations do not have to be added exhaustively: GIR has a set of
-default annotations which it applies based on various conventions (see
-[API design](#api-design)). For example, a `const gchar*`
-parameter does not need an explicit `(transfer none)` annotation,
-because the `const` modifier implies this already. Learning the defaults
-for annotations is a matter of practice.
-
-## API design
-
-In order to be introspectable without too many annotations, APIs must
-follow certain conventions, such as the [standard GObject naming
-conventions](https://developer.gnome.org/gobject/stable/gtype-conventions.html),
-and the [conventions for bindable
-APIs](https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs).
-This is necessary because of the flexibility of C: code can be written
-to behave in any way imaginable, but higher level languages don’t allow
-this kind of freedom. So in order for a C API to be representable in a
-higher level language, it has to conform to the behaviours supported by
-that language.
-
-For example, GIR expects that if a function can fail, it will have a
-`GError**` parameter, which will always be its final parameter. The GIR
-scanner detects this and automatically converts that parameter to an
-exception attribute on the method in the GIR file. It cannot do this if
-the `GError*` is returned directly, or is not the final function
-parameter, for example.
-
-Therefore, APIs must be designed to be introspectable, and the GIR file
-should be checked as the APIs are being written. If the GIR doesn’t
-match what you expect for a new API, the API may need extra annotations,
-or even for its C declaration to be changed (as in the case of
-[`va_list`](https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs#va_list)).
-
-`g-ir-scanner` emits warnings when it encounters code it does not
-understand. By passing `--warn-error` as well as `--warn-all` in
-`INTROSPECTION_SCANNER_ARGS` in `Makefile.am`, compilation will fail
-when unintrospectable APIs are encountered. This will ensure all new
-APIs are introspectable, and is highly recommended.
-
-## External links
-
-  - [GObject introspection home
-    page](https://wiki.gnome.org/Projects/GObjectIntrospection)
-  - [GIR annotation
-    reference](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations)
-  - [GObject naming
-    conventions](https://developer.gnome.org/gobject/stable/gtype-conventions.html)
-  - [Guide to writing bindable
-    APIs](https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs)
diff --git a/content/guidelines/memory_management.md b/content/guidelines/memory_management.md
deleted file mode 100644
index aae24b7fa4b3d99367db7cdfe58e3cbad8bcb4cf..0000000000000000000000000000000000000000
--- a/content/guidelines/memory_management.md
+++ /dev/null
@@ -1,526 +0,0 @@
-+++
-date = "2015-09-08"
-weight = 100
-
-title = "Memory Management"
-
-aliases = [
-    "/old-wiki/Guidelines/Memory_management"
-]
-+++
-
-# Memory management
-
-Apertis is predominantly written in C, so dynamically allocated memory
-has to be managed manually. Through use of GLib convenience APIs, memory
-management can be trivial, but programmers always need to keep memory in
-mind when writing code.
-
-It is assumed that users of Apertis are familiar with the idea of heap
-allocation of memory using `malloc()` and `free()`, and know of the GLib
-equivalents, `g_malloc()` and `g_free()`.
-
-## Summary
-
-There are three situations to avoid, in order of descending importance:
-
-1.  Using memory after freeing it (use-after-free).
-2.  Using memory before allocating it.
-3.  Not freeing memory after allocating it (leaking).
-
-Key principles, in no particular order:
-
-  - Determine and document whether each variable is owned or unowned.
-    They must never change from one to the other at runtime.
-    ([Principles of memory
-    management](#principles-of-memory-management))
-  - Determine and document the ownership transfers at function
-    boundaries. ([Principles of memory
-    management](#principles-of-memory-management))
-  - Ensure that each assignment, function call and function return
-    respects the relevant ownership transfers.
-    ([Assignments](#assignments), [Function
-    calls](#function-calls), [Function
-    returns](#function-returns))
-  - Use reference counting rather than explicit finalisation where
-    possible. ([Reference counting](#reference-counting))
-  - Use GLib convenience functions like
-    [`g_clear_object()`](#g_clear_object) where
-    possible. ([Convenience
-    functions](#convenience-functions))
-  - Do not split memory management across code paths. ([Principles of
-    memory management](#principles-of-memory-management))
-  - Use the single-path cleanup pattern for large or complex functions.
-    ([Single-path cleanup](#single-path-cleanup))
-  - Leaks should be checked for using Valgrind.
-    ([Verification](#verification))
-
-## Principles of memory management
-
-The normal approach to memory management is for the programmer to keep
-track of which variables point to allocated memory, and to manually free
-them when they are no longer needed. This is correct, but can be
-clarified by introducing the concept of *ownership*, which is the piece
-of code (such as a function, struct or object) which is responsible for
-freeing a piece of allocated memory (an *allocation*). Each allocation
-has exactly one owner; this owner may change as the program runs, by
-*transferring* ownership to another piece of code. Each variable is
-*owned* or *unowned*, according to whether the scope containing it is
-always its owner. Each function parameter and return type either
-transfers ownership of the values passed to it, or it doesn’t. By
-statically calculating which variables are owned, memory management
-becomes a simple task of unconditionally freeing the owned variables
-before they leave their scope, and *not* freeing the unowned variables
-(see [Single-path cleanup](#single-path-cleanup)).
-
-There is an important restriction here: variables must **never** change
-from owned to unowned (or vice-versa) at runtime. This restriction is
-key to simplifying memory management.
-
-For example, given the functions:
-
-    gchar *generate_string (const gchar *template);
-    void print_string (const gchar *str);
-
-the following code has been annotated to note where the ownership
-transfers happen:
-
-    gchar *my_str = NULL;  /* owned */
-    const gchar *template;  /* unowned */
-    GValue value = G_VALUE_INIT;  /* owned */
-    g_value_init (&value, G_TYPE_STRING);
-
-    /* Transfers ownership of a string from the function to the variable. */
-    template = "XXXXXX";
-    my_str = generate_string (template);
-
-    /* No ownership transfer. */
-    print_string (my_str);
-
-    /* Transfer ownership. We no longer have to free @my_str. */
-    g_value_take_string (&value, my_str);
-
-    /* We still have ownership of @value, so free it before it goes out of scope. */
-    g_value_unset (&value);
-
-There are a few points here: Firstly, the ‘owned’ comments by the
-variable declarations denote that those variables are owned by the local
-scope, and hence need to be freed before they go out of scope. The
-alternative is ‘unowned’, which means the local scope does *not* have
-ownership, and *must not* free the variables before going out of scope.
-Similarly, ownership *must not* be transferred to them on assignment.
-
-Secondly, the variable type modifiers reflect the ownership status of
-each variable: because `my_str` is owned by the local scope, it has type
-`gchar`, whereas `template` is `const` to denote it is unowned.
-Similarly, the `template` parameter of `generate_string()` and the `str`
-parameter of `print_string()` are `const` because no ownership is
-transferred when those functions are called. As ownership *is*
-transferred for the string parameter of `g_value_take_string()`, we can
-expect its type to be `gchar`.
-
-(Note that this is not the case for `GObject`s and subclasses, which can
-never be `const`. It is only the case for strings and simple `struct`s.)
-
-Given this ownership and transfer infrastructure, the correct approach
-to memory allocation can be mechanically determined for each situation.
-In each case, the `copy()` function must be appropriate to the data
-type, e.g. `g_strdup()` for strings, or `g_object_ref()` for GObjects.
-
-### Assignments
-
-<table>
-<thead>
-<tr class="header">
-<th><p>Assigning from/to</p></th>
-<th><p>Owned destination</p></th>
-<th><p>Unowned destination</p></th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td><p>Owned source</p></td>
-<td><p>Copy or move the source to the destination.<br />
-<code>owned_dest = copy (owned_src)</code> or<br />
-<code>owned_dest = owned_src; owned_src = NULL</code>.</p></td>
-<td><p>Pure assignment, assuming the unowned variable is not used after the owned one is freed.<br />
-<code>unowned_dest = owned_src</code>.</p></td>
-</tr>
-<tr class="even">
-<td><p>Unowned source</p></td>
-<td><p>Copy the source to the destination.<br />
-<code>owned_dest = copy (unowned_src)</code>.</p></td>
-<td><p>Pure assignment.<br />
-<code>unowned_dest = unowned_src</code>.</p></td>
-</tr>
-</tbody>
-</table>
-
-### Function calls
-
-<table>
-<thead>
-<tr class="header">
-<th><p>Call from/to</p></th>
-<th><p>Transfer full parameter</p></th>
-<th><p>Transfer none parameter</p></th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td><p>Owned source</p></td>
-<td><p>Copy or move the source for the parameter.<br />
-<code>function_call (copy (owned_src))</code> or<br />
-<code>function_call (owned_src); owned_src = NULL</code>.</p></td>
-<td><p>Pure parameter passing.<br />
-<code>function_call (owned_src)</code>.</p></td>
-</tr>
-<tr class="even">
-<td><p>Unowned source</p></td>
-<td><p>Copy the source for the parameter.<br />
-<code>function_call (copy (unowned_src))</code>.</p></td>
-<td><p>Pure parameter passing.<br />
-<code>function_call (unowned_src)</code>.</p></td>
-</tr>
-</tbody>
-</table>
-
-### Function returns
-
-<table>
-<thead>
-<tr class="header">
-<th><p>Return from/to</p></th>
-<th><p>Transfer full return</p></th>
-<th><p>Transfer none return</p></th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td><p>Owned source</p></td>
-<td><p>Pure variable return.<br />
-<code>return owned_src</code>.</p></td>
-<td><p>Invalid. The source needs to be freed, so the return value would use freed memory — a use-after-free error.</p></td>
-</tr>
-<tr class="even">
-<td><p>Unowned source</p></td>
-<td><p>Copy the source for the return.<br />
-<code>return copy (unowned_src)</code>.</p></td>
-<td><p>Pure variable passing.<br />
-<code>return unowned_src</code>.</p></td>
-</tr>
-</tbody>
-</table>
-
-## Documentation
-
-Documenting the ownership transfer for each function parameter and
-return, and the ownership for each variable, is important. While they
-may be clear when writing the code, they are not clear a few months
-later; and may never be clear to users of an API. They should always be
-documented.
-
-The best way to document ownership transfer is to use the
-[`(transfer)`](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Memory_and_lifecycle_management)
-annotation introduced by
-[gobject-introspection](https://wiki.gnome.org/Projects/GObjectIntrospection).
-Include this in the API documentation comment for each function
-parameter and return type. If a function is not public API, write a
-documentation comment for it anyway and include the `(transfer)`
-annotations. By doing so, the gobject-introspection tools can also read
-the annotations and use them to correctly introspect the API.
-
-Further [documentation on introspection is
-available]( {{< ref "/guidelines/introspection.md" >}} ).
-
-For example:
-
-    /**
-     * g_value_take_string:
-     * @value: (transfer none): an initialised #GValue
-     * @str: (transfer full): string to set it to
-     *
-     * Function documentation goes here.
-     */
-
-    /**
-     * generate_string:
-     * @template: (transfer none): a template to follow when generating the string
-     *
-     * Function documentation goes here.
-     *
-     * Returns: (transfer full): a newly generated string
-     */
-
-Ownership for variables can be documented using inline comments. These
-are non-standard, and not read by any tools, but can form a convention
-if used consistently.
-
-    GObject *some_owned_object = NULL;  /* owned */
-    GObject *some_unowned_object;  /* unowned */
-
-The documentation for [Container types](#container-types)
-is similarly only a convention; it includes the type of the contained
-elements too:
-
-    GPtrArray/*<owned gchar*>*/ *some_unowned_string_array;  /* unowned */
-    GPtrArray/*<owned gchar*>*/ *some_owned_string_array = NULL;  /* owned */
-    GPtrArray/*<unowned GObject*>*/ *some_owned_object_array = NULL;  /* owned */
-
-Note also that owned variables should always be initialised so that
-freeing them is more convenient. See [Convenience
-functions](#convenience-functions).
-
-Also note that some types, e.g. basic C types like strings, can have the
-`const` modifier added if they are unowned, to take advantage of
-compiler warnings resulting from assigning those variables to owned
-variables (which must *not* use the `const` modifier). If so, the `/*
-unowned */` comment may be omitted.
-
-## Reference counting
-
-As well as conventional `malloc()`/`free()`-style types, GLib has
-various reference counted types —
-[`GObject`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html)
-being a prime example.
-
-The concepts of ownership and transfer apply just as well to reference
-counted types as they do to allocated types. A scope *owns* a reference
-counted type if it holds a strong reference to the instance (e.g. by
-calling
-[`g_object_ref()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref)).
-An instance can be ‘copied’ by calling `g_object_ref()` again. Ownership
-can be freed with
-[`g_object_unref()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref)
-— even though this may not actually finalise the instance, it frees the
-current scope’s ownership of that instance.
-
-See [`g_clear_object()`](#g_clear_object) for a
-convenient way of handling GObject references.
-
-There are other reference counted types in GLib, such as
-[`GHashTable`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html)
-(using
-[`g_hash_table_ref()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-ref)
-and
-[`g_hash_table_unref()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-unref)),
-or
-[`GVariant`](https://developer.gnome.org/glib/stable/glib-GVariant.html)
-([`g_variant_ref()`](https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-ref),
-[`g_variant_unref()`](https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-unref)).
-Some types, like `GHashTable`, support both reference counting and
-explicit finalisation. Reference counting should always be used in
-preference, because it allows instances to be easily shared between
-multiple scopes (each holding their own reference) without having to
-allocate multiple copies of the instance. This saves memory.
-
-## Convenience functions
-
-GLib provides various convenience functions for memory management,
-especially for GObjects. Three will be covered here, but others exist —
-check the GLib API documentation for more. They typically follow similar
-naming schemas to these three (using ‘_full’ suffixes, or the verb
-‘clear’ in the function name).
-
-### `g_clear_object()`
-
-[`g_clear_object()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-clear-object)
-is a version of
-[`g_object_unref()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref)
-which unrefs a GObject and then clears the pointer to it to `NULL`.
-
-This makes it easier to implement code that guarantees a GObject pointer
-is always either `NULL`, or has ownership of a GObject (but which never
-points to a GObject it no longer owns).
-
-By initialising all owned GObject pointers to `NULL`, freeing them at
-the end of the scope is as simple as calling `g_clear_object()` without
-any checks, as discussed in [Single-path
-cleanup](#single-path-cleanup):
-
-    void
-    my_function (void)
-    {
-      GObject *some_object = NULL;  /* owned */
-
-      if (rand ())
-        {
-          some_object = create_new_object ();
-          /* do something with the object */
-        }
-
-      g_clear_object (&some_object);
-    }
-
-### `g_list_free_full()`
-
-[`g_list_free_full()`](https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free-full)
-frees all the elements in a linked list, *and all their data*. It is
-much more convenient than iterating through the list to free all the
-elements’ data, then calling
-[`g_list_free()`](https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free)
-to free the `GList` elements themselves.
-
-### `g_hash_table_new_full()`
-
-[`g_hash_table_new_full()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new-full)
-is a newer version of
-[`g_hash_table_new()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new)
-which allows setting functions to destroy each key and value in the hash
-table when they are removed. These functions are then automatically
-called for all keys and values when the hash table is destroyed, or when
-an entry is removed using `g_hash_table_remove()`.
-
-Essentially, it simplifies memory management of keys and values to the
-question of whether they are present in the hash table. See [Container
-types](#container-types) for a discussion on ownership of
-elements within container types.
-
-A similar function exists for `GPtrArray`:
-[`g_ptr_array_new_with_free_func()`](https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-new-with-free-func).
-
-## Container types
-
-When using container types, such as `GPtrArray` or `GList`, an
-additional level of ownership is introduced: as well as the ownership of
-the container instance, each element in the container is either owned or
-unowned too. By nesting containers, multiple levels of ownership must be
-tracked. Ownership of owned elements belongs to the container; ownership
-of the container belongs to the scope it’s in (which may be another
-container).
-
-A key principle for simplifying this is to ensure that all elements in a
-container have the same ownership: they are either all owned, or all
-unowned. This happens automatically if the normal [Convenience
-functions](#convenience-functions) are used for types like
-`GPtrArray` and `GHashTable`.
-
-If elements in a container are *owned*, adding them to the container is
-essentially an ownership transfer. For example, for an array of strings,
-if the elements are owned, the definition of `g_ptr_array_add()` is
-effectively:
-
-    /**
-     * g_ptr_array_add:
-     * @array: a #GPtrArray
-     * @str: (transfer full): string to add
-     */
-    void
-    g_ptr_array_add (GPtrArray *array,
-                     gchar *str);
-
-So, for example, constant (unowned) strings must be added to the array
-using `g_ptr_array_add (array, g_strdup ("constant string"))`.
-
-Whereas if the elements are unowned, the definition is effectively:
-
-    /**
-     * g_ptr_array_add:
-     * @array: a #GPtrArray
-     * @str: (transfer none): string to add
-     */
-    void
-    g_ptr_array_add (GPtrArray *array,
-                     const gchar *str);
-
-and constant strings can be added without copying them: `g_ptr_array_add
-(array, "constant string")`.
-
-See the [Documentation](#documentation) section for
-examples of comments to add to variable definitions to annotate them
-with the element type and ownership.
-
-## Single-path cleanup
-
-A useful design pattern for more complex functions is to have a single
-control path which cleans up (frees) allocations and returns to the
-caller. This vastly simplifies tracking of allocations, as it’s no
-longer necessary to mentally work out which allocations have been freed
-on each code path — all code paths end at the same point, so perform all
-the frees then. The benefits of this approach rapidly become greater for
-larger functions with more owned local variables; it may not make sense
-to apply the pattern to smaller functions.
-
-This approach has two requirements:
-
-1.  The function returns from a single point, and uses `goto` to reach
-    that point from other paths.
-2.  All owned variables are set to `NULL` when initialised or when
-    ownership is transferred away from them.
-
-The example below is for a small function (for brevity), but should
-illustrate the principles for application of the pattern to larger
-functions:
-
-    GObject *
-    some_function (GError **error)
-    {
-      gchar *some_str = NULL;  /* owned */
-      GObject *temp_object = NULL;  /* owned */
-      const gchar *temp_str;
-      GObject *my_object = NULL;  /* owned */
-      GError *child_error = NULL;  /* owned */
-
-      temp_object = generate_object ();
-      temp_str = "example string";
-
-      if (rand ())
-        {
-          some_str = g_strconcat (temp_str, temp_str, NULL);
-        }
-      else
-        {
-          some_operation_which_might_fail (&child_error);
-
-          if (child_error != NULL)
-            {
-              goto done;
-            }
-
-          my_object = generate_wrapped_object (temp_object);
-        }
-
-    done:
-      /* Here, @some_str is either NULL or a string to be freed, so can be passed to g_free() unconditionally.
-       * Similarly, @temp_object is either NULL or an object to be unreffed, so can be passed to g_clear_object() unconditionally. */
-      g_free (some_str);
-      g_clear_object (&temp_object);
-
-      /* The pattern can also be used to ensure that the function always returns either an error or a return value (but never both). */
-      if (child_error != NULL)
-        {
-          g_propagate_error (error, child_error);
-          g_clear_object (&my_object);
-        }
-
-      return my_object;
-    }
-
-## Verification
-
-Memory leaks can be checked for in two ways: static analysis, and
-runtime leak checking.
-
-Static analysis with tools like [Coverity](https://scan.coverity.com/)
-or [Tartan](http://people.collabora.com/~pwith/tartan/) can catch some
-leaks, but require knowledge of the ownership transfer of every function
-called in the code. Domain-specific static analysers like Tartan (which
-knows about GLib memory allocation and transfer) can perform better
-here, but Tartan is quite a young project and still misses things (a low
-true positive rate). It is recommended that code be put through a static
-analyser, but the primary tool for detecting leaks should be runtime
-leak checking.
-
-Runtime leak checking is done using [Valgrind](http://valgrind.org/),
-using its [memcheck](http://valgrind.org/docs/manual/mc-manual.html)
-tool. Any leak it detects as ‘definitely losing memory’ should be fixed.
-Many of the leaks which ‘potentially’ lose memory are not real leaks,
-and should be added to the suppression file.
-
-See the [tooling page]( {{< ref "/guidelines/tooling.md#valgrind" >}} ) for more
-information on using Valgrind.
-
-## External links
-
-  - [An article on ownership
-    transfer](https://tecnocode.co.uk/2013/09/03/const-gchar-vs-gchar-and-other-memory-management-stories/)
diff --git a/content/guidelines/processes.md b/content/guidelines/processes.md
deleted file mode 100644
index d036a63065f50003e8881511701e9a897dc66f31..0000000000000000000000000000000000000000
--- a/content/guidelines/processes.md
+++ /dev/null
@@ -1,117 +0,0 @@
-+++
-date = "2015-01-14"
-weight = 100
-
-title = "Processes"
-
-aliases = [
-    "/old-wiki/Guidelines/Processes"
-]
-+++
-
-# Processes
-
-There are various things which affect an entire application process.
-They are not all related, so are covered in separate subsections; some
-apply to all applications, others to specific functionality.
-
-## Summary
-
-  - Use libraries instead of subprocesses where possible.
-    ([Subprocesses](#subprocesses))
-  - Use closed-loop subprocess management to keep track of when
-    subprocesses exit. ([Subprocesses](#subprocesses))
-  - Do *not* use `sigaction()`: use `g_unix_signal_add()` instead.
-    ([UNIX signals](#unix-signals))
-  - Do *not* use `sleep()`: use `g_timeout_add_seconds()` instead.
-    ([Sleeping](#sleeping))
-  - Do *not* use `system()`: use libraries or single subprocesses
-    instead. ([Shell commands](#shell-commands))
-  - Use `GApplication` and `GOptionContext` to do command line parsing.
-    ([Command line parsing](#command-line-parsing))
-
-## Subprocesses
-
-Launching subprocesses is sometimes necessary to perform specific tasks,
-though where possible it is generally better to link against and use an
-appropriate library to perform the same task, as it eliminates a lot of
-potential failure points, simplifies passing data around (as passing
-data to subprocesses involves pipes, and is complex), and generally
-allows for greater interaction between the parent process and the task.
-
-Subprocesses should not be used to implement functionality which could
-be implemented by [D-Bus service
-daemons]( {{< ref "d-bus_services.md" >}} ).
-
-When using subprocesses, closed-loop management should be used, by
-monitoring the child process’ PID after sending it kill signals, and
-waiting until the child process terminates before proceeding with
-further processing. The alternative, open-loop management, sends signals
-and never checks to see if the child responded to them, which is more
-fragile.
-
-To do this, use
-[`g_spawn_async()`](https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html)
-to spawn child processes, and
-[`g_child_watch_add()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html)
-to set up a callback to be invoked when the child exits.
-
-## UNIX signals
-
-The standard UNIX function for setting up signal handlers,
-[`sigaction()`](http://man7.org/linux/man-pages/man2/sigaction.2.html),
-*must not* be used in GLib programs, as its callback must be re-entrancy
-safe, and no GLib code is re-entrancy safe. Instead,
-[`g_unix_signal_add()`](https://developer.gnome.org/glib/stable/glib-UNIX-specific-utilities-and-integration.html#g-unix-signal-add)
-should be used, which doesn’t require its callback to be re-entrancy
-safe.
-
-## Sleeping
-
-The
-[`sleep()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html)
-function *must not* be used in GLib code, as it blocks the current
-thread. Instead,
-[`g_timeout_add_seconds()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add-seconds)
-or
-[`g_timeout_add()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add)
-should be used to schedule a callback to be invoked after a period of
-time; in the mean time, events can continue being processed by the main
-context.
-
-## Shell commands
-
-The [`system()`](http://linux.die.net/man/3/system) function *must not*
-be used. It is extremely prone to [shell injection
-vulnerabilities](http://en.wikipedia.org/wiki/Code_injection#Shell_injection),
-and any functionality which can be implemented using it can be
-implemented using libraries directly or, if that is not possible,
-spawning individual [subprocesses](#subprocesses).
-
-For example, instead of calling `system (g_strdup_printf ("mv %s %s",
-file_path1, file_path2))`, use
-[`g_file_move()`](https://developer.gnome.org/gio/stable/GFile.html#g-file-move).
-In this situation, using `system()` exposes a shell injection
-vulnerability, and will not work with paths containing spaces in any
-case.
-
-## Command line parsing
-
-Command line parsing should be implemented using
-[`GApplication`](https://developer.gnome.org/gio/stable/GApplication.html)
-and
-[`GOptionContext`](https://developer.gnome.org/glib/stable/glib-Commandline-option-parser.html),
-rather than being implemented manually or using another library (such as
-[popt](http://directory.fsf.org/wiki/Popt)).
-
-By using `GOptionContext`, command line parsing follows the standard
-format used by most Linux applications. It gives automatic support for
-`--help` output, and short and long option parsing.
-
-An example of using `GApplication` together with `GOptionContext` is
-[here](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline3.c).
-
-## External links
-
-  - [Article on shell injection
-    vulnerabilities](http://en.wikipedia.org/wiki/Code_injection#Shell_injection)
diff --git a/content/guidelines/threading.md b/content/guidelines/threading.md
deleted file mode 100644
index d3dbfeb0c023e2841c2948b848336d1f5703b0e7..0000000000000000000000000000000000000000
--- a/content/guidelines/threading.md
+++ /dev/null
@@ -1,229 +0,0 @@
-+++
-date = "2015-01-14"
-weight = 100
-
-title = "Threading"
-
-aliases = [
-    "/old-wiki/Guidelines/Threading"
-]
-+++
-
-# Threading
-
-## Summary
-
-  - Do not use threads if at all possible. ([When to use
-    threading](#when-to-use-threading))
-  - If threads have to be used, use `GTask` or `GThreadPool` and isolate
-    the threaded code as much as possible. ([Using
-    threading](#using-threading))
-  - Use `g_thread_join()` to avoid leaking thread resources if using
-    `GThread` manually. ([Using
-    threading](#using-threading))
-  - Be careful about the `GMainContext` which code is executed in if
-    using threads. Executing code in the wrong context can cause race
-    conditions, or block the main loop. ([Using
-    threading](#using-threading))
-
-## When to use threading
-
-When writing projects using GLib, the default approach should be to
-**never use threads**. Instead, make proper use of the GLib main context
-which, through the use of asynchronous operations, allows most blocking
-I/O operations to continue in the background while the main context
-continues to process other events. Analysis, review and debugging of
-threaded code becomes very hard, very quickly.
-
-Threading should only be necessary when using an external library which
-has blocking functions which need to be called from GLib code. If the
-library provides a non-blocking alternative, or one which integrates
-with a
-[`poll()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html)
-loop, that should be used in preference. If the blocking function really
-must be used, a thin wrapper should be written for it to convert it to
-the normal [`GAsyncResult`
-style](https://developer.gnome.org/gio/stable/GAsyncResult.html) of GLib
-asynchronous function, running the blocking operation in a worker
-thread.
-
-e.g.
-
-    int some_blocking_function (void *param1, void *param2);
-
-should be wrapped as:
-
-    void some_blocking_function_async (void *param1, void *param2, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-    int some_blocking_function_finish (GAsyncResult *result, GError **error);
-
-With an implementation something like:
-
-    /* Closure for the call’s parameters. */
-    typedef struct {
-      void *param1;
-      void *param2;
-    } SomeBlockingFunctionData;
-
-    static void
-    some_blocking_function_data_free (SomeBlockingFunctionData *data)
-    {
-      free_param (data->param1);
-      free_param (data->param2);
-
-      g_slice_free (SomeBlockingFunctionData, data);
-    }
-
-    static void
-    some_blocking_function_thread_cb (GTask *task,
-                                      gpointer source_object,
-                                      gpointer task_data,
-                                      GCancellable *cancellable)
-    {
-      SomeBlockingFunctionData *data = task_data;
-      int retval;
-
-      /* Handle cancellation. */
-      if (g_task_return_error_if_cancelled (task))
-        {
-          return;
-        }
-
-      /* Run the blocking function. */
-      retval = some_blocking_function (data->param1, data->param2);
-      g_task_return_int (task, retval);
-    }
-
-    void
-    some_blocking_function_async (void *param1,
-                                  void *param2,
-                                  GCancellable *cancellable,
-                                  GAsyncReadyCallback callback,
-                                  gpointer user_data)
-    {
-      GTask *task = NULL;  /* owned */
-      SomeBlockingFunctionData *data = NULL;  /* owned */
-
-      g_return_if_fail (validate_param (param1));
-      g_return_if_fail (validate_param (param2));
-      g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
-      task = g_task_new (NULL, cancellable, callback, user_data);
-      g_task_set_source_tag (task, some_blocking_function_async);
-
-      /* Cancellation should be handled manually using mechanisms specific to
-       * some_blocking_function(). */
-      g_task_set_return_on_cancel (task, FALSE);
-
-      /* Set up a closure containing the call’s parameters. Copy them to avoid
-       * locking issues between the calling thread and the worker thread. */
-      data = g_slice_new (SomeBlockingFunctionData);
-      data->param1 = copy_param (param1);
-      data->param2 = copy_param (param2);
-
-      g_task_set_task_data (task, data, some_blocking_function_data_free);
-
-      /* Run the task in a worker thread and return immediately while that continues
-       * in the background. When it’s done it will call @callback in the current
-       * thread default main context. */
-      g_task_run_in_thread (task, some_blocking_function_thread_cb);
-
-      g_object_unref (task);
-    }
-
-    int
-    some_blocking_function_finish (GAsyncResult *result,
-                                   GError **error)
-    {
-      g_return_val_if_fail (g_task_is_valid (result,
-                                             some_blocking_function_async), -1);
-      g_return_val_if_fail (error == NULL || *error == NULL, -1);
-
-      return g_task_propagate_int (G_TASK (result), error);
-    }
-
-See the [`GAsyncResult`
-documentation](https://developer.gnome.org/gio/stable/GAsyncResult.html)
-for more details. A simple way to implement the worker thread is to use
-[`GTask`](https://developer.gnome.org/gio/stable/GTask.html) and
-[`g_task_run_in_thread()`](https://developer.gnome.org/gio/stable/GTask.html#g-task-run-in-thread).
-
-## Using threading
-
-If `GTask` is not suitable for writing the worker thread, a more
-low-level approach must be used. This should be considered very
-carefully, as it is very easy to get threading code wrong in ways which
-will unpredictably cause bugs at runtime, cause deadlocks, or consume
-too many resources and terminate the program.
-
-A full manual on writing threaded code is beyond the scope of this
-document, but here are a number of guidelines to follow which should
-reduce the potential for bugs in threading code. The overriding
-principle is to reduce the amount of code and data which can be affected
-by threading — e.g. reducing the number of threads, the complexity of
-worker thread implementation, and the amount of data shared between
-threads.
-
-  - Use
-    [`GThreadPool`](https://developer.gnome.org/glib/stable/glib-Thread-Pools.html)
-    instead of manually creating
-    [`GThread`s](https://developer.gnome.org/glib/stable/glib-Threads.html)
-    if possible. `GThreadPool` supports a work queue, limits on the
-    number of spawned threads, and automatically joins finished threads
-    so they are not leaked.
-  - If it is not possible to use a `GThreadPool` (which is rarely the
-    case):
-      - Use
-        [`g_thread_try_new()`](https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-try-new)
-        to spawn threads, instead of
-        [`g_thread_new()`](https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-new),
-        so errors due to the system running out of threads can be
-        handled gracefully rather than unconditionally aborting the
-        program.
-      - Explicitly join threads using
-        [`g_thread_join()`](https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-join)
-        to avoid leaking the thread resources.
-  - Use message passing to transfer data between threads, rather than
-    manual locking with mutexes. `GThreadPool` explicitly supports this
-    with
-    [`g_thread_pool_push()`](https://developer.gnome.org/glib/stable/glib-Thread-Pools.html#g-thread-pool-push).
-  - If mutexes must be used:
-      - Isolate threading code as much as possible, keeping mutexes
-        private within classes, and tightly bound to very specific class
-        members.
-      - All mutexes should be clearly commented beside their
-        declaration, indicating which other structures or variables they
-        protect access to. Similarly, those variables should be
-        commented saying that they should *only* be accessed with that
-        mutex held.
-  - Be careful about interactions between main contexts and threads. For
-    example,
-    [`g_timeout_add_seconds()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add-seconds)
-    adds a timeout *to be executed in the global default main context*,
-    which is being run in the main thread, *not necessarily* the current
-    thread. Getting this wrong can mean that work intended for a worker
-    thread accidentally ends up being executed in the main thread
-    anyway.
-
-## Debugging
-
-Debugging threading issues is tricky, both because they are hard to
-reproduce, and because they are hard to reason about. This is one of the
-big reasons for avoiding using threads in the first place.
-
-However, if a threading issue does arise, [Valgrind’s drd and helgrind
-tools are useful]( {{< ref "/guidelines/tooling.md#helgrind-and-drd" >}} ).
-
-## External links
-
-  - [GThread API
-    documentation](https://developer.gnome.org/glib/stable/glib-Threads.html)
-  - [GThreadPool API
-    documentation](https://developer.gnome.org/glib/stable/glib-Thread-Pools.html)
-  - [GMainContext API
-    documentation](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html)
-  - [GAsyncResult
-    documentation](https://developer.gnome.org/gio/stable/GAsyncResult.html)
-  - [Introduction to
-    GMainContext](https://tecnocode.co.uk/2014/03/27/what-is-gmaincontext/)
-  - [Article on GMainContext and
-    threading](https://tecnocode.co.uk/2014/04/19/ensuring-functions-are-called-in-the-right-context/)
diff --git a/content/guidelines/tooling.md b/content/guidelines/tooling.md
deleted file mode 100644
index 89e90318c0900ea97287a8f8808092576fc29ab9..0000000000000000000000000000000000000000
--- a/content/guidelines/tooling.md
+++ /dev/null
@@ -1,349 +0,0 @@
-+++
-date = "2016-02-18"
-weight = 100
-
-title = "Tooling"
-
-aliases = [
-    "/old-wiki/Guidelines/Tooling"
-]
-+++
-
-# Tooling
-
-Development tools are much more than just a text editor and a compiler.
-Correct use of the right tools can drastically ease debugging and
-tracking down of complex problems with memory allocation and system
-calls, amongst other things. Some of the most commonly used tools are
-described below; other tools exist for more specialised use cases, and
-should be used when appropriate.
-
-## Summary
-
-  - Compile frequently with a second compiler. ([GCC and
-    Clang](#gcc-and-clang))
-  - Enable a large selection of compiler warnings and make them fatal.
-    ([GCC and Clang](#gcc-and-clang))
-  - Use GDB to debug and step through code. ([GDB](#gdb))
-  - Use Valgrind to analyse memory usage, memory errors, cache and CPU
-    performance and threading errors.
-    ([Valgrind](#valgrind))
-  - Use gcov and lcov to analyse unit test coverage. ([gcov and
-    lcov](#gcov-and-lcov))
-  - Submit to Coverity as a cronjob and eliminate static analysis errors
-    as they appear. ([Coverity](#coverity))
-  - Use Clang static analyser and Tartan regularly to eliminate
-    statically analysable errors locally. ([Clang static
-    analyser](#clang-static-analyser))
-
-## GCC and Clang
-
-GCC is the standard C compiler for Linux. An alternative exists in the
-form of Clang, with comparable functionality. Choose one (probably GCC)
-to use as a main compiler, but occasionally use the other to compile the
-code, as the two detect slightly different sets of errors and warnings
-in code. Clang also comes with a static analyser tool which can be used
-to detect errors in code without compiling or running it; see [Clang
-static analyser](#clang-static-analyser).
-
-Both compilers should be used with as many warning flags enabled as
-possible. Although compiler warnings do occasionally provide false
-positives, most warnings legitimately point to problems in the code, and
-hence should be fixed rather than ignored. A development policy of
-enabling all warning flags and also specifying the `-Werror` flag (which
-makes all warnings fatal to compilation) promotes fixing warnings as
-soon as they are introduced. This helps code quality. The alternative of
-ignoring warnings leads to long debugging sessions to track down bugs
-caused by issues which would have been flagged up by the warnings.
-Similarly, ignoring warnings until the end of the development cycle,
-then spending a block of time enabling and fixing them all wastes time.
-
-Both GCC and Clang support a wide range of compiler flags, only some of
-which are related to modern, multi-purpose code (e.g. others are
-outdated, or architecture-specific). Finding a reasonable set of flags
-to enable can be tricky, and hence the
-[`AX_COMPILER_FLAGS`](http://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html)
-macro exists.
-
-`AX_COMPILER_FLAGS` enables a consistent set of compiler warnings, and
-also tests that the compiler supports each flag before enabling it. This
-accounts for differences in the set of flags supported by GCC and Clang.
-To use it, add `AX_COMPILER_FLAGS` to `configure.ac`. If you are using
-in-tree copies of autoconf-archive macros, copy
-[`ax_compiler_flags.m4`](http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_compiler_flags.m4)
-to the `m4/` directory of your project. Note that it depends on the
-following autoconf-archive macros which cannot be copied in-tree due to
-being GPL-licenced. They must remain in autoconf-archive, with that as a
-built time dependency of the project:
-
-  - `ax_append_compile_flags.m4`
-  - `ax_append_flag.m4`
-  - `ax_check_compile_flag.m4`
-  - `ax_require_defined.m4`
-
-`AX_COMPILER_FLAGS` supports disabling `-Werror` for release builds, so
-that releases may always be built against newer compilers which have
-introduced more warnings. Set its third parameter to ‘yes’ for release
-builds (and only release builds) to enable this functionality.
-Development and CI builds should always have `-Werror` enabled.
-
-An easy way of determining whether this is a release version of a
-project is to use `AX_IS_RELEASE([micro-version])`. If this macro is
-used before `AX_COMPILER_FLAGS`, the third parameter to
-`AX_COMPILER_FLAGS` should not be passed — it will be picked up
-automatically from `AX_IS_RELEASE`.
-
-## GDB
-
-GDB is the standard debugger for C on Linux. Its most common uses are
-for debugging crashes, and for stepping through code as it executes. A
-full tutorial for using GDB is given
-[here](https://sourceware.org/gdb/current/onlinedocs/gdb/).
-
-To run GDB on a program from within the source tree, use:
-
-    libtool exec gdb --args ./program-name --some --arguments --here
-
-This is necessary due to libtool wrapping each compiled binary in the
-source tree in a shell script which sets up some libtool variables. It
-is not necessary for debugging installed executables.
-
-GDB has many advanced features which can be combined to essentially
-create small debugging scripts, triggered by different breakpoints in
-code. Sometimes this is a useful approach (e.g. for [reference count
-debugging](https://tecnocode.co.uk/2010/07/12/reference-count-debugging-with-gdb/)),
-but sometimes simply using `g_debug()` to output a debug message is
-simpler.
-
-## Valgrind
-
-Valgrind is a suite of tools for instrumenting and profiling programs.
-Its most famous tool is [memcheck](#memcheck), but it has
-several other powerful and useful tools too. They are covered separately
-in the sections below.
-
-A useful way of running Valgrind is to run a program’s unit test suite
-under Valgrind, setting Valgrind to return a status code indicating the
-number of errors it encountered. When run as part of `make check`, this
-will cause the checks to succeed if Valgrind finds no problems, and fail
-otherwise. However, running `make check` under Valgrind is not trivial
-to do on the command line. A macro,
-[`AX_VALGRIND_CHECK`](http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html)
-can be used which adds a new `make check-valgrind` target to automate
-this. To use it, copy
-[`ax_valgrind_check.m4`](http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_valgrind_check.m4)
-to the `m4/` directory of a project, add `AX_VALGRIND_CHECK` to
-`configure.ac` and add `@VALGRIND_CHECK_RULES` to the top-level
-`Makefile.am`.
-
-When `make check-valgrind` is run, it will save its results in
-`test-suite-*.log`, one log file per tool.
-
-Valgrind has a way to suppress false positives, by using [suppression
-files](http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress).
-These list patterns which may match error stack traces. If a stack trace
-from an error matches part of a suppression entry, it is not reported.
-For various reasons, GLib currently causes a number of false positives
-in [memcheck](#memcheck) and [helgrind and
-drd](#helgrind-and-drd) which must be suppressed by default
-for Valgrind to be useful. For this reason, every project should use a
-standard GLib suppression file as well as a project specific one.
-
-Suppression files are supported by the `AX_VALGRIND_CHECK` macro:
-
-    @VALGRIND_CHECK_RULES@
-    VALGRIND_SUPPRESSIONS_FILES = my-project.supp glib.supp
-    EXTRA_DIST = $(VALGRIND_SUPPRESSIONS_FILES)
-
-### memcheck
-
-memcheck is a memory usage and allocation analyser. It detects problems
-with memory accesses and modifications of the heap (allocations and
-frees). It is a highly robust and mature tool, and its output can be
-entirely trusted. If it says there is ‘definitely’ a memory leak, there
-is definitely a memory leak which should be fixed. If it says there is
-‘potentially’ a memory leak, there may be a leak to be fixed, or it
-may be memory allocated at initialisation time and used throughout the
-life of the program without needing to be freed.
-
-A full tutorial on using memcheck is
-[here](http://valgrind.org/docs/manual/mc-manual.html).
-
-### cachegrind and KCacheGrind
-
-cachegrind is a cache performance profiler which can also measure
-instruction execution, and hence is very useful for profiling general
-performance of a program.
-[KCacheGrind](http://kcachegrind.sourceforge.net/html/Home.html) is a
-useful UI for it which allows visualisation and exploration of the
-profiling data, and the two tools should rarely be used separately.
-
-cachegrind works by simulating the processor's memory hierarchy, so
-there are situations where it is [not perfectly
-accurate](http://valgrind.org/docs/manual/cg-manual.html#cg-manual.annopts.accuracy).
-However, its results are always representative enough to be very useful
-in debugging performance hotspots.
-
-A full tutorial on using cachegrind is
-[here](http://valgrind.org/docs/manual/cg-manual.html).
-
-### helgrind and drd
-
-helgrind and drd are threading error detectors, checking for race
-conditions in memory accesses, and abuses of the [POSIX pthreads
-API](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html).
-They are similar tools, but are implemented using different techniques,
-so both should be used.
-
-The kinds of errors detected by helgrind and drd are: data accessed from
-multiple threads without consistent locking, changes in lock acquisition
-order, freeing a mutex while it is locked, locking a locked mutex,
-unlocking an unlocked mutex, and several other errors. Each error, when
-detected, is printed to the console in a little report, with a separate
-report giving the allocation or spawning details of the mutexes or
-threads involved so that their definitions can be found.
-
-helgrind and drd can produce more false positives than memcheck or
-cachegrind, so their output should be studied a little more carefully.
-However, threading problems are notoriously elusive even to experienced
-programmers, so helgrind and drd errors should not be dismissed lightly.
-
-Full tutorials on using helgrind and drd are
-[here](http://valgrind.org/docs/manual/hg-manual.html) and
-[here](http://valgrind.org/docs/manual/drd-manual.html).
-
-### sgcheck
-
-sgcheck is an array bounds checker, which detects accesses to arrays
-which have overstepped the length of the array. However, it is a very
-young tool, still marked as experimental, and hence may produce more
-false positives than other tools.
-
-As it is experimental, sgcheck must be run by passing
-`--tool=exp-sgcheck` to Valgrind, rather than `--tool=sgcheck`.
-
-A full tutorial on using sgcheck is
-[here](http://valgrind.org/docs/manual/sg-manual.html).
-
-## gcov and lcov
-
-[gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) is a profiling tool
-built into GCC, which instruments code by adding extra instructions at
-compile time. When the program is run, this code generates `.gcda` and
-`.gcno` profiling output files. These files can be analysed by the
-`lcov` tool, which generates visual reports of code coverage at runtime,
-highlighting lines of code in the project which are run more than
-others.
-
-A critical use for this code coverage data collection is when running
-the unit tests: if the amount of code covered (e.g. which particular
-lines were run) by the unit tests is known, it can be used to guide
-further expansion of the unit tests. By regularly checking the code
-coverage attained by the unit tests, and expanding them towards 100%,
-you can be sure that the entire project is being tested. Often it is the
-case that a unit test exercises most of the code, but not a particular
-control flow path, which then harbours residual bugs.
-
-lcov supports [branch coverage
-measurement](http://en.wikipedia.org/wiki/Code_coverage#Basic_coverage_criteria),
-so is not suitable for demonstrating coverage of safety critical code.
-It is perfectly suitable for non-safety critical code.
-
-As code coverage has to be enabled at both compile time and run time, a
-macro is provided to make things simpler. The
-[`AX_CODE_COVERAGE`](http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html)
-macro adds a `make check-code-coverage` target to the build system,
-which runs the unit tests with code coverage enabled, and generates a
-report using `lcov`.
-
-To add `AX_CODE_COVERAGE` support to a project, add `AX_CODE_COVERAGE`
-to `configure.ac`. The macro itself cannot be copied to the `m4/`
-directory due to being GPL-licenced. Instead, the project must have a
-build time dependency on autoconf-archive (version 2014-10-15 or later).
-
-Documentation on using gcov and lcov is
-[here](http://ltp.sourceforge.net/coverage/lcov.php).
-
-## Coverity
-
-[Coverity](http://scan.coverity.com/) is one of the most popular and
-biggest commercial static analyser tools available. However, it is
-available to use free for Open Source projects, and any project is
-encouraged to [sign up](https://scan.coverity.com/users/sign_up).
-[Analysis is
-performed](https://scan.coverity.com/faq#how-get-project-included-in-scan)
-by running some analysis tools locally, then uploading the source code
-and results as a tarball to Coverity’s site. The results are then
-visible online to members of the project, as annotations on the
-project’s source code (similarly to how lcov presents its results).
-
-As Coverity cannot be run entirely locally, it cannot be integrated
-properly into the build system. However, scripts do exist to
-automatically scan a project and upload the tarball to Coverity
-regularly. The recommended approach is to run these scripts regularly on
-a server (i.e. as a cronjob), using a clean checkout of the project’s
-git repository. Coverity automatically e-mails project members about new
-static analysis problems it finds, so the same approch as for [compiler
-warnings](#gcc-and-clang) can be taken: eliminate all the
-static analysis warnings, then eliminate new ones as they are detected.
-
-Coverity is good, but it is not perfect, and it does produce a number of
-false positives. These should be marked as ignored in the online
-interface.
-
-## Clang static analyser
-
-One tool which can be used to perform static analysis locally is the
-[Clang static analyser](http://clang-analyzer.llvm.org/), which is a
-tool co-developed with the [Clang compiler](#gcc-and-clang).
-It detects a variety of problems in C code which compilers cannot, and
-which would otherwise only be detectable at run time (i.e. using unit
-tests).
-
-Clang produces some false positives, and there is no easy way to ignore
-them. The recommended thing to do is to [file a bug report against the
-static
-analyser](http://clang-analyzer.llvm.org/faq.html#suppress_issue), so
-that the false positive can be fixed in future.
-
-A full tutorial on using Clang is
-[here](http://clang-analyzer.llvm.org/scan-build.html).
-
-### Tartan
-
-However, for all the power of the Clang static analyser, it cannot
-detect problems with specific libraries, such as GLib. This is a problem
-if (as recommended) a project uses GLib exclusively, and rarely uses
-POSIX APIs (which Clang does understand). There is a plugin available
-for the Clang static analyser, called
-[Tartan](http://people.collabora.com/~pwith/tartan/), which extends it
-to support checks against some of the common GLib APIs.
-
-Tartan is still young software, and will produce false positives and may
-crash when run on some code. However, it can find legitimate bugs quite
-quickly, and is worth running over a code base frequently to detect new
-errors in the use of GLib in the code. Please [report any problems with
-Tartan](http://people.collabora.com/~pwith/tartan/#troubleshooting).
-
-A full tutorial on enabling Tartan for use with the Clang static
-analyser is
-[here](http://people.collabora.com/~pwith/tartan/#usage-standalone). If
-set up correctly, the output from Tartan will be mixed together with the
-normal static analyser output.
-
-## External links
-
-  - [GCC](https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/)
-  - [Clang](http://clang.llvm.org/docs/UsersManual.html)
-  - [GDB](https://sourceware.org/gdb/current/onlinedocs/gdb/)
-  - [Valgrind](http://valgrind.org/docs/manual/)
-      - [memcheck](http://valgrind.org/docs/manual/mc-manual.html)
-      - [cachegrind](http://valgrind.org/docs/manual/cg-manual.html)
-      - [helgrind](http://valgrind.org/docs/manual/hg-manual.html)
-      - [drd](http://valgrind.org/docs/manual/drd-manual.html)
-      - [sgcheck](http://valgrind.org/docs/manual/sg-manual.html)
-  - [KCacheGrind](http://kcachegrind.sourceforge.net/html/Home.html)
-  - [gcov/lcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html)
-  - [Coverity](https://scan.coverity.com/)
-  - [Clang SA](http://clang-analyzer.llvm.org/)
-  - [Tartan](http://people.collabora.com/~pwith/tartan/)
diff --git a/content/guidelines/unit_testing.md b/content/guidelines/unit_testing.md
deleted file mode 100644
index f1f678bc97dbfaf704ac731d59935e3fe4a2c0cf..0000000000000000000000000000000000000000
--- a/content/guidelines/unit_testing.md
+++ /dev/null
@@ -1,219 +0,0 @@
-+++
-date = "2015-09-08"
-weight = 100
-
-title = "Unit Testing"
-
-aliases = [
-    "/old-wiki/Guidelines/Unit_testing"
-]
-+++
-
-# Unit testing
-
-Unit testing should be the primary method of testing the bulk of code
-written, because a unit test can be written once and run many times —
-manual tests have to be planned once and then manually run each time.
-
-Development of unit tests starts with the architecture and API design of
-the code to be tested: code should be designed to be easily testable, or
-will potentially be very difficult to test.
-
-## Summary
-
-  - Write unit tests to be as small as possible, but no smaller.
-    ([Writing unit tests](#writing-unit-tests))
-  - Use code coverage tools to write tests to get high code coverage.
-    ([Writing unit tests](#writing-unit-tests))
-  - Run all unit tests under Valgrind to check for leaks and other
-    problems. ([Leak checking](#leak-checking))
-  - Use appropriate tools to automatically generate unit tests where
-    possible. ([Test generation](#test-generation))
-  - Design code to be testable from the beginning. ([Writing testable
-    code](#writing-testable-code))
-
-## Writing unit tests
-
-Unit tests should be written in conjunction with looking at [code
-coverage information gained from running the
-tests]( {{< ref "/guidelines/tooling.md#gcov-and-lcov" >}} ). This typically
-means writing an initial set of unit tests, running them to get coverage
-data, then reworking and expanding them to increase the code coverage
-levels. Coverage should be increased first by ensuring all functions are
-covered (at least in part), and then by ensuring all lines of code are
-covered. By covering functions first, API problems which will prevent
-effective testing can be found quickly. These typically manifest as
-internal functions which cannot easily be called from unit tests.
-Overall, coverage levels of over 90% should be aimed for; don’t just
-test cases covered by project requirements, test everything.
-
-Like [git commits]( {{< ref "version_control.md" >}} ), each unit
-test should be ‘as small as possible, but no smaller’, testing a single
-specific API or behaviour. Each test case must be able to be run
-individually, without depending on state from other test cases. This is
-important to allow debugging of a single failing test, without having to
-step through all the other test code as well. It also means that a
-single test failure can easily be traced back to a specific API, rather
-than a generic ‘unit tests failed somewhere’ message.
-
-GLib has support for unit testing with its [GTest
-framework](https://developer.gnome.org/glib/stable/glib-Testing.html),
-allowing tests to be arranged in groups and hierarchies. This means that
-groups of related tests can be run together for enhanced debugging too,
-by running the test binary with the `-p` argument:
-
-    ./test-suite-name -p /path/to/test/group
-
-## Installed tests
-
-All unit tests should be installed system-wide, following the
-[installed-tests
-standard](https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests).
-
-By installing the unit tests, continuous integration (CI) is made
-easier, since tests for one project can be re-run after changes to other
-projects in the CI environment, thus testing the interfaces between
-modules. That is useful for a highly-coupled set of projects like
-Apertis.
-
-To add support for installed-tests, add the following to `configure.ac`:
-
-    # Installed tests
-    AC_ARG_ENABLE([modular_tests],
-                  AS_HELP_STRING([--disable-modular-tests],
-                                 [Disable build of test programs (default: no)]),,
-                  [enable_modular_tests=yes])
-    AC_ARG_ENABLE([installed_tests],
-                  AS_HELP_STRING([--enable-installed-tests],
-                                 [Install test programs (default: no)]),,
-                  [enable_installed_tests=no])
-    AM_CONDITIONAL([BUILD_MODULAR_TESTS],
-                   [test "$enable_modular_tests" = "yes" ||
-                    test "$enable_installed_tests" = "yes"])
-    AM_CONDITIONAL([BUILDOPT_INSTALL_TESTS],[test "$enable_installed_tests" = "yes"])
-
-Then in `tests/Makefile.am`:
-
-    insttestdir = $(libexecdir)/installed-tests/[project]
-
-    all_test_programs = \
-        test-program1 \
-        test-program2 \
-        test-program3 \
-        $(NULL)
-    if BUILD_MODULAR_TESTS
-    TESTS = $(all_test_programs)
-    noinst_PROGRAMS = $(TESTS)
-    endif
-
-    if BUILDOPT_INSTALL_TESTS
-    insttest_PROGRAMS = $(all_test_programs)
-
-    testmetadir = $(datadir)/installed-tests/[project]
-    testmeta_DATA = $(all_test_programs:=.test)
-
-    testdatadir = $(insttestdir)
-    testdata_DATA = $(test_files)
-
-    testdata_SCRIPTS = $(test_script_files)
-    endif
-
-    EXTRA_DIST = $(test_files)
-
-    %.test: % Makefile
-        $(AM_V_GEN) (echo '[Test]' > $@.tmp; \
-        echo 'Type=session' >> $@.tmp; \
-        echo 'Exec=$(insttestdir)/$<' >> $@.tmp; \
-        mv $@.tmp $@)
-
-## Leak checking
-
-Once unit tests with high code coverage have been written, they can be
-run under various dynamic analysis tools, such as
-[Valgrind]( {{< ref "/guidelines/tooling.md#valgrind" >}} ) to check for leaks,
-threading errors, allocation problems, etc. across the entire code base.
-The higher the code coverage of the unit tests, the more confidence the
-Valgrind results can be treated with. See the
-[Tooling]( {{< ref "/guidelines/tooling.md" >}} ) page for more information,
-including build system integration instructions.
-
-Critically, this means that unit tests should not leak memory or other
-resources themselves, and similarly should not have any threading
-problems. Any such problems would effectively be false positives in the
-analysis of the actual project code. (False positives which need to be
-fixed by fixing the unit tests.)
-
-## Test generation
-
-Certain types of code are quite repetitive, and require a lot of unit
-tests to gain good coverage; but are appropriate for [test data
-generation](http://en.wikipedia.org/wiki/Test_data_generation), where a
-tool is used to automatically generate test vectors for the code. This
-can drastically reduce the time needed for writing unit tests, for code
-in these specific domains.
-
-### JSON
-
-One example of a domain amenable to test data generation is parsing,
-where the data to be parsed is required to follow a strict schema — this
-is the case for XML and JSON documents. For JSON, a tool such as
-[Walbottle](http://people.collabora.com/~pwith/walbottle/) can be used
-to generate test vectors for all types of valid and invalid input
-according to the schema.
-
-Every type of JSON document should have a [JSON
-Schema](http://json-schema.org/) defined for it, which can then be
-passed to Walbottle to generate test vectors:
-
-    json-schema-generate --valid-only schema.json
-    json-schema-generate --invalid-only schema.json
-
-These test vectors can then be passed to the code under test in its unit
-tests. The JSON instances generated by `--valid-only` should be
-accepted; those from `--invalid-only` should be rejected.
-
-## Writing testable code
-
-Code should be written with testability in mind from the design stage,
-as it affects API design and architecture in fundamental ways. A few key
-principles:
-
-  - Do not use global state. Singleton objects are usually a bad idea as
-    they can’t be instantiated separately or controlled in the unit
-    tests.
-  - Separate out use of external state, such as databases, networking,
-    or the file system. The unit tests can then replace the accesses to
-    external state with mocked objects. A common approach to this is to
-    use dependency injection to pass a file system wrapper object to the
-    code under test. For example, a class should not load a global
-    database (from a fixed location in the file system) because the unit
-    tests would then potentially overwrite the running system’s copy of
-    the database, and could never be executed in parallel. They should
-    be passed an object which provides an interface to the database: in
-    a production system, this would be a thin wrapper around the
-    database API; for testing, it would be a mock object which checks
-    the requests given to it and returns hard-coded responses for
-    various tests.
-  - Expose utility functions where they might be generally useful.
-  - Split projects up into collections of small, private libraries which
-    are then linked together with a minimal amount of glue code into the
-    overall executable. Each can be tested separately.
-
-The topic of software testability is covered in the following articles:
-
-  - [Design for
-    testability](http://msdn.microsoft.com/en-us/magazine/dd263069.aspx)
-  - [Software
-    testability](http://en.wikipedia.org/wiki/Software_testability)
-  - [Dependency
-    injection](http://en.wikipedia.org/wiki/Dependency_injection)
-  - [Software design for
-    testing](http://c2.com/cgi/wiki?SoftwareDesignForTesting)
-
-## External links
-
-  - [GLib test
-    framework](https://developer.gnome.org/glib/stable/glib-Testing.html)
-  - [Walbottle](http://people.collabora.com/~pwith/walbottle/)
-  - [installed-tests
-    documentation](https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests)
diff --git a/content/guides/api_design.md b/content/guides/api_design.md
index 505f303a54cd7af8accafdf72e864d4d2f00ca16..5c1abc65fa087af5d6c9f560738f7dac2c6988db 100644
--- a/content/guides/api_design.md
+++ b/content/guides/api_design.md
@@ -105,7 +105,7 @@ requirements allow it, we should do the same.
 Not all of the code in Apertis is equally-privileged: components that
 run as root are more privileged than components that run as the user,
 and components with a permissive
-[AppArmor]( {{< ref "/guidelines/apparmor.md" >}} ) profile are more privileged
+[AppArmor]( {{< ref "apparmor.md" >}} ) profile are more privileged
 than components with a restrictive profile.
 
 Whenever two components with different privilege levels communicate, we
diff --git a/content/guides/api_documentation.md b/content/guides/api_documentation.md
new file mode 100644
index 0000000000000000000000000000000000000000..48c61bcf40902fd56aad894a117525beb4ff8878
--- /dev/null
+++ b/content/guides/api_documentation.md
@@ -0,0 +1,283 @@
++++
+date = "2015-03-03"
+weight = 100
+
+title = "API Documentation"
+
+aliases = [
+    "/old-wiki/Guidelines/API_documentation"
+]
++++
+
+# Summary
+
+- Use gtk-doc with up-to-date settings for API documentation.
+  ([gtk-doc](#gtk-doc))
+- Use XML entities for including external symbols into the documentation.
+  ([Build system](#build-system))
+- Use a consistent, standard, table of contents for all API documentation to
+  maintain familiarity. ([Standard layout](#standard-layout))
+- Use `gdbus-codegen` to generate D-Bus API documentation to include in the
+  gtk-doc build. ([D-Bus APIs](#d-bus-apis))
+- Add introspection annotations to all API documentation.
+  ([Introspection annotations](#introspection-annotations))
+- Add `Since` lines to all API documentation.
+  ([Symbol versioning](#symbol-versioning))
+- Enable gtk-doc tests.
+  ([Keeping documentation up to date](#keeping-documentation-up-to-date))
+
+# gtk-doc
+
+API documentation should be generated by gtk-doc, which collects specially
+formatted documentation comments from C and header files, and reformats them to
+generate [DocBook](http://www.docbook.org/) and HTML output. The DocBook output
+can be used by [Devhelp](https://wiki.gnome.org/Apps/Devhelp).
+
+Using gtk-doc requires two things:
+
+- The gtk-doc build system code to be integrated, which is a one-time
+  operation.
+- Documentation comments to be added to all public APIs, and kept up to date.
+
+# Build system
+
+To integrate gtk-doc into a project’s build system, follow the
+[instructions in the gtk-doc manual](https://developer.gnome.org/gtk-doc-manual/stable/settingup.html.en).
+Note that while the `sections.txt` file is automatically generated the first
+time gtk-doc is run, it is not generated subsequently, and should be kept up to
+date manually. It should also be
+[in version control](https://developer.gnome.org/gtk-doc-manual/stable/settingup_vcs.html.en).
+
+gtk-doc’s `no-tmpl` flavour should be used, and XML mode should be used instead
+of SGML. (tmpl mode and SGML are both outdated and slower than XML.)
+
+If the package version is needed to be substituted into the documentation,
+create a file named `docs/version.xml.in`, containing:
+
+```
+@PACKAGE_VERSION@
+```
+
+Add it to `AC_CONFIG_FILES` in `configure.ac`, then include it into the main
+documentation file (`*-docs.xml`) using:
+
+```
+<!ENTITY version SYSTEM "version.xml">
+```
+
+in the `DOCTYPE` at the top of the document. The package version can then be
+used inline as `&version;`.
+
+# Standard layout
+
+Using a standard layout for the table of contents, sections, appendices, etc.
+means the same `*-docs.xml` template can be reused with few changes between
+projects. It also means the documentation layout is similar across all
+projects, making it more familiar to developers.
+
+The following layout is suggested:
+
+```
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+    <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+    <!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index">
+    <bookinfo>
+        <title>[project] Reference Manual</title>
+        <releaseinfo>
+            For [project] &version;. The latest version of this documentation can be found on-line at
+            <ulink role="online-location" url="http://[server]/[project]/index.html">http://[server]/[project]/</ulink>.
+        </releaseinfo>
+    </bookinfo>
+
+    <part>
+        <title>[project] Overview</title>
+
+        <xi:include href="xml/SomeObject.xml"/>
+        <xi:include href="xml/OtherObject.xml"/>
+        <xi:include href="xml/Utilities.xml"/>
+
+        <chapter>
+            <title>Object Hierarchy</title>
+            <xi:include href="xml/tree_index.sgml"/>
+        </chapter>
+    </part>
+
+    <part>
+        <title>D-Bus Interfaces</title>
+
+        <chapter>
+            <title>D-Bus Interfaces</title>
+
+            <partintro>
+                <para>D-Bus interface definitions for the project.</para>
+            </partintro>
+
+            <xi:include href="xml/docs-Some.Interface.xml"/>
+            <xi:include href="xml/docs-Other.Interface.xml"/>
+        </chapter>
+
+        <chapter>
+            <title>C Interfaces</title>
+
+            <partintro>
+                <para>C wrappers for the project D-Bus interfaces.</para>
+            </partintro>
+
+            <xi:include href="xml/SomeInterface.xml"/>
+            <xi:include href="xml/OtherInterface.xml"/>
+        </chapter>
+    </part>
+
+    <part>
+        <title>Appendices</title>
+        <index id="api-index-full">
+            <title>API Index</title>
+            <xi:include href="xml/api-index-full.xml"><xi:fallback/></xi:include>
+        </index>
+        <index id="api-index-deprecated">
+            <title>Index of deprecated symbols</title>
+            <xi:include href="xml/api-index-deprecated.xml"><xi:fallback/></xi:include>
+        </index>
+        <index role="1.0.0">
+            <title>Index of new symbols in 1.0.0</title>
+            <xi:include href="xml/api-index-1.0.0.xml"><xi:fallback/></xi:include>
+        </index>
+        <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+    </part>
+
+    <xi:include href="xml/license.xml"/>
+</book>
+```
+
+# D-Bus APIs
+
+D-Bus interface descriptions contain documentation comments, and these can be
+extracted from the XML using `gdbus-codegen`, and turned into DocBook files to
+be included by gtk-doc. Generate the documentation using the rules described in
+the [D-Bus services guidelines]( {{< ref "d-bus_services.md" >}} ).
+
+The DocBook files can be included in the main `*-docs.xml` file using:
+
+```
+<chapter>
+    <title>C Interfaces</title>
+    <partintro>
+        <para>C wrappers for the D-Bus interfaces.</para>
+    </partintro>
+
+    <xi:include href="xml/SomeDBusService.xml"/>
+    <xi:include href="xml/SomeOtherService.xml"/>
+</chapter>
+```
+
+The generated XML files must be included in the `content_files` variable in
+`docs/reference/Makefile.am`, otherwise the build will fail. (This is to fix
+situations where the `builddir` does not equal the `srcdir`.)
+
+# Introspection annotations
+
+Each gtk-doc comment should have appropriate
+[GObject introspection annotations](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations).
+These are useful for two reasons:
+
+1. They add important information about parameter types, nullability and memory
+management to the C API documentation generated by gtk-doc.  2. They allow
+public APIs to be automatically bound in other languages, such as Python.
+
+Introspection annotations add information to APIs (functions, function
+parameters, function return values, structures, GObject properties, GObject
+signals) which is otherwise not present in the machine readable C API and only
+exists in the form of human readable documentation or convention. They are very
+important.
+
+In gtk-doc comments, annotations should be preferred over human-readable
+equivalents. For example, when documenting a function parameter which may be
+`NULL`, use the `(nullable)` annotation rather than some text:
+
+```
+/**
+ * my_function:
+ * @parameter: (nullable): some parameter which affects something
+ *
+ * Body of the function documentation.
+ */
+```
+
+Instead of:
+
+```
+/**
+ * my_bad_function:
+ * @parameter: some parameter which affects something, or %NULL to ignore
+ *
+ * Bad body of the function documentation.
+ */
+```
+
+For more information on introspection, see the
+[introspection guidelines]( {{< ref "introspection.md" >}} ).
+
+# Symbol versioning
+
+Whenever a symbol is added to the public API, it should have a documentation
+comment added. This comment should always contain a `Since` line with the
+package version number of the release which will first contain the new API.
+This should be the number currently in `configure.ac` if
+[post-release version incrementing]( {{< ref "howtoreleasepackages.md#release-process" >}} )
+is being used.
+
+e.g.
+
+```
+/**
+ * my_function:
+ * @param: some parameter
+ *
+ * Body of the function documentation.
+ *
+ * Since: 0.5.0
+ */
+```
+
+gtk-doc uses this information to generate indexes of the APIs added in each
+release. These should be added to the main `*-docs.xml` as an appendix:
+
+```
+<part>
+    <title>Appendices</title>
+    <index id="api-index-full">
+        <title>API Index</title>
+        <xi:include href="xml/api-index-full.xml"><xi:fallback/></xi:include>
+    </index>
+    <index id="api-index-deprecated">
+        <title>Index of deprecated symbols</title>
+        <xi:include href="xml/api-index-deprecated.xml"><xi:fallback/></xi:include>
+    </index>
+    <index role="0.1.0">
+        <title>Index of new symbols in 0.1.0</title>
+        <xi:include href="xml/api-index-0.1.0.xml"><xi:fallback/></xi:include>
+    </index>
+    <!-- More versions here. -->
+    <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</part>
+```
+
+# Keeping documentation up to date
+
+gtk-doc comes with support for checking the documentation with some basic
+tests. These check that all version indexes are included in the main
+`*-docs.xml` file and that all symbols are documented, amongst other things.
+
+These tests should always be enabled, by adding the following to
+`docs/Makefile.am`:
+
+```
+TESTS = $(GTKDOC_CHECK)
+```
+
+They will then be run as part of `make check`.
diff --git a/content/guides/apparmor.md b/content/guides/apparmor.md
new file mode 100644
index 0000000000000000000000000000000000000000..80f399c3e256cbddf947b8d17a25fde387af8f6d
--- /dev/null
+++ b/content/guides/apparmor.md
@@ -0,0 +1,67 @@
++++
+date = "2015-09-08"
+weight = 100
+
+title = "AppArmor"
+
+aliases = [
+    "/old-wiki/Guidelines/AppArmor"
+]
++++
+
+AppArmor is a security layer which enforces access control on the filesystem
+resources applications can access, and the permissions they can access them
+with. It comprises a kernel module and user space profiles for each
+application, which define the resources an application expects to access. For
+more information, see the
+[AppArmor home page](http://wiki.apparmor.net/index.php/Main_Page). Apertis
+uses AppArmor for all applications and services.
+
+# Summary
+
+- Write AppArmor profiles to be as constrained as possible.
+  ([Profiles](#profiles))
+- Validate the profiles manually before release, and during testing.
+  ([Validation](#validation))
+
+# Profiles
+
+For application development, the only work which needs to be done for AppArmor
+integration is to write and install a profile for the application. See the
+[AppArmor website](http://wiki.apparmor.net/index.php/Profiles) for information
+on writing profiles. Profiles should be as constrained as possible, following
+the
+[principle of least privilege](http://en.wikipedia.org/wiki/Principle_of_least_privilege).
+
+To install a profile, use the following `Makefile.am` snippet:
+
+    aaprofiledir = $(sysconfdir)/apparmor.d
+    aaprofile_DATA = usr.bin.application-name
+    EXTRA_DIST = $(aaprofile_DATA)
+
+# Validation
+
+AppArmor profiles can be validated in two ways: manually, and at runtime.
+Manual verification should be performed before each release, manually
+inspecting the profile against the list of changes made to the application
+since the last release, and checking that each entry is still relevant and
+correct, and that no new entries are needed.
+
+Runtime verification is automatic: AppArmor will deny access to files which
+violate the profile, emitting a message in the audit logs (`audit.log`), for
+example:
+
+    Feb 23 18:54:07 my-host kernel: [   24.610703] type=1400 audit(1393181647.872:15): apparmor="DENIED" operation="open" parent=1 profile="/usr/sbin/ntpd" name="/etc/ldap/ldap.conf" pid=1526 comm="ntpd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
+
+Such messages should be investigated, and may result in changes to the
+application (to prevent it making such accesses) or to the profile (to allow
+them).
+
+Manual and runtime verification are complementary: manual verification ensures
+the profile is as small as possible; runtime verification ensures the profile
+is as big as it needs to be.
+
+# External links
+
+- [AppArmor home page](http://wiki.apparmor.net/index.php/Main_Page)
+- [AppArmor profile wiki page](http://wiki.apparmor.net/index.php/Profiles)
diff --git a/content/guides/d-bus_services.md b/content/guides/d-bus_services.md
index 9f3d32f12af59114bd710f1764ef947ad3f0a292..1c610bba1c369756b0ca123c4cf05691a788288b 100644
--- a/content/guides/d-bus_services.md
+++ b/content/guides/d-bus_services.md
@@ -236,7 +236,7 @@ The standard interface rules in
 [Code generation]( {{< ref "d-bus_services.md#code-generation" >}} ) also
 generate a DocBook documentation file for each D-Bus API. Include these DocBook
 files in the API documentation using the approach described in the
-[API documentation guidelines]( {{< ref "/guidelines/api_documentation.md#d-bus-apis" >}} ).
+[API documentation guide]( {{< ref "api_documentation.md#d-bus-apis" >}} ).
 
 ## Service implementation
 
diff --git a/content/guides/filesystem_access.md b/content/guides/filesystem_access.md
new file mode 100644
index 0000000000000000000000000000000000000000..212e9220053d650a2e8733176308ab769df7eea9
--- /dev/null
+++ b/content/guides/filesystem_access.md
@@ -0,0 +1,100 @@
++++
+date = "2015-01-14"
+weight = 100
+
+title = "Filesystem Access"
+
+aliases = [
+    "/old-wiki/Guidelines/Filesystem_access"
+]
++++
+
+There are a few anti-patterns to consider when accessing the filesystem.  This
+article assumes knowledge of the standard
+[`GFile`](https://developer.gnome.org/gio/stable/GFile.html),
+[`GInputStream`](https://developer.gnome.org/gio/stable/GInputStream.html) and
+[`GOutputStream`](https://developer.gnome.org/gio/stable/GOutputStream.html)
+APIs.
+
+# Summary
+
+- Always use asynchronous I/O for file access.
+  ([Asynchronous I/O](#asynchronous-i/o))
+- Always use appropriate functions to construct file names and paths.
+  ([File path construction](#file-path-construction))
+- Validate file paths are in the expected directories before using them.
+  ([Path validation and sandboxing](#path-validation-and-sandboxing))
+- Use AppArmor profiles to enforce constraints on file access.
+  ([Path validation and sandboxing](#path-validation-and-sandboxing))
+
+# Asynchronous I/O
+
+All I/O should be performed asynchronously. That is, without blocking the
+[GLib main context](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html).
+This can be achieved by always using the `*_async()` and `*_finish()` variants
+of each I/O function. For example,
+[`g_input_stream_read_async()`](https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async)
+rather than
+[`g_input_stream_read()`](https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read).
+
+Synchronous I/O blocks the main loop, which means that other events, such as
+user input, incoming networking packets, timeouts and idle callbacks, are not
+handled until the blocking function returns.
+
+Note that the alternative – running synchronous I/O in a separate thread – is
+highly discouraged; see the
+[threading guidelines]( {{< relref "threading.md#when-to-use-threading" >}} )
+for more information.
+
+# File path construction
+
+File names and paths are not normal strings: on some systems, they can use a
+character encoding other than UTF-8, while normal strings in GLib are
+guaranteed to always use UTF-8. For this reason, special functions should be
+used to build and handle file names and paths. (Modern Linux systems almost
+universally use UTF-8 for filename encoding, so this is not an issue in
+practice, but the file path functions should still be used.)
+
+For example, file paths should be built using
+[`g_build_filename()`](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-build-filename)
+rather than
+[`g_strconcat()`](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strconcat).
+Doing so makes it clearer what the code is meant to do, and also eliminates
+duplicate directory separators, so the returned path is canonical (though not
+necessarily absolute).
+
+As another example, paths should be disassembled using
+[`g_path_get_basename()`](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-basename)
+and
+[`g_path_get_dirname()`](https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-dirname)
+rather than
+[`g_strrstr()`](https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strrstr)
+and other manual searching functions.
+
+# Path validation and sandboxing
+
+If a filename or path comes from external input, such as a web page or user
+input, it should be validated to ensure that putting it into a file path will
+not produce an arbitrary path. For example if a filename is constructed from
+the constant string `~/` plus some user input, if the user inputs
+`../../etc/passwd`, they can (potentially) gain access to sensitive account
+information, depending on which user the program is running as, and what it
+does with data loaded from the constructed path.
+
+This can be avoided by validating constructed paths before using them, using
+[`g_file_resolve_relative_path()`](https://developer.gnome.org/gio/stable/GFile.html#g-file-resolve-relative-path)
+to convert any relative paths to absolute ones, and then validating that the
+path is beneath a given root sandboxing directory appropriate for the
+operation. For example, if code downloads a file, it could validate that all
+paths are beneath `~/Downloads`, using
+[`g_file_has_parent()`](https://developer.gnome.org/gio/stable/GFile.html#g-file-has-parent).
+
+As a second line of defence, all projects which access the filesystem should
+provide an AppArmor profile which limits the directories they can read from and
+write to. See the
+[AppArmor guidelines]( {{< ref "apparmor.md" >}} )
+for more information.
+
+# External links
+
+- [GFile documentation](https://developer.gnome.org/gio/stable/GFile.html)
diff --git a/content/guides/introspection.md b/content/guides/introspection.md
new file mode 100644
index 0000000000000000000000000000000000000000..626a37854a1b46d91779edc5010850da79f584f5
--- /dev/null
+++ b/content/guides/introspection.md
@@ -0,0 +1,100 @@
++++
+date = "2015-01-15"
+weight = 100
+
+title = "Introspection"
+
+aliases = [
+    "/old-wiki/Guidelines/Introspection"
+]
++++
+
+[GObject introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
+(abbreviated ‘GIR’) is a system which extracts APIs from C code and produces
+binary type libraries which can be used by non-C language bindings, and other
+tools, to [introspect](http://en.wikipedia.org/wiki/Type_introspection) or
+[wrap](http://en.wikipedia.org/wiki/Language_binding) the original C libraries.
+It uses a system of annotations in documentation comments in the C code to
+expose extra information about the APIs which is not machine readable from the
+code itself.
+
+It should be enabled for all public APIs: so all libraries. It cannot be
+enabled for programs, since they expose no APIs. However, it is still
+recommended to
+[add introspection annotations to documentation comments]( {{< ref "api_documentation.md#introspection-annotations" >}} )
+in program code, as they clarify the documentation.
+
+# Summary
+
+- Enable introspection for all libraries.
+  ([Using introspection](#using-introspection))
+- Pay attention to warnings from `g-ir-scanner` and `introspectable="0"`
+  attributes in GIR files. ([Using introspection](#using-introspection))
+- Add introspection annotations to all documentation comments.
+  ([Using introspection](#using-introspection))
+- Design APIs to be introspectable from the start. ([API design](#api-design))
+
+# Using introspection
+
+The first step for using introspection is to add it to the build system,
+following the instructions
+[here](https://wiki.gnome.org/Projects/GObjectIntrospection/AutotoolsIntegration#Method_1_-_Recommended_-_most_portable),
+following method 1. This should be done early in the life of a project, as
+introspectability affects [API design](#api-design).
+
+This should result in a `.gir` and `.typelib` file being generated for the
+project. The `.gir` file is human readable, and can be inspected manually to
+see if the API has been introspected correctly (although the GIR compilation
+process will print error messages and warnings for any missing annotations or
+other problems). APIs with `introspectable="0"` will not be exposed to language
+bindings as they are missing annotations or are otherwise not representable in
+the GIR file.
+
+The next step is to
+[add annotations to the documentation comments for every piece of public API]( {{< ref "api_documentation.md#introspection-annotations" >}} ).
+If a particular piece of API should not be exposed in the GIR file, use the
+`(skip)` annotation. Documentation on the available annotations is
+[here](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations).
+
+Annotations do not have to be added exhaustively: GIR has a set of default
+annotations which it applies based on various conventions (see [API
+design](#api-design)). For example, a `const gchar*` parameter does not need an
+explicit `(transfer none)` annotation, because the `const` modifier implies
+this already. Learning the defaults for annotations is a matter of practice.
+
+# API design
+
+In order to be introspectable without too many annotations, APIs must follow
+certain conventions, such as the
+[standard GObject naming conventions](https://developer.gnome.org/gobject/stable/gtype-conventions.html),
+and the
+[conventions for bindable APIs](https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs).
+This is necessary because of the flexibility of C: code can be written to
+behave in any way imaginable, but higher level languages don’t allow this kind
+of freedom. So in order for a C API to be representable in a higher level
+language, it has to conform to the behaviours supported by that language.
+
+For example, GIR expects that if a function can fail, it will have a `GError**`
+parameter, which will always be its final parameter. The GIR scanner detects
+this and automatically converts that parameter to an exception attribute on the
+method in the GIR file. It cannot do this if the `GError*` is returned
+directly, or is not the final function parameter, for example.
+
+Therefore, APIs must be designed to be introspectable, and the GIR file should
+be checked as the APIs are being written. If the GIR doesn’t match what you
+expect for a new API, the API may need extra annotations, or even for its C
+declaration to be changed (as in the case of
+[`va_list`](https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs#va_list)).
+
+`g-ir-scanner` emits warnings when it encounters code it does not understand.
+By passing `--warn-error` as well as `--warn-all` in
+`INTROSPECTION_SCANNER_ARGS` in `Makefile.am`, compilation will fail when
+unintrospectable APIs are encountered. This will ensure all new APIs are
+introspectable, and is highly recommended.
+
+# External links
+
+- [GObject introspection home page](https://wiki.gnome.org/Projects/GObjectIntrospection)
+- [GIR annotation reference](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations)
+- [GObject naming conventions](https://developer.gnome.org/gobject/stable/gtype-conventions.html)
+- [Guide to writing bindable APIs](https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs)
diff --git a/content/guides/json_parsing.md b/content/guides/json_parsing.md
index a388049f4df411c3f23f452b4ad3648fcdfd4aeb..135e146c413e0043d473bd46f011eef35e0a2596 100644
--- a/content/guides/json_parsing.md
+++ b/content/guides/json_parsing.md
@@ -130,14 +130,14 @@ compile time:
 Due to the susceptibility of JSON handling code to break on invalid input (as
 it assumes the input follows the correct schema, which it may not, as it’s
 untrusted), it is important to unit test such code. See the [Unit testing
-guidelines]( {{< ref "/guidelines/unit_testing.md" >}} ) for suggestions on
+guidelines]( {{< ref "unit_testing.md" >}} ) for suggestions on
 writing code for testing. The ideal is for the JSON parsing code to be
 separated from whatever code calls it, so that it can be linked into unit tests
 by itself, and passed JSON snippets to check what it retrieves from them.
 
 Thinking of JSON snippets which thoroughly test parsing and validation code is
 hard, and is impossible to do without also using code coverage metrics (see the
-[Tooling guidelines]( {{< ref "/guidelines/tooling.md#code-coverage" >}} )).
+[Tooling guidelines]( {{< ref "tooling.md#code-coverage" >}} )).
 However, given a JSON schema for the document, it is possible to automatically
 and exhaustively generate [unit test
 vectors](http://en.wikipedia.org/wiki/Test_vector) which can be easily copied
diff --git a/content/guides/memory_management.md b/content/guides/memory_management.md
new file mode 100644
index 0000000000000000000000000000000000000000..0f11a82c52e18782d993c45f157e7ff7e50800a4
--- /dev/null
+++ b/content/guides/memory_management.md
@@ -0,0 +1,443 @@
++++
+date = "2015-09-08"
+weight = 100
+
+title = "Memory Management"
+
+aliases = [
+    "/old-wiki/Guidelines/Memory_management"
+]
++++
+
+Apertis is predominantly written in C, so dynamically allocated memory has to
+be managed manually. Through use of GLib convenience APIs, memory management
+can be trivial, but programmers always need to keep memory in mind when writing
+code.
+
+It is assumed that users of Apertis are familiar with the idea of heap
+allocation of memory using `malloc()` and `free()`, and know of the GLib
+equivalents, `g_malloc()` and `g_free()`.
+
+# Summary
+
+There are three situations to avoid, in order of descending importance:
+
+1. Using memory after freeing it (use-after-free).
+2. Using memory before allocating it.
+3. Not freeing memory after allocating it (leaking).
+
+Key principles, in no particular order:
+
+- Determine and document whether each variable is owned or unowned.
+  They must never change from one to the other at runtime.
+  ([Principles of memory management](#principles-of-memory-management))
+- Determine and document the ownership transfers at function
+  boundaries.
+  ([Principles of memory management](#principles-of-memory-management))
+- Ensure that each assignment, function call and function return
+  respects the relevant ownership transfers.
+  ([Assignments](#assignments), [Function calls](#function-calls),
+  [Function returns](#function-returns))
+- Use reference counting rather than explicit finalisation where
+  possible. ([Reference counting](#reference-counting))
+- Use GLib convenience functions like
+  [`g_clear_object()`](#g_clear_object) where
+  possible. ([Convenience functions](#convenience-functions))
+- Do not split memory management across code paths.
+  ([Principles of memory management](#principles-of-memory-management))
+- Use the single-path cleanup pattern for large or complex functions.
+  ([Single-path cleanup](#single-path-cleanup))
+- Leaks should be checked for using Valgrind.
+  ([Verification](#verification))
+
+# Principles of memory management
+
+The normal approach to memory management is for the programmer to keep track of
+which variables point to allocated memory, and to manually free them when they
+are no longer needed. This is correct, but can be clarified by introducing the
+concept of *ownership*, which is the piece of code (such as a function, struct
+or object) which is responsible for freeing a piece of allocated memory (an
+*allocation*). Each allocation has exactly one owner; this owner may change as
+the program runs, by *transferring* ownership to another piece of code. Each
+variable is *owned* or *unowned*, according to whether the scope containing it
+is always its owner. Each function parameter and return type either transfers
+ownership of the values passed to it, or it doesn’t. By statically calculating
+which variables are owned, memory management becomes a simple task of
+unconditionally freeing the owned variables before they leave their scope, and
+*not* freeing the unowned variables (see [Single-path
+cleanup](#single-path-cleanup)).
+
+There is an important restriction here: variables must **never** change from
+owned to unowned (or vice-versa) at runtime. This restriction is key to
+simplifying memory management.
+
+For example, given the functions:
+
+    gchar *generate_string (const gchar *template);
+    void print_string (const gchar *str);
+
+the following code has been annotated to note where the ownership transfers
+happen:
+
+    gchar *my_str = NULL;  /* owned */
+    const gchar *template;  /* unowned */
+    GValue value = G_VALUE_INIT;  /* owned */
+    g_value_init (&value, G_TYPE_STRING);
+
+    /* Transfers ownership of a string from the function to the variable. */
+    template = "XXXXXX";
+    my_str = generate_string (template);
+
+    /* No ownership transfer. */
+    print_string (my_str);
+
+    /* Transfer ownership. We no longer have to free @my_str. */
+    g_value_take_string (&value, my_str);
+
+    /* We still have ownership of @value, so free it before it goes out of scope. */
+    g_value_unset (&value);
+
+There are a few points here: Firstly, the ‘owned’ comments by the variable
+declarations denote that those variables are owned by the local scope, and
+hence need to be freed before they go out of scope. The alternative is
+‘unowned’, which means the local scope does *not* have ownership, and *must
+not* free the variables before going out of scope.  Similarly, ownership *must
+not* be transferred to them on assignment.
+
+Secondly, the variable type modifiers reflect the ownership status of each
+variable: because `my_str` is owned by the local scope, it has type `gchar`,
+whereas `template` is `const` to denote it is unowned.  Similarly, the
+`template` parameter of `generate_string()` and the `str` parameter of
+`print_string()` are `const` because no ownership is transferred when those
+functions are called. As ownership *is* transferred for the string parameter of
+`g_value_take_string()`, we can expect its type to be `gchar`.
+
+(Note that this is not the case for `GObject`s and subclasses, which can never
+be `const`. It is only the case for strings and simple `struct`s.)
+
+Given this ownership and transfer infrastructure, the correct approach to
+memory allocation can be mechanically determined for each situation.  In each
+case, the `copy()` function must be appropriate to the data type, e.g.
+`g_strdup()` for strings, or `g_object_ref()` for GObjects.
+
+## Assignments
+
+| Assigning from/to | Owned destination                                                                                                          | Unowned destination                                                                                                  |
+| ----------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
+| Owned source      | Copy or move the source to the destination. `owned_dest = copy (owned_src)` or `owned_dest = owned_src; owned_src = NULL`. | Pure assignment, assuming the unowned variable is not used after the owned one is freed. `unowned_dest = owned_src`. |
+| Unowned source    | Copy the source to the destination. `owned_dest = copy (unowned_src)`.                                                     | Pure assignment. `unowned_dest = unowned_src`.                                                                       |
+
+## Function calls
+
+| Call from/to   | Transfer full parameter                                                                                                         | Transfer none parameter                                |
+| -------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
+| Owned source   | Copy or move the source for the parameter, `function_call (copy (owned_src))` or `function_call (owned_src); owned_src = NULL`. | Pure parameter passing. `function_call (owned_src)`.   |
+| Unowned source | Copy the source for the parameter. `function_call (copy (unowned_src))`.                                                        | Pure parameter passing. `function_call (unowned_src)`. |
+
+## Function returns
+
+| Return from/to | Transfer full return                                         | Transfer none return                                                                                        |
+| -------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
+| Owned source   | Pure variable return. `return owned_src`.                    | Invalid. The source needs to be freed, so the return value would use freed memory — a use-after-free error. |
+| Unowned source | Copy the source for the return. `return copy (unowned_src)`. | Pure variable passing. `return unowned_src`.                                                                |
+
+# Documentation
+
+Documenting the ownership transfer for each function parameter and return, and
+the ownership for each variable, is important. While they may be clear when
+writing the code, they are not clear a few months later; and may never be clear
+to users of an API. They should always be documented.
+
+The best way to document ownership transfer is to use the
+[`(transfer)`](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Memory_and_lifecycle_management)
+annotation introduced by
+[gobject-introspection](https://wiki.gnome.org/Projects/GObjectIntrospection).
+Include this in the API documentation comment for each function parameter and
+return type. If a function is not public API, write a documentation comment for
+it anyway and include the `(transfer)` annotations. By doing so, the
+gobject-introspection tools can also read the annotations and use them to
+correctly introspect the API.
+
+Further
+[documentation on introspection is available]( {{< ref "introspection.md" >}} ).
+
+For example:
+
+    /**
+     * g_value_take_string:
+     * @value: (transfer none): an initialised #GValue
+     * @str: (transfer full): string to set it to
+     *
+     * Function documentation goes here.
+     */
+
+    /**
+     * generate_string:
+     * @template: (transfer none): a template to follow when generating the string
+     *
+     * Function documentation goes here.
+     *
+     * Returns: (transfer full): a newly generated string
+     */
+
+Ownership for variables can be documented using inline comments. These are
+non-standard, and not read by any tools, but can form a convention if used
+consistently.
+
+    GObject *some_owned_object = NULL;  /* owned */
+    GObject *some_unowned_object;  /* unowned */
+
+The documentation for [Container types](#container-types) is similarly only a
+convention; it includes the type of the contained elements too:
+
+    GPtrArray/*<owned gchar*>*/ *some_unowned_string_array;  /* unowned */
+    GPtrArray/*<owned gchar*>*/ *some_owned_string_array = NULL;  /* owned */
+    GPtrArray/*<unowned GObject*>*/ *some_owned_object_array = NULL;  /* owned */
+
+Note also that owned variables should always be initialised so that freeing
+them is more convenient. See
+[Convenience functions](#convenience-functions).
+
+Also note that some types, e.g. basic C types like strings, can have the
+`const` modifier added if they are unowned, to take advantage of compiler
+warnings resulting from assigning those variables to owned variables (which
+must *not* use the `const` modifier). If so, the `/* unowned */` comment may be
+omitted.
+
+# Reference counting
+
+As well as conventional `malloc()`/`free()`-style types, GLib has various
+reference counted types —
+[`GObject`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html)
+being a prime example.
+
+The concepts of ownership and transfer apply just as well to reference counted
+types as they do to allocated types. A scope *owns* a reference counted type if
+it holds a strong reference to the instance (e.g. by calling
+[`g_object_ref()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref)).
+An instance can be ‘copied’ by calling `g_object_ref()` again. Ownership can be
+freed with
+[`g_object_unref()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref)
+— even though this may not actually finalise the instance, it frees the current
+scope’s ownership of that instance.
+
+See [`g_clear_object()`](#g_clear_object) for a convenient way of handling
+GObject references.
+
+There are other reference counted types in GLib, such as
+[`GHashTable`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html)
+(using
+[`g_hash_table_ref()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-ref)
+and
+[`g_hash_table_unref()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-unref)),
+or
+[`GVariant`](https://developer.gnome.org/glib/stable/glib-GVariant.html)
+([`g_variant_ref()`](https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-ref),
+[`g_variant_unref()`](https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-unref)).
+Some types, like `GHashTable`, support both reference counting and explicit
+finalisation. Reference counting should always be used in preference, because
+it allows instances to be easily shared between multiple scopes (each holding
+their own reference) without having to allocate multiple copies of the
+instance. This saves memory.
+
+# Convenience functions
+
+GLib provides various convenience functions for memory management, especially
+for GObjects. Three will be covered here, but others exist — check the GLib API
+documentation for more. They typically follow similar naming schemas to these
+three (using ‘_full’ suffixes, or the verb ‘clear’ in the function name).
+
+## `g_clear_object()`
+
+[`g_clear_object()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-clear-object)
+is a version of
+[`g_object_unref()`](https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref)
+which unrefs a GObject and then clears the pointer to it to `NULL`.
+
+This makes it easier to implement code that guarantees a GObject pointer is
+always either `NULL`, or has ownership of a GObject (but which never points to
+a GObject it no longer owns).
+
+By initialising all owned GObject pointers to `NULL`, freeing them at the end
+of the scope is as simple as calling `g_clear_object()` without any checks, as
+discussed in [Single-path cleanup](#single-path-cleanup):
+
+    void
+    my_function (void)
+    {
+      GObject *some_object = NULL;  /* owned */
+
+      if (rand ())
+        {
+          some_object = create_new_object ();
+          /* do something with the object */
+        }
+
+      g_clear_object (&some_object);
+    }
+
+## `g_list_free_full()`
+
+[`g_list_free_full()`](https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free-full)
+frees all the elements in a linked list, *and all their data*. It is much more
+convenient than iterating through the list to free all the elements’ data, then
+calling
+[`g_list_free()`](https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free)
+to free the `GList` elements themselves.
+
+## `g_hash_table_new_full()`
+
+[`g_hash_table_new_full()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new-full)
+is a newer version of
+[`g_hash_table_new()`](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new)
+which allows setting functions to destroy each key and value in the hash table
+when they are removed. These functions are then automatically called for all
+keys and values when the hash table is destroyed, or when an entry is removed
+using `g_hash_table_remove()`.
+
+Essentially, it simplifies memory management of keys and values to the question
+of whether they are present in the hash table. See
+[Container types](#container-types) for a discussion on ownership of elements
+within container types.
+
+A similar function exists for `GPtrArray`:
+[`g_ptr_array_new_with_free_func()`](https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-new-with-free-func).
+
+# Container types
+
+When using container types, such as `GPtrArray` or `GList`, an additional level
+of ownership is introduced: as well as the ownership of the container instance,
+each element in the container is either owned or unowned too. By nesting
+containers, multiple levels of ownership must be tracked. Ownership of owned
+elements belongs to the container; ownership of the container belongs to the
+scope it’s in (which may be another container).
+
+A key principle for simplifying this is to ensure that all elements in a
+container have the same ownership: they are either all owned, or all unowned.
+This happens automatically if the normal
+[Convenience functions](#convenience-functions) are used for types like
+`GPtrArray` and `GHashTable`.
+
+If elements in a container are *owned*, adding them to the container is
+essentially an ownership transfer. For example, for an array of strings, if the
+elements are owned, the definition of `g_ptr_array_add()` is effectively:
+
+    /**
+     * g_ptr_array_add:
+     * @array: a #GPtrArray
+     * @str: (transfer full): string to add
+     */
+    void
+    g_ptr_array_add (GPtrArray *array,
+                     gchar *str);
+
+So, for example, constant (unowned) strings must be added to the array using
+`g_ptr_array_add (array, g_strdup ("constant string"))`.
+
+Whereas if the elements are unowned, the definition is effectively:
+
+    /**
+     * g_ptr_array_add:
+     * @array: a #GPtrArray
+     * @str: (transfer none): string to add
+     */
+    void
+    g_ptr_array_add (GPtrArray *array,
+                     const gchar *str);
+
+and constant strings can be added without copying them: `g_ptr_array_add
+(array, "constant string")`.
+
+See the [Documentation](#documentation) section for examples of comments to add
+to variable definitions to annotate them with the element type and ownership.
+
+# Single-path cleanup
+
+A useful design pattern for more complex functions is to have a single control
+path which cleans up (frees) allocations and returns to the caller. This vastly
+simplifies tracking of allocations, as it’s no longer necessary to mentally
+work out which allocations have been freed on each code path — all code paths
+end at the same point, so perform all the frees then. The benefits of this
+approach rapidly become greater for larger functions with more owned local
+variables; it may not make sense to apply the pattern to smaller functions.
+
+This approach has two requirements:
+
+1. The function returns from a single point, and uses `goto` to reach that
+   point from other paths.
+2. All owned variables are set to `NULL` when initialised or when ownership is
+   transferred away from them.
+
+The example below is for a small function (for brevity), but should illustrate
+the principles for application of the pattern to larger functions:
+
+    GObject *
+    some_function (GError **error)
+    {
+      gchar *some_str = NULL;  /* owned */
+      GObject *temp_object = NULL;  /* owned */
+      const gchar *temp_str;
+      GObject *my_object = NULL;  /* owned */
+      GError *child_error = NULL;  /* owned */
+
+      temp_object = generate_object ();
+      temp_str = "example string";
+
+      if (rand ())
+        {
+          some_str = g_strconcat (temp_str, temp_str, NULL);
+        }
+      else
+        {
+          some_operation_which_might_fail (&child_error);
+
+          if (child_error != NULL)
+            {
+              goto done;
+            }
+
+          my_object = generate_wrapped_object (temp_object);
+        }
+
+    done:
+      /* Here, @some_str is either NULL or a string to be freed, so can be passed to g_free() unconditionally.
+       * Similarly, @temp_object is either NULL or an object to be unreffed, so can be passed to g_clear_object() unconditionally. */
+      g_free (some_str);
+      g_clear_object (&temp_object);
+
+      /* The pattern can also be used to ensure that the function always returns either an error or a return value (but never both). */
+      if (child_error != NULL)
+        {
+          g_propagate_error (error, child_error);
+          g_clear_object (&my_object);
+        }
+
+      return my_object;
+    }
+
+# Verification
+
+Memory leaks can be checked for in two ways: static analysis, and runtime leak
+checking.
+
+Static analysis with tools like [Coverity](https://scan.coverity.com/) or
+[Tartan](http://people.collabora.com/~pwith/tartan/) can catch some leaks, but
+require knowledge of the ownership transfer of every function called in the
+code. Domain-specific static analysers like Tartan (which knows about GLib
+memory allocation and transfer) can perform better here, but Tartan is quite a
+young project and still misses things (a low true positive rate). It is
+recommended that code be put through a static analyser, but the primary tool
+for detecting leaks should be runtime leak checking.
+
+Runtime leak checking is done using [Valgrind](http://valgrind.org/), using its
+[memcheck](http://valgrind.org/docs/manual/mc-manual.html) tool. Any leak it
+detects as ‘definitely losing memory’ should be fixed.  Many of the leaks which
+‘potentially’ lose memory are not real leaks, and should be added to the
+suppression file.
+
+See the [tooling page]( {{< ref "tooling.md#valgrind" >}} ) for
+more information on using Valgrind.
+
+# External links
+
+- [An article on ownership transfer](https://tecnocode.co.uk/2013/09/03/const-gchar-vs-gchar-and-other-memory-management-stories/)
diff --git a/content/guides/processes.md b/content/guides/processes.md
new file mode 100644
index 0000000000000000000000000000000000000000..e8aca470cd2fba827b9cf8cc26be76dc9a42b7e7
--- /dev/null
+++ b/content/guides/processes.md
@@ -0,0 +1,108 @@
++++
+date = "2015-01-14"
+weight = 100
+
+title = "Processes"
+
+aliases = [
+    "/old-wiki/Guidelines/Processes"
+]
++++
+
+There are various things which affect an entire application process.  They are
+not all related, so are covered in separate subsections; some apply to all
+applications, others to specific functionality.
+
+# Summary
+
+- Use libraries instead of subprocesses where possible.
+  ([Subprocesses](#subprocesses))
+- Use closed-loop subprocess management to keep track of when subprocesses
+  exit. ([Subprocesses](#subprocesses))
+- Do *not* use `sigaction()`: use `g_unix_signal_add()` instead.
+  ([UNIX signals](#unix-signals))
+- Do *not* use `sleep()`: use `g_timeout_add_seconds()` instead.
+  ([Sleeping](#sleeping))
+- Do *not* use `system()`: use libraries or single subprocesses instead.
+  ([Shell commands](#shell-commands))
+- Use `GApplication` and `GOptionContext` to do command line parsing.
+  ([Command line parsing](#command-line-parsing))
+
+# Subprocesses
+
+Launching subprocesses is sometimes necessary to perform specific tasks, though
+where possible it is generally better to link against and use an appropriate
+library to perform the same task, as it eliminates a lot of potential failure
+points, simplifies passing data around (as passing data to subprocesses
+involves pipes, and is complex), and generally allows for greater interaction
+between the parent process and the task.
+
+Subprocesses should not be used to implement functionality which could be
+implemented by [D-Bus service daemons]( {{< ref "d-bus_services.md" >}} ).
+
+When using subprocesses, closed-loop management should be used, by monitoring
+the child process’ PID after sending it kill signals, and waiting until the
+child process terminates before proceeding with further processing. The
+alternative, open-loop management, sends signals and never checks to see if the
+child responded to them, which is more fragile.
+
+To do this, use
+[`g_spawn_async()`](https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html)
+to spawn child processes, and
+[`g_child_watch_add()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html)
+to set up a callback to be invoked when the child exits.
+
+# UNIX signals
+
+The standard UNIX function for setting up signal handlers,
+[`sigaction()`](http://man7.org/linux/man-pages/man2/sigaction.2.html), *must
+not* be used in GLib programs, as its callback must be re-entrancy safe, and no
+GLib code is re-entrancy safe. Instead,
+[`g_unix_signal_add()`](https://developer.gnome.org/glib/stable/glib-UNIX-specific-utilities-and-integration.html#g-unix-signal-add)
+should be used, which doesn’t require its callback to be re-entrancy safe.
+
+# Sleeping
+
+The
+[`sleep()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html)
+function *must not* be used in GLib code, as it blocks the current thread.
+Instead,
+[`g_timeout_add_seconds()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add-seconds)
+or
+[`g_timeout_add()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add)
+should be used to schedule a callback to be invoked after a period of time; in
+the mean time, events can continue being processed by the main context.
+
+# Shell commands
+
+The [`system()`](http://linux.die.net/man/3/system) function *must not* be
+used. It is extremely prone to
+[shell injection vulnerabilities](http://en.wikipedia.org/wiki/Code_injection#Shell_injection),
+and any functionality which can be implemented using it can be implemented
+using libraries directly or, if that is not possible, spawning individual
+[subprocesses](#subprocesses).
+
+For example, instead of calling `system (g_strdup_printf ("mv %s %s",
+file_path1, file_path2))`, use
+[`g_file_move()`](https://developer.gnome.org/gio/stable/GFile.html#g-file-move).
+In this situation, using `system()` exposes a shell injection vulnerability,
+and will not work with paths containing spaces in any case.
+
+# Command line parsing
+
+Command line parsing should be implemented using
+[`GApplication`](https://developer.gnome.org/gio/stable/GApplication.html) and
+[`GOptionContext`](https://developer.gnome.org/glib/stable/glib-Commandline-option-parser.html),
+rather than being implemented manually or using another library (such as
+[popt](http://directory.fsf.org/wiki/Popt)).
+
+By using `GOptionContext`, command line parsing follows the standard format
+used by most Linux applications. It gives automatic support for `--help`
+output, and short and long option parsing.
+
+An example of using `GApplication` together with `GOptionContext` is
+[here](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline3.c).
+
+# External links
+
+- [Article on shell injection vulnerabilities](http://en.wikipedia.org/wiki/Code_injection#Shell_injection)
diff --git a/content/guides/threading.md b/content/guides/threading.md
new file mode 100644
index 0000000000000000000000000000000000000000..d5421d3b55d48b5fe706a6c53210a3680ee7c74d
--- /dev/null
+++ b/content/guides/threading.md
@@ -0,0 +1,208 @@
++++
+date = "2015-01-14"
+weight = 100
+
+title = "Threading"
+
+aliases = [
+    "/old-wiki/Guidelines/Threading"
+]
++++
+
+# Summary
+
+- Do not use threads if at all possible.
+  ([When to use threading](#when-to-use-threading))
+- If threads have to be used, use `GTask` or `GThreadPool` and isolate the
+  threaded code as much as possible. ([Using threading](#using-threading))
+- Use `g_thread_join()` to avoid leaking thread resources if using `GThread`
+  manually. ([Using threading](#using-threading))
+- Be careful about the `GMainContext` which code is executed in if using
+  threads. Executing code in the wrong context can cause race conditions, or
+  block the main loop. ([Using threading](#using-threading))
+
+# When to use threading
+
+When writing projects using GLib, the default approach should be to **never use
+threads**. Instead, make proper use of the GLib main context which, through the
+use of asynchronous operations, allows most blocking I/O operations to continue
+in the background while the main context continues to process other events.
+Analysis, review and debugging of threaded code becomes very hard, very
+quickly.
+
+Threading should only be necessary when using an external library which has
+blocking functions which need to be called from GLib code. If the library
+provides a non-blocking alternative, or one which integrates with a
+[`poll()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html)
+loop, that should be used in preference. If the blocking function really must
+be used, a thin wrapper should be written for it to convert it to the normal
+[`GAsyncResult` style](https://developer.gnome.org/gio/stable/GAsyncResult.html)
+ of GLib asynchronous function, running the blocking operation in a worker
+thread.
+
+e.g.
+
+    int some_blocking_function (void *param1, void *param2);
+
+should be wrapped as:
+
+    void some_blocking_function_async (void *param1, void *param2, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+    int some_blocking_function_finish (GAsyncResult *result, GError **error);
+
+With an implementation something like:
+
+    /* Closure for the call’s parameters. */
+    typedef struct {
+      void *param1;
+      void *param2;
+    } SomeBlockingFunctionData;
+
+    static void
+    some_blocking_function_data_free (SomeBlockingFunctionData *data)
+    {
+      free_param (data->param1);
+      free_param (data->param2);
+
+      g_slice_free (SomeBlockingFunctionData, data);
+    }
+
+    static void
+    some_blocking_function_thread_cb (GTask *task,
+                                      gpointer source_object,
+                                      gpointer task_data,
+                                      GCancellable *cancellable)
+    {
+      SomeBlockingFunctionData *data = task_data;
+      int retval;
+
+      /* Handle cancellation. */
+      if (g_task_return_error_if_cancelled (task))
+        {
+          return;
+        }
+
+      /* Run the blocking function. */
+      retval = some_blocking_function (data->param1, data->param2);
+      g_task_return_int (task, retval);
+    }
+
+    void
+    some_blocking_function_async (void *param1,
+                                  void *param2,
+                                  GCancellable *cancellable,
+                                  GAsyncReadyCallback callback,
+                                  gpointer user_data)
+    {
+      GTask *task = NULL;  /* owned */
+      SomeBlockingFunctionData *data = NULL;  /* owned */
+
+      g_return_if_fail (validate_param (param1));
+      g_return_if_fail (validate_param (param2));
+      g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+      task = g_task_new (NULL, cancellable, callback, user_data);
+      g_task_set_source_tag (task, some_blocking_function_async);
+
+      /* Cancellation should be handled manually using mechanisms specific to
+       * some_blocking_function(). */
+      g_task_set_return_on_cancel (task, FALSE);
+
+      /* Set up a closure containing the call’s parameters. Copy them to avoid
+       * locking issues between the calling thread and the worker thread. */
+      data = g_slice_new (SomeBlockingFunctionData);
+      data->param1 = copy_param (param1);
+      data->param2 = copy_param (param2);
+
+      g_task_set_task_data (task, data, some_blocking_function_data_free);
+
+      /* Run the task in a worker thread and return immediately while that continues
+       * in the background. When it’s done it will call @callback in the current
+       * thread default main context. */
+      g_task_run_in_thread (task, some_blocking_function_thread_cb);
+
+      g_object_unref (task);
+    }
+
+    int
+    some_blocking_function_finish (GAsyncResult *result,
+                                   GError **error)
+    {
+      g_return_val_if_fail (g_task_is_valid (result,
+                                             some_blocking_function_async), -1);
+      g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+      return g_task_propagate_int (G_TASK (result), error);
+    }
+
+See the
+[`GAsyncResult` documentation](https://developer.gnome.org/gio/stable/GAsyncResult.html)
+for more details. A simple way to implement the worker thread is to use
+[`GTask`](https://developer.gnome.org/gio/stable/GTask.html) and
+[`g_task_run_in_thread()`](https://developer.gnome.org/gio/stable/GTask.html#g-task-run-in-thread).
+
+# Using threading
+
+If `GTask` is not suitable for writing the worker thread, a more low-level
+approach must be used. This should be considered very carefully, as it is very
+easy to get threading code wrong in ways which will unpredictably cause bugs at
+runtime, cause deadlocks, or consume too many resources and terminate the
+program.
+
+A full manual on writing threaded code is beyond the scope of this document,
+but here are a number of guidelines to follow which should reduce the potential
+for bugs in threading code. The overriding principle is to reduce the amount of
+code and data which can be affected by threading — e.g. reducing the number of
+threads, the complexity of worker thread implementation, and the amount of data
+shared between threads.
+
+- Use
+  [`GThreadPool`](https://developer.gnome.org/glib/stable/glib-Thread-Pools.html)
+  instead of manually creating
+  [`GThread`s](https://developer.gnome.org/glib/stable/glib-Threads.html) if
+  possible. `GThreadPool` supports a work queue, limits on the number of
+  spawned threads, and automatically joins finished threads so they are not
+  leaked.
+- If it is not possible to use a `GThreadPool` (which is rarely the case):
+  - Use
+    [`g_thread_try_new()`](https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-try-new)
+    to spawn threads, instead of
+    [`g_thread_new()`](https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-new),
+    so errors due to the system running out of threads can be handled
+    gracefully rather than unconditionally aborting the program.
+  - Explicitly join threads using
+    [`g_thread_join()`](https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-join)
+    to avoid leaking the thread resources.
+- Use message passing to transfer data between threads, rather than manual
+  locking with mutexes. `GThreadPool` explicitly supports this with
+  [`g_thread_pool_push()`](https://developer.gnome.org/glib/stable/glib-Thread-Pools.html#g-thread-pool-push).
+- If mutexes must be used:
+  - Isolate threading code as much as possible, keeping mutexes private within
+    classes, and tightly bound to very specific class members.
+  - All mutexes should be clearly commented beside their declaration,
+    indicating which other structures or variables they protect access to.
+    Similarly, those variables should be commented saying that they should
+    *only* be accessed with that mutex held.
+- Be careful about interactions between main contexts and threads. For example,
+  [`g_timeout_add_seconds()`](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add-seconds)
+  adds a timeout *to be executed in the global default main context*, which is
+  being run in the main thread, *not necessarily* the current thread. Getting
+  this wrong can mean that work intended for a worker thread accidentally ends
+  up being executed in the main thread anyway.
+
+# Debugging
+
+Debugging threading issues is tricky, both because they are hard to reproduce,
+and because they are hard to reason about. This is one of the big reasons for
+avoiding using threads in the first place.
+
+However, if a threading issue does arise,
+[Valgrind’s drd and helgrind tools are useful]( {{< ref "tooling.md#helgrind-and-drd" >}} ).
+
+# External links
+
+- [GThread API documentation](https://developer.gnome.org/glib/stable/glib-Threads.html)
+- [GThreadPool API documentation](https://developer.gnome.org/glib/stable/glib-Thread-Pools.html)
+- [GMainContext API documentation](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html)
+- [GAsyncResult documentation](https://developer.gnome.org/gio/stable/GAsyncResult.html)
+- [Introduction to GMainContext](https://tecnocode.co.uk/2014/03/27/what-is-gmaincontext/)
+- [Article on GMainContext and threading](https://tecnocode.co.uk/2014/04/19/ensuring-functions-are-called-in-the-right-context/)
diff --git a/content/guides/tooling.md b/content/guides/tooling.md
new file mode 100644
index 0000000000000000000000000000000000000000..9293c2fd4bdbe66cad923a2c1e4da7b7cc8d77d0
--- /dev/null
+++ b/content/guides/tooling.md
@@ -0,0 +1,324 @@
++++
+date = "2016-02-18"
+weight = 100
+
+title = "Tooling"
+
+aliases = [
+    "/old-wiki/Guidelines/Tooling"
+]
++++
+
+Development tools are much more than just a text editor and a compiler.
+Correct use of the right tools can drastically ease debugging and tracking down
+of complex problems with memory allocation and system calls, amongst other
+things. Some of the most commonly used tools are described below; other tools
+exist for more specialised use cases, and should be used when appropriate.
+
+# Summary
+
+- Compile frequently with a second compiler. ([GCC and Clang](#gcc-and-clang))
+- Enable a large selection of compiler warnings and make them fatal.
+  ([GCC and Clang](#gcc-and-clang))
+- Use GDB to debug and step through code. ([GDB](#gdb))
+- Use Valgrind to analyse memory usage, memory errors, cache and CPU
+  performance and threading errors.  ([Valgrind](#valgrind))
+- Use gcov and lcov to analyse unit test coverage.
+  ([gcov and lcov](#gcov-and-lcov))
+- Submit to Coverity as a cronjob and eliminate static analysis errors as they
+  appear. ([Coverity](#coverity))
+- Use Clang static analyser and Tartan regularly to eliminate statically
+  analysable errors locally. ([Clang static analyser](#clang-static-analyser))
+
+# GCC and Clang
+
+GCC is the standard C compiler for Linux. An alternative exists in the form of
+Clang, with comparable functionality. Choose one (probably GCC) to use as a
+main compiler, but occasionally use the other to compile the code, as the two
+detect slightly different sets of errors and warnings in code. Clang also comes
+with a static analyser tool which can be used to detect errors in code without
+compiling or running it; see [Clang static analyser](#clang-static-analyser).
+
+Both compilers should be used with as many warning flags enabled as possible.
+Although compiler warnings do occasionally provide false positives, most
+warnings legitimately point to problems in the code, and hence should be fixed
+rather than ignored. A development policy of enabling all warning flags and
+also specifying the `-Werror` flag (which makes all warnings fatal to
+compilation) promotes fixing warnings as soon as they are introduced. This
+helps code quality. The alternative of ignoring warnings leads to long
+debugging sessions to track down bugs caused by issues which would have been
+flagged up by the warnings.  Similarly, ignoring warnings until the end of the
+development cycle, then spending a block of time enabling and fixing them all
+wastes time.
+
+Both GCC and Clang support a wide range of compiler flags, only some of which
+are related to modern, multi-purpose code (e.g. others are outdated, or
+architecture-specific). Finding a reasonable set of flags to enable can be
+tricky, and hence the
+[`AX_COMPILER_FLAGS`](http://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html)
+macro exists.
+
+`AX_COMPILER_FLAGS` enables a consistent set of compiler warnings, and also
+tests that the compiler supports each flag before enabling it. This accounts
+for differences in the set of flags supported by GCC and Clang.  To use it, add
+`AX_COMPILER_FLAGS` to `configure.ac`. If you are using in-tree copies of
+autoconf-archive macros, copy
+[`ax_compiler_flags.m4`](http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_compiler_flags.m4)
+to the `m4/` directory of your project. Note that it depends on the following
+autoconf-archive macros which cannot be copied in-tree due to being
+GPL-licenced. They must remain in autoconf-archive, with that as a built time
+dependency of the project:
+
+- `ax_append_compile_flags.m4`
+- `ax_append_flag.m4`
+- `ax_check_compile_flag.m4`
+- `ax_require_defined.m4`
+
+`AX_COMPILER_FLAGS` supports disabling `-Werror` for release builds, so that
+releases may always be built against newer compilers which have introduced more
+warnings. Set its third parameter to ‘yes’ for release builds (and only release
+builds) to enable this functionality.  Development and CI builds should always
+have `-Werror` enabled.
+
+An easy way of determining whether this is a release version of a project is to
+use `AX_IS_RELEASE([micro-version])`. If this macro is used before
+`AX_COMPILER_FLAGS`, the third parameter to `AX_COMPILER_FLAGS` should not be
+passed — it will be picked up automatically from `AX_IS_RELEASE`.
+
+# GDB
+
+GDB is the standard debugger for C on Linux. Its most common uses are for
+debugging crashes, and for stepping through code as it executes. A full
+tutorial for using GDB is given
+[here](https://sourceware.org/gdb/current/onlinedocs/gdb/).
+
+To run GDB on a program from within the source tree, use:
+
+    libtool exec gdb --args ./program-name --some --arguments --here
+
+This is necessary due to libtool wrapping each compiled binary in the source
+tree in a shell script which sets up some libtool variables. It is not
+necessary for debugging installed executables.
+
+GDB has many advanced features which can be combined to essentially create
+small debugging scripts, triggered by different breakpoints in code. Sometimes
+this is a useful approach (e.g. for
+[reference count debugging](https://tecnocode.co.uk/2010/07/12/reference-count-debugging-with-gdb/)),
+but sometimes simply using `g_debug()` to output a debug message is simpler.
+
+# Valgrind
+
+Valgrind is a suite of tools for instrumenting and profiling programs.  Its
+most famous tool is [memcheck](#memcheck), but it has several other powerful
+and useful tools too. They are covered separately in the sections below.
+
+A useful way of running Valgrind is to run a program’s unit test suite under
+Valgrind, setting Valgrind to return a status code indicating the number of
+errors it encountered. When run as part of `make check`, this will cause the
+checks to succeed if Valgrind finds no problems, and fail otherwise. However,
+running `make check` under Valgrind is not trivial to do on the command line. A
+macro,
+[`AX_VALGRIND_CHECK`](http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html)
+can be used which adds a new `make check-valgrind` target to automate this. To
+use it, copy
+[`ax_valgrind_check.m4`](http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_valgrind_check.m4)
+to the `m4/` directory of a project, add `AX_VALGRIND_CHECK` to `configure.ac`
+and add `@VALGRIND_CHECK_RULES` to the top-level `Makefile.am`.
+
+When `make check-valgrind` is run, it will save its results in
+`test-suite-*.log`, one log file per tool.
+
+Valgrind has a way to suppress false positives, by using
+[suppression files](http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress).
+These list patterns which may match error stack traces. If a stack trace from
+an error matches part of a suppression entry, it is not reported.  For various
+reasons, GLib currently causes a number of false positives in
+[memcheck](#memcheck) and [helgrind and drd](#helgrind-and-drd) which must be
+suppressed by default for Valgrind to be useful. For this reason, every project
+should use a standard GLib suppression file as well as a project specific one.
+
+Suppression files are supported by the `AX_VALGRIND_CHECK` macro:
+
+    @VALGRIND_CHECK_RULES@ VALGRIND_SUPPRESSIONS_FILES = my-project.supp
+glib.supp EXTRA_DIST = $(VALGRIND_SUPPRESSIONS_FILES)
+
+## memcheck
+
+memcheck is a memory usage and allocation analyser. It detects problems with
+memory accesses and modifications of the heap (allocations and frees). It is a
+highly robust and mature tool, and its output can be entirely trusted. If it
+says there is ‘definitely’ a memory leak, there is definitely a memory leak
+which should be fixed. If it says there is ‘potentially’ a memory leak, there
+may be a leak to be fixed, or it may be memory allocated at initialisation time
+and used throughout the life of the program without needing to be freed.
+
+A full tutorial on using memcheck is
+[here](http://valgrind.org/docs/manual/mc-manual.html).
+
+## cachegrind and KCacheGrind
+
+cachegrind is a cache performance profiler which can also measure instruction
+execution, and hence is very useful for profiling general performance of a
+program.  [KCacheGrind](http://kcachegrind.sourceforge.net/html/Home.html) is a
+useful UI for it which allows visualisation and exploration of the profiling
+data, and the two tools should rarely be used separately.
+
+cachegrind works by simulating the processor's memory hierarchy, so there are
+situations where it is
+[not perfectly accurate](http://valgrind.org/docs/manual/cg-manual.html#cg-manual.annopts.accuracy).
+However, its results are always representative enough to be very useful in
+debugging performance hotspots.
+
+A full tutorial on using cachegrind is
+[here](http://valgrind.org/docs/manual/cg-manual.html).
+
+## helgrind and drd
+
+helgrind and drd are threading error detectors, checking for race conditions in
+memory accesses, and abuses of the
+[POSIX pthreads API](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html).
+They are similar tools, but are implemented using different techniques, so both
+should be used.
+
+The kinds of errors detected by helgrind and drd are: data accessed from
+multiple threads without consistent locking, changes in lock acquisition order,
+freeing a mutex while it is locked, locking a locked mutex, unlocking an
+unlocked mutex, and several other errors. Each error, when detected, is printed
+to the console in a little report, with a separate report giving the allocation
+or spawning details of the mutexes or threads involved so that their
+definitions can be found.
+
+helgrind and drd can produce more false positives than memcheck or cachegrind,
+so their output should be studied a little more carefully.  However, threading
+problems are notoriously elusive even to experienced programmers, so helgrind
+and drd errors should not be dismissed lightly.
+
+Full tutorials on using helgrind and drd are
+[here](http://valgrind.org/docs/manual/hg-manual.html) and
+[here](http://valgrind.org/docs/manual/drd-manual.html).
+
+## sgcheck
+
+sgcheck is an array bounds checker, which detects accesses to arrays which have
+overstepped the length of the array. However, it is a very young tool, still
+marked as experimental, and hence may produce more false positives than other
+tools.
+
+As it is experimental, sgcheck must be run by passing `--tool=exp-sgcheck` to
+Valgrind, rather than `--tool=sgcheck`.
+
+A full tutorial on using sgcheck is
+[here](http://valgrind.org/docs/manual/sg-manual.html).
+
+# gcov and lcov
+
+[gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) is a profiling tool built
+into GCC, which instruments code by adding extra instructions at compile time.
+When the program is run, this code generates `.gcda` and `.gcno` profiling
+output files. These files can be analysed by the `lcov` tool, which generates
+visual reports of code coverage at runtime, highlighting lines of code in the
+project which are run more than others.
+
+A critical use for this code coverage data collection is when running the unit
+tests: if the amount of code covered (e.g. which particular lines were run) by
+the unit tests is known, it can be used to guide further expansion of the unit
+tests. By regularly checking the code coverage attained by the unit tests, and
+expanding them towards 100%, you can be sure that the entire project is being
+tested. Often it is the case that a unit test exercises most of the code, but
+not a particular control flow path, which then harbours residual bugs.
+
+lcov supports
+[branch coverage measurement](http://en.wikipedia.org/wiki/Code_coverage#Basic_coverage_criteria),
+so is not suitable for demonstrating coverage of safety critical code.  It is
+perfectly suitable for non-safety critical code.
+
+As code coverage has to be enabled at both compile time and run time, a macro
+is provided to make things simpler. The
+[`AX_CODE_COVERAGE`](http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html)
+macro adds a `make check-code-coverage` target to the build system, which runs
+the unit tests with code coverage enabled, and generates a report using `lcov`.
+
+To add `AX_CODE_COVERAGE` support to a project, add `AX_CODE_COVERAGE` to
+`configure.ac`. The macro itself cannot be copied to the `m4/` directory due to
+being GPL-licenced. Instead, the project must have a build time dependency on
+autoconf-archive (version 2014-10-15 or later).
+
+Documentation on using gcov and lcov is
+[here](http://ltp.sourceforge.net/coverage/lcov.php).
+
+# Coverity
+
+[Coverity](http://scan.coverity.com/) is one of the most popular and biggest
+commercial static analyser tools available. However, it is available to use
+free for Open Source projects, and any project is encouraged to
+[sign up](https://scan.coverity.com/users/sign_up).
+[Analysis is performed](https://scan.coverity.com/faq#how-get-project-included-in-scan)
+by running some analysis tools locally, then uploading the source code and
+results as a tarball to Coverity’s site. The results are then visible online to
+members of the project, as annotations on the project’s source code (similarly
+to how lcov presents its results).
+
+As Coverity cannot be run entirely locally, it cannot be integrated properly
+into the build system. However, scripts do exist to automatically scan a
+project and upload the tarball to Coverity regularly. The recommended approach
+is to run these scripts regularly on a server (i.e. as a cronjob), using a
+clean checkout of the project’s git repository. Coverity automatically e-mails
+project members about new static analysis problems it finds, so the same
+approch as for [compiler warnings](#gcc-and-clang) can be taken: eliminate all
+the static analysis warnings, then eliminate new ones as they are detected.
+
+Coverity is good, but it is not perfect, and it does produce a number of false
+positives. These should be marked as ignored in the online interface.
+
+# Clang static analyser
+
+One tool which can be used to perform static analysis locally is the
+[Clang static analyser](http://clang-analyzer.llvm.org/), which is a tool
+co-developed with the [Clang compiler](#gcc-and-clang).  It detects a variety
+of problems in C code which compilers cannot, and which would otherwise only be
+detectable at run time (i.e. using unit tests).
+
+Clang produces some false positives, and there is no easy way to ignore them.
+The recommended thing to do is to
+[file a bug report against the static analyser](http://clang-analyzer.llvm.org/faq.html#suppress_issue),
+so that the false positive can be fixed in future.
+
+A full tutorial on using Clang is
+[here](http://clang-analyzer.llvm.org/scan-build.html).
+
+## Tartan
+
+However, for all the power of the Clang static analyser, it cannot detect
+problems with specific libraries, such as GLib. This is a problem if (as
+recommended) a project uses GLib exclusively, and rarely uses POSIX APIs (which
+Clang does understand). There is a plugin available for the Clang static
+analyser, called [Tartan](https://gitlab.freedesktop.org/tartan/tartan), which
+extends it to support checks against some of the common GLib APIs.
+
+Tartan is still young software, and will produce false positives and may crash
+when run on some code. However, it can find legitimate bugs quite quickly, and
+is worth running over a code base frequently to detect new errors in the use of
+GLib in the code. Please
+[report any problems with Tartan](https://gitlab.freedesktop.org/tartan/tartan/-/wikis/home#troubleshooting).
+
+A full tutorial on enabling Tartan for use with the Clang static analyser is
+[here](https://gitlab.freedesktop.org/tartan/tartan/-/wikis/home#standalone-usage).
+If set up correctly, the output from Tartan will be mixed together with the
+normal static analyser output.
+
+# External links
+
+- [GCC](https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/)
+- [Clang](http://clang.llvm.org/docs/UsersManual.html)
+- [GDB](https://sourceware.org/gdb/current/onlinedocs/gdb/)
+- [Valgrind](http://valgrind.org/docs/manual/)
+  - [memcheck](http://valgrind.org/docs/manual/mc-manual.html)
+  - [cachegrind](http://valgrind.org/docs/manual/cg-manual.html)
+  - [helgrind](http://valgrind.org/docs/manual/hg-manual.html)
+  - [drd](http://valgrind.org/docs/manual/drd-manual.html)
+  - [sgcheck](http://valgrind.org/docs/manual/sg-manual.html)
+- [KCacheGrind](http://kcachegrind.sourceforge.net/html/Home.html)
+- [gcov/lcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html)
+- [Coverity](https://scan.coverity.com/)
+- [Clang SA](http://clang-analyzer.llvm.org/)
+- [Tartan](https://gitlab.freedesktop.org/tartan/tartan)
diff --git a/content/guides/unit_testing.md b/content/guides/unit_testing.md
new file mode 100644
index 0000000000000000000000000000000000000000..90ada6e20f39564158d1e63da51dfcd872d9e0fc
--- /dev/null
+++ b/content/guides/unit_testing.md
@@ -0,0 +1,207 @@
++++
+date = "2015-09-08"
+weight = 100
+
+title = "Unit Testing"
+
+aliases = [
+    "/old-wiki/Guidelines/Unit_testing"
+]
++++
+
+
+Unit testing should be the primary method of testing the bulk of code
+written, because a unit test can be written once and run many times —
+manual tests have to be planned once and then manually run each time.
+
+Development of unit tests starts with the architecture and API design of
+the code to be tested: code should be designed to be easily testable, or
+will potentially be very difficult to test.
+
+# Summary
+
+- Write unit tests to be as small as possible, but no smaller.
+  ([Writing unit tests](#writing-unit-tests))
+- Use code coverage tools to write tests to get high code coverage.
+  ([Writing unit tests](#writing-unit-tests))
+- Run all unit tests under Valgrind to check for leaks and other problems.
+  ([Leak checking](#leak-checking))
+- Use appropriate tools to automatically generate unit tests where possible.
+  ([Test generation](#test-generation))
+- Design code to be testable from the beginning.
+  ([Writing testable code](#writing-testable-code))
+
+# Writing unit tests
+
+Unit tests should be written in conjunction with looking at
+[code coverage information gained from running the tests]( {{< ref "tooling.md#gcov-and-lcov" >}} ).
+This typically means writing an initial set of unit tests, running them to get
+coverage data, then reworking and expanding them to increase the code coverage
+levels. Coverage should be increased first by ensuring all functions are
+covered (at least in part), and then by ensuring all lines of code are covered.
+By covering functions first, API problems which will prevent effective testing
+can be found quickly. These typically manifest as internal functions which
+cannot easily be called from unit tests.  Overall, coverage levels of over 90%
+should be aimed for; don’t just test cases covered by project requirements,
+test everything.
+
+Like [git commits]( {{< ref "version_control.md" >}} ), each unit test should
+be ‘as small as possible, but no smaller’, testing a single specific API or
+behaviour. Each test case must be able to be run individually, without
+depending on state from other test cases. This is important to allow debugging
+of a single failing test, without having to step through all the other test
+code as well. It also means that a single test failure can easily be traced
+back to a specific API, rather than a generic "unit tests failed somewhere"
+message.
+
+GLib has support for unit testing with its
+[GTest framework](https://developer.gnome.org/glib/stable/glib-Testing.html),
+allowing tests to be arranged in groups and hierarchies. This means that groups
+of related tests can be run together for enhanced debugging too, by running the
+test binary with the `-p` argument:
+
+    ./test-suite-name -p /path/to/test/group
+
+# Installed tests
+
+All unit tests should be installed system-wide, following the
+[installed-tests standard](https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests).
+
+By installing the unit tests, continuous integration (CI) is made easier, since
+tests for one project can be re-run after changes to other projects in the CI
+environment, thus testing the interfaces between modules. That is useful for a
+highly-coupled set of projects like Apertis.
+
+To add support for installed-tests, add the following to `configure.ac`:
+
+```
+# Installed tests
+AC_ARG_ENABLE([modular_tests],
+              AS_HELP_STRING([--disable-modular-tests],
+                             [Disable build of test programs (default: no)]),,
+              [enable_modular_tests=yes])
+AC_ARG_ENABLE([installed_tests],
+              AS_HELP_STRING([--enable-installed-tests],
+                             [Install test programs (default: no)]),,
+              [enable_installed_tests=no])
+AM_CONDITIONAL([BUILD_MODULAR_TESTS],
+               [test "$enable_modular_tests" = "yes" ||
+                test "$enable_installed_tests" = "yes"])
+AM_CONDITIONAL([BUILDOPT_INSTALL_TESTS],[test "$enable_installed_tests" = "yes"])
+```
+
+Then in `tests/Makefile.am`:
+
+```
+insttestdir = $(libexecdir)/installed-tests/[project]
+
+all_test_programs = \
+    test-program1 \
+    test-program2 \
+    test-program3 \
+    $(NULL)
+if BUILD_MODULAR_TESTS
+TESTS = $(all_test_programs)
+noinst_PROGRAMS = $(TESTS)
+endif
+
+if BUILDOPT_INSTALL_TESTS
+insttest_PROGRAMS = $(all_test_programs)
+
+testmetadir = $(datadir)/installed-tests/[project]
+testmeta_DATA = $(all_test_programs:=.test)
+
+testdatadir = $(insttestdir)
+testdata_DATA = $(test_files)
+
+testdata_SCRIPTS = $(test_script_files)
+endif
+
+EXTRA_DIST = $(test_files)
+
+%.test: % Makefile
+    $(AM_V_GEN) (echo '[Test]' > $@.tmp; \
+    echo 'Type=session' >> $@.tmp; \
+    echo 'Exec=$(insttestdir)/$<' >> $@.tmp; \
+    mv $@.tmp $@)
+```
+
+# Leak checking
+
+Once unit tests with high code coverage have been written, they can be run
+under various dynamic analysis tools, such as
+[Valgrind]( {{< ref "tooling.md#valgrind" >}} ) to check for leaks, threading
+errors, allocation problems, etc. across the entire code base.  The higher the
+code coverage of the unit tests, the more confidence the Valgrind results can
+be treated with.  See the [Tooling]( {{< ref "tooling.md" >}} ) page for more
+information, including build system integration instructions.
+
+Critically, this means that unit tests should not leak memory or other
+resources themselves, and similarly should not have any threading problems. Any
+such problems would effectively be false positives in the analysis of the
+actual project code. (False positives which need to be fixed by fixing the unit
+tests.)
+
+# Test generation
+
+Certain types of code are quite repetitive, and require a lot of unit tests to
+gain good coverage; but are appropriate for
+[test data generation](http://en.wikipedia.org/wiki/Test_data_generation),
+where a tool is used to automatically generate test vectors for the code. This
+can drastically reduce the time needed for writing unit tests, for code in
+these specific domains.
+
+## JSON
+
+One example of a domain amenable to test data generation is parsing, where the
+data to be parsed is required to follow a strict schema — this is the case for
+XML and JSON documents. For JSON, a tool such as
+[Walbottle](https://github.com/pwithnall/walbottle) can be used to generate
+test vectors for all types of valid and invalid input according to the schema.
+
+Every type of JSON document should have a
+[JSON Schema](http://json-schema.org/) defined for it, which can then be passed
+to Walbottle to generate test vectors:
+
+    json-schema-generate --valid-only schema.json
+    json-schema-generate --invalid-only schema.json
+
+These test vectors can then be passed to the code under test in its unit tests.
+The JSON instances generated by `--valid-only` should be accepted; those from
+`--invalid-only` should be rejected.
+
+# Writing testable code
+
+Code should be written with testability in mind from the design stage, as it
+affects API design and architecture in fundamental ways. A few key principles:
+
+- Do not use global state. Singleton objects are usually a bad idea as they
+  can’t be instantiated separately or controlled in the unit tests.
+- Separate out use of external state, such as databases, networking, or the
+  file system. The unit tests can then replace the accesses to external state
+  with mocked objects. A common approach to this is to use dependency injection
+  to pass a file system wrapper object to the code under test. For example, a
+  class should not load a global database (from a fixed location in the file
+  system) because the unit tests would then potentially overwrite the running
+  system’s copy of the database, and could never be executed in parallel. They
+  should be passed an object which provides an interface to the database: in a
+  production system, this would be a thin wrapper around the database API; for
+  testing, it would be a mock object which checks the requests given to it and
+  returns hard-coded responses for various tests.
+- Expose utility functions where they might be generally useful.
+- Split projects up into collections of small, private libraries which are then
+  linked together with a minimal amount of glue code into the overall
+  executable. Each can be tested separately.
+
+The topic of software testability is covered in the following articles:
+
+- [Design for testability](http://msdn.microsoft.com/en-us/magazine/dd263069.aspx)
+- [Software testability](http://en.wikipedia.org/wiki/Software_testability)
+- [Dependency injection](http://en.wikipedia.org/wiki/Dependency_injection)
+- [Software design for testing](http://c2.com/cgi/wiki?SoftwareDesignForTesting)
+
+# External links
+
+- [GLib test framework](https://developer.gnome.org/glib/stable/glib-Testing.html)
+- [Walbottle](http://people.collabora.com/~pwith/walbottle/)
+- [installed-tests documentation](https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests)