Large refactoring
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