incremental
diff --git a/boost-dbus/include/dbus/impl/connection.ipp b/boost-dbus/include/dbus/impl/connection.ipp
new file mode 100644
index 0000000..24a257d
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/connection.ipp
@@ -0,0 +1,102 @@
+// 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)
+
+#ifndef DBUS_CONNECTION_IPP
+#define DBUS_CONNECTION_IPP
+
+#include <dbus/dbus.h>
+#include <dbus/detail/watch_timeout.hpp>
+
+#include <boost/atomic.hpp>
+
+namespace dbus {
+namespace impl {
+
+class connection {
+ public:
+  boost::atomic<bool> is_paused;
+  DBusConnection* conn;
+
+  connection() : is_paused(true), conn(NULL) {}
+
+  void open(boost::asio::io_service& io, int bus) {
+    error e;
+    conn = dbus_bus_get_private((DBusBusType)bus, e);
+    e.throw_if_set();
+
+    dbus_connection_set_exit_on_disconnect(conn, false);
+
+    detail::set_watch_timeout_dispatch_functions(conn, io);
+  }
+
+  void open(boost::asio::io_service& io, const string& address) {
+    error e;
+    conn = dbus_connection_open_private(address.c_str(), e);
+    e.throw_if_set();
+
+    dbus_bus_register(conn, e);
+    e.throw_if_set();
+
+    dbus_connection_set_exit_on_disconnect(conn, false);
+
+    detail::set_watch_timeout_dispatch_functions(conn, io);
+  }
+
+  ~connection() {
+    if (conn != NULL) {
+      dbus_connection_close(conn);
+      dbus_connection_unref(conn);
+    }
+  }
+
+  operator DBusConnection*() { return conn; }
+  operator const DBusConnection*() const { return conn; }
+
+  message send_with_reply_and_block(message& m,
+                                    int timeout_in_milliseconds = -1) {
+    error e;
+    DBusMessage* out = dbus_connection_send_with_reply_and_block(
+        conn, m, timeout_in_milliseconds, e);
+    e.throw_if_set();
+    message reply(out);
+
+    return reply;
+  }
+
+  void send(message& m) {
+    // ignoring message serial for now
+    dbus_connection_send(conn, m, NULL);
+  }
+
+  void send_with_reply(message& m, DBusPendingCall** p,
+                       int timeout_in_milliseconds = -1) {
+    dbus_connection_send_with_reply(conn, m, p, timeout_in_milliseconds);
+  }
+
+  // begin asynchronous operation
+  // FIXME should not get io from an argument
+  void start(boost::asio::io_service& io) {
+    bool old_value(true);
+    if (is_paused.compare_exchange_strong(old_value, false)) {
+      // If two threads call connection::async_send()
+      // simultaneously on a paused connection, then
+      // only one will pass the CAS instruction and
+      // only one dispatch_handler will be injected.
+      io.post(detail::dispatch_handler(io, conn));
+    }
+  }
+
+  void cancel(boost::asio::io_service& io) {
+    bool old_value(false);
+    if (is_paused.compare_exchange_strong(old_value, true)) {
+      // TODO
+    }
+  }
+};
+
+}  // namespace impl
+}  // namespace dbus
+
+#endif  // DBUS_CONNECTION_IPP
diff --git a/boost-dbus/include/dbus/impl/filter.ipp b/boost-dbus/include/dbus/impl/filter.ipp
new file mode 100644
index 0000000..a64d6fd
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/filter.ipp
@@ -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)
+
+#ifndef DBUS_FILTER_IPP
+#define DBUS_FILTER_IPP
+
+namespace dbus {
+namespace impl {
+
+inline DBusHandlerResult filter_callback(DBusConnection* c, DBusMessage* m,
+                                  void* userdata) {
+  try {
+    filter& f = *static_cast<filter*>(userdata);
+    message m_(m);
+    if (f.offer(m_)) {
+      return DBUS_HANDLER_RESULT_HANDLED;
+    }
+  } catch (...) {
+    // do not throw in C callbacks. Just don't.
+  }
+
+  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+}  // namespace impl
+
+void connection_service::new_filter(implementation_type& impl, filter& f) {
+  dbus_connection_add_filter(impl, &impl::filter_callback, &f, NULL);
+}
+
+void connection_service::delete_filter(implementation_type& impl, filter& f) {
+  dbus_connection_remove_filter(impl, &impl::filter_callback, &f);
+}
+
+}  // namespace dbus
+
+#endif  // DBUS_FILTER_IPP
diff --git a/boost-dbus/include/dbus/impl/match.ipp b/boost-dbus/include/dbus/impl/match.ipp
new file mode 100644
index 0000000..9f6a5da
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/match.ipp
@@ -0,0 +1,26 @@
+// 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)
+
+#ifndef DBUS_MATCH_IPP
+#define DBUS_MATCH_IPP
+
+namespace dbus {
+void connection_service::new_match(implementation_type& impl, match& m) {
+  error e;
+  dbus_bus_add_match(impl, m.get_expression().c_str(), e);
+  e.throw_if_set();
+  // eventually, for complete asynchronicity, this should connect to
+  // org.freedesktop.DBus and call AddMatch
+}
+
+void connection_service::delete_match(implementation_type& impl, match& m) {
+  error e;
+  dbus_bus_remove_match(impl, m.get_expression().c_str(), e);
+  e.throw_if_set();
+}
+
+}  // namespace dbus
+
+#endif  // DBUS_MATCH_IPP
diff --git a/boost-dbus/include/dbus/impl/message_iterator.hpp b/boost-dbus/include/dbus/impl/message_iterator.hpp
new file mode 100644
index 0000000..44bcf2e
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/message_iterator.hpp
@@ -0,0 +1,50 @@
+// 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)
+
+#ifndef DBUS_IMPL_MESSAGE_ITERATOR_HPP
+#define DBUS_IMPL_MESSAGE_ITERATOR_HPP
+
+#include <dbus/dbus.h>
+
+namespace dbus {
+
+class message;
+
+namespace impl {
+
+class message_iterator {
+  DBusMessageIter DBusMessageIter_;
+
+ public:
+  // writing
+  static void init_append(message &m, message_iterator &i);
+
+  void append_basic(int code, const void *value);
+
+  void open_container(int code, const char *signature, message_iterator &);
+  void close_container(message_iterator &);
+  void abandon_container(message_iterator &);
+
+  void append_fixed_array(int code, const void *value, int n_elements);
+
+  // reading
+  static bool init(message &m, message_iterator &i);
+
+  bool next();
+  bool has_next();
+  int get_arg_type();
+
+  void get_basic(void *value);
+
+  void recurse(message_iterator &);
+
+  int get_element_type();
+  void get_fixed_array(void *value, int *n_elements);
+};
+
+}  // namespace impl
+}  // namespace dbus
+
+#endif  // DBUS_IMPL_MESSAGE_ITERATOR_HPP
diff --git a/boost-dbus/include/dbus/impl/message_iterator.ipp b/boost-dbus/include/dbus/impl/message_iterator.ipp
new file mode 100644
index 0000000..eb2584f
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/message_iterator.ipp
@@ -0,0 +1,89 @@
+// 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)
+
+#ifndef DBUS_IMPL_MESSAGE_ITERATOR_IPP
+#define DBUS_IMPL_MESSAGE_ITERATOR_IPP
+
+#include <dbus/impl/message_iterator.hpp>
+
+namespace dbus {
+namespace impl {
+
+inline void message_iterator::init_append(message& m, message_iterator& i)
+{
+  dbus_message_iter_init_append(m, &i.DBusMessageIter_);
+}
+inline void message_iterator::append_basic(int code, const void *value)
+{
+  // returns false if not enough memory- throw bad_alloc
+  dbus_message_iter_append_basic(&DBusMessageIter_, code, value);
+}
+inline void message_iterator::open_container(int code, const char *signature, message_iterator& sub)
+{
+  // returns false if not enough memory- throw bad_alloc
+  dbus_message_iter_open_container(&DBusMessageIter_, code, signature, &sub.DBusMessageIter_);
+}
+
+inline void message_iterator::close_container(message_iterator& sub)
+{
+  // returns false if not enough memory- throw bad_alloc
+  dbus_message_iter_close_container(&DBusMessageIter_, &sub.DBusMessageIter_);
+}
+
+inline void message_iterator::abandon_container(message_iterator& sub)
+{
+  dbus_message_iter_abandon_container(&DBusMessageIter_, &sub.DBusMessageIter_);
+}
+
+inline void message_iterator::append_fixed_array(int code, const void *value, int n_elements)
+{
+  // returns false if not enough memory- throw bad_alloc
+  dbus_message_iter_append_fixed_array(&DBusMessageIter_, code, value, n_elements);
+}
+
+inline bool message_iterator::init(message& m, message_iterator& i)
+{
+  return dbus_message_iter_init(m, &i.DBusMessageIter_);
+}
+
+inline bool message_iterator::next()
+{
+  return dbus_message_iter_next(&DBusMessageIter_);
+}
+
+inline bool message_iterator::has_next()
+{
+  return dbus_message_iter_has_next(&DBusMessageIter_);
+}
+
+inline int message_iterator::get_arg_type()
+{
+  return dbus_message_iter_get_arg_type(&DBusMessageIter_);
+}
+
+inline void message_iterator::get_basic(void *value)
+{
+  dbus_message_iter_get_basic(&DBusMessageIter_, value);
+}
+
+inline void message_iterator::recurse(message_iterator& sub)
+{
+  dbus_message_iter_recurse(&DBusMessageIter_, &sub.DBusMessageIter_);
+}
+
+inline int message_iterator::get_element_type()
+{
+  return dbus_message_iter_get_element_type(&DBusMessageIter_);
+}
+
+inline void message_iterator::get_fixed_array(void *value, int *n_elements)
+{
+  dbus_message_iter_get_fixed_array(&DBusMessageIter_, value, n_elements);
+}
+
+} // namespace impl
+} // namespace dbus
+
+#endif // DBUS_IMPL_MESSAGE_ITERATOR_IPP