You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rm...@apache.org on 2021/11/06 00:43:07 UTC

[logging-log4cxx] 02/20: Converted part of the hierarchy to be ABI stable

This is an automated email from the ASF dual-hosted git repository.

rmiddleton pushed a commit to branch LOGCXX-510
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit ca2ba838ab2700a8ac8b23b7b78228fd783b4e36
Author: Robert Middleton <ro...@rm5248.com>
AuthorDate: Sat Sep 25 09:48:53 2021 -0400

    Converted part of the hierarchy to be ABI stable
---
 src/main/cpp/CMakeLists.txt                        |   2 -
 src/main/cpp/action.cpp                            |  38 +++-
 src/main/cpp/andfilter.cpp                         |  25 ++-
 src/main/cpp/appenderattachableimpl.cpp            |  66 +++---
 src/main/cpp/appenderskeleton.cpp                  | 100 +++++----
 src/main/cpp/asyncappender.cpp                     | 249 +++++++++++++++------
 src/main/cpp/class.cpp                             |   5 -
 src/main/cpp/consoleappender.cpp                   |  32 ++-
 src/main/cpp/fileappender.cpp                      | 135 ++++++-----
 src/main/cpp/odbcappender.cpp                      | 118 +++++++---
 src/main/cpp/rollingfileappender.cpp               | 140 +++++++-----
 src/main/cpp/smtpappender.cpp                      | 135 ++++++-----
 src/main/cpp/socketappender.cpp                    |  80 +++----
 src/main/cpp/socketappenderskeleton.cpp            | 169 ++++++++++----
 src/main/cpp/sockethubappender.cpp                 |  83 +++++--
 src/main/cpp/syslogappender.cpp                    | 132 +++++------
 src/main/cpp/telnetappender.cpp                    | 112 +++++----
 src/main/cpp/writerappender.cpp                    |  96 ++++----
 src/main/cpp/xmlsocketappender.cpp                 |  35 +--
 src/main/include/log4cxx/appender.h                |   6 +-
 src/main/include/log4cxx/appenderskeleton.h        |  86 ++-----
 src/main/include/log4cxx/asyncappender.h           | 101 ---------
 src/main/include/log4cxx/consoleappender.h         |   3 -
 src/main/include/log4cxx/db/odbcappender.h         | 109 ++-------
 src/main/include/log4cxx/fileappender.h            |  52 +----
 src/main/include/log4cxx/filter/andfilter.h        |   9 +-
 .../log4cxx/helpers/appenderattachableimpl.h       |  14 +-
 src/main/include/log4cxx/net/smtpappender.h        |  22 +-
 src/main/include/log4cxx/net/socketappender.h      |   3 -
 .../include/log4cxx/net/socketappenderskeleton.h   |  59 +----
 src/main/include/log4cxx/net/sockethubappender.h   |  25 +--
 src/main/include/log4cxx/net/syslogappender.h      |  37 +--
 src/main/include/log4cxx/net/telnetappender.h      |  17 +-
 src/main/include/log4cxx/net/xmlsocketappender.h   |   1 -
 .../log4cxx/private/appenderskeleton_priv.h        |  75 +++++++
 .../include/log4cxx/private/fileappender_priv.h    |  56 +++++
 .../log4cxx/private/nteventlogappender_priv.h      |   0
 .../include/log4cxx/private/odbcappender_priv.h    |  82 +++++++
 .../include/log4cxx/private/syslogappender_priv.h  |  91 ++++++++
 .../include/log4cxx/private/writerappender_priv.h  |  77 +++++++
 src/main/include/log4cxx/rolling/action.h          |  16 +-
 .../include/log4cxx/rolling/rollingfileappender.h  | 102 ++++++++-
 .../log4cxx/rolling/rollingfileappenderskeleton.h  |   1 -
 src/main/include/log4cxx/rolling/rollingpolicy.h   |   1 -
 .../include/log4cxx/rolling/rolloverdescription.h  |   1 -
 .../log4cxx/rolling/timebasedrollingpolicy.h       |   1 -
 src/main/include/log4cxx/writerappender.h          |  39 +---
 src/test/cpp/vectorappender.cpp                    |   4 +-
 src/test/cpp/vectorappender.h                      |   3 +-
 49 files changed, 1675 insertions(+), 1170 deletions(-)

diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index 0f8f40d..c83217b 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -33,7 +33,6 @@ target_sources(log4cxx
   configurator.cpp
   consoleappender.cpp
   cyclicbuffer.cpp
-  dailyrollingfileappender.cpp
   datagrampacket.cpp
   datagramsocket.cpp
   date.cpp
@@ -99,7 +98,6 @@ target_sources(log4cxx
   ndcpatternconverter.cpp
   nteventlogappender.cpp
   objectoutputstream.cpp
-  obsoleterollingfileappender.cpp
   odbcappender.cpp
   onlyonceerrorhandler.cpp
   optionconverter.cpp
diff --git a/src/main/cpp/action.cpp b/src/main/cpp/action.cpp
index fdc5285..1e6b8b9 100644
--- a/src/main/cpp/action.cpp
+++ b/src/main/cpp/action.cpp
@@ -24,10 +24,28 @@ using namespace log4cxx::helpers;
 
 IMPLEMENT_LOG4CXX_OBJECT(Action)
 
+struct Action::priv_data{
+	priv_data() :
+		complete(false),
+		interrupted(false),
+		pool(){}
+
+	/**
+	 * Is action complete.
+	 */
+	bool complete;
+
+	/**
+	 * Is action interrupted.
+	 */
+	bool interrupted;
+
+	log4cxx::helpers::Pool pool;
+	std::mutex mutex;
+};
+
 Action::Action() :
-	complete(false),
-	interrupted(false),
-	pool()
+	m_priv( std::make_unique<Action::priv_data>() )
 {
 }
 
@@ -40,9 +58,9 @@ Action::~Action()
  */
 void Action::run(log4cxx::helpers::Pool& pool1)
 {
-	std::unique_lock<std::mutex> lock(mutex);
+	std::unique_lock<std::mutex> lock(m_priv->mutex);
 
-	if (!interrupted)
+	if (!m_priv->interrupted)
 	{
 		try
 		{
@@ -53,8 +71,8 @@ void Action::run(log4cxx::helpers::Pool& pool1)
 			reportException(ex);
 		}
 
-		complete = true;
-		interrupted = true;
+		m_priv->complete = true;
+		m_priv->interrupted = true;
 	}
 }
 
@@ -63,8 +81,8 @@ void Action::run(log4cxx::helpers::Pool& pool1)
  */
 void Action::close()
 {
-	std::unique_lock<std::mutex> lock(mutex);
-	interrupted = true;
+	std::unique_lock<std::mutex> lock(m_priv->mutex);
+	m_priv->interrupted = true;
 }
 
 /**
@@ -73,7 +91,7 @@ void Action::close()
  */
 bool Action::isComplete() const
 {
-	return complete;
+	return m_priv->complete;
 }
 
 /**
diff --git a/src/main/cpp/andfilter.cpp b/src/main/cpp/andfilter.cpp
index 0bf16cd..d5a24b0 100644
--- a/src/main/cpp/andfilter.cpp
+++ b/src/main/cpp/andfilter.cpp
@@ -27,36 +27,45 @@ using namespace log4cxx::helpers;
 
 IMPLEMENT_LOG4CXX_OBJECT(AndFilter)
 
+struct AndFilter::priv_data{
+	priv_data() : headFilter(), tailFilter(), acceptOnMatch(true){}
+
+	log4cxx::spi::FilterPtr headFilter;
+	log4cxx::spi::FilterPtr tailFilter;
+	bool acceptOnMatch;
+};
 
 AndFilter::AndFilter()
-	: headFilter(), tailFilter(), acceptOnMatch(true)
+	: m_priv( std::make_unique<priv_data>() )
 {
 }
 
+AndFilter::~AndFilter(){}
+
 void AndFilter::addFilter(const FilterPtr& filter)
 {
-	if (headFilter == NULL)
+	if (m_priv->headFilter == NULL)
 	{
-		headFilter = filter;
-		tailFilter = filter;
+		m_priv->headFilter = filter;
+		m_priv->tailFilter = filter;
 	}
 	else
 	{
-		tailFilter->setNext(filter);
+		m_priv->tailFilter->setNext(filter);
 	}
 }
 
 
 void AndFilter::setAcceptOnMatch(bool newValue)
 {
-	acceptOnMatch = newValue;
+	m_priv->acceptOnMatch = newValue;
 }
 
 Filter::FilterDecision AndFilter::decide(
 	const spi::LoggingEventPtr& event) const
 {
 	bool accepted = true;
-	FilterPtr f(headFilter);
+	FilterPtr f(m_priv->headFilter);
 
 	while (f != NULL)
 	{
@@ -66,7 +75,7 @@ Filter::FilterDecision AndFilter::decide(
 
 	if (accepted)
 	{
-		if (acceptOnMatch)
+		if (m_priv->acceptOnMatch)
 		{
 			return Filter::ACCEPT;
 		}
diff --git a/src/main/cpp/appenderattachableimpl.cpp b/src/main/cpp/appenderattachableimpl.cpp
index 4277a2b..734d9a3 100644
--- a/src/main/cpp/appenderattachableimpl.cpp
+++ b/src/main/cpp/appenderattachableimpl.cpp
@@ -28,12 +28,21 @@ using namespace log4cxx::spi;
 
 IMPLEMENT_LOG4CXX_OBJECT(AppenderAttachableImpl)
 
+struct AppenderAttachableImpl::priv_data{
+	/** Array of appenders. */
+	AppenderList  appenderList;
+	mutable std::mutex m_mutex;
+};
 
-AppenderAttachableImpl::AppenderAttachableImpl(Pool& pool)
-	: appenderList()
+
+AppenderAttachableImpl::AppenderAttachableImpl(Pool& pool) :
+	m_priv(std::make_unique<AppenderAttachableImpl::priv_data>())
 {
 }
 
+AppenderAttachableImpl::~AppenderAttachableImpl(){
+
+}
 
 void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
 {
@@ -43,13 +52,13 @@ void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
 		return;
 	}
 
-	std::unique_lock<std::mutex> lock( m_mutex );
+	std::unique_lock<std::mutex> lock( m_priv->m_mutex );
 	AppenderList::iterator it = std::find(
-			appenderList.begin(), appenderList.end(), newAppender);
+			m_priv->appenderList.begin(), m_priv->appenderList.end(), newAppender);
 
-	if (it == appenderList.end())
+	if (it == m_priv->appenderList.end())
 	{
-		appenderList.push_back(newAppender);
+		m_priv->appenderList.push_back(newAppender);
 	}
 }
 
@@ -66,8 +75,8 @@ int AppenderAttachableImpl::appendLoopOnAppenders(
 		// appenders fails, we may want to swap it out for a new one.
 		// So, make a local copy of the appenders that we want to iterate over
 		// before actually iterating over them.
-		std::unique_lock<std::mutex> lock( m_mutex );
-		allAppenders = appenderList;
+		std::unique_lock<std::mutex> lock( m_priv->m_mutex );
+		allAppenders = m_priv->appenderList;
 	}
 	for (AppenderList::iterator it = allAppenders.begin();
 		it != allAppenders.end();
@@ -82,7 +91,7 @@ int AppenderAttachableImpl::appendLoopOnAppenders(
 
 AppenderList AppenderAttachableImpl::getAllAppenders() const
 {
-	return appenderList;
+	return m_priv->appenderList;
 }
 
 AppenderPtr AppenderAttachableImpl::getAppender(const LogString& name) const
@@ -92,11 +101,11 @@ AppenderPtr AppenderAttachableImpl::getAppender(const LogString& name) const
 		return 0;
 	}
 
-	std::unique_lock<std::mutex> lock( m_mutex );
-	AppenderList::const_iterator it, itEnd = appenderList.end();
+	std::unique_lock<std::mutex> lock( m_priv->m_mutex );
+	AppenderList::const_iterator it, itEnd = m_priv->appenderList.end();
 	AppenderPtr appender;
 
-	for (it = appenderList.begin(); it != itEnd; it++)
+	for (it = m_priv->appenderList.begin(); it != itEnd; it++)
 	{
 		appender = *it;
 
@@ -116,26 +125,26 @@ bool AppenderAttachableImpl::isAttached(const AppenderPtr appender) const
 		return false;
 	}
 
-	std::unique_lock<std::mutex> lock( m_mutex );
+	std::unique_lock<std::mutex> lock( m_priv->m_mutex );
 	AppenderList::const_iterator it = std::find(
-			appenderList.begin(), appenderList.end(), appender);
+			m_priv->appenderList.begin(), m_priv->appenderList.end(), appender);
 
-	return it != appenderList.end();
+	return it != m_priv->appenderList.end();
 }
 
 void AppenderAttachableImpl::removeAllAppenders()
 {
-	std::unique_lock<std::mutex> lock( m_mutex );
-	AppenderList::iterator it, itEnd = appenderList.end();
+	std::unique_lock<std::mutex> lock( m_priv->m_mutex );
+	AppenderList::iterator it, itEnd = m_priv->appenderList.end();
 	AppenderPtr a;
 
-	for (it = appenderList.begin(); it != itEnd; it++)
+	for (it = m_priv->appenderList.begin(); it != itEnd; it++)
 	{
 		a = *it;
 		a->close();
 	}
 
-	appenderList.clear();
+	m_priv->appenderList.clear();
 }
 
 void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
@@ -145,13 +154,13 @@ void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
 		return;
 	}
 
-	std::unique_lock<std::mutex> lock( m_mutex );
+	std::unique_lock<std::mutex> lock( m_priv->m_mutex );
 	AppenderList::iterator it = std::find(
-			appenderList.begin(), appenderList.end(), appender);
+			m_priv->appenderList.begin(), m_priv->appenderList.end(), appender);
 
-	if (it != appenderList.end())
+	if (it != m_priv->appenderList.end())
 	{
-		appenderList.erase(it);
+		m_priv->appenderList.erase(it);
 	}
 }
 
@@ -162,20 +171,23 @@ void AppenderAttachableImpl::removeAppender(const LogString& name)
 		return;
 	}
 
-	std::unique_lock<std::mutex> lock( m_mutex );
-	AppenderList::iterator it, itEnd = appenderList.end();
+	std::unique_lock<std::mutex> lock( m_priv->m_mutex );
+	AppenderList::iterator it, itEnd = m_priv->appenderList.end();
 	AppenderPtr appender;
 
-	for (it = appenderList.begin(); it != itEnd; it++)
+	for (it = m_priv->appenderList.begin(); it != itEnd; it++)
 	{
 		appender = *it;
 
 		if (name == appender->getName())
 		{
-			appenderList.erase(it);
+			m_priv->appenderList.erase(it);
 			return;
 		}
 	}
 }
 
+std::mutex& AppenderAttachableImpl::getMutex(){
+	return m_priv->m_mutex;
+}
 
diff --git a/src/main/cpp/appenderskeleton.cpp b/src/main/cpp/appenderskeleton.cpp
index 6df2551..2c433d8 100644
--- a/src/main/cpp/appenderskeleton.cpp
+++ b/src/main/cpp/appenderskeleton.cpp
@@ -21,6 +21,7 @@
 #include <log4cxx/helpers/onlyonceerrorhandler.h>
 #include <log4cxx/level.h>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
 #include <mutex>
 
 using namespace log4cxx;
@@ -29,38 +30,31 @@ using namespace log4cxx::helpers;
 
 IMPLEMENT_LOG4CXX_OBJECT(AppenderSkeleton)
 
+AppenderSkeleton::AppenderSkeleton( std::unique_ptr<priv::AppenderSkeletonPrivate> priv )
+	:	m_priv(std::move(priv))
+{
+
+}
 
 AppenderSkeleton::AppenderSkeleton()
-	:   layout(),
-		name(),
-		threshold(Level::getAll()),
-		errorHandler(new OnlyOnceErrorHandler()),
-		headFilter(),
-		tailFilter(),
-		pool()
+	:   m_priv(std::make_unique<priv::AppenderSkeletonPrivate>())
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	closed = false;
+
 }
 
 AppenderSkeleton::AppenderSkeleton(const LayoutPtr& layout1)
-	: layout(layout1),
-	  name(),
-	  threshold(Level::getAll()),
-	  errorHandler(new OnlyOnceErrorHandler()),
-	  headFilter(),
-	  tailFilter(),
-	  pool()
+	:	m_priv(std::make_unique<priv::AppenderSkeletonPrivate>())
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	closed = false;
+
 }
 
+AppenderSkeleton::~AppenderSkeleton(){}
+
 void AppenderSkeleton::finalize()
 {
 	// An appender might be closed then garbage collected. There is no
 	// point in closing twice.
-	if (closed)
+	if (m_priv->closed)
 	{
 		return;
 	}
@@ -68,45 +62,45 @@ void AppenderSkeleton::finalize()
 	close();
 }
 
-void AppenderSkeleton::addFilter(const spi::FilterPtr& newFilter)
+void AppenderSkeleton::addFilter(const spi::FilterPtr newFilter)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(m_priv->mutex);
 
-	if (headFilter == 0)
+	if (m_priv->headFilter == nullptr)
 	{
-		headFilter = tailFilter = newFilter;
+		m_priv->headFilter = m_priv->tailFilter = newFilter;
 	}
 	else
 	{
-		tailFilter->setNext(newFilter);
-		tailFilter = newFilter;
+		m_priv->tailFilter->setNext(newFilter);
+		m_priv->tailFilter = newFilter;
 	}
 }
 
 void AppenderSkeleton::clearFilters()
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	headFilter = tailFilter = 0;
+	std::unique_lock<log4cxx::shared_mutex> lock(m_priv->mutex);
+	m_priv->headFilter = m_priv->tailFilter = nullptr;
 }
 
 bool AppenderSkeleton::isAsSevereAsThreshold(const LevelPtr& level) const
 {
-	return ((level == 0) || level->isGreaterOrEqual(threshold));
+	return ((level == 0) || level->isGreaterOrEqual(m_priv->threshold));
 }
 
 void AppenderSkeleton::doAppend(const spi::LoggingEventPtr& event, Pool& pool1)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(m_priv->mutex);
 
 	doAppendImpl(event, pool1);
 }
 
 void AppenderSkeleton::doAppendImpl(const spi::LoggingEventPtr& event, Pool& pool1)
 {
-	if (closed)
+	if (m_priv->closed)
 	{
 		LogLog::error(((LogString) LOG4CXX_STR("Attempted to append to closed appender named ["))
-			+ name + LOG4CXX_STR("]."));
+			+ m_priv->name + LOG4CXX_STR("]."));
 		return;
 	}
 
@@ -115,7 +109,7 @@ void AppenderSkeleton::doAppendImpl(const spi::LoggingEventPtr& event, Pool& poo
 		return;
 	}
 
-	FilterPtr f = headFilter;
+	FilterPtr f = m_priv->headFilter;
 
 
 	while (f != 0)
@@ -126,7 +120,7 @@ void AppenderSkeleton::doAppendImpl(const spi::LoggingEventPtr& event, Pool& poo
 				return;
 
 			case Filter::ACCEPT:
-				f = 0;
+				f = nullptr;
 				break;
 
 			case Filter::NEUTRAL:
@@ -139,9 +133,9 @@ void AppenderSkeleton::doAppendImpl(const spi::LoggingEventPtr& event, Pool& poo
 
 void AppenderSkeleton::setErrorHandler(const spi::ErrorHandlerPtr errorHandler1)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(m_priv->mutex);
 
-	if (errorHandler1 == 0)
+	if (errorHandler1 == nullptr)
 	{
 		// We do not throw exception here since the cause is probably a
 		// bad config file.
@@ -149,14 +143,14 @@ void AppenderSkeleton::setErrorHandler(const spi::ErrorHandlerPtr errorHandler1)
 	}
 	else
 	{
-		this->errorHandler = errorHandler1;
+		m_priv->errorHandler = errorHandler1;
 	}
 }
 
 void AppenderSkeleton::setThreshold(const LevelPtr& threshold1)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	this->threshold = threshold1;
+	std::unique_lock<log4cxx::shared_mutex> lock(m_priv->mutex);
+	m_priv->threshold = threshold1;
 }
 
 void AppenderSkeleton::setOption(const LogString& option,
@@ -169,4 +163,34 @@ void AppenderSkeleton::setOption(const LogString& option,
 	}
 }
 
+const spi::ErrorHandlerPtr AppenderSkeleton::getErrorHandler() const{
+	return m_priv->errorHandler;
+}
+
+spi::FilterPtr AppenderSkeleton::getFilter() const{
+	return m_priv->headFilter;
+}
+
+const spi::FilterPtr AppenderSkeleton::getFirstFilter() const{
+	return m_priv->headFilter;
+}
+
+LayoutPtr AppenderSkeleton::getLayout() const{
+	return m_priv->layout;
+}
+
+LogString AppenderSkeleton::getName() const{
+	return m_priv->name;
+}
 
+const LevelPtr AppenderSkeleton::getThreshold() const{
+	return m_priv->threshold;
+}
+
+void AppenderSkeleton::setLayout(const LayoutPtr layout1){
+	m_priv->layout = layout1;
+}
+
+void AppenderSkeleton::setName(const LogString& name1){
+	m_priv->name.assign(name1);
+}
diff --git a/src/main/cpp/asyncappender.cpp b/src/main/cpp/asyncappender.cpp
index d357ff0..f878038 100644
--- a/src/main/cpp/asyncappender.cpp
+++ b/src/main/cpp/asyncappender.cpp
@@ -31,38 +31,145 @@
 #include <apr_atomic.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/threadutility.h>
-
+#include <log4cxx/private/appenderskeleton_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 using namespace log4cxx::spi;
 
+/**
+ * The default buffer size is set to 128 events.
+*/
+enum { DEFAULT_BUFFER_SIZE = 128 };
+
+class DiscardSummary
+{
+	private:
+		/**
+		 * First event of the highest severity.
+		*/
+		::log4cxx::spi::LoggingEventPtr maxEvent;
+
+		/**
+		* Total count of messages discarded.
+		*/
+		int count;
+
+	public:
+		/**
+		 * Create new instance.
+		 *
+		 * @param event event, may not be null.
+		*/
+		DiscardSummary(const ::log4cxx::spi::LoggingEventPtr& event);
+		/** Copy constructor.  */
+		DiscardSummary(const DiscardSummary& src);
+		/** Assignment operator. */
+		DiscardSummary& operator=(const DiscardSummary& src);
+
+		/**
+		 * Add discarded event to summary.
+		 *
+		 * @param event event, may not be null.
+		*/
+		void add(const ::log4cxx::spi::LoggingEventPtr& event);
+
+		/**
+		 * Create event with summary information.
+		 *
+		 * @return new event.
+		 */
+		::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p);
+
+		static
+		::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p,
+			size_t discardedCount);
+};
+
+typedef std::map<LogString, DiscardSummary> DiscardMap;
+
+struct AsyncAppenderPriv : public priv::AppenderSkeletonPrivate {
+	AsyncAppenderPriv()	:
+		buffer(),
+		bufferSize(DEFAULT_BUFFER_SIZE),
+		appenders(std::make_shared<AppenderAttachableImpl>(pool)),
+		dispatcher(),
+		locationInfo(false),
+		blocking(true){}
+
+	/**
+	 * Event buffer.
+	*/
+#if defined(NON_BLOCKING)
+	boost::lockfree::queue<log4cxx::spi::LoggingEvent* > buffer;
+	std::atomic<size_t> discardedCount;
+#else
+	LoggingEventList buffer;
+#endif
+
+	/**
+	 *  Mutex used to guard access to buffer and discardMap.
+	 */
+	std::mutex bufferMutex;
+
+#if defined(NON_BLOCKING)
+	::log4cxx::helpers::Semaphore bufferNotFull;
+	::log4cxx::helpers::Semaphore bufferNotEmpty;
+#else
+	std::condition_variable bufferNotFull;
+	std::condition_variable bufferNotEmpty;
+#endif
+
+	/**
+	  * Map of DiscardSummary objects keyed by logger name.
+	*/
+	DiscardMap discardMap;
+
+	/**
+	 * Buffer size.
+	*/
+	int bufferSize;
+
+	/**
+	 * Nested appenders.
+	*/
+	helpers::AppenderAttachableImplPtr appenders;
+
+	/**
+	 *  Dispatcher.
+	 */
+	std::thread dispatcher;
+
+	/**
+	 * Should location info be included in dispatched messages.
+	*/
+	bool locationInfo;
+
+	/**
+	 * Does appender block when buffer is full.
+	*/
+	bool blocking;
+};
+
 
 IMPLEMENT_LOG4CXX_OBJECT(AsyncAppender)
 
