[Pkg-cli-libs-commits] [dbus-sharp-legacy] 01/02: Imported Upstream version 0.7.0

Jo Shields directhex at moszumanska.debian.org
Thu Mar 13 00:22:37 UTC 2014


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

directhex pushed a commit to branch master
in repository dbus-sharp-legacy.

commit a5669f9da968700f5859f87030de6406ef5b88d3
Author: Jo Shields <directhex at apebox.org>
Date:   Thu Mar 13 00:15:43 2014 +0000

    Imported Upstream version 0.7.0
---
 AUTHORS                         |    1 +
 COPYING                         |   21 +
 ChangeLog                       |    0
 INSTALL                         |  365 ++++
 Makefile.am                     |   22 +
 Makefile.in                     |  722 ++++++++
 NEWS                            |    0
 README                          |   44 +
 aclocal.m4                      |  835 +++++++++
 configure                       | 3786 +++++++++++++++++++++++++++++++++++++++
 configure.ac                    |   59 +
 dbus-sharp-1.0.pc.in            |   11 +
 dbus-sharp.snk                  |  Bin 0 -> 596 bytes
 examples/Makefile.am            |    6 +
 examples/Makefile.in            |  314 ++++
 examples/Notifications.cs       |   31 +
 examples/Test.cs                |   49 +
 examples/TestExportInterface.cs |  305 ++++
 examples/TestNotifications.cs   |   39 +
 examples/TestSample.cs          |   54 +
 install-sh                      |  520 ++++++
 missing                         |  376 ++++
 src/Address.cs                  |  188 ++
 src/AssemblyInfo.cs.in          |   27 +
 src/Authentication.cs           |  538 ++++++
 src/Bus.cs                      |  179 ++
 src/BusObject.cs                |  402 +++++
 src/Connection.cs               |  507 ++++++
 src/DBus.cs                     |   98 +
 src/DProxy.cs                   |   79 +
 src/ExportObject.cs             |  199 ++
 src/Introspection.cs            |  316 ++++
 src/Makefile.am                 |   68 +
 src/Makefile.in                 |  382 ++++
 src/Mapper.cs                   |  389 ++++
 src/MatchRule.cs                |  319 ++++
 src/Message.cs                  |  499 ++++++
 src/MessageFilter.cs            |   58 +
 src/MessageReader.cs            |  494 +++++
 src/MessageWriter.cs            |  570 ++++++
 src/PendingCall.cs              |  111 ++
 src/Protocol.cs                 |  525 ++++++
 src/Signature.cs                |  897 ++++++++++
 src/SocketTransport.cs          |   70 +
 src/Transport.cs                |  383 ++++
 src/TypeImplementer.cs          |  909 ++++++++++
 src/TypeRental.cs               |  504 ++++++
 src/Unix.cs                     |  484 +++++
 src/UnixNativeTransport.cs      |  180 ++
 src/UnixTransport.cs            |   29 +
 src/Wrapper.cs                  |  158 ++
 src/dbus-sharp.dll.config       |    3 +
 tools/Introspect.cs             |   35 +
 tools/Makefile.am               |    3 +
 tools/Makefile.in               |  311 ++++
 tools/Monitor.cs                |  239 +++
 56 files changed, 17713 insertions(+)

diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..d6b9e4c
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Alp Toker <alp at atoker.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..0dfc23e
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,21 @@
+Copyright 2006 Alp Toker <alp at atoker.com>
+Copyright 2010 Other Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..7d1c323
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,365 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.  Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+   The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package, generally using the just-built uninstalled binaries.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the `make install' phase executed with root
+     privileges.
+
+  5. Optionally, type `make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior `make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  7. Often, you can also type `make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide `make
+     distcheck', which can by used by developers to test that all other
+     targets like `make install' and `make uninstall' work correctly.
+     This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.  This
+is known as a "VPATH" build.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'.  Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated.  The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the `DESTDIR' variable.  For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names.  The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+   Some packages offer the ability to configure how verbose the
+execution of `make' will be.  For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..f4f4f01
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,22 @@
+SUBDIRS = src tools examples
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = dbus-sharp-1.0.pc
+
+EXTRA_DIST = \
+	dbus-sharp-1.0.pc.in \
+	dbus-sharp.snk
+
+DISTCLEANFILES = \
+	dbus-sharp-1.0.pc
+
+MAINTAINERCLEANFILES = \
+	INSTALL \
+	Makefile.in \
+	aclocal.m4 \
+	config.guess \
+	config.sub \
+	configure \
+	install-sh \
+	missing
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..d2b5c93
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,722 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/dbus-sharp-1.0.pc.in \
+	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
+	install-sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES = dbus-sharp-1.0.pc
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(pkgconfig_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d "$(distdir)" \
+    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr "$(distdir)"; }; }
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+API_VERSION = @API_VERSION@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+GACUTIL = @GACUTIL@
+GMCS = @GMCS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MONO_CFLAGS = @MONO_CFLAGS@
+MONO_LIBS = @MONO_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = src tools examples
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = dbus-sharp-1.0.pc
+EXTRA_DIST = \
+	dbus-sharp-1.0.pc.in \
+	dbus-sharp.snk
+
+DISTCLEANFILES = \
+	dbus-sharp-1.0.pc
+
+MAINTAINERCLEANFILES = \
+	INSTALL \
+	Makefile.in \
+	aclocal.m4 \
+	config.guess \
+	config.sub \
+	configure \
+	install-sh \
+	missing
+
+all: all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+dbus-sharp-1.0.pc: $(top_builddir)/config.status $(srcdir)/dbus-sharp-1.0.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-lzma: distdir
+	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+	$(am__remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lzma*) \
+	  lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@$(am__cd) '$(distuninstallcheck_dir)' \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkgconfigDATA
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am am--refresh check check-am clean clean-generic \
+	ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
+	dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
+	distclean distclean-generic distclean-tags distcleancheck \
+	distdir distuninstallcheck dvi dvi-am html html-am info \
+	info-am install install-am install-data install-data-am \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-pkgconfigDATA \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+	uninstall-pkgconfigDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644
index 0000000..066e2ea
--- /dev/null
+++ b/README
@@ -0,0 +1,44 @@
+D-Bus for .NET
+==============
+
+This is a fork of ndesk-dbus, which is a C# implementation of D-Bus. It's
+often referred to as "managed D-Bus" to avoid confusion with existing
+bindings (which wrap libdbus).
+
+See http://mono.github.com/dbus-sharp/ for our fork
+    - Tarball download: http://github.com/mono/dbus-sharp/downloads
+    - GitHub repository: http://www.github.com/mono/dbus-sharp
+    - Reporting bugs: http://github.com/mono/dbus-sharp/issues
+
+See http://www.ndesk.org/DBusSharp for Alp Toker's original project
+
+D-Bus is an inter-process communication framework that lets applications
+interface with the system event bus as well as allowing them to talk to
+one another in a peer-to-peer configuration.
+
+See http://www.freedesktop.org/wiki/Software/dbus for general
+information on the D-Bus IPC mechanism.
+
+This software is under active development but is already used by a wide
+range of applications for tasks as simple as maintaining a single
+instance of the GUI to whole instant messaging frameworks and hardware
+detection APIs.
+
+It provides a tested, high-performance bridge to and from all systems
+that are exposed via D-Bus, regardless of programming language, UI
+toolkit or license. The source code is MIT X11 licensed (Free
+Software/Open Source), allowing integration into other projects with
+very few restrictions.
+
+The code was written by Alp Toker <alp at atoker.com> and others, and is
+maintained by the dbus-sharp team.
+
+It is a clean-room implementation based on the D-Bus Specification
+Version 0.11 and study of the wire protocol of existing tools.
+
+It aims for compatibility with Mono and Microsoft .NET frameworks
+supporting the 2.0 profile. Backward compatibility with 1.0 will not be
+a consideration.
+
+-- 
+Alp Toker <alp at atoker.com> and others
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..e6daac9
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,835 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
+[m4_warning([this file was generated for autoconf 2.67.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+# 
+# Copyright © 2004 Scott James Remnant <scott at netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=m4_default([$1], [0.9.0])
+	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		PKG_CONFIG=""
+	fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_default([$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+    pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+    PKG_CHECK_EXISTS([$3],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+		     [pkg_failed=yes])
+ else
+    pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+   	AC_MSG_RESULT([no])
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
+        else 
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+	m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+        ])
+elif test $pkg_failed = untried; then
+     	AC_MSG_RESULT([no])
+	m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])dnl
+        ])
+else
+	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+	$3
+fi[]dnl
+])# PKG_CHECK_MODULES
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES(CC)],
+		  [define([AC_PROG_CC],
+			  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES(CXX)],
+		  [define([AC_PROG_CXX],
+			  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES(OBJC)],
+		  [define([AC_PROG_OBJC],
+			  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well.  Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+       [enable], [m4_define([am_maintainer_other], [disable])],
+       [disable], [m4_define([am_maintainer_other], [enable])],
+       [m4_define([am_maintainer_other], [enable])
+        m4_warn([syntax], [unexpected argument to AM@&t at _MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+[  --][am_maintainer_other][-maintainer-mode  am_maintainer_other make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer],
+      [USE_MAINTAINER_MODE=$enableval],
+      [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
diff --git a/configure b/configure
new file mode 100755
index 0000000..4d6c178
--- /dev/null
+++ b/configure
@@ -0,0 +1,3786 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.67.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="src/DBus.cs"
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+GACUTIL
+GMCS
+MONO_LIBS
+MONO_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+VERSION
+API_VERSION
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+MONO_CFLAGS
+MONO_LIBS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer
+
+Some influential environment variables:
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
+  MONO_CFLAGS C compiler flags for MONO, overriding pkg-config
+  MONO_LIBS   linker flags for MONO, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.67
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+API_VERSION=1.0
+#VERSION=$API_VERSION.0
+VERSION=0.7.0
+
+
+
+
+am__api_version='1.11'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=dbus-sharp
+ VERSION=$VERSION
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+   if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+
+# Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$PKG_CONFIG" = "xno"; then
+	as_fn_error $? "You need to install pkg-config" "$LINENO" 5
+fi
+
+
+MONO_REQ_VERSION=1.1.13
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MONO" >&5
+$as_echo_n "checking for MONO... " >&6; }
+
+if test -n "$MONO_CFLAGS"; then
+    pkg_cv_MONO_CFLAGS="$MONO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mono >= \$MONO_REQ_VERSION\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "mono >= $MONO_REQ_VERSION") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MONO_CFLAGS=`$PKG_CONFIG --cflags "mono >= $MONO_REQ_VERSION" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$MONO_LIBS"; then
+    pkg_cv_MONO_LIBS="$MONO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mono >= \$MONO_REQ_VERSION\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "mono >= $MONO_REQ_VERSION") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MONO_LIBS=`$PKG_CONFIG --libs "mono >= $MONO_REQ_VERSION" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        MONO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "mono >= $MONO_REQ_VERSION" 2>&1`
+        else
+	        MONO_PKG_ERRORS=`$PKG_CONFIG --print-errors "mono >= $MONO_REQ_VERSION" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$MONO_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (mono >= $MONO_REQ_VERSION) were not met:
+
+$MONO_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables MONO_CFLAGS
+and MONO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables MONO_CFLAGS
+and MONO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	MONO_CFLAGS=$pkg_cv_MONO_CFLAGS
+	MONO_LIBS=$pkg_cv_MONO_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+# Extract the first word of "gmcs", so it can be a program name with args.
+set dummy gmcs; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_GMCS+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GMCS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GMCS="$GMCS" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GMCS="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_GMCS" && ac_cv_path_GMCS="no"
+  ;;
+esac
+fi
+GMCS=$ac_cv_path_GMCS
+if test -n "$GMCS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMCS" >&5
+$as_echo "$GMCS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$GMCS" = "xno"; then
+	as_fn_error $? "You need to install gmcs" "$LINENO" 5
+fi
+
+
+# Extract the first word of "gacutil", so it can be a program name with args.
+set dummy gacutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_GACUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GACUTIL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GACUTIL="$GACUTIL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GACUTIL="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_GACUTIL" && ac_cv_path_GACUTIL="no"
+  ;;
+esac
+fi
+GACUTIL=$ac_cv_path_GACUTIL
+if test -n "$GACUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GACUTIL" >&5
+$as_echo "$GACUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$GACUTIL" = "xno"; then
+	as_fn_error $? "You need to install gacutil" "$LINENO" 5
+fi
+
+
+required_assemblies="Mono.Posix"
+
+for asm in $required_assemblies; do
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $asm.dll" >&5
+$as_echo_n "checking for $asm.dll... " >&6; }
+	if test -n "`$GACUTIL /l $asm.dll | grep ^$asm.dll`"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+		as_fn_error $? "missing required assembly in the GAC: $asm.dll" "$LINENO" 5
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	fi
+done
+
+ac_config_files="$ac_config_files Makefile dbus-sharp-1.0.pc src/AssemblyInfo.cs src/Makefile tools/Makefile examples/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.67,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "dbus-sharp-1.0.pc") CONFIG_FILES="$CONFIG_FILES dbus-sharp-1.0.pc" ;;
+    "src/AssemblyInfo.cs") CONFIG_FILES="$CONFIG_FILES src/AssemblyInfo.cs" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
+    "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..e589e2b
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,59 @@
+AC_INIT(src/DBus.cs)
+
+AC_PREREQ(2.13)
+
+API_VERSION=1.0
+#VERSION=$API_VERSION.0
+VERSION=0.7.0
+
+AC_SUBST(API_VERSION)
+AC_SUBST(VERSION)
+
+AM_INIT_AUTOMAKE(dbus-sharp, $VERSION)
+
+AM_MAINTAINER_MODE
+
+AC_PROG_INSTALL
+
+AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+if test "x$PKG_CONFIG" = "xno"; then
+	AC_MSG_ERROR([You need to install pkg-config])
+fi
+AC_SUBST(PKG_CONFIG)
+
+MONO_REQ_VERSION=1.1.13
+PKG_CHECK_MODULES(MONO, mono >= $MONO_REQ_VERSION)
+
+AC_PATH_PROG(GMCS, gmcs, no)
+if test "x$GMCS" = "xno"; then
+	AC_MSG_ERROR([You need to install gmcs])
+fi
+AC_SUBST(GMCS)
+
+AC_PATH_PROG(GACUTIL, gacutil, no)
+if test "x$GACUTIL" = "xno"; then
+	AC_MSG_ERROR([You need to install gacutil])
+fi
+AC_SUBST(GACUTIL)
+
+required_assemblies="Mono.Posix"
+
+for asm in $required_assemblies; do
+	AC_MSG_CHECKING([for $asm.dll])
+	if test -n "`$GACUTIL /l $asm.dll | grep ^$asm.dll`"; then
+		AC_MSG_RESULT([not found])
+		AC_MSG_ERROR([missing required assembly in the GAC: $asm.dll])
+	else
+		AC_MSG_RESULT([found])
+	fi
+done
+
+AC_OUTPUT([
+Makefile
+dbus-sharp-1.0.pc
+src/AssemblyInfo.cs
+src/Makefile
+tools/Makefile
+examples/Makefile
+])
+
diff --git a/dbus-sharp-1.0.pc.in b/dbus-sharp-1.0.pc.in
new file mode 100644
index 0000000..7e1b657
--- /dev/null
+++ b/dbus-sharp-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+datadir=${prefix}/share
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+session_bus_services_dir=${datadir}/dbus-1/services
+
+Name: Managed DBus
+Description: Managed D-Bus IPC protocol library and CLR binding
+Version: @VERSION@
+URL: http://mono.github.com/dbus-sharp/
+Libs: -r:${libdir}/mono/@PACKAGE at -@API_VERSION@/dbus-sharp.dll
diff --git a/dbus-sharp.snk b/dbus-sharp.snk
new file mode 100644
index 0000000..fddb426
Binary files /dev/null and b/dbus-sharp.snk differ
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..b0e4a39
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,6 @@
+EXTRA_DIST = \
+	Test.cs \
+	TestExportInterface.cs \
+	Notifications.cs \
+	TestNotifications.cs \
+	TestSample.cs
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..c2d15f5
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,314 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = examples
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+API_VERSION = @API_VERSION@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+GACUTIL = @GACUTIL@
+GMCS = @GMCS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MONO_CFLAGS = @MONO_CFLAGS@
+MONO_LIBS = @MONO_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+	Test.cs \
+	TestExportInterface.cs \
+	Notifications.cs \
+	TestNotifications.cs \
+	TestSample.cs
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu examples/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/examples/Notifications.cs b/examples/Notifications.cs
new file mode 100644
index 0000000..b57bb80
--- /dev/null
+++ b/examples/Notifications.cs
@@ -0,0 +1,31 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+
+using DBus;
+using org.freedesktop.DBus;
+
+// Hand-written interfaces for bootstrapping
+
+namespace org.freedesktop
+{
+	public struct ServerInformation
+	{
+		public string Name;
+		public string Vendor;
+		public string Version;
+		public string SpecVersion;
+	}
+
+	[Interface ("org.freedesktop.Notifications")]
+	public interface Notifications : Introspectable, Properties
+	{
+		ServerInformation GetServerInformation ();
+		string[] GetCapabilities ();
+		void CloseNotification (uint id);
+		uint Notify (string app_name, uint id, string icon, string summary, string body, string[] actions, IDictionary<string,object> hints, int timeout);
+	}
+}
diff --git a/examples/Test.cs b/examples/Test.cs
new file mode 100644
index 0000000..93e5233
--- /dev/null
+++ b/examples/Test.cs
@@ -0,0 +1,49 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using DBus;
+using org.freedesktop.DBus;
+
+public class ManagedDBusTest
+{
+	public static void Main (string[] args)
+	{
+		Connection conn;
+
+		if (args.Length == 0)
+			conn = Bus.Session;
+		else {
+			if (args[0] == "--session")
+				conn = Bus.Session;
+			else if (args[0] == "--system")
+				conn = Bus.System;
+			else
+				conn = Connection.Open (args[0]);
+		}
+
+		ObjectPath opath = new ObjectPath ("/org/freedesktop/DBus");
+		string name = "org.freedesktop.DBus";
+
+		IBus bus = conn.GetObject<IBus> (name, opath);
+
+		bus.NameAcquired += delegate (string acquired_name) {
+			Console.WriteLine ("NameAcquired: " + acquired_name);
+		};
+
+		Console.WriteLine ();
+		string xmlData = bus.Introspect ();
+		Console.WriteLine ("xmlData: " + xmlData);
+
+		Console.WriteLine ();
+		foreach (string n in bus.ListNames ())
+			Console.WriteLine (n);
+
+		Console.WriteLine ();
+		foreach (string n in bus.ListNames ())
+			Console.WriteLine ("Name " + n + " has owner: " + bus.NameHasOwner (n));
+
+		Console.WriteLine ();
+	}
+}
diff --git a/examples/TestExportInterface.cs b/examples/TestExportInterface.cs
new file mode 100644
index 0000000..f46132d
--- /dev/null
+++ b/examples/TestExportInterface.cs
@@ -0,0 +1,305 @@
+// Copyright 2007 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using DBus;
+using org.freedesktop.DBus;
+
+public class ManagedDBusTestExport
+{
+	public static void Main ()
+	{
+		Bus bus = Bus.Session;
+
+		string bus_name = "org.ndesk.test";
+		ObjectPath path = new ObjectPath ("/org/ndesk/test");
+
+		IDemoOne demo;
+
+		if (bus.RequestName (bus_name) == RequestNameReply.PrimaryOwner) {
+			//create a new instance of the object to be exported
+			demo = new Demo ();
+			bus.Register (path, demo);
+
+			//run the main loop
+			while (true)
+				bus.Iterate ();
+		} else {
+			//import a remote to a local proxy
+			//demo = bus.GetObject<IDemo> (bus_name, path);
+			demo = bus.GetObject<DemoProx> (bus_name, path);
+		}
+
+		Console.WriteLine ();
+		demo.SomeEvent += HandleSomeEventA;
+		demo.FireOffSomeEvent ();
+
+		Console.WriteLine ();
+		demo.SomeEvent -= HandleSomeEventA;
+		demo.FireOffSomeEvent ();
+
+		Console.WriteLine ();
+		demo.SomeEvent += delegate (string arg1, object arg2, double arg3, MyTuple mt) {Console.WriteLine ("SomeEvent handler: " + arg1 + ", " + arg2 + ", " + arg3 + ", " + mt.A + ", " + mt.B);};
+		demo.SomeEvent += delegate (string arg1, object arg2, double arg3, MyTuple mt) {Console.WriteLine ("SomeEvent handler two: " + arg1 + ", " + arg2 + ", " + arg3 + ", " + mt.A + ", " + mt.B);};
+		demo.FireOffSomeEvent ();
+
+		Console.WriteLine ();
+
+		Console.WriteLine (demo.GetSomeVariant ());
+
+		Console.WriteLine ();
+
+		demo.Say2 ("demo.Say2");
+		((IDemoTwo)demo).Say2 ("((IDemoTwo)demo).Say2");
+
+		demo.SayEnum (DemoEnum.Bar, DemoEnum.Foo);
+
+		uint n;
+		string ostr;
+		demo.WithOutParameters (out n, "21", out ostr);
+		Console.WriteLine ("n: " + n);
+		Console.WriteLine ("ostr: " + ostr);
+
+		uint[] a1, a2, a3;
+		demo.WithOutParameters2 (out a1, out a2, out a3);
+		Console.WriteLine ("oparam2: " + a2[1]);
+
+		uint[] @contacts = new uint[] { 2 };
+		IDictionary<uint,SimplePresence> presence;
+		demo.GetPresences (contacts, out presence);
+		Console.WriteLine ("pres: " + presence[2].Status);
+
+		MyTuple2 cpx = new MyTuple2 ();
+		cpx.A = "a";
+		cpx.B = "b";
+		cpx.C = new Dictionary<int,MyTuple> ();
+		cpx.C[3] = new MyTuple("foo", "bar");
+		object cpxRet = demo.ComplexAsVariant (cpx, 12);
+		MyTuple2 mt2ret = (MyTuple2)Convert.ChangeType (cpxRet, typeof (MyTuple2));
+		Console.WriteLine ("mt2ret.C[3].B " + mt2ret.C[3].B);
+
+		/*
+		IDemoOne[] objs = demo.GetObjArr ();
+		foreach (IDemoOne obj in objs)
+			obj.Say ("Some obj");
+		*/
+
+		Console.WriteLine("SomeProp: " + demo.SomeProp);
+		demo.SomeProp = 321;
+
+		DemoProx demoProx = demo as DemoProx;
+		if (demoProx != null)
+			demoProx.SayRepeatedly(5, "Repetition");
+
+		demo.ThrowSomeException ();
+	}
+
+	public static void HandleSomeEventA (string arg1, object arg2, double arg3, MyTuple mt)
+	{
+		Console.WriteLine ("SomeEvent handler A: " + arg1 + ", " + arg2 + ", " + arg3 + ", " + mt.A + ", " + mt.B);
+	}
+
+	public static void HandleSomeEventB (string arg1, object arg2, double arg3, MyTuple mt)
+	{
+		Console.WriteLine ("SomeEvent handler B: " + arg1 + ", " + arg2 + ", " + arg3 + ", " + mt.A + ", " + mt.B);
+	}
+}
+
+[Interface ("org.ndesk.test")]
+public interface IDemoOne
+{
+	event SomeEventHandler SomeEvent;
+	void FireOffSomeEvent ();
+	void Say (object var);
+	void SayEnum (DemoEnum a, DemoEnum b);
+	void Say2 (string str);
+	object GetSomeVariant ();
+	void ThrowSomeException ();
+	void WithOutParameters (out uint n, string str, out string ostr);
+	void WithOutParameters2 (out uint[] a1, out uint[] a2, out uint[] a3);
+	void GetPresences (uint[] @contacts, out IDictionary<uint,SimplePresence> @presence);
+	object ComplexAsVariant (object v, int num);
+
+	IDemoOne[] GetEmptyObjArr ();
+	IDemoOne[] GetObjArr ();
+	int SomeProp { get; set; }
+}
+
+[Interface ("org.ndesk.test2")]
+public interface IDemoTwo
+{
+	int Say (string str);
+	void Say2 (string str);
+}
+
+public interface IDemo : IDemoOne, IDemoTwo
+{
+}
+
+public abstract class DemoProx : DemoBase
+{
+	public virtual void SayRepeatedly (int count, string str)
+	{
+		for (int i = 0 ; i != count ; i++)
+			Say2(str);
+	}
+}
+
+public class Demo : DemoBase
+{
+	public override void Say2 (string str)
+	{
+		Console.WriteLine ("Subclassed IDemoOne.Say2: " + str);
+	}
+}
+
+public class DemoBase : IDemo
+{
+	public event SomeEventHandler SomeEvent;
+
+	public void Say (object var)
+	{
+		Console.WriteLine ("variant: " + var);
+	}
+
+	public int Say (string str)
+	{
+		Console.WriteLine ("string: " + str);
+		return str.Length;
+	}
+
+	public void SayEnum (DemoEnum a, DemoEnum b)
+	{
+		Console.WriteLine ("SayEnum: " + a + ", " + b);
+	}
+
+	public virtual void Say2 (string str)
+	{
+		Console.WriteLine ("IDemoOne.Say2: " + str);
+	}
+
+	void IDemoTwo.Say2 (string str)
+	{
+		Console.WriteLine ("IDemoTwo.Say2: " + str);
+	}
+
+	public void FireOffSomeEvent ()
+	{
+		Console.WriteLine ("Asked to fire off SomeEvent");
+
+		MyTuple mt;
+		mt.A = "a";
+		mt.B = "b";
+
+		if (SomeEvent != null) {
+			SomeEvent ("some string", 21, 19.84, mt);
+			Console.WriteLine ("Fired off SomeEvent");
+		}
+	}
+
+	public object GetSomeVariant ()
+	{
+		Console.WriteLine ("GetSomeVariant()");
+
+		return new byte[0];
+	}
+
+	public void ThrowSomeException ()
+	{
+		throw new Exception ("Some exception");
+	}
+
+	public void WithOutParameters (out uint n, string str, out string ostr)
+	{
+		n = UInt32.Parse (str);
+		ostr = "." + str + ".";
+	}
+
+	public void WithOutParameters2 (out uint[] a1, out uint[] a2, out uint[] a3)
+	{
+		a1 = new uint[] { };
+		a2 = new uint[] { 21, 23, 16 };
+		a3 = new uint[] { 21, 23 };
+	}
+
+	public void GetPresences (uint[] @contacts, out IDictionary<uint,SimplePresence> @presence)
+	{
+		Dictionary<uint,SimplePresence> presences = new Dictionary<uint,SimplePresence>();
+		presences[2] = new SimplePresence { Type = ConnectionPresenceType.Offline, Status = "offline", StatusMessage = "" };
+		presence = presences;
+	}
+
+	public object ComplexAsVariant (object v, int num)
+	{
+		Console.WriteLine ("v: " + v);
+		Console.WriteLine ("v null? " + (v == null));
+
+		MyTuple2 mt2 = (MyTuple2)Convert.ChangeType (v, typeof (MyTuple2));
+		Console.WriteLine ("mt2.C[3].B " + mt2.C[3].B);
+		Console.WriteLine ("num: " + num);
+
+		return v;
+	}
+
+	public IDemoOne[] GetEmptyObjArr ()
+	{
+		return new Demo[] {};
+	}
+
+	public IDemoOne[] GetObjArr ()
+	{
+		return new IDemoOne[] {this};
+	}
+
+	public int SomeProp
+	{
+		get {
+			return 123;
+		} set {
+			Console.WriteLine ("Set SomeProp: " + value);
+		}
+	}
+}
+
+public enum DemoEnum : byte
+{
+	Foo,
+	Bar,
+}
+
+
+public struct MyTuple
+{
+	public MyTuple (string a, string b)
+	{
+		A = a;
+		B = b;
+	}
+
+	public string A;
+	public string B;
+}
+
+public struct MyTuple2
+{
+	public string A;
+	public string B;
+	public IDictionary<int,MyTuple> C;
+}
+
+public delegate void SomeEventHandler (string arg1, object arg2, double arg3, MyTuple mt);
+
+public enum ConnectionPresenceType : uint
+{
+	Unset = 0, Offline = 1, Available = 2, Away = 3, ExtendedAway = 4, Hidden = 5, Busy = 6, Unknown = 7, Error = 8, 
+}
+
+public struct SimplePresence
+{
+	public ConnectionPresenceType Type;
+	public string Status;
+	public string StatusMessage;
+}
+
diff --git a/examples/TestNotifications.cs b/examples/TestNotifications.cs
new file mode 100644
index 0000000..e44681d
--- /dev/null
+++ b/examples/TestNotifications.cs
@@ -0,0 +1,39 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+
+using DBus;
+using org.freedesktop;
+using org.freedesktop.DBus;
+
+// Just for fun. A more complete implementation would cover the API at:
+// http://www.galago-project.org/docs/api/libnotify/notification_8h.html
+public class ManagedDBusTestNotifications
+{
+	public static void Main ()
+	{
+		Bus bus = Bus.Session;
+
+		Notifications nf = bus.GetObject<Notifications> ("org.freedesktop.Notifications", new ObjectPath ("/org/freedesktop/Notifications"));
+
+		Console.WriteLine ();
+		Console.WriteLine ("Capabilities:");
+		foreach (string cap in nf.GetCapabilities ())
+			Console.WriteLine ("\t" + cap);
+
+		ServerInformation si = nf.GetServerInformation ();
+
+		//TODO: ability to pass null
+		Dictionary<string,object> hints = new Dictionary<string,object> ();
+
+		string message = String.Format ("Brought to you using {0} {1} (implementing spec version {2}) from {3}.", si.Name, si.Version, si.SpecVersion, si.Vendor);
+
+		uint handle = nf.Notify ("D-Bus# Notifications Demo", 0, "warning", "Managed D-Bus# says 'Hello'!", message, new string[0], hints, 0);
+
+		Console.WriteLine ();
+		Console.WriteLine ("Got handle " + handle);
+	}
+}
diff --git a/examples/TestSample.cs b/examples/TestSample.cs
new file mode 100644
index 0000000..0b6c555
--- /dev/null
+++ b/examples/TestSample.cs
@@ -0,0 +1,54 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using DBus;
+using org.freedesktop.DBus;
+
+public class ManagedDBusTestSample
+{
+	public static void Main ()
+	{
+		Bus bus = Bus.Session;
+
+		SampleInterface sample = bus.GetObject<SampleInterface> ("com.example.SampleService", new ObjectPath ("/SomeObject"));
+
+		Console.WriteLine ();
+		string xmlData = sample.Introspect ();
+		Console.WriteLine ("xmlData: " + xmlData);
+
+		//object obj = sample.HelloWorld ("Hello from example-client.py!");
+		string[] vals = sample.HelloWorld ("Hello from example-client.py!");
+		foreach (string val in vals)
+			Console.WriteLine (val);
+
+		Console.WriteLine ();
+		MyTuple tup = sample.GetTuple ();
+		Console.WriteLine (tup.A);
+		Console.WriteLine (tup.B);
+
+		Console.WriteLine ();
+		IDictionary<string,string> dict = sample.GetDict ();
+		foreach (KeyValuePair<string,string> pair in dict)
+			Console.WriteLine (pair.Key + ": " + pair.Value);
+	}
+}
+
+[Interface ("com.example.SampleInterface")]
+public interface SampleInterface : Introspectable
+{
+	//void HelloWorld (object hello_message);
+	//object HelloWorld (object hello_message);
+	string[] HelloWorld (object hello_message);
+	MyTuple GetTuple ();
+	IDictionary<string,string> GetDict ();
+}
+
+//(ss)
+public struct MyTuple
+{
+	public string A;
+	public string B;
+}
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/missing b/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/src/Address.cs b/src/Address.cs
new file mode 100644
index 0000000..a73c1bb
--- /dev/null
+++ b/src/Address.cs
@@ -0,0 +1,188 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Text;
+using System.Collections.Generic;
+
+namespace DBus
+{
+	// Subclass obsolete BadAddressException to avoid ABI break
+#pragma warning disable 0618
+	//public class InvalidAddressException : Exception
+	public class InvalidAddressException : BadAddressException
+	{
+		public InvalidAddressException (string reason) : base (reason) {}
+	}
+#pragma warning restore 0618
+
+	[Obsolete ("Use InvalidAddressException")]
+	public class BadAddressException : Exception
+	{
+		public BadAddressException (string reason) : base (reason) {}
+	}
+
+	class AddressEntry
+	{
+		public string Method;
+		public readonly IDictionary<string,string> Properties = new Dictionary<string,string> ();
+		public UUID GUID = UUID.Zero;
+
+		public override string ToString ()
+		{
+			StringBuilder sb = new StringBuilder ();
+			sb.Append (Method);
+			sb.Append (':');
+
+			bool first = true;
+			foreach (KeyValuePair<string,string> prop in Properties) {
+				if (first)
+					first = false;
+				else
+					sb.Append (',');
+
+				sb.Append (prop.Key);
+				sb.Append ('=');
+				sb.Append (Escape (prop.Value));
+			}
+
+			if (GUID != UUID.Zero) {
+				if (Properties.Count != 0)
+					sb.Append (',');
+				sb.Append ("guid");
+				sb.Append ('=');
+				sb.Append (GUID.ToString ());
+			}
+
+			return sb.ToString ();
+		}
+
+		static string Escape (string str)
+		{
+			if (str == null)
+				return String.Empty;
+
+			StringBuilder sb = new StringBuilder ();
+			int len = str.Length;
+
+			for (int i = 0 ; i != len ; i++) {
+				char c = str[i];
+
+				//everything other than the optionally escaped chars _must_ be escaped
+				if (Char.IsLetterOrDigit (c) || c == '-' || c == '_' || c == '/' || c == '\\' || c == '.')
+					sb.Append (c);
+				else
+					sb.Append (Uri.HexEscape (c));
+			}
+
+			return sb.ToString ();
+		}
+
+		static string Unescape (string str)
+		{
+			if (str == null)
+				return String.Empty;
+
+			StringBuilder sb = new StringBuilder ();
+			int len = str.Length;
+			int i = 0;
+			while (i != len) {
+				if (Uri.IsHexEncoding (str, i))
+					sb.Append (Uri.HexUnescape (str, ref i));
+				else
+					sb.Append (str[i++]);
+			}
+
+			return sb.ToString ();
+		}
+
+
+		public static AddressEntry Parse (string s)
+		{
+			AddressEntry entry = new AddressEntry ();
+
+			string[] parts = s.Split (':');
+
+			if (parts.Length < 2)
+				throw new InvalidAddressException ("No colon found");
+			if (parts.Length > 2)
+				throw new InvalidAddressException ("Too many colons found");
+
+			entry.Method = parts[0];
+
+			foreach (string propStr in parts[1].Split (',')) {
+				parts = propStr.Split ('=');
+
+				if (parts.Length < 2)
+					throw new InvalidAddressException ("No equals sign found");
+				if (parts.Length > 2)
+					throw new InvalidAddressException ("Too many equals signs found");
+
+				if (parts[0] == "guid") {
+					try {
+						entry.GUID = UUID.Parse (parts[1]);
+					} catch {
+						throw new InvalidAddressException ("Invalid guid specified");
+					}
+					continue;
+				}
+
+				entry.Properties[parts[0]] = Unescape (parts[1]);
+			}
+
+			return entry;
+		}
+	}
+
+	static class Address
+	{
+		//(unix:(path|abstract)=.*,guid=.*|tcp:host=.*(,port=.*)?);? ...
+		public static AddressEntry[] Parse (string addresses)
+		{
+			if (addresses == null)
+				throw new ArgumentNullException (addresses);
+
+			List<AddressEntry> entries = new List<AddressEntry> ();
+
+			foreach (string entryStr in addresses.Split (';'))
+				entries.Add (AddressEntry.Parse (entryStr));
+
+			return entries.ToArray ();
+		}
+
+		const string SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket";
+		public static string System
+		{
+			get {
+				string addr = Environment.GetEnvironmentVariable ("DBUS_SYSTEM_BUS_ADDRESS");
+
+				if (String.IsNullOrEmpty (addr))
+					addr = SYSTEM_BUS_ADDRESS;
+
+				return addr;
+			}
+		}
+
+		public static string Session
+		{
+			get {
+				return Environment.GetEnvironmentVariable ("DBUS_SESSION_BUS_ADDRESS");
+			}
+		}
+
+		public static string Starter
+		{
+			get {
+				return Environment.GetEnvironmentVariable ("DBUS_STARTER_ADDRESS");
+			}
+		}
+
+		public static string StarterBusType
+		{
+			get {
+				return Environment.GetEnvironmentVariable ("DBUS_STARTER_BUS_TYPE");
+			}
+		}
+	}
+}
diff --git a/src/AssemblyInfo.cs.in b/src/AssemblyInfo.cs.in
new file mode 100644
index 0000000..42f9ec0
--- /dev/null
+++ b/src/AssemblyInfo.cs.in
@@ -0,0 +1,27 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyFileVersion("@VERSION@")]
+[assembly: AssemblyInformationalVersion("@VERSION@")]
+[assembly: AssemblyVersion("@API_VERSION@")]
+[assembly: AssemblyTitle ("dbus-sharp")]
+[assembly: AssemblyDescription ("D-Bus IPC protocol library and CLR binding")]
+[assembly: AssemblyCopyright ("Copyright (C) Alp Toker and others")]
+
+#if STRONG_NAME
+[assembly: InternalsVisibleTo ("dbus-sharp-tests, PublicKey=0024000004800000940000000602000000240000525341310004000011000000931ae68c635866ff1dcc22547815bbfd67e3d6e80dbfdc9afe7d079670243b9af245eb9797e0766f8adf6afb5eae1d6716fb46ef25d82c37ac7303fe1d13b90780886e0f7a8208167f16dd4678682d4d793a56ccaf0a233411b7604128ae128e306c959fcd2a8038003b2830a326fda3cbbade2f285a9477f6ff8d194e20a2a5")]
+[assembly: InternalsVisibleTo ("dbus-monitor, PublicKey=0024000004800000940000000602000000240000525341310004000011000000931ae68c635866ff1dcc22547815bbfd67e3d6e80dbfdc9afe7d079670243b9af245eb9797e0766f8adf6afb5eae1d6716fb46ef25d82c37ac7303fe1d13b90780886e0f7a8208167f16dd4678682d4d793a56ccaf0a233411b7604128ae128e306c959fcd2a8038003b2830a326fda3cbbade2f285a9477f6ff8d194e20a2a5")]
+[assembly: InternalsVisibleTo ("dbus-daemon, PublicKey=0024000004800000940000000602000000240000525341310004000011000000931ae68c635866ff1dcc22547815bbfd67e3d6e80dbfdc9afe7d079670243b9af245eb9797e0766f8adf6afb5eae1d6716fb46ef25d82c37ac7303fe1d13b90780886e0f7a8208167f16dd4678682d4d793a56ccaf0a233411b7604128ae128e306c959fcd2a8038003b2830a326fda3cbbade2f285a9477f6ff8d194e20a2a5")]
+[assembly: InternalsVisibleTo ("dbus-sharp-glib, PublicKey=0024000004800000940000000602000000240000525341310004000011000000931ae68c635866ff1dcc22547815bbfd67e3d6e80dbfdc9afe7d079670243b9af245eb9797e0766f8adf6afb5eae1d6716fb46ef25d82c37ac7303fe1d13b90780886e0f7a8208167f16dd4678682d4d793a56ccaf0a233411b7604128ae128e306c959fcd2a8038003b2830a326fda3cbbade2f285a9477f6ff8d194e20a2a5")]
+[assembly: InternalsVisibleTo ("dbus-sharp-proxies, PublicKey=0024000004800000940000000602000000240000525341310004000011000000931ae68c635866ff1dcc22547815bbfd67e3d6e80dbfdc9afe7d079670243b9af245eb9797e0766f8adf6afb5eae1d6716fb46ef25d82c37ac7303fe1d13b90780886e0f7a8208167f16dd4678682d4d793a56ccaf0a233411b7604128ae128e306c959fcd2a8038003b2830a326fda3cbbade2f285a9477f6ff8d194e20a2a5")]
+#else
+[assembly: InternalsVisibleTo ("dbus-sharp-tests")]
+[assembly: InternalsVisibleTo ("dbus-monitor")]
+[assembly: InternalsVisibleTo ("dbus-daemon")]
+[assembly: InternalsVisibleTo ("dbus-sharp-glib")]
+[assembly: InternalsVisibleTo ("dbus-sharp-proxies")]
+#endif
diff --git a/src/Authentication.cs b/src/Authentication.cs
new file mode 100644
index 0000000..cd23945
--- /dev/null
+++ b/src/Authentication.cs
@@ -0,0 +1,538 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Globalization;
+
+namespace DBus
+{
+	using Authentication;
+
+	//using System.Runtime.InteropServices;
+	//[StructLayout (LayoutKind.Sequential)]
+	unsafe struct UUID
+	{
+		private int a, b, c, d;
+		const int ByteLength = 16;
+
+		public static readonly UUID Zero = new UUID ();
+
+		public static bool operator == (UUID a, UUID b)
+		{
+			if (a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d)
+				return true;
+			else
+				return false;
+		}
+
+		public static bool operator != (UUID a, UUID b)
+		{
+			return !(a == b);
+		}
+
+		public override bool Equals (object o)
+		{
+			if (o == null)
+				return false;
+
+			if (!(o is UUID))
+				return false;
+
+			return this == (UUID)o;
+		}
+
+		public override int GetHashCode ()
+		{
+			return a ^ b ^ c ^ d;
+		}
+
+		public override string ToString ()
+		{
+			StringBuilder sb = new StringBuilder (ByteLength * 2);
+
+			fixed (int* p = &a) {
+					byte* bp = (byte*)p;
+					for (int i = 0 ; i != ByteLength ; i++)
+						sb.Append (bp[i].ToString ("x2", CultureInfo.InvariantCulture));
+			}
+
+			return sb.ToString ();
+		}
+
+		public static UUID Parse (string hex)
+		{
+			if (hex.Length != ByteLength * 2)
+				throw new Exception ("Cannot parse UUID/GUID of invalid length");
+
+			UUID id = new UUID ();
+
+			byte* result = (byte*)&id.a;
+			int n = 0, i = 0;
+			while (n < ByteLength) {
+				result[n] = (byte)(Sasl.FromHexChar (hex[i++]) << 4);
+				result[n++] += Sasl.FromHexChar (hex[i++]);
+			}
+
+			return id;
+		}
+
+		static Random rand = new Random ();
+		static byte[] buf = new byte[12];
+		public static UUID Generate (DateTime timestamp)
+		{
+			UUID id = new UUID ();
+
+			lock (buf) {
+				rand.NextBytes (buf);
+				fixed (byte* bp = &buf[0]) {
+					int* p = (int*)bp;
+					id.a = p[0];
+					id.b = p[1];
+					id.c = p[2];
+				}
+			}
+
+			//id.d is assigned to by Timestamp
+			id.Timestamp = timestamp;
+
+			return id;
+		}
+
+		public static UUID Generate ()
+		{
+			return Generate (DateTime.Now);
+		}
+
+		public uint UnixTimestamp
+		{
+			get {
+				uint unixTime;
+
+				fixed (int* ip = &d) {
+					if (BitConverter.IsLittleEndian) {
+						byte* p = (byte*)ip;
+						byte* bp = (byte*)&unixTime;
+						bp[0] = p[3];
+						bp[1] = p[2];
+						bp[2] = p[1];
+						bp[3] = p[0];
+					} else {
+						unixTime = *(uint*)ip;
+					}
+				}
+
+				return unixTime;
+			} set {
+				uint unixTime = value;
+
+				fixed (int* ip = &d) {
+					if (BitConverter.IsLittleEndian) {
+						byte* p = (byte*)&unixTime;
+						byte* bp = (byte*)ip;
+						bp[0] = p[3];
+						bp[1] = p[2];
+						bp[2] = p[1];
+						bp[3] = p[0];
+					} else {
+						*(uint*)ip = unixTime;
+					}
+				}
+			}
+		}
+
+		public DateTime Timestamp
+		{
+			get {
+				return Sasl.UnixToDateTime (UnixTimestamp);
+			} set {
+				UnixTimestamp = (uint)Sasl.DateTimeToUnix (value);
+			}
+		}
+	}
+}
+
+namespace DBus.Authentication
+{
+	enum ClientState
+	{
+		WaitingForData,
+		WaitingForOK,
+		WaitingForReject,
+	}
+
+	enum ServerState
+	{
+		WaitingForAuth,
+		WaitingForData,
+		WaitingForBegin,
+	}
+
+	class AuthCommand
+	{
+		/*
+		public AuthCommand (string value)
+		{
+			//this.Value = value;
+			this.Value = value.Trim ();
+		}
+		*/
+
+
+		public AuthCommand (string value)
+		{
+			//this.Value = value;
+			this.Value = value.Trim ();
+			Args.AddRange (Value.Split (' '));
+		}
+
+		readonly List<string> Args = new List<string> ();
+
+		public string this[int index]
+		{
+			get {
+				if (index >= Args.Count)
+					return String.Empty;
+				return Args[index];
+			}
+		}
+
+		/*
+		public AuthCommand (string value, params string[] args)
+		{
+			if (args.Length == 0)
+				this.Value = value;
+			else
+				this.Value = value + " " + String.Join (" ", args);
+		}
+		*/
+
+		public readonly string Value;
+	}
+
+	class SaslPeer : IEnumerable<AuthCommand>
+	{
+		//public Connection conn;
+		public SaslPeer Peer;
+
+		public Stream stream = null;
+		public bool UseConsole = false;
+
+		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
+		{
+			return GetEnumerator ();
+		}
+
+		internal bool isFinalRead = false;
+
+		public virtual IEnumerator<AuthCommand> GetEnumerator ()
+		{
+			// Read the mandatory null credentials byte
+			/*
+			if (!UseConsole)
+				if (conn.Transport.Stream.ReadByte () != 0)
+					yield break;
+			*/
+
+			TextReader sr;
+			sr = UseConsole ? Console.In : new StreamReader (stream, Encoding.ASCII);
+
+			while (true) {
+				string ln;
+				bool isEnd = false;
+				if (!UseConsole && isFinalRead) {
+					StringBuilder sb = new StringBuilder ();
+
+					while (true) {
+						//MemoryStream ms = new MemoryStream ();
+						// TODO: Use char instead? Check for -1?
+						int a = stream.ReadByte ();
+
+						if (a == -1) {
+							isEnd = true;
+							break;
+						}
+
+						if (a == '\r') {
+							int b = stream.ReadByte ();
+							if (b != '\n')
+								throw new Exception ();
+							break;
+						}
+
+						sb.Append ((char)a);
+					}
+
+					ln = sb.ToString ();
+					//isFinalRead = false;
+				} else {
+					ln = sr.ReadLine ();
+				}
+
+				//if (isEnd && ln == string.Empty)
+				//	yield break;
+				if (ln == null)
+					yield break;
+				if (ln != String.Empty)
+					yield return new AuthCommand (ln);
+				if (isEnd)
+					yield break;
+			}
+		}
+
+		public bool Authenticate ()
+		{
+			return Run (this);
+		}
+
+		public bool AuthenticateSelf ()
+		{
+			//IEnumerator<AuthCommand> a = Peer.GetEnumerator ();
+			IEnumerator<AuthCommand> b = GetEnumerator ();
+			//bool ret = b.MoveNext ();
+			while (b.MoveNext ()) {
+				if (b.Current.Value == "BEGIN")
+					return true;
+			}
+			return false;
+		}
+
+		public virtual bool Run (IEnumerable<AuthCommand> commands)
+		{
+			TextWriter sw;
+			sw = UseConsole ? Console.Out : new StreamWriter (stream, Encoding.ASCII);
+			if (!UseConsole)
+				sw.NewLine = "\r\n";
+
+			foreach (AuthCommand command in commands) {
+				if (command == null) {
+					// Disconnect here?
+					return false;
+				}
+				sw.WriteLine (command.Value);
+				sw.Flush ();
+			}
+
+			return true;
+		}
+	}
+
+	class SaslClient : SaslPeer
+	{
+		public string Identity = String.Empty;
+
+		//static Regex rejectedRegex = new Regex (@"^REJECTED(\s+(\w+))*$");
+
+		// This enables simple support for multiple AUTH schemes
+		enum AuthMech
+		{
+			External,
+			Anonymous,
+			None,
+		}
+
+		public override IEnumerator<AuthCommand> GetEnumerator ()
+		{
+			IEnumerator<AuthCommand> replies = Peer.GetEnumerator ();
+
+			AuthMech currMech = AuthMech.External;
+
+			while (true) {
+				Peer.isFinalRead = false;
+
+				if (currMech == AuthMech.External) {
+					string str = Identity;
+					byte[] bs = Encoding.ASCII.GetBytes (str);
+					string initialData = Sasl.ToHex (bs);
+					yield return new AuthCommand ("AUTH EXTERNAL " + initialData);
+					currMech = AuthMech.Anonymous;
+				} else if (currMech == AuthMech.Anonymous) {
+					yield return new AuthCommand ("AUTH ANONYMOUS");
+					currMech = AuthMech.None;
+				} else {
+					throw new Exception ("Authentication failure");
+				}
+
+				Peer.isFinalRead = true;
+
+				AuthCommand reply;
+				if (!replies.MoveNext ())
+					yield break;
+				reply = replies.Current;
+
+				if (reply[0] == "REJECTED") {
+					continue;
+				}
+
+				/*
+				Match m = rejectedRegex.Match (reply.Value);
+				if (m.Success) {
+					string[] mechanisms = m.Groups[1].Value.Split (' ');
+					//yield return new AuthCommand ("CANCEL");
+					continue;
+				}
+				*/
+
+				if (reply[0] != "OK") {
+					yield return new AuthCommand ("ERROR");
+					continue;
+				}
+
+				if (reply[1] == String.Empty)
+					ActualId = UUID.Zero;
+				else
+					ActualId = UUID.Parse (reply[1]);
+
+				yield return new AuthCommand ("BEGIN");
+				yield break;
+			}
+
+		}
+
+		public UUID ActualId = UUID.Zero;
+	}
+
+	class SaslServer : SaslPeer
+	{
+		//public int MaxFailures = 10;
+		public UUID Guid = UUID.Zero;
+
+		public long uid = 0;
+
+		static Regex authRegex = new Regex (@"^AUTH\s+(\w+)(?:\s+(.*))?$");
+		static string[] supportedMechanisms = {"EXTERNAL"};
+
+		public override IEnumerator<AuthCommand> GetEnumerator ()
+		{
+			IEnumerator<AuthCommand> replies = Peer.GetEnumerator ();
+
+			while (true) {
+				Peer.isFinalRead = false;
+
+				AuthCommand reply;
+				if (!replies.MoveNext ()) {
+					yield return null;
+					yield break;
+					//continue;
+				}
+				reply = replies.Current;
+
+				Match m = authRegex.Match (reply.Value);
+				if (!m.Success) {
+					yield return new AuthCommand ("ERROR");
+					continue;
+				}
+
+				string mechanism = m.Groups[1].Value;
+				string initialResponse = m.Groups[2].Value;
+
+				if (mechanism == "EXTERNAL") {
+					try {
+						byte[] bs = Sasl.FromHex (initialResponse);
+						string authStr = Encoding.ASCII.GetString (bs);
+						uid = UInt32.Parse (authStr);
+					} catch {
+						uid = 0;
+					}
+					//return RunExternal (Run (), initialResponse);
+				} else {
+					yield return new AuthCommand ("REJECTED " + String.Join (" ", supportedMechanisms));
+					continue;
+				}
+
+				if (Guid == UUID.Zero)
+					yield return new AuthCommand ("OK");
+				else
+					yield return new AuthCommand ("OK " + Guid.ToString ());
+
+				Peer.isFinalRead = true;
+
+				if (!replies.MoveNext ()) {
+					/*
+					yield break;
+					continue;
+					*/
+					yield return null;
+					yield break;
+				}
+
+				reply = replies.Current;
+				if (reply.Value != "BEGIN") {
+					yield return new AuthCommand ("ERROR");
+					continue;
+				}
+
+				yield break;
+			}
+		}
+	}
+
+	static class Sasl
+	{
+		//From Mono.Unix.Native.NativeConvert
+		//should these methods use long or (u)int?
+		public static DateTime UnixToDateTime (long time)
+		{
+			DateTime LocalUnixEpoch = new DateTime (1970, 1, 1);
+			TimeSpan LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow);
+			return LocalUnixEpoch.AddSeconds ((double) time + LocalUtcOffset.TotalSeconds);
+		}
+
+		public static long DateTimeToUnix (DateTime time)
+		{
+			DateTime LocalUnixEpoch = new DateTime (1970, 1, 1);
+			TimeSpan LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow);
+			TimeSpan unixTime = time.Subtract (LocalUnixEpoch) - LocalUtcOffset;
+
+			return (long) unixTime.TotalSeconds;
+		}
+
+		//From Mono.Security.Cryptography
+		//Modified to output lowercase hex
+		static public string ToHex (byte[] input)
+		{
+			if (input == null)
+				return null;
+
+			StringBuilder sb = new StringBuilder (input.Length * 2);
+			foreach (byte b in input) {
+				sb.Append (b.ToString ("x2", CultureInfo.InvariantCulture));
+			}
+			return sb.ToString ();
+		}
+
+		//From Mono.Security.Cryptography
+		static public byte FromHexChar (char c)
+		{
+			if ((c >= 'a') && (c <= 'f'))
+				return (byte) (c - 'a' + 10);
+			if ((c >= 'A') && (c <= 'F'))
+				return (byte) (c - 'A' + 10);
+			if ((c >= '0') && (c <= '9'))
+				return (byte) (c - '0');
+			throw new ArgumentException ("Invalid hex char");
+		}
+
+		//From Mono.Security.Cryptography
+		static public byte[] FromHex (string hex)
+		{
+			if (hex == null)
+				return null;
+			if ((hex.Length & 0x1) == 0x1)
+				throw new ArgumentException ("Length must be a multiple of 2");
+
+			byte[] result = new byte [hex.Length >> 1];
+			int n = 0;
+			int i = 0;
+			while (n < result.Length) {
+				result [n] = (byte) (FromHexChar (hex [i++]) << 4);
+				result [n++] += FromHexChar (hex [i++]);
+			}
+			return result;
+		}
+	}
+}
diff --git a/src/Bus.cs b/src/Bus.cs
new file mode 100644
index 0000000..0b44b10
--- /dev/null
+++ b/src/Bus.cs
@@ -0,0 +1,179 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using org.freedesktop.DBus;
+
+namespace DBus
+{
+	public sealed class Bus : Connection
+	{
+		static Bus systemBus = null;
+		public static Bus System
+		{
+			get {
+				if (systemBus == null) {
+					try {
+						if (Address.StarterBusType == "system")
+							systemBus = Starter;
+						else
+							systemBus = Bus.Open (Address.System);
+					} catch (Exception e) {
+						throw new Exception ("Unable to open the system message bus.", e);
+					}
+				}
+
+				return systemBus;
+			}
+		}
+
+		static Bus sessionBus = null;
+		public static Bus Session
+		{
+			get {
+				if (sessionBus == null) {
+					try {
+						if (Address.StarterBusType == "session")
+							sessionBus = Starter;
+						else
+							sessionBus = Bus.Open (Address.Session);
+					} catch (Exception e) {
+						throw new Exception ("Unable to open the session message bus.", e);
+					}
+				}
+
+				return sessionBus;
+			}
+		}
+
+		//TODO: parsing of starter bus type, or maybe do this another way
+		static Bus starterBus = null;
+		public static Bus Starter
+		{
+			get {
+				if (starterBus == null) {
+					try {
+						starterBus = Bus.Open (Address.Starter);
+					} catch (Exception e) {
+						throw new Exception ("Unable to open the starter message bus.", e);
+					}
+				}
+
+				return starterBus;
+			}
+		}
+
+		//public static readonly Bus Session = null;
+
+		//TODO: use the guid, not the whole address string
+		//TODO: consider what happens when a connection has been closed
+		static Dictionary<string,Bus> buses = new Dictionary<string,Bus> ();
+
+		//public static Connection Open (string address)
+		public static new Bus Open (string address)
+		{
+			if (address == null)
+				throw new ArgumentNullException ("address");
+
+			Bus bus;
+			if (buses.TryGetValue (address, out bus))
+				return bus;
+
+			bus = new Bus (address);
+			buses[address] = bus;
+
+			return bus;
+		}
+
+		IBus bus;
+
+		static readonly string DBusName = "org.freedesktop.DBus";
+		static readonly ObjectPath DBusPath = new ObjectPath ("/org/freedesktop/DBus");
+
+		public Bus (string address) : base (address)
+		{
+			bus = GetObject<IBus> (DBusName, DBusPath);
+
+			/*
+					bus.NameAcquired += delegate (string acquired_name) {
+			Console.WriteLine ("NameAcquired: " + acquired_name);
+		};
+		*/
+			Register ();
+		}
+
+		//should this be public?
+		//as long as Bus subclasses Connection, having a Register with a completely different meaning is bad
+		void Register ()
+		{
+			if (unique_name != null)
+				throw new Exception ("Bus already has a unique name");
+
+			unique_name = bus.Hello ();
+		}
+
+		public ulong GetUnixUser (string name)
+		{
+			return bus.GetConnectionUnixUser (name);
+		}
+
+		public RequestNameReply RequestName (string name)
+		{
+			return RequestName (name, NameFlag.None);
+		}
+
+		public RequestNameReply RequestName (string name, NameFlag flags)
+		{
+			return bus.RequestName (name, flags);
+		}
+
+		public ReleaseNameReply ReleaseName (string name)
+		{
+			return bus.ReleaseName (name);
+		}
+
+		public bool NameHasOwner (string name)
+		{
+			return bus.NameHasOwner (name);
+		}
+
+		public StartReply StartServiceByName (string name)
+		{
+			return StartServiceByName (name, 0);
+		}
+
+		public StartReply StartServiceByName (string name, uint flags)
+		{
+			return bus.StartServiceByName (name, flags);
+		}
+
+		internal protected override void AddMatch (string rule)
+		{
+			bus.AddMatch (rule);
+		}
+
+		internal protected override void RemoveMatch (string rule)
+		{
+			bus.RemoveMatch (rule);
+		}
+
+		public string GetId ()
+		{
+			return bus.GetId ();
+		}
+
+		string unique_name = null;
+		public string UniqueName
+		{
+			get {
+				return unique_name;
+			} set {
+				if (unique_name != null)
+					throw new Exception ("Unique name can only be set once");
+				unique_name = value;
+			}
+		}
+	}
+}
diff --git a/src/BusObject.cs b/src/BusObject.cs
new file mode 100644
index 0000000..e12207e
--- /dev/null
+++ b/src/BusObject.cs
@@ -0,0 +1,402 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections.Generic;
+
+namespace DBus
+{
+	class BusObject
+	{
+		protected Connection conn;
+		string bus_name;
+		string alt_bus_name;
+		ObjectPath object_path;
+
+		//protected BusObject ()
+		public BusObject ()
+		{
+		}
+
+		public BusObject (Connection conn, string bus_name, ObjectPath object_path)
+		{
+			this.conn = conn;
+			this.bus_name = bus_name;
+			this.object_path = object_path;
+		}
+
+		public Connection Connection
+		{
+			get {
+				return conn;
+			}
+		}
+
+		public string BusName
+		{
+			get {
+				return bus_name;
+			}
+		}
+
+		public ObjectPath Path
+		{
+			get {
+				return object_path;
+			}
+		}
+
+		public void ToggleSignal (string iface, string member, Delegate dlg, bool adding)
+		{
+			MatchRule rule = new MatchRule ();
+			rule.MessageType = MessageType.Signal;
+			rule.Fields.Add (FieldCode.Interface, new MatchTest (iface));
+			rule.Fields.Add (FieldCode.Member, new MatchTest (member));
+			rule.Fields.Add (FieldCode.Path, new MatchTest (object_path));
+			rule.Fields.Add (FieldCode.Sender, new MatchTest (alt_bus_name ?? bus_name));
+
+			if (adding) {
+				if (conn.Handlers.ContainsKey (rule))
+					conn.Handlers[rule] = Delegate.Combine (conn.Handlers[rule], dlg);
+				else {
+					conn.Handlers[rule] = dlg;
+					conn.AddMatch (rule.ToString ());
+				}
+			} else if (conn.Handlers.ContainsKey (rule)) {
+				conn.Handlers[rule] = Delegate.Remove (conn.Handlers[rule], dlg);
+				if (conn.Handlers[rule] == null) {
+					conn.RemoveMatch (rule.ToString ());
+					conn.Handlers.Remove (rule);
+				}
+			}
+		}
+
+		public void SendSignal (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
+		{
+			exception = null;
+
+			//TODO: don't ignore retVal, exception etc.
+
+			Signature outSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);
+
+			Signal signal = new Signal (object_path, iface, member);
+			signal.message.Signature = outSig;
+
+			Message signalMsg = signal.message;
+			signalMsg.Body = writer.ToArray ();
+
+			conn.Send (signalMsg);
+		}
+
+		public object SendMethodCallOld (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
+		{
+			exception = null;
+
+			//TODO: don't ignore retVal, exception etc.
+
+			Signature inSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);
+
+			MethodCall method_call = new MethodCall (object_path, iface, member, bus_name, inSig);
+
+			Message callMsg = method_call.message;
+			callMsg.Body = writer.ToArray ();
+
+			//Invoke Code::
+
+			//TODO: complete out parameter support
+			/*
+			Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
+			Signature outParmSig = Signature.GetSig (outParmTypes);
+
+			if (outParmSig != Signature.Empty)
+				throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
+			*/
+
+			Type[] outTypes = new Type[1];
+			outTypes[0] = retType;
+
+			//we default to always requiring replies for now, even though unnecessary
+			//this is to make sure errors are handled synchronously
+			//TODO: don't hard code this
+			bool needsReply = true;
+
+			//if (mi.ReturnType == typeof (void))
+			//	needsReply = false;
+
+			callMsg.ReplyExpected = needsReply;
+			callMsg.Signature = inSig;
+
+			if (!needsReply) {
+				conn.Send (callMsg);
+				return null;
+			}
+
+#if PROTO_REPLY_SIGNATURE
+			if (needsReply) {
+				Signature outSig = Signature.GetSig (outTypes);
+				callMsg.Header[FieldCode.ReplySignature] = outSig;
+			}
+#endif
+
+			Message retMsg = conn.SendWithReplyAndBlock (callMsg);
+
+			object retVal = null;
+
+			//handle the reply message
+			switch (retMsg.Header.MessageType) {
+				case MessageType.MethodReturn:
+				object[] retVals = MessageHelper.GetDynamicValues (retMsg, outTypes);
+				if (retVals.Length != 0)
+					retVal = retVals[retVals.Length - 1];
+				break;
+				case MessageType.Error:
+				//TODO: typed exceptions
+				Error error = new Error (retMsg);
+				string errMsg = String.Empty;
+				if (retMsg.Signature.Value.StartsWith ("s")) {
+					MessageReader reader = new MessageReader (retMsg);
+					errMsg = reader.ReadString ();
+				}
+				exception = new Exception (error.ErrorName + ": " + errMsg);
+				break;
+				default:
+				throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
+			}
+
+			return retVal;
+		}
+
+		public MessageReader SendMethodCall (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
+		{
+			exception = null;
+
+			//TODO: don't ignore retVal, exception etc.
+
+			Signature inSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);
+
+			MethodCall method_call = new MethodCall (object_path, iface, member, bus_name, inSig);
+
+			Message callMsg = method_call.message;
+			callMsg.Body = writer.ToArray ();
+
+			//Invoke Code::
+
+			//TODO: complete out parameter support
+			/*
+			Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
+			Signature outParmSig = Signature.GetSig (outParmTypes);
+
+			if (outParmSig != Signature.Empty)
+				throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
+			*/
+
+			Type[] outTypes = new Type[1];
+			outTypes[0] = retType;
+
+			//we default to always requiring replies for now, even though unnecessary
+			//this is to make sure errors are handled synchronously
+			//TODO: don't hard code this
+			bool needsReply = true;
+
+			//if (mi.ReturnType == typeof (void))
+			//	needsReply = false;
+
+			callMsg.ReplyExpected = needsReply;
+			callMsg.Signature = inSig;
+
+			if (!needsReply) {
+				conn.Send (callMsg);
+				return null;
+			}
+
+#if PROTO_REPLY_SIGNATURE
+			if (needsReply) {
+				Signature outSig = Signature.GetSig (outTypes);
+				callMsg.Header[FieldCode.ReplySignature] = outSig;
+			}
+#endif
+
+			Message retMsg = conn.SendWithReplyAndBlock (callMsg);
+
+			MessageReader retVal = null;
+
+			//handle the reply message
+			switch (retMsg.Header.MessageType) {
+				case MessageType.MethodReturn:
+				if ((string)retMsg.Header[FieldCode.Sender] != bus_name)
+					alt_bus_name = (string)retMsg.Header[FieldCode.Sender];
+					retVal = new MessageReader (retMsg);
+				break;
+				case MessageType.Error:
+				//TODO: typed exceptions
+				Error error = new Error (retMsg);
+				string errMsg = String.Empty;
+				if (retMsg.Signature.Value.StartsWith ("s")) {
+					MessageReader reader = new MessageReader (retMsg);
+					errMsg = reader.ReadString ();
+				}
+				exception = new Exception (error.ErrorName + ": " + errMsg);
+				break;
+				default:
+				throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
+			}
+
+			return retVal;
+		}
+
+		public void Invoke (MethodBase methodBase, string methodName, object[] inArgs, out object[] outArgs, out object retVal, out Exception exception)
+		{
+			outArgs = new object[0];
+			retVal = null;
+			exception = null;
+
+			MethodInfo mi = methodBase as MethodInfo;
+
+			if (mi != null && mi.IsSpecialName && (methodName.StartsWith ("add_") || methodName.StartsWith ("remove_"))) {
+				string[] parts = methodName.Split (new char[]{'_'}, 2);
+				string ename = parts[1];
+				Delegate dlg = (Delegate)inArgs[0];
+
+				ToggleSignal (Mapper.GetInterfaceName (mi), ename, dlg, parts[0] == "add");
+
+				return;
+			}
+
+			Type[] inTypes = Mapper.GetTypes (ArgDirection.In, mi.GetParameters ());
+			Signature inSig = Signature.GetSig (inTypes);
+
+			MethodCall method_call;
+			Message callMsg;
+
+			//build the outbound method call message
+			{
+				//this bit is error-prone (no null checking) and will need rewriting when DProxy is replaced
+				string iface = null;
+				if (mi != null)
+					iface = Mapper.GetInterfaceName (mi);
+
+				//map property accessors
+				//TODO: this needs to be done properly, not with simple String.Replace
+				//note that IsSpecialName is also for event accessors, but we already handled those and returned
+				if (mi != null && mi.IsSpecialName) {
+					methodName = methodName.Replace ("get_", "Get");
+					methodName = methodName.Replace ("set_", "Set");
+				}
+
+				method_call = new MethodCall (object_path, iface, methodName, bus_name, inSig);
+
+				callMsg = method_call.message;
+
+				if (inArgs != null && inArgs.Length != 0) {
+					MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
+					writer.connection = conn;
+
+					for (int i = 0 ; i != inTypes.Length ; i++)
+						writer.Write (inTypes[i], inArgs[i]);
+
+					callMsg.Body = writer.ToArray ();
+				}
+			}
+
+			//TODO: complete out parameter support
+			/*
+			Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
+			Signature outParmSig = Signature.GetSig (outParmTypes);
+
+			if (outParmSig != Signature.Empty)
+				throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
+			*/
+
+			Type[] outTypes = new Type[1];
+			outTypes[0] = mi.ReturnType;
+
+			//we default to always requiring replies for now, even though unnecessary
+			//this is to make sure errors are handled synchronously
+			//TODO: don't hard code this
+			bool needsReply = true;
+
+			//if (mi.ReturnType == typeof (void))
+			//	needsReply = false;
+
+			callMsg.ReplyExpected = needsReply;
+			callMsg.Signature = inSig;
+
+			if (!needsReply) {
+				conn.Send (callMsg);
+				return;
+			}
+
+#if PROTO_REPLY_SIGNATURE
+			if (needsReply) {
+				Signature outSig = Signature.GetSig (outTypes);
+				callMsg.Header[FieldCode.ReplySignature] = outSig;
+			}
+#endif
+
+			Message retMsg = conn.SendWithReplyAndBlock (callMsg);
+
+			//handle the reply message
+			switch (retMsg.Header.MessageType) {
+				case MessageType.MethodReturn:
+				object[] retVals = MessageHelper.GetDynamicValues (retMsg, outTypes);
+				if (retVals.Length != 0)
+					retVal = retVals[retVals.Length - 1];
+				break;
+				case MessageType.Error:
+				//TODO: typed exceptions
+				Error error = new Error (retMsg);
+				string errMsg = String.Empty;
+				if (retMsg.Signature.Value.StartsWith ("s")) {
+					MessageReader reader = new MessageReader (retMsg);
+					errMsg = reader.ReadString ();
+				}
+				exception = new Exception (error.ErrorName + ": " + errMsg);
+				break;
+				default:
+				throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
+			}
+
+			return;
+		}
+
+		public static object GetObject (Connection conn, string bus_name, ObjectPath object_path, Type declType)
+		{
+			Type proxyType = TypeImplementer.Root.GetImplementation (declType);
+
+			//BusObject inst = (BusObject)Activator.CreateInstance (proxyType);
+			object instObj = Activator.CreateInstance (proxyType);
+			BusObject inst = GetBusObject (instObj);
+			inst.conn = conn;
+			inst.bus_name = bus_name;
+			inst.object_path = object_path;
+
+			return instObj;
+		}
+
+		static Dictionary<object,BusObject> boCache = new Dictionary<object,BusObject>();
+		public static BusObject GetBusObject (object instObj)
+		{
+			if (instObj is BusObject)
+				return (BusObject)instObj;
+
+			BusObject inst;
+			if (boCache.TryGetValue (instObj, out inst))
+				return inst;
+
+			inst = new BusObject ();
+			boCache[instObj] = inst;
+
+			return inst;
+		}
+
+		public Delegate GetHookupDelegate (EventInfo ei)
+		{
+			DynamicMethod hookupMethod = TypeImplementer.GetHookupMethod (ei);
+			Delegate d = hookupMethod.CreateDelegate (ei.EventHandlerType, this);
+			return d;
+		}
+	}
+}
diff --git a/src/Connection.cs b/src/Connection.cs
new file mode 100644
index 0000000..4ad1ce9
--- /dev/null
+++ b/src/Connection.cs
@@ -0,0 +1,507 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Reflection;
+
+namespace DBus
+{
+	using Authentication;
+	using Transports;
+
+	public partial class Connection
+	{
+		Transport transport;
+		internal Transport Transport {
+			get {
+				return transport;
+			} set {
+				transport = value;
+				transport.Connection = this;
+			}
+		}
+
+		protected Connection () {}
+
+		internal Connection (Transport transport)
+		{
+			this.transport = transport;
+			transport.Connection = this;
+		}
+
+		//should this be public?
+		internal Connection (string address)
+		{
+			OpenPrivate (address);
+			Authenticate ();
+		}
+
+		internal bool isConnected = false;
+		public bool IsConnected
+		{
+			get {
+				return isConnected;
+			}
+		}
+
+		// TODO: Complete disconnection support
+		internal bool isShared = false;
+		public void Close ()
+		{
+			if (isShared)
+				throw new Exception ("Cannot disconnect a shared Connection");
+
+			if (!IsConnected)
+				return;
+
+			transport.Disconnect ();
+			isConnected = false;
+		}
+
+		//should we do connection sharing here?
+		public static Connection Open (string address)
+		{
+			Connection conn = new Connection ();
+			conn.OpenPrivate (address);
+			conn.Authenticate ();
+
+			return conn;
+		}
+
+		internal void OpenPrivate (string address)
+		{
+			if (address == null)
+				throw new ArgumentNullException ("address");
+
+			AddressEntry[] entries = Address.Parse (address);
+			if (entries.Length == 0)
+				throw new Exception ("No addresses were found");
+
+			//TODO: try alternative addresses if needed
+			AddressEntry entry = entries[0];
+
+			Id = entry.GUID;
+			Transport = Transport.Create (entry);
+			isConnected = true;
+		}
+
+		internal UUID Id = UUID.Zero;
+
+		void Authenticate ()
+		{
+			if (transport != null)
+				transport.WriteCred ();
+
+			SaslClient auth = new SaslClient ();
+			auth.Identity = transport.AuthString ();
+			auth.stream = transport.Stream;
+			auth.Peer = new SaslPeer ();
+			auth.Peer.Peer = auth;
+			auth.Peer.stream = transport.Stream;
+
+			if (!auth.Authenticate ())
+				throw new Exception ("Authentication failure");
+
+			if (Id != UUID.Zero)
+				if (auth.ActualId != Id)
+					throw new Exception ("Authentication failure: Unexpected GUID");
+
+			if (Id == UUID.Zero)
+				Id = auth.ActualId;
+
+			isAuthenticated = true;
+		}
+
+		internal bool isAuthenticated = false;
+		internal bool IsAuthenticated
+		{
+			get {
+				return isAuthenticated;
+			}
+		}
+
+		//Interlocked.Increment() handles the overflow condition for uint correctly, so it's ok to store the value as an int but cast it to uint
+		int serial = 0;
+		internal uint GenerateSerial ()
+		{
+			return (uint)Interlocked.Increment (ref serial);
+		}
+
+		internal Message SendWithReplyAndBlock (Message msg)
+		{
+			PendingCall pending = SendWithReply (msg);
+			return pending.Reply;
+		}
+
+		internal PendingCall SendWithReply (Message msg)
+		{
+			msg.ReplyExpected = true;
+
+			if (msg.Header.Serial == 0)
+				msg.Header.Serial = GenerateSerial ();
+
+			// Should we throttle the maximum number of concurrent PendingCalls?
+			// Should we support timeouts?
+			PendingCall pending = new PendingCall (this);
+			lock (pendingCalls)
+				pendingCalls[msg.Header.Serial] = pending;
+
+			Send (msg);
+
+			return pending;
+		}
+
+		internal virtual uint Send (Message msg)
+		{
+			if (msg.Header.Serial == 0)
+				msg.Header.Serial = GenerateSerial ();
+
+			transport.WriteMessage (msg);
+
+			return msg.Header.Serial;
+		}
+
+		Queue<Message> Inbound = new Queue<Message> ();
+
+		//temporary hack
+		internal void DispatchSignals ()
+		{
+			lock (Inbound) {
+				while (Inbound.Count != 0) {
+					Message msg = Inbound.Dequeue ();
+					HandleSignal (msg);
+				}
+			}
+		}
+
+		internal Thread mainThread = Thread.CurrentThread;
+
+		//temporary hack
+		public void Iterate ()
+		{
+			mainThread = Thread.CurrentThread;
+
+			Message msg = transport.ReadMessage ();
+
+			HandleMessage (msg);
+			DispatchSignals ();
+		}
+
+		internal void Dispatch ()
+		{
+			while (transport.Inbound.Count != 0) {
+				Message msg = transport.Inbound.Dequeue ();
+				HandleMessage (msg);
+			}
+			DispatchSignals ();
+		}
+
+		internal virtual void HandleMessage (Message msg)
+		{
+			if (msg == null)
+				return;
+
+			//TODO: support disconnection situations properly and move this check elsewhere
+			if (msg == null)
+				throw new ArgumentNullException ("msg", "Cannot handle a null message; maybe the bus was disconnected");
+
+			//TODO: Restrict messages to Local ObjectPath?
+
+			{
+				object field_value = msg.Header[FieldCode.ReplySerial];
+				if (field_value != null) {
+					uint reply_serial = (uint)field_value;
+					PendingCall pending;
+
+					lock (pendingCalls) {
+						if (pendingCalls.TryGetValue (reply_serial, out pending)) {
+							if (pendingCalls.Remove (reply_serial))
+								pending.Reply = msg;
+
+							return;
+						}
+					}
+
+					//we discard reply messages with no corresponding PendingCall
+					if (Protocol.Verbose)
+						Console.Error.WriteLine ("Unexpected reply message received: MessageType='" + msg.Header.MessageType + "', ReplySerial=" + reply_serial);
+
+					return;
+				}
+			}
+
+			switch (msg.Header.MessageType) {
+				case MessageType.MethodCall:
+					MethodCall method_call = new MethodCall (msg);
+					HandleMethodCall (method_call);
+					break;
+				case MessageType.Signal:
+					//HandleSignal (msg);
+					lock (Inbound)
+						Inbound.Enqueue (msg);
+					break;
+				case MessageType.Error:
+					//TODO: better exception handling
+					Error error = new Error (msg);
+					string errMsg = String.Empty;
+					if (msg.Signature.Value.StartsWith ("s")) {
+						MessageReader reader = new MessageReader (msg);
+						errMsg = reader.ReadString ();
+					}
+					Console.Error.WriteLine ("Remote Error: Signature='" + msg.Signature.Value + "' " + error.ErrorName + ": " + errMsg);
+					break;
+				case MessageType.Invalid:
+				default:
+					throw new Exception ("Invalid message received: MessageType='" + msg.Header.MessageType + "'");
+			}
+		}
+
+		Dictionary<uint,PendingCall> pendingCalls = new Dictionary<uint,PendingCall> ();
+
+		//this might need reworking with MulticastDelegate
+		internal void HandleSignal (Message msg)
+		{
+			Signal signal = new Signal (msg);
+
+			//TODO: this is a hack, not necessary when MatchRule is complete
+			MatchRule rule = new MatchRule ();
+			rule.MessageType = MessageType.Signal;
+			rule.Fields.Add (FieldCode.Interface, new MatchTest (signal.Interface));
+			rule.Fields.Add (FieldCode.Member, new MatchTest (signal.Member));
+			rule.Fields.Add (FieldCode.Sender, new MatchTest (signal.Sender));
+			rule.Fields.Add (FieldCode.Path, new MatchTest (signal.Path));
+
+			Delegate dlg;
+			if (Handlers.TryGetValue (rule, out dlg) && dlg != null) {
+				MethodInfo mi = dlg.GetType ().GetMethod ("Invoke");
+
+				bool compatible = false;
+				Signature inSig, outSig;
+
+				if (TypeImplementer.SigsForMethod(mi, out inSig, out outSig))
+					if (outSig == Signature.Empty && inSig == msg.Signature)
+						compatible = true;
+
+				if (!compatible) {
+					if (Protocol.Verbose)
+						Console.Error.WriteLine ("Signal argument mismatch: " + signal.Interface + '.' + signal.Member);
+					return;
+				}
+
+				//signals have no return value
+				dlg.DynamicInvoke (MessageHelper.GetDynamicValues (msg, mi.GetParameters ()));
+			} else {
+				//TODO: how should we handle this condition? sending an Error may not be appropriate in this case
+				if (Protocol.Verbose)
+					Console.Error.WriteLine ("Warning: No signal handler for " + signal.Member);
+			}
+		}
+
+		internal Dictionary<MatchRule,Delegate> Handlers = new Dictionary<MatchRule,Delegate> ();
+
+		//very messy
+		internal void MaybeSendUnknownMethodError (MethodCall method_call)
+		{
+			Message msg = MessageHelper.CreateUnknownMethodError (method_call);
+			if (msg != null)
+				Send (msg);
+		}
+
+		//not particularly efficient and needs to be generalized
+		internal void HandleMethodCall (MethodCall method_call)
+		{
+			//TODO: Ping and Introspect need to be abstracted and moved somewhere more appropriate once message filter infrastructure is complete
+
+			//FIXME: these special cases are slightly broken for the case where the member but not the interface is specified in the message
+			if (method_call.Interface == "org.freedesktop.DBus.Peer") {
+				switch (method_call.Member) {
+					case "Ping":
+						Send (MessageHelper.ConstructReply (method_call));
+						return;
+					case "GetMachineId":
+						if (MachineId != UUID.Zero) {
+							Send (MessageHelper.ConstructReply (method_call, MachineId.ToString ()));
+							return;
+						} else {
+							// Might want to send back an error here?
+						}
+						break;
+				}
+			}
+
+			if (method_call.Interface == "org.freedesktop.DBus.Introspectable" && method_call.Member == "Introspect") {
+				Introspector intro = new Introspector ();
+				intro.root_path = method_call.Path;
+				intro.WriteStart ();
+
+				//FIXME: do this properly
+				//this is messy and inefficient
+				List<string> linkNodes = new List<string> ();
+				int depth = method_call.Path.Decomposed.Length;
+				foreach (ObjectPath pth in RegisteredObjects.Keys) {
+					if (pth.Value == (method_call.Path.Value)) {
+						ExportObject exo = (ExportObject)RegisteredObjects[pth];
+						exo.WriteIntrospect (intro);
+					} else {
+						for (ObjectPath cur = pth ; cur != null ; cur = cur.Parent) {
+							if (cur.Value == method_call.Path.Value) {
+								string linkNode = pth.Decomposed[depth];
+								if (!linkNodes.Contains (linkNode)) {
+									intro.WriteNode (linkNode);
+									linkNodes.Add (linkNode);
+								}
+							}
+						}
+					}
+				}
+
+				intro.WriteEnd ();
+
+				Message reply = MessageHelper.ConstructReply (method_call, intro.xml);
+				Send (reply);
+				return;
+			}
+
+			BusObject bo;
+			if (RegisteredObjects.TryGetValue (method_call.Path, out bo)) {
+				ExportObject eo = (ExportObject)bo;
+				eo.HandleMethodCall (method_call);
+			} else {
+				MaybeSendUnknownMethodError (method_call);
+			}
+		}
+
+		Dictionary<ObjectPath,BusObject> RegisteredObjects = new Dictionary<ObjectPath,BusObject> ();
+
+		//FIXME: this shouldn't be part of the core API
+		//that also applies to much of the other object mapping code
+
+		public object GetObject (Type type, string bus_name, ObjectPath path)
+		{
+			//if (type == null)
+			//	return GetObject (bus_name, path);
+
+			//if the requested type is an interface, we can implement it efficiently
+			//otherwise we fall back to using a transparent proxy
+			if (type.IsInterface || type.IsAbstract) {
+				return BusObject.GetObject (this, bus_name, path, type);
+			} else {
+				if (Protocol.Verbose)
+					Console.Error.WriteLine ("Warning: Note that MarshalByRefObject use is not recommended; for best performance, define interfaces");
+
+				BusObject busObject = new BusObject (this, bus_name, path);
+				DProxy prox = new DProxy (busObject, type);
+				return prox.GetTransparentProxy ();
+			}
+		}
+
+		public T GetObject<T> (string bus_name, ObjectPath path)
+		{
+			return (T)GetObject (typeof (T), bus_name, path);
+		}
+
+		[Obsolete ("Use the overload of Register() which does not take a bus_name parameter")]
+		public void Register (string bus_name, ObjectPath path, object obj)
+		{
+			Register (path, obj);
+		}
+
+		[Obsolete ("Use the overload of Unregister() which does not take a bus_name parameter")]
+		public object Unregister (string bus_name, ObjectPath path)
+		{
+			return Unregister (path);
+		}
+
+		public void Register (ObjectPath path, object obj)
+		{
+			ExportObject eo = ExportObject.CreateExportObject (this, path, obj);
+			eo.Registered = true;
+
+			//TODO: implement some kind of tree data structure or internal object hierarchy. right now we are ignoring the name and putting all object paths in one namespace, which is bad
+			RegisteredObjects[path] = eo;
+		}
+
+		public object Unregister (ObjectPath path)
+		{
+			BusObject bo;
+
+			if (!RegisteredObjects.TryGetValue (path, out bo))
+				throw new Exception ("Cannot unregister " + path + " as it isn't registered");
+
+			RegisteredObjects.Remove (path);
+
+			ExportObject eo = (ExportObject)bo;
+			eo.Registered = false;
+
+			return eo.obj;
+		}
+
+		//these look out of place, but are useful
+		internal protected virtual void AddMatch (string rule)
+		{
+		}
+
+		internal protected virtual void RemoveMatch (string rule)
+		{
+		}
+
+		// Maybe we should use XDG/basedir or check an env var for this?
+		const string machineUuidFilename = @"/var/lib/dbus/machine-id";
+		static UUID? machineId = null;
+		private static object idReadLock = new object ();
+		internal static UUID MachineId
+		{
+			get {
+				lock (idReadLock) {
+					if (machineId != null)
+						return (UUID)machineId;
+					try {
+						machineId = ReadMachineId (machineUuidFilename);
+					} catch {
+						machineId = UUID.Zero;
+					}
+					return (UUID)machineId;
+				}
+			}
+		}
+
+		static UUID ReadMachineId (string fname)
+		{
+			using (FileStream fs = File.OpenRead (fname)) {
+				// Length is typically 33 (32 for the UUID, plus a linefeed)
+				//if (fs.Length < 32)
+				//	return UUID.Zero;
+
+				byte[] data = new byte[32];
+
+				int pos = 0;
+				while (pos < data.Length) {
+					int read = fs.Read (data, pos, data.Length - pos);
+					if (read == 0)
+						break;
+					pos += read;
+				}
+
+				if (pos != data.Length)
+					//return UUID.Zero;
+					throw new Exception ("Insufficient data while reading GUID string");
+
+				return UUID.Parse (System.Text.Encoding.ASCII.GetString (data));
+			}
+		}
+
+		static Connection ()
+		{
+			if (BitConverter.IsLittleEndian)
+				NativeEndianness = EndianFlag.Little;
+			else
+				NativeEndianness = EndianFlag.Big;
+		}
+
+		internal static readonly EndianFlag NativeEndianness;
+	}
+}
diff --git a/src/DBus.cs b/src/DBus.cs
new file mode 100644
index 0000000..262f299
--- /dev/null
+++ b/src/DBus.cs
@@ -0,0 +1,98 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using DBus;
+
+namespace org.freedesktop.DBus
+{
+	[Flags]
+	public enum NameFlag : uint
+	{
+		None = 0,
+		AllowReplacement = 0x1,
+		ReplaceExisting = 0x2,
+		DoNotQueue = 0x4,
+	}
+
+	public enum RequestNameReply : uint
+	{
+		PrimaryOwner = 1,
+		InQueue,
+		Exists,
+		AlreadyOwner,
+	}
+
+	public enum ReleaseNameReply : uint
+	{
+		Released = 1,
+		NonExistent,
+		NotOwner,
+	}
+
+	public enum StartReply : uint
+	{
+		//The service was successfully started.
+		Success = 1,
+		//A connection already owns the given name.
+		AlreadyRunning,
+	}
+
+	public delegate void NameOwnerChangedHandler (string name, string old_owner, string new_owner);
+	public delegate void NameAcquiredHandler (string name);
+	public delegate void NameLostHandler (string name);
+
+	[Interface ("org.freedesktop.DBus.Peer")]
+	public interface Peer
+	{
+		void Ping ();
+		[return: Argument ("machine_uuid")]
+		string GetMachineId ();
+	}
+
+	[Interface ("org.freedesktop.DBus.Introspectable")]
+	public interface Introspectable
+	{
+		[return: Argument ("data")]
+		string Introspect ();
+	}
+
+	[Interface ("org.freedesktop.DBus.Properties")]
+	public interface Properties
+	{
+		[return: Argument ("value")]
+		object Get (string @interface, string propname);
+		void Set (string @interface, string propname, object value);
+		[return: Argument ("props")]
+		IDictionary<string,object> GetAll (string @interface);
+	}
+
+	[Interface ("org.freedesktop.DBus")]
+	public interface IBus
+	{
+		RequestNameReply RequestName (string name, NameFlag flags);
+		ReleaseNameReply ReleaseName (string name);
+		string Hello ();
+		string[] ListNames ();
+		string[] ListActivatableNames ();
+		bool NameHasOwner (string name);
+		event NameOwnerChangedHandler NameOwnerChanged;
+		event NameLostHandler NameLost;
+		event NameAcquiredHandler NameAcquired;
+		StartReply StartServiceByName (string name, uint flags);
+		void UpdateActivationEnvironment (IDictionary<string, string> environment);
+		string GetNameOwner (string name);
+		uint GetConnectionUnixUser (string connection_name);
+		void AddMatch (string rule);
+		void RemoveMatch (string rule);
+		string GetId ();
+
+		//undocumented in spec
+		string[] ListQueuedOwners (string name);
+		uint GetConnectionUnixProcessID (string connection_name);
+		byte[] GetConnectionSELinuxSecurityContext (string connection_name);
+		void ReloadConfig ();
+	}
+}
diff --git a/src/DProxy.cs b/src/DProxy.cs
new file mode 100644
index 0000000..8b0b7ab
--- /dev/null
+++ b/src/DProxy.cs
@@ -0,0 +1,79 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Reflection;
+using System.Runtime.Remoting.Proxies;
+using System.Runtime.Remoting.Messaging;
+
+namespace DBus
+{
+	//marked internal because this is really an implementation detail and needs to be replaced
+	internal class DProxy : RealProxy
+	{
+		protected BusObject busObject;
+
+		public DProxy (BusObject busObject, Type type) : base(type)
+		{
+			this.busObject = busObject;
+		}
+
+		static MethodInfo mi_GetHashCode = typeof (object).GetMethod ("GetHashCode");
+		static MethodInfo mi_Equals = typeof (object).GetMethod ("Equals", BindingFlags.Instance);
+		static MethodInfo mi_ToString = typeof (object).GetMethod ("ToString");
+		static MethodInfo mi_GetLifetimeService = typeof (MarshalByRefObject).GetMethod ("GetLifetimeService");
+
+		object GetDefaultReturn (MethodBase mi, object[] inArgs)
+		{
+			if (mi == mi_GetHashCode)
+				return busObject.Path.Value.GetHashCode ();
+			if (mi == mi_Equals)
+				return busObject.Path.Value == ((BusObject)((MarshalByRefObject)inArgs[0]).GetLifetimeService ()).Path.Value;
+			if (mi == mi_ToString)
+				return busObject.Path.Value;
+			if (mi == mi_GetLifetimeService)
+				return busObject;
+
+			return null;
+		}
+
+		public override IMessage Invoke (IMessage message)
+		{
+			IMethodCallMessage callMessage = (IMethodCallMessage) message;
+
+			object defaultRetVal = GetDefaultReturn (callMessage.MethodBase, callMessage.InArgs);
+			if (defaultRetVal != null) {
+				MethodReturnMessageWrapper defaultReturnMessage = new MethodReturnMessageWrapper ((IMethodReturnMessage) message);
+				defaultReturnMessage.ReturnValue = defaultRetVal;
+
+				return defaultReturnMessage;
+			}
+
+			object[] outArgs;
+			object retVal;
+			Exception exception;
+			busObject.Invoke (callMessage.MethodBase, callMessage.MethodName, callMessage.InArgs, out outArgs, out retVal, out exception);
+
+			MethodReturnMessageWrapper returnMessage = new MethodReturnMessageWrapper ((IMethodReturnMessage) message);
+			returnMessage.Exception = exception;
+			returnMessage.ReturnValue = retVal;
+
+			return returnMessage;
+		}
+
+		/*
+		public override ObjRef CreateObjRef (Type ServerType)
+		{
+			throw new System.NotImplementedException ();
+		}
+		*/
+
+		~DProxy ()
+		{
+			//FIXME: remove handlers/match rules here
+			if (Protocol.Verbose)
+				Console.Error.WriteLine ("Warning: Finalization of " + busObject.Path + " not yet supported");
+		}
+	}
+}
diff --git a/src/ExportObject.cs b/src/ExportObject.cs
new file mode 100644
index 0000000..6284ff5
--- /dev/null
+++ b/src/ExportObject.cs
@@ -0,0 +1,199 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+
+using org.freedesktop.DBus;
+
+namespace DBus
+{
+	//TODO: perhaps ExportObject should not derive from BusObject
+	internal class ExportObject : BusObject, IDisposable //, Peer
+	{
+		public object obj;
+
+		public ExportObject (Connection conn, ObjectPath object_path, object obj) : base (conn, null, object_path)
+		{
+			this.obj = obj;
+		}
+
+		//maybe add checks to make sure this is not called more than once
+		//it's a bit silly as a property
+		bool isRegistered = false;
+		public virtual bool Registered
+		{
+			get {
+				return isRegistered;
+			}
+			set {
+				if (value == isRegistered)
+					return;
+
+				Type type = obj.GetType ();
+
+				foreach (MemberInfo mi in Mapper.GetPublicMembers (type)) {
+					EventInfo ei = mi as EventInfo;
+
+					if (ei == null)
+						continue;
+
+					Delegate dlg = GetHookupDelegate (ei);
+
+					if (value)
+						ei.AddEventHandler (obj, dlg);
+					else
+						ei.RemoveEventHandler (obj, dlg);
+				}
+
+				isRegistered = value;
+			}
+		}
+
+		internal virtual void WriteIntrospect (Introspector intro)
+		{
+			intro.WriteType (obj.GetType ());
+		}
+
+		internal static MethodCaller2 GetMCaller (MethodInfo mi)
+		{
+			MethodCaller2 mCaller;
+			if (!mCallers.TryGetValue (mi, out mCaller)) {
+				//mCaller = TypeImplementer.GenCaller (mi, obj);
+				mCaller = TypeImplementer.GenCaller2 (mi);
+				mCallers[mi] = mCaller;
+			}
+			return mCaller;
+		}
+
+		public static ExportObject CreateExportObject (Connection conn, ObjectPath object_path, object obj)
+		{
+#if DLR
+			Type type = obj.GetType ();
+			if (type.Name == "RubyObject" || type.FullName == "IronPython.Runtime.Types.OldInstance")
+				return new DynamicExportObject (conn, object_path, obj);
+#endif
+
+			return new ExportObject (conn, object_path, obj);
+		}
+
+		static internal readonly Dictionary<MethodInfo,MethodCaller2> mCallers = new Dictionary<MethodInfo,MethodCaller2> ();
+		public virtual void HandleMethodCall (MethodCall method_call)
+		{
+			Type type = obj.GetType ();
+
+			//object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg));
+
+			//TODO: there is no member name mapping for properties etc. yet
+
+			// FIXME: Inefficient to do this on every call
+			MethodInfo mi = Mapper.GetMethod (type, method_call);
+
+			if (mi == null) {
+				conn.MaybeSendUnknownMethodError (method_call);
+				return;
+			}
+
+			MethodCaller2 mCaller;
+			if (!mCallers.TryGetValue (mi, out mCaller)) {
+				//mCaller = TypeImplementer.GenCaller (mi, obj);
+				mCaller = TypeImplementer.GenCaller2 (mi);
+				mCallers[mi] = mCaller;
+			}
+
+			Signature inSig, outSig;
+			TypeImplementer.SigsForMethod (mi, out inSig, out outSig);
+
+			Message msg = method_call.message;
+			MessageReader msgReader = new MessageReader (method_call.message);
+			MessageWriter retWriter = new MessageWriter ();
+
+			/*
+			MessageWriter retWriter = null;
+			if (msg.ReplyExpected)
+				retWriter = new MessageWriter ();
+			*/
+
+			Exception raisedException = null;
+			try {
+				//mCaller (msgReader, method_call.message, retWriter);
+				mCaller (obj, msgReader, method_call.message, retWriter);
+			} catch (Exception e) {
+				raisedException = e;
+			}
+
+			if (!msg.ReplyExpected)
+				return;
+
+			Message replyMsg;
+
+			if (raisedException == null) {
+				MethodReturn method_return = new MethodReturn (msg.Header.Serial);
+				replyMsg = method_return.message;
+				replyMsg.Body = retWriter.ToArray ();
+				replyMsg.Signature = outSig;
+			} else {
+				Error error;
+				// BusException allows precisely formatted Error messages.
+				BusException busException = raisedException as BusException;
+				if (busException != null)
+					error = method_call.CreateError (busException.ErrorName, busException.ErrorMessage);
+				else if (raisedException is ArgumentException && raisedException.TargetSite.Name == mi.Name) {
+					// Name match trick above is a hack since we don't have the resolved MethodInfo.
+					ArgumentException argException = (ArgumentException)raisedException;
+					using (System.IO.StringReader sr = new System.IO.StringReader (argException.Message)) {
+						error = method_call.CreateError ("org.freedesktop.DBus.Error.InvalidArgs", sr.ReadLine ());
+					}
+				} else
+					error = method_call.CreateError (Mapper.GetInterfaceName (raisedException.GetType ()), raisedException.Message);
+
+				replyMsg = error.message;
+			}
+
+			if (method_call.Sender != null)
+				replyMsg.Header[FieldCode.Destination] = method_call.Sender;
+
+			conn.Send (replyMsg);
+		}
+
+		/*
+		public void Ping ()
+		{
+		}
+
+		public string GetMachineId ()
+		{
+			//TODO: implement this
+			return String.Empty;
+		}
+		*/
+
+#region IDisposable
+		public void Dispose ()
+		{
+			Dispose (true);
+			GC.SuppressFinalize (this);
+		}
+
+		~ExportObject ()
+		{
+			Dispose (false);
+		}
+
+		protected virtual void Dispose (bool disposing)
+		{
+			if (disposing)
+			{
+				if (obj != null)
+				{
+					Registered = false;
+					obj = null;
+				}
+			}
+		}
+#endregion
+	}
+}
diff --git a/src/Introspection.cs b/src/Introspection.cs
new file mode 100644
index 0000000..acf34b4
--- /dev/null
+++ b/src/Introspection.cs
@@ -0,0 +1,316 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Text;
+using System.Reflection;
+
+namespace DBus
+{
+	//TODO: complete this class
+	class Introspector
+	{
+		const string NAMESPACE = "http://www.freedesktop.org/standards/dbus";
+		const string PUBLIC_IDENTIFIER = "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN";
+		const string SYSTEM_IDENTIFIER = "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";
+
+		public StringBuilder sb;
+		public string xml;
+		public ObjectPath root_path = ObjectPath.Root;
+		public bool ExtendedAnnotations = false;
+
+		protected XmlWriter writer;
+
+		public Introspector ()
+		{
+			XmlWriterSettings settings = new XmlWriterSettings ();
+			settings.Indent = true;
+			settings.IndentChars = ("  ");
+			settings.OmitXmlDeclaration = true;
+
+			sb = new StringBuilder ();
+
+			writer = XmlWriter.Create (sb, settings);
+		}
+
+		static string GetProductDescription ()
+		{
+			String version;
+
+			Assembly assembly = Assembly.GetExecutingAssembly ();
+			AssemblyName aname = assembly.GetName ();
+
+			AssemblyInformationalVersionAttribute iversion = Attribute.GetCustomAttribute (assembly, typeof (AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
+
+			if (iversion != null)
+				version = iversion.InformationalVersion;
+			else
+				version = aname.Version.ToString ();
+
+			return aname.Name + " " + version;
+		}
+
+		public void WriteStart ()
+		{
+			writer.WriteDocType ("node", PUBLIC_IDENTIFIER, SYSTEM_IDENTIFIER, null);
+
+			writer.WriteComment (" " + GetProductDescription () + " ");
+
+			//the root node element
+			writer.WriteStartElement ("node");
+		}
+
+		public void WriteNode (string name)
+		{
+			writer.WriteStartElement ("node");
+			writer.WriteAttributeString ("name", name);
+			writer.WriteEndElement ();
+		}
+
+		public void WriteEnd ()
+		{
+			/*
+			WriteEnum (typeof (org.freedesktop.DBus.NameFlag));
+			WriteEnum (typeof (org.freedesktop.DBus.NameReply));
+			WriteEnum (typeof (org.freedesktop.DBus.ReleaseNameReply));
+			WriteEnum (typeof (org.freedesktop.DBus.StartReply));
+			WriteInterface (typeof (org.freedesktop.DBus.IBus));
+			*/
+
+			writer.WriteEndElement ();
+
+			writer.Flush ();
+			xml = sb.ToString ();
+		}
+
+		//public void WriteNode ()
+		public void WriteType (Type target_type)
+		{
+			//writer.WriteStartElement ("node");
+
+			//TODO: non-well-known introspection has paths as well, which we don't do yet. read the spec again
+			//hackishly just remove the root '/' to make the path relative for now
+			//writer.WriteAttributeString ("name", target_path.Value.Substring (1));
+			//writer.WriteAttributeString ("name", "test");
+
+			//reflect our own interface manually
+			WriteInterface (typeof (org.freedesktop.DBus.Introspectable));
+
+			//reflect the target interface
+			if (target_type != null) {
+				WriteInterface (target_type);
+
+				foreach (Type ifType in target_type.GetInterfaces ())
+					WriteInterface (ifType);
+			}
+
+			//TODO: review recursion of interfaces and inheritance hierarchy
+
+			//writer.WriteEndElement ();
+		}
+
+		public void WriteArg (ParameterInfo pi)
+		{
+			WriteArg (pi.ParameterType, Mapper.GetArgumentName (pi), pi.IsOut, false);
+		}
+
+		public void WriteArgReverse (ParameterInfo pi)
+		{
+			WriteArg (pi.ParameterType, Mapper.GetArgumentName (pi), pi.IsOut, true);
+		}
+
+		//TODO: clean up and get rid of reverse (or argIsOut) parm
+		public void WriteArg (Type argType, string argName, bool argIsOut, bool reverse)
+		{
+			argType = argIsOut ? argType.GetElementType () : argType;
+			if (argType == typeof (void))
+				return;
+
+			writer.WriteStartElement ("arg");
+
+			if (!String.IsNullOrEmpty (argName))
+				writer.WriteAttributeString ("name", argName);
+
+			//we can't rely on the default direction (qt-dbus requires a direction at time of writing), so we use a boolean to reverse the parameter direction and make it explicit
+
+			if (argIsOut)
+				writer.WriteAttributeString ("direction", !reverse ? "out" : "in");
+			else
+				writer.WriteAttributeString ("direction", !reverse ? "in" : "out");
+
+			Signature sig = Signature.GetSig (argType);
+
+			//TODO: avoid writing null (DType.Invalid) to the XML stream
+			writer.WriteAttributeString ("type", sig.Value);
+
+			//annotations aren't valid in an arg element, so this is disabled
+			//if (argType.IsEnum)
+			//	WriteAnnotation ("org.ndesk.DBus.Enum", Mapper.GetInterfaceName (argType));
+
+			writer.WriteEndElement ();
+		}
+
+		public void WriteMethod (MethodInfo mi)
+		{
+			writer.WriteStartElement ("method");
+			writer.WriteAttributeString ("name", mi.Name);
+
+			foreach (ParameterInfo pi in mi.GetParameters ())
+				WriteArg (pi);
+
+			//Mono <= 1.1.13 doesn't support MethodInfo.ReturnParameter, so avoid it
+			//WriteArgReverse (mi.ReturnParameter);
+			WriteArg (mi.ReturnType, Mapper.GetArgumentName (mi.ReturnTypeCustomAttributes, "ret"), false, true);
+
+			WriteAnnotations (mi);
+
+			writer.WriteEndElement ();
+		}
+
+		public void WriteProperty (PropertyInfo pri)
+		{
+			//expose properties as dbus properties
+			writer.WriteStartElement ("property");
+			writer.WriteAttributeString ("name", pri.Name);
+			writer.WriteAttributeString ("type", Signature.GetSig (pri.PropertyType).Value);
+			string access = (pri.CanRead ? "read" : String.Empty) + (pri.CanWrite ? "write" : String.Empty);
+			writer.WriteAttributeString ("access", access);
+			WriteAnnotations (pri);
+			writer.WriteEndElement ();
+
+			//expose properties as methods also
+			//it may not be worth doing this in the long run
+			/*
+			if (pri.CanRead) {
+				writer.WriteStartElement ("method");
+				writer.WriteAttributeString ("name", "Get" + pri.Name);
+				WriteArgReverse (pri.GetGetMethod ().ReturnParameter);
+				writer.WriteEndElement ();
+			}
+
+			if (pri.CanWrite) {
+				writer.WriteStartElement ("method");
+				writer.WriteAttributeString ("name", "Set" + pri.Name);
+				foreach (ParameterInfo pi in pri.GetSetMethod ().GetParameters ())
+					WriteArg (pi);
+				writer.WriteEndElement ();
+			}
+			*/
+		}
+
+		public void WriteSignal (EventInfo ei)
+		{
+			writer.WriteStartElement ("signal");
+			writer.WriteAttributeString ("name", ei.Name);
+
+			foreach (ParameterInfo pi in ei.EventHandlerType.GetMethod ("Invoke").GetParameters ())
+				WriteArgReverse (pi);
+
+			if (ExtendedAnnotations) {
+				string handlerName = Mapper.GetInterfaceName (ei.EventHandlerType);
+				WriteAnnotation ("org.ndesk.DBus.SignalHandler", handlerName);
+			}
+
+			WriteAnnotations (ei);
+
+			//no need to consider the delegate return value as dbus doesn't support it
+			writer.WriteEndElement ();
+		}
+
+		const BindingFlags relevantBindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
+
+		public void WriteInterface (Type type)
+		{
+			if (type == null)
+				return;
+
+			//TODO: this is unreliable, fix it
+			if (!Mapper.IsPublic (type))
+				return;
+
+			writer.WriteStartElement ("interface");
+
+			writer.WriteAttributeString ("name", Mapper.GetInterfaceName (type));
+
+			/*
+			foreach (MemberInfo mbi in type.GetMembers (relevantBindingFlags)) {
+				switch (mbi.MemberType) {
+					case MemberTypes.Method:
+						if (!((MethodInfo)mbi).IsSpecialName)
+							WriteMethod ((MethodInfo)mbi);
+						break;
+					case MemberTypes.Event:
+						WriteSignal ((EventInfo)mbi);
+						break;
+					case MemberTypes.Property:
+						WriteProperty ((PropertyInfo)mbi);
+						break;
+					default:
+						Console.Error.WriteLine ("Warning: Unhandled MemberType '{0}' encountered while introspecting {1}", mbi.MemberType, type.FullName);
+						break;
+				}
+			}
+			*/
+
+			foreach (MethodInfo mi in type.GetMethods (relevantBindingFlags))
+				if (!mi.IsSpecialName)
+					WriteMethod (mi);
+
+			foreach (EventInfo ei in type.GetEvents (relevantBindingFlags))
+				WriteSignal (ei);
+
+			foreach (PropertyInfo pri in type.GetProperties (relevantBindingFlags))
+				WriteProperty (pri);
+
+			//TODO: indexers
+
+			//TODO: attributes as annotations?
+
+			writer.WriteEndElement ();
+
+			//this recursion seems somewhat inelegant
+			WriteInterface (type.BaseType);
+		}
+
+		public void WriteAnnotations (ICustomAttributeProvider attrProvider)
+		{
+			if (Mapper.IsDeprecated (attrProvider))
+				WriteAnnotation ("org.freedesktop.DBus.Deprecated", "true");
+		}
+
+		public void WriteAnnotation (string name, string value)
+		{
+			writer.WriteStartElement ("annotation");
+
+			writer.WriteAttributeString ("name", name);
+			writer.WriteAttributeString ("value", value);
+
+			writer.WriteEndElement ();
+		}
+
+		//this is not in the spec, and is not finalized
+		public void WriteEnum (Type type)
+		{
+			writer.WriteStartElement ("enum");
+			writer.WriteAttributeString ("name", Mapper.GetInterfaceName (type));
+			writer.WriteAttributeString ("type", Signature.GetSig (type.GetElementType ()).Value);
+			writer.WriteAttributeString ("flags", (type.IsDefined (typeof (FlagsAttribute), false)) ? "true" : "false");
+
+			string[] names = Enum.GetNames (type);
+
+			int i = 0;
+			foreach (Enum val in Enum.GetValues (type)) {
+				writer.WriteStartElement ("element");
+				writer.WriteAttributeString ("name", names[i++]);
+				writer.WriteAttributeString ("value", val.ToString ("d"));
+				writer.WriteEndElement ();
+			}
+
+			writer.WriteEndElement ();
+		}
+	}
+}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..8078edc
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,68 @@
+ASSEMBLY = dbus-sharp
+TARGET = $(ASSEMBLY).dll
+
+CSFLAGS = \
+	-debug -target:library -unsafe -d:STRONG_NAME -keyfile:$(top_srcdir)/dbus-sharp.snk
+
+LIBFLAGS = \
+	-r:Mono.Posix
+
+CSFILES = \
+	$(srcdir)/Address.cs \
+	$(srcdir)/Authentication.cs \
+	$(srcdir)/Bus.cs \
+	$(srcdir)/BusObject.cs \
+	$(srcdir)/Connection.cs \
+	$(srcdir)/DBus.cs \
+	$(srcdir)/DProxy.cs \
+	$(srcdir)/ExportObject.cs \
+	$(srcdir)/Introspection.cs \
+	$(srcdir)/Protocol.cs \
+	$(srcdir)/Mapper.cs \
+	$(srcdir)/MatchRule.cs \
+	$(srcdir)/Message.cs \
+	$(srcdir)/MessageFilter.cs \
+	$(srcdir)/MessageReader.cs \
+	$(srcdir)/MessageWriter.cs \
+	$(srcdir)/PendingCall.cs \
+	$(srcdir)/Signature.cs \
+	$(srcdir)/SocketTransport.cs \
+	$(srcdir)/Transport.cs \
+	$(srcdir)/TypeImplementer.cs \
+	$(srcdir)/TypeRental.cs \
+	$(srcdir)/Unix.cs \
+	$(srcdir)/UnixNativeTransport.cs \
+	$(srcdir)/UnixTransport.cs \
+	$(srcdir)/Wrapper.cs
+
+all: $(TARGET)
+
+$(TARGET): $(CSFILES) AssemblyInfo.cs
+	$(GMCS) -out:$@ $(CSFLAGS) $(LIBFLAGS) $^
+
+install-data-local: $(TARGET)
+	@if test -n '$(TARGET)'; then                       \
+          echo "$(GACUTIL) /i $(TARGET) /f /gacdir $(DESTDIR)$(libdir)";    \
+          $(GACUTIL) /i $(TARGET) /package $(PACKAGE)-$(API_VERSION) /f /gacdir $(libdir) /root $(DESTDIR)$(libdir) || exit 1; \
+        fi
+
+uninstall-local:
+	@if test -n '$(TARGET)'; then                       \
+          echo "$(GACUTIL) /u $(ASSEMBLY) /gacdir $(DESTDIR)$(libdir)";  \
+          $(GACUTIL) /u $(ASSEMBLY) /package $(PACKAGE)-$(API_VERSION) /gacdir $(libdir) /root $(DESTDIR)$(libdir) || exit 1;   \
+        fi
+
+EXTRA_DIST = \
+	$(CSFILES) \
+	$(srcdir)/dbus-sharp.dll.config \
+	$(srcdir)/AssemblyInfo.cs.in
+
+CLEANFILES = \
+	$(TARGET) \
+	$(TARGET).mdb
+
+DISTCLEANFILES = \
+	AssemblyInfo.cs
+
+MAINTAINERCLEANFILES = \
+	Makefile.in
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..dacdb8d
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,382 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = src
+DIST_COMMON = $(srcdir)/AssemblyInfo.cs.in $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES = AssemblyInfo.cs
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+API_VERSION = @API_VERSION@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+GACUTIL = @GACUTIL@
+GMCS = @GMCS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MONO_CFLAGS = @MONO_CFLAGS@
+MONO_LIBS = @MONO_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ASSEMBLY = dbus-sharp
+TARGET = $(ASSEMBLY).dll
+CSFLAGS = \
+	-debug -target:library -unsafe -d:STRONG_NAME -keyfile:$(top_srcdir)/dbus-sharp.snk
+
+LIBFLAGS = \
+	-r:Mono.Posix
+
+CSFILES = \
+	$(srcdir)/Address.cs \
+	$(srcdir)/Authentication.cs \
+	$(srcdir)/Bus.cs \
+	$(srcdir)/BusObject.cs \
+	$(srcdir)/Connection.cs \
+	$(srcdir)/DBus.cs \
+	$(srcdir)/DProxy.cs \
+	$(srcdir)/ExportObject.cs \
+	$(srcdir)/Introspection.cs \
+	$(srcdir)/Protocol.cs \
+	$(srcdir)/Mapper.cs \
+	$(srcdir)/MatchRule.cs \
+	$(srcdir)/Message.cs \
+	$(srcdir)/MessageFilter.cs \
+	$(srcdir)/MessageReader.cs \
+	$(srcdir)/MessageWriter.cs \
+	$(srcdir)/PendingCall.cs \
+	$(srcdir)/Signature.cs \
+	$(srcdir)/SocketTransport.cs \
+	$(srcdir)/Transport.cs \
+	$(srcdir)/TypeImplementer.cs \
+	$(srcdir)/TypeRental.cs \
+	$(srcdir)/Unix.cs \
+	$(srcdir)/UnixNativeTransport.cs \
+	$(srcdir)/UnixTransport.cs \
+	$(srcdir)/Wrapper.cs
+
+EXTRA_DIST = \
+	$(CSFILES) \
+	$(srcdir)/dbus-sharp.dll.config \
+	$(srcdir)/AssemblyInfo.cs.in
+
+CLEANFILES = \
+	$(TARGET) \
+	$(TARGET).mdb
+
+DISTCLEANFILES = \
+	AssemblyInfo.cs
+
+MAINTAINERCLEANFILES = \
+	Makefile.in
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+AssemblyInfo.cs: $(top_builddir)/config.status $(srcdir)/AssemblyInfo.cs.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-local
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-data-local install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am uninstall uninstall-am uninstall-local
+
+
+all: $(TARGET)
+
+$(TARGET): $(CSFILES) AssemblyInfo.cs
+	$(GMCS) -out:$@ $(CSFLAGS) $(LIBFLAGS) $^
+
+install-data-local: $(TARGET)
+	@if test -n '$(TARGET)'; then                       \
+          echo "$(GACUTIL) /i $(TARGET) /f /gacdir $(DESTDIR)$(libdir)";    \
+          $(GACUTIL) /i $(TARGET) /package $(PACKAGE)-$(API_VERSION) /f /gacdir $(libdir) /root $(DESTDIR)$(libdir) || exit 1; \
+        fi
+
+uninstall-local:
+	@if test -n '$(TARGET)'; then                       \
+          echo "$(GACUTIL) /u $(ASSEMBLY) /gacdir $(DESTDIR)$(libdir)";  \
+          $(GACUTIL) /u $(ASSEMBLY) /package $(PACKAGE)-$(API_VERSION) /gacdir $(libdir) /root $(DESTDIR)$(libdir) || exit 1;   \
+        fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/Mapper.cs b/src/Mapper.cs
new file mode 100644
index 0000000..4f223bc
--- /dev/null
+++ b/src/Mapper.cs
@@ -0,0 +1,389 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace DBus
+{
+	static class Mapper
+	{
+		//TODO: move these Get*Name helpers somewhere more appropriate
+		public static string GetArgumentName (ParameterInfo pi)
+		{
+			string argName = pi.Name;
+
+			if (pi.IsRetval && String.IsNullOrEmpty (argName))
+				argName = "ret";
+
+			return GetArgumentName ((ICustomAttributeProvider)pi, argName);
+		}
+
+		public static string GetArgumentName (ICustomAttributeProvider attrProvider, string defaultName)
+		{
+			string argName = defaultName;
+
+			//TODO: no need for foreach
+			foreach (ArgumentAttribute aa in attrProvider.GetCustomAttributes (typeof (ArgumentAttribute), true))
+				argName = aa.Name;
+
+			return argName;
+		}
+
+		//TODO: these two methods are quite messy and need review
+		public static IEnumerable<MemberInfo> GetPublicMembers (Type type)
+		{
+			//note that Type.GetInterfaces() returns all interfaces with flattened hierarchy
+			foreach (Type ifType in type.GetInterfaces ())
+				foreach (MemberInfo mi in GetDeclaredPublicMembers (ifType))
+					yield return mi;
+
+			if (IsPublic (type))
+				foreach (MemberInfo mi in GetDeclaredPublicMembers (type))
+					yield return mi;
+		}
+
+		static IEnumerable<MemberInfo> GetDeclaredPublicMembers (Type type)
+		{
+			if (IsPublic (type))
+				foreach (MemberInfo mi in type.GetMembers (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+					yield return mi;
+		}
+
+		//this method walks the interface tree in an undefined manner and returns the first match, or if no matches are found, null
+		//the logic needs review and cleanup
+		//TODO: unify member name mapping as is already done with interfaces and args
+		public static MethodInfo GetMethod (Type type, MethodCall method_call)
+		{
+			foreach (MemberInfo member in Mapper.GetPublicMembers (type)) {
+				//this could be made more efficient by using the given interface name earlier and avoiding walking through all public interfaces
+				if (method_call.Interface != null)
+					if (GetInterfaceName (member) != method_call.Interface)
+						continue;
+
+				MethodInfo meth = null;
+				Type[] inTypes = null;
+
+				if (member is PropertyInfo) {
+					PropertyInfo prop = member as PropertyInfo;
+
+					MethodInfo getter = prop.GetGetMethod (false);
+					MethodInfo setter = prop.GetSetMethod (false);
+
+					if (getter != null && "Get" + prop.Name == method_call.Member) {
+						meth = getter;
+						inTypes = Type.EmptyTypes;
+					} else if (setter != null && "Set" + prop.Name == method_call.Member) {
+						meth = setter;
+						inTypes = new Type[] {prop.PropertyType};
+					}
+				} else {
+					meth = member as MethodInfo;
+
+					if (meth == null)
+						continue;
+
+					if (meth.Name != method_call.Member)
+						continue;
+
+					inTypes = Mapper.GetTypes (ArgDirection.In, meth.GetParameters ());
+				}
+
+				if (meth == null || inTypes == null)
+					continue;
+
+				Signature inSig = Signature.GetSig (inTypes);
+
+				if (inSig != method_call.Signature)
+					continue;
+
+				return meth;
+			}
+
+			return null;
+		}
+
+		public static bool IsPublic (MemberInfo mi)
+		{
+			return IsPublic (mi.DeclaringType);
+		}
+
+		public static bool IsPublic (Type type)
+		{
+			//we need to have a proper look at what's really public at some point
+			//this will do for now
+
+			if (type.IsDefined (typeof (InterfaceAttribute), false))
+				return true;
+
+			if (type.IsSubclassOf (typeof (MarshalByRefObject)))
+				return true;
+
+			return false;
+		}
+
+		public static string GetInterfaceName (MemberInfo mi)
+		{
+			return GetInterfaceName (mi.DeclaringType);
+		}
+
+		public static string GetInterfaceName (Type type)
+		{
+			string interfaceName = type.FullName;
+
+			//TODO: better fallbacks and namespace mangling when no InterfaceAttribute is available
+
+			//TODO: no need for foreach
+			foreach (InterfaceAttribute ia in type.GetCustomAttributes (typeof (InterfaceAttribute), true))
+				interfaceName = ia.Name;
+
+			return interfaceName;
+		}
+
+		public static Type[] GetTypes (ArgDirection dir, ParameterInfo[] parms)
+		{
+			List<Type> types = new List<Type> ();
+
+			//TODO: consider InOut/Ref
+
+			for (int i = 0 ; i != parms.Length ; i++) {
+				switch (dir) {
+					case ArgDirection.In:
+						//docs say IsIn isn't reliable, and this is indeed true
+						//if (parms[i].IsIn)
+						if (!parms[i].IsOut)
+							types.Add (parms[i].ParameterType);
+						break;
+					case ArgDirection.Out:
+						if (parms[i].IsOut) {
+							//TODO: note that IsOut is optional to the compiler, we may want to use IsByRef instead
+						//eg: if (parms[i].ParameterType.IsByRef)
+							types.Add (parms[i].ParameterType.GetElementType ());
+						}
+						break;
+				}
+			}
+
+			return types.ToArray ();
+		}
+
+		public static bool IsDeprecated (ICustomAttributeProvider attrProvider)
+		{
+			return attrProvider.IsDefined (typeof (ObsoleteAttribute), true);
+		}
+
+		static bool AreEqual (Type[] a, Type[] b)
+		{
+			if (a.Length != b.Length)
+				return false;
+
+			for (int i = 0 ; i != a.Length ; i++)
+				if (a[i] != b[i])
+					return false;
+
+			return true;
+		}
+
+		//workaround for Mono bug #81035 (memory leak)
+		static List<Type> genTypes = new List<Type> ();
+		internal static Type GetGenericType (Type defType, Type[] parms)
+		{
+			lock (genTypes) {
+				foreach (Type genType in genTypes) {
+					if (genType.GetGenericTypeDefinition () != defType)
+						continue;
+
+					Type[] genParms = genType.GetGenericArguments ();
+
+					if (!AreEqual (genParms, parms))
+						continue;
+
+					return genType;
+				}
+
+				Type type = defType.MakeGenericType (parms);
+				genTypes.Add (type);
+				return type;
+			}
+		}
+	}
+
+	//TODO: this class is messy, move the methods somewhere more appropriate
+	static class MessageHelper
+	{
+		public static Message CreateUnknownMethodError (MethodCall method_call)
+		{
+			if (!method_call.message.ReplyExpected)
+				return null;
+
+			string errMsg = String.Format ("Method \"{0}\" with signature \"{1}\" on interface \"{2}\" doesn't exist", method_call.Member, method_call.Signature.Value, method_call.Interface);
+
+			Error error = new Error ("org.freedesktop.DBus.Error.UnknownMethod", method_call.message.Header.Serial);
+			error.message.Signature = new Signature (DType.String);
+
+			MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
+			writer.Write (errMsg);
+			error.message.Body = writer.ToArray ();
+
+			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
+			if (method_call.Sender != null)
+				error.message.Header[FieldCode.Destination] = method_call.Sender;
+
+			return error.message;
+		}
+
+		public static void WriteDynamicValues (MessageWriter mw, ParameterInfo[] parms, object[] vals)
+		{
+			foreach (ParameterInfo parm in parms) {
+				if (!parm.IsOut)
+					continue;
+
+				Type actualType = parm.ParameterType.GetElementType ();
+				mw.Write (actualType, vals[parm.Position]);
+			}
+		}
+
+		public static object[] GetDynamicValues (Message msg, ParameterInfo[] parms)
+		{
+			//TODO: this validation check should provide better information, eg. message dump or a stack trace, or at least the interface/member
+			/*
+			if (Protocol.Verbose) {
+				Signature expected = Signature.GetSig (types);
+				Signature actual = msg.Signature;
+				if (actual != expected)
+					Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler: " + "Expected '" + expected + "', got '" + actual + "'");
+			}
+			*/
+
+			object[] vals = new object[parms.Length];
+
+			if (msg.Body != null) {
+				MessageReader reader = new MessageReader (msg);
+				foreach (ParameterInfo parm in parms) {
+					if (parm.IsOut)
+						continue;
+
+					vals[parm.Position] = reader.ReadValue (parm.ParameterType);
+				}
+			}
+
+			return vals;
+		}
+
+		public static object[] GetDynamicValues (Message msg, Type[] types)
+		{
+			//TODO: this validation check should provide better information, eg. message dump or a stack trace, or at least the interface/member
+			if (Protocol.Verbose) {
+				Signature expected = Signature.GetSig (types);
+				Signature actual = msg.Signature;
+				if (actual != expected)
+					Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler: " + "Expected '" + expected + "', got '" + actual + "'");
+			}
+
+			object[] vals = new object[types.Length];
+
+			if (msg.Body != null) {
+				MessageReader reader = new MessageReader (msg);
+
+				for (int i = 0 ; i != types.Length ; i++)
+					vals[i] = reader.ReadValue (types[i]);
+			}
+
+			return vals;
+		}
+
+		public static object[] GetDynamicValues (Message msg)
+		{
+			Type[] types = msg.Signature.ToTypes ();
+			return GetDynamicValues (msg, types);
+		}
+
+		public static Message ConstructReply (MethodCall method_call, params object[] vals)
+		{
+			MethodReturn method_return = new MethodReturn (method_call.message.Header.Serial);
+			Message replyMsg = method_return.message;
+
+			Signature inSig = Signature.GetSig (vals);
+
+			if (vals != null && vals.Length != 0) {
+				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
+
+				foreach (object arg in vals)
+					writer.Write (arg.GetType (), arg);
+
+				replyMsg.Body = writer.ToArray ();
+			}
+
+			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
+			if (method_call.Sender != null)
+				replyMsg.Header[FieldCode.Destination] = method_call.Sender;
+
+			replyMsg.Signature = inSig;
+
+			//replyMsg.WriteHeader ();
+
+			return replyMsg;
+		}
+
+		public static Message ConstructDynamicReply (MethodCall method_call, MethodInfo mi, object retVal, object[] vals)
+		{
+			Type retType = mi.ReturnType;
+
+			MethodReturn method_return = new MethodReturn (method_call.message.Header.Serial);
+			Message replyMsg = method_return.message;
+
+			Signature outSig = Signature.GetSig (retType);
+			outSig += Signature.GetSig (Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ()));
+
+			if (outSig != Signature.Empty) {
+				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
+
+				//first write the return value, if any
+				if (retType != null && retType != typeof (void))
+					writer.Write (retType, retVal);
+
+				//then write the out args
+				WriteDynamicValues (writer, mi.GetParameters (), vals);
+
+				replyMsg.Body = writer.ToArray ();
+			}
+
+			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
+			if (method_call.Sender != null)
+				replyMsg.Header[FieldCode.Destination] = method_call.Sender;
+
+			replyMsg.Signature = outSig;
+
+			return replyMsg;
+		}
+	}
+
+	[AttributeUsage (AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
+	public class InterfaceAttribute : Attribute
+	{
+		public string Name;
+
+		public InterfaceAttribute (string name)
+		{
+			this.Name = name;
+		}
+	}
+
+	[AttributeUsage (AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple=false, Inherited=true)]
+	public class ArgumentAttribute : Attribute
+	{
+		public string Name;
+
+		public ArgumentAttribute (string name)
+		{
+			this.Name = name;
+		}
+
+		public static string GetSignatureString (Type type)
+		{
+			return Signature.GetSig (type).Value;
+		}
+	}
+}
diff --git a/src/MatchRule.cs b/src/MatchRule.cs
new file mode 100644
index 0000000..317c171
--- /dev/null
+++ b/src/MatchRule.cs
@@ -0,0 +1,319 @@
+// Copyright 2007 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+
+namespace DBus
+{
+	class MatchRule
+	{
+		public MessageType? MessageType;
+		public readonly SortedList<FieldCode,MatchTest> Fields = new SortedList<FieldCode,MatchTest> ();
+		//public readonly SortedList<int,MatchTest> Args = new SortedList<int,MatchTest> ();
+		public readonly HashSet<ArgMatchTest> Args = new HashSet<ArgMatchTest> ();
+
+		public MatchRule ()
+		{
+		}
+
+		static void Append (StringBuilder sb, string key, object value)
+		{
+			Append (sb, key, value.ToString ());
+		}
+
+		static void Append (StringBuilder sb, string key, string value)
+		{
+			if (sb.Length != 0)
+				sb.Append (',');
+
+			sb.Append (key);
+			sb.Append ("='");
+			sb.Append (value.Replace (@"\", @"\\").Replace (@"'", @"\'"));
+			sb.Append ('\'');
+		}
+
+		static void AppendArg (StringBuilder sb, int index, string value)
+		{
+			Append (sb, "arg" + index, value);
+		}
+
+		static void AppendPathArg (StringBuilder sb, int index, ObjectPath value)
+		{
+			Append (sb, "arg" + index + "path", value.ToString ());
+		}
+
+		public override bool Equals (object o)
+		{
+			MatchRule r = o as MatchRule;
+			if (o == null)
+				return false;
+
+			return ToString () == r.ToString ();
+		}
+
+		public override int GetHashCode ()
+		{
+			//FIXME: not at all optimal
+			return ToString ().GetHashCode ();
+		}
+
+		public override string ToString ()
+		{
+			StringBuilder sb = new StringBuilder ();
+
+			if (MessageType != null)
+				Append (sb, "type", MessageFilter.MessageTypeToString ((MessageType)MessageType));
+
+			// Note that fdo D-Bus daemon sorts in a different order.
+			// It shouldn't matter though as long as we're consistent.
+			foreach (KeyValuePair<FieldCode,MatchTest> pair in Fields) {
+				Append (sb, pair.Key.ToString ().ToLower (), pair.Value.Value);
+			}
+
+			// Sorting the list here is not ideal
+			List<ArgMatchTest> tests = new List<ArgMatchTest> (Args);
+			tests.Sort ( delegate (ArgMatchTest aa, ArgMatchTest bb) { return aa.ArgNum - bb.ArgNum; } );
+
+			if (Args != null)
+				foreach (ArgMatchTest test in tests)
+					if (test.Signature == Signature.StringSig)
+						AppendArg (sb, test.ArgNum, (string)test.Value);
+					else if (test.Signature == Signature.ObjectPathSig)
+						AppendPathArg (sb, test.ArgNum, (ObjectPath)test.Value);
+
+			return sb.ToString ();
+		}
+
+		public static void Test (HashSet<ArgMatchTest> a, Message msg)
+		{
+			List<Signature> sigs = new List<Signature> ();
+			sigs.AddRange (msg.Signature.GetParts ());
+
+			if (sigs.Count == 0) {
+				a.Clear ();
+				return;
+			}
+
+			a.RemoveWhere ( delegate (ArgMatchTest t) { return t.ArgNum >= sigs.Count || t.Signature != sigs[t.ArgNum]; } );
+
+			// Sorting the list here is not ideal
+			List<ArgMatchTest> tests = new List<ArgMatchTest> (a);
+			tests.Sort ( delegate (ArgMatchTest aa, ArgMatchTest bb) { return aa.ArgNum - bb.ArgNum; } );
+
+			if (tests.Count == 0) {
+				a.Clear ();
+				return;
+			}
+
+			MessageReader reader = new MessageReader (msg);
+
+			int argNum = 0;
+			foreach (ArgMatchTest test in tests) {
+				if (argNum > test.ArgNum) {
+					// This test cannot pass because a previous test already did.
+					// So we already know it will fail without even trying.
+					// This logic will need to be changed to support wildcards.
+					a.Remove (test);
+					continue;
+				}
+
+				while (argNum != test.ArgNum) {
+					Signature sig = sigs[argNum];
+					if (!reader.StepOver (sig))
+						throw new Exception ();
+					argNum++;
+				}
+
+				// TODO: Avoid re-reading values
+				int savedPos = reader.pos;
+				if (!reader.ReadValue (test.Signature[0]).Equals (test.Value)) {
+					a.Remove (test);
+					reader.pos = savedPos;
+					continue;
+				}
+
+				argNum++;
+			}
+		}
+
+		public bool MatchesHeader (Message msg)
+		{
+			if (MessageType != null)
+				if (msg.Header.MessageType != MessageType)
+					return false;
+
+			foreach (KeyValuePair<FieldCode,MatchTest> pair in Fields) {
+				object value;
+				if (!msg.Header.Fields.TryGetValue ((byte)pair.Key, out value))
+					return false;
+				if (!pair.Value.Value.Equals (value))
+					return false;
+			}
+
+			return true;
+		}
+
+		static Regex argNRegex = new Regex (@"^arg(\d+)(path)?$");
+		static Regex matchRuleRegex = new Regex (@"(\w+)\s*=\s*'((\\\\|\\'|[^'\\])*)'", RegexOptions.Compiled);
+		public static MatchRule Parse (string text)
+		{
+			if (text.Length > Protocol.MaxMatchRuleLength)
+				throw new Exception ("Match rule length exceeds maximum " + Protocol.MaxMatchRuleLength + " characters");
+
+			MatchRule r = new MatchRule ();
+
+			// TODO: Stricter validation. Tighten up the regex.
+			// It currently succeeds and silently drops malformed test parts.
+
+			for (Match m = matchRuleRegex.Match (text) ; m.Success ; m = m.NextMatch ()) {
+				string key = m.Groups[1].Value;
+				string value = m.Groups[2].Value;
+				// This unescaping may not be perfect..
+				value = value.Replace (@"\\", @"\");
+				value = value.Replace (@"\'", @"'");
+
+				if (key.StartsWith ("arg")) {
+					Match mArg = argNRegex.Match (key);
+					if (!mArg.Success)
+						return null;
+					int argNum = (int)UInt32.Parse (mArg.Groups[1].Value);
+
+					if (argNum < 0 || argNum >= Protocol.MaxMatchRuleArgs)
+						throw new Exception ("arg match must be between 0 and " + (Protocol.MaxMatchRuleArgs - 1) + " inclusive");
+
+					//if (r.Args.ContainsKey (argNum))
+					//	return null;
+
+					string argType = mArg.Groups[2].Value;
+
+					if (argType == "path")
+						r.Args.Add (new ArgMatchTest (argNum, new ObjectPath (value)));
+					else
+						r.Args.Add (new ArgMatchTest (argNum, value));
+
+					continue;
+				}
+
+				//TODO: more consistent error handling
+				switch (key) {
+					case "type":
+						if (r.MessageType != null)
+							return null;
+						r.MessageType = MessageFilter.StringToMessageType (value);
+						break;
+					case "interface":
+						r.Fields[FieldCode.Interface] = new MatchTest (value);
+						break;
+					case "member":
+						r.Fields[FieldCode.Member] = new MatchTest (value);
+						break;
+					case "path":
+						r.Fields[FieldCode.Path] = new MatchTest (new ObjectPath (value));
+						break;
+					case "sender":
+						r.Fields[FieldCode.Sender] = new MatchTest (value);
+						break;
+					case "destination":
+						r.Fields[FieldCode.Destination] = new MatchTest (value);
+						break;
+					default:
+						if (Protocol.Verbose)
+							Console.Error.WriteLine ("Warning: Unrecognized match rule key: " + key);
+						break;
+				}
+			}
+
+			return r;
+		}
+	}
+
+	class HeaderTest : MatchTest
+	{
+		public FieldCode Field;
+		public HeaderTest (FieldCode field, object value)
+		{
+			Field = field;
+			Signature = Signature.GetSig (value.GetType ());
+			Value = value;
+		}
+	}
+
+	struct ArgMatchTest
+	{
+		public int ArgNum;
+		public Signature Signature;
+		public object Value;
+
+		public ArgMatchTest (int argNum, string value)
+		{
+			ArgNum = argNum;
+			Signature = Signature.StringSig;
+			Value = value;
+		}
+
+		public ArgMatchTest (int argNum, ObjectPath value)
+		{
+			ArgNum = argNum;
+			Signature = Signature.ObjectPathSig;
+			Value = value;
+		}
+
+		public override int GetHashCode ()
+		{
+			return Signature.GetHashCode () ^ Value.GetHashCode () ^ ArgNum;
+		}
+	}
+
+	/*
+	class ArgMatchTest : MatchTest
+	{
+		public int ArgNum;
+
+		public ArgMatchTest (int argNum, string value) : base (value)
+		{
+			ArgNum = argNum;
+		}
+
+		public ArgMatchTest (int argNum, ObjectPath value) : base (value)
+		{
+			ArgNum = argNum;
+		}
+
+		public override int GetHashCode ()
+		{
+			return base.GetHashCode () ^ ArgNum;
+		}
+	}
+	*/
+
+	class MatchTest
+	{
+		public Signature Signature;
+		public object Value;
+
+		public override int GetHashCode ()
+		{
+			return Signature.GetHashCode () ^ Value.GetHashCode ();
+		}
+
+		protected MatchTest ()
+		{
+		}
+
+		public MatchTest (string value)
+		{
+			Signature = Signature.StringSig;
+			Value = value;
+		}
+
+		public MatchTest (ObjectPath value)
+		{
+			Signature = Signature.ObjectPathSig;
+			Value = value;
+		}
+	}
+}
diff --git a/src/Message.cs b/src/Message.cs
new file mode 100644
index 0000000..9487e12
--- /dev/null
+++ b/src/Message.cs
@@ -0,0 +1,499 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace DBus
+{
+	class Message
+	{
+		public Message ()
+		{
+			Header.Endianness = Connection.NativeEndianness;
+			Header.MessageType = MessageType.MethodCall;
+			Header.Flags = HeaderFlag.NoReplyExpected; //TODO: is this the right place to do this?
+			Header.MajorVersion = Protocol.Version;
+			Header.Fields = new Dictionary<byte, object> ();
+		}
+
+		public Header Header = new Header ();
+
+		public Connection Connection;
+
+		public Signature Signature
+		{
+			get {
+				object o = Header[FieldCode.Signature];
+				if (o == null)
+					return Signature.Empty;
+				else
+					return (Signature)o;
+			} set {
+				if (value == Signature.Empty)
+					Header[FieldCode.Signature] = null;
+				else
+					Header[FieldCode.Signature] = value;
+			}
+		}
+
+		public bool ReplyExpected
+		{
+			get {
+				return (Header.Flags & HeaderFlag.NoReplyExpected) == HeaderFlag.None;
+			} set {
+				if (value)
+					Header.Flags &= ~HeaderFlag.NoReplyExpected; //flag off
+				else
+					Header.Flags |= HeaderFlag.NoReplyExpected; //flag on
+			}
+		}
+
+		//public HeaderField[] HeaderFields;
+		//public Dictionary<FieldCode,object>;
+
+		public byte[] Body;
+
+		//TODO: make use of Locked
+		/*
+		protected bool locked = false;
+		public bool Locked
+		{
+			get {
+				return locked;
+			}
+		}
+		*/
+
+		public void HandleHeader (Header headerIn)
+		{
+			Header = headerIn;
+		}
+
+		static System.Reflection.MethodInfo hHandler = typeof (Message).GetMethod ("HandleHeader");
+		public void SetHeaderData (byte[] data)
+		{
+			EndianFlag endianness = (EndianFlag)data[0];
+			MessageReader reader = new MessageReader (endianness, data);
+
+			MethodCaller2 mCaller = ExportObject.GetMCaller (hHandler);
+			mCaller (this, reader, null, new MessageWriter ());
+		}
+
+		//public HeaderField[] Fields;
+
+		/*
+		public void SetHeaderData (byte[] data)
+		{
+			EndianFlag endianness = (EndianFlag)data[0];
+			MessageReader reader = new MessageReader (endianness, data);
+
+			Header = (Header)reader.ReadStruct (typeof (Header));
+		}
+		*/
+
+		//TypeWriter<Header> headerWriter = TypeImplementer.GetTypeWriter<Header> ();
+		public byte[] GetHeaderData ()
+		{
+			if (Body != null)
+				Header.Length = (uint)Body.Length;
+
+			MessageWriter writer = new MessageWriter (Header.Endianness);
+
+			//writer.stream.Capacity = 512;
+			//headerWriter (writer, Header);
+
+			writer.Write ((byte)Header.Endianness);
+			writer.Write ((byte)Header.MessageType);
+			writer.Write ((byte)Header.Flags);
+			writer.Write (Header.MajorVersion);
+			writer.Write (Header.Length);
+			writer.Write (Header.Serial);
+			writer.WriteHeaderFields (Header.Fields);
+
+			writer.CloseWrite ();
+
+			return writer.ToArray ();
+		}
+
+		public void GetHeaderDataToStream (Stream stream)
+		{
+			if (Body != null)
+				Header.Length = (uint)Body.Length;
+
+			MessageWriter writer = new MessageWriter (Header.Endianness);
+
+			//headerWriter (writer, Header);
+
+			writer.Write ((byte)Header.Endianness);
+			writer.Write ((byte)Header.MessageType);
+			writer.Write ((byte)Header.Flags);
+			writer.Write (Header.MajorVersion);
+			writer.Write (Header.Length);
+			writer.Write (Header.Serial);
+			writer.WriteHeaderFields (Header.Fields);
+
+			writer.CloseWrite ();
+
+			writer.ToStream (stream);
+		}
+	}
+
+	// Allows conversion of complex variants via System.Convert
+	class DValue : IConvertible
+	{
+		// TODO: Note that we currently drop the originating Connection/Message details
+		// They may be useful later in conversion!
+
+		internal EndianFlag endianness;
+		internal Signature signature;
+		internal byte[] data;
+
+		public bool CanConvertTo (Type conversionType)
+		{
+			Signature typeSig = Signature.GetSig (conversionType);
+			return signature == typeSig;
+		}
+
+		public TypeCode GetTypeCode ()
+		{
+			return TypeCode.Object;
+		}
+
+		public object ToType (Type conversionType)
+		{
+			return ToType (conversionType, null);
+		}
+
+		public object ToType (Type conversionType, IFormatProvider provider)
+		{
+			Signature typeSig = Signature.GetSig (conversionType);
+			if (typeSig != signature)
+				throw new InvalidCastException ();
+
+			MessageReader reader = new MessageReader (endianness, data);
+			return reader.ReadValue (conversionType);
+		}
+
+		public override string ToString ()
+		{
+			// Seems a reasonable way of providing the signature to the API layer
+			return signature.ToString ();
+		}
+
+		// IConvertible implementation:
+
+		/*
+		public TypeCode GetTypeCode ()
+		{
+			throw new NotSupportedException ();
+		}
+		*/
+
+		public bool ToBoolean (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public byte ToByte (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public char ToChar (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public DateTime ToDateTime (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public decimal ToDecimal (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public double ToDouble (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public short ToInt16 (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public int ToInt32 (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public long ToInt64 (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public sbyte ToSByte (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public float ToSingle (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public string ToString (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		/*
+		public object ToType (Type conversionType, IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+		*/
+
+		public ushort ToUInt16 (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public uint ToUInt32 (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+
+		public ulong ToUInt64 (IFormatProvider provider)
+		{
+			throw new NotSupportedException ();
+		}
+	}
+
+	partial class MessageReader
+	{
+		// Note: This method doesn't support aggregate signatures
+		public bool StepOver (Signature sig)
+		{
+			if (sig == Signature.VariantSig) {
+				Signature valueSig = ReadSignature ();
+				return StepOver (valueSig);
+			}
+
+			if (sig == Signature.StringSig) {
+				uint valueLength = ReadUInt32 ();
+				pos += (int)valueLength;
+				pos++;
+				return true;
+			}
+
+			if (sig == Signature.ObjectPathSig) {
+				uint valueLength = ReadUInt32 ();
+				pos += (int)valueLength;
+				pos++;
+				return true;
+			}
+
+			if (sig == Signature.SignatureSig) {
+				byte valueLength = ReadByte ();
+				pos += valueLength;
+				pos++;
+				return true;
+			}
+
+			// No need to handle dicts specially. IsArray does the job
+			if (sig.IsArray) {
+				Signature elemSig = sig.GetElementSignature ();
+				uint ln = ReadUInt32 ();
+				pos = Protocol.Padded (pos, elemSig.Alignment);
+				pos += (int)ln;
+				return true;
+			}
+
+			int endPos = pos;
+			if (sig.GetFixedSize (ref endPos)) {
+				pos = endPos;
+				return true;
+			}
+
+			if (sig.IsDictEntry) {
+				pos = Protocol.Padded (pos, sig.Alignment);
+				Signature sigKey, sigValue;
+				sig.GetDictEntrySignatures (out sigKey, out sigValue);
+				if (!StepOver (sigKey))
+					return false;
+				if (!StepOver (sigValue))
+					return false;
+				return true;
+			}
+
+			if (sig.IsStruct) {
+				pos = Protocol.Padded (pos, sig.Alignment);
+				foreach (Signature fieldSig in sig.GetFieldSignatures ())
+					if (!StepOver (fieldSig))
+						return false;
+				return true;
+			}
+
+			throw new Exception ("Can't step over '" + sig + "'");
+			//return false;
+		}
+
+		public IEnumerable<Signature> StepInto (Signature sig)
+		{
+			if (sig == Signature.VariantSig) {
+				Signature valueSig = ReadSignature ();
+				yield return valueSig;
+				yield break;
+			}
+
+			// No need to handle dicts specially. IsArray does the job
+			if (sig.IsArray) {
+				Signature elemSig = sig.GetElementSignature ();
+				uint ln = ReadUInt32 ();
+				ReadPad (elemSig.Alignment);
+				int endPos = pos + (int)ln;
+				while (pos < endPos)
+					yield return elemSig;
+				yield break;
+			}
+
+			if (sig.IsDictEntry) {
+				pos = Protocol.Padded (pos, sig.Alignment);
+				Signature sigKey, sigValue;
+				sig.GetDictEntrySignatures (out sigKey, out sigValue);
+				yield return sigKey;
+				yield return sigValue;
+				yield break;
+			}
+
+			if (sig.IsStruct) {
+				pos = Protocol.Padded (pos, sig.Alignment);
+				foreach (Signature fieldSig in sig.GetFieldSignatures ())
+					yield return fieldSig;
+				yield break;
+			}
+
+			throw new Exception ("Can't step into '" + sig + "'");
+			//yield break;
+		}
+	}
+
+	class MessageDumper
+	{
+		public static byte[] ReadBlock (TextReader r)
+		{
+			//if (Body == null)
+			//	return;
+
+			MemoryStream ms = new MemoryStream ();
+
+			while (true) {
+				string ln = r.ReadLine ();
+				if (ln == null)
+					break;
+				if (!ReadFromHex (ms, ln))
+					break;
+			}
+
+			if (ms.Length == 0)
+				return null;
+
+			return ms.ToArray ();
+		}
+
+		public static void WriteComment (string comment, TextWriter w)
+		{
+			w.WriteLine ("# " + comment);
+		}
+
+		public static void WriteBlock (byte[] Body, TextWriter w)
+		{
+			//if (Body == null)
+			//	return;
+			if (Body != null)
+			for (int i = 0 ; i != Body.Length ; i++) {
+				if (i == 0) {}
+				else if (i % 32 == 0)
+					w.WriteLine ();
+				else if (i % 4 == 0)
+					w.Write (' ');
+
+				w.Write (Body[i].ToString ("x2", System.Globalization.CultureInfo.InvariantCulture));
+			}
+
+			w.Write ('.');
+			w.WriteLine ();
+			w.Flush ();
+		}
+
+		public static void WriteMessage (Message msg, TextWriter w)
+		{
+			w.WriteLine ("# Message");
+			w.WriteLine ("# Header");
+			MessageDumper.WriteBlock (msg.GetHeaderData (), w);
+			w.WriteLine ("# Body");
+			MessageDumper.WriteBlock (msg.Body, w);
+			w.WriteLine ();
+			w.Flush ();
+		}
+
+		public static Message ReadMessage (TextReader r)
+		{
+			byte[] header = MessageDumper.ReadBlock (r);
+
+			if (header == null)
+				return null;
+
+			byte[] body = MessageDumper.ReadBlock (r);
+
+			Message msg = new Message ();
+			msg.SetHeaderData (header);
+			msg.Body = body;
+
+			return msg;
+		}
+
+		static byte FromHexChar (char c)
+		{
+			if ((c >= 'a') && (c <= 'f'))
+				return (byte) (c - 'a' + 10);
+			if ((c >= 'A') && (c <= 'F'))
+				return (byte) (c - 'A' + 10);
+			if ((c >= '0') && (c <= '9'))
+				return (byte) (c - '0');
+			throw new ArgumentException ("Invalid hex char");
+		}
+
+		static bool ReadFromHex (Stream ms, string hex)
+		{
+			if (hex.StartsWith ("#"))
+				return true;
+
+			int i = 0;
+			while (i < hex.Length) {
+				if (char.IsWhiteSpace (hex [i])) {
+					i++;
+					continue;
+				}
+
+				if (hex [i] == '.') {
+					ms.Flush ();
+					return false;
+				}
+
+				byte res = (byte) (FromHexChar (hex [i++]) << 4);
+				res += FromHexChar (hex [i++]);
+				ms.WriteByte (res);
+			}
+
+			ms.Flush ();
+			return true;
+		}
+	}
+}
diff --git a/src/MessageFilter.cs b/src/MessageFilter.cs
new file mode 100644
index 0000000..9d2a042
--- /dev/null
+++ b/src/MessageFilter.cs
@@ -0,0 +1,58 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+
+namespace DBus
+{
+	class MessageFilter
+	{
+		//this should probably be made to use HeaderField or similar
+		//this class is not generalized yet
+
+		public static string MessageTypeToString (MessageType mtype)
+		{
+			switch (mtype)
+			{
+				case MessageType.MethodCall:
+					return "method_call";
+				case MessageType.MethodReturn:
+					return "method_return";
+				case MessageType.Error:
+					return "error";
+				case MessageType.Signal:
+					return "signal";
+				case MessageType.Invalid:
+					return "invalid";
+				default:
+					throw new Exception ("Bad MessageType: " + mtype);
+			}
+		}
+
+		public static MessageType StringToMessageType (string text)
+		{
+			switch (text)
+			{
+				case "method_call":
+					return MessageType.MethodCall;
+				case "method_return":
+					return MessageType.MethodReturn;
+				case "error":
+					return MessageType.Error;
+				case "signal":
+					return MessageType.Signal;
+				case "invalid":
+					return MessageType.Invalid;
+				default:
+					throw new Exception ("Bad MessageType: " + text);
+			}
+		}
+
+		//TODO: remove this -- left here for the benefit of the monitor tool for now
+		public static string CreateMatchRule (MessageType mtype)
+		{
+			return "type='" + MessageTypeToString (mtype) + "'";
+		}
+	}
+}
diff --git a/src/MessageReader.cs b/src/MessageReader.cs
new file mode 100644
index 0000000..758b1ac
--- /dev/null
+++ b/src/MessageReader.cs
@@ -0,0 +1,494 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+
+namespace DBus
+{
+	partial class MessageReader
+	{
+		protected EndianFlag endianness;
+		//protected byte[] data;
+		public byte[] data;
+		//TODO: this should be uint or long to handle long messages
+		//internal int pos = 0;
+		public int pos = 0;
+		protected Message message;
+
+		public MessageReader (EndianFlag endianness, byte[] data)
+		{
+			//if (data == null)
+			//	throw new ArgumentNullException ("data");
+			if (data == null)
+				data = new byte[0];
+
+			this.endianness = endianness;
+			this.IsNativeEndian = endianness == Connection.NativeEndianness;
+			this.data = data;
+		}
+
+		public MessageReader (Message message) : this (message.Header.Endianness, message.Body)
+		{
+			if (message == null)
+				throw new ArgumentNullException ("message");
+
+			this.message = message;
+		}
+
+		public readonly bool IsNativeEndian;
+
+		public object ReadValue (Type type)
+		{
+			if (type == typeof (void))
+				return null;
+
+			if (type.IsArray) {
+				return ReadArray (type.GetElementType ());
+			} else if (type == typeof (ObjectPath)) {
+				return ReadObjectPath ();
+			} else if (type == typeof (Signature)) {
+				return ReadSignature ();
+			} else if (type == typeof (object)) {
+				return ReadVariant ();
+			} else if (type == typeof (string)) {
+				return ReadString ();
+			} else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (IDictionary<,>)) {
+				Type[] genArgs = type.GetGenericArguments ();
+				//Type dictType = typeof (Dictionary<,>).MakeGenericType (genArgs);
+				//workaround for Mono bug #81035 (memory leak)
+				Type dictType = Mapper.GetGenericType (typeof (Dictionary<,>), genArgs);
+				System.Collections.IDictionary idict = (System.Collections.IDictionary)Activator.CreateInstance(dictType, new object[0]);
+				GetValueToDict (genArgs[0], genArgs[1], idict);
+				return idict;
+			} else if (Mapper.IsPublic (type)) {
+				return GetObject (type);
+			} else if (!type.IsPrimitive && !type.IsEnum) {
+				return ReadStruct (type);
+			} else {
+				object val;
+				DType dtype = Signature.TypeToDType (type);
+				val = ReadValue (dtype);
+
+				if (type.IsEnum)
+					val = Enum.ToObject (type, val);
+
+				return val;
+			}
+		}
+
+		//helper method, should not be used generally
+		public object ReadValue (DType dtype)
+		{
+			switch (dtype)
+			{
+				case DType.Byte:
+					return ReadByte ();
+
+				case DType.Boolean:
+					return ReadBoolean ();
+
+				case DType.Int16:
+					return ReadInt16 ();
+
+				case DType.UInt16:
+					return ReadUInt16 ();
+
+				case DType.Int32:
+					return ReadInt32 ();
+
+				case DType.UInt32:
+					return ReadUInt32 ();
+
+				case DType.Int64:
+					return ReadInt64 ();
+
+				case DType.UInt64:
+					return ReadUInt64 ();
+
+#if !DISABLE_SINGLE
+				case DType.Single:
+					return ReadSingle ();
+#endif
+
+				case DType.Double:
+					return ReadDouble ();
+
+				case DType.String:
+					return ReadString ();
+
+				case DType.ObjectPath:
+					return ReadObjectPath ();
+
+				case DType.Signature:
+					return ReadSignature ();
+
+				case DType.Variant:
+					return ReadVariant ();
+
+				default:
+					throw new Exception ("Unhandled D-Bus type: " + dtype);
+			}
+		}
+
+		public object GetObject (Type type)
+		{
+			ObjectPath path = ReadObjectPath ();
+
+			return message.Connection.GetObject (type, (string)message.Header[FieldCode.Sender], path);
+		}
+
+		public byte ReadByte ()
+		{
+			return data[pos++];
+		}
+
+		public bool ReadBoolean ()
+		{
+			uint intval = ReadUInt32 ();
+
+			switch (intval) {
+				case 0:
+					return false;
+				case 1:
+					return true;
+				default:
+					throw new Exception ("Read value " + intval + " at position " + pos + " while expecting boolean (0/1)");
+			}
+		}
+
+		unsafe protected void MarshalUShort (void* dstPtr)
+		{
+			ReadPad (2);
+
+			if (data.Length < pos + 2)
+				throw new Exception ("Cannot read beyond end of data");
+
+			if (endianness == Connection.NativeEndianness) {
+				fixed (byte* p = &data[pos])
+					*((ushort*)dstPtr) = *((ushort*)p);
+			} else {
+				byte* dst = (byte*)dstPtr;
+				dst[0] = data[pos + 1];
+				dst[1] = data[pos + 0];
+			}
+
+			pos += 2;
+		}
+
+		unsafe public short ReadInt16 ()
+		{
+			short val;
+
+			MarshalUShort (&val);
+
+			return val;
+		}
+
+		unsafe public ushort ReadUInt16 ()
+		{
+			ushort val;
+
+			MarshalUShort (&val);
+
+			return val;
+		}
+
+		unsafe protected void MarshalUInt (void* dstPtr)
+		{
+			ReadPad (4);
+
+			if (data.Length < pos + 4)
+				throw new Exception ("Cannot read beyond end of data");
+
+			if (endianness == Connection.NativeEndianness) {
+				fixed (byte* p = &data[pos])
+					*((uint*)dstPtr) = *((uint*)p);
+			} else {
+				byte* dst = (byte*)dstPtr;
+				dst[0] = data[pos + 3];
+				dst[1] = data[pos + 2];
+				dst[2] = data[pos + 1];
+				dst[3] = data[pos + 0];
+			}
+
+			pos += 4;
+		}
+
+		unsafe public int ReadInt32 ()
+		{
+			int val;
+
+			MarshalUInt (&val);
+
+			return val;
+		}
+
+		unsafe public uint ReadUInt32 ()
+		{
+			uint val;
+
+			MarshalUInt (&val);
+
+			return val;
+		}
+
+		unsafe protected void MarshalULong (void* dstPtr)
+		{
+			ReadPad (8);
+
+			if (data.Length < pos + 8)
+				throw new Exception ("Cannot read beyond end of data");
+
+			if (endianness == Connection.NativeEndianness) {
+				fixed (byte* p = &data[pos])
+					*((ulong*)dstPtr) = *((ulong*)p);
+			} else {
+				byte* dst = (byte*)dstPtr;
+				for (int i = 0; i < 8; ++i)
+					dst[i] = data[pos + (7 - i)];
+			}
+
+			pos += 8;
+		}
+
+		unsafe public long ReadInt64 ()
+		{
+			long val;
+
+			MarshalULong (&val);
+
+			return val;
+		}
+
+		unsafe public ulong ReadUInt64 ()
+		{
+			ulong val;
+
+			MarshalULong (&val);
+
+			return val;
+		}
+
+#if !DISABLE_SINGLE
+		unsafe public float ReadSingle ()
+		{
+			float val;
+
+			MarshalUInt (&val);
+
+			return val;
+		}
+#endif
+
+		unsafe public double ReadDouble ()
+		{
+			double val;
+
+			MarshalULong (&val);
+
+			return val;
+		}
+
+		public string ReadString ()
+		{
+			uint ln = ReadUInt32 ();
+
+			string val = Encoding.UTF8.GetString (data, pos, (int)ln);
+			pos += (int)ln;
+			ReadNull ();
+
+			return val;
+		}
+
+		public ObjectPath ReadObjectPath ()
+		{
+			//exactly the same as string
+			return new ObjectPath (ReadString ());
+		}
+
+		public Signature ReadSignature ()
+		{
+			byte ln = ReadByte ();
+
+			// Avoid an array allocation for small signatures
+			if (ln == 1) {
+				DType dtype = (DType)ReadByte ();
+				ReadNull ();
+				return new Signature (dtype);
+			}
+
+			if (ln > Protocol.MaxSignatureLength)
+				throw new Exception ("Signature length " + ln + " exceeds maximum allowed " + Protocol.MaxSignatureLength + " bytes");
+
+			byte[] sigData = new byte[ln];
+			Array.Copy (data, pos, sigData, 0, (int)ln);
+			pos += (int)ln;
+			ReadNull ();
+
+			return Signature.Take (sigData);
+		}
+
+		public object ReadVariant ()
+		{
+			return ReadValue (ReadSignature ());
+		}
+
+		// Used primarily for reading variant values
+		object ReadValue (Signature sig)
+		{
+			if (sig.IsPrimitive)
+				return ReadValue (sig[0]);
+
+			Type t = null;
+			try {
+				t = sig.ToType ();
+			} catch (NotSupportedException e) {
+				// We don't catch other exceptions as they indicate a malformed signature
+				if (Protocol.Verbose)
+					Console.Error.WriteLine (e.Message);
+			}
+
+			/*
+			if (t == null) {
+				StepOver (sig);
+				return null;
+			}
+			*/
+
+			if (t == null) {
+				ReadPad (sig.Alignment);
+				int startPos = pos;
+				StepOver (sig);
+				int ln = pos - startPos;
+
+				DValue dv = new DValue();
+				dv.endianness = endianness;
+				dv.signature = sig;
+				dv.data = new byte[ln];
+				Array.Copy (data, startPos, dv.data, 0, ln);
+				return dv;
+			}
+
+			return ReadValue (t);
+		}
+
+		//not pretty or efficient but works
+		public void GetValueToDict (Type keyType, Type valType, System.Collections.IDictionary val)
+		{
+			uint ln = ReadUInt32 ();
+
+			if (ln > Protocol.MaxArrayLength)
+				throw new Exception ("Dict length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+			//advance to the alignment of the element
+			//ReadPad (Protocol.GetAlignment (Signature.TypeToDType (type)));
+			ReadPad (8);
+
+			int endPos = pos + (int)ln;
+
+			//while (stream.Position != endPos)
+			while (pos < endPos)
+			{
+				ReadPad (8);
+
+				val.Add (ReadValue (keyType), ReadValue (valType));
+			}
+
+			if (pos != endPos)
+				throw new Exception ("Read pos " + pos + " != ep " + endPos);
+		}
+
+		//this could be made generic to avoid boxing
+		public Array ReadArray (Type elemType)
+		{
+			uint ln = ReadUInt32 ();
+
+			if (ln > Protocol.MaxArrayLength)
+				throw new Exception ("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+			//TODO: more fast paths for primitive arrays
+			if (elemType == typeof (byte)) {
+				byte[] valb = new byte[ln];
+				Array.Copy (data, pos, valb, 0, (int)ln);
+				pos += (int)ln;
+				return valb;
+			}
+
+			//advance to the alignment of the element
+			ReadPad (Protocol.GetAlignment (Signature.TypeToDType (elemType)));
+
+			int endPos = pos + (int)ln;
+
+			//List<T> vals = new List<T> ();
+			System.Collections.ArrayList vals = new System.Collections.ArrayList ();
+
+			//while (stream.Position != endPos)
+			while (pos < endPos)
+				vals.Add (ReadValue (elemType));
+
+			if (pos != endPos)
+				throw new Exception ("Read pos " + pos + " != ep " + endPos);
+
+			return vals.ToArray (elemType);
+		}
+
+		//struct
+		//probably the wrong place for this
+		//there might be more elegant solutions
+		public object ReadStruct (Type type)
+		{
+			ReadPad (8);
+
+			object val = Activator.CreateInstance (type);
+
+			/*
+			if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (KeyValuePair<,>)) {
+				object elem;
+
+				System.Reflection.PropertyInfo key_prop = type.GetProperty ("Key");
+				GetValue (key_prop.PropertyType, out elem);
+				key_prop.SetValue (val, elem, null);
+
+				System.Reflection.PropertyInfo val_prop = type.GetProperty ("Value");
+				GetValue (val_prop.PropertyType, out elem);
+				val_prop.SetValue (val, elem, null);
+
+				return;
+			}
+			*/
+
+			FieldInfo[] fis = type.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+
+			foreach (System.Reflection.FieldInfo fi in fis)
+				fi.SetValue (val, ReadValue (fi.FieldType));
+
+			return val;
+		}
+
+		public void ReadNull ()
+		{
+			if (data[pos] != 0)
+				throw new Exception ("Read non-zero byte at position " + pos + " while expecting null terminator");
+			pos++;
+		}
+
+		/*
+		public void ReadPad (int alignment)
+		{
+			pos = Protocol.Padded (pos, alignment);
+		}
+		*/
+
+		public void ReadPad (int alignment)
+		{
+			for (int endPos = Protocol.Padded (pos, alignment) ; pos != endPos ; pos++)
+				if (data[pos] != 0)
+					throw new Exception ("Read non-zero byte at position " + pos + " while expecting padding");
+		}
+	}
+}
diff --git a/src/MessageWriter.cs b/src/MessageWriter.cs
new file mode 100644
index 0000000..bbe25d9
--- /dev/null
+++ b/src/MessageWriter.cs
@@ -0,0 +1,570 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace DBus
+{
+	sealed class MessageWriter
+	{
+		EndianFlag endianness;
+		internal MemoryStream stream;
+
+		public Connection connection;
+
+		//a default constructor is a bad idea for now as we want to make sure the header and content-type match
+		public MessageWriter () : this (Connection.NativeEndianness) {}
+
+		public MessageWriter (EndianFlag endianness)
+		{
+			this.endianness = endianness;
+			stream = new MemoryStream ();
+		}
+
+		public byte[] ToArray ()
+		{
+			//TODO: mark the writer locked or something here
+			return stream.ToArray ();
+		}
+
+		public void ToStream (Stream dest)
+		{
+			stream.WriteTo (dest);
+		}
+
+		public void CloseWrite ()
+		{
+			WritePad (8);
+		}
+
+		public void Write (byte val)
+		{
+			stream.WriteByte (val);
+		}
+
+		public void Write (bool val)
+		{
+			Write ((uint) (val ? 1 : 0));
+		}
+
+		// Buffer for integer marshaling
+		byte[] dst = new byte[8];
+		unsafe void MarshalUShort (void* dataPtr)
+		{
+			WritePad (2);
+
+			if (endianness == Connection.NativeEndianness) {
+				fixed (byte* p = &dst[0])
+					*((ushort*)p) = *((ushort*)dataPtr);
+			} else {
+				byte* data = (byte*)dataPtr;
+				dst[0] = data[1];
+				dst[1] = data[0];
+			}
+
+			stream.Write (dst, 0, 2);
+		}
+
+		unsafe public void Write (short val)
+		{
+			MarshalUShort (&val);
+		}
+
+		unsafe public void Write (ushort val)
+		{
+			MarshalUShort (&val);
+		}
+
+		unsafe void MarshalUInt (void* dataPtr)
+		{
+			WritePad (4);
+
+			if (endianness == Connection.NativeEndianness) {
+				fixed (byte* p = &dst[0])
+					*((uint*)p) = *((uint*)dataPtr);
+			} else {
+				byte* data = (byte*)dataPtr;
+				dst[0] = data[3];
+				dst[1] = data[2];
+				dst[2] = data[1];
+				dst[3] = data[0];
+			}
+
+			stream.Write (dst, 0, 4);
+		}
+
+		unsafe public void Write (int val)
+		{
+			MarshalUInt (&val);
+		}
+
+		unsafe public void Write (uint val)
+		{
+			MarshalUInt (&val);
+		}
+
+		unsafe void MarshalULong (void* dataPtr)
+		{
+			WritePad (8);
+
+			if (endianness == Connection.NativeEndianness) {
+				fixed (byte* p = &dst[0])
+					*((ulong*)p) = *((ulong*)dataPtr);
+			} else {
+				byte* data = (byte*)dataPtr;
+				for (int i = 0; i < 8; ++i)
+					dst[i] = data[7 - i];
+			}
+
+			stream.Write (dst, 0, 8);
+		}
+
+		unsafe public void Write (long val)
+		{
+			MarshalULong (&val);
+		}
+
+		unsafe public void Write (ulong val)
+		{
+			MarshalULong (&val);
+		}
+
+#if !DISABLE_SINGLE
+		unsafe public void Write (float val)
+		{
+			MarshalUInt (&val);
+		}
+#endif
+
+		unsafe public void Write (double val)
+		{
+			MarshalULong (&val);
+		}
+
+		public void Write (string val)
+		{
+			byte[] utf8_data = Encoding.UTF8.GetBytes (val);
+			Write ((uint)utf8_data.Length);
+			stream.Write (utf8_data, 0, utf8_data.Length);
+			WriteNull ();
+		}
+
+		public void Write (ObjectPath val)
+		{
+			Write (val.Value);
+		}
+
+		public void Write (Signature val)
+		{
+			byte[] ascii_data = val.GetBuffer ();
+
+			if (ascii_data.Length > Protocol.MaxSignatureLength)
+				throw new Exception ("Signature length " + ascii_data.Length + " exceeds maximum allowed " + Protocol.MaxSignatureLength + " bytes");
+
+			Write ((byte)ascii_data.Length);
+			stream.Write (ascii_data, 0, ascii_data.Length);
+			WriteNull ();
+		}
+
+		[Obsolete]
+		public void WriteComplex (object val, Type type)
+		{
+			if (type == typeof (void))
+				return;
+
+			if (type.IsArray) {
+				MethodInfo miDict = typeof (MessageWriter).GetMethod ("WriteArray");
+				MethodInfo mi = miDict.MakeGenericMethod (type.GetElementType ());
+				mi.Invoke (this, new object[] {val});
+			} else if (type.IsGenericType && (type.GetGenericTypeDefinition () == typeof (IDictionary<,>) || type.GetGenericTypeDefinition () == typeof (Dictionary<,>))) {
+				Type[] genArgs = type.GetGenericArguments ();
+				MethodInfo miDict = typeof (MessageWriter).GetMethod ("WriteFromDict");
+				MethodInfo mi = miDict.MakeGenericMethod (genArgs);
+				mi.Invoke (this, new object[] {val});
+			} else if (Mapper.IsPublic (type)) {
+				WriteObject (type, val);
+			} else if (!type.IsPrimitive && !type.IsEnum) {
+				WriteValueType (val, type);
+				/*
+			} else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>)) {
+				//is it possible to support nullable types?
+				Type[] genArgs = type.GetGenericArguments ();
+				WriteVariant (genArgs[0], val);
+				*/
+			} else {
+				throw new Exception ("Can't write");
+			}
+		}
+
+		[Obsolete]
+		public void Write (Type type, object val)
+		{
+			if (type == typeof (void))
+				return;
+
+			if (type.IsArray) {
+				MethodInfo miDict = typeof (MessageWriter).GetMethod ("WriteArray");
+				MethodInfo mi = miDict.MakeGenericMethod (type.GetElementType ());
+				mi.Invoke (this, new object[] {val});
+			} else if (type == typeof (ObjectPath)) {
+				Write ((ObjectPath)val);
+			} else if (type == typeof (Signature)) {
+				Write ((Signature)val);
+			} else if (type == typeof (object)) {
+				Write (val);
+			} else if (type == typeof (string)) {
+				Write ((string)val);
+			} else if (type.IsGenericType && (type.GetGenericTypeDefinition () == typeof (IDictionary<,>) || type.GetGenericTypeDefinition () == typeof (Dictionary<,>))) {
+				Type[] genArgs = type.GetGenericArguments ();
+				MethodInfo miDict = typeof (MessageWriter).GetMethod ("WriteFromDict");
+				MethodInfo mi = miDict.MakeGenericMethod (genArgs);
+				mi.Invoke (this, new object[] {val});
+			} else if (Mapper.IsPublic (type)) {
+				WriteObject (type, val);
+			} else if (!type.IsPrimitive && !type.IsEnum) {
+				WriteValueType (val, type);
+			} else {
+				Write (Signature.TypeToDType (type), val);
+			}
+		}
+
+		//helper method, should not be used as it boxes needlessly
+		public void Write (DType dtype, object val)
+		{
+			switch (dtype)
+			{
+				case DType.Byte:
+				{
+					Write ((byte)val);
+				}
+				break;
+				case DType.Boolean:
+				{
+					Write ((bool)val);
+				}
+				break;
+				case DType.Int16:
+				{
+					Write ((short)val);
+				}
+				break;
+				case DType.UInt16:
+				{
+					Write ((ushort)val);
+				}
+				break;
+				case DType.Int32:
+				{
+					Write ((int)val);
+				}
+				break;
+				case DType.UInt32:
+				{
+					Write ((uint)val);
+				}
+				break;
+				case DType.Int64:
+				{
+					Write ((long)val);
+				}
+				break;
+				case DType.UInt64:
+				{
+					Write ((ulong)val);
+				}
+				break;
+#if !DISABLE_SINGLE
+				case DType.Single:
+				{
+					Write ((float)val);
+				}
+				break;
+#endif
+				case DType.Double:
+				{
+					Write ((double)val);
+				}
+				break;
+				case DType.String:
+				{
+					Write ((string)val);
+				}
+				break;
+				case DType.ObjectPath:
+				{
+					Write ((ObjectPath)val);
+				}
+				break;
+				case DType.Signature:
+				{
+					Write ((Signature)val);
+				}
+				break;
+				case DType.Variant:
+				{
+					Write ((object)val);
+				}
+				break;
+				default:
+				throw new Exception ("Unhandled D-Bus type: " + dtype);
+			}
+		}
+
+		public void WriteObject (Type type, object val)
+		{
+			ObjectPath path;
+
+			BusObject bobj = val as BusObject;
+
+			if (bobj == null && val is MarshalByRefObject) {
+				bobj = ((MarshalByRefObject)val).GetLifetimeService () as BusObject;
+			}
+
+			if (bobj == null)
+				throw new Exception ("No object reference to write");
+
+			path = bobj.Path;
+
+			Write (path);
+		}
+
+		//variant
+		public void Write (object val)
+		{
+			if (val == null)
+				throw new NotSupportedException ("Cannot send null variant");
+
+			if (val is DValue) {
+				DValue dv = (DValue)val;
+
+				if (dv.endianness != endianness)
+					throw new NotImplementedException ("Writing opposite endian DValues not yet implemented.");
+
+				Write (dv.signature);
+				WritePad (dv.signature.Alignment);
+				stream.Write (dv.data, 0, dv.data.Length);
+				return;
+			}
+
+			Type type = val.GetType ();
+
+			WriteVariant (type, val);
+		}
+
+		public void WriteVariant (Type type, object val)
+		{
+			Signature sig = Signature.GetSig (type);
+
+			Write (sig);
+			Write (type, val);
+		}
+
+		//this requires a seekable stream for now
+		public unsafe void WriteArray<T> (T[] val)
+		{
+			Type elemType = typeof (T);
+
+			if (elemType == typeof (byte)) {
+				if (val.Length > Protocol.MaxArrayLength)
+					throw new Exception ("Array length " + val.Length + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+				Write ((uint)val.Length);
+				stream.Write ((byte[])(object)val, 0, val.Length);
+				return;
+			}
+
+			if (elemType.IsEnum)
+				elemType = Enum.GetUnderlyingType (elemType);
+
+			Signature sigElem = Signature.GetSig (elemType);
+			int fixedSize = 0;
+			if (endianness == Connection.NativeEndianness && elemType.IsValueType && !sigElem.IsStruct && sigElem.GetFixedSize (ref fixedSize)) {
+				int byteLength = fixedSize * val.Length;
+				if (byteLength > Protocol.MaxArrayLength)
+					throw new Exception ("Array length " + byteLength + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+				Write ((uint)byteLength);
+				WritePad (sigElem.Alignment);
+
+				GCHandle valHandle = GCHandle.Alloc (val, GCHandleType.Pinned);
+				IntPtr p = valHandle.AddrOfPinnedObject ();
+				byte[] data = new byte[byteLength];
+				byte* bp = (byte*)p;
+				for (int i = 0 ; i != byteLength ; i++)
+					data[i] = bp[i];
+				stream.Write (data, 0, data.Length);
+				valHandle.Free ();
+				return;
+			}
+
+			long origPos = stream.Position;
+			Write ((uint)0);
+
+			//advance to the alignment of the element
+			WritePad (sigElem.Alignment);
+
+			long startPos = stream.Position;
+
+			TypeWriter<T> tWriter = TypeImplementer.GetTypeWriter<T> ();
+
+			foreach (T elem in val)
+				tWriter (this, elem);
+
+			long endPos = stream.Position;
+			uint ln = (uint)(endPos - startPos);
+			stream.Position = origPos;
+
+			if (ln > Protocol.MaxArrayLength)
+				throw new Exception ("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+			Write (ln);
+			stream.Position = endPos;
+		}
+
+		public void WriteValueType (object val, Type type)
+		{
+			MethodInfo mi = TypeImplementer.GetWriteMethod (type);
+			mi.Invoke (null, new object[] {this, val});
+		}
+
+		public void WriteStructure<T> (T value)
+		{
+			TypeWriter<T> tWriter = TypeImplementer.GetTypeWriter<T> ();
+			tWriter (this, value);
+		}
+
+		public void WriteFromDict<TKey,TValue> (IDictionary<TKey,TValue> val)
+		{
+			long origPos = stream.Position;
+			Write ((uint)0);
+
+			WritePad (8);
+
+			long startPos = stream.Position;
+
+			TypeWriter<TKey> keyWriter = TypeImplementer.GetTypeWriter<TKey> ();
+			TypeWriter<TValue> valueWriter = TypeImplementer.GetTypeWriter<TValue> ();
+
+			foreach (KeyValuePair<TKey,TValue> entry in val)
+			{
+				WritePad (8);
+				keyWriter (this, entry.Key);
+				valueWriter (this, entry.Value);
+			}
+
+			long endPos = stream.Position;
+			uint ln = (uint)(endPos - startPos);
+			stream.Position = origPos;
+
+			if (ln > Protocol.MaxArrayLength)
+				throw new Exception ("Dict length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+			Write (ln);
+			stream.Position = endPos;
+		}
+
+		/*
+		public void Write (IDictionary<FieldCode, object> val)
+		{
+			WriteHeaderDict(val);
+		}
+
+		public void Write (Dictionary<FieldCode, object> val)
+		{
+			WriteHeaderDict (val);
+		}
+		*/
+
+		/*
+		public void Write (Dictionary<byte, object> val)
+		{
+			long origPos = stream.Position;
+			Write ((uint)0);
+
+			WritePad (8);
+
+			long startPos = stream.Position;
+
+			foreach (KeyValuePair<byte, object> entry in val) {
+				WritePad (8);
+				Write (entry.Key);
+				Write (entry.Value);
+			}
+
+			long endPos = stream.Position;
+			uint ln = (uint)(endPos - startPos);
+			stream.Position = origPos;
+
+			if (ln > Protocol.MaxArrayLength)
+				throw new Exception ("Dict length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+			Write (ln);
+			stream.Position = endPos;
+		}
+		*/
+
+		internal void WriteHeaderFields (Dictionary<byte, object> val)
+		{
+			long origPos = stream.Position;
+			Write ((uint)0);
+
+			WritePad (8);
+
+			long startPos = stream.Position;
+
+			foreach (KeyValuePair<byte, object> entry in val) {
+				WritePad (8);
+				Write (entry.Key);
+				switch ((FieldCode)entry.Key) {
+					case FieldCode.Destination:
+					case FieldCode.ErrorName:
+					case FieldCode.Interface:
+					case FieldCode.Member:
+					case FieldCode.Sender:
+						Write (Signature.StringSig);
+						Write ((string)entry.Value);
+						break;
+					case FieldCode.Path:
+						Write (Signature.ObjectPathSig);
+						Write ((ObjectPath)entry.Value);
+						break;
+					case FieldCode.ReplySerial:
+						Write (Signature.UInt32Sig);
+						Write ((uint)entry.Value);
+						break;
+					default:
+						Write (entry.Value);
+						break;
+				}
+			}
+
+			long endPos = stream.Position;
+			uint ln = (uint)(endPos - startPos);
+			stream.Position = origPos;
+
+			if (ln > Protocol.MaxArrayLength)
+				throw new Exception ("Dict length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
+
+			Write (ln);
+			stream.Position = endPos;
+		}
+
+		public void WriteNull ()
+		{
+			stream.WriteByte (0);
+		}
+
+		// Source buffer for zero-padding
+		static readonly byte[] nullBytes = new byte[8];
+		public void WritePad (int alignment)
+		{
+			int needed = Protocol.PadNeeded ((int)stream.Position, alignment);
+			stream.Write (nullBytes, 0, needed);
+		}
+	}
+}
diff --git a/src/PendingCall.cs b/src/PendingCall.cs
new file mode 100644
index 0000000..09e5e16
--- /dev/null
+++ b/src/PendingCall.cs
@@ -0,0 +1,111 @@
+// Copyright 2007 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Threading;
+
+namespace DBus
+{
+	class PendingCall : IAsyncResult
+	{
+		Connection conn;
+		Message reply = null;
+		//AutoResetEvent waitHandle = new AutoResetEvent (false);
+		ManualResetEvent waitHandle;
+
+		public PendingCall (Connection conn)
+		{
+			this.conn = conn;
+		}
+
+		public Message Reply
+		{
+			get {
+				if (reply != null)
+					return reply;
+
+				if (Thread.CurrentThread == conn.mainThread) {
+					/*
+					while (reply == null)
+						conn.Iterate ();
+					*/
+
+					while (reply == null)
+						conn.HandleMessage (conn.Transport.ReadMessage ());
+
+					completedSync = true;
+
+					conn.DispatchSignals ();
+				} else {
+					if (waitHandle == null)
+						waitHandle = new ManualResetEvent (false);
+
+					// TODO: Possible race condition?
+					while (reply == null)
+						waitHandle.WaitOne ();
+
+					completedSync = false;
+				}
+
+				return reply;
+			} set {
+				if (reply != null)
+					throw new Exception ("Cannot handle reply more than once");
+
+				reply = value;
+
+				if (waitHandle != null)
+					waitHandle.Set ();
+
+				if (Completed != null)
+					Completed (reply);
+			}
+		}
+
+		public event Action<Message> Completed;
+		bool completedSync;
+
+		public void Cancel ()
+		{
+			throw new NotImplementedException ();
+		}
+
+
+
+		#region IAsyncResult Members
+
+		object IAsyncResult.AsyncState
+		{
+			get {
+				return conn;
+			}
+		}
+
+		WaitHandle IAsyncResult.AsyncWaitHandle
+		{
+			get {
+				if (waitHandle == null)
+					waitHandle = new ManualResetEvent (false);
+
+				return waitHandle;
+			}
+		}
+
+		bool IAsyncResult.CompletedSynchronously
+		{
+			get {
+				return reply != null && completedSync;
+			}
+		}
+
+		bool IAsyncResult.IsCompleted
+		{
+			get {
+				return reply != null;
+			}
+		}
+
+		#endregion
+	}
+}
diff --git a/src/Protocol.cs b/src/Protocol.cs
new file mode 100644
index 0000000..d7a5df4
--- /dev/null
+++ b/src/Protocol.cs
@@ -0,0 +1,525 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+
+namespace DBus
+{
+	//yyyyuua{yv}
+	//struct Header
+	class Header
+	{
+		public EndianFlag Endianness;
+		public MessageType MessageType;
+		public HeaderFlag Flags;
+		public byte MajorVersion;
+		public uint Length;
+		public uint Serial;
+		//public HeaderField[] Fields;
+
+		// Dictionary keyed by Enum has performance issues on .NET
+		// So we key by byte and use an indexer instead.
+		public Dictionary<byte, object> Fields;
+		public object this[FieldCode key]
+		{
+			get
+			{
+				object value = null;
+				Fields.TryGetValue ((byte)key, out value);
+				return value;
+			} set {
+				if (value == null)
+					Fields.Remove((byte)key);
+				else
+					Fields[(byte)key] = value;
+			}
+		}
+
+		/*
+		public static DType TypeForField (FieldCode f)
+		{
+			switch (f) {
+				case FieldCode.Invalid:
+					return DType.Invalid;
+				case FieldCode.Path:
+					return DType.ObjectPath;
+				case FieldCode.Interface:
+					return DType.String;
+				case FieldCode.Member:
+					return DType.String;
+				case FieldCode.ErrorName:
+					return DType.String;
+				case FieldCode.ReplySerial:
+					return DType.UInt32;
+				case FieldCode.Destination:
+					return DType.String;
+				case FieldCode.Sender:
+					return DType.String;
+				case FieldCode.Signature:
+					return DType.Signature;
+#if PROTO_REPLY_SIGNATURE
+				case FieldCode.ReplySignature: //note: not supported in dbus
+					return DType.Signature;
+#endif
+				default:
+					return DType.Invalid;
+			}
+		}
+		*/
+	}
+
+	/*
+	public struct HeaderField
+	{
+		//public HeaderField (FieldCode code, object value)
+		//{
+		//	this.Code = code;
+		//	this.Value = value;
+		//}
+
+		public static HeaderField Create (FieldCode code, object value)
+		{
+			HeaderField hf;
+
+			hf.Code = code;
+			hf.Value = value;
+
+			return hf;
+		}
+
+		public FieldCode Code;
+		public object Value;
+	}
+	*/
+
+	/*
+	struct HeaderFieldSet
+	{
+		public ObjectPath Path;
+		public string Interface;
+		public string Member;
+		public string ErrorName;
+		public uint ReplySerial;
+		public string Destination;
+		public string Sender;
+		//public Signature Signature;
+		public Signature Sig;
+
+#if PROTO_REPLY_SIGNATURE
+		public Signature ReplySignature;
+#endif
+
+		public void Read (MessageReader reader)
+		{
+			FieldCode code = (FieldCode)reader.ReadByte ();
+		}
+
+		public void Write (MessageWriter writer)
+		{
+			// TODO: Write overall length
+
+			if (Path != null) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.Path);
+				writer.Write (Signature.ObjectPathSig);
+				writer.Write (Path);
+			}
+
+			if (Interface != null) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.Interface);
+				writer.Write (Signature.StringSig);
+				writer.Write (Interface);
+			}
+
+			if (Member != null) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.Member);
+				writer.Write (Signature.StringSig);
+				writer.Write (Member);
+			}
+
+			if (ErrorName != null) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.ErrorName);
+				writer.Write (Signature.StringSig);
+				writer.Write (ErrorName);
+			}
+
+			if (ReplySerial != 0) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.ReplySerial);
+				writer.Write (Signature.UInt32Sig);
+				writer.Write (ReplySerial);
+			}
+
+			if (Destination != null) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.Destination);
+				writer.Write (Signature.StringSig);
+				writer.Write (Destination);
+			}
+
+			if (Sender != null) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.Sender);
+				writer.Write (Signature.StringSig);
+				writer.Write (Sender);
+			}
+
+			if (Sig != Signature.Empty) {
+				writer.WritePad (8);
+				writer.Write ((byte)FieldCode.Signature);
+				writer.Write (Signature.SignatureSig);
+				writer.Write (Sig);
+			}
+		}
+	}
+	*/
+
+	enum MessageType : byte
+	{
+		//This is an invalid type.
+		Invalid,
+		//Method call.
+		MethodCall,
+		//Method reply with returned data.
+		MethodReturn,
+		//Error reply. If the first argument exists and is a string, it is an error message.
+		Error,
+		//Signal emission.
+		Signal,
+	}
+
+	enum FieldCode : byte
+	{
+		Invalid,
+			Path,
+			Interface,
+			Member,
+			ErrorName,
+			ReplySerial,
+			Destination,
+			Sender,
+			Signature,
+#if PROTO_REPLY_SIGNATURE
+			ReplySignature, //note: not supported in dbus
+#endif
+	}
+
+	enum EndianFlag : byte
+	{
+		Little = (byte)'l',
+		Big = (byte)'B',
+	}
+
+	[Flags]
+	enum HeaderFlag : byte
+	{
+		None = 0,
+		NoReplyExpected = 0x1,
+		NoAutoStart = 0x2,
+	}
+
+	public sealed class ObjectPath : IComparable, IComparable<ObjectPath>, IEquatable<ObjectPath>
+	{
+		public static readonly ObjectPath Root = new ObjectPath ("/");
+
+		internal readonly string Value;
+
+		public ObjectPath (string value)
+		{
+			if (value == null)
+				throw new ArgumentNullException ("value");
+
+			Validate (value);
+
+			this.Value = value;
+		}
+
+		static void Validate (string value)
+		{
+			if (!value.StartsWith ("/"))
+				throw new ArgumentException ("value");
+			if (value.EndsWith ("/") && value.Length > 1)
+				throw new ArgumentException ("ObjectPath cannot end in '/'");
+
+			bool multipleSlash = false;
+
+			foreach (char c in value) {
+				bool valid = (c >= 'a' && c <='z')
+					|| (c >= 'A' && c <= 'Z')
+					|| (c >= '0' && c <= '9')
+					|| c == '_'
+					|| (!multipleSlash && c == '/');
+
+				if (!valid) {
+					var message = string.Format ("'{0}' is not a valid character in an ObjectPath", c);
+					throw new ArgumentException (message, "value");
+				}
+
+				multipleSlash = c == '/';
+			}
+
+		}
+
+		public int CompareTo (ObjectPath other)
+		{
+			if (other == null)
+				return 1;
+
+			return Value.CompareTo (other.Value);
+		}
+
+		public int CompareTo (object otherObject)
+		{
+			ObjectPath other = otherObject as ObjectPath;
+
+			if (other == null)
+				return 1;
+
+			return Value.CompareTo (other.Value);
+		}
+
+		public bool Equals (ObjectPath other)
+		{
+			if (other == null)
+				return false;
+
+			return Value == other.Value;
+		}
+
+		public override bool Equals (object o)
+		{
+			ObjectPath b = o as ObjectPath;
+
+			if (b == null)
+				return false;
+
+			return Value.Equals (b.Value);
+		}
+
+		public static bool operator == (ObjectPath a, ObjectPath b)
+		{
+			object aa = a, bb = b;
+			if (aa == null && bb == null)
+				return true;
+
+			if (aa == null || bb == null)
+				return false;
+
+			return a.Value == b.Value;
+		}
+
+		public static bool operator != (ObjectPath a, ObjectPath b)
+		{
+			return !(a == b);
+		}
+
+		public override int GetHashCode ()
+		{
+			return Value.GetHashCode ();
+		}
+
+		public override string ToString ()
+		{
+			return Value;
+		}
+
+		//this may or may not prove useful
+		internal string[] Decomposed
+		{
+			get {
+				return Value.Split (new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
+			/*
+			} set {
+				Value = String.Join ("/", value);
+			*/
+			}
+		}
+
+		internal ObjectPath Parent
+		{
+			get {
+				if (Value == Root.Value)
+					return null;
+
+				string par = Value.Substring (0, Value.LastIndexOf ('/'));
+				if (par == String.Empty)
+					par = "/";
+
+				return new ObjectPath (par);
+			}
+		}
+
+		/*
+		public int CompareTo (object value)
+		{
+			return 1;
+		}
+
+		public int CompareTo (ObjectPath value)
+		{
+			return 1;
+		}
+
+		public bool Equals (ObjectPath value)
+		{
+			return false;
+		}
+		*/
+	}
+
+	static class Protocol
+	{
+		//protocol versions that we support
+		public const byte MinVersion = 0;
+		public const byte Version = 1;
+		public const byte MaxVersion = Version + 1;
+
+		public const uint MaxMessageLength = 134217728; //2 to the 27th power
+		public const uint MaxArrayLength = 67108864; //2 to the 26th power
+		public const uint MaxSignatureLength = 255;
+		public const uint MaxArrayDepth = 32;
+		public const uint MaxStructDepth = 32;
+
+		//this is not strictly related to Protocol since names are passed around as strings
+		internal const uint MaxNameLength = 255;
+		internal const uint MaxMatchRuleLength = 1024;
+		internal const uint MaxMatchRuleArgs = 64;
+
+		public static int PadNeeded (int pos, int alignment)
+		{
+			int pad = pos % alignment;
+			pad = pad == 0 ? 0 : alignment - pad;
+
+			return pad;
+		}
+
+		public static int Padded (int pos, int alignment)
+		{
+			int pad = pos % alignment;
+			if (pad != 0)
+				pos += alignment - pad;
+
+			return pos;
+		}
+
+		public static int GetAlignment (DType dtype)
+		{
+			switch (dtype) {
+				case DType.Byte:
+					return 1;
+				case DType.Boolean:
+					return 4;
+				case DType.Int16:
+				case DType.UInt16:
+					return 2;
+				case DType.Int32:
+				case DType.UInt32:
+					return 4;
+				case DType.Int64:
+				case DType.UInt64:
+					return 8;
+#if !DISABLE_SINGLE
+				case DType.Single: //Not yet supported!
+					return 4;
+#endif
+				case DType.Double:
+					return 8;
+				case DType.String:
+					return 4;
+				case DType.ObjectPath:
+					return 4;
+				case DType.Signature:
+					return 1;
+				case DType.Array:
+					return 4;
+				case DType.Struct:
+				case DType.StructBegin:
+					return 8;
+				case DType.Variant:
+					return 1;
+				case DType.DictEntry:
+				case DType.DictEntryBegin:
+					return 8;
+				case DType.Invalid:
+				default:
+					throw new Exception ("Cannot determine alignment of " + dtype);
+			}
+		}
+
+		//this class may not be the best place for Verbose
+		public readonly static bool Verbose;
+
+		static Protocol ()
+		{
+			Verbose = !String.IsNullOrEmpty (Environment.GetEnvironmentVariable ("DBUS_VERBOSE"));
+		}
+	}
+
+	// Currently only for internal use on exported objects
+	class BusException : Exception
+	{
+		public BusException (string errorName, string errorMessage)
+		{
+			this.ErrorName = errorName;
+			this.ErrorMessage = errorMessage;
+		}
+
+		public BusException (string errorName, string format, params object[] args)
+		{
+			this.ErrorName = errorName;
+			this.ErrorMessage = String.Format (format, args);
+		}
+
+		public override string Message
+		{
+			get
+			{
+				return ErrorName + ": " + ErrorMessage;
+			}
+		}
+
+		public readonly string ErrorName;
+
+		public readonly string ErrorMessage;
+	}
+
+#if UNDOCUMENTED_IN_SPEC
+/*
+"org.freedesktop.DBus.Error.Failed"
+"org.freedesktop.DBus.Error.NoMemory"
+"org.freedesktop.DBus.Error.ServiceUnknown"
+"org.freedesktop.DBus.Error.NameHasNoOwner"
+"org.freedesktop.DBus.Error.NoReply"
+"org.freedesktop.DBus.Error.IOError"
+"org.freedesktop.DBus.Error.BadAddress"
+"org.freedesktop.DBus.Error.NotSupported"
+"org.freedesktop.DBus.Error.LimitsExceeded"
+"org.freedesktop.DBus.Error.AccessDenied"
+"org.freedesktop.DBus.Error.AuthFailed"
+"org.freedesktop.DBus.Error.NoServer"
+"org.freedesktop.DBus.Error.Timeout"
+"org.freedesktop.DBus.Error.NoNetwork"
+"org.freedesktop.DBus.Error.AddressInUse"
+"org.freedesktop.DBus.Error.Disconnected"
+"org.freedesktop.DBus.Error.InvalidArgs"
+"org.freedesktop.DBus.Error.FileNotFound"
+"org.freedesktop.DBus.Error.UnknownMethod"
+"org.freedesktop.DBus.Error.TimedOut"
+"org.freedesktop.DBus.Error.MatchRuleNotFound"
+"org.freedesktop.DBus.Error.MatchRuleInvalid"
+"org.freedesktop.DBus.Error.Spawn.ExecFailed"
+"org.freedesktop.DBus.Error.Spawn.ForkFailed"
+"org.freedesktop.DBus.Error.Spawn.ChildExited"
+"org.freedesktop.DBus.Error.Spawn.ChildSignaled"
+"org.freedesktop.DBus.Error.Spawn.Failed"
+"org.freedesktop.DBus.Error.UnixProcessIdUnknown"
+"org.freedesktop.DBus.Error.InvalidSignature"
+"org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
+*/
+#endif
+}
diff --git a/src/Signature.cs b/src/Signature.cs
new file mode 100644
index 0000000..6439fe8
--- /dev/null
+++ b/src/Signature.cs
@@ -0,0 +1,897 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Text;
+
+using System.Collections.Generic;
+//TODO: Reflection should be done at a higher level than this class
+using System.Reflection;
+
+namespace DBus
+{
+	//maybe this should be nullable?
+	struct Signature
+	{
+		//TODO: this class needs some work
+		//Data should probably include the null terminator
+
+		public static readonly Signature Empty = new Signature (String.Empty);
+		public static readonly Signature ByteSig = Allocate (DType.Byte);
+		public static readonly Signature UInt16Sig = Allocate (DType.UInt16);
+		public static readonly Signature UInt32Sig = Allocate (DType.UInt32);
+		public static readonly Signature StringSig = Allocate (DType.String);
+		public static readonly Signature ObjectPathSig = Allocate (DType.ObjectPath);
+		public static readonly Signature SignatureSig = Allocate (DType.Signature);
+		public static readonly Signature VariantSig = Allocate (DType.Variant);
+
+		public static bool operator == (Signature a, Signature b)
+		{
+			if (a.data == b.data)
+				return true;
+
+			if (a.data == null)
+				return false;
+
+			if (b.data == null)
+				return false;
+
+			if (a.data.Length != b.data.Length)
+				return false;
+
+			for (int i = 0 ; i != a.data.Length ; i++)
+				if (a.data[i] != b.data[i])
+					return false;
+
+			return true;
+		}
+
+		public static bool operator != (Signature a, Signature b)
+		{
+			return !(a == b);
+		}
+
+		public override bool Equals (object o)
+		{
+			if (o == null)
+				return false;
+
+			if (!(o is Signature))
+				return false;
+
+			return this == (Signature)o;
+		}
+
+		public override int GetHashCode ()
+		{
+			// TODO: Avoid string conversion
+			return Value.GetHashCode ();
+		}
+
+		public static Signature operator + (Signature s1, Signature s2)
+		{
+			return Concat (s1, s2);
+		}
+
+		public static Signature Concat (Signature s1, Signature s2)
+		{
+			if (s1.data == null && s2.data == null)
+				return Signature.Empty;
+
+			if (s1.data == null)
+				return s2;
+
+			if (s2.data == null)
+				return s1;
+
+			if (s1.Length + s2.Length == 0)
+				return Signature.Empty;
+
+			byte[] data = new byte[s1.data.Length + s2.data.Length];
+			s1.data.CopyTo (data, 0);
+			s2.data.CopyTo (data, s1.data.Length);
+			return Signature.Take (data);
+		}
+
+		public Signature (string value)
+		{
+			if (value.Length == 0) {
+				this.data = Empty.data;
+				return;
+			}
+
+			if (value.Length == 1) {
+				this.data = DataForDType ((DType)value[0]);
+				return;
+			}
+
+			this.data = Encoding.ASCII.GetBytes (value);
+		}
+
+		internal static Signature Take (byte[] value)
+		{
+			Signature sig;
+
+			if (value.Length == 0) {
+				sig.data = Empty.data;
+				return sig;
+			}
+
+			if (value.Length == 1) {
+				sig.data = DataForDType ((DType)value[0]);
+				return sig;
+			}
+
+			sig.data = value;
+			return sig;
+		}
+
+		static byte[] DataForDType (DType value)
+		{
+			// Reduce heap allocations.
+			// For now, we only cache the most common protocol signatures.
+			switch (value) {
+				case DType.Byte:
+					return ByteSig.data;
+				case DType.UInt16:
+					return UInt16Sig.data;
+				case DType.UInt32:
+					return UInt32Sig.data;
+				case DType.String:
+					return StringSig.data;
+				case DType.ObjectPath:
+					return ObjectPathSig.data;
+				case DType.Signature:
+					return SignatureSig.data;
+				case DType.Variant:
+					return VariantSig.data;
+				default:
+					return new byte[] {(byte)value};
+			}
+		}
+
+		private static Signature Allocate (DType value)
+		{
+			Signature sig;
+			sig.data = new byte[] {(byte)value};
+			return sig;
+		}
+
+		internal Signature (DType value)
+		{
+			this.data = DataForDType (value);
+		}
+
+		internal Signature (DType[] value)
+		{
+			if (value.Length == 0) {
+				this.data = Empty.data;
+				return;
+			}
+
+			if (value.Length == 1) {
+				this.data = DataForDType (value[0]);
+				return;
+			}
+
+			this.data = new byte[value.Length];
+
+			for (int i = 0 ; i != value.Length ; i++)
+				this.data[i] = (byte)value[i];
+		}
+
+		byte[] data;
+
+		//TODO: this should be private, but MessageWriter and Monitor still use it
+		//[Obsolete]
+		public byte[] GetBuffer ()
+		{
+			return data;
+		}
+
+		internal DType this[int index]
+		{
+			get {
+				return (DType)data[index];
+			}
+		}
+
+		public int Length
+		{
+			get {
+				return data.Length;
+			}
+		}
+
+		//[Obsolete]
+		public string Value
+		{
+			get {
+				//FIXME: hack to handle bad case when Data is null
+				if (data == null)
+					return String.Empty;
+
+				return Encoding.ASCII.GetString (data);
+			}
+		}
+
+		public override string ToString ()
+		{
+			return Value;
+
+			/*
+			StringBuilder sb = new StringBuilder ();
+
+			foreach (DType t in data) {
+				//we shouldn't rely on object mapping here, but it's an easy way to get string representations for now
+				Type type = DTypeToType (t);
+				if (type != null) {
+					sb.Append (type.Name);
+				} else {
+					char c = (char)t;
+					if (!Char.IsControl (c))
+						sb.Append (c);
+					else
+						sb.Append (@"\" + (int)c);
+				}
+				sb.Append (" ");
+			}
+
+			return sb.ToString ();
+			*/
+		}
+
+		public Signature MakeArraySignature ()
+		{
+			return new Signature (DType.Array) + this;
+		}
+
+		public static Signature MakeStruct (params Signature[] elems)
+		{
+			Signature sig = Signature.Empty;
+
+			sig += new Signature (DType.StructBegin);
+
+			foreach (Signature elem in elems)
+				sig += elem;
+
+			sig += new Signature (DType.StructEnd);
+
+			return sig;
+		}
+
+		public static Signature MakeDictEntry (Signature keyType, Signature valueType)
+		{
+			Signature sig = Signature.Empty;
+
+			sig += new Signature (DType.DictEntryBegin);
+
+			sig += keyType;
+			sig += valueType;
+
+			sig += new Signature (DType.DictEntryEnd);
+
+			return sig;
+		}
+
+		public static Signature MakeDict (Signature keyType, Signature valueType)
+		{
+			return MakeDictEntry (keyType, valueType).MakeArraySignature ();
+		}
+
+		public int Alignment
+		{
+			get {
+				if (data.Length == 0)
+					return 0;
+
+				return Protocol.GetAlignment (this[0]);
+			}
+		}
+
+		static int GetSize (DType dtype)
+		{
+			switch (dtype) {
+				case DType.Byte:
+					return 1;
+				case DType.Boolean:
+					return 4;
+				case DType.Int16:
+				case DType.UInt16:
+					return 2;
+				case DType.Int32:
+				case DType.UInt32:
+					return 4;
+				case DType.Int64:
+				case DType.UInt64:
+					return 8;
+#if !DISABLE_SINGLE
+				case DType.Single: //Not yet supported!
+					return 4;
+#endif
+				case DType.Double:
+					return 8;
+				case DType.String:
+				case DType.ObjectPath:
+				case DType.Signature:
+				case DType.Array:
+				case DType.StructBegin:
+				case DType.Variant:
+				case DType.DictEntryBegin:
+					return -1;
+				case DType.Invalid:
+				default:
+					throw new Exception ("Cannot determine size of " + dtype);
+			}
+		}
+
+		public bool GetFixedSize (ref int size)
+		{
+			if (size < 0)
+				return false;
+
+			if (data.Length == 0)
+				return true;
+
+			// Sensible?
+			size = Protocol.Padded (size, Alignment);
+
+			if (data.Length == 1) {
+				int valueSize = GetSize (this[0]);
+
+				if (valueSize == -1)
+					return false;
+
+				size += valueSize;
+				return true;
+			}
+
+			if (IsStructlike) {
+				foreach (Signature sig in GetParts ())
+						if (!sig.GetFixedSize (ref size))
+							return false;
+				return true;
+			}
+
+			if (IsArray || IsDict)
+				return false;
+
+			if (IsStruct) {
+				foreach (Signature sig in GetFieldSignatures ())
+						if (!sig.GetFixedSize (ref size))
+							return false;
+				return true;
+			}
+
+			// Any other cases?
+			throw new Exception ();
+		}
+
+		public bool IsFixedSize
+		{
+			get {
+				if (data.Length == 0)
+					return true;
+
+				if (data.Length == 1) {
+					int size = GetSize (this[0]);
+					return size != -1;
+				}
+
+				if (IsStructlike) {
+					foreach (Signature sig in GetParts ())
+						if (!sig.IsFixedSize)
+							return false;
+					return true;
+				}
+
+				if (IsArray || IsDict)
+					return false;
+
+				if (IsStruct) {
+					foreach (Signature sig in GetFieldSignatures ())
+						if (!sig.IsFixedSize)
+							return false;
+					return true;
+				}
+
+				// Any other cases?
+				throw new Exception ();
+			}
+		}
+
+		//TODO: complete this
+		public bool IsPrimitive
+		{
+			get {
+				if (data.Length != 1)
+					return false;
+
+				if (this[0] == DType.Variant)
+					return false;
+
+				if (this[0] == DType.Invalid)
+					return false;
+
+				return true;
+			}
+		}
+
+		public bool IsStruct
+		{
+			get {
+				if (Length < 2)
+					return false;
+
+				if (this[0] != DType.StructBegin)
+					return false;
+
+				// FIXME: Incorrect! What if this is in fact a Structlike starting and finishing with structs?
+				if (this[Length - 1] != DType.StructEnd)
+					return false;
+
+				return true;
+			}
+		}
+
+		public bool IsDictEntry
+		{
+			get {
+				if (Length < 2)
+					return false;
+
+				if (this[0] != DType.DictEntryBegin)
+					return false;
+
+				// FIXME: Incorrect! What if this is in fact a Structlike starting and finishing with structs?
+				if (this[Length - 1] != DType.DictEntryEnd)
+					return false;
+
+				return true;
+			}
+		}
+
+		public bool IsStructlike
+		{
+			get {
+				if (Length < 2)
+					return false;
+
+				if (IsArray)
+					return false;
+
+				if (IsDict)
+					return false;
+
+				if (IsStruct)
+					return false;
+
+				return true;
+			}
+		}
+
+		public bool IsDict
+		{
+			get {
+				if (Length < 3)
+					return false;
+
+				if (!IsArray)
+					return false;
+
+				// 0 is 'a'
+				if (this[1] != DType.DictEntryBegin)
+					return false;
+
+				return true;
+			}
+		}
+
+		public bool IsArray
+		{
+			get {
+				if (Length < 2)
+					return false;
+
+				if (this[0] != DType.Array)
+					return false;
+
+				return true;
+			}
+		}
+
+		public Signature GetElementSignature ()
+		{
+			if (!IsArray)
+				throw new Exception ("Cannot get the element signature of a non-array (signature was '" + this + "')");
+
+			//TODO: improve this
+			//if (IsDict)
+			//	throw new NotSupportedException ("Parsing dict signature is not supported (signature was '" + this + "')");
+
+			// Skip over 'a'
+			int pos = 1;
+			return GetNextSignature (ref pos);
+		}
+
+		public Type[] ToTypes ()
+		{
+			// TODO: Find a way to avoid these null checks everywhere.
+			if (data == null)
+				return Type.EmptyTypes;
+
+			List<Type> types = new List<Type> ();
+			for (int i = 0 ; i != data.Length ; types.Add (ToType (ref i)));
+			return types.ToArray ();
+		}
+
+		public Type ToType ()
+		{
+			int pos = 0;
+			Type ret = ToType (ref pos);
+			if (pos != data.Length)
+				throw new Exception ("Signature '" + Value + "' is not a single complete type");
+			return ret;
+		}
+
+		internal static DType TypeCodeToDType (TypeCode typeCode)
+		{
+			switch (typeCode)
+			{
+				case TypeCode.Empty:
+					return DType.Invalid;
+				case TypeCode.Object:
+					return DType.Invalid;
+				case TypeCode.DBNull:
+					return DType.Invalid;
+				case TypeCode.Boolean:
+					return DType.Boolean;
+				case TypeCode.Char:
+					return DType.UInt16;
+				case TypeCode.SByte:
+					return DType.Byte;
+				case TypeCode.Byte:
+					return DType.Byte;
+				case TypeCode.Int16:
+					return DType.Int16;
+				case TypeCode.UInt16:
+					return DType.UInt16;
+				case TypeCode.Int32:
+					return DType.Int32;
+				case TypeCode.UInt32:
+					return DType.UInt32;
+				case TypeCode.Int64:
+					return DType.Int64;
+				case TypeCode.UInt64:
+					return DType.UInt64;
+				case TypeCode.Single:
+					return DType.Single;
+				case TypeCode.Double:
+					return DType.Double;
+				case TypeCode.Decimal:
+					return DType.Invalid;
+				case TypeCode.DateTime:
+					return DType.Invalid;
+				case TypeCode.String:
+					return DType.String;
+				default:
+					return DType.Invalid;
+			}
+		}
+
+		//FIXME: this method is bad, get rid of it
+		internal static DType TypeToDType (Type type)
+		{
+			if (type == typeof (void))
+				return DType.Invalid;
+
+			if (type == typeof (string))
+				return DType.String;
+
+			if (type == typeof (ObjectPath))
+				return DType.ObjectPath;
+
+			if (type == typeof (Signature))
+				return DType.Signature;
+
+			if (type == typeof (object))
+				return DType.Variant;
+
+			if (type.IsPrimitive)
+				return TypeCodeToDType (Type.GetTypeCode (type));
+
+			if (type.IsEnum)
+				return TypeToDType (Enum.GetUnderlyingType (type));
+
+			//needs work
+			if (type.IsArray)
+				return DType.Array;
+
+			//if (type.UnderlyingSystemType != null)
+			//	return TypeToDType (type.UnderlyingSystemType);
+			if (Mapper.IsPublic (type))
+				return DType.ObjectPath;
+
+			if (!type.IsPrimitive && !type.IsEnum)
+				return DType.Struct;
+
+			//TODO: maybe throw an exception here
+			return DType.Invalid;
+		}
+
+		/*
+		public static DType TypeToDType (Type type)
+		{
+			if (type == null)
+				return DType.Invalid;
+			else if (type == typeof (byte))
+				return DType.Byte;
+			else if (type == typeof (bool))
+				return DType.Boolean;
+			else if (type == typeof (short))
+				return DType.Int16;
+			else if (type == typeof (ushort))
+				return DType.UInt16;
+			else if (type == typeof (int))
+				return DType.Int32;
+			else if (type == typeof (uint))
+				return DType.UInt32;
+			else if (type == typeof (long))
+				return DType.Int64;
+			else if (type == typeof (ulong))
+				return DType.UInt64;
+			else if (type == typeof (float)) //not supported by libdbus at time of writing
+				return DType.Single;
+			else if (type == typeof (double))
+				return DType.Double;
+			else if (type == typeof (string))
+				return DType.String;
+			else if (type == typeof (ObjectPath))
+				return DType.ObjectPath;
+			else if (type == typeof (Signature))
+				return DType.Signature;
+			else
+				return DType.Invalid;
+		}
+		*/
+
+		public IEnumerable<Signature> GetFieldSignatures ()
+		{
+			if (this == Signature.Empty || this[0] != DType.StructBegin)
+				throw new Exception ("Not a struct");
+
+			for (int pos = 1 ; pos < data.Length - 1 ;)
+				yield return GetNextSignature (ref pos);
+		}
+
+		public void GetDictEntrySignatures (out Signature sigKey, out Signature sigValue)
+		{
+			if (this == Signature.Empty || this[0] != DType.DictEntryBegin)
+				throw new Exception ("Not a DictEntry");
+
+			int pos = 1;
+			sigKey = GetNextSignature (ref pos);
+			sigValue = GetNextSignature (ref pos);
+		}
+
+		public IEnumerable<Signature> GetParts ()
+		{
+			if (data == null)
+				yield break;
+			for (int pos = 0 ; pos < data.Length ;) {
+				yield return GetNextSignature (ref pos);
+			}
+		}
+
+		public Signature GetNextSignature (ref int pos)
+		{
+			if (data == null)
+				return Signature.Empty;
+
+			DType dtype = (DType)data[pos++];
+
+			switch (dtype) {
+				//case DType.Invalid:
+				//	return typeof (void);
+				case DType.Array:
+					//peek to see if this is in fact a dictionary
+					if ((DType)data[pos] == DType.DictEntryBegin) {
+						//skip over the {
+						pos++;
+						Signature keyType = GetNextSignature (ref pos);
+						Signature valueType = GetNextSignature (ref pos);
+						//skip over the }
+						pos++;
+						return Signature.MakeDict (keyType, valueType);
+					} else {
+						Signature elementType = GetNextSignature (ref pos);
+						return elementType.MakeArraySignature ();
+					}
+				//case DType.DictEntryBegin: // FIXME: DictEntries should be handled separately.
+				case DType.StructBegin:
+					//List<Signature> fieldTypes = new List<Signature> ();
+					Signature fieldsSig = Signature.Empty;
+					while ((DType)data[pos] != DType.StructEnd)
+						fieldsSig += GetNextSignature (ref pos);
+					//skip over the )
+					pos++;
+					return Signature.MakeStruct (fieldsSig);
+					//return fieldsSig;
+				case DType.DictEntryBegin:
+					Signature sigKey = GetNextSignature (ref pos);
+					Signature sigValue = GetNextSignature (ref pos);
+					//skip over the }
+					pos++;
+					return Signature.MakeDictEntry (sigKey, sigValue);
+				default:
+					return new Signature (dtype);
+			}
+		}
+
+		public Type ToType (ref int pos)
+		{
+			// TODO: Find a way to avoid these null checks everywhere.
+			if (data == null)
+				return typeof (void);
+
+			DType dtype = (DType)data[pos++];
+
+			switch (dtype) {
+				case DType.Invalid:
+					return typeof (void);
+				case DType.Byte:
+					return typeof (byte);
+				case DType.Boolean:
+					return typeof (bool);
+				case DType.Int16:
+					return typeof (short);
+				case DType.UInt16:
+					return typeof (ushort);
+				case DType.Int32:
+					return typeof (int);
+				case DType.UInt32:
+					return typeof (uint);
+				case DType.Int64:
+					return typeof (long);
+				case DType.UInt64:
+					return typeof (ulong);
+				case DType.Single: ////not supported by libdbus at time of writing
+					return typeof (float);
+				case DType.Double:
+					return typeof (double);
+				case DType.String:
+					return typeof (string);
+				case DType.ObjectPath:
+					return typeof (ObjectPath);
+				case DType.Signature:
+					return typeof (Signature);
+				case DType.Array:
+					//peek to see if this is in fact a dictionary
+					if ((DType)data[pos] == DType.DictEntryBegin) {
+						//skip over the {
+						pos++;
+						Type keyType = ToType (ref pos);
+						Type valueType = ToType (ref pos);
+						//skip over the }
+						pos++;
+						//return typeof (IDictionary<,>).MakeGenericType (new Type[] {keyType, valueType});
+						//workaround for Mono bug #81035 (memory leak)
+						return Mapper.GetGenericType (typeof (IDictionary<,>), new Type[] {keyType, valueType});
+					} else {
+						return ToType (ref pos).MakeArrayType ();
+					}
+				case DType.Struct:
+					return typeof (ValueType);
+				case DType.DictEntry:
+					return typeof (System.Collections.Generic.KeyValuePair<,>);
+				case DType.Variant:
+					return typeof (object);
+				default:
+					throw new NotSupportedException ("Parsing or converting this signature is not yet supported (signature was '" + this + "'), at DType." + dtype);
+			}
+		}
+
+		public static Signature GetSig (object[] objs)
+		{
+			return GetSig (Type.GetTypeArray (objs));
+		}
+
+		public static Signature GetSig (Type[] types)
+		{
+			if (types == null)
+				throw new ArgumentNullException ("types");
+
+			Signature sig = Signature.Empty;
+
+			foreach (Type type in types)
+					sig += GetSig (type);
+
+			return sig;
+		}
+
+		public static Signature GetSig (Type type)
+		{
+			if (type == null)
+				throw new ArgumentNullException ("type");
+
+			//this is inelegant, but works for now
+			if (type == typeof (Signature))
+				return new Signature (DType.Signature);
+
+			if (type == typeof (ObjectPath))
+				return new Signature (DType.ObjectPath);
+
+			if (type == typeof (void))
+				return Signature.Empty;
+
+			if (type == typeof (string))
+				return new Signature (DType.String);
+
+			if (type == typeof (object))
+				return new Signature (DType.Variant);
+
+			if (type.IsArray)
+				return GetSig (type.GetElementType ()).MakeArraySignature ();
+
+			if (type.IsGenericType && (type.GetGenericTypeDefinition () == typeof (IDictionary<,>) || type.GetGenericTypeDefinition () == typeof (Dictionary<,>))) {
+
+				Type[] genArgs = type.GetGenericArguments ();
+				return Signature.MakeDict (GetSig (genArgs[0]), GetSig (genArgs[1]));
+			}
+
+			if (Mapper.IsPublic (type)) {
+				return new Signature (DType.ObjectPath);
+			}
+
+			if (!type.IsPrimitive && !type.IsEnum) {
+				Signature sig = Signature.Empty;
+
+				foreach (FieldInfo fi in type.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
+					sig += GetSig (fi.FieldType);
+
+				return Signature.MakeStruct (sig);
+			}
+
+			DType dtype = Signature.TypeToDType (type);
+			return new Signature (dtype);
+		}
+	}
+
+	enum ArgDirection
+	{
+		In,
+		Out,
+	}
+
+	enum DType : byte
+	{
+		Invalid = (byte)'\0',
+
+		Byte = (byte)'y',
+		Boolean = (byte)'b',
+		Int16 = (byte)'n',
+		UInt16 = (byte)'q',
+		Int32 = (byte)'i',
+		UInt32 = (byte)'u',
+		Int64 = (byte)'x',
+		UInt64 = (byte)'t',
+		Single = (byte)'f', //This is not yet supported!
+		Double = (byte)'d',
+		String = (byte)'s',
+		ObjectPath = (byte)'o',
+		Signature = (byte)'g',
+
+		Array = (byte)'a',
+		[Obsolete ("Not in protocol")]
+		Struct = (byte)'r',
+		[Obsolete ("Not in protocol")]
+		DictEntry = (byte)'e',
+		Variant = (byte)'v',
+
+		StructBegin = (byte)'(',
+		StructEnd = (byte)')',
+		DictEntryBegin = (byte)'{',
+		DictEntryEnd = (byte)'}',
+	}
+}
diff --git a/src/SocketTransport.cs b/src/SocketTransport.cs
new file mode 100644
index 0000000..e6eb6b3
--- /dev/null
+++ b/src/SocketTransport.cs
@@ -0,0 +1,70 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+
+namespace DBus.Transports
+{
+	class SocketTransport : Transport
+	{
+		internal Socket socket;
+
+		public override void Open (AddressEntry entry)
+		{
+			string host, portStr, family;
+			int port;
+
+			if (!entry.Properties.TryGetValue ("host", out host))
+				host = "localhost";
+
+			if (!entry.Properties.TryGetValue ("port", out portStr))
+				throw new Exception ("No port specified");
+
+			if (!Int32.TryParse (portStr, out port))
+				throw new Exception ("Invalid port: \"" + port + "\"");
+
+			if (!entry.Properties.TryGetValue ("family", out family))
+				family = null;
+
+			Open (host, port, family);
+		}
+
+		public void Open (string host, int port, string family)
+		{
+			//TODO: use Socket directly
+			TcpClient client = new TcpClient (host, port);
+			/*
+			client.NoDelay = true;
+			client.ReceiveBufferSize = (int)Protocol.MaxMessageLength;
+			client.SendBufferSize = (int)Protocol.MaxMessageLength;
+			*/
+			this.socket = client.Client;
+			SocketHandle = (long)client.Client.Handle;
+			Stream = client.GetStream ();
+		}
+
+		public void Open (Socket socket)
+		{
+			this.socket = socket;
+
+			socket.Blocking = true;
+			SocketHandle = (long)socket.Handle;
+			//Stream = new UnixStream ((int)socket.Handle);
+			Stream = new NetworkStream (socket);
+		}
+
+		public override void WriteCred ()
+		{
+			Stream.WriteByte (0);
+		}
+
+		public override string AuthString ()
+		{
+			return String.Empty;
+		}
+	}
+}
diff --git a/src/Transport.cs b/src/Transport.cs
new file mode 100644
index 0000000..991683d
--- /dev/null
+++ b/src/Transport.cs
@@ -0,0 +1,383 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+
+namespace DBus.Transports
+{
+	abstract class Transport
+	{
+		public static Transport Create (AddressEntry entry)
+		{
+			switch (entry.Method) {
+				case "tcp":
+				{
+					Transport transport = new SocketTransport ();
+					transport.Open (entry);
+					return transport;
+				}
+#if !PORTABLE
+				case "unix":
+				{
+					Transport transport = new UnixNativeTransport ();
+					transport.Open (entry);
+					return transport;
+				}
+#endif
+#if ENABLE_PIPES
+				case "win": {
+					Transport transport = new PipeTransport ();
+					transport.Open (entry);
+					return transport;
+				}
+#endif
+				default:
+					throw new NotSupportedException ("Transport method \"" + entry.Method + "\" not supported");
+			}
+		}
+
+		protected Connection connection;
+
+		public Connection Connection
+		{
+			get {
+				return connection;
+			} set {
+				connection = value;
+			}
+		}
+
+		//TODO: design this properly
+
+		//this is just a temporary solution
+		public Stream Stream;
+		public long SocketHandle;
+		public abstract void Open (AddressEntry entry);
+		public abstract string AuthString ();
+		public abstract void WriteCred ();
+
+		public virtual bool TryGetPeerPid (out uint pid)
+		{
+			pid = 0;
+			return false;
+		}
+
+		Stream ns {
+			get {
+				return this.Stream;
+			}
+		}
+
+		public virtual void Disconnect ()
+		{
+			ns.Dispose ();
+		}
+
+		internal Queue<Message> Inbound = new Queue<Message> ();
+
+		public event EventHandler WakeUp;
+		protected void FireWakeUp ()
+		{
+			if (WakeUp != null)
+				WakeUp (this, EventArgs.Empty);
+		}
+
+		internal Message TryReadMessage ()
+		{
+			GetData ();
+			if (Inbound.Count > 0)
+				return Inbound.Dequeue ();
+			return null;
+		}
+
+		public void Iterate ()
+		{
+			GetData ();
+		}
+
+		internal Message ReadMessage ()
+		{
+			// Hack to complete pending async reads in progress.
+			while (msgRdr != null)
+				GetData ();
+
+			try {
+				return ReadMessageReal ();
+			} catch (IOException e) {
+				if (Protocol.Verbose)
+					Console.Error.WriteLine (e.Message);
+				connection.isConnected = false;
+				return null;
+			}
+		}
+
+		int Read (byte[] buffer, int offset, int count)
+		{
+			int read = 0;
+			//System.Net.Sockets.NetworkStream nns = ns as System.Net.Sockets.NetworkStream;
+			//SocketTransport st = this as SocketTransport;
+			while (read < count) {
+				// FIXME: Remove this hack to support non-blocking sockets on Windows
+				//if (st != null && st.socket.Blocking == false && nns != null && !nns.DataAvailable) {
+				/*
+				if (nns != null && !nns.DataAvailable) {
+					System.Threading.Thread.Sleep (10);
+					continue;
+				}
+				*/
+				int nread = ns.Read (buffer, offset + read, count - read);
+				if (nread == 0)
+					break;
+				read += nread;
+			}
+
+			//if (read < count)
+			//	throw new Exception ();
+
+			if (read > count)
+				throw new Exception ();
+
+			return read;
+		}
+
+		byte[] mmbuf = null;
+
+		int mmpos = 0;
+		int mmneeded = 16;
+		IEnumerator<MsgState> msgRdr;
+
+		public void GetData ()
+		{
+			if (msgRdr == null) {
+				msgRdr = ReadMessageReal2 ();
+			}
+
+			SocketTransport st = this as SocketTransport;
+
+			int avail = st.socket.Available;
+			if (mmneeded == 0)
+				throw new Exception ();
+
+			if (avail == 0)
+				return;
+
+			avail = Math.Min (avail, mmneeded);
+			int nread = st.socket.Receive (mmbuf, mmpos, avail, System.Net.Sockets.SocketFlags.None);
+			mmpos += nread;
+			mmneeded -= nread;
+			if (!msgRdr.MoveNext ())
+				throw new Exception ();
+
+			MsgState state = msgRdr.Current;
+			if (state != MsgState.Done)
+				return;
+
+			mmpos = 0;
+			mmneeded = 16;
+
+			msgRdr = null;
+		}
+
+		enum MsgState
+		{
+			Wait16,
+			WaitHeader,
+			WaitBody,
+			Done,
+		}
+
+		IEnumerator<MsgState> ReadMessageReal2 ()
+		{
+			byte[] body = null;
+			mmneeded = 16;
+			while (mmpos < 16)
+				yield return MsgState.Wait16;
+
+			EndianFlag endianness = (EndianFlag)mmbuf[0];
+			MessageReader reader = new MessageReader (endianness, mmbuf);
+
+			//discard the endian byte as we've already read it
+			reader.ReadByte ();
+
+			//discard message type and flags, which we don't care about here
+			reader.ReadByte ();
+			reader.ReadByte ();
+
+			byte version = reader.ReadByte ();
+
+			if (version < Protocol.MinVersion || version > Protocol.MaxVersion)
+				throw new NotSupportedException ("Protocol version '" + version.ToString () + "' is not supported");
+
+			if (Protocol.Verbose)
+				if (version != Protocol.Version)
+					Console.Error.WriteLine ("Warning: Protocol version '" + version.ToString () + "' is not explicitly supported but may be compatible");
+
+			uint bodyLength = reader.ReadUInt32 ();
+			//discard serial
+			reader.ReadUInt32 ();
+			uint headerLength = reader.ReadUInt32 ();
+
+			//this check may become relevant if a future version of the protocol allows larger messages
+			/*
+			if (bodyLength > Int32.MaxValue || headerLength > Int32.MaxValue)
+				throw new NotImplementedException ("Long messages are not yet supported");
+			*/
+
+			int bodyLen = (int)bodyLength;
+			int toRead = (int)headerLength;
+
+			//we fixup to include the padding following the header
+			toRead = Protocol.Padded (toRead, 8);
+
+			long msgLength = toRead + bodyLen;
+			if (msgLength > Protocol.MaxMessageLength)
+				throw new Exception ("Message length " + msgLength + " exceeds maximum allowed " + Protocol.MaxMessageLength + " bytes");
+
+			byte[] header = new byte[16 + toRead];
+			Array.Copy (mmbuf, header, 16);
+
+			mmneeded = toRead;
+			while (mmpos < 16 + toRead)
+				yield return MsgState.WaitHeader;
+
+			Array.Copy (mmbuf, 16, header, 16, toRead);
+
+			//if (read != toRead)
+			//	throw new Exception ("Message header length mismatch: " + read + " of expected " + toRead);
+
+			mmneeded = bodyLen;
+			while (mmpos < 16 + toRead + bodyLen)
+				yield return MsgState.WaitBody;
+
+			//read the body
+			if (bodyLen != 0) {
+				body = new byte[bodyLen];
+
+				Array.Copy (mmbuf, 16 + toRead, body, 0, bodyLen);
+
+				//if (read != bodyLen)
+				//	throw new Exception ("Message body length mismatch: " + read + " of expected " + bodyLen);
+			}
+
+			Message msg = new Message ();
+			msg.Connection = this.Connection;
+			msg.Body = body;
+			msg.SetHeaderData (header);
+
+			Inbound.Enqueue (msg);
+
+			mmneeded = 16;
+
+			yield return MsgState.Done;
+		}
+
+		Message ReadMessageReal ()
+		{
+			byte[] header;
+			byte[] body = null;
+
+			int read;
+
+			//16 bytes is the size of the fixed part of the header
+			byte[] hbuf = new byte[16];
+
+			read = Read (hbuf, 0, 16);
+
+			if (read == 0)
+				return null;
+
+			if (read != 16)
+				throw new Exception ("Header read length mismatch: " + read + " of expected " + "16");
+
+			EndianFlag endianness = (EndianFlag)hbuf[0];
+			MessageReader reader = new MessageReader (endianness, hbuf);
+
+			//discard the endian byte as we've already read it
+			reader.ReadByte ();
+
+			//discard message type and flags, which we don't care about here
+			reader.ReadByte ();
+			reader.ReadByte ();
+
+			byte version = reader.ReadByte ();
+
+			if (version < Protocol.MinVersion || version > Protocol.MaxVersion)
+				throw new NotSupportedException ("Protocol version '" + version.ToString () + "' is not supported");
+
+			if (Protocol.Verbose)
+				if (version != Protocol.Version)
+					Console.Error.WriteLine ("Warning: Protocol version '" + version.ToString () + "' is not explicitly supported but may be compatible");
+
+			uint bodyLength = reader.ReadUInt32 ();
+			//discard serial
+			reader.ReadUInt32 ();
+			uint headerLength = reader.ReadUInt32 ();
+
+			//this check may become relevant if a future version of the protocol allows larger messages
+			/*
+			if (bodyLength > Int32.MaxValue || headerLength > Int32.MaxValue)
+				throw new NotImplementedException ("Long messages are not yet supported");
+			*/
+
+			int bodyLen = (int)bodyLength;
+			int toRead = (int)headerLength;
+
+			//we fixup to include the padding following the header
+			toRead = Protocol.Padded (toRead, 8);
+
+			long msgLength = toRead + bodyLen;
+			if (msgLength > Protocol.MaxMessageLength)
+				throw new Exception ("Message length " + msgLength + " exceeds maximum allowed " + Protocol.MaxMessageLength + " bytes");
+
+			header = new byte[16 + toRead];
+			Array.Copy (hbuf, header, 16);
+
+			read = Read (header, 16, toRead);
+
+			if (read != toRead)
+				throw new Exception ("Message header length mismatch: " + read + " of expected " + toRead);
+
+			//read the body
+			if (bodyLen != 0) {
+				body = new byte[bodyLen];
+
+				read = Read (body, 0, bodyLen);
+
+				if (read != bodyLen)
+					throw new Exception ("Message body length mismatch: " + read + " of expected " + bodyLen);
+			}
+
+			Message msg = new Message ();
+			msg.Connection = this.Connection;
+			msg.Body = body;
+			msg.SetHeaderData (header);
+
+			return msg;
+		}
+
+		readonly object writeLock = new object ();
+		internal virtual void WriteMessage (Message msg)
+		{
+			/*
+			byte[] HeaderData = msg.GetHeaderData ();
+
+			long msgLength = HeaderData.Length + (msg.Body != null ? msg.Body.Length : 0);
+			if (msgLength > Protocol.MaxMessageLength)
+				throw new Exception ("Message length " + msgLength + " exceeds maximum allowed " + Protocol.MaxMessageLength + " bytes");
+			*/
+
+			lock (writeLock) {
+				//ns.Write (HeaderData, 0, HeaderData.Length);
+				msg.GetHeaderDataToStream (ns);
+				if (msg.Body != null && msg.Body.Length != 0)
+					ns.Write (msg.Body, 0, msg.Body.Length);
+				ns.Flush ();
+			}
+
+		}
+	}
+}
diff --git a/src/TypeImplementer.cs b/src/TypeImplementer.cs
new file mode 100644
index 0000000..2d0b106
--- /dev/null
+++ b/src/TypeImplementer.cs
@@ -0,0 +1,909 @@
+// Copyright 2007 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections.Generic;
+
+namespace DBus
+{
+	class TypeImplementer
+	{
+		public static readonly TypeImplementer Root = new TypeImplementer ("DBus.Proxies", false);
+		AssemblyBuilder asmB;
+		ModuleBuilder modB;
+		static readonly object getImplLock = new Object ();
+
+		public TypeImplementer (string name, bool canSave)
+		{
+			asmB = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName (name), canSave ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
+			modB = asmB.DefineDynamicModule (name);
+		}
+
+		Dictionary<Type,Type> map = new Dictionary<Type,Type> ();
+
+		public Type GetImplementation (Type declType)
+		{
+			Type retT;
+
+			lock (getImplLock)
+				if (map.TryGetValue (declType, out retT))
+					return retT;
+
+			string proxyName = declType.FullName + "Proxy";
+
+			Type parentType;
+
+			if (declType.IsInterface)
+				parentType = typeof (BusObject);
+			else
+				parentType = declType;
+
+			TypeBuilder typeB = modB.DefineType (proxyName, TypeAttributes.Class | TypeAttributes.Public, parentType);
+
+			if (declType.IsInterface)
+				Implement (typeB, declType);
+
+			foreach (Type iface in declType.GetInterfaces ())
+				Implement (typeB, iface);
+
+			retT = typeB.CreateType ();
+
+			lock (getImplLock)
+				map[declType] = retT;
+
+			return retT;
+		}
+
+		static void Implement (TypeBuilder typeB, Type iface)
+		{
+			typeB.AddInterfaceImplementation (iface);
+
+			Dictionary<string,MethodBuilder> builders = new Dictionary<string,MethodBuilder> ();
+
+			foreach (MethodInfo declMethod in iface.GetMethods ()) {
+				ParameterInfo[] parms = declMethod.GetParameters ();
+
+				Type[] parmTypes = new Type[parms.Length];
+				for (int i = 0 ; i < parms.Length ; i++)
+					parmTypes[i] = parms[i].ParameterType;
+
+				MethodAttributes attrs = declMethod.Attributes ^ MethodAttributes.Abstract;
+				attrs ^= MethodAttributes.NewSlot;
+				attrs |= MethodAttributes.Final;
+				MethodBuilder method_builder = typeB.DefineMethod (declMethod.Name, attrs, declMethod.ReturnType, parmTypes);
+				typeB.DefineMethodOverride (method_builder, declMethod);
+
+				//define in/out/ref/name for each of the parameters
+				for (int i = 0; i < parms.Length ; i++)
+					method_builder.DefineParameter (i + 1, parms[i].Attributes, parms[i].Name);
+
+				ILGenerator ilg = method_builder.GetILGenerator ();
+				GenHookupMethod (ilg, declMethod, sendMethodCallMethod, Mapper.GetInterfaceName (iface), declMethod.Name);
+
+				if (declMethod.IsSpecialName)
+					builders[declMethod.Name] = method_builder;
+			}
+
+			foreach (EventInfo declEvent in iface.GetEvents ())
+			{
+				EventBuilder event_builder = typeB.DefineEvent (declEvent.Name, declEvent.Attributes, declEvent.EventHandlerType);
+				event_builder.SetAddOnMethod (builders["add_" + declEvent.Name]);
+				event_builder.SetRemoveOnMethod (builders["remove_" + declEvent.Name]);
+			}
+
+			foreach (PropertyInfo declProp in iface.GetProperties ())
+			{
+				List<Type> indexers = new List<Type> ();
+				foreach (ParameterInfo pi in declProp.GetIndexParameters ())
+					indexers.Add (pi.ParameterType);
+
+				PropertyBuilder prop_builder = typeB.DefineProperty (declProp.Name, declProp.Attributes, declProp.PropertyType, indexers.ToArray ());
+				MethodBuilder mb;
+				if (builders.TryGetValue ("get_" + declProp.Name, out mb))
+					prop_builder.SetGetMethod (mb);
+				if (builders.TryGetValue ("set_" + declProp.Name, out mb))
+					prop_builder.SetSetMethod (mb);
+			}
+		}
+
+		static MethodInfo sendMethodCallMethod = typeof (BusObject).GetMethod ("SendMethodCall");
+		static MethodInfo sendSignalMethod = typeof (BusObject).GetMethod ("SendSignal");
+		static MethodInfo toggleSignalMethod = typeof (BusObject).GetMethod ("ToggleSignal");
+
+		static Dictionary<EventInfo,DynamicMethod> hookup_methods = new Dictionary<EventInfo,DynamicMethod> ();
+		public static DynamicMethod GetHookupMethod (EventInfo ei)
+		{
+			DynamicMethod hookupMethod;
+			if (hookup_methods.TryGetValue (ei, out hookupMethod))
+				return hookupMethod;
+
+			if (ei.EventHandlerType.IsAssignableFrom (typeof (System.EventHandler)))
+				Console.Error.WriteLine ("Warning: Cannot yet fully expose EventHandler and its subclasses: " + ei.EventHandlerType);
+
+			MethodInfo declMethod = ei.EventHandlerType.GetMethod ("Invoke");
+
+			hookupMethod = GetHookupMethod (declMethod, sendSignalMethod, Mapper.GetInterfaceName (ei), ei.Name);
+
+			hookup_methods[ei] = hookupMethod;
+
+			return hookupMethod;
+		}
+
+		public static DynamicMethod GetHookupMethod (MethodInfo declMethod, MethodInfo invokeMethod, string @interface, string member)
+		{
+			ParameterInfo[] delegateParms = declMethod.GetParameters ();
+			Type[] hookupParms = new Type[delegateParms.Length+1];
+			hookupParms[0] = typeof (BusObject);
+			for (int i = 0; i < delegateParms.Length ; i++)
+				hookupParms[i+1] = delegateParms[i].ParameterType;
+
+			DynamicMethod hookupMethod = new DynamicMethod ("Handle" + member, declMethod.ReturnType, hookupParms, typeof (MessageWriter));
+
+			ILGenerator ilg = hookupMethod.GetILGenerator ();
+
+			GenHookupMethod (ilg, declMethod, invokeMethod, @interface, member);
+
+			return hookupMethod;
+		}
+
+		static MethodInfo getTypeFromHandleMethod = typeof (Type).GetMethod ("GetTypeFromHandle", new Type[] {typeof (RuntimeTypeHandle)});
+		static ConstructorInfo argumentNullExceptionConstructor = typeof (ArgumentNullException).GetConstructor (new Type[] {typeof (string)});
+		static ConstructorInfo messageWriterConstructor = typeof (MessageWriter).GetConstructor (Type.EmptyTypes);
+		static MethodInfo messageWriterWritePad = typeof (MessageWriter).GetMethod ("WritePad", new Type[] {typeof (int)});
+		static MethodInfo messageReaderReadPad = typeof (MessageReader).GetMethod ("ReadPad", new Type[] {typeof (int)});
+
+		static Dictionary<Type,MethodInfo> writeMethods = new Dictionary<Type,MethodInfo> ();
+
+		public static MethodInfo GetWriteMethod (Type t)
+		{
+			MethodInfo meth;
+
+			if (writeMethods.TryGetValue (t, out meth))
+				return meth;
+
+			DynamicMethod method_builder = new DynamicMethod ("Write" + t.Name, typeof (void), new Type[] {typeof (MessageWriter), t}, typeof (MessageWriter), true);
+
+			ILGenerator ilg = method_builder.GetILGenerator ();
+
+			ilg.Emit (OpCodes.Ldarg_0);
+			ilg.Emit (OpCodes.Ldarg_1);
+
+			GenWriter (ilg, t);
+
+			ilg.Emit (OpCodes.Ret);
+
+			meth = method_builder;
+
+			writeMethods[t] = meth;
+			return meth;
+		}
+
+		static Dictionary<Type,object> typeWriters = new Dictionary<Type,object> ();
+		public static TypeWriter<T> GetTypeWriter<T> ()
+		{
+			Type t = typeof (T);
+
+			object value;
+			if (typeWriters.TryGetValue (t, out value))
+				return (TypeWriter<T>)value;
+
+			MethodInfo mi = GetWriteMethod (t);
+			DynamicMethod dm = mi as DynamicMethod;
+			if (dm == null)
+				return null;
+
+			TypeWriter<T> tWriter = dm.CreateDelegate (typeof (TypeWriter<T>)) as TypeWriter<T>;
+			typeWriters[t] = tWriter;
+			return tWriter;
+		}
+
+		//takes the Writer instance and the value of Type t off the stack, writes it
+		public static void GenWriter (ILGenerator ilg, Type t)
+		{
+			Type tUnder = t;
+
+			if (t.IsEnum) {
+				tUnder = Enum.GetUnderlyingType (t);
+				//imprecise = true;
+			}
+
+			Type type = t;
+
+			//MethodInfo exactWriteMethod = typeof (MessageWriter).GetMethod ("Write", new Type[] {tUnder});
+			MethodInfo exactWriteMethod = typeof (MessageWriter).GetMethod ("Write", BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public, null, new Type[] {tUnder}, null);
+			//ExactBinding InvokeMethod
+
+			if (exactWriteMethod != null) {
+				ilg.Emit (exactWriteMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, exactWriteMethod);
+			} else if (t.IsArray) {
+				MethodInfo mi = typeof (MessageWriter).GetMethod ("WriteArray");
+				exactWriteMethod = mi.MakeGenericMethod (type.GetElementType ());
+				ilg.Emit (exactWriteMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, exactWriteMethod);
+			} else if (type.IsGenericType && (type.GetGenericTypeDefinition () == typeof (IDictionary<,>) || type.GetGenericTypeDefinition () == typeof (Dictionary<,>))) {
+				Type[] genArgs = type.GetGenericArguments ();
+				MethodInfo mi = typeof (MessageWriter).GetMethod ("WriteFromDict");
+				exactWriteMethod = mi.MakeGenericMethod (genArgs);
+				ilg.Emit (exactWriteMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, exactWriteMethod);
+			} else {
+				GenStructWriter (ilg, t);
+			}
+		}
+
+		public static IEnumerable<FieldInfo> GetMarshalFields (Type type)
+		{
+			// FIXME: Field order!
+			return type.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+		}
+
+		//takes a writer and a reference to an object off the stack
+		public static void GenStructWriter (ILGenerator ilg, Type type)
+		{
+			LocalBuilder val = ilg.DeclareLocal (type);
+			ilg.Emit (OpCodes.Stloc, val);
+
+			LocalBuilder writer = ilg.DeclareLocal (typeof (MessageWriter));
+			ilg.Emit (OpCodes.Stloc, writer);
+
+			//align to 8 for structs
+			ilg.Emit (OpCodes.Ldloc, writer);
+			ilg.Emit (OpCodes.Ldc_I4, 8);
+			ilg.Emit (OpCodes.Call, messageWriterWritePad);
+
+			foreach (FieldInfo fi in GetMarshalFields (type)) {
+				Type t = fi.FieldType;
+
+				// null checking of fields
+				if (!t.IsValueType) {
+					Label notNull = ilg.DefineLabel ();
+
+					//if the value is null...
+					//ilg.Emit (OpCodes.Ldarg, i);
+					ilg.Emit (OpCodes.Ldloc, val);
+					ilg.Emit (OpCodes.Ldfld, fi);
+
+					ilg.Emit (OpCodes.Brtrue_S, notNull);
+
+					//...throw Exception
+					string paramName = fi.Name;
+					ilg.Emit (OpCodes.Ldstr, paramName);
+					// TODO: Should not really be argumentNullException
+					ilg.Emit (OpCodes.Newobj, argumentNullExceptionConstructor);
+					ilg.Emit (OpCodes.Throw);
+
+					//was not null, so all is well
+					ilg.MarkLabel (notNull);
+				}
+
+				//the Writer to write to
+				ilg.Emit (OpCodes.Ldloc, writer);
+
+				//the object to read from
+				ilg.Emit (OpCodes.Ldloc, val);
+				ilg.Emit (OpCodes.Ldfld, fi);
+
+				GenWriter (ilg, t);
+			}
+		}
+
+		//takes a reader and a reference to an object off the stack
+		public static void GenStructReader (ILGenerator ilg, Type type)
+		{
+			// FIXME: Newobj fails if type has no default ctor!
+
+			LocalBuilder val = ilg.DeclareLocal (type);
+			ConstructorInfo ctor = type.GetConstructor (Type.EmptyTypes);
+			ilg.Emit (OpCodes.Newobj, ctor);
+			ilg.Emit (OpCodes.Stloc, val);
+
+			LocalBuilder reader = ilg.DeclareLocal (typeof (MessageReader));
+			ilg.Emit (OpCodes.Stloc, reader);
+
+			//align to 8 for structs
+			ilg.Emit (OpCodes.Ldloc, reader);
+			ilg.Emit (OpCodes.Ldc_I4, 8);
+			ilg.Emit (OpCodes.Call, messageReaderReadPad);
+
+			foreach (FieldInfo fi in GetMarshalFields (type)) {
+				Type t = fi.FieldType;
+
+				//the object to read into
+				ilg.Emit (OpCodes.Ldloc, val);
+
+				//the Reader to read from
+				ilg.Emit (OpCodes.Ldloc, reader);
+
+				GenReader (ilg, t);
+
+				ilg.Emit (OpCodes.Stfld, fi);
+			}
+
+			ilg.Emit (OpCodes.Ldloc, val);
+			//if (type.IsValueType)
+			//	ilg.Emit (OpCodes.Box, type);
+		}
+
+		static MethodInfo getBusObject = typeof(BusObject).GetMethod("GetBusObject");
+
+		public static void GenHookupMethod (ILGenerator ilg, MethodInfo declMethod, MethodInfo invokeMethod, string @interface, string member)
+		{
+			ParameterInfo[] parms = declMethod.GetParameters ();
+			Type retType = declMethod.ReturnType;
+
+			//the BusObject instance
+			ilg.Emit (OpCodes.Ldarg_0);
+
+			ilg.Emit (OpCodes.Call, getBusObject);
+
+			//MethodInfo
+
+			//interface
+			ilg.Emit (OpCodes.Ldstr, @interface);
+
+			//special case event add/remove methods
+			if (declMethod.IsSpecialName && (declMethod.Name.StartsWith ("add_") || declMethod.Name.StartsWith ("remove_"))) {
+				string[] parts = declMethod.Name.Split (new char[]{'_'}, 2);
+				string ename = parts[1];
+				//Delegate dlg = (Delegate)inArgs[0];
+				bool adding = parts[0] == "add";
+
+				ilg.Emit (OpCodes.Ldstr, ename);
+
+				ilg.Emit (OpCodes.Ldarg_1);
+
+				ilg.Emit (OpCodes.Ldc_I4, adding ? 1 : 0);
+
+				ilg.Emit (OpCodes.Tailcall);
+				ilg.Emit (toggleSignalMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, toggleSignalMethod);
+				ilg.Emit (OpCodes.Ret);
+				return;
+			}
+
+			//property accessor mapping
+			if (declMethod.IsSpecialName) {
+				if (member.StartsWith ("get_"))
+					member = "Get" + member.Substring (4);
+				else if (member.StartsWith ("set_"))
+					member = "Set" + member.Substring (4);
+			}
+
+			//member
+			ilg.Emit (OpCodes.Ldstr, member);
+
+			//signature
+			Signature inSig = Signature.Empty;
+			Signature outSig = Signature.Empty;
+			SigsForMethod (declMethod, out inSig, out outSig);
+
+			ilg.Emit (OpCodes.Ldstr, inSig.Value);
+
+			LocalBuilder writer = ilg.DeclareLocal (typeof (MessageWriter));
+			ilg.Emit (OpCodes.Newobj, messageWriterConstructor);
+			ilg.Emit (OpCodes.Stloc, writer);
+
+			foreach (ParameterInfo parm in parms)
+			{
+				if (parm.IsOut)
+					continue;
+
+				Type t = parm.ParameterType;
+				//offset by one to account for "this"
+				int i = parm.Position + 1;
+
+				//null checking of parameters (but not their recursive contents)
+				if (!t.IsValueType) {
+					Label notNull = ilg.DefineLabel ();
+
+					//if the value is null...
+					ilg.Emit (OpCodes.Ldarg, i);
+					ilg.Emit (OpCodes.Brtrue_S, notNull);
+
+					//...throw Exception
+					string paramName = parm.Name;
+					ilg.Emit (OpCodes.Ldstr, paramName);
+					ilg.Emit (OpCodes.Newobj, argumentNullExceptionConstructor);
+					ilg.Emit (OpCodes.Throw);
+
+					//was not null, so all is well
+					ilg.MarkLabel (notNull);
+				}
+
+				ilg.Emit (OpCodes.Ldloc, writer);
+
+				//the parameter
+				ilg.Emit (OpCodes.Ldarg, i);
+
+				GenWriter (ilg, t);
+			}
+
+			ilg.Emit (OpCodes.Ldloc, writer);
+
+			//the expected return Type
+			ilg.Emit (OpCodes.Ldtoken, retType);
+			ilg.Emit (OpCodes.Call, getTypeFromHandleMethod);
+
+			LocalBuilder exc = ilg.DeclareLocal (typeof (Exception));
+			ilg.Emit (OpCodes.Ldloca_S, exc);
+
+			//make the call
+			ilg.Emit (invokeMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, invokeMethod);
+
+			//define a label we'll use to deal with a non-null Exception
+			Label noErr = ilg.DefineLabel ();
+
+			//if the out Exception is not null...
+			ilg.Emit (OpCodes.Ldloc, exc);
+			ilg.Emit (OpCodes.Brfalse_S, noErr);
+
+			//...throw it.
+			ilg.Emit (OpCodes.Ldloc, exc);
+			ilg.Emit (OpCodes.Throw);
+
+			//Exception was null, so all is well
+			ilg.MarkLabel (noErr);
+
+			if (invokeMethod.ReturnType == typeof (MessageReader)) {
+				LocalBuilder reader = ilg.DeclareLocal (typeof (MessageReader));
+				ilg.Emit (OpCodes.Stloc, reader);
+
+				foreach (ParameterInfo parm in parms)
+				{
+					//t.IsByRef
+					if (!parm.IsOut)
+						continue;
+
+					Type t = parm.ParameterType.GetElementType ();
+					//offset by one to account for "this"
+					int i = parm.Position + 1;
+
+					ilg.Emit (OpCodes.Ldarg, i);
+					ilg.Emit (OpCodes.Ldloc, reader);
+					GenReader (ilg, t);
+					ilg.Emit (OpCodes.Stobj, t);
+				}
+
+				if (retType != typeof (void)) {
+					ilg.Emit (OpCodes.Ldloc, reader);
+					GenReader (ilg, retType);
+				}
+
+				ilg.Emit (OpCodes.Ret);
+				return;
+			}
+
+			if (retType == typeof (void)) {
+				//we aren't expecting a return value, so throw away the (hopefully) null return
+				if (invokeMethod.ReturnType != typeof (void))
+					ilg.Emit (OpCodes.Pop);
+			} else {
+				if (retType.IsValueType)
+					ilg.Emit (OpCodes.Unbox_Any, retType);
+				else
+					ilg.Emit (OpCodes.Castclass, retType);
+			}
+
+			ilg.Emit (OpCodes.Ret);
+		}
+
+
+		public static bool SigsForMethod (MethodInfo mi, out Signature inSig, out Signature outSig)
+		{
+			inSig = Signature.Empty;
+			outSig = Signature.Empty;
+
+			foreach (ParameterInfo parm in mi.GetParameters ()) {
+				if (parm.IsOut)
+					outSig += Signature.GetSig (parm.ParameterType.GetElementType ());
+				else
+					inSig += Signature.GetSig (parm.ParameterType);
+			}
+
+			outSig += Signature.GetSig (mi.ReturnType);
+
+			return true;
+		}
+
+		static Dictionary<Type,MethodInfo> readMethods = new Dictionary<Type,MethodInfo> ();
+		static void InitReaders ()
+		{
+			foreach (MethodInfo mi in typeof (MessageReader).GetMethods (BindingFlags.Instance | BindingFlags.Public)) {
+				if (!mi.Name.StartsWith ("Read"))
+					continue;
+				if (mi.ReturnType == typeof (void))
+					continue;
+				if (mi.GetParameters ().Length != 0)
+					continue;
+
+				readMethods[mi.ReturnType] = mi;
+			}
+		}
+
+		internal static MethodInfo GetReadMethod (Type t)
+		{
+			if (readMethods.Count == 0)
+				InitReaders ();
+
+			MethodInfo mi;
+			if (readMethods.TryGetValue (t, out mi))
+				return mi;
+
+			return null;
+		}
+
+		internal static MethodCaller2 GenCaller2 (MethodInfo target)
+		{
+			DynamicMethod hookupMethod = GenReadMethod (target);
+			MethodCaller2 caller = hookupMethod.CreateDelegate (typeof (MethodCaller2)) as MethodCaller2;
+			return caller;
+		}
+
+		internal static MethodCaller GenCaller (MethodInfo target, object targetInstance)
+		{
+			DynamicMethod hookupMethod = GenReadMethod (target);
+			MethodCaller caller = hookupMethod.CreateDelegate (typeof (MethodCaller), targetInstance) as MethodCaller;
+			return caller;
+		}
+
+		internal static DynamicMethod GenReadMethod (MethodInfo target)
+		{
+			Type[] parms = new Type[] { typeof (object), typeof (MessageReader), typeof (Message), typeof (MessageWriter) };
+			DynamicMethod hookupMethod = new DynamicMethod ("Caller", typeof (void), parms, typeof (MessageReader));
+			Gen (hookupMethod, target);
+			return hookupMethod;
+		}
+
+		static void Gen (DynamicMethod hookupMethod, MethodInfo declMethod)
+		{
+			ILGenerator ilg = hookupMethod.GetILGenerator ();
+
+			ParameterInfo[] parms = declMethod.GetParameters ();
+			Type retType = declMethod.ReturnType;
+
+			// The target instance
+			ilg.Emit (OpCodes.Ldarg_0);
+
+			Dictionary<ParameterInfo,LocalBuilder> locals = new Dictionary<ParameterInfo,LocalBuilder> ();
+
+			foreach (ParameterInfo parm in parms) {
+
+				Type parmType = parm.ParameterType;
+
+				if (parm.IsOut) {
+					LocalBuilder parmLocal = ilg.DeclareLocal (parmType.GetElementType ());
+					locals[parm] = parmLocal;
+					ilg.Emit (OpCodes.Ldloca, parmLocal);
+					continue;
+				}
+
+				ilg.Emit (OpCodes.Ldarg_1);
+				GenReader (ilg, parmType);
+			}
+
+			ilg.Emit (declMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, declMethod);
+
+			foreach (ParameterInfo parm in parms) {
+				if (!parm.IsOut)
+					continue;
+
+				Type parmType = parm.ParameterType.GetElementType ();
+
+				LocalBuilder parmLocal = locals[parm];
+				ilg.Emit (OpCodes.Ldarg_3); // writer
+				ilg.Emit (OpCodes.Ldloc, parmLocal);
+				GenWriter (ilg, parmType);
+			}
+
+			if (retType != typeof (void)) {
+				// Skip reply message construction if MessageWriter is null
+
+				LocalBuilder retLocal = ilg.DeclareLocal (retType);
+				ilg.Emit (OpCodes.Stloc, retLocal);
+
+				ilg.Emit (OpCodes.Ldarg_3); // writer
+				ilg.Emit (OpCodes.Ldloc, retLocal);
+				GenWriter (ilg, retType);
+
+			}
+
+			ilg.Emit (OpCodes.Ret);
+		}
+
+		//takes the Reader instance off the stack, puts value of type t on the stack
+		public static void GenReader (ILGenerator ilg, Type t)
+		{
+			// TODO: Cache generated methods
+			// TODO: Generate methods with the correct module/type permissions
+
+			Type tUnder = t;
+
+			if (t.IsEnum)
+				tUnder = Enum.GetUnderlyingType (t);
+
+			MethodInfo exactMethod = GetReadMethod (tUnder);
+			if (exactMethod != null)
+				ilg.Emit (exactMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, exactMethod);
+			else if (t.IsArray)
+				GenReadCollection (ilg, t);
+			else if (t.IsGenericType && (t.GetGenericTypeDefinition () == typeof (IList<>)))
+				GenReadCollection (ilg, t);
+			else if (t.IsGenericType && (t.GetGenericTypeDefinition () == typeof (IDictionary<,>) || t.GetGenericTypeDefinition () == typeof (Dictionary<,>)))
+				GenReadCollection (ilg, t);
+			else if (t.IsInterface)
+				GenFallbackReader (ilg, tUnder);
+			else if (!tUnder.IsValueType) {
+				GenStructReader (ilg, tUnder);
+			} else
+				GenFallbackReader (ilg, tUnder);
+		}
+
+		public static void GenFallbackReader (ILGenerator ilg, Type t)
+		{
+			// TODO: do we want non-tUnder here for Castclass use?
+			if (Protocol.Verbose)
+				Console.Error.WriteLine ("Bad! Generating fallback reader for " + t);
+
+			MethodInfo exactMethod;
+			exactMethod = typeof (MessageReader).GetMethod ("ReadValue", new Type[] { typeof (System.Type) });
+
+			// The Type parameter
+			ilg.Emit (OpCodes.Ldtoken, t);
+			ilg.Emit (OpCodes.Call, getTypeFromHandleMethod);
+
+			ilg.Emit (exactMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, exactMethod);
+
+			if (t.IsValueType)
+				ilg.Emit (OpCodes.Unbox_Any, t);
+			else
+				ilg.Emit (OpCodes.Castclass, t);
+		}
+
+		public static void GenReadArrayFixed (ILGenerator ilg, Type t, int knownElemSize)
+		{
+			LocalBuilder readerLocal = ilg.DeclareLocal (typeof (MessageReader));
+			ilg.Emit (OpCodes.Stloc, readerLocal);
+
+			Type tElem = t.GetElementType ();
+			Signature sigElem = Signature.GetSig (tElem);
+			int alignElem = sigElem.Alignment;
+			int knownElemSizePadded = Protocol.Padded (knownElemSize, sigElem.Alignment);
+			Type tUnder = tElem.IsEnum ? Enum.GetUnderlyingType (tElem) : tElem;
+			int managedElemSize = System.Runtime.InteropServices.Marshal.SizeOf (tUnder);
+
+			// Read the array's byte length
+			ilg.Emit (OpCodes.Ldloc, readerLocal);
+			MethodInfo exactMethod = GetReadMethod (typeof (uint));
+			ilg.Emit (exactMethod.IsFinal ? OpCodes.Call : OpCodes.Callvirt, exactMethod);
+			LocalBuilder sizeLocal = ilg.DeclareLocal (typeof (uint));
+			ilg.Emit (OpCodes.Stloc, sizeLocal);
+
+			// Create a new array of the correct element length
+			ilg.Emit (OpCodes.Ldloc, sizeLocal);
+			if (knownElemSizePadded > 1) {
+				ilg.Emit (OpCodes.Ldc_I4, alignElem);
+				MethodInfo paddedMethod = typeof (Protocol).GetMethod ("Padded");
+				ilg.Emit (OpCodes.Call, paddedMethod);
+				// Divide by the known element size
+				ilg.Emit (OpCodes.Ldc_I4, knownElemSizePadded);
+				ilg.Emit (OpCodes.Div_Un);
+			}
+			ilg.Emit (OpCodes.Newarr, tElem);
+			LocalBuilder aryLocal = ilg.DeclareLocal (t);
+			ilg.Emit (OpCodes.Stloc, aryLocal);
+
+			Label nonBlitLabel = ilg.DefineLabel ();
+			Label endLabel = ilg.DefineLabel ();
+
+			// Skip read or blit for zero-length arrays.
+			ilg.Emit (OpCodes.Ldloc, sizeLocal);
+			ilg.Emit (OpCodes.Brfalse, endLabel);
+
+			// WARNING: This may skew pos when we later increment it!
+			if (alignElem > 4) {
+				// Align to element if alignment requirement is higher than 4 (since we just read a uint)
+				ilg.Emit (OpCodes.Ldloc, readerLocal);
+				ilg.Emit (OpCodes.Ldc_I4, alignElem);
+				ilg.Emit (OpCodes.Call, messageReaderReadPad);
+			}
+
+			// Blit where possible
+
+			// shouldBlit: Blit if endian is native
+			// mustBlit: Blit regardless of endian (ie. byte or structs containing only bytes)
+
+			bool shouldBlit = tElem.IsValueType && knownElemSizePadded == managedElemSize && !sigElem.IsStruct;
+
+			// bool and char are not reliably blittable, so we don't allow blitting in these cases.
+			// Their exact layout varies between runtimes, platforms and even data types.
+			shouldBlit &= tElem != typeof (bool) && tElem != typeof (char);
+
+			bool mustBlit = shouldBlit && knownElemSizePadded == 1;
+
+			if (shouldBlit) {
+				if (!mustBlit) {
+					// Check to see if we can blit the data structures
+					FieldInfo nativeEndianField = typeof (MessageReader).GetField ("IsNativeEndian");
+					ilg.Emit (OpCodes.Ldloc, readerLocal);
+					ilg.Emit (OpCodes.Ldfld, nativeEndianField);
+					ilg.Emit (OpCodes.Brfalse_S, nonBlitLabel);
+				}
+
+				// Get the destination address
+				ilg.Emit (OpCodes.Ldloc, aryLocal);
+				ilg.Emit (OpCodes.Ldc_I4_0);
+				ilg.Emit (OpCodes.Ldelema, tElem);
+
+				// Get the source address
+				FieldInfo dataField = typeof (MessageReader).GetField ("data");
+				FieldInfo posField = typeof (MessageReader).GetField ("pos");
+				ilg.Emit (OpCodes.Ldloc, readerLocal);
+				ilg.Emit (OpCodes.Ldfld, dataField);
+				{
+					ilg.Emit (OpCodes.Ldloc, readerLocal);
+					ilg.Emit (OpCodes.Ldfld, posField);
+				}
+				ilg.Emit (OpCodes.Ldelema, typeof (byte));
+
+				// The number of bytes to copy
+				ilg.Emit (OpCodes.Ldloc, sizeLocal);
+
+				// Blit the array
+				ilg.Emit (OpCodes.Cpblk);
+
+				// pos += bytesRead
+				ilg.Emit (OpCodes.Ldloc, readerLocal);
+				ilg.Emit (OpCodes.Ldloc, readerLocal);
+				ilg.Emit (OpCodes.Ldfld, posField);
+				ilg.Emit (OpCodes.Ldloc, sizeLocal);
+				ilg.Emit (OpCodes.Add);
+				ilg.Emit (OpCodes.Stfld, posField);
+
+				ilg.Emit (OpCodes.Br, endLabel);
+			}
+
+			if (!mustBlit) {
+				ilg.MarkLabel (nonBlitLabel);
+
+				// for (int i = 0 ; i < ary.Length ; i++)
+				LocalBuilder indexLocal = ilg.DeclareLocal (typeof (int));
+				ilg.Emit (OpCodes.Ldc_I4_0);
+				ilg.Emit (OpCodes.Stloc, indexLocal);
+
+				Label loopStartLabel = ilg.DefineLabel ();
+				Label loopEndLabel = ilg.DefineLabel ();
+
+				ilg.Emit (OpCodes.Br, loopEndLabel);
+
+				ilg.MarkLabel (loopStartLabel);
+
+				{
+					// Read and store an element to the array
+					ilg.Emit (OpCodes.Ldloc, aryLocal);
+					ilg.Emit (OpCodes.Ldloc, indexLocal);
+
+					ilg.Emit (OpCodes.Ldloc, readerLocal);
+					GenReader (ilg, tElem);
+
+					ilg.Emit (OpCodes.Stelem, tElem);
+				}
+
+				// i++
+				ilg.Emit (OpCodes.Ldloc, indexLocal);
+				ilg.Emit (OpCodes.Ldc_I4_1);
+				ilg.Emit (OpCodes.Add);
+				ilg.Emit (OpCodes.Stloc, indexLocal);
+
+				ilg.MarkLabel (loopEndLabel);
+				ilg.Emit (OpCodes.Ldloc, indexLocal);
+				ilg.Emit (OpCodes.Ldloc, aryLocal);
+				ilg.Emit (OpCodes.Ldlen);
+				ilg.Emit (OpCodes.Blt, loopStartLabel);
+			}
+
+			ilg.MarkLabel (endLabel);
+
+			// Return the new array
+			ilg.Emit (OpCodes.Ldloc, aryLocal);
+		}
+
+		public static void GenReadCollection (ILGenerator ilg, Type type)
+		{
+			int fixedSize = 0;
+			if (type.IsArray && Signature.GetSig (type.GetElementType ()).GetFixedSize (ref fixedSize)) {
+				GenReadArrayFixed (ilg, type, fixedSize);
+				return;
+			}
+
+			LocalBuilder readerLocal = ilg.DeclareLocal (typeof (MessageReader));
+			ilg.Emit (OpCodes.Stloc, readerLocal);
+
+			Type[] genArgs = type.IsArray ? new Type[] { type.GetElementType () } : type.GetGenericArguments ();
+
+			Type collType = Mapper.GetGenericType (genArgs.Length == 2 ? typeof (Dictionary<,>) : typeof (List<>), genArgs);
+
+			ConstructorInfo ctor = collType.GetConstructor (Type.EmptyTypes);
+			ilg.Emit (OpCodes.Newobj, ctor);
+
+			LocalBuilder collLocal = ilg.DeclareLocal (collType);
+			ilg.Emit (OpCodes.Stloc, collLocal);
+
+			MethodInfo addMethod = collType.GetMethod ("Add", genArgs);
+
+
+			// Read the array's byte length
+			MethodInfo readUInt32Method = GetReadMethod (typeof (uint));
+			ilg.Emit (OpCodes.Ldloc, readerLocal);
+			ilg.Emit (readUInt32Method.IsFinal ? OpCodes.Call : OpCodes.Callvirt, readUInt32Method);
+
+			{
+				// Align to 8 for structs
+				ilg.Emit (OpCodes.Ldloc, readerLocal);
+				// TODO: This padding logic is sketchy
+				ilg.Emit (OpCodes.Ldc_I4, genArgs.Length > 1 ? 8 : Signature.GetSig (genArgs[0]).Alignment);
+				ilg.Emit (OpCodes.Call, messageReaderReadPad);
+			}
+
+			// Similar to the fixed array loop code
+
+			FieldInfo posField = typeof (MessageReader).GetField ("pos");
+			LocalBuilder endPosLocal = ilg.DeclareLocal (typeof (int));
+			ilg.Emit (OpCodes.Ldloc, readerLocal);
+			ilg.Emit (OpCodes.Ldfld, posField);
+
+			// Add the current position and byte length to determine endPos
+			// TODO: Consider padding?
+			ilg.Emit (OpCodes.Add);
+			ilg.Emit (OpCodes.Stloc, endPosLocal);
+
+			{
+				Label loopStartLabel = ilg.DefineLabel ();
+				Label loopEndLabel = ilg.DefineLabel ();
+
+				ilg.Emit (OpCodes.Br, loopEndLabel);
+
+				ilg.MarkLabel (loopStartLabel);
+
+				{
+					if (genArgs.Length > 1) {
+						// Align to 8 for structs
+						ilg.Emit (OpCodes.Ldloc, readerLocal);
+						ilg.Emit (OpCodes.Ldc_I4, 8);
+						ilg.Emit (OpCodes.Call, messageReaderReadPad);
+					}
+
+					// Read and store an element to the array
+					ilg.Emit (OpCodes.Ldloc, collLocal);
+
+					foreach (Type genArg in genArgs) {
+						ilg.Emit (OpCodes.Ldloc, readerLocal);
+						GenReader (ilg, genArg);
+					}
+
+					ilg.Emit (OpCodes.Call, addMethod);
+				}
+
+				ilg.MarkLabel (loopEndLabel);
+
+				ilg.Emit (OpCodes.Ldloc, readerLocal);
+				ilg.Emit (OpCodes.Ldfld, posField);
+
+				ilg.Emit (OpCodes.Ldloc, endPosLocal);
+				ilg.Emit (OpCodes.Blt, loopStartLabel);
+			}
+
+			// Return the new collection
+			ilg.Emit (OpCodes.Ldloc, collLocal);
+
+			if (type.IsArray) {
+				MethodInfo toArrayMethod = collType.GetMethod ("ToArray", Type.EmptyTypes);
+				ilg.Emit (OpCodes.Call, toArrayMethod);
+			}
+		}
+	}
+
+	internal delegate void TypeWriter<T> (MessageWriter writer, T value);
+
+	internal delegate void MethodCaller (MessageReader rdr, Message msg, MessageWriter ret);
+	internal delegate void MethodCaller2 (object instance, MessageReader rdr, Message msg, MessageWriter ret);
+}
diff --git a/src/TypeRental.cs b/src/TypeRental.cs
new file mode 100644
index 0000000..96af149
--- /dev/null
+++ b/src/TypeRental.cs
@@ -0,0 +1,504 @@
+// Copyright 2009 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections.Generic;
+
+namespace DBus
+{
+	public class ILReader2
+	{
+		public byte[] m_byteArray;
+		Int32 m_position;
+		MethodBase m_enclosingMethod;
+
+		static OpCode[] s_OneByteOpCodes = new OpCode[0x100];
+		static OpCode[] s_TwoByteOpCodes = new OpCode[0x100];
+		static ILReader2()
+		{
+			foreach (FieldInfo fi in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static))
+			{
+				OpCode opCode = (OpCode)fi.GetValue(null);
+				UInt16 value = (UInt16)opCode.Value;
+				if (value < 0x100)
+					s_OneByteOpCodes[value] = opCode;
+				else if ((value & 0xff00) == 0xfe00)
+					s_TwoByteOpCodes[value & 0xff] = opCode;
+			}
+		}
+
+		/*
+			 public ILReader(MethodBase enclosingMethod)
+			 {
+			 this.m_enclosingMethod = enclosingMethod;
+			 MethodBody methodBody = m_enclosingMethod.GetMethodBody();
+			 this.m_byteArray = (methodBody == null) ? new Byte[0] : methodBody.GetILAsByteArray();
+			 this.m_position = 0;
+			 }
+			 */
+
+		public ILReader2(MethodBase enclosingMethod)
+		{
+			this.m_enclosingMethod = enclosingMethod;
+			MethodBody methodBody = m_enclosingMethod.GetMethodBody();
+			this.m_byteArray = (methodBody == null) ? new Byte[0] : methodBody.GetILAsByteArray();
+			this.m_position = 0;
+		}
+
+		public ILOp[] Iterate()
+		{
+			List<ILOp> data = new List<ILOp>();
+
+			while (m_position < m_byteArray.Length) {
+				Next();
+
+				if (current.operandType == null)
+					current.operandType = String.Empty;
+
+				if (current.operand == null)
+					current.operand = String.Empty;
+
+				data.Add(current);
+			}
+
+			//Console.WriteLine("dataCount: " + data.Count);
+			m_position = 0;
+
+			return data.ToArray();
+		}
+
+		public struct ILOp
+		{
+			/*
+			public ILOp(OpCodeType opType, string operandType)
+			{
+				this.opType = opType;
+				this.operandType = operandType;
+				this.operand = String.Empty;
+			}
+			*/
+
+			public OpCode opCode;
+
+			//public OpCodeType opType;
+			public string operandType;
+			public object operand;
+
+			/*
+			public string operandType
+			{
+				get {
+					//return String.Empty;
+					return String.Empty;
+				} set {
+				}
+			}
+			*/
+			public Type operandTypeT
+			{
+				get {
+					//return String.Empty;
+					if (operandType == String.Empty)
+						return null;
+					return Type.GetType("System" + Type.Delimiter + operandType);
+				}
+			}
+
+			/*
+			public string operand
+			{
+				get {
+					return String.Empty;
+				} set {
+				}
+			}
+			*/
+
+
+			/*
+			public OpCode _opCode
+			{
+				get {
+					//UInt16 value = (UInt16)opCode.Value;
+					UInt16 value = (UInt16)opCodeValue;
+					if (value < 0x100)
+						s_OneByteOpCodes[value] = opCode;
+					else if ((value & 0xff00) == 0xfe00)
+						s_TwoByteOpCodes[value & 0xff] = opCode;
+				}
+			}
+			*/
+
+			static Type ilgType = typeof(ILGenerator);
+
+			public bool Emit(ILGenerator ilg)
+			{
+				Type t = operandTypeT;
+
+				if (t == null) {
+						//Console.WriteLine("emitsimple: " + opCode);
+						if (ilg != null)
+							ilg.Emit(opCode);
+						return true;
+				}
+
+				MethodInfo emitmi = ilgType.GetMethod("Emit", new Type[] {typeof(OpCode), t});
+				//Console.WriteLine("emitmi: " + opCode + " " + emitmi);
+
+				object operandObj = null;
+
+				//if (t == typeof(MethodInfo)) {
+				if (typeof(MemberInfo).IsAssignableFrom(t)) {
+					string operandStr = (string)operand;
+					int idx = operandStr.LastIndexOf(Type.Delimiter);
+					if (idx < 0)
+						return false;
+					string ifaceName = operandStr.Remove(idx);
+					string methName = operandStr.Substring(idx + 1);
+
+					//Console.WriteLine("ifacename: " + ifaceName);
+					//Console.WriteLine("methname: " + methName);
+
+					Type declType = Type.GetType(ifaceName);
+					if (declType == null)
+						declType = Assembly.GetExecutingAssembly().GetType(ifaceName, false);
+					if (declType == null)
+						declType = Assembly.GetCallingAssembly().GetType(ifaceName, false);
+
+					if (declType == null)
+						return false;
+
+					//MethodInfo mi = declType.GetMethod(methName);
+					//if (mi == null)
+					//	return false;
+					MemberInfo[] mis = declType.GetMember(methName);
+					if (mis.Length == 0)
+						return false;
+
+					MemberInfo mi = mis[0];
+
+					//Console.WriteLine("good!: " + mi);
+
+					operandObj = mi;
+				} else if (t == typeof(string))
+					operandObj = (string)operand;
+				else
+					operandObj = Convert.ChangeType(operand, t);
+
+				//Console.WriteLine("operandObj: " + operandObj);
+				if (ilg != null)
+					emitmi.Invoke(ilg, new object[] { opCode, operandObj });
+
+				/*
+				switch (operandType) {
+					case nu:
+						ilg.Emit(opCode);
+					return true;
+					case "MethodInfo":
+						MethodInfo mi = null;
+					ilg.Emit(opCode, mi);
+					return true;
+				}
+				*/
+
+				return true;
+			}
+		}
+
+		public static bool TryGetType(string ifaceName, out Type declType)
+		{
+			declType = Type.GetType(ifaceName);
+			if (declType == null)
+				declType = Assembly.GetExecutingAssembly().GetType(ifaceName, false);
+			if (declType == null)
+				declType = Assembly.GetCallingAssembly().GetType(ifaceName, false);
+			return declType != null;
+		}
+
+
+		ILOp current;
+
+		void Next()
+		{
+			Int32 offset = m_position;
+			OpCode opCode = OpCodes.Nop;
+			int token = 0;
+
+			// read first 1 or 2 bytes as opCode
+			Byte code = ReadByte();
+			if (code != 0xFE)
+				opCode = s_OneByteOpCodes[code];
+			else
+			{
+				code = ReadByte();
+				opCode = s_TwoByteOpCodes[code];
+			}
+
+			//Console.WriteLine("opcode: " + opCode);
+
+			current = new ILOp();
+			//current.opType = opCode.OpCodeType;
+			current.opCode = opCode;
+			//current.opType = opCode.OperandType;
+
+			switch (opCode.OperandType)
+			{
+				case OperandType.InlineNone:
+					//ilg.Emit(opCode);
+					break;
+				case OperandType.ShortInlineBrTarget:
+					SByte shortDelta = ReadSByte();
+					//ilg.Emit(opCode, shortDelta);
+					break;
+				case OperandType.InlineBrTarget:
+					Int32 delta = ReadInt32();
+					//ilg.Emit(opCode, delta);
+					break;
+				case OperandType.ShortInlineI:
+					byte int8 = ReadByte();
+					//ilg.Emit(opCode, int8);
+					break;
+				case OperandType.InlineI:
+					Int32 int32 = ReadInt32();
+					//ilg.Emit(opCode, int32);
+					break;
+				case OperandType.InlineI8:
+					Int64 int64 = ReadInt64();
+					//ilg.Emit(opCode, int64);
+					break;
+				case OperandType.ShortInlineR:
+					Single float32 = ReadSingle();
+					//ilg.Emit(opCode, float32);
+					break;
+				case OperandType.InlineR:
+					Double float64 = ReadDouble();
+					//ilg.Emit(opCode, float64);
+					break;
+				case OperandType.ShortInlineVar:
+					Byte index8 = ReadByte();
+					//ilg.Emit(opCode, index8);
+					break;
+				case OperandType.InlineVar:
+					UInt16 index16 = ReadUInt16();
+					//ilg.Emit(opCode, index16);
+					break;
+				case OperandType.InlineString:
+					token = ReadInt32();
+					current.operandType = "String";
+					current.operand = m_enclosingMethod.Module.ResolveString(token);
+					//ilg.Emit(opCode, m_enclosingMethod.Module.ResolveString(token));
+					break;
+				case OperandType.InlineSig:
+					token = ReadInt32();
+					//ilg.Emit(opCode, m_enclosingMethod.Module.ResolveSignature(token));
+					throw new NotImplementedException();
+					break;
+				case OperandType.InlineField:
+					token = ReadInt32();
+					FieldInfo fi = m_enclosingMethod.Module.ResolveField(token);
+					current.operandType = "Reflection.FieldInfo";
+					current.operand = fi.DeclaringType.FullName + Type.Delimiter + fi.Name;
+					//ilg.Emit(opCode, m_enclosingMethod.Module.ResolveField(token));
+					break;
+				case OperandType.InlineType:
+					token = ReadInt32();
+					current.operandType = "Type";
+					Type t = m_enclosingMethod.Module.ResolveType(token);
+					current.operand = t.FullName;
+					//ilg.Emit(opCode, m_enclosingMethod.Module.ResolveType(token));
+					break;
+				case OperandType.InlineTok:
+					token = ReadInt32();
+					//ilg.Emit(opCode, token);
+					break;
+				case OperandType.InlineMethod:
+					token = ReadInt32();
+					MethodInfo mi = (MethodInfo)m_enclosingMethod.Module.ResolveMethod(token);
+					current.operandType = "Reflection.MethodInfo";
+					current.operand = mi.DeclaringType.FullName + Type.Delimiter + mi.Name;
+					//ilg.Emit(opCode, mi);
+					break;
+				case OperandType.InlineSwitch:
+
+					throw new NotImplementedException();
+
+					Int32 cases = ReadInt32();
+					Int32[] deltas = new Int32[cases];
+					for (Int32 i = 0; i < cases; i++) deltas[i] = ReadInt32();
+					break;
+
+				default:
+					throw new BadImageFormatException("unexpected OperandType " + opCode.OperandType);
+			}
+		}
+
+		Byte ReadByte()
+		{
+			current.operandType = "Byte";
+			Byte ret = (Byte)m_byteArray[m_position++];
+			current.operand = ret;
+			return ret;
+		}
+
+		SByte ReadSByte()
+		{
+			current.operandType = "SByte";
+			SByte ret = (SByte)ReadByte();
+			current.operand = ret;
+			return ret;
+		}
+
+		UInt16 ReadUInt16() {
+			current.operandType = "UInt16";
+			m_position += 2;
+			UInt16 ret = BitConverter.ToUInt16(m_byteArray, m_position - 2);
+			current.operand = ret;
+			return ret;
+		}
+
+		UInt32 ReadUInt32() {
+			current.operandType = "UInt32";
+			m_position += 4;
+			UInt32 ret = BitConverter.ToUInt32(m_byteArray, m_position - 4);
+			current.operand = ret;
+			return ret;
+		}
+
+		UInt64 ReadUInt64() {
+			current.operandType = "UInt64";
+			m_position += 8;
+			UInt64 ret = BitConverter.ToUInt64(m_byteArray, m_position - 8);
+			current.operand = ret;
+			return ret;
+		}
+
+		Int32 ReadInt32() {
+			current.operandType = "Int32";
+			m_position += 4;
+			Int32 ret = BitConverter.ToInt32(m_byteArray, m_position - 4);
+			current.operand = ret;
+			return ret;
+		}
+
+		Int64 ReadInt64() {
+			current.operandType = "Int64";
+			m_position += 8;
+			Int64 ret = BitConverter.ToInt64(m_byteArray, m_position - 8);
+			current.operand = ret;
+			return ret;
+		}
+
+		Single ReadSingle() {
+			current.operandType = "UInt16";
+			m_position += 4;
+			Single ret = BitConverter.ToSingle(m_byteArray, m_position - 4);
+			current.operand = ret;
+			return ret;
+		}
+
+		Double ReadDouble() {
+			current.operandType = "Double";
+			m_position += 8;
+			Double ret = BitConverter.ToDouble(m_byteArray, m_position - 8);
+			current.operand = ret;
+			return ret;
+		}
+	}
+
+#if RENTAL_STUFF_FROM_DAEMON
+
+		/*
+		public string MyMeth (uint val1, string val2)
+		{
+			Console.WriteLine ("MyMeth " + val1 + " " + val2);
+			return "WEE!";
+		}
+		*/
+
+		/*
+		public struct MethData
+		{
+			public int A;
+			public int B;
+			public int C;
+		}
+		*/
+
+		public class MethDataBase
+		{
+			public int A;
+		}
+
+		public class MethData : MethDataBase
+		{
+			public int B;
+			public int C;
+			//public MethData[] Children;
+			public long[] Children;
+		}
+
+		public void MyMeth0 ()
+		{
+		}
+
+		public string MyMeth (MethData d, int[] ary, IDictionary<int, string> dict)
+		{
+			Console.WriteLine ("MyMeth struct " + d.A + " " + d.B + " " + d.C);
+			foreach (int i in ary)
+				Console.WriteLine (i);
+			Console.WriteLine ("Children: " + d.Children.Length);
+			Console.WriteLine ("Dict entries: " + dict.Count);
+			Console.WriteLine ("321: " + dict[321]);
+			return "WEE!";
+		}
+
+	// From HandleMessage():
+				//if (msg.Signature == new Signature ("u"))
+			if (false) {
+				System.Reflection.MethodInfo target = typeof (ServerBus).GetMethod ("MyMeth");
+				//System.Reflection.MethodInfo target = typeof (ServerBus).GetMethod ("MyMeth0");
+				Signature inSig, outSig;
+				TypeImplementer.SigsForMethod (target, out inSig, out outSig);
+				Console.WriteLine ("inSig: " + inSig);
+
+				if (msg.Signature == inSig) {
+					MethodCaller caller = TypeImplementer.GenCaller (target, this);
+					//caller (new MessageReader (msg), msg);
+
+					MessageWriter retWriter = new MessageWriter ();
+					caller (new MessageReader (msg), msg, retWriter);
+
+					if (msg.ReplyExpected) {
+						MethodReturn method_return = new MethodReturn (msg.Header.Serial);
+						Message replyMsg = method_return.message;
+						replyMsg.Body = retWriter.ToArray ();
+						Console.WriteLine ("replyMsg body: " + replyMsg.Body.Length);
+						/*
+						try {
+						replyMsg.Header[FieldCode.Destination] = msg.Header[FieldCode.Sender];
+						replyMsg.Header[FieldCode.Sender] = Caller.UniqueName;
+						} catch (Exception e) {
+							Console.Error.WriteLine (e);
+						}
+						*/
+						replyMsg.Header[FieldCode.Destination] = Caller.UniqueName;
+						replyMsg.Header[FieldCode.Sender] = "org.freedesktop.DBus";
+						replyMsg.Signature = outSig;
+						{
+							Caller.Send (replyMsg);
+
+							/*
+							replyMsg.Header.Serial = Caller.GenerateSerial ();
+							MessageDumper.WriteMessage (replyMsg, Console.Out);
+							Caller.SendReal (replyMsg);
+							*/
+							return;
+						}
+					}
+				}
+			}
+#endif
+}
diff --git a/src/Unix.cs b/src/Unix.cs
new file mode 100644
index 0000000..5cd6879
--- /dev/null
+++ b/src/Unix.cs
@@ -0,0 +1,484 @@
+// Copyright 2008 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace DBus.Unix
+{
+	// size_t
+	using SizeT = System.UIntPtr;
+	// ssize_t
+	using SSizeT = System.IntPtr;
+	// socklen_t: assumed to be 4 bytes
+	// uid_t: assumed to be 4 bytes
+
+	sealed class UnixStream : Stream //, IDisposable
+	{
+		public readonly UnixSocket usock;
+
+		public UnixStream (int fd)
+		{
+			this.usock = new UnixSocket (fd);
+		}
+
+		public UnixStream (UnixSocket usock)
+		{
+			this.usock = usock;
+		}
+
+		public override bool CanRead
+		{
+			get {
+				return true;
+			}
+		}
+
+		public override bool CanSeek
+		{
+			get {
+				return false;
+			}
+		}
+
+		public override bool CanWrite
+		{
+			get {
+				return true;
+			}
+		}
+
+		public override long Length
+		{
+			get {
+				throw new NotImplementedException ("Seeking is not implemented");
+			}
+		}
+
+		public override long Position
+		{
+			get {
+				throw new NotImplementedException ("Seeking is not implemented");
+			} set {
+				throw new NotImplementedException ("Seeking is not implemented");
+			}
+		}
+
+		public override long Seek (long offset, SeekOrigin origin)
+		{
+			throw new NotImplementedException ("Seeking is not implemented");
+		}
+
+		public override void SetLength (long value)
+		{
+			throw new NotImplementedException ("Not implemented");
+		}
+
+		public override void Flush ()
+		{
+		}
+
+		public override int Read ([In, Out] byte[] buffer, int offset, int count)
+		{
+			return usock.Read (buffer, offset, count);
+		}
+
+		public override void Write (byte[] buffer, int offset, int count)
+		{
+			usock.Write (buffer, offset, count);
+		}
+
+		unsafe public override int ReadByte ()
+		{
+			byte value;
+			usock.Read (&value, 1);
+			return value;
+		}
+
+		unsafe public override void WriteByte (byte value)
+		{
+			usock.Write (&value, 1);
+		}
+	}
+
+	static class UnixUid
+	{
+		internal const string LIBC = "libc";
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=false)]
+		static extern uint getuid ();
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=false)]
+		static extern uint geteuid ();
+
+		public static long GetUID ()
+		{
+			long uid = getuid ();
+			return uid;
+		}
+
+		public static long GetEUID ()
+		{
+			long euid = geteuid ();
+			return euid;
+		}
+	}
+
+	static class UnixError
+	{
+		internal const string LIBC = "libc";
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=false)]
+		static extern IntPtr strerror (int errnum);
+
+		static string GetErrorString (int errnum)
+		{
+			IntPtr strPtr = strerror (errnum);
+
+			if (strPtr == IntPtr.Zero)
+				return "Unknown Unix error";
+
+			return Marshal.PtrToStringAnsi (strPtr);
+		}
+
+		// FIXME: Don't hard-code this.
+		const int EINTR = 4;
+
+		public static bool ShouldRetry
+		{
+			get {
+				int errno = System.Runtime.InteropServices.Marshal.GetLastWin32Error ();
+				return errno == EINTR;
+			}
+		}
+
+		public static Exception GetLastUnixException ()
+		{
+			int errno = System.Runtime.InteropServices.Marshal.GetLastWin32Error ();
+			return new Exception (String.Format ("Error {0}: {1}", errno, GetErrorString (errno)));
+		}
+	}
+
+	//[StructLayout(LayoutKind.Sequential, Pack=1)]
+	unsafe struct IOVector
+	{
+		public IOVector (IntPtr bbase, int length)
+		{
+			this.Base = (void*)bbase;
+			this.length = (SizeT)length;
+		}
+
+		//public IntPtr Base;
+		public void* Base;
+
+		public SizeT length;
+		public int Length
+		{
+			get {
+				return (int)length;
+			} set {
+				length = (SizeT)value;
+			}
+		}
+	}
+
+	/*
+	unsafe class SockAddr
+	{
+		byte[] data;
+	}
+	*/
+
+	unsafe class UnixSocket
+	{
+		internal const string LIBC = "libc";
+
+		// Solaris provides socket functionality in libsocket rather than libc.
+		// We use a dllmap in the .config to deal with this.
+		internal const string LIBSOCKET = "libsocket";
+
+		public const short AF_UNIX = 1;
+		// FIXME: SOCK_STREAM is 2 on Solaris
+		public const short SOCK_STREAM = 1;
+
+		[DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
+		internal static extern IntPtr fork ();
+
+		[DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
+		internal static extern int dup2 (int fd, int fd2);
+
+		[DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
+		internal static extern int open ([MarshalAs(UnmanagedType.LPStr)] string path, int oflag);
+
+		[DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
+		internal static extern IntPtr setsid ();
+
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		internal static extern int close (int fd);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int socket (int domain, int type, int protocol);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int connect (int sockfd, byte[] serv_addr, uint addrlen);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int bind (int sockfd, byte[] my_addr, uint addrlen);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int listen (int sockfd, int backlog);
+
+		//TODO: this prototype is probably wrong, fix it
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int accept (int sockfd, void* addr, ref uint addrlen);
+
+		//TODO: confirm and make use of these functions
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int getsockopt (int s, int optname, IntPtr optval, ref uint optlen);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		protected static extern int setsockopt (int s, int optname, IntPtr optval, uint optlen);
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		unsafe static extern SSizeT read (int fd, byte* buf, SizeT count);
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		unsafe static extern SSizeT write (int fd, byte* buf, SizeT count);
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		unsafe static extern SSizeT readv (int fd, IOVector* iov, int iovcnt);
+
+		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		unsafe static extern SSizeT writev (int fd, IOVector* iov, int iovcnt);
+
+		// Linux
+		//[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		//static extern int vmsplice (int fd, IOVector* iov, uint nr_segs, uint flags);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		public static extern SSizeT recvmsg (int s, void* msg, int flags);
+
+		[DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
+		public static extern SSizeT sendmsg (int s, void* msg, int flags);
+
+		public int Handle;
+		bool ownsHandle = false;
+
+		public UnixSocket (int handle) : this (handle, false)
+		{
+		}
+
+		public UnixSocket (int handle, bool ownsHandle)
+		{
+			this.Handle = handle;
+			this.ownsHandle = ownsHandle;
+			// TODO: SafeHandle?
+		}
+
+		public UnixSocket ()
+		{
+			//TODO: don't hard-code PF_UNIX and SOCK_STREAM or SocketType.Stream
+			//AddressFamily family, SocketType type, ProtocolType proto
+
+			int r = socket (AF_UNIX, SOCK_STREAM, 0);
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			Handle = r;
+			ownsHandle = true;
+		}
+
+		~UnixSocket ()
+		{
+			if (ownsHandle && Handle > 0)
+				Close ();
+		}
+
+		protected bool connected = false;
+
+		//TODO: consider memory management
+		public void Close ()
+		{
+			int r = 0;
+
+			do {
+				r = close (Handle);
+			} while (r < 0 && UnixError.ShouldRetry);
+
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			Handle = -1;
+			connected = false;
+		}
+
+		//TODO: consider memory management
+		public void Connect (byte[] remote_end)
+		{
+			int r = 0;
+
+			do {
+				r = connect (Handle, remote_end, (uint)remote_end.Length);
+			} while (r < 0 && UnixError.ShouldRetry);
+
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			connected = true;
+		}
+
+		//assigns a name to the socket
+		public void Bind (byte[] local_end)
+		{
+			int r = bind (Handle, local_end, (uint)local_end.Length);
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+		}
+
+		public void Listen (int backlog)
+		{
+			int r = listen (Handle, backlog);
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+		}
+
+		public UnixSocket Accept ()
+		{
+			byte[] addr = new byte[110];
+			uint addrlen = (uint)addr.Length;
+
+			fixed (byte* addrP = addr) {
+				int r = 0;
+
+				do {
+					r = accept (Handle, addrP, ref addrlen);
+				} while (r < 0 && UnixError.ShouldRetry);
+
+				if (r < 0)
+					throw UnixError.GetLastUnixException ();
+
+				//TODO: use the returned addr
+				//string str = Encoding.Default.GetString (addr, 0, (int)addrlen);
+				return new UnixSocket (r, true);
+			}
+		}
+
+		unsafe public int Read (byte[] buf, int offset, int count)
+		{
+			fixed (byte* bufP = buf)
+				return Read (bufP + offset, count);
+		}
+
+		public int Write (byte[] buf, int offset, int count)
+		{
+			fixed (byte* bufP = buf)
+				return Write (bufP + offset, count);
+		}
+
+		unsafe public int Read (byte* bufP, int count)
+		{
+			int r = 0;
+
+			do {
+				r = (int)read (Handle, bufP, (SizeT)count);
+			} while (r < 0 && UnixError.ShouldRetry);
+
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			return r;
+		}
+
+		public int Write (byte* bufP, int count)
+		{
+			int r = 0;
+
+			do {
+				r = (int)write (Handle, bufP, (SizeT)count);
+			} while (r < 0 && UnixError.ShouldRetry);
+
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			return r;
+		}
+
+		public int RecvMsg (void* bufP, int flags)
+		{
+			int r = 0;
+
+			do {
+				r = (int)recvmsg (Handle, bufP, flags);
+			} while (r < 0 && UnixError.ShouldRetry);
+
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			return r;
+		}
+
+		public int SendMsg (void* bufP, int flags)
+		{
+			int r = 0;
+
+			do {
+				r = (int)sendmsg (Handle, bufP, flags);
+			} while (r < 0 && UnixError.ShouldRetry);
+
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			return r;
+		}
+
+		public int ReadV (IOVector* iov, int count)
+		{
+			//FIXME: Handle EINTR here or elsewhere
+			//FIXME: handle r != count
+			//TODO: check offset correctness
+
+			int r = (int)readv (Handle, iov, count);
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			return r;
+		}
+
+		public int WriteV (IOVector* iov, int count)
+		{
+			//FIXME: Handle EINTR here or elsewhere
+			//FIXME: handle r != count
+			//TODO: check offset correctness
+
+			int r = (int)writev (Handle, iov, count);
+			if (r < 0)
+				throw UnixError.GetLastUnixException ();
+
+			return r;
+		}
+
+		public int Write (IOVector[] iov, int offset, int count)
+		{
+			//FIXME: Handle EINTR here or elsewhere
+			//FIXME: handle r != count
+			//TODO: check offset correctness
+
+			fixed (IOVector* bufP = &iov[offset]) {
+				int r = (int)writev (Handle, bufP + offset, count);
+				if (r < 0)
+					throw UnixError.GetLastUnixException ();
+
+				return r;
+			}
+		}
+
+		public int Write (IOVector[] iov)
+		{
+			return Write (iov, 0, iov.Length);
+		}
+
+	}
+}
diff --git a/src/UnixNativeTransport.cs b/src/UnixNativeTransport.cs
new file mode 100644
index 0000000..14eca60
--- /dev/null
+++ b/src/UnixNativeTransport.cs
@@ -0,0 +1,180 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+//We send BSD-style credentials on all platforms
+//Doesn't seem to break Linux (but is redundant there)
+//This may turn out to be a bad idea
+#define HAVE_CMSGCRED
+
+using System;
+using System.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+using DBus.Unix;
+
+namespace DBus.Transports
+{
+	class UnixNativeTransport : UnixTransport
+	{
+		internal UnixSocket socket;
+
+		public override string AuthString ()
+		{
+			long uid = UnixUid.GetEUID ();
+			return uid.ToString ();
+		}
+
+		public override void Open (string path, bool @abstract)
+		{
+			if (String.IsNullOrEmpty (path))
+				throw new ArgumentException ("path");
+
+			if (@abstract)
+				socket = OpenAbstractUnix (path);
+			else
+				socket = OpenUnix (path);
+
+			//socket.Blocking = true;
+			SocketHandle = (long)socket.Handle;
+			//Stream = new UnixStream ((int)socket.Handle);
+			Stream = new UnixStream (socket);
+		}
+
+		//send peer credentials null byte
+		//different platforms do this in different ways
+#if HAVE_CMSGCRED
+		unsafe void WriteBsdCred ()
+		{
+			//null credentials byte
+			byte buf = 0;
+
+			IOVector iov = new IOVector ();
+			//iov.Base = (IntPtr)(&buf);
+			iov.Base = &buf;
+			iov.Length = 1;
+
+			msghdr msg = new msghdr ();
+			msg.msg_iov = &iov;
+			msg.msg_iovlen = 1;
+
+			cmsg cm = new cmsg ();
+			msg.msg_control = (IntPtr)(&cm);
+			msg.msg_controllen = (uint)sizeof (cmsg);
+			cm.hdr.cmsg_len = (uint)sizeof (cmsg);
+			cm.hdr.cmsg_level = 0xffff; //SOL_SOCKET
+			cm.hdr.cmsg_type = 0x03; //SCM_CREDS
+
+			int written = socket.SendMsg (&msg, 0);
+			if (written != 1)
+				throw new Exception ("Failed to write credentials");
+		}
+#endif
+
+		public override void WriteCred ()
+		{
+#if HAVE_CMSGCRED
+			try {
+				WriteBsdCred ();
+				return;
+			} catch {
+				if (Protocol.Verbose)
+					Console.Error.WriteLine ("Warning: WriteBsdCred() failed; falling back to ordinary WriteCred()");
+			}
+#endif
+			//null credentials byte
+			byte buf = 0;
+			Stream.WriteByte (buf);
+		}
+
+		public static byte[] GetSockAddr (string path)
+		{
+			byte[] p = Encoding.Default.GetBytes (path);
+
+			byte[] sa = new byte[2 + p.Length + 1];
+
+			//we use BitConverter to stay endian-safe
+			byte[] afData = BitConverter.GetBytes (UnixSocket.AF_UNIX);
+			sa[0] = afData[0];
+			sa[1] = afData[1];
+
+			for (int i = 0 ; i != p.Length ; i++)
+				sa[2 + i] = p[i];
+			sa[2 + p.Length] = 0; //null suffix for domain socket addresses, see unix(7)
+
+			return sa;
+		}
+
+		public static byte[] GetSockAddrAbstract (string path)
+		{
+			byte[] p = Encoding.Default.GetBytes (path);
+
+			byte[] sa = new byte[2 + 1 + p.Length];
+
+			//we use BitConverter to stay endian-safe
+			byte[] afData = BitConverter.GetBytes (UnixSocket.AF_UNIX);
+			sa[0] = afData[0];
+			sa[1] = afData[1];
+
+			sa[2] = 0; //null prefix for abstract domain socket addresses, see unix(7)
+			for (int i = 0 ; i != p.Length ; i++)
+				sa[3 + i] = p[i];
+
+			return sa;
+		}
+
+		internal UnixSocket OpenUnix (string path)
+		{
+			byte[] sa = GetSockAddr (path);
+			UnixSocket client = new UnixSocket ();
+			client.Connect (sa);
+			return client;
+		}
+
+		internal UnixSocket OpenAbstractUnix (string path)
+		{
+			byte[] sa = GetSockAddrAbstract (path);
+			UnixSocket client = new UnixSocket ();
+			client.Connect (sa);
+			return client;
+		}
+	}
+
+#if HAVE_CMSGCRED
+	unsafe struct msghdr
+	{
+		public IntPtr msg_name; //optional address
+		public uint msg_namelen; //size of address
+		public IOVector *msg_iov; //scatter/gather array
+		public int msg_iovlen; //# elements in msg_iov
+		public IntPtr msg_control; //ancillary data, see below
+		public uint msg_controllen; //ancillary data buffer len
+		public int msg_flags; //flags on received message
+	}
+
+	struct cmsghdr
+	{
+		public uint cmsg_len; //data byte count, including header
+		public int cmsg_level; //originating protocol
+		public int cmsg_type; //protocol-specific type
+	}
+
+	unsafe struct cmsgcred
+	{
+		const int CMGROUP_MAX = 16;
+
+		public int cmcred_pid; //PID of sending process
+		public uint cmcred_uid; //real UID of sending process
+		public uint cmcred_euid; //effective UID of sending process
+		public uint cmcred_gid; //real GID of sending process
+		public short cmcred_ngroups; //number or groups
+		public fixed uint cmcred_groups[CMGROUP_MAX]; //groups
+	}
+
+	struct cmsg
+	{
+		public cmsghdr hdr;
+		public cmsgcred cred;
+	}
+#endif
+}
diff --git a/src/UnixTransport.cs b/src/UnixTransport.cs
new file mode 100644
index 0000000..e433b6d
--- /dev/null
+++ b/src/UnixTransport.cs
@@ -0,0 +1,29 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.IO;
+
+namespace DBus.Transports
+{
+	abstract class UnixTransport : Transport
+	{
+		public override void Open (AddressEntry entry)
+		{
+			string path;
+			bool abstr;
+
+			if (entry.Properties.TryGetValue ("path", out path))
+				abstr = false;
+			else if (entry.Properties.TryGetValue ("abstract", out path))
+				abstr = true;
+			else
+				throw new Exception ("No path specified for UNIX transport");
+
+			Open (path, abstr);
+		}
+
+		public abstract void Open (string path, bool @abstract);
+	}
+}
diff --git a/src/Wrapper.cs b/src/Wrapper.cs
new file mode 100644
index 0000000..ff13102
--- /dev/null
+++ b/src/Wrapper.cs
@@ -0,0 +1,158 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace DBus
+{
+	//TODO: complete and use these wrapper classes
+	//not sure exactly what I'm thinking but there seems to be sense here
+
+	//FIXME: signature sending/receiving is currently ambiguous in this code
+	//FIXME: in fact, these classes are totally broken and end up doing no-op, do not use without understanding the problem
+	class MethodCall
+	{
+		public Message message = new Message ();
+
+		public MethodCall (ObjectPath path, string @interface, string member, string destination, Signature signature)
+		{
+			message.Header.MessageType = MessageType.MethodCall;
+			message.ReplyExpected = true;
+			message.Header[FieldCode.Path] = path;
+			message.Header[FieldCode.Interface] = @interface;
+			message.Header[FieldCode.Member] = member;
+			message.Header[FieldCode.Destination] = destination;
+			//TODO: consider setting Sender here for p2p situations
+			//this will allow us to remove the p2p hacks in MethodCall and Message
+#if PROTO_REPLY_SIGNATURE
+			//TODO
+#endif
+			message.Signature = signature;
+		}
+
+		public MethodCall (Message message)
+		{
+			this.message = message;
+			Path = (ObjectPath)message.Header[FieldCode.Path];
+			Interface = (string)message.Header[FieldCode.Interface];
+			Member = (string)message.Header[FieldCode.Member];
+			Destination = (string)message.Header[FieldCode.Destination];
+			//TODO: filled by the bus so reliable, but not the case for p2p
+			//so we make it optional here, but this needs some more thought
+			//if (message.Header.Fields.ContainsKey (FieldCode.Sender))
+			Sender = (string)message.Header[FieldCode.Sender];
+#if PROTO_REPLY_SIGNATURE
+			//TODO: note that an empty ReplySignature should really be treated differently to the field not existing!
+			if (message.Header.Fields.ContainsKey (FieldCode.ReplySignature))
+				ReplySignature = (Signature)message.Header[FieldCode.ReplySignature];
+			else
+				ReplySignature = Signature.Empty;
+#endif
+			Signature = message.Signature;
+		}
+
+		public ObjectPath Path;
+		public string Interface;
+		public string Member;
+		public string Destination;
+		public string Sender;
+#if PROTO_REPLY_SIGNATURE
+		public Signature ReplySignature;
+#endif
+		public Signature Signature;
+
+		public Error CreateError (string errorName, string errorMessage)
+		{
+			Error error = new Error (errorName, message.Header.Serial);
+			error.message.Signature = Signature.StringSig;
+
+			MessageWriter writer = new MessageWriter (message.Header.Endianness);
+			//writer.connection = conn;
+			writer.Write (errorMessage);
+			error.message.Body = writer.ToArray ();
+
+			//if (method_call.Sender != null)
+			//	replyMsg.Header[FieldCode.Destination] = method_call.Sender;
+
+			return error;
+		}
+	}
+
+	class MethodReturn
+	{
+		public Message message = new Message ();
+
+		public MethodReturn (uint reply_serial)
+		{
+			message.Header.MessageType = MessageType.MethodReturn;
+			message.Header.Flags = HeaderFlag.NoReplyExpected | HeaderFlag.NoAutoStart;
+			message.Header[FieldCode.ReplySerial] = reply_serial;
+			//signature optional?
+			//message.Header[FieldCode.Signature] = signature;
+		}
+
+		public MethodReturn (Message message)
+		{
+			this.message = message;
+			ReplySerial = (uint)message.Header[FieldCode.ReplySerial];
+		}
+
+		public uint ReplySerial;
+	}
+
+	class Error
+	{
+		public Message message = new Message ();
+
+		public Error (string error_name, uint reply_serial)
+		{
+			message.Header.MessageType = MessageType.Error;
+			message.Header.Flags = HeaderFlag.NoReplyExpected | HeaderFlag.NoAutoStart;
+			message.Header[FieldCode.ErrorName] = error_name;
+			message.Header[FieldCode.ReplySerial] = reply_serial;
+		}
+
+		public Error (Message message)
+		{
+			this.message = message;
+			ErrorName = (string)message.Header[FieldCode.ErrorName];
+			ReplySerial = (uint)message.Header[FieldCode.ReplySerial];
+			//Signature = (Signature)message.Header[FieldCode.Signature];
+		}
+
+		public string ErrorName;
+		public uint ReplySerial;
+		//public Signature Signature;
+	}
+
+	class Signal
+	{
+		public Message message = new Message ();
+
+		public Signal (ObjectPath path, string @interface, string member)
+		{
+			message.Header.MessageType = MessageType.Signal;
+			message.Header.Flags = HeaderFlag.NoReplyExpected | HeaderFlag.NoAutoStart;
+			message.Header[FieldCode.Path] = path;
+			message.Header[FieldCode.Interface] = @interface;
+			message.Header[FieldCode.Member] = member;
+		}
+
+		public Signal (Message message)
+		{
+			this.message = message;
+			Path = (ObjectPath)message.Header[FieldCode.Path];
+			Interface = (string)message.Header[FieldCode.Interface];
+			Member = (string)message.Header[FieldCode.Member];
+			Sender = (string)message.Header[FieldCode.Sender];
+		}
+
+		public ObjectPath Path;
+		public string Interface;
+		public string Member;
+		public string Sender;
+	}
+}
diff --git a/src/dbus-sharp.dll.config b/src/dbus-sharp.dll.config
new file mode 100644
index 0000000..39995ef
--- /dev/null
+++ b/src/dbus-sharp.dll.config
@@ -0,0 +1,3 @@
+<configuration>
+  <dllmap dll="libsocket" os="!solaris" target="libc.so.6"/>
+</configuration>
diff --git a/tools/Introspect.cs b/tools/Introspect.cs
new file mode 100644
index 0000000..d1c6d68
--- /dev/null
+++ b/tools/Introspect.cs
@@ -0,0 +1,35 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+using DBus;
+using Schemas;
+
+public class test
+{
+	public static void Main (string[] args)
+	{
+		string fname = args[0];
+		StreamReader sr = new StreamReader (fname);
+		XmlSerializer sz = new XmlSerializer (typeof (Node));
+		Node node = (Node)sz.Deserialize (sr);
+
+		Interface iface = node.Interfaces[1];
+
+		foreach (Method meth in iface.Methods) {
+			Console.Write (meth.Name);
+			Console.Write (" (");
+
+			if (meth.Arguments != null)
+			foreach (Argument arg in meth.Arguments)
+				Console.Write ("[" + arg.Direction + "] " + arg.Type + " " + arg.Name + ", ");
+			Console.Write (");");
+			Console.WriteLine ();
+		}
+	}
+}
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..b7610af
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,3 @@
+EXTRA_DIST = \
+	Introspect.cs \
+	Monitor.cs
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000..52b3490
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,311 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = tools
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+API_VERSION = @API_VERSION@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+GACUTIL = @GACUTIL@
+GMCS = @GMCS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MONO_CFLAGS = @MONO_CFLAGS@
+MONO_LIBS = @MONO_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+	Introspect.cs \
+	Monitor.cs
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu tools/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/Monitor.cs b/tools/Monitor.cs
new file mode 100644
index 0000000..73bfb05
--- /dev/null
+++ b/tools/Monitor.cs
@@ -0,0 +1,239 @@
+// Copyright 2006 Alp Toker <alp at atoker.com>
+// This software is made available under the MIT License
+// See COPYING for details
+
+using System;
+using System.Text;
+using System.IO;
+using System.Collections.Generic;
+using DBus;
+using org.freedesktop.DBus;
+
+class BusMonitor
+{
+	static Connection bus = null;
+
+	public static int Main (string[] args)
+	{
+		bus = null;
+		bool readIn = false;
+		bool readOut = false;
+		List<string> rules = new List<string> ();
+
+		for (int i = 0 ; i != args.Length ; i++) {
+			string arg = args[i];
+
+			if (!arg.StartsWith ("--")) {
+				rules.Add (arg);
+				continue;
+			}
+
+			switch (arg)
+			{
+				case "--stdin":
+					readIn = true;
+					break;
+				case "--stdout":
+					readOut = true;
+					break;
+				case "--system":
+					bus = Bus.System;
+					break;
+				case "--session":
+					bus = Bus.Session;
+					break;
+				default:
+					Console.Error.WriteLine ("Usage: monitor.exe [--stdin|--stdout|--system|--session] [watch expressions]");
+					Console.Error.WriteLine ("       If no watch expressions are provided, defaults will be used.");
+					return 1;
+			}
+		}
+
+		if (bus == null)
+			bus = Bus.Session;
+
+		if (rules.Count != 0) {
+			//install custom match rules only
+			foreach (string rule in rules)
+				bus.AddMatch (rule);
+		} else {
+			//no custom match rules, install the defaults
+			bus.AddMatch (MessageFilter.CreateMatchRule (MessageType.Signal));
+			bus.AddMatch (MessageFilter.CreateMatchRule (MessageType.MethodReturn));
+			bus.AddMatch (MessageFilter.CreateMatchRule (MessageType.Error));
+			bus.AddMatch (MessageFilter.CreateMatchRule (MessageType.MethodCall));
+		}
+
+		if (readIn) {
+			ReadIn ();
+			return 0;
+		}
+
+		if (readOut) {
+			ReadOut ();
+			return 0;
+		}
+
+		PrettyPrintOut ();
+		return 0;
+	}
+
+	static void ReadIn ()
+	{
+		TextReader r = Console.In;
+
+		while (true) {
+			Message msg = MessageDumper.ReadMessage (r);
+			if (msg == null)
+				break;
+			PrintMessage (msg);
+			Console.WriteLine ();
+
+			/*
+			byte[] header = MessageDumper.ReadBlock (r);
+			if (header == null)
+				break;
+			PrintHeader (header);
+
+			byte[] body = MessageDumper.ReadBlock (r);
+			PrintBody (header);
+			*/
+		}
+	}
+
+	static void ReadOut ()
+	{
+		TextWriter w = Console.Out;
+
+		DumpConn (bus, w);
+
+		while (true) {
+			Message msg = bus.Transport.ReadMessage ();
+			if (msg == null)
+				break;
+			DumpMessage (msg, w);
+		}
+	}
+
+	static void PrettyPrintOut ()
+	{
+		while (true) {
+			Message msg = bus.Transport.ReadMessage ();
+			if (msg == null)
+				break;
+			PrintMessage (msg);
+			Console.WriteLine ();
+		}
+	}
+
+	static void DumpConn (Connection conn, TextWriter w)
+	{
+		w.WriteLine ("# This is a managed D-Bus protocol dump");
+		w.WriteLine ();
+		w.WriteLine ("# Machine: " + Connection.MachineId);
+		w.WriteLine ("# Connection: " + conn.Id);
+		w.WriteLine ("# Date: " + DateTime.Now.ToString ("F"));
+		w.WriteLine ();
+	}
+
+	static DateTime startTime = DateTime.Now;
+	static void DumpMessage (Message msg, TextWriter w)
+	{
+		w.WriteLine ("# Message: " + msg.Header.Serial);
+
+		TimeSpan delta = DateTime.Now - startTime;
+		startTime = DateTime.Now;
+		w.WriteLine ("# Time delta: " + delta.Ticks);
+
+		w.WriteLine ("# Header");
+		MessageDumper.WriteBlock (msg.GetHeaderData (), w);
+		w.WriteLine ("# Body");
+		MessageDumper.WriteBlock (msg.Body, w);
+
+		w.WriteLine ();
+		w.Flush ();
+	}
+
+	const string indent = "  ";
+
+	static void PrintMessage (Message msg)
+	{
+		Console.WriteLine ("Message (" + msg.Header.Endianness + " endian, v" + msg.Header.MajorVersion + "):");
+		Console.WriteLine (indent + "Type: " + msg.Header.MessageType);
+		Console.WriteLine (indent + "Flags: " + msg.Header.Flags);
+		Console.WriteLine (indent + "Serial: " + msg.Header.Serial);
+
+		//foreach (HeaderField hf in msg.HeaderFields)
+		//	Console.WriteLine (indent + hf.Code + ": " + hf.Value);
+		Console.WriteLine (indent + "Header Fields:");
+		foreach (KeyValuePair<byte,object> field in msg.Header.Fields)
+			Console.WriteLine (indent + indent + field.Key + ": " + field.Value);
+
+		Console.WriteLine (indent + "Body (" + msg.Header.Length + " bytes):");
+		if (msg.Body != null) {
+			MessageReader reader = new MessageReader (msg);
+
+			int argNum = 0;
+			foreach (Signature sig in msg.Signature.GetParts ()) {
+				//Console.Write (indent + indent + "arg" + argNum + " " + sig + ": ");
+				PrintValue (reader, sig, 1);
+				/*
+				if (sig.IsPrimitive) {
+					object arg = reader.ReadValue (sig[0]);
+					Console.WriteLine (arg);
+				} else {
+					if (sig.IsArray) {
+						//foreach (Signature elemSig in writer.StepInto (sig))
+					}
+					reader.StepOver (sig);
+					Console.WriteLine ("?");
+				}
+				*/
+				argNum++;
+			}
+		}
+	}
+
+	static void PrintValue (MessageReader reader, Signature sig, int depth)
+	{
+		string indent = new String (' ', depth * 2);
+		indent += "  ";
+
+		//Console.Write (indent + indent + "arg" + argNum + " " + sig + ": ");
+		Console.Write (indent);
+		if (sig == Signature.VariantSig) {
+			foreach (Signature elemSig in reader.StepInto (sig)) {
+				Console.WriteLine ("Variant '{0}' (", elemSig);
+				PrintValue (reader, elemSig, depth + 1);
+				Console.WriteLine (indent + ")");
+			}
+		} else if (sig.IsPrimitive) {
+			object arg = reader.ReadValue (sig[0]);
+			Type argType = sig.ToType ();
+			if (sig == Signature.StringSig || sig == Signature.ObjectPathSig)
+				Console.WriteLine ("{0} \"{1}\"", argType.Name, arg);
+			else if (sig == Signature.SignatureSig)
+				Console.WriteLine ("{0} '{1}'", argType.Name, arg);
+			else
+				Console.WriteLine ("{0} {1}", argType.Name, arg);
+		} else if (sig.IsArray) {
+			Console.WriteLine ("Array [");
+			foreach (Signature elemSig in reader.StepInto (sig))
+				PrintValue (reader, elemSig, depth + 1);
+			Console.WriteLine (indent + "]");
+		} else if (sig.IsDictEntry) {
+			Console.WriteLine ("DictEntry {");
+			foreach (Signature elemSig in reader.StepInto (sig))
+				PrintValue (reader, elemSig, depth + 1);
+			Console.WriteLine (indent + "}");
+		} else if (sig.IsStruct) {
+			Console.WriteLine ("Struct {");
+			foreach (Signature elemSig in reader.StepInto (sig))
+				PrintValue (reader, elemSig, depth + 1);
+			Console.WriteLine (indent + "}");
+		} else {
+			reader.StepOver (sig);
+			Console.WriteLine ("'{0}'?", sig);
+		}
+	}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-cli-libs/packages/dbus-sharp-legacy.git



More information about the Pkg-cli-libs-commits mailing list