Large refactoring
diff --git a/.clang-format b/.clang-format
index bbc1bb1..8872c3b 100644
--- a/.clang-format
+++ b/.clang-format
@@ -42,7 +42,7 @@
 ConstructorInitializerIndentWidth: 4
 ContinuationIndentWidth: 4
 Cpp11BracedListStyle: true
-DerivePointerAlignment: true
+DerivePointerAlignment: false
 PointerAlignment: Left
 DisableFormat:   false
 ExperimentalAutoDetectBinPacking: false
@@ -65,9 +65,9 @@
 PenaltyBreakString: 1000
 PenaltyExcessCharacter: 1000000
 PenaltyReturnTypeOnItsOwnLine: 60
-PointerAlignment: Right
 ReflowComments:  true
-SortIncludes:    false
+SortIncludes:    true
+SortUsingDeclarations: true
 SpaceAfterCStyleCast: false
 SpaceBeforeAssignmentOperators: true
 SpaceBeforeParens: ControlStatements
diff --git a/.gitignore b/.gitignore
index 99b73dc..c62c609 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,5 +44,5 @@
 /example/follow
 /test/event
 /test/exception
-/test/sdref
-/test/source
+/test/internal_sdref
+/test/source_base
diff --git a/src/Makefile.am b/src/Makefile.am
index f006891..2943a2c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,12 +10,13 @@
 nobase_include_HEADERS += sdeventplus/exception.hpp
 libsdeventplus_la_SOURCES += sdeventplus/exception.cpp
 
-nobase_include_HEADERS += sdeventplus/source.hpp
-libsdeventplus_la_SOURCES += sdeventplus/source.cpp
-
 nobase_include_HEADERS += sdeventplus/internal/sdevent.hpp
 libsdeventplus_la_SOURCES += sdeventplus/internal/sdevent.cpp
 
 nobase_include_HEADERS += sdeventplus/internal/sdref.hpp
+libsdeventplus_la_SOURCES += sdeventplus/internal/sdref.cpp
+
+nobase_include_HEADERS += sdeventplus/source/base.hpp
+libsdeventplus_la_SOURCES += sdeventplus/source/base.cpp
 
 nobase_include_HEADERS += sdeventplus/test/sdevent.hpp
diff --git a/src/sdeventplus/event.cpp b/src/sdeventplus/event.cpp
index b472602..897f549 100644
--- a/src/sdeventplus/event.cpp
+++ b/src/sdeventplus/event.cpp
@@ -1,49 +1,50 @@
 #include <functional>
 #include <sdeventplus/event.hpp>
 #include <sdeventplus/exception.hpp>
