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();
+}