incremental
diff --git a/boost-dbus/test/avahi.cpp b/boost-dbus/test/avahi.cpp
new file mode 100644
index 0000000..debbff3
--- /dev/null
+++ b/boost-dbus/test/avahi.cpp
@@ -0,0 +1,176 @@
+// Copyright (c) Benjamin Kietzman (github.com/bkietz)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <dbus/connection.hpp>
+#include <dbus/endpoint.hpp>
+#include <dbus/filter.hpp>
+#include <dbus/match.hpp>
+#include <dbus/message.hpp>
+#include <dbus/utility.hpp>
+#include <functional>
+
+#include <unistd.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+TEST(AvahiTest, GetHostName) {
+  dbus::endpoint test_daemon("org.freedesktop.Avahi", "/",
+                             "org.freedesktop.Avahi.Server");
+  boost::asio::io_service io;
+  dbus::connection system_bus(io, dbus::bus::system);
+
+  dbus::message m = dbus::message::new_call(test_daemon, "GetHostName");
+
+  system_bus.async_send(
+      m, [&](const boost::system::error_code ec, dbus::message r) {
+
+        std::string avahi_hostname;
+        std::string hostname;
+
+        // get hostname from a system call
+        char c[1024];
+        gethostname(c, 1024);
+        hostname = c;
+
+        r.unpack(avahi_hostname);
+
+        // Get only the host name, not the fqdn
+        auto unix_hostname = hostname.substr(0, hostname.find("."));
+        EXPECT_EQ(unix_hostname, avahi_hostname);
+
+        io.stop();
+      });
+  boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
+  t.async_wait([&](const boost::system::error_code& /*e*/) {
+    io.stop();
+    FAIL() << "Callback was never called\n";
+  });
+  io.run();
+}
+
+TEST(AvahiTest, ServiceBrowser) {
+  boost::asio::io_service io;
+  dbus::connection system_bus(io, dbus::bus::system);
+
+  dbus::endpoint test_daemon("org.freedesktop.Avahi", "/",
+                             "org.freedesktop.Avahi.Server");
+  // create new service browser
+  dbus::message m1 = dbus::message::new_call(test_daemon, "ServiceBrowserNew");
+  m1.pack<int32_t>(-1)
+      .pack<int32_t>(-1)
+      .pack<std::string>("_http._tcp")
+      .pack<std::string>("local")
+      .pack<uint32_t>(0);
+
+  dbus::message r = system_bus.send(m1);
+  std::string browser_path;
+  r.unpack(browser_path);
+  testing::Test::RecordProperty("browserPath", browser_path);
+
+  dbus::match ma(system_bus, "type='signal',path='" + browser_path + "'");
+  dbus::filter f(system_bus, [](dbus::message& m) {
+    auto member = m.get_member();
+    return member == "NameAcquired";
+  });
+
+  std::function<void(boost::system::error_code, dbus::message)> event_handler =
+      [&](boost::system::error_code ec, dbus::message s) {
+        testing::Test::RecordProperty("firstSignal", s.get_member());
+        std::string a = s.get_member();
+        std::string dude;
+        s.unpack(dude);
+        f.async_dispatch(event_handler);
+        io.stop();
+      };
+  f.async_dispatch(event_handler);
+
+  boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
+  t.async_wait([&](const boost::system::error_code& /*e*/) {
+    io.stop();
+    FAIL() << "Callback was never called\n";
+  });
+  io.run();
+}
+
+TEST(BOOST_DBUS, ListServices) {
+  boost::asio::io_service io;
+  boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
+  t.async_wait([&](const boost::system::error_code& /*e*/) {
+    io.stop();
+    FAIL() << "Callback was never called\n";
+  });
+
+  dbus::connection system_bus(io, dbus::bus::system);
+
+  dbus::endpoint test_daemon("org.freedesktop.DBus", "/",
+                             "org.freedesktop.DBus");
+  // create new service browser
+  dbus::message m = dbus::message::new_call(test_daemon, "ListNames");
+  system_bus.async_send(
+      m, [&](const boost::system::error_code ec, dbus::message r) {
+        io.stop();
+        std::vector<std::string> services;
+        r.unpack(services);
+        // Test a couple things that should always be present.... adapt if
+        // neccesary
+        EXPECT_THAT(services, testing::Contains("org.freedesktop.DBus"));
+        EXPECT_THAT(services, testing::Contains("org.freedesktop.Accounts"));
+
+      });
+
+  io.run();
+}
+
+void query_interfaces(dbus::connection& system_bus, std::string& service_name,
+                      std::string& object_name) {
+  dbus::endpoint service_daemon(service_name, object_name,
+                                "org.freedestop.DBus.Introspectable");
+  dbus::message m = dbus::message::new_call(service_daemon, "Introspect");
+  try {
+    auto r = system_bus.send(m);
+    std::vector<std::string> names;
+    // Todo(ed) figure out why we're occassionally getting access
+    // denied errors
+    // EXPECT_EQ(ec, boost::system::errc::success);
+
+    std::string xml;
+    r.unpack(xml);
+    // TODO(ed) names needs lock for multithreaded access
+    dbus::read_dbus_xml_names(xml, names);
+    // loop over the newly added items
+    for (auto name : names) {
+      std::cout << name << "\n";
+      auto new_service_string = object_name + "/" + name;
+      query_interfaces(system_bus, service_name, new_service_string);
+    }
+  } catch (boost::system::error_code e) {
+    std::cout << e;
+  }
+}
+
+TEST(BOOST_DBUS, ListObjects) {
+  boost::asio::io_service io;
+  dbus::connection system_bus(io, dbus::bus::system);
+
+  dbus::endpoint test_daemon("org.freedesktop.DBus", "/",
+                             "org.freedesktop.DBus");
+
+  // create new service browser
+  dbus::message m = dbus::message::new_call(test_daemon, "ListNames");
+  auto r = system_bus.send(m);
+
+  std::vector<std::string> services;
+  r.unpack(services);
+  // todo(ed) find out why this needs to be static
+  static std::atomic<int> dbus_count(0);
+  std::cout << dbus_count << " Callers\n";
+  auto names = std::make_shared<std::vector<std::string>>();
+  for (auto& service : services) {
+    std::string name = "/";
+    query_interfaces(system_bus, service, name);
+  }
+
+  io.run();
+}
diff --git a/boost-dbus/test/avahi.py b/boost-dbus/test/avahi.py
new file mode 100644
index 0000000..1bcd24d
--- /dev/null
+++ b/boost-dbus/test/avahi.py
@@ -0,0 +1,42 @@
+# Copyright (c) Benjamin Kietzman (github.com/bkietz)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import unittest
+import dbus
+from dbus.mainloop.glib import DBusGMainLoop
+from gobject import MainLoop
+from socket import gethostname
+
+class AvahiTest(unittest.TestCase):
+
+  @classmethod
+  def setUpClass(c):
+    c.system_bus = dbus.SystemBus(mainloop=DBusGMainLoop())
+
+  def setUp(self):
+    None
+
+  def testAvahi(self):
+    # Connect to Avahi Daemon's interface:
+    avahi_remote = AvahiTest.system_bus.get_object('org.freedesktop.Avahi', '/')
+    avahi = dbus.Interface(avahi_remote, 'org.freedesktop.Avahi.Server')
+    self.assertEqual(gethostname(), avahi.GetHostName())
+
+    # Use the Avahi Daemon to produce a new 
+    # ServiceBrowser and connect to its interface:
+    browser_path = avahi.ServiceBrowserNew(-1, -1, "_http._tcp", "local", dbus.UInt32(0))
+    browser_remote = AvahiTest.system_bus.get_object('org.freedesktop.Avahi', browser_path)
+
+    browser = dbus.Interface(browser_remote, 'org.freedesktop.Avahi.ServiceBrowser')
+
+    # Connect to the ItemNew signal from the browser:
+    def new_item_handler(interface, protocol, instance_name, instance_type, domain, flags):
+      print "Found service '%s'" % instance_name
+
+    browser.connect_to_signal("ItemNew", new_item_handler)
+
+if __name__ == '__main__':
+  unittest.main()
+  MainLoop().run()
diff --git a/boost-dbus/test/export_sample.py b/boost-dbus/test/export_sample.py
new file mode 100644
index 0000000..be8a04b
--- /dev/null
+++ b/boost-dbus/test/export_sample.py
@@ -0,0 +1,39 @@
+# Copyright (c) Benjamin Kietzman (github.com/bkietz)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import dbus
+import dbus.service
+from dbus.mainloop.glib import DBusGMainLoop
+from gobject import MainLoop
+
+bus_name = 'com.example.Sample'
+
+class Example(dbus.service.Object):
+  def __init__(self, connection, path):
+    dbus.service.Object.__init__(self, connection, path)
+    self._last_input = None
+
+  @dbus.service.method(bus_name+'.Iface', in_signature='v', out_signature='s')
+  def StringifyVariant(self, var):
+    self.LastInputChanged(var)      # emits the signal
+    return str(var)
+
+  @dbus.service.signal(bus_name+'.Iface', signature='v')
+  def LastInputChanged(self, var):
+    # run just before the signal is actually emitted
+    # just put "pass" if nothing should happen
+    self._last_input = var
+
+  @dbus.service.method(bus_name+'.Iface', in_signature='', out_signature='v')
+  def GetLastInput(self):
+    return self._last_input
+
+bus = dbus.SessionBus(mainloop=DBusGMainLoop())
+bus.request_name(bus_name)
+
+example = Example(bus, '/path/to/obj')
+
+print bus.get_name_owner(bus_name)
+MainLoop().run()
diff --git a/boost-dbus/test/message.cpp b/boost-dbus/test/message.cpp
new file mode 100644
index 0000000..d591f61
--- /dev/null
+++ b/boost-dbus/test/message.cpp
@@ -0,0 +1,62 @@
+// Copyright (c) Benjamin Kietzman (github.com/bkietz)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <dbus/error.hpp>
+#include <dbus/connection.hpp>
+#include <dbus/endpoint.hpp>
+#include <dbus/filter.hpp>
+#include <dbus/match.hpp>
+#include <dbus/message.hpp>
+#include <gtest/gtest.h>
+
+TEST(MessageTest, CallMessage) {
+  const dbus::message m =
+      dbus::message::new_call(dbus::endpoint("org.freedesktop.Avahi", "/",
+                                             "org.freedesktop.Avahi.Server"),
+                              "GetHostName");
+
+  ASSERT_EQ("org.freedesktop.Avahi", m.get_destination());
+  ASSERT_EQ("/", m.get_path());
+  ASSERT_EQ("org.freedesktop.Avahi.Server", m.get_interface());
+  ASSERT_EQ("GetHostName", m.get_member());
+
+  dbus::message m2 =
+      dbus::message::new_call(dbus::endpoint("org.freedesktop.Avahi", "/",
+                                             "org.freedesktop.Avahi.Server"),
+                              "GetHostName");
+
+  m2 << 1;
+  int i;
+  m2 >> i;
+  ASSERT_EQ(i, 1);
+
+  // m.get_sender();
+}
+
+// I actually don't know what to do with these yet.
+/*
+TEST(MessageTest, ErrorMessage)
+{
+
+  dbus::message m = dbus::message::new_call(
+    dbus::endpoint(
+      "org.freedesktop.Avahi",
+      "/",
+      "org.freedesktop.Avahi.Server"),
+    "GetHostName");
+
+  m.set_reply_serial(42);
+  m.set_serial(43);
+
+  dbus::message em = dbus::message::new_error(
+    m,
+    "com.skizizo.NoHostname",
+    "No hostname for you!");
+
+  const error e(em);
+
+  e.throw_if_set();
+}
+*/
diff --git a/boost-dbus/test/proxy_sample.py b/boost-dbus/test/proxy_sample.py
new file mode 100644
index 0000000..a467410
--- /dev/null
+++ b/boost-dbus/test/proxy_sample.py
@@ -0,0 +1,19 @@
+# Copyright (c) Benjamin Kietzman (github.com/bkietz)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import dbus
+from dbus.mainloop.glib import DBusGMainLoop
+from gobject import MainLoop
+
+bus_name = 'com.example.Sample'
+session_bus = dbus.SessionBus(mainloop=DBusGMainLoop())
+
+example_remote = session_bus.get_object(bus_name, '/path/to/obj')
+example = dbus.Interface(example_remote, bus_name+'.Iface')
+
+example.StringifyVariant(123)
+print example.GetLastInput()
+
+MainLoop().run()