+#include <sdeventplus/internal/sdevent.hpp>
 #include <systemd/sd-event.h>
 
 namespace sdeventplus
 {
 
-Event::Event(sd_event* event, SdEventInterface* intf) :
-    intf(intf), event(event, &SdEventInterface::sd_event_ref,
-                      &SdEventInterface::sd_event_unref, intf)
+Event::Event(sd_event* event, internal::SdEvent* sdevent) :
+    sdevent(sdevent), event(event, &internal::SdEvent::sd_event_ref,
+                            &internal::SdEvent::sd_event_unref, sdevent)
 {
 }
 
-Event::Event(sd_event* event, std::false_type, SdEventInterface* intf) :
-    intf(intf),
-    event(event, &SdEventInterface::sd_event_ref,
-          &SdEventInterface::sd_event_unref, std::false_type(), intf)
+Event::Event(sd_event* event, std::false_type, internal::SdEvent* sdevent) :
+    sdevent(sdevent),
+    event(event, &internal::SdEvent::sd_event_ref,
+          &internal::SdEvent::sd_event_unref, std::false_type(), sdevent)
 {
 }
 
-Event Event::get_new(SdEventInterface* intf)
+Event Event::get_new(internal::SdEvent* sdevent)
 {
     sd_event* event = nullptr;
-    int r = intf->sd_event_new(&event);
+    int r = sdevent->sd_event_new(&event);
     if (r < 0)
     {
         throw SdEventError(-r, "sd_event_new");
     }
-    return Event(event, std::false_type(), intf);
+    return Event(event, std::false_type(), sdevent);
 }
 
-Event Event::get_default(SdEventInterface* intf)
+Event Event::get_default(internal::SdEvent* sdevent)
 {
     sd_event* event = nullptr;
-    int r = intf->sd_event_default(&event);
+    int r = sdevent->sd_event_default(&event);
     if (r < 0)
     {
         throw SdEventError(-r, "sd_event_default");
     }
-    return Event(event, std::false_type(), intf);
+    return Event(event, std::false_type(), sdevent);
 }
 
 int Event::loop()
 {
-    int r = intf->sd_event_loop(event.get());
+    int r = sdevent->sd_event_loop(event.get());
     if (r < 0)
     {
         throw SdEventError(-r, "sd_event_loop");
@@ -53,7 +54,7 @@
 
 int Event::get_watchdog()
 {
-    int r = intf->sd_event_get_watchdog(event.get());
+    int r = sdevent->sd_event_get_watchdog(event.get());
     if (r < 0)
     {
         throw SdEventError(-r, "sd_event_get_watchdog");
@@ -63,7 +64,7 @@
 
 int Event::set_watchdog(int b)
 {
-    int r = intf->sd_event_set_watchdog(event.get(), b);
+    int r = sdevent->sd_event_set_watchdog(event.get(), b);
     if (r < 0)
     {
         throw SdEventError(-r, "sd_event_set_watchdog");
diff --git a/src/sdeventplus/event.hpp b/src/sdeventplus/event.hpp
index 9206ee9..f55e9fa 100644
--- a/src/sdeventplus/event.hpp
+++ b/src/sdeventplus/event.hpp
@@ -10,19 +10,21 @@
 class Event
 {
   public:
-    Event(sd_event* event, SdEventInterface* intf = &sdevent_impl);
+    Event(sd_event* event,
+          internal::SdEvent* sdevent = &internal::sdevent_impl);
     Event(sd_event* event, std::false_type,
-          SdEventInterface* intf = &sdevent_impl);
-    static Event get_new(SdEventInterface* intf = &sdevent_impl);
-    static Event get_default(SdEventInterface* intf = &sdevent_impl);
+          internal::SdEvent* sdevent = &internal::sdevent_impl);
+    static Event get_new(internal::SdEvent* sdevent = &internal::sdevent_impl);
+    static Event
+        get_default(internal::SdEvent* sdevent = &internal::sdevent_impl);
 
     int loop();
     int get_watchdog();
     int set_watchdog(int b);
 
   private:
-    SdEventInterface* intf;
-    SdRef<sd_event> event;
+    internal::SdEvent* sdevent;
+    internal::SdRef<sd_event> event;
 };
 
 } // namespace sdeventplus
diff --git a/src/sdeventplus/exception.cpp b/src/sdeventplus/exception.cpp
index 1cfba4f..9e8b7de 100644
--- a/src/sdeventplus/exception.cpp
+++ b/src/sdeventplus/exception.cpp
@@ -4,7 +4,7 @@
 namespace sdeventplus
 {
 
-SdEventError::SdEventError(int r, const char *prefix) :
+SdEventError::SdEventError(int r, const char* prefix) :
     std::system_error(r, std::generic_category(), prefix)
 {
 }
diff --git a/src/sdeventplus/exception.hpp b/src/sdeventplus/exception.hpp
index eb88649..5412d70 100644
--- a/src/sdeventplus/exception.hpp
+++ b/src/sdeventplus/exception.hpp
@@ -8,7 +8,7 @@
 class SdEventError final : public std::system_error
 {
   public:
-    SdEventError(int r, const char *prefix);
+    SdEventError(int r, const char* prefix);
 };
 
 } // namespace sdeventplus
diff --git a/src/sdeventplus/internal/sdevent.cpp b/src/sdeventplus/internal/sdevent.cpp
index cf992ef..af729b2 100644
--- a/src/sdeventplus/internal/sdevent.cpp
+++ b/src/sdeventplus/internal/sdevent.cpp
@@ -2,5 +2,10 @@
 
 namespace sdeventplus
 {
+namespace internal
+{
+
 SdEventImpl sdevent_impl;
-}
+
+} // namespace internal
+} // namespace sdeventplus
diff --git a/src/sdeventplus/internal/sdevent.hpp b/src/sdeventplus/internal/sdevent.hpp
index 670d46a..7603a3d 100644
--- a/src/sdeventplus/internal/sdevent.hpp
+++ b/src/sdeventplus/internal/sdevent.hpp
@@ -4,71 +4,73 @@
 
 namespace sdeventplus
 {
+namespace internal
+{
 
-class SdEventInterface
+class SdEvent
 {
   public:
-    virtual ~SdEventInterface() = default;
+    virtual ~SdEvent() = default;
 
-    virtual int sd_event_default(sd_event **event) const = 0;
-    virtual int sd_event_new(sd_event **event) const = 0;
-    virtual sd_event *sd_event_ref(sd_event *event) const = 0;
-    virtual sd_event *sd_event_unref(sd_event *event) const = 0;
+    virtual int sd_event_default(sd_event** event) const = 0;
+    virtual int sd_event_new(sd_event** event) const = 0;
+    virtual sd_event* sd_event_ref(sd_event* event) const = 0;
+    virtual sd_event* sd_event_unref(sd_event* event) const = 0;
 
-    virtual int sd_event_loop(sd_event *event) const = 0;
-    virtual int sd_event_get_watchdog(sd_event *event) const = 0;
-    virtual int sd_event_set_watchdog(sd_event *event, int b) const = 0;
+    virtual int sd_event_loop(sd_event* event) const = 0;
+    virtual int sd_event_get_watchdog(sd_event* event) const = 0;
+    virtual int sd_event_set_watchdog(sd_event* event, int b) const = 0;
 
-    virtual sd_event_source *
-        sd_event_source_ref(sd_event_source *source) const = 0;
-    virtual sd_event_source *
-        sd_event_source_unref(sd_event_source *source) const = 0;
+    virtual sd_event_source*
+        sd_event_source_ref(sd_event_source* source) const = 0;
+    virtual sd_event_source*
+        sd_event_source_unref(sd_event_source* source) const = 0;
 };
 
-class SdEventImpl : public SdEventInterface
+class SdEventImpl : public SdEvent
 {
   public:
-    int sd_event_default(sd_event **event) const override
+    int sd_event_default(sd_event** event) const override
     {
         return ::sd_event_default(event);
     }
 
-    int sd_event_new(sd_event **event) const override
+    int sd_event_new(sd_event** event) const override
     {
         return ::sd_event_default(event);
     }
 
-    sd_event *sd_event_ref(sd_event *event) const override
+    sd_event* sd_event_ref(sd_event* event) const override
     {
         return ::sd_event_ref(event);
     }
 
-    sd_event *sd_event_unref(sd_event *event) const override
+    sd_event* sd_event_unref(sd_event* event) const override
     {
         return ::sd_event_unref(event);
     }
 
-    int sd_event_loop(sd_event *event) const override
+    int sd_event_loop(sd_event* event) const override
     {
         return ::sd_event_loop(event);
     }
 
-    int sd_event_get_watchdog(sd_event *event) const override
+    int sd_event_get_watchdog(sd_event* event) const override
     {
         return ::sd_event_get_watchdog(event);
     }
 
-    int sd_event_set_watchdog(sd_event *event, int b) const override
+    int sd_event_set_watchdog(sd_event* event, int b) const override
     {
         return ::sd_event_set_watchdog(event, b);
     }
 
-    sd_event_source *sd_event_source_ref(sd_event_source *source) const override
+    sd_event_source* sd_event_source_ref(sd_event_source* source) const override
     {
         return ::sd_event_source_ref(source);
     }
-    sd_event_source *
-        sd_event_source_unref(sd_event_source *source) const override
+    sd_event_source*
+        sd_event_source_unref(sd_event_source* source) const override
     {
         return ::sd_event_source_unref(source);
     }
@@ -76,4 +78,5 @@
 
 extern SdEventImpl sdevent_impl;
 
+} // namespace internal
 } // namespace sdeventplus
diff --git a/src/sdeventplus/internal/sdref.cpp b/src/sdeventplus/internal/sdref.cpp
new file mode 100644
index 0000000..44e38d6
--- /dev/null
+++ b/src/sdeventplus/internal/sdref.cpp
@@ -0,0 +1,79 @@
+#include <sdeventplus/internal/sdref.hpp>
+#include <type_traits>
+#include <utility>
+
+namespace sdeventplus
+{
+namespace internal
+{
+
+template <typename T>
+SdRef<T>::SdRef(T* ref, Func take_ref, Func release_ref, SdEvent* sdevent) :
+    SdRef(take_ref(sdevent, ref), take_ref, release_ref, std::false_type(),
+          sdevent)
+{
+}
+
+template <typename T>
+SdRef<T>::SdRef(T* ref, Func take_ref, Func release_ref, std::false_type,
+                SdEvent* sdevent) :
+    sdevent(sdevent),
+    take_ref(take_ref), release_ref(release_ref), ref(ref)
+{
+}
+
+template <typename T>
+SdRef<T>::SdRef(const SdRef& other) :
+    SdRef(other.ref, other.take_ref, other.release_ref, other.sdevent)
+{
+}
+
+template <typename T> SdRef<T>& SdRef<T>::operator=(const SdRef& other)
+{
+    if (this != &other)
+    {
+        // release_ref will be invalid if moved
+        if (release_ref)
+            release_ref(sdevent, ref);
+
+        sdevent = other.sdevent;
+        take_ref = other.take_ref;
+        release_ref = other.release_ref;
+        ref = take_ref(sdevent, other.ref);
+    }
+    return *this;
+}
+
+template <typename T> SdRef<T>& SdRef<T>::operator=(SdRef&& other)
+{
+    if (this != &other)
+    {
+        // release_ref will be invalid if move
+        if (release_ref)
+            release_ref(sdevent, ref);
+
+        sdevent = std::move(other.sdevent);
+        take_ref = std::move(other.take_ref);
+        release_ref = std::move(other.release_ref);
+        ref = std::move(other.ref);
+    }
+    return *this;
+}
+
+template <typename T> SdRef<T>::~SdRef()
+{
+    // release_ref will be invalid after a move
+    if (release_ref)
+        release_ref(sdevent, ref);
+}
+
+template <typename T> T* SdRef<T>::get() const
+{
+    return ref;
+}
+
+template class SdRef<sd_event>;
+template class SdRef<sd_event_source>;
+
+} // namespace internal
+} // namespace sdeventplus
diff --git a/src/sdeventplus/internal/sdref.hpp b/src/sdeventplus/internal/sdref.hpp
index b6e2ba2..bd220dd 100644
--- a/src/sdeventplus/internal/sdref.hpp
+++ b/src/sdeventplus/internal/sdref.hpp
@@ -1,89 +1,38 @@
 #pragma once
 
 #include <functional>
-#include <memory>
 #include <sdeventplus/internal/sdevent.hpp>
 #include <type_traits>
 
 namespace sdeventplus
 {
+namespace internal
+{
 
 template <typename T> class SdRef
 {
   public:
-    using Func = std::function<T*(SdEventInterface*, T*)>;
+    using Func = std::function<T*(SdEvent*, T*)>;
 
     SdRef(T* ref, Func take_ref, Func release_ref,
-          SdEventInterface* intf = sdevent_impl) :
-        SdRef(take_ref(intf, ref), take_ref, release_ref, std::false_type(),
-              intf)
-    {
-    }
-
+          SdEvent* sdevent = &sdevent_impl);
     SdRef(T* ref, Func take_ref, Func release_ref, std::false_type,
-          SdEventInterface* intf = sdevent_impl) :
-        intf(intf),
-        take_ref(take_ref), release_ref(release_ref), ref(ref)
-    {
-    }
+          SdEvent* sdevent = &sdevent_impl);
+    virtual ~SdRef();
 
-    SdRef(const SdRef& other) :
-        intf(other.intf), take_ref(other.take_ref),
-        release_ref(other.release_ref), ref(take_ref(intf, other.ref))
-    {
-    }
-
-    SdRef& operator=(const SdRef& other)
-    {
-        if (this != &other)
-        {
-            // release_ref will be invalid if moved
-            if (release_ref)
-                release_ref(intf, ref);
-
-            intf = other.intf;
-            take_ref = other.take_ref;
-            release_ref = other.release_ref;
-            ref = take_ref(intf, other.ref);
-        }
-        return *this;
-    }
-
+    SdRef(const SdRef& other);
+    SdRef& operator=(const SdRef& other);
     SdRef(SdRef&& other) = default;
+    SdRef& operator=(SdRef&& other);
 
-    SdRef& operator=(SdRef&& other)
-    {
-        if (this != &other)
-        {
-            // release_ref will be invalid if move
-            if (release_ref)
-                release_ref(intf, ref);
-
-            intf = std::move(other.intf);
-            take_ref = std::move(other.take_ref);
-            release_ref = std::move(other.release_ref);
-            ref = std::move(other.ref);
-        }
-        return *this;
-    }
-
-    virtual ~SdRef()
-    {
-        // release_ref will be invalid after a move
-        if (release_ref)
-            release_ref(intf, ref);
-    }
-
-    T* get() const
-    {
-        return ref;
-    }
+    T* get() const;
 
   private:
-    SdEventInterface* intf;
+    SdEvent* sdevent;
     Func take_ref;
     Func release_ref;
     T* ref;
 };
 
+} // namespace internal
 } // namespace sdeventplus
diff --git a/src/sdeventplus/source.cpp b/src/sdeventplus/source.cpp
deleted file mode 100644
index eb3c903..0000000
--- a/src/sdeventplus/source.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <sdeventplus/source.hpp>
-#include <type_traits>
-
-namespace sdeventplus
-{
-
-Source::Source(sd_event_source* source, SdEventInterface* intf) :
-    intf(intf), source(source, &SdEventInterface::sd_event_source_ref,
-                       &SdEventInterface::sd_event_source_unref, intf)
-{
-}
-
-Source::Source(sd_event_source* source, std::false_type,
-               SdEventInterface* intf) :
-    intf(intf),
-    source(source, &SdEventInterface::sd_event_source_ref,
-           &SdEventInterface::sd_event_source_unref, std::false_type(), intf)
-{
-}
-
-} // namespace sdeventplus
diff --git a/src/sdeventplus/source.hpp b/src/sdeventplus/source.hpp
deleted file mode 100644
index 9921a88..0000000
--- a/src/sdeventplus/source.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <sdeventplus/internal/sdevent.hpp>
-#include <sdeventplus/internal/sdref.hpp>
-#include <type_traits>
-
-namespace sdeventplus
-{
-
-class Source
-{
-  public:
-    Source(sd_event_source* source, SdEventInterface* intf = &sdevent_impl);
-    Source(sd_event_source* source, std::false_type,
-           SdEventInterface* intf = &sdevent_impl);
-
-  private:
-    SdEventInterface* intf;
-    SdRef<sd_event_source> source;
-};
-
-} // namespace sdeventplus
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
new file mode 100644
index 0000000..fd9b45f
--- /dev/null
+++ b/src/sdeventplus/source/base.cpp
@@ -0,0 +1,26 @@
+#include <sdeventplus/internal/sdevent.hpp>
+#include <sdeventplus/source/base.hpp>
+#include <type_traits>
+
+namespace sdeventplus
+{
+namespace source
+{
+
+Base::Base(sd_event_source* source, internal::SdEvent* sdevent) :
+    sdevent(sdevent), source(source, &internal::SdEvent::sd_event_source_ref,
+                             &internal::SdEvent::sd_event_source_unref, sdevent)
+{
+}
+
+Base::Base(sd_event_source* source, std::false_type,
+           internal::SdEvent* sdevent) :
+    sdevent(sdevent),
+    source(source, &internal::SdEvent::sd_event_source_ref,
+           &internal::SdEvent::sd_event_source_unref, std::false_type(),
+           sdevent)
+{
+}
+
+} // namespace source
+} // namespace sdeventplus
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
new file mode 100644
index 0000000..88a17f0
--- /dev/null
+++ b/src/sdeventplus/source/base.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <sdeventplus/internal/sdevent.hpp>
+#include <sdeventplus/internal/sdref.hpp>
+#include <systemd/sd-bus.h>
+#include <type_traits>
+
+namespace sdeventplus
+{
+namespace source
+{
+
+class Base
+{
+  public:
+    // We don't want to allow any kind of slicing.
+    Base(const Base& source) = delete;
+    Base& operator=(const Base& source) = delete;
+    Base(Base&& source) = delete;
+    Base& operator=(Base&& source) = delete;
+
+  protected:
+    internal::SdEvent* sdevent;
+    internal::SdRef<sd_event_source> source;
+
+    // Base sources cannot be directly constructed.
+    Base(sd_event_source* source,
+         internal::SdEvent* sdevent = &internal::sdevent_impl);
+    Base(sd_event_source* source, std::false_type,
+         internal::SdEvent* sdevent = &internal::sdevent_impl);
+};
+
+} // namespace source
+} // namespace sdeventplus
diff --git a/src/sdeventplus/test/sdevent.hpp b/src/sdeventplus/test/sdevent.hpp
index e85b13e..982e4e7 100644
--- a/src/sdeventplus/test/sdevent.hpp
+++ b/src/sdeventplus/test/sdevent.hpp
@@ -6,23 +6,25 @@
 
 namespace sdeventplus
 {
+namespace test
+{
 
-class SdEventMock : public SdEventInterface
+class SdEventMock : public internal::SdEvent
 {
   public:
-    MOCK_CONST_METHOD1(sd_event_default, int(sd_event **));
-    MOCK_CONST_METHOD1(sd_event_new, int(sd_event **));
-    MOCK_CONST_METHOD1(sd_event_ref, sd_event *(sd_event *));
-    MOCK_CONST_METHOD1(sd_event_unref, sd_event *(sd_event *));
+    MOCK_CONST_METHOD1(sd_event_default, int(sd_event**));
+    MOCK_CONST_METHOD1(sd_event_new, int(sd_event**));
+    MOCK_CONST_METHOD1(sd_event_ref, sd_event*(sd_event*));
+    MOCK_CONST_METHOD1(sd_event_unref, sd_event*(sd_event*));
 
-    MOCK_CONST_METHOD1(sd_event_loop, int(sd_event *));
-    MOCK_CONST_METHOD1(sd_event_get_watchdog, int(sd_event *));
-    MOCK_CONST_METHOD2(sd_event_set_watchdog, int(sd_event *, int b));
+    MOCK_CONST_METHOD1(sd_event_loop, int(sd_event*));
+    MOCK_CONST_METHOD1(sd_event_get_watchdog, int(sd_event*));
+    MOCK_CONST_METHOD2(sd_event_set_watchdog, int(sd_event*, int b));
 
-    MOCK_CONST_METHOD1(sd_event_source_ref,
-                       sd_event_source *(sd_event_source *));
+    MOCK_CONST_METHOD1(sd_event_source_ref, sd_event_source*(sd_event_source*));
     MOCK_CONST_METHOD1(sd_event_source_unref,
-                       sd_event_source *(sd_event_source *));
+                       sd_event_source*(sd_event_source*));
 };
 
+} // namespace test
 } // namespace sdeventplus
diff --git a/test/Makefile.am b/test/Makefile.am
index e899539..1b4ee1e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -17,12 +17,12 @@
 exception_CPPFLAGS = $(gtest_cppflags)
 exception_LDADD = $(gtest_ldadd)
 
-check_PROGRAMS += sdref
-sdref_SOURCES = sdref.cpp
-sdref_CPPFLAGS = $(gtest_cppflags)
-sdref_LDADD = $(gtest_ldadd)
+check_PROGRAMS += internal_sdref
+internal_sdref_SOURCES = internal/sdref.cpp
+internal_sdref_CPPFLAGS = $(gtest_cppflags)
+internal_sdref_LDADD = $(gtest_ldadd)
 
-check_PROGRAMS += source
-source_SOURCES = source.cpp
-source_CPPFLAGS = $(gtest_cppflags)
-source_LDADD = $(gtest_ldadd)
+check_PROGRAMS += source_base
+source_base_SOURCES = source/base.cpp
+source_base_CPPFLAGS = $(gtest_cppflags)
+source_base_LDADD = $(gtest_ldadd)
diff --git a/test/event.cpp b/test/event.cpp
index 1c30d20..6ec3770 100644
--- a/test/event.cpp
+++ b/test/event.cpp
@@ -18,8 +18,8 @@
 class EventTest : public testing::Test
 {
   protected:
-    testing::StrictMock<SdEventMock> mock;
-    sd_event *const expected_event = reinterpret_cast<sd_event *>(1234);
+    testing::StrictMock<test::SdEventMock> mock;
+    sd_event* const expected_event = reinterpret_cast<sd_event*>(1234);
 };
 
 TEST_F(EventTest, NewEventRef)
diff --git a/test/exception.cpp b/test/exception.cpp
index 050513c..2c437e4 100644
--- a/test/exception.cpp
+++ b/test/exception.cpp
@@ -11,7 +11,7 @@
 TEST(ExceptionTest, Construct)
 {
     const int code = EINTR;
-    const char *const prefix = "construct_test";
+    const char* const prefix = "construct_test";
 
     std::system_error expected(code, std::generic_category(), prefix);
     SdEventError err(code, prefix);
diff --git a/test/internal/sdref.cpp b/test/internal/sdref.cpp
new file mode 100644
index 0000000..190d388
--- /dev/null
+++ b/test/internal/sdref.cpp
@@ -0,0 +1,187 @@
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <sdeventplus/internal/sdref.hpp>
+#include <sdeventplus/test/sdevent.hpp>
+#include <systemd/sd-event.h>
+#include <type_traits>
+#include <utility>
+
+namespace sdeventplus
+{
+namespace internal
+{
+namespace
+{
+
+class SdRefTest : public testing::Test
+{
+  protected:
+    sd_event* const expected_event = reinterpret_cast<sd_event*>(1234);
+    sd_event* const expected_event2 = reinterpret_cast<sd_event*>(2345);
+    testing::StrictMock<test::SdEventMock> mock;
+    testing::StrictMock<test::SdEventMock> mock2;
+};
+
+TEST_F(SdRefTest, ConstructRef)
+{
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(testing::Return(expected_event));
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, &mock);
+    EXPECT_EQ(expected_event, event.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, ConstructNoRef)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, CopyConstruct)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(testing::Return(expected_event));
+    SdRef<sd_event> event2(event);
+    EXPECT_EQ(expected_event, event2.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .Times(2)
+        .WillRepeatedly(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, MoveConstruct)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+
+    SdRef<sd_event> event2(std::move(event));
+    EXPECT_EQ(expected_event, event2.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, CopyAssignOverValid)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+    SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
+                           &SdEvent::sd_event_unref, std::false_type(), &mock2);
+    EXPECT_EQ(expected_event2, event2.get());
+
+    EXPECT_CALL(mock2, sd_event_unref(expected_event2))
+        .WillOnce(testing::Return(nullptr));
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(testing::Return(expected_event));
+    event2 = event;
+    EXPECT_EQ(expected_event, event2.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .Times(2)
+        .WillRepeatedly(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, CopyAssignOverMoved)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+    SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
+                           &SdEvent::sd_event_unref, std::false_type(), &mock2);
+    EXPECT_EQ(expected_event2, event2.get());
+    {
+        SdRef<sd_event> event_mover(std::move(event2));
+        EXPECT_EQ(expected_event2, event_mover.get());
+
+        EXPECT_CALL(mock2, sd_event_unref(expected_event2))
+            .WillOnce(testing::Return(nullptr));
+    }
+
+    EXPECT_CALL(mock, sd_event_ref(expected_event))
+        .WillOnce(testing::Return(expected_event));
+    event2 = event;
+    EXPECT_EQ(expected_event, event2.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .Times(2)
+        .WillRepeatedly(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, CopySelf)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+
+    event = event;
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, MoveAssignOverValid)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+    SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
+                           &SdEvent::sd_event_unref, std::false_type(), &mock2);
+    EXPECT_EQ(expected_event2, event2.get());
+
+    EXPECT_CALL(mock2, sd_event_unref(expected_event2))
+        .WillOnce(testing::Return(nullptr));
+    event2 = std::move(event);
+    EXPECT_EQ(expected_event, event2.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, MoveAssignOverMoved)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+    SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
+                           &SdEvent::sd_event_unref, std::false_type(), &mock2);
+    EXPECT_EQ(expected_event2, event2.get());
+    {
+        SdRef<sd_event> event_mover(std::move(event2));
+        EXPECT_EQ(expected_event2, event_mover.get());
+
+        EXPECT_CALL(mock2, sd_event_unref(expected_event2))
+            .WillOnce(testing::Return(nullptr));
+    }
+
+    event2 = std::move(event);
+    EXPECT_EQ(expected_event, event2.get());
+
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+TEST_F(SdRefTest, MoveSelf)
+{
+    SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
+                          &SdEvent::sd_event_unref, std::false_type(), &mock);
+    EXPECT_EQ(expected_event, event.get());
+    event = std::move(event);
+    EXPECT_CALL(mock, sd_event_unref(expected_event))
+        .WillOnce(testing::Return(nullptr));
+}
+
+} // namespace
+} // namespace internal
+} // namespace sdeventplus
diff --git a/test/sdref.cpp b/test/sdref.cpp
deleted file mode 100644
index ab004f5..0000000
--- a/test/sdref.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <sdeventplus/internal/sdref.hpp>
-#include <sdeventplus/test/sdevent.hpp>
-#include <systemd/sd-event.h>
-#include <type_traits>
-#include <utility>
-
-namespace sdeventplus
-{
-namespace
-{
-
-class SdRefTest : public testing::Test
-{
-  protected:
-    sd_event *const expected_event = reinterpret_cast<sd_event *>(1234);
-    sd_event *const expected_event2 = reinterpret_cast<sd_event *>(2345);
-    testing::StrictMock<SdEventMock> mock;
-    testing::StrictMock<SdEventMock> mock2;
-};
-
-TEST_F(SdRefTest, ConstructRef)
-{
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(testing::Return(expected_event));
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, &mock);
-    EXPECT_EQ(expected_event, event.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, ConstructNoRef)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, CopyConstruct)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(testing::Return(expected_event));
-    SdRef<sd_event> event2(event);
-    EXPECT_EQ(expected_event, event2.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .Times(2)
-        .WillRepeatedly(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, MoveConstruct)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-
-    SdRef<sd_event> event2(std::move(event));
-    EXPECT_EQ(expected_event, event2.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, CopyAssignOverValid)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-    SdRef<sd_event> event2(expected_event2, &SdEventInterface::sd_event_ref,
-                           &SdEventInterface::sd_event_unref, std::false_type(),
-                           &mock2);
-    EXPECT_EQ(expected_event2, event2.get());
-
-    EXPECT_CALL(mock2, sd_event_unref(expected_event2))
-        .WillOnce(testing::Return(nullptr));
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(testing::Return(expected_event));
-    event2 = event;
-    EXPECT_EQ(expected_event, event2.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .Times(2)
-        .WillRepeatedly(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, CopyAssignOverMoved)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-    SdRef<sd_event> event2(expected_event2, &SdEventInterface::sd_event_ref,
-                           &SdEventInterface::sd_event_unref, std::false_type(),
-                           &mock2);
-    EXPECT_EQ(expected_event2, event2.get());
-    {
-        SdRef<sd_event> event_mover(std::move(event2));
-        EXPECT_EQ(expected_event2, event_mover.get());
-
-        EXPECT_CALL(mock2, sd_event_unref(expected_event2))
-            .WillOnce(testing::Return(nullptr));
-    }
-
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(testing::Return(expected_event));
-    event2 = event;
-    EXPECT_EQ(expected_event, event2.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .Times(2)
-        .WillRepeatedly(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, CopySelf)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-
-    event = event;
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, MoveAssignOverValid)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-    SdRef<sd_event> event2(expected_event2, &SdEventInterface::sd_event_ref,
-                           &SdEventInterface::sd_event_unref, std::false_type(),
-                           &mock2);
-    EXPECT_EQ(expected_event2, event2.get());
-
-    EXPECT_CALL(mock2, sd_event_unref(expected_event2))
-        .WillOnce(testing::Return(nullptr));
-    event2 = std::move(event);
-    EXPECT_EQ(expected_event, event2.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, MoveAssignOverMoved)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-    SdRef<sd_event> event2(expected_event2, &SdEventInterface::sd_event_ref,
-                           &SdEventInterface::sd_event_unref, std::false_type(),
-                           &mock2);
-    EXPECT_EQ(expected_event2, event2.get());
-    {
-        SdRef<sd_event> event_mover(std::move(event2));
-        EXPECT_EQ(expected_event2, event_mover.get());
-
-        EXPECT_CALL(mock2, sd_event_unref(expected_event2))
-            .WillOnce(testing::Return(nullptr));
-    }
-
-    event2 = std::move(event);
-    EXPECT_EQ(expected_event, event2.get());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-TEST_F(SdRefTest, MoveSelf)
-{
-    SdRef<sd_event> event(expected_event, &SdEventInterface::sd_event_ref,
-                          &SdEventInterface::sd_event_unref, std::false_type(),
-                          &mock);
-    EXPECT_EQ(expected_event, event.get());
-    event = std::move(event);
-    EXPECT_CALL(mock, sd_event_unref(expected_event))
-        .WillOnce(testing::Return(nullptr));
-}
-
-} // namespace
-} // namespace sdeventplus
diff --git a/test/source.cpp b/test/source.cpp
deleted file mode 100644
index 4fa87ab..0000000
--- a/test/source.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <sdeventplus/source.hpp>
-#include <sdeventplus/test/sdevent.hpp>
-
-namespace sdeventplus
-{
-namespace
-{
-
-using testing::Return;
-
-class SourceTest : public testing::Test
-{
-  protected:
-    testing::StrictMock<SdEventMock> mock;
-    sd_event_source *const expected_source =
-        reinterpret_cast<sd_event_source *>(1234);
-};
-
-TEST_F(SourceTest, NewSourceRef)
-{
-    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
-        .WillOnce(Return(expected_source));
-    Source source(expected_source, &mock);
-
-    EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-        .WillOnce(Return(nullptr));
-}
-
-TEST_F(SourceTest, NewSourceNoRef)
-{
-    Source source(expected_source, std::false_type(), &mock);
-
-    EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-        .WillOnce(Return(nullptr));
-}
-
-} // namespace
-} // namespace sdeventplus
diff --git a/test/source/base.cpp b/test/source/base.cpp
new file mode 100644
index 0000000..3bf76c0
--- /dev/null
+++ b/test/source/base.cpp
@@ -0,0 +1,59 @@
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <sdeventplus/internal/sdevent.hpp>
+#include <sdeventplus/source/base.hpp>
+#include <sdeventplus/test/sdevent.hpp>
+#include <type_traits>
+
+namespace sdeventplus
+{
+namespace source
+{
+namespace
+{
+
+using testing::Return;
+
+class BaseImpl : public Base
+{
+  public:
+    BaseImpl(sd_event_source* source, internal::SdEvent* sdevent) :
+        Base(source, sdevent)
+    {
+    }
+    BaseImpl(sd_event_source* source, std::false_type,
+             internal::SdEvent* sdevent) :
+        Base(source, std::false_type(), sdevent)
+    {
+    }
+};
+
+class BaseTest : public testing::Test
+{
+  protected:
+    testing::StrictMock<test::SdEventMock> mock;
+    sd_event_source* const expected_source =
+        reinterpret_cast<sd_event_source*>(1234);
+};
+
+TEST_F(BaseTest, NewBaseRef)
+{
+    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
+        .WillOnce(Return(expected_source));
+    BaseImpl source(expected_source, &mock);
+
+    EXPECT_CALL(mock, sd_event_source_unref(expected_source))
+        .WillOnce(Return(nullptr));
+}
+
+TEST_F(BaseTest, NewBaseNoRef)
+{
+    BaseImpl source(expected_source, std::false_type(), &mock);
+
+    EXPECT_CALL(mock, sd_event_source_unref(expected_source))
+        .WillOnce(Return(nullptr));
+}
+
+} // namespace
+} // namespace source
+} // namespace sdeventplus