+#define priv static_cast<AsyncAppenderPriv*>(m_priv.get())
 
 AsyncAppender::AsyncAppender()
-	: AppenderSkeleton(),
-	  buffer(),
-	  discardMap(new DiscardMap()),
-	  bufferSize(DEFAULT_BUFFER_SIZE),
-	  appenders(new AppenderAttachableImpl(pool)),
-	  dispatcher(),
-	  locationInfo(false),
-	  blocking(true)
+	: AppenderSkeleton(std::make_unique<AsyncAppenderPriv>())
 {
-	dispatcher = ThreadUtility::instance()->createThread( LOG4CXX_STR("AsyncAppender"), &AsyncAppender::dispatch, this );
+	priv->dispatcher = ThreadUtility::instance()->createThread( LOG4CXX_STR("AsyncAppender"), &AsyncAppender::dispatch, this );
 }
 
 AsyncAppender::~AsyncAppender()
 {
 	finalize();
-	delete discardMap;
 }
 
 void AsyncAppender::addAppender(const AppenderPtr newAppender)
 {
-	appenders->addAppender(newAppender);
+	priv->appenders->addAppender(newAppender);
 }
 
 
@@ -92,7 +199,7 @@ void AsyncAppender::setOption(const LogString& option,
 
 void AsyncAppender::doAppend(const spi::LoggingEventPtr& event, Pool& pool1)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(priv->mutex);
 
 	doAppendImpl(event, pool1);
 }
@@ -103,10 +210,10 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 	//   if dispatcher has died then
 	//      append subsequent events synchronously
 	//
-	if (!dispatcher.joinable() || bufferSize <= 0)
+	if (!priv->dispatcher.joinable() || priv->bufferSize <= 0)
 	{
-		std::unique_lock<std::mutex> lock(appenders->getMutex());
-		appenders->appendLoopOnAppenders(event, p);
+		std::unique_lock<std::mutex> lock(priv->appenders->getMutex());
+		priv->appenders->appendLoopOnAppenders(event, p);
 		return;
 	}
 
