diff --git a/src/basic_oarchive.cpp b/src/basic_oarchive.cpp
new file mode 100644
index 0000000..653260c
--- /dev/null
+++ b/src/basic_oarchive.cpp
@@ -0,0 +1,470 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// basic_oarchive.cpp:
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
+
+#include <boost/assert.hpp>
+#include <set>
+#include <cstddef> // NULL
+
+#include <boost/limits.hpp>
+
+// including this here to work around an ICC in intel 7.0
+// normally this would be part of basic_oarchive.hpp below.
+#define BOOST_ARCHIVE_SOURCE
+// include this to prevent linker errors when the
+// same modules are marked export and import.
+#define BOOST_SERIALIZATION_SOURCE
+#include <boost/serialization/config.hpp>
+#include <boost/serialization/state_saver.hpp>
+#include <boost/serialization/throw_exception.hpp>
+#include <boost/serialization/extended_type_info.hpp>
+
+#include <boost/archive/detail/decl.hpp>
+#include <boost/archive/basic_archive.hpp>
+#include <boost/archive/detail/basic_oserializer.hpp>
+#include <boost/archive/detail/basic_pointer_oserializer.hpp>
+#include <boost/archive/detail/basic_oarchive.hpp>
+#include <boost/archive/archive_exception.hpp>
+
+#ifdef BOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable : 4251 4231 4660 4275)
+#endif
+
+using namespace boost::serialization;
+
+namespace boost {
+namespace archive {
+namespace detail {
+
+class basic_oarchive_impl {
+    friend class basic_oarchive;
+    unsigned int m_flags;
+
+    //////////////////////////////////////////////////////////////////////
+    // information about each serialized object saved
+    // keyed on address, class_id
+    struct aobject
+    {
+        const void * address;
+        class_id_type class_id;
+        object_id_type object_id;
+
+        bool operator<(const aobject &rhs) const
+        {
+            BOOST_ASSERT(NULL != address);
+            BOOST_ASSERT(NULL != rhs.address);
+            if( address < rhs.address )
+                return true;
+            if( address > rhs.address )
+                return false;
+            return class_id < rhs.class_id;
+        }
+        aobject & operator=(const aobject & rhs)
+        {
+            address = rhs.address;
+            class_id = rhs.class_id;
+            object_id = rhs.object_id;
+            return *this;
+        }
+        aobject(
+            const void *a,
+            class_id_type class_id_,
+            object_id_type object_id_
+        ) :
+            address(a),
+            class_id(class_id_),
+            object_id(object_id_)
+        {}
+        aobject() : address(NULL){}
+    };
+    // keyed on class_id, address
+    typedef std::set<aobject> object_set_type;
+    object_set_type object_set;
+
+    //////////////////////////////////////////////////////////////////////
+    // information about each serialized class saved
+    // keyed on type_info
+    struct cobject_type
+    {
+        const basic_oserializer * m_bos_ptr;
+        const class_id_type m_class_id;
+        bool m_initialized;
+        cobject_type(
+            std::size_t class_id,
+            const basic_oserializer & bos
+        ) :
+            m_bos_ptr(& bos),
+            m_class_id(class_id),
+            m_initialized(false)
+        {}
+        cobject_type(const basic_oserializer & bos) :
+            m_bos_ptr(& bos),
+            m_initialized(false)
+        {}
+        cobject_type(
+            const cobject_type & rhs
+        ) :
+            m_bos_ptr(rhs.m_bos_ptr),
+            m_class_id(rhs.m_class_id),
+            m_initialized(rhs.m_initialized)
+        {}
+        // the following cannot be defined because of the const
+        // member.  This will generate a link error if an attempt
+        // is made to assign.  This should never be necessary
+        // use this only for lookup argument 
+        cobject_type & operator=(const cobject_type &rhs);
+        bool operator<(const cobject_type &rhs) const {
+            return *m_bos_ptr < *(rhs.m_bos_ptr);
+        }
+    };
+    // keyed on type_info
+    typedef std::set<cobject_type> cobject_info_set_type;
+    cobject_info_set_type cobject_info_set;
+
+    // list of objects initially stored as pointers - used to detect errors
+    // keyed on object id
+    std::set<object_id_type> stored_pointers;
+
+    // address of the most recent object serialized as a poiner
+    // whose data itself is now pending serialization
+    const void * pending_object;
+    const basic_oserializer * pending_bos;
+
+    basic_oarchive_impl(unsigned int flags) :
+        m_flags(flags),
+        pending_object(NULL),
+        pending_bos(NULL)
+    {}
+
+    const cobject_type &
+    find(const basic_oserializer & bos);
+    const basic_oserializer *  
+    find(const serialization::extended_type_info &ti) const;
+
+//public:
+    const cobject_type &
+    register_type(const basic_oserializer & bos);
+    void save_object(
+        basic_oarchive & ar,
+        const void *t,
+        const basic_oserializer & bos
+    );
+    void save_pointer(
+        basic_oarchive & ar,
+        const void * t, 
+        const basic_pointer_oserializer * bpos
+    );
+};
+
+//////////////////////////////////////////////////////////////////////
+// basic_oarchive implementation functions
+
+// given a type_info - find its bos
+// return NULL if not found
+inline const basic_oserializer *
+basic_oarchive_impl::find(const serialization::extended_type_info & ti) const {
+    #ifdef BOOST_MSVC
+    #  pragma warning(push)
+    #  pragma warning(disable : 4511 4512)
+    #endif
+    class bosarg : 
+        public basic_oserializer
+    {
+        bool class_info() const {
+            BOOST_ASSERT(false); 
+            return false;
+        }
+        // returns true if objects should be tracked
+        bool tracking(const unsigned int) const {
+            BOOST_ASSERT(false);
+            return false;
+        }
+        // returns class version
+        version_type version() const {
+            BOOST_ASSERT(false);
+            return version_type(0);
+        }
+        // returns true if this class is polymorphic
+        bool is_polymorphic() const{
+            BOOST_ASSERT(false);
+            return false;
+        }
+        void save_object_data(      
+            basic_oarchive & /*ar*/, const void * /*x*/
+        ) const {
+            BOOST_ASSERT(false);
+        }
+    public:
+        bosarg(const serialization::extended_type_info & eti) :
+          boost::archive::detail::basic_oserializer(eti)
+        {}
+    };
+    #ifdef BOOST_MSVC
+    #pragma warning(pop)
+    #endif
+    bosarg bos(ti);
+    cobject_info_set_type::const_iterator cit 
+        = cobject_info_set.find(cobject_type(bos));
+    // it should already have been "registered" - see below
+    if(cit == cobject_info_set.end()){
+        // if an entry is not found in the table it is because a pointer
+        // of a derived class has been serialized through its base class
+        // but the derived class hasn't been "registered" 
+        return NULL;
+    }
+    // return pointer to the real class
+    return cit->m_bos_ptr;
+}
+
+inline const basic_oarchive_impl::cobject_type &
+basic_oarchive_impl::find(const basic_oserializer & bos)
+{
+    std::pair<cobject_info_set_type::iterator, bool> cresult = 
+        cobject_info_set.insert(cobject_type(cobject_info_set.size(), bos));
+    return *(cresult.first);
+}
+
+inline const basic_oarchive_impl::cobject_type &
+basic_oarchive_impl::register_type(
+    const basic_oserializer & bos
+){
+    cobject_type co(cobject_info_set.size(), bos);
+    std::pair<cobject_info_set_type::const_iterator, bool>
+        result = cobject_info_set.insert(co);
+    return *(result.first);
+}
+
+inline void
+basic_oarchive_impl::save_object(
+    basic_oarchive & ar,
+    const void *t,
+    const basic_oserializer & bos
+){
+    // if its been serialized through a pointer and the preamble's been done
+    if(t == pending_object && pending_bos == & bos){
+        // just save the object data
+        ar.end_preamble();
+        (bos.save_object_data)(ar, t);
+        return;
+    }
+
+    // get class information for this object
+    const cobject_type & co = register_type(bos);
+    if(bos.class_info()){
+        if( ! co.m_initialized){
+            ar.vsave(class_id_optional_type(co.m_class_id));
+            ar.vsave(tracking_type(bos.tracking(m_flags)));
+            ar.vsave(version_type(bos.version()));
+            (const_cast<cobject_type &>(co)).m_initialized = true;
+        }
+    }
+
+    // we're not tracking this type of object
+    if(! bos.tracking(m_flags)){
+        // just windup the preamble - no object id to write
+        ar.end_preamble();
+        // and save the data
+        (bos.save_object_data)(ar, t);
+        return;
+    }
+
+    // look for an existing object id
+    object_id_type oid(object_set.size());
+    // lookup to see if this object has already been written to the archive
+    basic_oarchive_impl::aobject ao(t, co.m_class_id, oid);
+    std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool>
+        aresult = object_set.insert(ao);
+    oid = aresult.first->object_id;
+
+    // if its a new object
+    if(aresult.second){
+        // write out the object id
+        ar.vsave(oid);
+        ar.end_preamble();
+        // and data
+        (bos.save_object_data)(ar, t);
+        return;
+    }
+
+    // check that it wasn't originally stored through a pointer
+    if(stored_pointers.end() != stored_pointers.find(oid)){
+        // this has to be a user error.  loading such an archive
+        // would create duplicate objects
+        boost::serialization::throw_exception(
+            archive_exception(archive_exception::pointer_conflict)
+        );
+    }
+    // just save the object id
+    ar.vsave(object_reference_type(oid));
+    ar.end_preamble();
+    return;
+}
+
+// save a pointer to an object instance
+inline void
+basic_oarchive_impl::save_pointer(
+    basic_oarchive & ar,
+    const void * t, 
+    const basic_pointer_oserializer * bpos_ptr
+){
+    const basic_oserializer & bos = bpos_ptr->get_basic_serializer();
+    std::size_t original_count = cobject_info_set.size();
+    const cobject_type & co = register_type(bos);
+    if(! co.m_initialized){
+        ar.vsave(co.m_class_id);
+        // if its a previously unregistered class 
+        if((cobject_info_set.size() > original_count)){
+            if(bos.is_polymorphic()){
+                const serialization::extended_type_info *eti = & bos.get_eti();
+                const char * key = NULL;
+                if(NULL != eti)
+                    key = eti->get_key();
+                if(NULL != key){
+                    // the following is required by IBM C++ compiler which
+                    // makes a copy when passing a non-const to a const.  This
+                    // is permitted by the standard but rarely seen in practice
+                    const class_name_type cn(key);
+                    if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
+                        boost::serialization::throw_exception(
+                            boost::archive::archive_exception(
+                                boost::archive::archive_exception::
+                                    invalid_class_name)
+                            );
+                    // write out the external class identifier
+                    ar.vsave(cn);
+                }
+                else
+                    // without an external class name
+                    // we won't be able to de-serialize it so bail now
+                    boost::serialization::throw_exception(
+                        archive_exception(archive_exception::unregistered_class)
+                    );
+            }
+        }
+        if(bos.class_info()){
+            ar.vsave(tracking_type(bos.tracking(m_flags)));
+            ar.vsave(version_type(bos.version()));
+        }
+        (const_cast<cobject_type &>(co)).m_initialized = true;
+    }
+    else{
+        ar.vsave(class_id_reference_type(co.m_class_id));
+    }
+
+    // if we're not tracking
+    if(! bos.tracking(m_flags)){
+        // just save the data itself
+        ar.end_preamble();
+        serialization::state_saver<const void *> x(pending_object);
+        serialization::state_saver<const basic_oserializer *> y(pending_bos);
+        pending_object = t;
+        pending_bos = & bpos_ptr->get_basic_serializer();
+        bpos_ptr->save_object_ptr(ar, t);
+        return;
+    }
+
+    object_id_type oid(object_set.size());
+    // lookup to see if this object has already been written to the archive
+    basic_oarchive_impl::aobject ao(t, co.m_class_id, oid);
+    std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool>
+        aresult = object_set.insert(ao);
+    oid = aresult.first->object_id;
+    // if the saved object already exists
+    if(! aresult.second){
+        // append the object id to he preamble
+        ar.vsave(object_reference_type(oid));
+        // and windup.
+        ar.end_preamble();
+        return;
+    }
+
+    // append id of this object to preamble
+    ar.vsave(oid);
+    ar.end_preamble();
+
+    // and save the object itself
+    serialization::state_saver<const void *> x(pending_object);
+    serialization::state_saver<const basic_oserializer *> y(pending_bos);
+    pending_object = t;
+    pending_bos = & bpos_ptr->get_basic_serializer();
+    bpos_ptr->save_object_ptr(ar, t);
+    // add to the set of object initially stored through pointers
+    stored_pointers.insert(oid);
+}
+
+} // namespace detail
+} // namespace archive
+} // namespace boost
+
+//////////////////////////////////////////////////////////////////////
+// implementation of basic_oarchive functions
+
+namespace boost {
+namespace archive {
+namespace detail {
+
+BOOST_ARCHIVE_DECL 
+basic_oarchive::basic_oarchive(unsigned int flags)
+    : pimpl(new basic_oarchive_impl(flags))
+{}
+
+BOOST_ARCHIVE_DECL 
+basic_oarchive::~basic_oarchive()
+{}
+
+BOOST_ARCHIVE_DECL void 
+basic_oarchive::save_object(
+    const void *x, 
+    const basic_oserializer & bos
+){
+    pimpl->save_object(*this, x, bos);
+}
+
+BOOST_ARCHIVE_DECL void 
+basic_oarchive::save_pointer(
+    const void * t, 
+    const basic_pointer_oserializer * bpos_ptr
+){
+    pimpl->save_pointer(*this, t, bpos_ptr);
+}
+
+BOOST_ARCHIVE_DECL void 
+basic_oarchive::register_basic_serializer(const basic_oserializer & bos){
+    pimpl->register_type(bos);
+}
+
+BOOST_ARCHIVE_DECL library_version_type
+basic_oarchive::get_library_version() const{
+    return BOOST_ARCHIVE_VERSION();
+}
+
+BOOST_ARCHIVE_DECL unsigned int
+basic_oarchive::get_flags() const{
+    return pimpl->m_flags;
+}
+
+BOOST_ARCHIVE_DECL void 
+basic_oarchive::end_preamble(){
+}
+
+BOOST_ARCHIVE_DECL helper_collection &
+basic_oarchive::get_helper_collection(){
+	return *this;
+}
+
+} // namespace detail
+} // namespace archive
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
