void Universe::serialize(Archive& ar, const unsigned int version)
{
    ObjectMap                       objects;
    EmpireObjectMap                 empire_latest_known_objects;
    EmpireObjectVisibilityMap       empire_object_visibility;
    EmpireObjectVisibilityTurnMap   empire_object_visibility_turns;
    ObjectKnowledgeMap              empire_known_destroyed_object_ids;
    ShipDesignMap                   ship_designs;

    ar.template register_type<System>();

    if (Archive::is_saving::value) {
        GetObjectsToSerialize(              objects,                            s_encoding_empire);
        GetEmpireKnownObjectsToSerialize(   empire_latest_known_objects,        s_encoding_empire);
        GetEmpireObjectVisibilityMap(       empire_object_visibility,           s_encoding_empire);
        GetEmpireObjectVisibilityTurnMap(   empire_object_visibility_turns,     s_encoding_empire);
        GetEmpireKnownDestroyedObjects(     empire_known_destroyed_object_ids,  s_encoding_empire);
        GetShipDesignsToSerialize(          ship_designs,                       s_encoding_empire);
    }

    if (Archive::is_loading::value) {
        Clear();    // clean up any existing dynamically allocated contents before replacing containers with deserialized data
    }

    ar  & BOOST_SERIALIZATION_NVP(s_universe_width)
        & BOOST_SERIALIZATION_NVP(ship_designs)
        & BOOST_SERIALIZATION_NVP(m_empire_known_ship_design_ids)
        & BOOST_SERIALIZATION_NVP(empire_object_visibility)
        & BOOST_SERIALIZATION_NVP(empire_object_visibility_turns)
        & BOOST_SERIALIZATION_NVP(empire_known_destroyed_object_ids)
        & BOOST_SERIALIZATION_NVP(objects)
        & BOOST_SERIALIZATION_NVP(empire_latest_known_objects)
        & BOOST_SERIALIZATION_NVP(m_last_allocated_object_id)
        & BOOST_SERIALIZATION_NVP(m_last_allocated_design_id);

    if (Archive::is_saving::value) {
        // clean up temporary objects in temporary ObjectMaps
        objects.Clear();
        for (EmpireObjectMap::iterator it = empire_latest_known_objects.begin(); it != empire_latest_known_objects.end(); ++it)
            it->second.Clear();
    }

    if (Archive::is_loading::value) {
        m_objects.swap(objects);
        m_empire_latest_known_objects.swap(empire_latest_known_objects);
        m_empire_object_visibility.swap(empire_object_visibility);
        m_empire_object_visibility_turns.swap(empire_object_visibility_turns);
        m_empire_known_destroyed_object_ids.swap(empire_known_destroyed_object_ids);
        m_ship_designs.swap(ship_designs);
        InitializeSystemGraph(s_encoding_empire);
    }
}
void Universe::serialize(Archive& ar, const unsigned int version)
{
    ObjectMap                       objects;
    EmpireObjectMap                 empire_latest_known_objects;
    EmpireObjectVisibilityMap       empire_object_visibility;
    EmpireObjectVisibilityTurnMap   empire_object_visibility_turns;
    ObjectKnowledgeMap              empire_known_destroyed_object_ids;
    ObjectKnowledgeMap              empire_stale_knowledge_object_ids;
    ShipDesignMap                   ship_designs;

    ar.template register_type<System>();

    if (Archive::is_saving::value) {
        Logger().debugStream() << "Universe::serialize : Getting gamestate data";
        GetObjectsToSerialize(              objects,                            m_encoding_empire);
        GetEmpireKnownObjectsToSerialize(   empire_latest_known_objects,        m_encoding_empire);
        GetEmpireObjectVisibilityMap(       empire_object_visibility,           m_encoding_empire);
        GetEmpireObjectVisibilityTurnMap(   empire_object_visibility_turns,     m_encoding_empire);
        GetEmpireKnownDestroyedObjects(     empire_known_destroyed_object_ids,  m_encoding_empire);
        GetEmpireStaleKnowledgeObjects(     empire_stale_knowledge_object_ids,  m_encoding_empire);
        GetShipDesignsToSerialize(          ship_designs,                       m_encoding_empire);
    }

    if (Archive::is_loading::value) {
        Clear();    // clean up any existing dynamically allocated contents before replacing containers with deserialized data
    }

    Logger().debugStream() << "Universe::serialize : (de)serializing universe width";
    ar  & BOOST_SERIALIZATION_NVP(m_universe_width);
    Logger().debugStream() << "Universe::serialize : (de)serializing ship designs";
    ar  & BOOST_SERIALIZATION_NVP(ship_designs);
    ar  & BOOST_SERIALIZATION_NVP(m_empire_known_ship_design_ids);
    Logger().debugStream() << "Universe::serialize : (de)serializing empire object visibility";
    ar  & BOOST_SERIALIZATION_NVP(empire_object_visibility);
    ar  & BOOST_SERIALIZATION_NVP(empire_object_visibility_turns);
    ar  & BOOST_SERIALIZATION_NVP(empire_known_destroyed_object_ids);
    ar  & BOOST_SERIALIZATION_NVP(empire_stale_knowledge_object_ids);
    Logger().debugStream() << "Universe::serialize : (de)serializing actual objects";
    ar  & BOOST_SERIALIZATION_NVP(objects);
    Logger().debugStream() << "Universe::serialize : (de)serializing empre known objects";
    ar  & BOOST_SERIALIZATION_NVP(empire_latest_known_objects);
    Logger().debugStream() << "Universe::serialize : (de)serializing last allocated ids";
    ar  & BOOST_SERIALIZATION_NVP(m_last_allocated_object_id);
    ar  & BOOST_SERIALIZATION_NVP(m_last_allocated_design_id);
    Logger().debugStream() << "Universe::serialize : (de)serializing done";

    if (Archive::is_saving::value) {
        Logger().debugStream() << "Universe::serialize : Cleaning up temporary data";
        // clean up temporary objects in temporary ObjectMaps
        objects.Clear();
        for (EmpireObjectMap::iterator it = empire_latest_known_objects.begin();
             it != empire_latest_known_objects.end(); ++it)
        { it->second.Clear(); }
    }

    if (Archive::is_loading::value) {
        Logger().debugStream() << "Universe::serialize : Swapping old/new data";
        m_objects.swap(objects);
        m_empire_latest_known_objects.swap(empire_latest_known_objects);
        m_empire_object_visibility.swap(empire_object_visibility);
        m_empire_object_visibility_turns.swap(empire_object_visibility_turns);
        m_empire_known_destroyed_object_ids.swap(empire_known_destroyed_object_ids);
        m_empire_stale_knowledge_object_ids.swap(empire_stale_knowledge_object_ids);
        m_ship_designs.swap(ship_designs);
    }
}