@@ -120,19 +227,19 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 
 
 	{
-		std::unique_lock<std::mutex> lock(bufferMutex);
+		std::unique_lock<std::mutex> lock(priv->bufferMutex);
 
 		while (true)
 		{
-			size_t previousSize = buffer.size();
+			size_t previousSize = priv->buffer.size();
 
-			if (previousSize < (size_t)bufferSize)
+			if (previousSize < (size_t)priv->bufferSize)
 			{
-				buffer.push_back(event);
+				priv->buffer.push_back(event);
 
 				if (previousSize == 0)
 				{
-					bufferNotEmpty.notify_all();
+					priv->bufferNotEmpty.notify_all();
 				}
 
 				break;
@@ -147,13 +254,13 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 			//      wait for a buffer notification
 			bool discard = true;
 
-			if (blocking
+			if (priv->blocking
 				//&& !Thread::interrupted()
-				&& (dispatcher.get_id() != std::this_thread::get_id()) )
+				&& (priv->dispatcher.get_id() != std::this_thread::get_id()) )
 			{
 				try
 				{
-					bufferNotFull.wait(lock);
+					priv->bufferNotFull.wait(lock);
 					discard = false;
 				}
 				catch (InterruptedException&)
@@ -173,12 +280,12 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 			if (discard)
 			{
 				LogString loggerName = event->getLoggerName();
-				DiscardMap::iterator iter = discardMap->find(loggerName);
+				DiscardMap::iterator iter = priv->discardMap.find(loggerName);
 
-				if (iter == discardMap->end())
+				if (iter == priv->discardMap.end())
 				{
 					DiscardSummary summary(event);
-					discardMap->insert(DiscardMap::value_type(loggerName, summary));
+					priv->discardMap.insert(DiscardMap::value_type(loggerName, summary));
 				}
 				else
 				{
@@ -195,20 +302,20 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 void AsyncAppender::close()
 {
 	{
-		std::unique_lock<std::mutex> lock(bufferMutex);
-		closed = true;
-		bufferNotEmpty.notify_all();
-		bufferNotFull.notify_all();
+		std::unique_lock<std::mutex> lock(priv->bufferMutex);
+		priv->closed = true;
+		priv->bufferNotEmpty.notify_all();
+		priv->bufferNotFull.notify_all();
 	}
 
-	if ( dispatcher.joinable() )
+	if ( priv->dispatcher.joinable() )
 	{
-		dispatcher.join();
+		priv->dispatcher.join();
 	}
 
 	{
-		std::unique_lock<std::mutex> lock(appenders->getMutex());
-		AppenderList appenderList = appenders->getAllAppenders();
+		std::unique_lock<std::mutex> lock(priv->appenders->getMutex());
+		AppenderList appenderList = priv->appenders->getAllAppenders();
 
 		for (AppenderList::iterator iter = appenderList.begin();
 			iter != appenderList.end();
@@ -221,17 +328,17 @@ void AsyncAppender::close()
 
 AppenderList AsyncAppender::getAllAppenders() const
 {
-	return appenders->getAllAppenders();
+	return priv->appenders->getAllAppenders();
 }
 
 AppenderPtr AsyncAppender::getAppender(const LogString& n) const
 {
-	return appenders->getAppender(n);
+	return priv->appenders->getAppender(n);
 }
 
 bool AsyncAppender::isAttached(const AppenderPtr appender) const
 {
-	return appenders->isAttached(appender);
+	return priv->appenders->isAttached(appender);
 }
 
 bool AsyncAppender::requiresLayout() const
@@ -241,27 +348,27 @@ bool AsyncAppender::requiresLayout() const
 
 void AsyncAppender::removeAllAppenders()
 {
-	appenders->removeAllAppenders();
+	priv->appenders->removeAllAppenders();
 }
 
 void AsyncAppender::removeAppender(const AppenderPtr appender)
 {
-	appenders->removeAppender(appender);
+	priv->appenders->removeAppender(appender);
 }
 
 void AsyncAppender::removeAppender(const LogString& n)
 {
-	appenders->removeAppender(n);
+	priv->appenders->removeAppender(n);
 }
 
 bool AsyncAppender::getLocationInfo() const
 {
-	return locationInfo;
+	return priv->locationInfo;
 }
 
 void AsyncAppender::setLocationInfo(bool flag)
 {
-	locationInfo = flag;
+	priv->locationInfo = flag;
 }
 
 
@@ -272,46 +379,46 @@ void AsyncAppender::setBufferSize(int size)
 		throw IllegalArgumentException(LOG4CXX_STR("size argument must be non-negative"));
 	}
 
-	std::unique_lock<std::mutex> lock(bufferMutex);
-	bufferSize = (size < 1) ? 1 : size;
-	bufferNotFull.notify_all();
+	std::unique_lock<std::mutex> lock(priv->bufferMutex);
+	priv->bufferSize = (size < 1) ? 1 : size;
+	priv->bufferNotFull.notify_all();
 }
 
 int AsyncAppender::getBufferSize() const
 {
-	return bufferSize;
+	return priv->bufferSize;
 }
 
 void AsyncAppender::setBlocking(bool value)
 {
-	std::unique_lock<std::mutex> lock(bufferMutex);
-	blocking = value;
-	bufferNotFull.notify_all();
+	std::unique_lock<std::mutex> lock(priv->bufferMutex);
+	priv->blocking = value;
+	priv->bufferNotFull.notify_all();
 }
 
 bool AsyncAppender::getBlocking() const
 {
-	return blocking;
+	return priv->blocking;
 }
 
-AsyncAppender::DiscardSummary::DiscardSummary(const LoggingEventPtr& event) :
+DiscardSummary::DiscardSummary(const LoggingEventPtr& event) :
 	maxEvent(event), count(1)
 {
 }
 
-AsyncAppender::DiscardSummary::DiscardSummary(const DiscardSummary& src) :
+DiscardSummary::DiscardSummary(const DiscardSummary& src) :
 	maxEvent(src.maxEvent), count(src.count)
 {
 }
 
-AsyncAppender::DiscardSummary& AsyncAppender::DiscardSummary::operator=(const DiscardSummary& src)
+DiscardSummary& DiscardSummary::operator=(const DiscardSummary& src)
 {
 	maxEvent = src.maxEvent;
 	count = src.count;
 	return *this;
 }
 
-void AsyncAppender::DiscardSummary::add(const LoggingEventPtr& event)
+void DiscardSummary::add(const LoggingEventPtr& event)
 {
 	if (event->getLevel()->toInt() > maxEvent->getLevel()->toInt())
 	{
@@ -321,7 +428,7 @@ void AsyncAppender::DiscardSummary::add(const LoggingEventPtr& event)
 	count++;
 }
 
-LoggingEventPtr AsyncAppender::DiscardSummary::createEvent(Pool& p)
+LoggingEventPtr DiscardSummary::createEvent(Pool& p)
 {
 	LogString msg(LOG4CXX_STR("Discarded "));
 	StringHelper::toString(count, p, msg);
@@ -335,7 +442,7 @@ LoggingEventPtr AsyncAppender::DiscardSummary::createEvent(Pool& p)
 }
 
 ::log4cxx::spi::LoggingEventPtr
-AsyncAppender::DiscardSummary::createEvent(::log4cxx::helpers::Pool& p,
+DiscardSummary::createEvent(::log4cxx::helpers::Pool& p,
 	size_t discardedCount)
 {
 	LogString msg(LOG4CXX_STR("Discarded "));
@@ -363,41 +470,41 @@ void AsyncAppender::dispatch()
 			Pool p;
 			LoggingEventList events;
 			{
-				std::unique_lock<std::mutex> lock(bufferMutex);
-				size_t bufferSize = buffer.size();
-				isActive = !closed;
+				std::unique_lock<std::mutex> lock(priv->bufferMutex);
+				size_t bufferSize = priv->buffer.size();
+				isActive = !priv->closed;
 
 				while ((bufferSize == 0) && isActive)
 				{
-					bufferNotEmpty.wait(lock);
-					bufferSize = buffer.size();
-					isActive = !closed;
+					priv->bufferNotEmpty.wait(lock);
+					bufferSize = priv->buffer.size();
+					isActive = !priv->closed;
 				}
 
-				for (LoggingEventList::iterator eventIter = buffer.begin();
-					eventIter != buffer.end();
+				for (LoggingEventList::iterator eventIter = priv->buffer.begin();
+					eventIter != priv->buffer.end();
 					eventIter++)
 				{
 					events.push_back(*eventIter);
 				}
 
-				for (DiscardMap::iterator discardIter = discardMap->begin();
-					discardIter != discardMap->end();
+				for (DiscardMap::iterator discardIter = priv->discardMap.begin();
+					discardIter != priv->discardMap.end();
 					discardIter++)
 				{
 					events.push_back(discardIter->second.createEvent(p));
 				}
 
-				buffer.clear();
-				discardMap->clear();
-				bufferNotFull.notify_all();
+				priv->buffer.clear();
+				priv->discardMap.clear();
+				priv->bufferNotFull.notify_all();
 			}
 
 			for (LoggingEventList::iterator iter = events.begin();
 				iter != events.end();
 				iter++)
 			{
-				appenders->appendLoopOnAppenders(*iter, p);
+				priv->appenders->appendLoopOnAppenders(*iter, p);
 			}
 		}
 	}
diff --git a/src/main/cpp/class.cpp b/src/main/cpp/class.cpp
index 307a7cb..80430f7 100644
--- a/src/main/cpp/class.cpp
+++ b/src/main/cpp/class.cpp
@@ -30,8 +30,6 @@
 	#define LOG4CXX 1
 #endif
 #include <log4cxx/private/log4cxx_private.h>
-#include <log4cxx/rollingfileappender.h>
-#include <log4cxx/dailyrollingfileappender.h>
 
 
 #include <log4cxx/asyncappender.h>
@@ -173,7 +171,6 @@ void Class::registerClasses()
 #endif
 	log4cxx::nt::OutputDebugStringAppender::registerClass();
 #endif
-	log4cxx::RollingFileAppender::registerClass();
 	SMTPAppender::registerClass();
 	SocketAppender::registerClass();
 #if APR_HAS_THREADS
@@ -193,9 +190,7 @@ void Class::registerClasses()
 	LevelMatchFilter::registerClass();
 	LevelRangeFilter::registerClass();
 	StringMatchFilter::registerClass();
-	log4cxx::RollingFileAppender::registerClass();
 	log4cxx::rolling::RollingFileAppender::registerClass();
-	DailyRollingFileAppender::registerClass();
 	log4cxx::rolling::SizeBasedTriggeringPolicy::registerClass();
 	log4cxx::rolling::TimeBasedRollingPolicy::registerClass();
 	log4cxx::rolling::ManualTriggeringPolicy::registerClass();
diff --git a/src/main/cpp/consoleappender.cpp b/src/main/cpp/consoleappender.cpp
index c81661d..c77c409 100644
--- a/src/main/cpp/consoleappender.cpp
+++ b/src/main/cpp/consoleappender.cpp
@@ -21,19 +21,31 @@
 #include <log4cxx/helpers/systemerrwriter.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/layout.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
+#include <log4cxx/private/writerappender_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 
+struct ConsoleAppenderPriv : public priv::WriterAppenderPriv{
+	ConsoleAppenderPriv(LogString target) :
+		WriterAppenderPriv(),
+		target(target){}
+
+	LogString target;
+};
+
+#define _priv static_cast<ConsoleAppenderPriv*>(m_priv.get())
+
 IMPLEMENT_LOG4CXX_OBJECT(ConsoleAppender)
 
 ConsoleAppender::ConsoleAppender()
-	: target(getSystemOut())
+	: WriterAppender (std::make_unique<ConsoleAppenderPriv>(getSystemOut()))
 {
 }
 
 ConsoleAppender::ConsoleAppender(const LayoutPtr& layout1)
-	: target(getSystemOut())
+	: WriterAppender (std::make_unique<ConsoleAppenderPriv>(getSystemOut()))
 {
 	setLayout(layout1);
 	Pool p;
@@ -43,7 +55,7 @@ ConsoleAppender::ConsoleAppender(const LayoutPtr& layout1)
 }
 
 ConsoleAppender::ConsoleAppender(const LayoutPtr& layout1, const LogString& target1)
-	: target(target1)
+	: WriterAppender (std::make_unique<ConsoleAppenderPriv>(getSystemOut()))
 {
 	setLayout(layout1);
 	Pool p;
@@ -74,12 +86,12 @@ void ConsoleAppender::setTarget(const LogString& value)
 	if (StringHelper::equalsIgnoreCase(v,
 			LOG4CXX_STR("SYSTEM.OUT"), LOG4CXX_STR("system.out")))
 	{
-		target = getSystemOut();
+		_priv->target = getSystemOut();
 	}
 	else if (StringHelper::equalsIgnoreCase(v,
 			LOG4CXX_STR("SYSTEM.ERR"), LOG4CXX_STR("system.err")))
 	{
-		target = getSystemErr();
+		_priv->target = getSystemErr();
 	}
 	else
 	{
@@ -89,7 +101,7 @@ void ConsoleAppender::setTarget(const LogString& value)
 
 LogString ConsoleAppender::getTarget() const
 {
-	return target;
+	return _priv->target;
 }
 
 void ConsoleAppender::targetWarn(const LogString& val)
@@ -101,16 +113,16 @@ void ConsoleAppender::targetWarn(const LogString& val)
 
 void ConsoleAppender::activateOptions(Pool& p)
 {
-	if (StringHelper::equalsIgnoreCase(target,
+	if (StringHelper::equalsIgnoreCase(_priv->target,
 			LOG4CXX_STR("SYSTEM.OUT"), LOG4CXX_STR("system.out")))
 	{
-		WriterPtr writer1(new SystemOutWriter());
+		WriterPtr writer1 = std::make_shared<SystemOutWriter>();
 		setWriter(writer1);
 	}
-	else if (StringHelper::equalsIgnoreCase(target,
+	else if (StringHelper::equalsIgnoreCase(_priv->target,
 			LOG4CXX_STR("SYSTEM.ERR"), LOG4CXX_STR("system.err")))
 	{
-		WriterPtr writer1(new SystemErrWriter());
+		WriterPtr writer1 = std::make_shared<SystemErrWriter>();
 		setWriter(writer1);
 	}
 
diff --git a/src/main/cpp/fileappender.cpp b/src/main/cpp/fileappender.cpp
index cca1abb..29ed49c 100644
--- a/src/main/cpp/fileappender.cpp
+++ b/src/main/cpp/fileappender.cpp
@@ -25,6 +25,8 @@
 #include <log4cxx/helpers/outputstreamwriter.h>
 #include <log4cxx/helpers/bufferedwriter.h>
 #include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/private/writerappender_priv.h>
+#include <log4cxx/private/fileappender_priv.h>
 #include <mutex>
 
 using namespace log4cxx;
@@ -33,59 +35,56 @@ using namespace log4cxx::spi;
 
 IMPLEMENT_LOG4CXX_OBJECT(FileAppender)
 
+#define _priv static_cast<priv::FileAppenderPriv*>(m_priv.get())
 
-FileAppender::FileAppender()
+FileAppender::FileAppender() :
+	WriterAppender (std::make_unique<priv::FileAppenderPriv>())
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	fileAppend = true;
-	bufferedIO = false;
-	bufferSize = 8 * 1024;
+	_priv->fileAppend = true;
+	_priv->bufferedIO = false;
+	_priv->bufferSize = 8 * 1024;
 }
 
 FileAppender::FileAppender(const LayoutPtr& layout1, const LogString& fileName1,
 	bool append1, bool bufferedIO1, int bufferSize1)
-	: WriterAppender(layout1)
+	: WriterAppender(std::make_unique<priv::FileAppenderPriv>(layout1))
 {
-	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		fileAppend = append1;
-		fileName = fileName1;
-		bufferedIO = bufferedIO1;
-		bufferSize = bufferSize1;
-	}
+	_priv->fileAppend = append1;
+	_priv->fileName = fileName1;
+	_priv->bufferedIO = bufferedIO1;
+	_priv->bufferSize = bufferSize1;
 	Pool p;
 	activateOptions(p);
 }
 
 FileAppender::FileAppender(const LayoutPtr& layout1, const LogString& fileName1,
 	bool append1)
-	: WriterAppender(layout1)
+	: WriterAppender(std::make_unique<priv::FileAppenderPriv>(layout1))
 {
-	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		fileAppend = append1;
-		fileName = fileName1;
-		bufferedIO = false;
-		bufferSize = 8 * 1024;
-	}
+	_priv->fileAppend = append1;
+	_priv->fileName = fileName1;
+	_priv->bufferedIO = false;
+	_priv->bufferSize = 8 * 1024;
 	Pool p;
 	activateOptions(p);
 }
 
 FileAppender::FileAppender(const LayoutPtr& layout1, const LogString& fileName1)
-	: WriterAppender(layout1)
+	: WriterAppender(std::make_unique<priv::FileAppenderPriv>(layout1))
 {
-	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		fileAppend = true;
-		fileName = fileName1;
-		bufferedIO = false;
-		bufferSize = 8 * 1024;
-	}
+	_priv->fileAppend = true;
+	_priv->fileName = fileName1;
+	_priv->bufferedIO = false;
+	_priv->bufferSize = 8 * 1024;
 	Pool p;
 	activateOptions(p);
 }
 
+FileAppender::FileAppender(std::unique_ptr<priv::FileAppenderPriv> priv) :
+	WriterAppender (std::move(priv)){
+
+}
+
 FileAppender::~FileAppender()
 {
 	finalize();
@@ -93,25 +92,25 @@ FileAppender::~FileAppender()
 
 void FileAppender::setAppend(bool fileAppend1)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	this->fileAppend = fileAppend1;
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+	_priv->fileAppend = fileAppend1;
 }
 
 void FileAppender::setFile(const LogString& file)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 	setFileInternal(file);
 }
 
 void FileAppender::setFileInternal(const LogString& file)
 {
-	fileName = file;
+	_priv->fileName = file;
 }
 
 void FileAppender::setBufferedIO(bool bufferedIO1)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	this->bufferedIO = bufferedIO1;
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+	_priv->bufferedIO = bufferedIO1;
 
 	if (bufferedIO1)
 	{
@@ -125,28 +124,28 @@ void FileAppender::setOption(const LogString& option,
 	if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FILE"), LOG4CXX_STR("file"))
 		|| StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FILENAME"), LOG4CXX_STR("filename")))
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		fileName = stripDuplicateBackslashes(value);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+		_priv->fileName = stripDuplicateBackslashes(value);
 	}
 	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("APPEND"), LOG4CXX_STR("append")))
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		fileAppend = OptionConverter::toBoolean(value, true);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+		_priv->fileAppend = OptionConverter::toBoolean(value, true);
 	}
 	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BUFFEREDIO"), LOG4CXX_STR("bufferedio")))
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		bufferedIO = OptionConverter::toBoolean(value, true);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+		_priv->bufferedIO = OptionConverter::toBoolean(value, true);
 	}
 	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("IMMEDIATEFLUSH"), LOG4CXX_STR("immediateflush")))
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		bufferedIO = !OptionConverter::toBoolean(value, false);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+		_priv->bufferedIO = !OptionConverter::toBoolean(value, false);
 	}
 	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BUFFERSIZE"), LOG4CXX_STR("buffersize")))
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		bufferSize = OptionConverter::toFileSize(value, 8 * 1024);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+		_priv->bufferSize = OptionConverter::toFileSize(value, 8 * 1024);
 	}
 	else
 	{
@@ -156,7 +155,7 @@ void FileAppender::setOption(const LogString& option,
 
 void FileAppender::activateOptions(Pool& p)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 	activateOptionsInternal(p);
 }
 
@@ -164,28 +163,28 @@ void FileAppender::activateOptionsInternal(Pool& p)
 {
 	int errors = 0;
 
-	if (!fileName.empty())
+	if (!_priv->fileName.empty())
 	{
 		try
 		{
-			setFileInternal(fileName, fileAppend, bufferedIO, bufferSize, p);
+			setFileInternal(_priv->fileName, _priv->fileAppend, _priv->bufferedIO, _priv->bufferSize, p);
 		}
 		catch (IOException& e)
 		{
 			errors++;
 			LogString msg(LOG4CXX_STR("setFile("));
-			msg.append(fileName);
+			msg.append(_priv->fileName);
 			msg.append(1, (logchar) 0x2C /* ',' */);
-			StringHelper::toString(fileAppend, msg);
+			StringHelper::toString(_priv->fileAppend, msg);
 			msg.append(LOG4CXX_STR(") call failed."));
-			errorHandler->error(msg, e, ErrorCode::FILE_OPEN_FAILURE);
+			_priv->errorHandler->error(msg, e, ErrorCode::FILE_OPEN_FAILURE);
 		}
 	}
 	else
 	{
 		errors++;
 		LogLog::error(LogString(LOG4CXX_STR("File option not set for appender ["))
-			+  name + LOG4CXX_STR("]."));
+			+  _priv->name + LOG4CXX_STR("]."));
 		LogLog::warn(LOG4CXX_STR("Are you using FileAppender instead of ConsoleAppender?"));
 	}
 
@@ -355,11 +354,35 @@ void FileAppender::setFileInternal(
 
 	setWriterInternal(newWriter);
 
-	this->fileAppend = append1;
-	this->bufferedIO = bufferedIO1;
-	this->fileName = filename;
-	this->bufferSize = (int)bufferSize1;
+	_priv->fileAppend = append1;
+	_priv->bufferedIO = bufferedIO1;
+	_priv->fileName = filename;
+	_priv->bufferSize = (int)bufferSize1;
 	writeHeader(p);
 
 }
 
+LogString FileAppender::getFile() const
+{
+	return _priv->fileName;
+}
+
+bool FileAppender::getBufferedIO() const
+{
+	return _priv->bufferedIO;
+}
+
+int FileAppender::getBufferSize() const
+{
+	return _priv->bufferSize;
+}
+
+void FileAppender::setBufferSize(int bufferSize1)
+{
+	_priv->bufferSize = bufferSize1;
+}
+
+bool FileAppender::getAppend() const
+{
+	return _priv->fileAppend;
+}
diff --git a/src/main/cpp/odbcappender.cpp b/src/main/cpp/odbcappender.cpp
index a8fa380..fb1632c 100644
--- a/src/main/cpp/odbcappender.cpp
+++ b/src/main/cpp/odbcappender.cpp
@@ -21,6 +21,7 @@
 #include <log4cxx/helpers/transcoder.h>
 #include <log4cxx/patternlayout.h>
 #include <apr_strings.h>
+#include <log4cxx/private/odbcappender_priv.h>
 
 #if !defined(LOG4CXX)
 	#define LOG4CXX 1
@@ -90,10 +91,10 @@ const char* SQLException::formatMessage(short fHandleType,
 
 IMPLEMENT_LOG4CXX_OBJECT(ODBCAppender)
 
-
+#define _priv static_cast<priv::ODBCAppenderPriv*>(m_priv.get())
 
 ODBCAppender::ODBCAppender()
-	: connection(0), env(0), bufferSize(1)
+	: AppenderSkeleton (std::make_unique<priv::ODBCAppenderPriv>())
 {
 }
 
@@ -143,9 +144,9 @@ void ODBCAppender::activateOptions(log4cxx::helpers::Pool&)
 void ODBCAppender::append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p)
 {
 #if LOG4CXX_HAVE_ODBC
-	buffer.push_back(event);
+	_priv->buffer.push_back(event);
 
-	if (buffer.size() >= bufferSize)
+	if (_priv->buffer.size() >=_priv->bufferSize)
 	{
 		flushBuffer(p);
 	}
@@ -219,46 +220,46 @@ ODBCAppender::SQLHDBC ODBCAppender::getConnection(log4cxx::helpers::Pool& p)
 #if LOG4CXX_HAVE_ODBC
 	SQLRETURN ret;
 
-	if (env == SQL_NULL_HENV)
+	if (_priv->env == SQL_NULL_HENV)
 	{
-		ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
+		ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &_priv->env);
 
 		if (ret < 0)
 		{
-			SQLException ex(SQL_HANDLE_ENV, env, "Failed to allocate SQL handle.", p);
-			env = SQL_NULL_HENV;
+			SQLException ex(SQL_HANDLE_ENV, _priv->env, "Failed to allocate SQL handle.", p);
+			_priv->env = SQL_NULL_HENV;
 			throw ex;
 		}
 
-		ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
+		ret = SQLSetEnvAttr(_priv->env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
 
 		if (ret < 0)
 		{
-			SQLException ex(SQL_HANDLE_ENV, env, "Failed to set odbc version.", p);
-			SQLFreeHandle(SQL_HANDLE_ENV, env);
-			env = SQL_NULL_HENV;
+			SQLException ex(SQL_HANDLE_ENV, _priv->env, "Failed to set odbc version.", p);
+			SQLFreeHandle(SQL_HANDLE_ENV, _priv->env);
+			_priv->env = SQL_NULL_HENV;
 			throw ex;
 		}
 	}
 
-	if (connection == SQL_NULL_HDBC)
+	if (_priv->connection == SQL_NULL_HDBC)
 	{
-		ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &connection);
+		ret = SQLAllocHandle(SQL_HANDLE_DBC, _priv->env, &_priv->connection);
 
 		if (ret < 0)
 		{
-			SQLException ex(SQL_HANDLE_DBC, connection, "Failed to allocate sql handle.", p);
-			connection = SQL_NULL_HDBC;
+			SQLException ex(SQL_HANDLE_DBC, _priv->connection, "Failed to allocate sql handle.", p);
+			_priv->connection = SQL_NULL_HDBC;
 			throw ex;
 		}
 
 
 		SQLWCHAR* wURL, *wUser, *wPwd;
-		encode(&wURL, databaseURL, p);
-		encode(&wUser, databaseUser, p);
-		encode(&wPwd, databasePassword, p);
+		encode(&wURL, _priv->databaseURL, p);
+		encode(&wUser, _priv->databaseUser, p);
+		encode(&wPwd, _priv->databasePassword, p);
 
-		ret = SQLConnectW( connection,
+		ret = SQLConnectW( _priv->connection,
 				wURL, SQL_NTS,
 				wUser, SQL_NTS,
 				wPwd, SQL_NTS);
@@ -266,14 +267,14 @@ ODBCAppender::SQLHDBC ODBCAppender::getConnection(log4cxx::helpers::Pool& p)
 
 		if (ret < 0)
 		{
-			SQLException ex(SQL_HANDLE_DBC, connection, "Failed to connect to database.", p);
-			SQLFreeHandle(SQL_HANDLE_DBC, connection);
-			connection = SQL_NULL_HDBC;
+			SQLException ex(SQL_HANDLE_DBC, _priv->connection, "Failed to connect to database.", p);
+			SQLFreeHandle(SQL_HANDLE_DBC, _priv->connection);
+			_priv->connection = SQL_NULL_HDBC;
 			throw ex;
 		}
 	}
 
-	return connection;
+	return _priv->connection;
 #else
 	return 0;
 #endif
@@ -281,7 +282,7 @@ ODBCAppender::SQLHDBC ODBCAppender::getConnection(log4cxx::helpers::Pool& p)
 
 void ODBCAppender::close()
 {
-	if (closed)
+	if (_priv->closed)
 	{
 		return;
 	}
@@ -294,32 +295,32 @@ void ODBCAppender::close()
 	}
 	catch (SQLException& e)
 	{
-		errorHandler->error(LOG4CXX_STR("Error closing connection"),
+		_priv->errorHandler->error(LOG4CXX_STR("Error closing connection"),
 			e, ErrorCode::GENERIC_FAILURE);
 	}
 
 #if LOG4CXX_HAVE_ODBC
 
-	if (connection != SQL_NULL_HDBC)
+	if (_priv->connection != SQL_NULL_HDBC)
 	{
-		SQLDisconnect(connection);
-		SQLFreeHandle(SQL_HANDLE_DBC, connection);
+		SQLDisconnect(_priv->connection);
+		SQLFreeHandle(SQL_HANDLE_DBC, _priv->connection);
 	}
 
-	if (env != SQL_NULL_HENV)
+	if (_priv->env != SQL_NULL_HENV)
 	{
-		SQLFreeHandle(SQL_HANDLE_ENV, env);
+		SQLFreeHandle(SQL_HANDLE_ENV, _priv->env);
 	}
 
 #endif
-	this->closed = true;
+	_priv->closed = true;
 }
 
 void ODBCAppender::flushBuffer(Pool& p)
 {
 	std::list<spi::LoggingEventPtr>::iterator i;
 
-	for (i = buffer.begin(); i != buffer.end(); i++)
+	for (i = _priv->buffer.begin(); i != _priv->buffer.end(); i++)
 	{
 		try
 		{
@@ -329,18 +330,18 @@ void ODBCAppender::flushBuffer(Pool& p)
 		}
 		catch (SQLException& e)
 		{
-			errorHandler->error(LOG4CXX_STR("Failed to execute sql"), e,
+			_priv->errorHandler->error(LOG4CXX_STR("Failed to execute sql"), e,
 				ErrorCode::FLUSH_FAILURE);
 		}
 	}
 
 	// clear the buffer of reported events
-	buffer.clear();
+	_priv->buffer.clear();
 }
 
 void ODBCAppender::setSql(const LogString& s)
 {
-	sqlStatement = s;
+	_priv->sqlStatement = s;
 
 	if (getLayout() == 0)
 	{
@@ -397,3 +398,48 @@ void ODBCAppender::encode(unsigned short** dest,
 	*current = 0;
 }
 
+const LogString& ODBCAppender::getSql() const
+{
+	return _priv->sqlStatement;
+}
+
+void ODBCAppender::setUser(const LogString& user)
+{
+	_priv->databaseUser = user;
+}
+
+void ODBCAppender::setURL(const LogString& url)
+{
+	_priv->databaseURL = url;
+}
+
+void ODBCAppender::setPassword(const LogString& password)
+{
+	_priv->databasePassword = password;
+}
+
+void ODBCAppender::setBufferSize(size_t newBufferSize)
+{
+	_priv->bufferSize = newBufferSize;
+}
+
+const LogString& ODBCAppender::getUser() const
+{
+	return _priv->databaseUser;
+}
+
+const LogString& ODBCAppender::getURL() const
+{
+	return _priv->databaseURL;
+}
+
+const LogString& ODBCAppender::getPassword() const
+{
+	return _priv->databasePassword;
+}
+
+size_t ODBCAppender::getBufferSize() const
+{
+	return _priv->bufferSize;
+}
+
diff --git a/src/main/cpp/rollingfileappender.cpp b/src/main/cpp/rollingfileappender.cpp
index 7d236f4..fe0cfa1 100644
--- a/src/main/cpp/rollingfileappender.cpp
+++ b/src/main/cpp/rollingfileappender.cpp
@@ -40,6 +40,7 @@
 #include <log4cxx/rolling/fixedwindowrollingpolicy.h>
 #include <log4cxx/rolling/manualtriggeringpolicy.h>
 #include <log4cxx/helpers/transcoder.h>
+#include <log4cxx/private/fileappender_priv.h>
 #include <mutex>
 
 using namespace log4cxx;
@@ -47,61 +48,84 @@ using namespace log4cxx::rolling;
 using namespace log4cxx::helpers;
 using namespace log4cxx::spi;
 
+struct RollingFileAppenderPriv : public priv::FileAppenderPriv{
+	RollingFileAppenderPriv() :
+		FileAppenderPriv(),
+		fileLength(0){}
+
+	/**
+	 * Triggering policy.
+	 */
+	TriggeringPolicyPtr triggeringPolicy;
+
+	/**
+	 * Rolling policy.
+	 */
+	RollingPolicyPtr rollingPolicy;
+
+	/**
+	 * Length of current active log file.
+	 */
+	size_t fileLength;
+
+	/**
+	 *  save the loggingevent
+	 */
+	spi::LoggingEventPtr _event;
+};
+
+#define _priv static_cast<RollingFileAppenderPriv*>(m_priv.get())
 
-IMPLEMENT_LOG4CXX_OBJECT(RollingFileAppenderSkeleton)
 IMPLEMENT_LOG4CXX_OBJECT(RollingFileAppender)
 
 
 /**
  * Construct a new instance.
  */
-RollingFileAppenderSkeleton::RollingFileAppenderSkeleton() : _event(NULL)
-{
-}
-
-RollingFileAppender::RollingFileAppender()
+RollingFileAppender::RollingFileAppender() :
+	FileAppender (std::make_unique<RollingFileAppenderPriv>())
 {
 }
 
 /**
  * Prepare instance of use.
  */
-void RollingFileAppenderSkeleton::activateOptions(Pool& p)
+void RollingFileAppender::activateOptions(Pool& p)
 {
-	if (rollingPolicy == NULL)
+	if (_priv->rollingPolicy == NULL)
 	{
 		FixedWindowRollingPolicyPtr fwrp = FixedWindowRollingPolicyPtr(new FixedWindowRollingPolicy());
 		fwrp->setFileNamePattern(getFile() + LOG4CXX_STR(".%i"));
-		rollingPolicy = fwrp;
+		_priv->rollingPolicy = fwrp;
 	}
 
 	//
 	//  if no explicit triggering policy and rolling policy is both.
 	//
-	if (triggeringPolicy == NULL)
+	if (_priv->triggeringPolicy == NULL)
 	{
-		TriggeringPolicyPtr trig = log4cxx::cast<TriggeringPolicy>(rollingPolicy);
+		TriggeringPolicyPtr trig = log4cxx::cast<TriggeringPolicy>(_priv->rollingPolicy);
 
 		if (trig != NULL)
 		{
-			triggeringPolicy = trig;
+			_priv->triggeringPolicy = trig;
 		}
 	}
 
-	if (triggeringPolicy == NULL)
+	if (_priv->triggeringPolicy == NULL)
 	{
-		triggeringPolicy = TriggeringPolicyPtr(new ManualTriggeringPolicy());
+		_priv->triggeringPolicy = TriggeringPolicyPtr(new ManualTriggeringPolicy());
 	}
 
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-		triggeringPolicy->activateOptions(p);
-		rollingPolicy->activateOptions(p);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+		_priv->triggeringPolicy->activateOptions(p);
+		_priv->rollingPolicy->activateOptions(p);
 
 		try
 		{
 			RolloverDescriptionPtr rollover1 =
-				rollingPolicy->initialize(getFile(), getAppend(), p);
+				_priv->rollingPolicy->initialize(getFile(), getAppend(), p);
 
 			if (rollover1 != NULL)
 			{
@@ -112,8 +136,8 @@ void RollingFileAppenderSkeleton::activateOptions(Pool& p)
 					syncAction->execute(p);
 				}
 
-				fileName = rollover1->getActiveFileName();
-				fileAppend = rollover1->getAppend();
+				_priv->fileName = rollover1->getActiveFileName();
+				_priv->fileAppend = rollover1->getAppend();
 
 				//
 				//  async action not yet implemented
@@ -131,11 +155,11 @@ void RollingFileAppenderSkeleton::activateOptions(Pool& p)
 
 			if (getAppend())
 			{
-				fileLength = activeFile.length(p);
+				_priv->fileLength = activeFile.length(p);
 			}
 			else
 			{
-				fileLength = 0;
+				_priv->fileLength = 0;
 			}
 
 			FileAppender::activateOptionsInternal(p);
@@ -181,18 +205,18 @@ void RollingFileAppenderSkeleton::releaseFileLock(apr_file_t* lock_file)
 
  * @return true if rollover performed.
  */
-bool RollingFileAppenderSkeleton::rollover(Pool& p)
+bool RollingFileAppender::rollover(Pool& p)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 	return rolloverInternal(p);
 }
 
-bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
+bool RollingFileAppender::rolloverInternal(Pool& p)
 {
 	//
 	//   can't roll without a policy
 	//
-	if (rollingPolicy != NULL)
+	if (_priv->rollingPolicy != NULL)
 	{
 
 		{
@@ -289,7 +313,7 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 
 				try
 				{
-					RolloverDescriptionPtr rollover1(rollingPolicy->rollover(this->getFile(), this->getAppend(), p));
+					RolloverDescriptionPtr rollover1(_priv->rollingPolicy->rollover(this->getFile(), this->getAppend(), p));
 
 					if (rollover1 != NULL)
 					{
@@ -312,7 +336,7 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 									LogLog::warn(LOG4CXX_STR("Exception on rollover"));
 									LogString exmsg;
 									log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
-									errorHandler->error(exmsg, ex, 0);
+									_priv->errorHandler->error(exmsg, ex, 0);
 								}
 							}
 
@@ -320,11 +344,11 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 							{
 								if (rollover1->getAppend())
 								{
-									fileLength = File().setPath(rollover1->getActiveFileName()).length(p);
+									_priv->fileLength = File().setPath(rollover1->getActiveFileName()).length(p);
 								}
 								else
 								{
-									fileLength = 0;
+									_priv->fileLength = 0;
 								}
 
 								//
@@ -339,12 +363,12 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 
 								setFileInternal(
 									rollover1->getActiveFileName(), rollover1->getAppend(),
-									bufferedIO, bufferSize, p);
+									_priv->bufferedIO, _priv->bufferSize, p);
 							}
 							else
 							{
 								setFileInternal(
-									rollover1->getActiveFileName(), true, bufferedIO, bufferSize, p);
+									rollover1->getActiveFileName(), true, _priv->bufferedIO, _priv->bufferSize, p);
 							}
 						}
 						else
@@ -373,7 +397,7 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 									LogLog::warn(LOG4CXX_STR("Exception during rollover"));
 									LogString exmsg;
 									log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
-									errorHandler->error(exmsg, ex, 0);
+									_priv->errorHandler->error(exmsg, ex, 0);
 								}
 							}
 
@@ -381,11 +405,11 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 							{
 								if (rollover1->getAppend())
 								{
-									fileLength = File().setPath(rollover1->getActiveFileName()).length(p);
+									_priv->fileLength = File().setPath(rollover1->getActiveFileName()).length(p);
 								}
 								else
 								{
-									fileLength = 0;
+									_priv->fileLength = 0;
 								}
 
 								//
@@ -413,7 +437,7 @@ bool RollingFileAppenderSkeleton::rolloverInternal(Pool& p)
 					LogLog::warn(LOG4CXX_STR("Exception during rollover"));
 					LogString exmsg;
 					log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
-					errorHandler->error(exmsg, ex, 0);
+					_priv->errorHandler->error(exmsg, ex, 0);
 				}
 
 #ifdef LOG4CXX_MULTI_PROCESS
@@ -451,12 +475,12 @@ void RollingFileAppenderSkeleton::reopenLatestFile(Pool& p)
 /**
  * {@inheritDoc}
 */
-void RollingFileAppenderSkeleton::subAppend(const LoggingEventPtr& event, Pool& p)
+void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
 {
 	// The rollover check must precede actual writing. This is the
 	// only correct behavior for time driven triggers.
 	if (
-		triggeringPolicy->isTriggeringEvent(
+		_priv->triggeringPolicy->isTriggeringEvent(
 			this, event, getFile(), getFileLength()))
 	{
 		//
@@ -466,7 +490,7 @@ void RollingFileAppenderSkeleton::subAppend(const LoggingEventPtr& event, Pool&
 		//     condition and the append should still happen.
 		try
 		{
-			_event = &(const_cast<LoggingEventPtr&>(event));
+			_priv->_event = event;
 			rolloverInternal(p);
 		}
 		catch (std::exception& ex)
@@ -474,7 +498,7 @@ void RollingFileAppenderSkeleton::subAppend(const LoggingEventPtr& event, Pool&
 			LogLog::warn(LOG4CXX_STR("Exception during rollover attempt."));
 			LogString exmsg;
 			log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
-			errorHandler->error(exmsg);
+			_priv->errorHandler->error(exmsg);
 		}
 	}
 
@@ -516,42 +540,42 @@ void RollingFileAppenderSkeleton::subAppend(const LoggingEventPtr& event, Pool&
  * Get rolling policy.
  * @return rolling policy.
  */
-RollingPolicyPtr RollingFileAppenderSkeleton::getRollingPolicy() const
+RollingPolicyPtr RollingFileAppender::getRollingPolicy() const
 {
-	return rollingPolicy;
+	return _priv->rollingPolicy;
 }
 
 /**
  * Get triggering policy.
  * @return triggering policy.
  */
-TriggeringPolicyPtr RollingFileAppenderSkeleton::getTriggeringPolicy() const
+TriggeringPolicyPtr RollingFileAppender::getTriggeringPolicy() const
 {
-	return triggeringPolicy;
+	return _priv->triggeringPolicy;
 }
 
 /**
  * Sets the rolling policy.
  * @param policy rolling policy.
  */
-void RollingFileAppenderSkeleton::setRollingPolicy(const RollingPolicyPtr& policy)
+void RollingFileAppender::setRollingPolicy(const RollingPolicyPtr& policy)
 {
-	rollingPolicy = policy;
+	_priv->rollingPolicy = policy;
 }
 
 /**
  * Set triggering policy.
  * @param policy triggering policy.
  */
-void RollingFileAppenderSkeleton::setTriggeringPolicy(const TriggeringPolicyPtr& policy)
+void RollingFileAppender::setTriggeringPolicy(const TriggeringPolicyPtr& policy)
 {
-	triggeringPolicy = policy;
+	_priv->triggeringPolicy = policy;
 }
 
 /**
  * Close appender.  Waits for any asynchronous file compression actions to be completed.
  */
-void RollingFileAppenderSkeleton::close()
+void RollingFileAppender::close()
 {
 	FileAppender::close();
 }
@@ -575,7 +599,7 @@ class CountingOutputStream : public OutputStream
 		/**
 		 * Rolling file appender to inform of stream writes.
 		 */
-		RollingFileAppenderSkeleton* rfa;
+		RollingFileAppender* rfa;
 
 	public:
 		/**
@@ -584,7 +608,7 @@ class CountingOutputStream : public OutputStream
 		 * @param rfa rolling file appender to inform.
 		 */
 		CountingOutputStream(
-			OutputStreamPtr& os1, RollingFileAppenderSkeleton* rfa1) :
+			OutputStreamPtr& os1, RollingFileAppender* rfa1) :
 			os(os1), rfa(rfa1)
 		{
 		}
@@ -642,7 +666,7 @@ class CountingOutputStream : public OutputStream
  @param os output stream, may not be null.
  @return new writer.
  */
-WriterPtr RollingFileAppenderSkeleton::createWriter(OutputStreamPtr& os)
+WriterPtr RollingFileAppender::createWriter(OutputStreamPtr& os)
 {
 	OutputStreamPtr cos(new CountingOutputStream(os, this));
 	return FileAppender::createWriter(cos);
@@ -652,15 +676,15 @@ WriterPtr RollingFileAppenderSkeleton::createWriter(OutputStreamPtr& os)
  * Get byte length of current active log file.
  * @return byte length of current active log file.
  */
-size_t RollingFileAppenderSkeleton::getFileLength() const
+size_t RollingFileAppender::getFileLength() const
 {
-	return fileLength;
+	return _priv->fileLength;
 }
 
 #ifdef LOG4CXX_MULTI_PROCESS
-void RollingFileAppenderSkeleton::setFileLength(size_t length)
+void RollingFileAppender::setFileLength(size_t length)
 {
-	fileLength = length;
+	_priv->fileLength = length;
 }
 #endif
 
@@ -668,7 +692,7 @@ void RollingFileAppenderSkeleton::setFileLength(size_t length)
  * Increments estimated byte length of current active log file.
  * @param increment additional bytes written to log file.
  */
-void RollingFileAppenderSkeleton::incrementFileLength(size_t increment)
+void RollingFileAppender::incrementFileLength(size_t increment)
 {
-	fileLength += increment;
+	_priv->fileLength += increment;
 }
diff --git a/src/main/cpp/smtpappender.cpp b/src/main/cpp/smtpappender.cpp
index 28ec806..41b6153 100644
--- a/src/main/cpp/smtpappender.cpp
+++ b/src/main/cpp/smtpappender.cpp
@@ -27,7 +27,7 @@
 	#define LOG4CXX 1
 #endif
 #include <log4cxx/private/log4cxx_private.h>
-
+#include <log4cxx/private/appenderskeleton_priv.h>
 
 
 #include <apr_strings.h>
@@ -377,6 +377,40 @@ class LOG4CXX_EXPORT DefaultEvaluator :
 IMPLEMENT_LOG4CXX_OBJECT(DefaultEvaluator)
 IMPLEMENT_LOG4CXX_OBJECT(SMTPAppender)
 
+struct SMTPPriv : public priv::AppenderSkeletonPrivate {
+	SMTPPriv() :
+		priv::AppenderSkeletonPrivate(),
+		smtpPort(25),
+		bufferSize(512),
+		locationInfo(false),
+		cb(bufferSize),
+		evaluator(new DefaultEvaluator()){}
+
+	SMTPPriv(spi::TriggeringEventEvaluatorPtr evaluator) :
+		priv::AppenderSkeletonPrivate(),
+		smtpPort(25),
+		bufferSize(512),
+		locationInfo(false),
+		cb(bufferSize),
+		evaluator(evaluator){}
+
+	LogString to;
+	LogString cc;
+	LogString bcc;
+	LogString from;
+	LogString subject;
+	LogString smtpHost;
+	LogString smtpUsername;
+	LogString smtpPassword;
+	int smtpPort;
+	int bufferSize; // 512
+	bool locationInfo;
+	helpers::CyclicBuffer cb;
+	spi::TriggeringEventEvaluatorPtr evaluator;
+};
+
+#define _priv static_cast<SMTPPriv*>(m_priv.get())
+
 DefaultEvaluator::DefaultEvaluator()
 {
 }
@@ -387,8 +421,7 @@ bool DefaultEvaluator::isTriggeringEvent(const spi::LoggingEventPtr& event)
 }
 
 SMTPAppender::SMTPAppender()
-	: smtpPort(25), bufferSize(512), locationInfo(false), cb(bufferSize),
-	  evaluator(new DefaultEvaluator())
+	: AppenderSkeleton (std::make_unique<SMTPPriv>())
 {
 }
 
@@ -396,8 +429,7 @@ SMTPAppender::SMTPAppender()
 Use <code>evaluator</code> passed as parameter as the
 TriggeringEventEvaluator for this SMTPAppender.  */
 SMTPAppender::SMTPAppender(spi::TriggeringEventEvaluatorPtr evaluator)
-	: smtpPort(25), bufferSize(512), locationInfo(false), cb(bufferSize),
-	  evaluator(evaluator)
+	: AppenderSkeleton (std::make_unique<SMTPPriv>(evaluator))
 {
 }
 
@@ -414,73 +446,73 @@ bool SMTPAppender::requiresLayout() const
 
 LogString SMTPAppender::getFrom() const
 {
-	return from;
+	return _priv->from;
 }
 
 void SMTPAppender::setFrom(const LogString& newVal)
 {
-	from = newVal;
+	_priv->from = newVal;
 }
 
 
 LogString SMTPAppender::getSubject() const
 {
-	return subject;
+	return _priv->subject;
 }
 
 void SMTPAppender::setSubject(const LogString& newVal)
 {
-	subject = newVal;
+	_priv->subject = newVal;
 }
 
 LogString SMTPAppender::getSMTPHost() const
 {
-	return smtpHost;
+	return _priv->smtpHost;
 }
 
 void SMTPAppender::setSMTPHost(const LogString& newVal)
 {
-	smtpHost = newVal;
+	_priv->smtpHost = newVal;
 }
 
 int SMTPAppender::getSMTPPort() const
 {
-	return smtpPort;
+	return _priv->smtpPort;
 }
 
 void SMTPAppender::setSMTPPort(int newVal)
 {
-	smtpPort = newVal;
+	_priv->smtpPort = newVal;
 }
 
 bool SMTPAppender::getLocationInfo() const
 {
-	return locationInfo;
+	return _priv->locationInfo;
 }
 
 void SMTPAppender::setLocationInfo(bool newVal)
 {
-	locationInfo = newVal;
+	_priv->locationInfo = newVal;
 }
 
 LogString SMTPAppender::getSMTPUsername() const
 {
-	return smtpUsername;
+	return _priv->smtpUsername;
 }
 
 void SMTPAppender::setSMTPUsername(const LogString& newVal)
 {
-	smtpUsername = newVal;
+	_priv->smtpUsername = newVal;
 }
 
 LogString SMTPAppender::getSMTPPassword() const
 {
-	return smtpPassword;
+	return _priv->smtpPassword;
 }
 
 void SMTPAppender::setSMTPPassword(const LogString& newVal)
 {
-	smtpPassword = newVal;
+	_priv->smtpPassword = newVal;
 }
 
 
@@ -564,40 +596,40 @@ void SMTPAppender::activateOptions(Pool& p)
 {
 	bool activate = true;
 
-	if (layout == 0)
+	if (_priv->layout == 0)
 	{
-		errorHandler->error(LOG4CXX_STR("No layout set for appender named [") + name + LOG4CXX_STR("]."));
+		_priv->errorHandler->error(LOG4CXX_STR("No layout set for appender named [") + _priv->name + LOG4CXX_STR("]."));
 		activate = false;
 	}
 
-	if (evaluator == 0)
+	if (_priv->evaluator == 0)
 	{
-		errorHandler->error(LOG4CXX_STR("No TriggeringEventEvaluator is set for appender [") +
-			name + LOG4CXX_STR("]."));
+		_priv->errorHandler->error(LOG4CXX_STR("No TriggeringEventEvaluator is set for appender [") +
+			_priv->name + LOG4CXX_STR("]."));
 		activate = false;
 	}
 
-	if (smtpHost.empty())
+	if (_priv->smtpHost.empty())
 	{
-		errorHandler->error(LOG4CXX_STR("No smtpHost is set for appender [") +
-			name + LOG4CXX_STR("]."));
+		_priv->errorHandler->error(LOG4CXX_STR("No smtpHost is set for appender [") +
+			_priv->name + LOG4CXX_STR("]."));
 		activate = false;
 	}
 
-	if (to.empty() && cc.empty() && bcc.empty())
+	if (_priv->to.empty() && _priv->cc.empty() && _priv->bcc.empty())
 	{
-		errorHandler->error(LOG4CXX_STR("No recipient address is set for appender [") +
-			name + LOG4CXX_STR("]."));
+		_priv->errorHandler->error(LOG4CXX_STR("No recipient address is set for appender [") +
+			_priv->name + LOG4CXX_STR("]."));
 		activate = false;
 	}
 
-	activate &= asciiCheck(to, LOG4CXX_STR("to"));
-	activate &= asciiCheck(cc, LOG4CXX_STR("cc"));
-	activate &= asciiCheck(bcc, LOG4CXX_STR("bcc"));
-	activate &= asciiCheck(from, LOG4CXX_STR("from"));
+	activate &= asciiCheck(_priv->to, LOG4CXX_STR("to"));
+	activate &= asciiCheck(_priv->cc, LOG4CXX_STR("cc"));
+	activate &= asciiCheck(_priv->bcc, LOG4CXX_STR("bcc"));
+	activate &= asciiCheck(_priv->from, LOG4CXX_STR("from"));
 
 #if !LOG4CXX_HAVE_LIBESMTP
-	errorHandler->error(LOG4CXX_STR("log4cxx built without SMTP support."));
+	_priv->errorHandler->error(LOG4CXX_STR("log4cxx built without SMTP support."));
 	activate = false;
 #endif
 
@@ -624,9 +656,9 @@ void SMTPAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 	// Get a copy of this thread's MDC.
 	event->getMDCCopy();
 
-	cb.add(event);
+	_priv->cb.add(event);
 
-	if (evaluator->isTriggeringEvent(event))
+	if (_priv->evaluator->isTriggeringEvent(event))
 	{
 		sendBuffer(p);
 	}
@@ -671,37 +703,37 @@ bool SMTPAppender::checkEntryConditions()
 
 void SMTPAppender::close()
 {
-	this->closed = true;
+	_priv->closed = true;
 }
 
 LogString SMTPAppender::getTo() const
 {
-	return to;
+	return _priv->to;
 }
 
 void SMTPAppender::setTo(const LogString& addressStr)
 {
-	to = addressStr;
+	_priv->to = addressStr;
 }
 
 LogString SMTPAppender::getCc() const
 {
-	return cc;
+	return _priv->cc;
 }
 
 void SMTPAppender::setCc(const LogString& addressStr)
 {
-	cc = addressStr;
+	_priv->cc = addressStr;
 }
 
 LogString SMTPAppender::getBcc() const
 {
-	return bcc;
+	return _priv->bcc;
 }
 
 void SMTPAppender::setBcc(const LogString& addressStr)
 {
-	bcc = addressStr;
+	_priv->bcc = addressStr;
 }
 
 /**
@@ -749,17 +781,17 @@ Returns value of the <b>EvaluatorClass</b> option.
 */
 LogString SMTPAppender::getEvaluatorClass()
 {
-	return evaluator == 0 ? LogString() : evaluator->getClass().getName();
+	return _priv->evaluator == 0 ? LogString() : _priv->evaluator->getClass().getName();
 }
 
 log4cxx::spi::TriggeringEventEvaluatorPtr SMTPAppender::getEvaluator() const
 {
-	return evaluator;
+	return _priv->evaluator;
 }
 
 void SMTPAppender::setEvaluator(log4cxx::spi::TriggeringEventEvaluatorPtr& trigger)
 {
-	evaluator = trigger;
+	_priv->evaluator = trigger;
 }
 
 /**
@@ -771,8 +803,8 @@ buffer. By default the size of the cyclic buffer is 512 events.
 */
 void SMTPAppender::setBufferSize(int sz)
 {
-	this->bufferSize = sz;
-	cb.resize(sz);
+	_priv->bufferSize = sz;
+	_priv->cb.resize(sz);
 }
 
 /**
@@ -785,6 +817,9 @@ for the SMTPAppender.
 void SMTPAppender::setEvaluatorClass(const LogString& value)
 {
 	ObjectPtr obj = ObjectPtr(Loader::loadClass(value).newInstance());
-	evaluator = log4cxx::cast<TriggeringEventEvaluator>(obj);
+	_priv->evaluator = log4cxx::cast<TriggeringEventEvaluator>(obj);
 }
 
+int SMTPAppender::getBufferSize() const{
+
+}
diff --git a/src/main/cpp/socketappender.cpp b/src/main/cpp/socketappender.cpp
index 57f8ade..d2d987c 100644
--- a/src/main/cpp/socketappender.cpp
+++ b/src/main/cpp/socketappender.cpp
@@ -78,53 +78,53 @@ int SocketAppender::getDefaultPort() const
 
 void SocketAppender::setSocket(log4cxx::helpers::SocketPtr& socket, Pool& p)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+//	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
 
-	SocketOutputStreamPtr sock = SocketOutputStreamPtr(new SocketOutputStream(socket));
-	oos = ObjectOutputStreamPtr(new ObjectOutputStream(sock, p));
+//	SocketOutputStreamPtr sock = SocketOutputStreamPtr(new SocketOutputStream(socket));
+//	oos = ObjectOutputStreamPtr(new ObjectOutputStream(sock, p));
 }
 
 void SocketAppender::cleanUp(Pool& p)
 {
-	if (oos == 0)
-	{
-		return;
-	}
-
-	try
-	{
-		oos->close(p);
-		oos = 0;
-	}
-	catch (std::exception&)
-	{}
+//	if (oos == 0)
+//	{
+//		return;
+//	}
+
+//	try
+//	{
+//		oos->close(p);
+//		oos = 0;
+//	}
+//	catch (std::exception&)
+//	{}
 }
 
 void SocketAppender::append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p)
 {
-	if (oos == 0)
-	{
-		return;
-	}
-
-	LogString ndcVal;
-	event->getNDC(ndcVal);
-	event->getThreadName();
-	event->getMDCCopy();
-
-	try
-	{
-		event->write(*oos, p);
-		oos->reset(p);
-	}
-	catch (std::exception& e)
-	{
-		oos = 0;
-		LogLog::warn(LOG4CXX_STR("Detected problem with connection: "), e);
-
-		if (getReconnectionDelay() > 0)
-		{
-			fireConnector();
-		}
-	}
+//	if (oos == 0)
+//	{
+//		return;
+//	}
+
+//	LogString ndcVal;
+//	event->getNDC(ndcVal);
+//	event->getThreadName();
+//	event->getMDCCopy();
+
+//	try
+//	{
+//		event->write(*oos, p);
+//		oos->reset(p);
+//	}
+//	catch (std::exception& e)
+//	{
+//		oos = 0;
+//		LogLog::warn(LOG4CXX_STR("Detected problem with connection: "), e);
+
+//		if (getReconnectionDelay() > 0)
+//		{
+//			fireConnector();
+//		}
+//	}
 }
diff --git a/src/main/cpp/socketappenderskeleton.cpp b/src/main/cpp/socketappenderskeleton.cpp
index e3e1375..c1d6beb 100644
--- a/src/main/cpp/socketappenderskeleton.cpp
+++ b/src/main/cpp/socketappenderskeleton.cpp
@@ -27,41 +27,75 @@
 #include <log4cxx/helpers/transcoder.h>
 #include <log4cxx/helpers/bytearrayoutputstream.h>
 #include <log4cxx/helpers/threadutility.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
 #include <functional>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 using namespace log4cxx::net;
 
+struct SocketAppenderSkeletonPriv : public priv::AppenderSkeletonPrivate {
+	SocketAppenderSkeletonPriv(int defaultPort, int reconnectionDelay) :
+		AppenderSkeletonPrivate(),
+		remoteHost(),
+		address(),
+		port(defaultPort),
+		reconnectionDelay(reconnectionDelay),
+		locationInfo(false),
+		thread(){}
+
+	SocketAppenderSkeletonPriv(InetAddressPtr address, int defaultPort, int reconnectionDelay) :
+		AppenderSkeletonPrivate(),
+		remoteHost(),
+		address(address),
+		port(defaultPort),
+		reconnectionDelay(reconnectionDelay),
+		locationInfo(false),
+		thread(){}
+
+	SocketAppenderSkeletonPriv(const LogString& host, int port, int delay) :
+		AppenderSkeletonPrivate(),
+		remoteHost(host),
+		address(InetAddress::getByName(host)),
+		port(port),
+		reconnectionDelay(delay),
+		locationInfo(false),
+		thread(){}
+
+	/**
+	host name
+	*/
+	LogString remoteHost;
+
+	/**
+	IP address
+	*/
+	helpers::InetAddressPtr address;
+
+	int port;
+	int reconnectionDelay;
+	bool locationInfo;
+	std::thread thread;
+	std::condition_variable interrupt;
+	std::mutex interrupt_mutex;
+};
+
+#define _priv static_cast<SocketAppenderSkeletonPriv*>(m_priv.get())
+
 SocketAppenderSkeleton::SocketAppenderSkeleton(int defaultPort, int reconnectionDelay1)
-	:  remoteHost(),
-	   address(),
-	   port(defaultPort),
-	   reconnectionDelay(reconnectionDelay1),
-	   locationInfo(false),
-	   thread()
+	:  AppenderSkeleton (std::make_unique<SocketAppenderSkeletonPriv>(defaultPort, reconnectionDelay1))
 {
 }
 
 SocketAppenderSkeleton::SocketAppenderSkeleton(InetAddressPtr address1, int port1, int delay)
-	:
-	remoteHost(),
-	address(address1),
-	port(port1),
-	reconnectionDelay(delay),
-	locationInfo(false),
-	thread()
+	:AppenderSkeleton (std::make_unique<SocketAppenderSkeletonPriv>(address1, port1, delay))
+
 {
-	remoteHost = this->address->getHostName();
+	_priv->remoteHost = _priv->address->getHostName();
 }
 
 SocketAppenderSkeleton::SocketAppenderSkeleton(const LogString& host, int port1, int delay)
-	:   remoteHost(host),
-		address(InetAddress::getByName(host)),
-		port(port1),
-		reconnectionDelay(delay),
-		locationInfo(false),
-		thread()
+	:   AppenderSkeleton (std::make_unique<SocketAppenderSkeletonPriv>(host, port1, delay))
 {
 }
 
@@ -78,33 +112,33 @@ void SocketAppenderSkeleton::activateOptions(Pool& p)
 
 void SocketAppenderSkeleton::close()
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
-	if (closed)
+	if (_priv->closed)
 	{
 		return;
 	}
 
-	closed = true;
-	cleanUp(pool);
+	_priv->closed = true;
+	cleanUp(_priv->pool);
 
 	{
-		std::unique_lock<std::mutex> lock2(interrupt_mutex);
-		interrupt.notify_all();
+		std::unique_lock<std::mutex> lock2(_priv->interrupt_mutex);
+		_priv->interrupt.notify_all();
 	}
 
-	if ( thread.joinable() )
+	if ( _priv->thread.joinable() )
 	{
-		thread.join();
+		_priv->thread.join();
 	}
 }
 
 void SocketAppenderSkeleton::connect(Pool& p)
 {
-	if (address == 0)
+	if (_priv->address == 0)
 	{
 		LogLog::error(LogString(LOG4CXX_STR("No remote host is set for Appender named \"")) +
-			name + LOG4CXX_STR("\"."));
+			_priv->name + LOG4CXX_STR("\"."));
 	}
 	else
 	{
@@ -112,15 +146,15 @@ void SocketAppenderSkeleton::connect(Pool& p)
 
 		try
 		{
-			SocketPtr socket(new Socket(address, port));
+			SocketPtr socket(new Socket(_priv->address, _priv->port));
 			setSocket(socket, p);
 		}
 		catch (SocketException& e)
 		{
 			LogString msg = LOG4CXX_STR("Could not connect to remote log4cxx server at [")
-				+ address->getHostName() + LOG4CXX_STR("].");
+				+ _priv->address->getHostName() + LOG4CXX_STR("].");
 
-			if (reconnectionDelay > 0)
+			if (_priv->reconnectionDelay > 0)
 			{
 				msg += LOG4CXX_STR(" We will try again later. ");
 			}
@@ -157,36 +191,36 @@ void SocketAppenderSkeleton::setOption(const LogString& option, const LogString&
 
 void SocketAppenderSkeleton::fireConnector()
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
-	if ( !thread.joinable() )
+	if ( !_priv->thread.joinable() )
 	{
 		LogLog::debug(LOG4CXX_STR("Connector thread not alive: starting monitor."));
 
-		thread = ThreadUtility::instance()->createThread( LOG4CXX_STR("SocketAppend"), &SocketAppenderSkeleton::monitor, this );
+		_priv->thread = ThreadUtility::instance()->createThread( LOG4CXX_STR("SocketAppend"), &SocketAppenderSkeleton::monitor, this );
 	}
 }
 
 void SocketAppenderSkeleton::monitor()
 {
 	SocketPtr socket;
-	bool isClosed = closed;
+	bool isClosed = _priv->closed;
 
 	while (!isClosed)
 	{
 		try
 		{
-			std::this_thread::sleep_for( std::chrono::milliseconds( reconnectionDelay ) );
+			std::this_thread::sleep_for( std::chrono::milliseconds( _priv->reconnectionDelay ) );
 
-			std::unique_lock<std::mutex> lock( interrupt_mutex );
-			interrupt.wait_for( lock, std::chrono::milliseconds( reconnectionDelay ),
+			std::unique_lock<std::mutex> lock( _priv->interrupt_mutex );
+			_priv->interrupt.wait_for( lock, std::chrono::milliseconds( _priv->reconnectionDelay ),
 				std::bind(&SocketAppenderSkeleton::is_closed, this) );
 
-			if (!closed)
+			if (!_priv->closed)
 			{
 				LogLog::debug(LogString(LOG4CXX_STR("Attempting connection to "))
-					+ address->getHostName());
-				socket = SocketPtr(new Socket(address, port));
+					+ _priv->address->getHostName());
+				socket = SocketPtr(new Socket(_priv->address, _priv->port));
 				Pool p;
 				setSocket(socket, p);
 				LogLog::debug(LOG4CXX_STR("Connection established. Exiting connector thread."));
@@ -202,7 +236,7 @@ void SocketAppenderSkeleton::monitor()
 		catch (ConnectException&)
 		{
 			LogLog::debug(LOG4CXX_STR("Remote host ")
-				+ address->getHostName()
+				+ _priv->address->getHostName()
 				+ LOG4CXX_STR(" refused connection."));
 		}
 		catch (IOException& e)
@@ -211,12 +245,12 @@ void SocketAppenderSkeleton::monitor()
 			log4cxx::helpers::Transcoder::decode(e.what(), exmsg);
 
 			LogLog::debug(((LogString) LOG4CXX_STR("Could not connect to "))
-				+ address->getHostName()
+				+ _priv->address->getHostName()
 				+ LOG4CXX_STR(". Exception is ")
 				+ exmsg);
 		}
 
-		isClosed = closed;
+		isClosed = _priv->closed;
 	}
 
 	LogLog::debug(LOG4CXX_STR("Exiting Connector.run() method."));
@@ -224,5 +258,46 @@ void SocketAppenderSkeleton::monitor()
 
 bool SocketAppenderSkeleton::is_closed()
 {
-	return closed;
+	return _priv->closed;
+}
+
+void SocketAppenderSkeleton::setRemoteHost(const LogString& host)
+{
+	_priv->address = helpers::InetAddress::getByName(host);
+	_priv->remoteHost.assign(host);
+}
+
+const LogString& SocketAppenderSkeleton::getRemoteHost() const
+{
+	return _priv->remoteHost;
+}
+
+void SocketAppenderSkeleton::setPort(int port1)
+{
+	_priv->port = port1;
+}
+
+int SocketAppenderSkeleton::getPort() const
+{
+	return _priv->port;
+}
+
+void SocketAppenderSkeleton::setLocationInfo(bool locationInfo1)
+{
+	_priv->locationInfo = locationInfo1;
+}
+
+bool SocketAppenderSkeleton::getLocationInfo() const
+{
+	return _priv->locationInfo;
+}
+
+void SocketAppenderSkeleton::setReconnectionDelay(int reconnectionDelay1)
+{
+	_priv->reconnectionDelay = reconnectionDelay1;
+}
+
+int SocketAppenderSkeleton::getReconnectionDelay() const
+{
+	return _priv->reconnectionDelay;
 }
diff --git a/src/main/cpp/sockethubappender.cpp b/src/main/cpp/sockethubappender.cpp
index 7d83a23..15ec6d1 100644
--- a/src/main/cpp/sockethubappender.cpp
+++ b/src/main/cpp/sockethubappender.cpp
@@ -31,6 +31,7 @@
 #include <log4cxx/helpers/socketoutputstream.h>
 #include <log4cxx/helpers/exception.h>
 #include <log4cxx/helpers/threadutility.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
 #include <mutex>
 
 using namespace log4cxx;
@@ -42,18 +43,34 @@ IMPLEMENT_LOG4CXX_OBJECT(SocketHubAppender)
 
 int SocketHubAppender::DEFAULT_PORT = 4560;
 
+struct SocketHubAppenderPriv : public priv::AppenderSkeletonPrivate{
+	SocketHubAppenderPriv(int port) :
+		AppenderSkeletonPrivate(),
+		port(port),
+		streams(),
+		locationInfo(false),
+		thread(){}
+
+	int port;
+	ObjectOutputStreamList streams;
+	bool locationInfo;
+	std::thread thread;
+};
+
+#define _priv static_cast<SocketHubAppenderPriv*>(m_priv.get())
+
 SocketHubAppender::~SocketHubAppender()
 {
 	finalize();
 }
 
 SocketHubAppender::SocketHubAppender()
-	: port(DEFAULT_PORT), streams(), locationInfo(false), thread()
+	:AppenderSkeleton (std::make_unique<SocketHubAppenderPriv>(SocketHubAppender::DEFAULT_PORT))
 {
 }
 
 SocketHubAppender::SocketHubAppender(int port1)
-	: port(port1), streams(), locationInfo(false), thread()
+	: AppenderSkeleton (std::make_unique<SocketHubAppenderPriv>(port1))
 {
 	startServer();
 }
@@ -84,14 +101,14 @@ void SocketHubAppender::setOption(const LogString& option,
 void SocketHubAppender::close()
 {
 	{
-		std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+		std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
-		if (closed)
+		if (_priv->closed)
 		{
 			return;
 		}
 
-		closed = true;
+		_priv->closed = true;
 	}
 
 	LogLog::debug(LOG4CXX_STR("closing SocketHubAppender ") + getName());
@@ -99,24 +116,24 @@ void SocketHubAppender::close()
 	//
 	//  wait until the server thread completes
 	//
-	if ( thread.joinable() )
+	if ( _priv->thread.joinable() )
 	{
-		thread.join();
+		_priv->thread.join();
 	}
 
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 	// close all of the connections
 	LogLog::debug(LOG4CXX_STR("closing client connections"));
 
-	for (std::vector<helpers::ObjectOutputStreamPtr>::iterator iter = streams.begin();
-		iter != streams.end();
+	for (std::vector<helpers::ObjectOutputStreamPtr>::iterator iter = _priv->streams.begin();
+		iter != _priv->streams.end();
 		iter++)
 	{
 		if ( (*iter) != NULL)
 		{
 			try
 			{
-				(*iter)->close(pool);
+				(*iter)->close(_priv->pool);
 			}
 			catch (SocketException& e)
 			{
@@ -125,7 +142,7 @@ void SocketHubAppender::close()
 		}
 	}
 
-	streams.erase(streams.begin(), streams.end());
+	_priv->streams.erase(_priv->streams.begin(), _priv->streams.end());
 
 
 	LogLog::debug(LOG4CXX_STR("SocketHubAppender ")
@@ -136,7 +153,7 @@ void SocketHubAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 {
 
 	// if no open connections, exit now
-	if (streams.empty())
+	if (_priv->streams.empty())
 	{
 		return;
 	}
@@ -149,8 +166,8 @@ void SocketHubAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 
 
 	// loop through the current set of open connections, appending the event to each
-	std::vector<ObjectOutputStreamPtr>::iterator it = streams.begin();
-	std::vector<ObjectOutputStreamPtr>::iterator itEnd = streams.end();
+	std::vector<ObjectOutputStreamPtr>::iterator it = _priv->streams.begin();
+	std::vector<ObjectOutputStreamPtr>::iterator itEnd = _priv->streams.end();
 
 	while (it != itEnd)
 	{
@@ -169,8 +186,8 @@ void SocketHubAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 		catch (std::exception& e)
 		{
 			// there was an io exception so just drop the connection
-			it = streams.erase(it);
-			itEnd = streams.end();
+			it = _priv->streams.erase(it);
+			itEnd = _priv->streams.end();
 			LogLog::debug(LOG4CXX_STR("dropped connection"), e);
 		}
 	}
@@ -178,7 +195,7 @@ void SocketHubAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 
 void SocketHubAppender::startServer()
 {
-	thread = ThreadUtility::instance()->createThread( LOG4CXX_STR("SocketHub"), &SocketHubAppender::monitor, this );
+	_priv->thread = ThreadUtility::instance()->createThread( LOG4CXX_STR("SocketHub"), &SocketHubAppender::monitor, this );
 }
 
 void SocketHubAppender::monitor()
@@ -187,7 +204,7 @@ void SocketHubAppender::monitor()
 
 	try
 	{
-		serverSocket = new ServerSocket(port);
+		serverSocket = new ServerSocket(_priv->port);
 		serverSocket->setSoTimeout(1000);
 	}
 	catch (SocketException& e)
@@ -197,7 +214,7 @@ void SocketHubAppender::monitor()
 		return;
 	}
 
-	bool stopRunning = closed;
+	bool stopRunning = _priv->closed;
 
 	while (!stopRunning)
 	{
@@ -234,11 +251,11 @@ void SocketHubAppender::monitor()
 					+ LOG4CXX_STR(")"));
 
 				// add it to the oosList.
-				std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+				std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 				OutputStreamPtr os(new SocketOutputStream(socket));
 				Pool p;
 				ObjectOutputStreamPtr oos(new ObjectOutputStream(os, p));
-				streams.push_back(oos);
+				_priv->streams.push_back(oos);
 			}
 			catch (IOException& e)
 			{
@@ -246,8 +263,28 @@ void SocketHubAppender::monitor()
 			}
 		}
 
-		stopRunning = (stopRunning || closed);
+		stopRunning = (stopRunning || _priv->closed);
 	}
 
 	delete serverSocket;
 }
+
+void SocketHubAppender::setPort(int port1)
+{
+	_priv->port = port1;
+}
+
+int SocketHubAppender::getPort() const
+{
+	return _priv->port;
+}
+
+void SocketHubAppender::setLocationInfo(bool locationInfo1)
+{
+	_priv->locationInfo = locationInfo1;
+}
+
+bool SocketHubAppender::getLocationInfo() const
+{
+	return _priv->locationInfo;
+}
diff --git a/src/main/cpp/syslogappender.cpp b/src/main/cpp/syslogappender.cpp
index 99d91f6..527d855 100644
--- a/src/main/cpp/syslogappender.cpp
+++ b/src/main/cpp/syslogappender.cpp
@@ -26,36 +26,8 @@
 #if !defined(LOG4CXX)
 	#define LOG4CXX 1
 #endif
-#include <log4cxx/private/log4cxx_private.h>
 #include <apr_strings.h>
-
-#if LOG4CXX_HAVE_SYSLOG
-	#include <syslog.h>
-#else
-	/* facility codes */
-	#define   LOG_KERN (0<<3)   /* kernel messages */
-	#define   LOG_USER (1<<3)   /* random user-level messages */
-	#define   LOG_MAIL (2<<3)   /* mail system */
-	#define   LOG_DAEMON  (3<<3)   /* system daemons */
-	#define   LOG_AUTH (4<<3)   /* security/authorization messages */
-	#define   LOG_SYSLOG  (5<<3)   /* messages generated internally by syslogd */
-	#define   LOG_LPR     (6<<3)   /* line printer subsystem */
-	#define   LOG_NEWS (7<<3)   /* network news subsystem */
-	#define   LOG_UUCP (8<<3)   /* UUCP subsystem */
-	#define   LOG_CRON (9<<3)   /* clock daemon */
-	#define   LOG_AUTHPRIV   (10<<3)  /* security/authorization messages (private) */
-	#define   LOG_FTP     (11<<3)  /* ftp daemon */
-
-	/* other codes through 15 reserved for system use */
-	#define   LOG_LOCAL0  (16<<3)  /* reserved for local use */
-	#define   LOG_LOCAL1  (17<<3)  /* reserved for local use */
-	#define   LOG_LOCAL2  (18<<3)  /* reserved for local use */
-	#define   LOG_LOCAL3  (19<<3)  /* reserved for local use */
-	#define   LOG_LOCAL4  (20<<3)  /* reserved for local use */
-	#define   LOG_LOCAL5  (21<<3)  /* reserved for local use */
-	#define   LOG_LOCAL6  (22<<3)  /* reserved for local use */
-	#define   LOG_LOCAL7  (23<<3)  /* reserved for local use */
-#endif
+#include <log4cxx/private/syslogappender_priv.h>
 
 #define LOG_UNDEF -1
 
@@ -65,8 +37,10 @@ using namespace log4cxx::net;
 
 IMPLEMENT_LOG4CXX_OBJECT(SyslogAppender)
 
+#define _priv static_cast<priv::SyslogAppenderPriv*>(m_priv.get())
+
 SyslogAppender::SyslogAppender()
-	: syslogFacility(LOG_USER), facilityPrinting(false), sw(0), maxMessageLength(1024)
+	: AppenderSkeleton (std::make_unique<priv::SyslogAppenderPriv>())
 {
 	this->initSyslogFacilityStr();
 
@@ -74,17 +48,15 @@ SyslogAppender::SyslogAppender()
 
 SyslogAppender::SyslogAppender(const LayoutPtr& layout1,
 	int syslogFacility1)
-	: syslogFacility(syslogFacility1), facilityPrinting(false), sw(0), maxMessageLength(1024)
+	: AppenderSkeleton (std::make_unique<priv::SyslogAppenderPriv>(layout1, syslogFacility1))
 {
-	this->layout = layout1;
 	this->initSyslogFacilityStr();
 }
 
 SyslogAppender::SyslogAppender(const LayoutPtr& layout1,
 	const LogString& syslogHost1, int syslogFacility1)
-	: syslogFacility(syslogFacility1), facilityPrinting(false), sw(0), maxMessageLength(1024)
+	: AppenderSkeleton (std::make_unique<priv::SyslogAppenderPriv>(layout1, syslogHost1, syslogFacility1))
 {
-	this->layout = layout1;
 	this->initSyslogFacilityStr();
 	setSyslogHost(syslogHost1);
 }
@@ -97,32 +69,31 @@ SyslogAppender::~SyslogAppender()
 /** Release any resources held by this SyslogAppender.*/
 void SyslogAppender::close()
 {
-	closed = true;
+	_priv->closed = true;
 
-	if (sw != 0)
+	if (_priv->sw)
 	{
-		delete sw;
-		sw = 0;
+		_priv->sw = nullptr;
 	}
 }
 
 void SyslogAppender::initSyslogFacilityStr()
 {
-	facilityStr = getFacilityString(this->syslogFacility);
+	_priv->facilityStr = getFacilityString(_priv->syslogFacility);
 
-	if (facilityStr.empty())
+	if (_priv->facilityStr.empty())
 	{
 		Pool p;
 		LogString msg(LOG4CXX_STR("\""));
-		StringHelper::toString(syslogFacility, p, msg);
+		StringHelper::toString(_priv->syslogFacility, p, msg);
 		msg.append(LOG4CXX_STR("\" is an unknown syslog facility. Defaulting to \"USER\"."));
 		LogLog::error(msg);
-		this->syslogFacility = LOG_USER;
-		facilityStr = LOG4CXX_STR("user:");
+		_priv->syslogFacility = LOG_USER;
+		_priv->facilityStr = LOG4CXX_STR("user:");
 	}
 	else
 	{
-		facilityStr += LOG4CXX_STR(":");
+		_priv->facilityStr += LOG4CXX_STR(":");
 	}
 }
 
@@ -309,7 +280,7 @@ void SyslogAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 
 	LogString msg;
 	std::string encoded;
-	layout->format(msg, event, p);
+	_priv->layout->format(msg, event, p);
 
 	Transcoder::encode(msg, encoded);
 
@@ -320,13 +291,13 @@ void SyslogAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 	// to indicate how far through the message we are
 	std::vector<LogString> packets;
 
-	if ( msg.size() > maxMessageLength )
+	if ( msg.size() > _priv->maxMessageLength )
 	{
 		LogString::iterator start = msg.begin();
 
 		while ( start != msg.end() )
 		{
-			LogString::iterator end = start + maxMessageLength - 12;
+			LogString::iterator end = start + _priv->maxMessageLength - 12;
 
 			if ( end > msg.end() )
 			{
@@ -359,14 +330,14 @@ void SyslogAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 	// if it is available
 #if LOG4CXX_HAVE_SYSLOG
 
-	if (sw == 0)
+	if (_priv->sw == 0)
 	{
 		for ( std::vector<LogString>::iterator it = packets.begin();
 			it != packets.end();
 			it++ )
 		{
 			// use of "%s" to avoid a security hole
-			::syslog(syslogFacility | event->getLevel()->getSyslogEquivalent(),
+			::syslog(_priv->syslogFacility | event->getLevel()->getSyslogEquivalent(),
 				"%s", it->c_str());
 		}
 
@@ -376,10 +347,10 @@ void SyslogAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 #endif
 
 	// We must not attempt to append if sw is null.
-	if (sw == 0)
+	if (_priv->sw == 0)
 	{
-		errorHandler->error(LOG4CXX_STR("No syslog host is set for SyslogAppedender named \"") +
-			this->name + LOG4CXX_STR("\"."));
+		_priv->errorHandler->error(LOG4CXX_STR("No syslog host is set for SyslogAppedender named \"") +
+			_priv->name + LOG4CXX_STR("\"."));
 		return;
 	}
 
@@ -388,16 +359,16 @@ void SyslogAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 		it++ )
 	{
 		LogString sbuf(1, 0x3C /* '<' */);
-		StringHelper::toString((syslogFacility | event->getLevel()->getSyslogEquivalent()), p, sbuf);
+		StringHelper::toString((_priv->syslogFacility | event->getLevel()->getSyslogEquivalent()), p, sbuf);
 		sbuf.append(1, (logchar) 0x3E /* '>' */);
 
-		if (facilityPrinting)
+		if (_priv->facilityPrinting)
 		{
-			sbuf.append(facilityStr);
+			sbuf.append(_priv->facilityStr);
 		}
 
 		sbuf.append(*it);
-		sw->write(sbuf);
+		_priv->sw->write(sbuf);
 	}
 }
 
@@ -427,10 +398,9 @@ void SyslogAppender::setOption(const LogString& option, const LogString& value)
 
 void SyslogAppender::setSyslogHost(const LogString& syslogHost1)
 {
-	if (this->sw != 0)
+	if (_priv->sw != 0)
 	{
-		delete this->sw;
-		this->sw = 0;
+		_priv->sw = nullptr;
 	}
 
 	LogString slHost = syslogHost1;
@@ -455,15 +425,15 @@ void SyslogAppender::setSyslogHost(const LogString& syslogHost1)
 #endif
 		if (slHostPort >= 0)
 		{
-			this->sw = new SyslogWriter(slHost, slHostPort);
+			_priv->sw = std::make_unique<SyslogWriter>(slHost, slHostPort);
 		}
 		else
 		{
-			this->sw = new SyslogWriter(slHost);
+			_priv->sw = std::make_unique<SyslogWriter>(slHost);
 		}
 
-	this->syslogHost = slHost;
-	this->syslogHostPort = slHostPort;
+	_priv->syslogHost = slHost;
+	_priv->syslogHostPort = slHostPort;
 }
 
 
@@ -474,15 +444,45 @@ void SyslogAppender::setFacility(const LogString& facilityName)
 		return;
 	}
 
-	syslogFacility = getFacility(facilityName);
+	_priv->syslogFacility = getFacility(facilityName);
 
-	if (syslogFacility == LOG_UNDEF)
+	if (_priv->syslogFacility == LOG_UNDEF)
 	{
 		LogLog::error(LOG4CXX_STR("[") + facilityName +
 			LOG4CXX_STR("] is an unknown syslog facility. Defaulting to [USER]."));
-		syslogFacility = LOG_USER;
+		_priv->syslogFacility = LOG_USER;
 	}
 
 	this->initSyslogFacilityStr();
 }
 
+const LogString& SyslogAppender::getSyslogHost() const
+{
+	return _priv->syslogHost;
+}
+
+LogString SyslogAppender::getFacility() const
+{
+	return getFacilityString(_priv->syslogFacility);
+}
+
+void SyslogAppender::setFacilityPrinting(bool facilityPrinting1)
+{
+	_priv->facilityPrinting = facilityPrinting1;
+}
+
+bool SyslogAppender::getFacilityPrinting() const
+{
+	return _priv->facilityPrinting;
+}
+
+void SyslogAppender::setMaxMessageLength(int maxMessageLength1)
+{
+	_priv->maxMessageLength = maxMessageLength1;
+}
+
+int SyslogAppender::getMaxMessageLength() const
+{
+	return _priv->maxMessageLength;
+}
+
diff --git a/src/main/cpp/telnetappender.cpp b/src/main/cpp/telnetappender.cpp
index 9087242..8071937 100644
--- a/src/main/cpp/telnetappender.cpp
+++ b/src/main/cpp/telnetappender.cpp
@@ -25,6 +25,7 @@
 #include <log4cxx/helpers/charsetencoder.h>
 #include <log4cxx/helpers/bytebuffer.h>
 #include <log4cxx/helpers/threadutility.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
 #include <mutex>
 
 using namespace log4cxx;
@@ -33,6 +34,26 @@ using namespace log4cxx::net;
 
 IMPLEMENT_LOG4CXX_OBJECT(TelnetAppender)
 
+struct TelnetAppenderPriv : public priv::AppenderSkeletonPrivate{
+	TelnetAppenderPriv( int port, int maxConnections ) : AppenderSkeletonPrivate(),
+		port(port),
+		connections(maxConnections),
+		encoding(LOG4CXX_STR("UTF-8")),
+		encoder(CharsetEncoder::getUTF8Encoder()),
+		sh(),
+		activeConnections(0){}
+
+	int port;
+	ConnectionList connections;
+	LogString encoding;
+	log4cxx::helpers::CharsetEncoderPtr encoder;
+	std::unique_ptr<helpers::ServerSocket> serverSocket;
+	std::thread sh;
+	size_t activeConnections;
+};
+
+#define _priv static_cast<TelnetAppenderPriv*>(m_priv.get())
+
 /** The default telnet server port */
 const int TelnetAppender::DEFAULT_PORT = 23;
 
@@ -40,29 +61,24 @@ const int TelnetAppender::DEFAULT_PORT = 23;
 const int TelnetAppender::MAX_CONNECTIONS = 20;
 
 TelnetAppender::TelnetAppender()
-	: port(DEFAULT_PORT), connections(MAX_CONNECTIONS),
-	  encoding(LOG4CXX_STR("UTF-8")),
-	  encoder(CharsetEncoder::getUTF8Encoder()),
-	  serverSocket(NULL), sh()
+	: AppenderSkeleton (std::make_unique<TelnetAppenderPriv>(DEFAULT_PORT,MAX_CONNECTIONS))
 {
-	activeConnections = 0;
 }
 
 TelnetAppender::~TelnetAppender()
 {
 	finalize();
-	delete serverSocket;
 }
 
 void TelnetAppender::activateOptions(Pool& /* p */)
 {
-	if (serverSocket == NULL)
+	if (_priv->serverSocket == NULL)
 	{
-		serverSocket = new ServerSocket(port);
-		serverSocket->setSoTimeout(1000);
+		_priv->serverSocket = std::make_unique<ServerSocket>(_priv->port);
+		_priv->serverSocket->setSoTimeout(1000);
 	}
 
-	sh = ThreadUtility::instance()->createThread( LOG4CXX_STR("TelnetAppender"), &TelnetAppender::acceptConnections, this );
+	_priv->sh = ThreadUtility::instance()->createThread( LOG4CXX_STR("TelnetAppender"), &TelnetAppender::acceptConnections, this );
 }
 
 void TelnetAppender::setOption(const LogString& option,
@@ -84,33 +100,33 @@ void TelnetAppender::setOption(const LogString& option,
 
 LogString TelnetAppender::getEncoding() const
 {
-	log4cxx::shared_lock<log4cxx::shared_mutex> lock(mutex);
-	return encoding;
+	log4cxx::shared_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+	return _priv->encoding;
 }
 
 void TelnetAppender::setEncoding(const LogString& value)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	encoder = CharsetEncoder::getEncoder(value);
-	encoding = value;
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+	_priv->encoder = CharsetEncoder::getEncoder(value);
+	_priv->encoding = value;
 }
 
 
 void TelnetAppender::close()
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
-	if (closed)
+	if (_priv->closed)
 	{
 		return;
 	}
 
-	closed = true;
+	_priv->closed = true;
 
 	SocketPtr nullSocket;
 
-	for (ConnectionList::iterator iter = connections.begin();
-		iter != connections.end();
+	for (ConnectionList::iterator iter = _priv->connections.begin();
+		iter != _priv->connections.end();
 		iter++)
 	{
 		if (*iter != 0)
@@ -120,30 +136,30 @@ void TelnetAppender::close()
 		}
 	}
 
-	if (serverSocket != NULL)
+	if (_priv->serverSocket != NULL)
 	{
 		try
 		{
-			serverSocket->close();
+			_priv->serverSocket->close();
 		}
 		catch (Exception&)
 		{
 		}
 	}
 
-	if ( sh.joinable() )
+	if ( _priv->sh.joinable() )
 	{
-		sh.join();
+		_priv->sh.join();
 	}
 
-	activeConnections = 0;
+	_priv->activeConnections = 0;
 }
 
 
 void TelnetAppender::write(ByteBuffer& buf)
 {
-	for (ConnectionList::iterator iter = connections.begin();
-		iter != connections.end();
+	for (ConnectionList::iterator iter = _priv->connections.begin();
+		iter != _priv->connections.end();
 		iter++)
 	{
 		if (*iter != 0)
@@ -157,7 +173,7 @@ void TelnetAppender::write(ByteBuffer& buf)
 			{
 				// The client has closed the connection, remove it from our list:
 				*iter = 0;
-				activeConnections--;
+				_priv->activeConnections--;
 			}
 		}
 	}
@@ -173,7 +189,7 @@ void TelnetAppender::writeStatus(const SocketPtr& socket, const LogString& msg,
 
 	while (msgIter != msg.end())
 	{
-		encoder->encode(msg, msgIter, buf);
+		_priv->encoder->encode(msg, msgIter, buf);
 		buf.flip();
 		socket->write(buf);
 		buf.clear();
@@ -182,12 +198,12 @@ void TelnetAppender::writeStatus(const SocketPtr& socket, const LogString& msg,
 
 void TelnetAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 {
-	size_t count = activeConnections;
+	size_t count = _priv->activeConnections;
 
 	if (count > 0)
 	{
 		LogString msg;
-		this->layout->format(msg, event, pool);
+		_priv->layout->format(msg, event, _priv->pool);
 		msg.append(LOG4CXX_STR("\r\n"));
 		size_t bytesSize = msg.size() * 2;
 		char* bytes = p.pstralloc(bytesSize);
@@ -195,11 +211,11 @@ void TelnetAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 		LogString::const_iterator msgIter(msg.begin());
 		ByteBuffer buf(bytes, bytesSize);
 
-		log4cxx::shared_lock<log4cxx::shared_mutex> lock(mutex);
+		log4cxx::shared_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
 		while (msgIter != msg.end())
 		{
-			log4cxx_status_t stat = encoder->encode(msg, msgIter, buf);
+			log4cxx_status_t stat = _priv->encoder->encode(msg, msgIter, buf);
 			buf.flip();
 			write(buf);
 			buf.clear();
@@ -208,7 +224,7 @@ void TelnetAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 			{
 				LogString unrepresented(1, 0x3F /* '?' */);
 				LogString::const_iterator unrepresentedIter(unrepresented.begin());
-				stat = encoder->encode(unrepresented, unrepresentedIter, buf);
+				stat = _priv->encoder->encode(unrepresented, unrepresentedIter, buf);
 				buf.flip();
 				write(buf);
 				buf.clear();
@@ -226,8 +242,8 @@ void TelnetAppender::acceptConnections()
 	{
 		try
 		{
-			SocketPtr newClient = serverSocket->accept();
-			bool done = closed;
+			SocketPtr newClient = _priv->serverSocket->accept();
+			bool done = _priv->closed;
 
 			if (done)
 			{
@@ -238,9 +254,9 @@ void TelnetAppender::acceptConnections()
 				break;
 			}
 
-			size_t count = activeConnections;
+			size_t count = _priv->activeConnections;
 
-			if (count >= connections.size())
+			if (count >= _priv->connections.size())
 			{
 				Pool p;
 				writeStatus(newClient, LOG4CXX_STR("Too many connections.\r\n"), p);
@@ -251,16 +267,16 @@ void TelnetAppender::acceptConnections()
 				//
 				//   find unoccupied connection
 				//
-				std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+				std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
-				for (ConnectionList::iterator iter = connections.begin();
-					iter != connections.end();
+				for (ConnectionList::iterator iter = _priv->connections.begin();
+					iter != _priv->connections.end();
 					iter++)
 				{
 					if (*iter == NULL)
 					{
 						*iter = newClient;
-						activeConnections++;
+						_priv->activeConnections++;
 
 						break;
 					}
@@ -275,14 +291,14 @@ void TelnetAppender::acceptConnections()
 		}
 		catch (InterruptedIOException&)
 		{
-			if (closed)
+			if (_priv->closed)
 			{
 				break;
 			}
 		}
 		catch (Exception& e)
 		{
-			if (!closed)
+			if (!_priv->closed)
 			{
 				LogLog::error(LOG4CXX_STR("Encountered error while in SocketHandler loop."), e);
 			}
@@ -294,3 +310,11 @@ void TelnetAppender::acceptConnections()
 	}
 
 }
+
+int TelnetAppender::getPort() const{
+	return _priv->port;
+}
+
+void TelnetAppender::setPort(int port1){
+	_priv->port = port1;
+}
diff --git a/src/main/cpp/writerappender.cpp b/src/main/cpp/writerappender.cpp
index 57996f5..bbd4842 100644
--- a/src/main/cpp/writerappender.cpp
+++ b/src/main/cpp/writerappender.cpp
@@ -19,34 +19,40 @@
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/layout.h>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
+#include <log4cxx/private/writerappender_priv.h>
 #include <mutex>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 using namespace log4cxx::spi;
 
+#define _priv static_cast<priv::WriterAppenderPriv*>(m_priv.get())
+
 IMPLEMENT_LOG4CXX_OBJECT(WriterAppender)
 
-WriterAppender::WriterAppender()
+WriterAppender::WriterAppender() :
+	AppenderSkeleton (std::make_unique<priv::WriterAppenderPriv>())
 {
-	immediateFlush = true;
 }
 
 WriterAppender::WriterAppender(const LayoutPtr& layout1,
 	log4cxx::helpers::WriterPtr& writer1)
-	: AppenderSkeleton(layout1), writer(writer1)
+	: AppenderSkeleton (std::make_unique<priv::WriterAppenderPriv>(layout1, writer1))
 {
 	Pool p;
-	immediateFlush = true;
 	activateOptions(p);
 }
 
 WriterAppender::WriterAppender(const LayoutPtr& layout1)
-	: AppenderSkeleton(layout1)
+	: AppenderSkeleton (std::make_unique<priv::WriterAppenderPriv>(layout1))
 {
-	immediateFlush = true;
 }
 
+WriterAppender::WriterAppender(std::unique_ptr<priv::WriterAppenderPriv> priv)
+	: AppenderSkeleton (std::move(priv)){
+
+}
 
 WriterAppender::~WriterAppender()
 {
@@ -57,19 +63,19 @@ void WriterAppender::activateOptions(Pool& p)
 {
 	int errors = 0;
 
-	if (layout == 0)
+	if (_priv->layout == 0)
 	{
-		errorHandler->error(
+		_priv->errorHandler->error(
 			((LogString) LOG4CXX_STR("No layout set for the appender named ["))
-			+ name + LOG4CXX_STR("]."));
+			+ _priv->name + LOG4CXX_STR("]."));
 		errors++;
 	}
 
-	if (writer == 0)
+	if (_priv->writer == 0)
 	{
-		errorHandler->error(
+		_priv->errorHandler->error(
 			((LogString) LOG4CXX_STR("No writer set for the appender named ["))
-			+ name + LOG4CXX_STR("]."));
+			+ _priv->name + LOG4CXX_STR("]."));
 		errors++;
 	}
 
@@ -103,7 +109,7 @@ bool WriterAppender::checkEntryConditions() const
 	static bool warnedClosed = false;
 	static bool warnedNoWriter = false;
 
-	if (closed)
+	if (_priv->closed)
 	{
 		if (!warnedClosed)
 		{
@@ -114,24 +120,24 @@ bool WriterAppender::checkEntryConditions() const
 		return false;
 	}
 
-	if (writer == 0)
+	if (_priv->writer == 0)
 	{
 		if (warnedNoWriter)
 		{
-			errorHandler->error(
+			_priv->errorHandler->error(
 				LogString(LOG4CXX_STR("No output stream or file set for the appender named [")) +
-				name + LOG4CXX_STR("]."));
+				_priv->name + LOG4CXX_STR("]."));
 			warnedNoWriter = true;
 		}
 
 		return false;
 	}
 
-	if (layout == 0)
+	if (_priv->layout == 0)
 	{
-		errorHandler->error(
+		_priv->errorHandler->error(
 			LogString(LOG4CXX_STR("No layout set for the appender named [")) +
-			name + LOG4CXX_STR("]."));
+			_priv->name + LOG4CXX_STR("]."));
 		return false;
 	}
 
@@ -151,14 +157,14 @@ bool WriterAppender::checkEntryConditions() const
    */
 void WriterAppender::close()
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 
-	if (closed)
+	if (_priv->closed)
 	{
 		return;
 	}
 
-	closed = true;
+	_priv->closed = true;
 	closeWriter();
 }
 
@@ -167,7 +173,7 @@ void WriterAppender::close()
  * */
 void WriterAppender::closeWriter()
 {
-	if (writer != NULL)
+	if (_priv->writer != NULL)
 	{
 		try
 		{
@@ -176,13 +182,13 @@ void WriterAppender::closeWriter()
 			//   Using the object's pool since this is a one-shot operation
 			//    and pool is likely to be reclaimed soon when appender is destructed.
 			//
-			writeFooter(pool);
-			writer->close(pool);
-			writer = 0;
+			writeFooter(_priv->pool);
+			_priv->writer->close(_priv->pool);
+			_priv->writer = 0;
 		}
 		catch (IOException& e)
 		{
-			LogLog::error(LogString(LOG4CXX_STR("Could not close writer for WriterAppender named ")) + name, e);
+			LogLog::error(LogString(LOG4CXX_STR("Could not close writer for WriterAppender named ")) + _priv->name, e);
 		}
 	}
 
@@ -230,26 +236,26 @@ WriterPtr WriterAppender::createWriter(OutputStreamPtr& os)
 
 LogString WriterAppender::getEncoding() const
 {
-	return encoding;
+	return _priv->encoding;
 }
 
 void WriterAppender::setEncoding(const LogString& enc)
 {
-	encoding = enc;
+	_priv->encoding = enc;
 }
 
 void WriterAppender::subAppend(const spi::LoggingEventPtr& event, Pool& p)
 {
 	LogString msg;
-	layout->format(msg, event, p);
+	_priv->layout->format(msg, event, p);
 
-	if (writer != NULL)
+	if (_priv->writer != NULL)
 	{
-		writer->write(msg, p);
+		_priv->writer->write(msg, p);
 
-		if (immediateFlush)
+		if (_priv->immediateFlush)
 		{
-			writer->flush(p);
+			_priv->writer->flush(p);
 		}
 	}
 }
@@ -257,34 +263,34 @@ void WriterAppender::subAppend(const spi::LoggingEventPtr& event, Pool& p)
 
 void WriterAppender::writeFooter(Pool& p)
 {
-	if (layout != NULL)
+	if (_priv->layout != NULL)
 	{
 		LogString foot;
-		layout->appendFooter(foot, p);
-		writer->write(foot, p);
+		_priv->layout->appendFooter(foot, p);
+		_priv->writer->write(foot, p);
 	}
 }
 
 void WriterAppender::writeHeader(Pool& p)
 {
-	if (layout != NULL)
+	if (_priv->layout != NULL)
 	{
 		LogString header;
-		layout->appendHeader(header, p);
-		writer->write(header, p);
+		_priv->layout->appendHeader(header, p);
+		_priv->writer->write(header, p);
 	}
 }
 
 
 void WriterAppender::setWriter(const WriterPtr& newWriter)
 {
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
 	setWriterInternal(newWriter);
 }
 
 void WriterAppender::setWriterInternal(const WriterPtr& newWriter)
 {
-	writer = newWriter;
+	_priv->writer = newWriter;
 }
 
 bool WriterAppender::requiresLayout() const
@@ -307,5 +313,9 @@ void WriterAppender::setOption(const LogString& option, const LogString& value)
 
 void WriterAppender::setImmediateFlush(bool value)
 {
-	immediateFlush = value;
+	_priv->immediateFlush = value;
+}
+
+bool WriterAppender::getImmediateFlush() const{
+	return _priv->immediateFlush;
 }
diff --git a/src/main/cpp/xmlsocketappender.cpp b/src/main/cpp/xmlsocketappender.cpp
index d5b9942..1b34573 100644
--- a/src/main/cpp/xmlsocketappender.cpp
+++ b/src/main/cpp/xmlsocketappender.cpp
@@ -26,6 +26,7 @@
 #include <log4cxx/helpers/transform.h>
 #include <log4cxx/helpers/transcoder.h>
 #include <log4cxx/helpers/socketoutputstream.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -34,6 +35,14 @@ using namespace log4cxx::xml;
 
 IMPLEMENT_LOG4CXX_OBJECT(XMLSocketAppender)
 
+struct XMLSocketAppenderPriv : public priv::AppenderSkeletonPrivate {
+	XMLSocketAppenderPriv() : AppenderSkeletonPrivate(){}
+
+	log4cxx::helpers::WriterPtr writer;
+};
+
+#define _priv static_cast<XMLSocketAppenderPriv*>(m_priv.get())
+
 // The default port number of remote logging server (4560)
 int XMLSocketAppender::DEFAULT_PORT                 = 4560;
 
@@ -45,13 +54,13 @@ const int XMLSocketAppender::MAX_EVENT_LEN          = 1024;
 XMLSocketAppender::XMLSocketAppender()
 	: SocketAppenderSkeleton(DEFAULT_PORT, DEFAULT_RECONNECTION_DELAY)
 {
-	layout = XMLLayoutPtr(new XMLLayout());
+	_priv->layout = std::make_shared<XMLLayout>();
 }
 
 XMLSocketAppender::XMLSocketAppender(InetAddressPtr address1, int port1)
 	: SocketAppenderSkeleton(address1, port1, DEFAULT_RECONNECTION_DELAY)
 {
-	layout = XMLLayoutPtr(new XMLLayout());
+	_priv->layout = std::make_shared<XMLLayout>();
 	Pool p;
 	activateOptions(p);
 }
@@ -59,7 +68,7 @@ XMLSocketAppender::XMLSocketAppender(InetAddressPtr address1, int port1)
 XMLSocketAppender::XMLSocketAppender(const LogString& host, int port1)
 	: SocketAppenderSkeleton(host, port1, DEFAULT_RECONNECTION_DELAY)
 {
-	layout = XMLLayoutPtr(new XMLLayout());
+	_priv->layout = std::make_shared<XMLLayout>();
 	Pool p;
 	activateOptions(p);
 }
@@ -84,18 +93,18 @@ void XMLSocketAppender::setSocket(log4cxx::helpers::SocketPtr& socket, Pool& p)
 {
 	OutputStreamPtr os(new SocketOutputStream(socket));
 	CharsetEncoderPtr charset(CharsetEncoder::getUTF8Encoder());
-	std::unique_lock<log4cxx::shared_mutex> lock(mutex);
-	writer = OutputStreamWriterPtr(new OutputStreamWriter(os, charset));
+	std::unique_lock<log4cxx::shared_mutex> lock(_priv->mutex);
+	_priv->writer = std::make_shared<OutputStreamWriter>(os, charset);
 }
 
 void XMLSocketAppender::cleanUp(Pool& p)
 {
-	if (writer != 0)
+	if (_priv->writer)
 	{
 		try
 		{
-			writer->close(p);
-			writer = 0;
+			_priv->writer->close(p);
+			_priv->writer = nullptr;
 		}
 		catch (std::exception&)
 		{
@@ -105,19 +114,19 @@ void XMLSocketAppender::cleanUp(Pool& p)
 
 void XMLSocketAppender::append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p)
 {
-	if (writer != 0)
+	if (_priv->writer)
 	{
 		LogString output;
-		layout->format(output, event, p);
+		_priv->layout->format(output, event, p);
 
 		try
 		{
-			writer->write(output, p);
-			writer->flush(p);
+			_priv->writer->write(output, p);
+			_priv->writer->flush(p);
 		}
 		catch (std::exception& e)
 		{
-			writer = 0;
+			_priv->writer = nullptr;
 			LogLog::warn(LOG4CXX_STR("Detected problem with connection: "), e);
 
 			if (getReconnectionDelay() > 0)
diff --git a/src/main/include/log4cxx/appender.h b/src/main/include/log4cxx/appender.h
index d3c3b76..6402c52 100644
--- a/src/main/include/log4cxx/appender.h
+++ b/src/main/include/log4cxx/appender.h
@@ -60,12 +60,10 @@ class LOG4CXX_EXPORT Appender :
 
 		virtual ~Appender() {}
 
-		void asdf();
-
 		/**
 		 Add a filter to the end of the filter list.
 		*/
-		virtual void addFilter(const spi::FilterPtr& newFilter) = 0;
+		virtual void addFilter(const spi::FilterPtr newFilter) = 0;
 
 		/**
 		 Returns the head Filter. The Filters are organized in a linked list
@@ -106,7 +104,7 @@ class LOG4CXX_EXPORT Appender :
 		/**
 		 Set the Layout for this appender.
 		*/
-		virtual void setLayout(const LayoutPtr& layout) = 0;
+		virtual void setLayout(const LayoutPtr layout) = 0;
 
 		/**
 		 Returns this appenders layout.
diff --git a/src/main/include/log4cxx/appenderskeleton.h b/src/main/include/log4cxx/appenderskeleton.h
index b89b09e..1076335 100644
--- a/src/main/include/log4cxx/appenderskeleton.h
+++ b/src/main/include/log4cxx/appenderskeleton.h
@@ -34,6 +34,11 @@
 
 namespace log4cxx
 {
+namespace priv
+{
+struct AppenderSkeletonPrivate;
+}
+
 /**
 *  Implementation base class for all appenders.
 *
@@ -45,36 +50,7 @@ class LOG4CXX_EXPORT AppenderSkeleton :
 	public virtual helpers::Object
 {
 	protected:
-		/** The layout variable does not need to be set if the appender
-		implementation has its own layout. */
-		LayoutPtr layout;
-
-		/** Appenders are named. */
-		LogString name;
-
-		/**
-		There is no level threshold filtering by default.  */
-		LevelPtr threshold;
-
-		/**
-		It is assumed and enforced that errorHandler is never null.
-		*/
-		spi::ErrorHandlerPtr errorHandler;
-
-		/** The first filter in the filter chain. Set to <code>null</code>
-		initially. */
-		spi::FilterPtr headFilter;
-
-		/** The last filter in the filter chain. */
-		spi::FilterPtr tailFilter;
-
-		/**
-		Is this appender closed?
-		*/
-		bool closed;
-
-		log4cxx::helpers::Pool pool;
-		mutable log4cxx::shared_mutex mutex;
+		AppenderSkeleton( std::unique_ptr<priv::AppenderSkeletonPrivate> priv );
 
 		/**
 		Subclasses of <code>AppenderSkeleton</code> should implement this
@@ -95,6 +71,7 @@ class LOG4CXX_EXPORT AppenderSkeleton :
 
 		AppenderSkeleton();
 		AppenderSkeleton(const LayoutPtr& layout);
+		virtual ~AppenderSkeleton();
 
 		/**
 		Finalize this appender by calling the derived class'
@@ -112,7 +89,7 @@ class LOG4CXX_EXPORT AppenderSkeleton :
 		/**
 		Add a filter to end of the filter list.
 		*/
-		void addFilter(const spi::FilterPtr& newFilter) ;
+		void addFilter(const spi::FilterPtr newFilter) ;
 
 	public:
 		/**
@@ -124,54 +101,36 @@ class LOG4CXX_EXPORT AppenderSkeleton :
 		Return the currently set spi::ErrorHandler for this
 		Appender.
 		*/
-		const spi::ErrorHandlerPtr& getErrorHandler() const
-		{
-			return errorHandler;
-		}
+		const spi::ErrorHandlerPtr getErrorHandler() const;
 
 		/**
 		Returns the head Filter.
 		*/
-		spi::FilterPtr getFilter() const
-		{
-			return headFilter;
-		}
+		spi::FilterPtr getFilter() const;
 
 		/**
 		Return the first filter in the filter chain for this
-		Appender. The return value may be <code>0</code> if no is
+		Appender. The return value may be <code>nullptr</code> if no is
 		filter is set.
 		*/
-		const spi::FilterPtr& getFirstFilter() const
-		{
-			return headFilter;
-		}
+		const spi::FilterPtr getFirstFilter() const;
 
 		/**
-		Returns the layout of this appender. The value may be 0.
+		Returns the layout of this appender. The value may be nullptr.
 		*/
-		LayoutPtr getLayout() const
-		{
-			return layout;
-		}
+		LayoutPtr getLayout() const;
 
 
 		/**
 		Returns the name of this Appender.
 		*/
-		LogString getName() const
-		{
-			return name;
-		}
+		LogString getName() const;
 
 		/**
 		Returns this appenders threshold level. See the #setThreshold
 		method for the meaning of this option.
 		*/
-		const LevelPtr& getThreshold() const
-		{
-			return threshold;
-		}
+		const LevelPtr getThreshold() const;
 
 		/**
 		Check whether the message level is below the appender's
@@ -199,18 +158,12 @@ class LOG4CXX_EXPORT AppenderSkeleton :
 		{@link net::SocketAppender SocketAppender} ignores the layout set
 		here.
 		*/
-		void setLayout(const LayoutPtr& layout1)
-		{
-			this->layout = layout1;
-		}
+		void setLayout(const LayoutPtr layout1);
 
 		/**
 		Set the name of this Appender.
 		*/
-		void setName(const LogString& name1)
-		{
-			this->name.assign(name1);
-		}
+		void setName(const LogString& name1);
 
 
 		/**
@@ -223,6 +176,9 @@ class LOG4CXX_EXPORT AppenderSkeleton :
 		*/
 		void setThreshold(const LevelPtr& threshold);
 
+protected:
+		std::unique_ptr<priv::AppenderSkeletonPrivate> m_priv;
+
 }; // class AppenderSkeleton
 }  // namespace log4cxx
 
diff --git a/src/main/include/log4cxx/asyncappender.h b/src/main/include/log4cxx/asyncappender.h
index d4a69ef..1f767b2 100644
--- a/src/main/include/log4cxx/asyncappender.h
+++ b/src/main/include/log4cxx/asyncappender.h
@@ -189,107 +189,6 @@ class LOG4CXX_EXPORT AsyncAppender :
 	private:
 		AsyncAppender(const AsyncAppender&);
 		AsyncAppender& operator=(const AsyncAppender&);
-		/**
-		 * The default buffer size is set to 128 events.
-		*/
-		enum { DEFAULT_BUFFER_SIZE = 128 };
-
-		/**
-		 * Event buffer.
-		*/
-#if defined(NON_BLOCKING)
-		boost::lockfree::queue<log4cxx::spi::LoggingEvent* > buffer;
-		std::atomic<size_t> discardedCount;
-#else
-		LoggingEventList buffer;
-#endif
-
-		/**
-		 *  Mutex used to guard access to buffer and discardMap.
-		 */
-		std::mutex bufferMutex;
-
-#if defined(NON_BLOCKING)
-		::log4cxx::helpers::Semaphore bufferNotFull;
-		::log4cxx::helpers::Semaphore bufferNotEmpty;
-#else
-		std::condition_variable bufferNotFull;
-		std::condition_variable bufferNotEmpty;
-#endif
-		class DiscardSummary
-		{
-			private:
-				/**
-				 * First event of the highest severity.
-				*/
-				::log4cxx::spi::LoggingEventPtr maxEvent;
-
-				/**
-				* Total count of messages discarded.
-				*/
-				int count;
-
-			public:
-				/**
-				 * Create new instance.
-				 *
-				 * @param event event, may not be null.
-				*/
-				DiscardSummary(const ::log4cxx::spi::LoggingEventPtr& event);
-				/** Copy constructor.  */
-				DiscardSummary(const DiscardSummary& src);
-				/** Assignment operator. */
-				DiscardSummary& operator=(const DiscardSummary& src);
-
-				/**
-				 * Add discarded event to summary.
-				 *
-				 * @param event event, may not be null.
-				*/
-				void add(const ::log4cxx::spi::LoggingEventPtr& event);
-
-				/**
-				 * Create event with summary information.
-				 *
-				 * @return new event.
-				 */
-				::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p);
-
-				static
-				::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p,
-					size_t discardedCount);
-		};
-
-		/**
-		  * Map of DiscardSummary objects keyed by logger name.
-		*/
-		typedef std::map<LogString, DiscardSummary> DiscardMap;
-		DiscardMap* discardMap;
-
-		/**
-		 * Buffer size.
-		*/
-		int bufferSize;
-
-		/**
-		 * Nested appenders.
-		*/
-		helpers::AppenderAttachableImplPtr appenders;
-
-		/**
-		 *  Dispatcher.
-		 */
-		std::thread dispatcher;
-
-		/**
-		 * Should location info be included in dispatched messages.
-		*/
-		bool locationInfo;
-
-		/**
-		 * Does appender block when buffer is full.
-		*/
-		bool blocking;
 
 		/**
 		 *  Dispatch routine.
diff --git a/src/main/include/log4cxx/consoleappender.h b/src/main/include/log4cxx/consoleappender.h
index 0c67c2c..31bfb17 100644
--- a/src/main/include/log4cxx/consoleappender.h
+++ b/src/main/include/log4cxx/consoleappender.h
@@ -35,9 +35,6 @@ namespace log4cxx
 */
 class LOG4CXX_EXPORT ConsoleAppender : public WriterAppender
 {
-	private:
-		LogString target;
-
 	public:
 		DECLARE_LOG4CXX_OBJECT(ConsoleAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
diff --git a/src/main/include/log4cxx/db/odbcappender.h b/src/main/include/log4cxx/db/odbcappender.h
index fdc144f..b16baaa 100644
--- a/src/main/include/log4cxx/db/odbcappender.h
+++ b/src/main/include/log4cxx/db/odbcappender.h
@@ -30,6 +30,7 @@
 #include <log4cxx/appenderskeleton.h>
 #include <log4cxx/spi/loggingevent.h>
 #include <list>
+#include <memory>
 
 namespace log4cxx
 {
@@ -97,59 +98,6 @@ sql option value.
 
 class LOG4CXX_EXPORT ODBCAppender : public AppenderSkeleton
 {
-	protected:
-		/**
-		* URL of the DB for default connection handling
-		*/
-		LogString databaseURL;
-
-		/**
-		* User to connect as for default connection handling
-		*/
-		LogString databaseUser;
-
-		/**
-		* User to use for default connection handling
-		*/
-		LogString databasePassword;
-
-		typedef void* SQLHDBC;
-		typedef void* SQLHENV;
-		typedef void* SQLHANDLE;
-		typedef short SQLSMALLINT;
-
-		/**
-		* Connection used by default.  The connection is opened the first time it
-		* is needed and then held open until the appender is closed (usually at
-		* garbage collection).  This behavior is best modified by creating a
-		* sub-class and overriding the <code>getConnection</code> and
-		* <code>closeConnection</code> methods.
-		*/
-		SQLHDBC connection;
-		SQLHENV env;
-
-		/**
-		* Stores the string given to the pattern layout for conversion into a SQL
-		* statement, eg: insert into LogTable (Thread, File, Message) values
-		* ("%t", "%F", "%m")
-		*
-		* Be careful of quotes in your messages!
-		*
-		* Also see PatternLayout.
-		*/
-		LogString sqlStatement;
-
-		/**
-		* size of LoggingEvent buffer before writing to the database.
-		* Default is 1.
-		*/
-		size_t bufferSize;
-
-		/**
-		* ArrayList holding the buffer of Logging Events.
-		*/
-		std::list<spi::LoggingEventPtr> buffer;
-
 	public:
 		DECLARE_LOG4CXX_OBJECT(ODBCAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
@@ -157,6 +105,11 @@ class LOG4CXX_EXPORT ODBCAppender : public AppenderSkeleton
 		LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton)
 		END_LOG4CXX_CAST_MAP()
 
+		typedef void* SQLHDBC;
+		typedef void* SQLHENV;
+		typedef void* SQLHANDLE;
+		typedef short SQLSMALLINT;
+
 		ODBCAppender();
 		virtual ~ODBCAppender();
 
@@ -247,56 +200,24 @@ class LOG4CXX_EXPORT ODBCAppender : public AppenderSkeleton
 		/**
 		* Returns pre-formated statement eg: insert into LogTable (msg) values ("%m")
 		*/
-		inline const LogString& getSql() const
-		{
-			return sqlStatement;
-		}
-
-
-		inline void setUser(const LogString& user)
-		{
-			databaseUser = user;
-		}
-
-
-		inline void setURL(const LogString& url)
-		{
-			databaseURL = url;
-		}
+		const LogString& getSql() const;
 
 
-		inline void setPassword(const LogString& password)
-		{
-			databasePassword = password;
-		}
+		void setUser(const LogString& user);
 
+		void setURL(const LogString& url);
 
-		inline void setBufferSize(size_t newBufferSize)
-		{
-			bufferSize = newBufferSize;
-		}
-
-		inline const LogString& getUser() const
-		{
-			return databaseUser;
-		}
+		void setPassword(const LogString& password);
 
+		void setBufferSize(size_t newBufferSize);
 
-		inline const LogString& getURL() const
-		{
-			return databaseURL;
-		}
+		const LogString& getUser() const;
 
+		const LogString& getURL() const;
 
-		inline const LogString& getPassword() const
-		{
-			return databasePassword;
-		}
+		const LogString& getPassword() const;
 
-		inline size_t getBufferSize() const
-		{
-			return bufferSize;
-		}
+		size_t getBufferSize() const;
 	private:
 		ODBCAppender(const ODBCAppender&);
 		ODBCAppender& operator=(const ODBCAppender&);
diff --git a/src/main/include/log4cxx/fileappender.h b/src/main/include/log4cxx/fileappender.h
index e5a2fbb..bca07da 100644
--- a/src/main/include/log4cxx/fileappender.h
+++ b/src/main/include/log4cxx/fileappender.h
@@ -35,6 +35,9 @@ namespace helpers
 {
 class Pool;
 }
+namespace priv{
+struct FileAppenderPriv;
+}
 
 /**
 *  FileAppender appends log events to a file.
@@ -45,28 +48,6 @@ class Pool;
 */
 class LOG4CXX_EXPORT FileAppender : public WriterAppender
 {
-	protected:
-		/** Append to or truncate the file? The default value for this
-		variable is <code>true</code>, meaning that by default a
-		<code>FileAppender</code> will append to an existing file and
-		not truncate it.
-		<p>This option is meaningful only if the FileAppender opens the
-		file.
-		*/
-		bool fileAppend;
-
-		/**
-		The name of the log file. */
-		LogString fileName;
-
-		/**
-		Do we do bufferedIO? */
-		bool bufferedIO;
-
-		/**
-		How big should the IO buffer be? Default is 8K. */
-		int bufferSize;
-
 	public:
 		DECLARE_LOG4CXX_OBJECT(FileAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
@@ -130,16 +111,10 @@ class LOG4CXX_EXPORT FileAppender : public WriterAppender
 		/**
 		Returns the value of the <b>Append</b> option.
 		*/
-		inline bool getAppend() const
-		{
-			return fileAppend;
-		}
+		bool getAppend() const;
 
 		/** Returns the value of the <b>File</b> option. */
-		inline LogString getFile() const
-		{
-			return fileName;
-		}
+		LogString getFile() const;
 
 		/**
 		<p>Sets and <i>opens</i> the file where the log output will
@@ -158,18 +133,12 @@ class LOG4CXX_EXPORT FileAppender : public WriterAppender
 		loaded systems.
 
 		*/
-		inline bool getBufferedIO() const
-		{
-			return bufferedIO;
-		}
+		bool getBufferedIO() const;
 
 		/**
 		Get the size of the IO buffer.
 		*/
-		inline  int getBufferSize() const
-		{
-			return bufferSize;
-		}
+		int getBufferSize() const;
 
 		/**
 		The <b>Append</b> option takes a boolean value. It is set to
@@ -197,10 +166,7 @@ class LOG4CXX_EXPORT FileAppender : public WriterAppender
 		/**
 		Set the size of the IO buffer.
 		*/
-		void setBufferSize(int bufferSize1)
-		{
-			this->bufferSize = bufferSize1;
-		}
+		void setBufferSize(int bufferSize1);
 
 		/**
 		 *   Replaces double backslashes with single backslashes
@@ -242,6 +208,8 @@ class LOG4CXX_EXPORT FileAppender : public WriterAppender
 	private:
 		FileAppender(const FileAppender&);
 		FileAppender& operator=(const FileAppender&);
+protected:
+		FileAppender(std::unique_ptr<priv::FileAppenderPriv> priv);
 
 }; // class FileAppender
 LOG4CXX_PTR_DEF(FileAppender);
diff --git a/src/main/include/log4cxx/filter/andfilter.h b/src/main/include/log4cxx/filter/andfilter.h
index e035540..03c43a4 100644
--- a/src/main/include/log4cxx/filter/andfilter.h
+++ b/src/main/include/log4cxx/filter/andfilter.h
@@ -25,6 +25,7 @@
 
 
 #include <log4cxx/spi/filter.h>
+#include <memory>
 
 namespace log4cxx
 {
@@ -78,13 +79,12 @@ namespace filter
 class LOG4CXX_EXPORT AndFilter: public log4cxx::spi::Filter
 {
 	private:
-		log4cxx::spi::FilterPtr headFilter;
-		log4cxx::spi::FilterPtr tailFilter;
-		bool acceptOnMatch;
+		struct priv_data;
+		std::unique_ptr<priv_data> m_priv;
+
 		AndFilter(const AndFilter&);
 		AndFilter& operator=(const AndFilter&);
 
-
 	public:
 		DECLARE_LOG4CXX_OBJECT(AndFilter)
 		BEGIN_LOG4CXX_CAST_MAP()
@@ -92,6 +92,7 @@ class LOG4CXX_EXPORT AndFilter: public log4cxx::spi::Filter
 		END_LOG4CXX_CAST_MAP()
 
 		AndFilter();
+		~AndFilter();
 
 		void addFilter(const log4cxx::spi::FilterPtr& filter);
 
diff --git a/src/main/include/log4cxx/helpers/appenderattachableimpl.h b/src/main/include/log4cxx/helpers/appenderattachableimpl.h
index b80b5aa..f8aa46b 100644
--- a/src/main/include/log4cxx/helpers/appenderattachableimpl.h
+++ b/src/main/include/log4cxx/helpers/appenderattachableimpl.h
@@ -46,8 +46,7 @@ class LOG4CXX_EXPORT AppenderAttachableImpl :
 	public virtual helpers::Object
 {
 	protected:
-		/** Array of appenders. */
-		AppenderList  appenderList;
+		AppenderList& appenderList();
 
 	public:
 		/**
@@ -56,6 +55,8 @@ class LOG4CXX_EXPORT AppenderAttachableImpl :
 		 */
 		AppenderAttachableImpl(Pool& pool);
 
+		~AppenderAttachableImpl();
+
 		DECLARE_ABSTRACT_LOG4CXX_OBJECT(AppenderAttachableImpl)
 		BEGIN_LOG4CXX_CAST_MAP()
 		LOG4CXX_CAST_ENTRY(AppenderAttachableImpl)
@@ -106,13 +107,12 @@ class LOG4CXX_EXPORT AppenderAttachableImpl :
 		 */
 		virtual void removeAppender(const LogString& name);
 
-		inline std::mutex& getMutex() const
-		{
-			return m_mutex;
-		}
+		std::mutex& getMutex();
 
 	private:
-		mutable std::mutex m_mutex;
+		struct priv_data;
+		std::unique_ptr<priv_data> m_priv;
+
 		AppenderAttachableImpl(const AppenderAttachableImpl&);
 		AppenderAttachableImpl& operator=(const AppenderAttachableImpl&);
 };
diff --git a/src/main/include/log4cxx/net/smtpappender.h b/src/main/include/log4cxx/net/smtpappender.h
index da40c77..593950d 100644
--- a/src/main/include/log4cxx/net/smtpappender.h
+++ b/src/main/include/log4cxx/net/smtpappender.h
@@ -45,11 +45,10 @@ delivering useful application context.
 class LOG4CXX_EXPORT SMTPAppender : public AppenderSkeleton
 {
 	private:
-
-	private:
 		SMTPAppender(const SMTPAppender&);
 		SMTPAppender& operator=(const SMTPAppender&);
 		static bool asciiCheck(const LogString& value, const LogString& label);
+
 		/**
 		This method determines if there is a sense in attempting to append.
 		<p>It checks whether there is a set output target and also if
@@ -57,20 +56,6 @@ class LOG4CXX_EXPORT SMTPAppender : public AppenderSkeleton
 		value <code>false</code> is returned. */
 		bool checkEntryConditions();
 
-		LogString to;
-		LogString cc;
-		LogString bcc;
-		LogString from;
-		LogString subject;
-		LogString smtpHost;
-		LogString smtpUsername;
-		LogString smtpPassword;
-		int smtpPort;
-		int bufferSize; // 512
-		bool locationInfo;
-		helpers::CyclicBuffer cb;
-		spi::TriggeringEventEvaluatorPtr evaluator;
-
 	public:
 		DECLARE_LOG4CXX_OBJECT(SMTPAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
@@ -243,10 +228,7 @@ class LOG4CXX_EXPORT SMTPAppender : public AppenderSkeleton
 		/**
 		Returns value of the <b>BufferSize</b> option.
 		*/
-		inline int getBufferSize() const
-		{
-			return bufferSize;
-		}
+		int getBufferSize() const;
 
 
 		/**
diff --git a/src/main/include/log4cxx/net/socketappender.h b/src/main/include/log4cxx/net/socketappender.h
index df4d23e..736c573 100644
--- a/src/main/include/log4cxx/net/socketappender.h
+++ b/src/main/include/log4cxx/net/socketappender.h
@@ -122,9 +122,6 @@ class LOG4CXX_EXPORT SocketAppender : public SocketAppenderSkeleton
 		virtual int getDefaultPort() const;
 		void append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool);
 
-	private:
-		log4cxx::helpers::ObjectOutputStreamPtr oos;
-
 }; // class SocketAppender
 
 LOG4CXX_PTR_DEF(SocketAppender);
diff --git a/src/main/include/log4cxx/net/socketappenderskeleton.h b/src/main/include/log4cxx/net/socketappenderskeleton.h
index 88d2a15..b4158f4 100644
--- a/src/main/include/log4cxx/net/socketappenderskeleton.h
+++ b/src/main/include/log4cxx/net/socketappenderskeleton.h
@@ -40,21 +40,6 @@ namespace net
  */
 class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton
 {
-	private:
-		/**
-		host name
-		*/
-		LogString remoteHost;
-
-		/**
-		IP address
-		*/
-		helpers::InetAddressPtr address;
-
-		int port;
-		int reconnectionDelay;
-		bool locationInfo;
-
 	public:
 		SocketAppenderSkeleton(int defaultPort, int reconnectionDelay);
 		~SocketAppenderSkeleton();
@@ -92,54 +77,35 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton
 		* the host name of the server where a
 		* Apache Chainsaw or compatible is running.
 		* */
-		inline void setRemoteHost(const LogString& host)
-		{
-			address = helpers::InetAddress::getByName(host);
-			remoteHost.assign(host);
-		}
+		void setRemoteHost(const LogString& host);
 
 		/**
 		Returns value of the <b>RemoteHost</b> option.
 		*/
-		inline const LogString& getRemoteHost() const
-		{
-			return remoteHost;
-		}
+		const LogString& getRemoteHost() const;
 
 		/**
 		The <b>Port</b> option takes a positive integer representing
 		the port where the server is waiting for connections.
 		*/
-		void setPort(int port1)
-		{
-			this->port = port1;
-		}
+		void setPort(int port1);
 
 		/**
 		Returns value of the <b>Port</b> option.
 		*/
-		int getPort() const
-		{
-			return port;
-		}
+		int getPort() const;
 
 		/**
 		The <b>LocationInfo</b> option takes a boolean value. If true,
 		the information sent to the remote host will include location
 		information. By default no location information is sent to the server.
 		*/
-		void setLocationInfo(bool locationInfo1)
-		{
-			this->locationInfo = locationInfo1;
-		}
+		void setLocationInfo(bool locationInfo1);
 
 		/**
 		Returns value of the <b>LocationInfo</b> option.
 		*/
-		bool getLocationInfo() const
-		{
-			return locationInfo;
-		}
+		bool getLocationInfo() const;
 
 		/**
 		The <b>ReconnectionDelay</b> option takes a positive integer
@@ -150,18 +116,12 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton
 		<p>Setting this option to zero turns off reconnection
 		capability.
 		*/
-		void setReconnectionDelay(int reconnectionDelay1)
-		{
-			this->reconnectionDelay = reconnectionDelay1;
-		}
+		void setReconnectionDelay(int reconnectionDelay1);
 
 		/**
 		Returns value of the <b>ReconnectionDelay</b> option.
 		*/
-		int getReconnectionDelay() const
-		{
-			return reconnectionDelay;
-		}
+		int getReconnectionDelay() const;
 
 		void fireConnector();
 
@@ -190,9 +150,6 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton
 		     connection is droppped.
 		     */
 
-		std::thread thread;
-		std::condition_variable interrupt;
-		std::mutex interrupt_mutex;
 		void monitor();
 		bool is_closed();
 		SocketAppenderSkeleton(const SocketAppenderSkeleton&);
diff --git a/src/main/include/log4cxx/net/sockethubappender.h b/src/main/include/log4cxx/net/sockethubappender.h
index 88c5891..33be85a 100644
--- a/src/main/include/log4cxx/net/sockethubappender.h
+++ b/src/main/include/log4cxx/net/sockethubappender.h
@@ -114,10 +114,6 @@ class LOG4CXX_EXPORT SocketHubAppender : public AppenderSkeleton
 		*/
 		static int DEFAULT_PORT;
 
-		int port;
-		ObjectOutputStreamList streams;
-		bool locationInfo;
-
 	public:
 		DECLARE_LOG4CXX_OBJECT(SocketHubAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
@@ -160,40 +156,27 @@ class LOG4CXX_EXPORT SocketHubAppender : public AppenderSkeleton
 		/**
 		The <b>Port</b> option takes a positive integer representing
 		the port where the server is waiting for connections. */
-		inline void setPort(int port1)
-		{
-			this->port = port1;
-		}
+		void setPort(int port1);
 
 		/**
 		Returns value of the <b>Port</b> option. */
-		inline int getPort() const
-		{
-			return port;
-		}
+		int getPort() const;
 
 		/**
 		The <b>LocationInfo</b> option takes a boolean value. If true,
 		the information sent to the remote host will include location
 		information. By default no location information is sent to the server. */
-		inline void setLocationInfo(bool locationInfo1)
-		{
-			this->locationInfo = locationInfo1;
-		}
+		void setLocationInfo(bool locationInfo1);
 
 		/**
 		Returns value of the <b>LocationInfo</b> option. */
-		inline bool getLocationInfo() const
-		{
-			return locationInfo;
-		}
+		bool getLocationInfo() const;
 
 		/**
 		Start the ServerMonitor thread. */
 	private:
 		void startServer();
 
-		std::thread thread;
 		void monitor();
 
 }; // class SocketHubAppender
diff --git a/src/main/include/log4cxx/net/syslogappender.h b/src/main/include/log4cxx/net/syslogappender.h
index 689fd2c..87bee2d 100644
--- a/src/main/include/log4cxx/net/syslogappender.h
+++ b/src/main/include/log4cxx/net/syslogappender.h
@@ -107,10 +107,7 @@ class LOG4CXX_EXPORT SyslogAppender : public AppenderSkeleton
 		/**
 		Returns the value of the <b>SyslogHost</b> option.
 		*/
-		inline const LogString& getSyslogHost() const
-		{
-			return syslogHost;
-		}
+		const LogString& getSyslogHost() const;
 
 		/**
 		Set the syslog facility. This is the <b>Facility</b> option.
@@ -125,49 +122,27 @@ class LOG4CXX_EXPORT SyslogAppender : public AppenderSkeleton
 		/**
 		Returns the value of the <b>Facility</b> option.
 		*/
-		inline LogString getFacility() const
-		{
-			return getFacilityString(syslogFacility);
-		}
+		LogString getFacility() const;
 
 		/**
 		If the <b>FacilityPrinting</b> option is set to true, the printed
 		message will include the facility name of the application. It is
 		<em>false</em> by default.
 		*/
-		inline void setFacilityPrinting(bool facilityPrinting1)
-		{
-			this->facilityPrinting = facilityPrinting1;
-		}
+		void setFacilityPrinting(bool facilityPrinting1);
 
 		/**
 		Returns the value of the <b>FacilityPrinting</b> option.
 		*/
-		inline bool getFacilityPrinting() const
-		{
-			return facilityPrinting;
-		}
+		bool getFacilityPrinting() const;
 
-		inline void setMaxMessageLength(int maxMessageLength1)
-		{
-			maxMessageLength = maxMessageLength1;
-		}
+		void setMaxMessageLength(int maxMessageLength1);
 
-		inline int getMaxMessageLength() const
-		{
-			return maxMessageLength;
-		}
+		int getMaxMessageLength() const;
 
 	protected:
 		void initSyslogFacilityStr();
 
-		int syslogFacility; // Have LOG_USER as default
-		LogString facilityStr;
-		bool facilityPrinting;
-		helpers::SyslogWriter* sw;
-		LogString syslogHost;
-		int syslogHostPort;
-		int maxMessageLength;
 	private:
 		SyslogAppender(const SyslogAppender&);
 		SyslogAppender& operator=(const SyslogAppender&);
diff --git a/src/main/include/log4cxx/net/telnetappender.h b/src/main/include/log4cxx/net/telnetappender.h
index 9d0d66a..e25d19d 100644
--- a/src/main/include/log4cxx/net/telnetappender.h
+++ b/src/main/include/log4cxx/net/telnetappender.h
@@ -75,7 +75,6 @@ class LOG4CXX_EXPORT TelnetAppender : public AppenderSkeleton
 	private:
 		static const int DEFAULT_PORT;
 		static const int MAX_CONNECTIONS;
-		int port;
 
 	public:
 		DECLARE_LOG4CXX_OBJECT(TelnetAppender)
@@ -111,19 +110,13 @@ class LOG4CXX_EXPORT TelnetAppender : public AppenderSkeleton
 		/**
 		Returns value of the <b>Port</b> option.
 		*/
-		int getPort() const
-		{
-			return port;
-		}
+		int getPort() const;
 
 		/**
 		The <b>Port</b> option takes a positive integer representing
 		the port where the server is waiting for connections.
 		*/
-		void setPort(int port1)
-		{
-			this->port = port1;
-		}
+		void setPort(int port1);
 
 
 		/** shuts down the appender. */
@@ -143,12 +136,6 @@ class LOG4CXX_EXPORT TelnetAppender : public AppenderSkeleton
 
 		void write(log4cxx::helpers::ByteBuffer&);
 		void writeStatus(const log4cxx::helpers::SocketPtr& socket, const LogString& msg, log4cxx::helpers::Pool& p);
-		ConnectionList connections;
-		LogString encoding;
-		log4cxx::helpers::CharsetEncoderPtr encoder;
-		helpers::ServerSocket* serverSocket;
-		std::thread sh;
-		size_t activeConnections;
 		void acceptConnections();
 }; // class TelnetAppender
 
diff --git a/src/main/include/log4cxx/net/xmlsocketappender.h b/src/main/include/log4cxx/net/xmlsocketappender.h
index 62d5872..2ce7be2 100644
--- a/src/main/include/log4cxx/net/xmlsocketappender.h
+++ b/src/main/include/log4cxx/net/xmlsocketappender.h
@@ -135,7 +135,6 @@ class LOG4CXX_EXPORT XMLSocketAppender : public SocketAppenderSkeleton
 		void append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool);
 
 	private:
-		log4cxx::helpers::WriterPtr writer;
 		//  prevent copy and assignment statements
 		XMLSocketAppender(const XMLSocketAppender&);
 		XMLSocketAppender& operator=(const XMLSocketAppender&);
diff --git a/src/main/include/log4cxx/private/appenderskeleton_priv.h b/src/main/include/log4cxx/private/appenderskeleton_priv.h
new file mode 100644
index 0000000..af81db2
--- /dev/null
+++ b/src/main/include/log4cxx/private/appenderskeleton_priv.h
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_APPENDERSKELETON_PRIV
+#define _LOG4CXX_APPENDERSKELETON_PRIV
+
+#include <log4cxx/appenderskeleton.h>
+#include <log4cxx/helpers/onlyonceerrorhandler.h>
+#include <memory>
+
+namespace log4cxx {
+namespace priv{
+
+struct AppenderSkeletonPrivate {
+    AppenderSkeletonPrivate() :
+        threshold(Level::getAll()),
+        errorHandler(std::make_shared<log4cxx::helpers::OnlyOnceErrorHandler>()),
+        closed(false){}
+
+    AppenderSkeletonPrivate( LayoutPtr lay ) :
+        layout( lay ),
+        threshold(Level::getAll()),
+        errorHandler(std::make_shared<log4cxx::helpers::OnlyOnceErrorHandler>()),
+        closed(false){}
+
+    /** The layout variable does not need to be set if the appender
+    implementation has its own layout. */
+    LayoutPtr layout;
+
+    /** Appenders are named. */
+    LogString name;
+
+    /**
+    There is no level threshold filtering by default.  */
+    LevelPtr threshold;
+
+    /**
+    It is assumed and enforced that errorHandler is never null.
+    */
+    spi::ErrorHandlerPtr errorHandler;
+
+    /** The first filter in the filter chain. Set to <code>null</code>
+    initially. */
+    spi::FilterPtr headFilter;
+
+    /** The last filter in the filter chain. */
+    spi::FilterPtr tailFilter;
+
+    /**
+    Is this appender closed?
+    */
+    bool closed;
+
+    log4cxx::helpers::Pool pool;
+    mutable log4cxx::shared_mutex mutex;
+};
+
+}
+}
+
+#endif /* _LOG4CXX_APPENDERSKELETON_PRIV */
diff --git a/src/main/include/log4cxx/private/fileappender_priv.h b/src/main/include/log4cxx/private/fileappender_priv.h
new file mode 100644
index 0000000..fe9cf2d
--- /dev/null
+++ b/src/main/include/log4cxx/private/fileappender_priv.h
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_FILEAPPENDER_PRIV_H
+#define _LOG4CXX_FILEAPPENDER_PRIV_H
+
+#include <log4cxx/private/writerappender_priv.h>
+
+namespace log4cxx{
+namespace priv{
+
+struct FileAppenderPriv : public WriterAppenderPriv {
+    FileAppenderPriv() : WriterAppenderPriv(){}
+
+    FileAppenderPriv(LayoutPtr layout) : WriterAppenderPriv(layout){}
+
+    /** Append to or truncate the file? The default value for this
+    variable is <code>true</code>, meaning that by default a
+    <code>FileAppender</code> will append to an existing file and
+    not truncate it.
+    <p>This option is meaningful only if the FileAppender opens the
+    file.
+    */
+    bool fileAppend;
+
+    /**
+    The name of the log file. */
+    LogString fileName;
+
+    /**
+    Do we do bufferedIO? */
+    bool bufferedIO;
+
+    /**
+    How big should the IO buffer be? Default is 8K. */
+    int bufferSize;
+};
+
+}
+}
+
+#endif
diff --git a/src/main/include/log4cxx/private/nteventlogappender_priv.h b/src/main/include/log4cxx/private/nteventlogappender_priv.h
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/include/log4cxx/private/odbcappender_priv.h b/src/main/include/log4cxx/private/odbcappender_priv.h
new file mode 100644
index 0000000..e6c5a85
--- /dev/null
+++ b/src/main/include/log4cxx/private/odbcappender_priv.h
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/db/odbcappender.h>
+#include "appenderskeleton_priv.h"
+
+#include <list>
+
+namespace log4cxx{
+namespace priv{
+
+struct ODBCAppenderPriv : public AppenderSkeletonPrivate {
+    ODBCAppenderPriv() :
+        AppenderSkeletonPrivate(),
+        connection(nullptr),
+        env(nullptr),
+        bufferSize(1){}
+
+    /**
+    * URL of the DB for default connection handling
+    */
+    LogString databaseURL;
+
+    /**
+    * User to connect as for default connection handling
+    */
+    LogString databaseUser;
+
+    /**
+    * User to use for default connection handling
+    */
+    LogString databasePassword;
+
+    /**
+    * Connection used by default.  The connection is opened the first time it
+    * is needed and then held open until the appender is closed (usually at
+    * garbage collection).  This behavior is best modified by creating a
+    * sub-class and overriding the <code>getConnection</code> and
+    * <code>closeConnection</code> methods.
+    */
+    log4cxx::db::ODBCAppender::SQLHDBC connection;
+    log4cxx::db::ODBCAppender::SQLHENV env;
+
+    /**
+    * Stores the string given to the pattern layout for conversion into a SQL
+    * statement, eg: insert into LogTable (Thread, File, Message) values
+    * ("%t", "%F", "%m")
+    *
+    * Be careful of quotes in your messages!
+    *
+    * Also see PatternLayout.
+    */
+    LogString sqlStatement;
+
+    /**
+    * size of LoggingEvent buffer before writing to the database.
+    * Default is 1.
+    */
+    size_t bufferSize;
+
+    /**
+    * ArrayList holding the buffer of Logging Events.
+    */
+    std::list<spi::LoggingEventPtr> buffer;
+};
+
+}
+}
diff --git a/src/main/include/log4cxx/private/syslogappender_priv.h b/src/main/include/log4cxx/private/syslogappender_priv.h
new file mode 100644
index 0000000..2e4519b
--- /dev/null
+++ b/src/main/include/log4cxx/private/syslogappender_priv.h
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/syslogwriter.h>
+
+#include "appenderskeleton_priv.h"
+
+#include <log4cxx/private/log4cxx_private.h>
+
+#if LOG4CXX_HAVE_SYSLOG
+        #include <syslog.h>
+#else
+        /* facility codes */
+        #define   LOG_KERN (0<<3)   /* kernel messages */
+        #define   LOG_USER (1<<3)   /* random user-level messages */
+        #define   LOG_MAIL (2<<3)   /* mail system */
+        #define   LOG_DAEMON  (3<<3)   /* system daemons */
+        #define   LOG_AUTH (4<<3)   /* security/authorization messages */
+        #define   LOG_SYSLOG  (5<<3)   /* messages generated internally by syslogd */
+        #define   LOG_LPR     (6<<3)   /* line printer subsystem */
+        #define   LOG_NEWS (7<<3)   /* network news subsystem */
+        #define   LOG_UUCP (8<<3)   /* UUCP subsystem */
+        #define   LOG_CRON (9<<3)   /* clock daemon */
+        #define   LOG_AUTHPRIV   (10<<3)  /* security/authorization messages (private) */
+        #define   LOG_FTP     (11<<3)  /* ftp daemon */
+
+        /* other codes through 15 reserved for system use */
+        #define   LOG_LOCAL0  (16<<3)  /* reserved for local use */
+        #define   LOG_LOCAL1  (17<<3)  /* reserved for local use */
+        #define   LOG_LOCAL2  (18<<3)  /* reserved for local use */
+        #define   LOG_LOCAL3  (19<<3)  /* reserved for local use */
+        #define   LOG_LOCAL4  (20<<3)  /* reserved for local use */
+        #define   LOG_LOCAL5  (21<<3)  /* reserved for local use */
+        #define   LOG_LOCAL6  (22<<3)  /* reserved for local use */
+        #define   LOG_LOCAL7  (23<<3)  /* reserved for local use */
+#endif
+
+namespace log4cxx{
+namespace priv{
+
+struct SyslogAppenderPriv : public AppenderSkeletonPrivate{
+    SyslogAppenderPriv() :
+        AppenderSkeletonPrivate(),
+        syslogFacility(LOG_USER),
+        facilityPrinting(false),
+        maxMessageLength(1024){
+
+    }
+
+    SyslogAppenderPriv(const LayoutPtr& layout, int syslogFacility) :
+        AppenderSkeletonPrivate (layout),
+        syslogFacility(syslogFacility),
+        facilityPrinting(false),
+        maxMessageLength(1024){
+
+    }
+
+    SyslogAppenderPriv(const LayoutPtr& layout,
+                       const LogString& syslogHost, int syslogFacility) :
+        AppenderSkeletonPrivate(layout),
+        syslogFacility(syslogFacility),
+        facilityPrinting(false),
+        maxMessageLength(1024){
+
+    }
+
+    int syslogFacility; // Have LOG_USER as default
+    LogString facilityStr;
+    bool facilityPrinting;
+    std::unique_ptr<helpers::SyslogWriter> sw;
+    LogString syslogHost;
+    int syslogHostPort;
+    int maxMessageLength;
+};
+
+}
+}
diff --git a/src/main/include/log4cxx/private/writerappender_priv.h b/src/main/include/log4cxx/private/writerappender_priv.h
new file mode 100644
index 0000000..9ff3100
--- /dev/null
+++ b/src/main/include/log4cxx/private/writerappender_priv.h
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/writer.h>
+#include <atomic>
+
+#include "appenderskeleton_priv.h"
+
+#ifndef _LOG4CXX_WRITERAPPENDER_PRIV_H
+#define _LOG4CXX_WRITERAPPENDER_PRIV_H
+
+namespace log4cxx{
+namespace priv{
+
+struct WriterAppenderPriv : public priv::AppenderSkeletonPrivate {
+        WriterAppenderPriv() :
+	        AppenderSkeletonPrivate(),
+	        immediateFlush(true){}
+
+	WriterAppenderPriv(const LayoutPtr& layout1,
+	                                   log4cxx::helpers::WriterPtr& writer1) :
+	        AppenderSkeletonPrivate(layout1),
+	        immediateFlush(true),
+	        writer(writer1){
+	}
+
+	WriterAppenderPriv(const LayoutPtr& layout1) :
+	        AppenderSkeletonPrivate(layout1),
+	        immediateFlush(true){
+	}
+
+	/**
+	Immediate flush means that the underlying writer or output stream
+	will be flushed at the end of each append operation. Immediate
+	flush is slower but ensures that each append request is actually
+	written. If <code>immediateFlush</code> is set to
+	<code>false</code>, then there is a good chance that the last few
+	logs events are not actually written to persistent media if and
+	when the application crashes.
+
+	<p>The <code>immediateFlush</code> variable is set to
+	<code>true</code> by default.
+
+	*/
+	std::atomic<bool> immediateFlush;
+
+	/**
+	The encoding to use when opening an input stream.
+	<p>The <code>encoding</code> variable is set to <code>""</code> by
+	default which results in the utilization of the system's default
+	encoding.  */
+	LogString encoding;
+
+	/**
+	*  This is the {@link Writer Writer} where we will write to.
+	*/
+	log4cxx::helpers::WriterPtr writer;
+};
+
+}
+}
+
+#endif /* _LOG4CXX_WRITERAPPENDER_PRIV_H */
diff --git a/src/main/include/log4cxx/rolling/action.h b/src/main/include/log4cxx/rolling/action.h
index fc44978..31363d5 100644
--- a/src/main/include/log4cxx/rolling/action.h
+++ b/src/main/include/log4cxx/rolling/action.h
@@ -18,10 +18,10 @@
 #if !defined(_LOG4CXX_ROLLING_ACTION_H)
 #define _LOG4CXX_ROLLING_ACTION_H
 
-#include <log4cxx/portability.h>
 #include <log4cxx/helpers/object.h>
 #include <log4cxx/helpers/pool.h>
 #include <mutex>
+#include <memory>
 
 namespace log4cxx
 {
@@ -38,19 +38,9 @@ class Action : public virtual log4cxx::helpers::Object
 		BEGIN_LOG4CXX_CAST_MAP()
 		LOG4CXX_CAST_ENTRY(Action)
 		END_LOG4CXX_CAST_MAP()
-		/**
-		 * Is action complete.
-		 */
-		bool complete;
-
-		/**
-		 * Is action interrupted.
-		 */
-		bool interrupted;
-
-		log4cxx::helpers::Pool pool;
-		std::mutex mutex;
 
+		struct priv_data;
+		std::unique_ptr<priv_data> m_priv;
 
 	protected:
 		/**
diff --git a/src/main/include/log4cxx/rolling/rollingfileappender.h b/src/main/include/log4cxx/rolling/rollingfileappender.h
index 29ce553..db95090 100644
--- a/src/main/include/log4cxx/rolling/rollingfileappender.h
+++ b/src/main/include/log4cxx/rolling/rollingfileappender.h
@@ -18,8 +18,12 @@
 #if !defined(_LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_H)
 #define _LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_H
 
-#include <log4cxx/rolling/rollingfileappenderskeleton.h>
-
+#include <log4cxx/fileappender.h>
+#include <log4cxx/spi/optionhandler.h>
+#include <log4cxx/fileappender.h>
+#include <log4cxx/rolling/triggeringpolicy.h>
+#include <log4cxx/rolling/rollingpolicy.h>
+#include <log4cxx/rolling/action.h>
 
 namespace log4cxx
 {
@@ -72,20 +76,49 @@ namespace rolling
  *
  *
  * */
-class LOG4CXX_EXPORT RollingFileAppender : public RollingFileAppenderSkeleton
+class LOG4CXX_EXPORT RollingFileAppender : public FileAppender
 {
 		DECLARE_LOG4CXX_OBJECT(RollingFileAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
 		LOG4CXX_CAST_ENTRY(RollingFileAppender)
-		LOG4CXX_CAST_ENTRY_CHAIN(RollingFileAppenderSkeleton)
 		END_LOG4CXX_CAST_MAP()
 
 	public:
 		RollingFileAppender();
 
-		using RollingFileAppenderSkeleton::getRollingPolicy;
+		void activateOptions(log4cxx::helpers::Pool&);
+
+
+		/**
+		   Implements the usual roll over behaviour.
+
+		   <p>If <code>MaxBackupIndex</code> is positive, then files
+		   {<code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code>}
+		   are renamed to {<code>File.2</code>, ...,
+		   <code>File.MaxBackupIndex</code>}. Moreover, <code>File</code> is
+		   renamed <code>File.1</code> and closed. A new <code>File</code> is
+		   created to receive further log output.
+
+		   <p>If <code>MaxBackupIndex</code> is equal to zero, then the
+		   <code>File</code> is truncated with no backup files created.
+
+		 */
+		bool rollover(log4cxx::helpers::Pool& p);
+
+	protected:
+
+		/**
+		 Actual writing occurs here.
+		*/
+		virtual void subAppend(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p);
+
+		bool rolloverInternal(log4cxx::helpers::Pool& p);
+
+	public:
+
+		RollingPolicyPtr getRollingPolicy() const;
 
-		using RollingFileAppenderSkeleton::getTriggeringPolicy;
+		TriggeringPolicyPtr getTriggeringPolicy() const;
 
 		/**
 		 * Sets the rolling policy. In case the 'policy' argument also implements
@@ -93,9 +126,62 @@ class LOG4CXX_EXPORT RollingFileAppender : public RollingFileAppenderSkeleton
 		 * is automatically set to be the policy argument.
 		 * @param policy
 		 */
-		using RollingFileAppenderSkeleton::setRollingPolicy;
+		void setRollingPolicy(const RollingPolicyPtr& policy);
+
+		void setTriggeringPolicy(const TriggeringPolicyPtr& policy);
+
+	public:
+		/**
+		  * Close appender.  Waits for any asynchronous file compression actions to be completed.
+		*/
+		void close();
+
+	protected:
+		/**
+		   Returns an OutputStreamWriter when passed an OutputStream.  The
+		   encoding used will depend on the value of the
+		   <code>encoding</code> property.  If the encoding value is
+		   specified incorrectly the writer will be opened using the default
+		   system encoding (an error message will be printed to the loglog.
+		 @param os output stream, may not be null.
+		 @return new writer.
+		 */
+		log4cxx::helpers::WriterPtr createWriter(log4cxx::helpers::OutputStreamPtr& os);
+
+	public:
+
+
+
+		/**
+		 * Get byte length of current active log file.
+		 * @return byte length of current active log file.
+		 */
+		size_t getFileLength() const;
+
+#ifdef LOG4CXX_MULTI_PROCESS
+		/**
+		 * Set byte length of current active log file.
+		 * @return void
+		 */
+		void setFileLength(size_t length);
+
+		/**
+		 *  Release the file lock
+		 * @return void
+		 */
+		void releaseFileLock(apr_file_t* lock_file);
+		/**
+		 * re-open the latest file when its own handler has been renamed
+		 * @return void
+		 */
+		void reopenLatestFile(log4cxx::helpers::Pool& p);
+#endif
 
-		using RollingFileAppenderSkeleton::setTriggeringPolicy;
+		/**
+		 * Increments estimated byte length of current active log file.
+		 * @param increment additional bytes written to log file.
+		 */
+		void incrementFileLength(size_t increment);
 
 };
 
diff --git a/src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h b/src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h
index 1663fdf..3dfa395 100644
--- a/src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h
+++ b/src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h
@@ -18,7 +18,6 @@
 #if !defined(_LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_SKELETON_H)
 #define _LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_SKELETON_H
 
-#include <log4cxx/portability.h>
 #include <log4cxx/spi/optionhandler.h>
 #include <log4cxx/fileappender.h>
 #include <log4cxx/rolling/triggeringpolicy.h>
diff --git a/src/main/include/log4cxx/rolling/rollingpolicy.h b/src/main/include/log4cxx/rolling/rollingpolicy.h
index e5c38f2..3e82f08 100644
--- a/src/main/include/log4cxx/rolling/rollingpolicy.h
+++ b/src/main/include/log4cxx/rolling/rollingpolicy.h
@@ -18,7 +18,6 @@
 #if !defined(_LOG4CXX_ROLLING_ROLLING_POLICY_H)
 #define _LOG4CXX_ROLLING_ROLLING_POLICY_H
 
-#include <log4cxx/portability.h>
 #include <log4cxx/spi/optionhandler.h>
 #include <log4cxx/rolling/rolloverdescription.h>
 #include <log4cxx/file.h>
diff --git a/src/main/include/log4cxx/rolling/rolloverdescription.h b/src/main/include/log4cxx/rolling/rolloverdescription.h
index 30894ab..eabb29f 100644
--- a/src/main/include/log4cxx/rolling/rolloverdescription.h
+++ b/src/main/include/log4cxx/rolling/rolloverdescription.h
@@ -18,7 +18,6 @@
 #if !defined(_LOG4CXX_ROLLING_ROLLOVER_DESCRIPTION_H)
 #define _LOG4CXX_ROLLING_ROLLOVER_DESCRIPTION_H
 
-#include <log4cxx/portability.h>
 #include <log4cxx/rolling/action.h>
 
 namespace log4cxx
diff --git a/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h b/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
index ddeacf5..4d842d4 100755
--- a/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
+++ b/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
@@ -19,7 +19,6 @@
 #if !defined(_LOG4CXX_ROLLING_TIME_BASED_ROLLING_POLICY_H)
 #define _LOG4CXX_ROLLING_TIME_BASED_ROLLING_POLICY_H
 
-#include <log4cxx/portability.h>
 #include <log4cxx/rolling/rollingpolicybase.h>
 #include <log4cxx/rolling/triggeringpolicy.h>
 #include <log4cxx/writerappender.h>
diff --git a/src/main/include/log4cxx/writerappender.h b/src/main/include/log4cxx/writerappender.h
index ded462b..8dc9e62 100644
--- a/src/main/include/log4cxx/writerappender.h
+++ b/src/main/include/log4cxx/writerappender.h
@@ -36,40 +36,15 @@ namespace helpers
 class Transcoder;
 }
 
+namespace priv{
+struct WriterAppenderPriv;
+}
+
 /**
 WriterAppender appends log events to a standard output stream
 */
 class LOG4CXX_EXPORT WriterAppender : public AppenderSkeleton
 {
-	private:
-		/**
-		Immediate flush means that the underlying writer or output stream
-		will be flushed at the end of each append operation. Immediate
-		flush is slower but ensures that each append request is actually
-		written. If <code>immediateFlush</code> is set to
-		<code>false</code>, then there is a good chance that the last few
-		logs events are not actually written to persistent media if and
-		when the application crashes.
-
-		<p>The <code>immediateFlush</code> variable is set to
-		<code>true</code> by default.
-
-		*/
-		std::atomic<bool> immediateFlush;
-
-		/**
-		The encoding to use when opening an input stream.
-		<p>The <code>encoding</code> variable is set to <code>""</code> by
-		default which results in the utilization of the system's default
-		encoding.  */
-		LogString encoding;
-
-		/**
-		*  This is the {@link Writer Writer} where we will write to.
-		*/
-		log4cxx::helpers::WriterPtr writer;
-
-
 	public:
 		DECLARE_ABSTRACT_LOG4CXX_OBJECT(WriterAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
@@ -84,6 +59,7 @@ class LOG4CXX_EXPORT WriterAppender : public AppenderSkeleton
 		WriterAppender(const LayoutPtr& layout,
 			log4cxx::helpers::WriterPtr& writer);
 		WriterAppender(const LayoutPtr& layout);
+		WriterAppender(std::unique_ptr<priv::WriterAppenderPriv> priv);
 
 	public:
 		~WriterAppender();
@@ -112,10 +88,7 @@ class LOG4CXX_EXPORT WriterAppender : public AppenderSkeleton
 		/**
 		Returns value of the <b>ImmediateFlush</b> option.
 		*/
-		bool getImmediateFlush() const
-		{
-			return immediateFlush;
-		}
+		bool getImmediateFlush() const;
 
 		/**
 		This method is called by the AppenderSkeleton#doAppend
diff --git a/src/test/cpp/vectorappender.cpp b/src/test/cpp/vectorappender.cpp
index 262fbd6..13fa565 100644
--- a/src/test/cpp/vectorappender.cpp
+++ b/src/test/cpp/vectorappender.cpp
@@ -32,10 +32,10 @@ void VectorAppender::append(const spi::LoggingEventPtr& event, Pool& /*p*/)
 
 void VectorAppender::close()
 {
-	if (this->closed)
+	if (m_priv->closed)
 	{
 		return;
 	}
 
-	this->closed = true;
+	m_priv->closed = true;
 }
diff --git a/src/test/cpp/vectorappender.h b/src/test/cpp/vectorappender.h
index 2f6176f..2895e4f 100644
--- a/src/test/cpp/vectorappender.h
+++ b/src/test/cpp/vectorappender.h
@@ -18,6 +18,7 @@
 #include <log4cxx/appenderskeleton.h>
 #include <vector>
 #include <log4cxx/spi/loggingevent.h>
+#include <log4cxx/private/appenderskeleton_priv.h>
 
 namespace log4cxx
 {
@@ -53,7 +54,7 @@ class VectorAppender : public AppenderSkeleton
 
 		bool isClosed() const
 		{
-			return closed;
+			return m_priv->closed;
 		}
 
 		bool requiresLayout() const