[mapguide-commits] r7187 - in sandbox/adsk/2.4k: . Common/CoordinateSystem Common/Geometry/CoordinateSystem Common/MapGuideCommon/System Server/src/Core Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sun Nov 4 12:24:23 PST 2012


Author: baertelchen
Date: 2012-11-04 12:24:23 -0800 (Sun, 04 Nov 2012)
New Revision: 7187

Modified:
   sandbox/adsk/2.4k/
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDatumDictionary.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionary.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCategory.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysUtil.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.cpp
   sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/CsmapVersion.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/MentorDictionary.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/MentorUtil.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/SmartCriticalClass.h
   sandbox/adsk/2.4k/Common/CoordinateSystem/namestruct.h
   sandbox/adsk/2.4k/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h
   sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.cpp
   sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.h
   sandbox/adsk/2.4k/Server/src/Core/Server.cpp
   sandbox/adsk/2.4k/Server/src/Core/serverconfig.ini
   sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.cpp
   sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.h
Log:
Merged revisions [7097,7111] of /MgDev/trunk into /sandbox/adsk/2.4k

These 2 revisions have been created for RFC127.
All changes in the trunk had been originally reviewed by Hugues.

See the details of the source revisions of the merge below:

+++ === +++ === +++
+++ Revision: 7097
+++ === +++ === +++
First drop of the RFC 127 implementation

This is the first drop of changes to implement RFC 127 "Change Coordinate System API (MgGeometry) to adopt changes proposed by CS-Map RFC6" 

In this first submission, the following main changes are contained:

1) Add the necessary API to the [MgCoordinateSystemCatalog] class:
GetDefaultUserDictionaryDir
SetUserDictionaryDir
GetUserDictionaryDir

1) Change the CCoordinateSystemCategory and CCoordinateSystemCategoryDictionary class to use the CS-Map API instead of
its own implementation to read/write the category information.

2) Changes all generic dictionary code that would call into the CS_[...]rd() functions to use the new CS_[...]rdAll() functions provided by
CS-Map.

3) Unit tests updates:
I have added some new unit tests to the TestCoordinateSystem.h/cpp module.
Those include full reading of the dictionaries as well as some update tests with & without
having a path set for user-defined dictionaries.

At the moment, it's not yet possible to initialize the 'user dictionary dir' from the serverconfig.ini file.

+++ === +++ === +++
+++ Revision: 7111
+++ === +++ === +++
Support MentorUserDictionaryPath in serverconfig.ini (part of RFC 127)

Implemented support for the [MentorUserDictionaryPath] setting in the serverconfig.ini file.
If that setting is available (i.e. not an empty string), the server startup code will call into
the MgCoordinateSystemCatalog's SetUserDictionaryDir() method thus overriding
the default location of the user dictionary path - which may or may not have been set before.

While an invalid [MentorDictionaryPath] setting leads to the server to failing to startup, an invalid
[MentorUserDictionaryPath] does not. It will be logged as a warning though.


Property changes on: sandbox/adsk/2.4k
___________________________________________________________________
Modified: svn:mergeinfo
   - /sandbox/rfc94:5099-5163
/trunk/MgDev:6346
   + /sandbox/rfc94:5099-5163
/trunk/MgDev:6346,7097,7111

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -278,19 +278,21 @@
 
 //Sets the complete path to the directory where the dictionaries are
 //located.  This method can be invoked only when not
-//currently connected to a dictionary database.  This method does not
-//perform any validation on the specified dictionary path.  Instead,
-//full validation is performed by the OpenDictionaries() method.
-//Throws an exception MgCoordinateSystemCatalogIsOpenException if already connected to a
-//dictionary database
-//
-void CCoordinateSystemCatalog::SetDictionaryDir(CREFSTRING sDirPath)
+//currently connected to a dictionary database.  This method just verifies that
+//the dictionary path exists, and, if appropriate, whether a file named Coordsys.CSD could be found-
+//Full validation is performed later on by the OpenDictionaries() method.
+//Throws [MgFileIoException] if the targeted directory is invalid and/or cannot be accessed in the
+//in the mode indicated by [dirWriteAccess]
+
+STRING CCoordinateSystemCatalog::SetDictionaryDir(CREFSTRING sDirPath, bool dirWriteAccess, int (*CsMapDirFunc)(const char *pszDirectoryPath))
 {
-    MG_TRY()
+    if (NULL == CsMapDirFunc)
+        throw new MgNullArgumentException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
 
     if (sDirPath.empty())
     {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
+        CsMapDirFunc("");
+        return L"";
     }
 
 #ifdef _WIN32
@@ -302,14 +304,14 @@
     wchar_t szDir[_MAX_DIR] = {0};
     wchar_t szFname[_MAX_FNAME] = {0};
     wchar_t szExt[_MAX_EXT] = {0};
-    _tsplitpath(sDirPath.c_str(), szDrive, szDir, szFname, szExt);
+
+    //make sure, we don't have any '/' in the string that CS-Map could stumble over
+    STRING sPathCopy = sDirPath;
+    std::replace(sPathCopy.begin(), sPathCopy.end(), L'/', L'\\');
+
+    _tsplitpath(sPathCopy.c_str(), szDrive, szDir, szFname, szExt);
     if ((_tcslen(szFname) > 0) || (_tcslen(szExt) > 0))
     {
-        //ABA: don't understand: if a filename or an extension has been found,
-        //we concatenate the filename to the directory + then the extension;
-        //Then, we call makepath() what will give us a full path information incl.
-        //the file name;
-        //
         //Nope, not properly terminated, need to fix it.
         assert(_tcslen(szDir) + _tcslen(szFname) + _tcslen(szExt) < _MAX_DIR);
         _tcscat(szDir, szFname);
@@ -337,22 +339,36 @@
         szPath,    //path to directory
         true,    //must exist
         true,    //must be a directory
-        false,    //must be writable?
+        dirWriteAccess,    //must be writable?
         &reason))
     {
         ThrowFileError(L"MgCoordinateSystemCatalog.SetDictionaryDir", szPath, reason);
     }
 
-    m_sDir = szPath;
-    m_libraryStatus = lsInitializationFailed; 
-
-    //initializes Mentor
-    char* pszPath=Convert_Wide_To_Ascii(szPath);
-    CriticalClass.Enter();
-    CS_altdr(pszPath);
-    CriticalClass.Leave();
+    //initializes CS-Map's target directory function with the new path
+    SmartCriticalClass csmapLock;
+    char* pszPath = Convert_Wide_To_Ascii(szPath);
+    int csmapResult = CsMapDirFunc(pszPath);
     delete[] pszPath;
 
+    //CS-Map return -1 if for cs_altdr() the Coordsys.CSD file couldn't be found; 0 otherwise
+
+    if (csmapResult)
+        throw new MgFileIoException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    return szPath;
+}
+
+void CCoordinateSystemCatalog::SetDictionaryDir(CREFSTRING sDirPath)
+{
+    MG_TRY()
+
+    if (sDirPath.empty())
+        throw new MgInvalidArgumentException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    m_libraryStatus = lsInitializationFailed;
+    m_sDir = this->SetDictionaryDir(sDirPath, false, CS_altdr);
+
     //now need to validate the dictionary files
     //an reinitialize their internal data
     STRING sCs=m_pCsDict->GetFileName();
@@ -376,6 +392,67 @@
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetDictionaryDir")
 }
 
+STRING CCoordinateSystemCatalog::GetDefaultUserDictionaryDir()
+{
+    STRING defaultUserDir;
+
+#ifdef _WIN32
+
+    //let the [MENTOR_USER_DICTIONARY_PATH] environment variable override the
+    //the default path - which on Windows systems is the "(user-)Local app data path\Autodesk\User Geospatial Coordinate Systems"
+
+    // Check to see if the environment variable is set
+    const TCHAR* szPathVar = _tgetenv(_T(MENTOR_USER_DICTIONARY_PATH));
+    bool variableDefined = (szPathVar && L'\0' != *szPathVar);
+
+    if(!variableDefined)
+    {
+        TCHAR szPath[MAX_PATH] = { L'\0' };
+        if(TRUE == SHGetSpecialFolderPath(NULL, szPath, CSIDL_LOCAL_APPDATA, FALSE))
+        {
+            defaultUserDir = szPath;
+            defaultUserDir += _T("\\Autodesk\\User Geospatial Coordinate Systems"); //NOXLATE
+        }
+    }
+
+    if (!defaultUserDir.empty() && L'\\' != defaultUserDir[defaultUserDir.length() - 1])
+        defaultUserDir.append(L"\\");
+
+#else
+
+    char* szPath = getenv(MENTOR_USER_DICTIONARY_PATH);
+    bool variableDefined = (szPath && L'\0' != *szPath);
+
+    if (variableDefined)
+    {
+        MgUtil::MultiByteToWideChar(string(szPath), defaultUserDir);
+        if(L'/' != defaultUserDir[defaultUserDir.length() - 1])
+            defaultUserDir.append(L"/");
+    }
+
+#endif
+
+    if (defaultUserDir.empty())
+        return L"";
+
+
+    return defaultUserDir.c_str();
+}
+
+void CCoordinateSystemCatalog::SetUserDictionaryDir(CREFSTRING sDirPath)
+{
+    MG_TRY()
+
+        m_sUserDir = this->SetDictionaryDir(sDirPath /* can be empty */, true, CS_usrdr);
+
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetUserDictionaryDir")
+}
+
+STRING CCoordinateSystemCatalog::GetUserDictionaryDir()
+{
+    return m_sUserDir;
+}
+
 //cgeck if the files are writable
 //The read mode was tracked down when the file names were set up
 //if the files were not valif an assertion was thorwn at that time
@@ -500,9 +577,39 @@
     m_pGpDict->SetFileName(sGp);
     m_pGxDict->SetFileName(sGx);
 
-    m_libraryStatus=lsInitialized;
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetDefaultDictionaryDirAndFileNames")
 
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetDefaultDictionaryDirAndFileNames")
+    STRING sDefUserDictionaryDir;
+    {
+        MG_TRY()
+
+            //Get the default path where to store the custom CS information
+            //note, that we don't require that to be available for (the server
+            sDefUserDictionaryDir = this->GetDefaultUserDictionaryDir();
+            if (!sDefUserDictionaryDir.empty())
+            {
+                this->SetUserDictionaryDir(sDefUserDictionaryDir);
+            }
+
+        MG_CATCH_AND_RELEASE()
+
+        #ifdef _DEBUG
+            if (NULL != mgException)
+            {
+                _ASSERT(!sDefUserDictionaryDir.empty());
+                //log the fact, that we couldn't set the right user dictionary dir
+                ACE_DEBUG((LM_DEBUG, ACE_TEXT("\n(%t) CCoordinateSystemCatalog::SetDefaultDictionaryDirAndFileNames() - The directory to store user defined CS information could not be set using this directory\n%W.\n"), 
+                    sDefUserDictionaryDir.c_str()));
+            }
+            else if (!sDefUserDictionaryDir.empty())
+            {
+                ACE_DEBUG((LM_DEBUG, ACE_TEXT("\n(%t) CCoordinateSystemCatalog::SetDefaultDictionaryDirAndFileNames() - The directory to store user defined CS information in has been set to \n%W.\n"), 
+                        sDefUserDictionaryDir.c_str()));
+            }
+        #endif
+    }
+
+    m_libraryStatus = lsInitialized;
 }
 
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCatalog.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -41,6 +41,10 @@
     virtual bool AreDictionaryFilesWritable();
     virtual STRING GetDictionaryDir();
 
+    virtual STRING GetDefaultUserDictionaryDir();
+    virtual void SetUserDictionaryDir(CREFSTRING sDirPath);
+    virtual STRING GetUserDictionaryDir();
+
     virtual void SetProtectionMode(INT16 nMode);
     virtual INT16 GetProtectionMode();
     virtual MgCoordinateSystemCategoryDictionary* GetCategoryDictionary();
@@ -76,6 +80,7 @@
 protected:
     //Data members
     STRING m_sDir;
+    STRING m_sUserDir;
 
     Ptr<CCoordinateSystemDictionary> m_pCsDict;
     Ptr<CCoordinateSystemDatumDictionary> m_pDtDict;
@@ -90,6 +95,8 @@
     //Unimplemented stuff
     CCoordinateSystemCatalog(const CCoordinateSystemCatalog&);
     CCoordinateSystemCatalog& operator=(const CCoordinateSystemCatalog&);
+
+    STRING SetDictionaryDir(CREFSTRING sDirPath, bool dirWriteAccess, int (*CsMapDirFunc)(const char *pszDirectoryPath));
 };
 
 } // End of namespace

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -15,6 +15,8 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
+#include <vector>
+
 #include "GeometryCommon.h"
 #include "CoordSysCommon.h"
 
@@ -24,302 +26,132 @@
 #include "MentorUtil.h"                            //for IsLegalMentorName
 #include <algorithm>                            //for std::find
 
+#include "cs_map.h"
+
+using namespace std;
 using namespace CSLibrary;
 
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CCoordinateSystemCategory::CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog)
+extern "C"
 {
-    m_pCatalog = SAFE_ADDREF(pCatalog);
+    extern int cs_Error;
 }
 
-CCoordinateSystemCategory::~CCoordinateSystemCategory()
+void CCoordinateSystemCategory::CtorInit(CCoordinateSystemCategory* pToInitialize, MgCoordinateSystemCatalog *pCatalog,
+    cs_Ctdef_* pSourceCtDef,
+    bool copyDef)
 {
-}
+    if (NULL == pCatalog)
+        throw new MgNullArgumentException(L"MgCoordinateSystemCategory.MgCoordinateSystemCategory()", __LINE__, __WFILE__, NULL, L"", NULL);
 
-//MgDisposable
-void CCoordinateSystemCategory::Dispose()
-{
-    delete this;
-}
+    _ASSERT(NULL != pToInitialize && NULL == pToInitialize->mp_ctDef);
 
-//Gets the name of the category definition.
-//
-char * CCoordinateSystemCategory::Name()
-{
-    return const_cast<char*>(m_categoryName.Name());
-}
-
-//Saves the object to a file.  Purpose of the ulMinSize parameter:
-//A category definition is, of necessity, a variable-length record
-//in a file, since it can contain an arbitrary number of coordinate
-//systems.  Therefore, when written, it stores the number of coordinate
-//systems which it contains.  However, suppose you have a file which
-//consists of a bunch of category definitions, one after the other,
-//and you modify one of them by deleting a single coordinate system
-//from it, thereby making it a bit smaller.  In that case, it seems
-//inefficient to have to re-write the entire file, compacting it; better
-//to simply be slightly disk-space-inefficient, write the individual
-//record in situ, and mark it so that the reader knows to skip a bit
-//of space.  Thus, a category definition in a disk file actually stores
-//two numbers:  how many coordinate systems it actually contains,
-//and how much space (in terms of number of coordinate systems) it
-//occupies in the disk file.  The second number will be greater than
-//or equal to the first.  The first number will always be supplied by
-//the category definition itself, but the caller needs to supply the
-//second number, which the ulMinSize parameter supplies.
-//
-//This function returns true for success, false for failure.  If the
-//ulMinSize parameter is less than the number of coordinate systems
-//in the category, it will be ignored.
-//
-void CCoordinateSystemCategory::SaveToFstream(csFILE *pFile, UINT32 ulMinSize)
-{
-    long previousPosition = -1;
-    MG_TRY()
-
-    UINT32 ulSize = static_cast<UINT32>(m_listCoordinateSystemNames.size());
-    if (ulMinSize < ulSize)
+    cs_Ctdef_ *pCategoryCopy = NULL;
+    if (NULL != pSourceCtDef)
     {
-        ulMinSize = ulSize;
+        if (copyDef)
+            pCategoryCopy = CScpyCategory(pSourceCtDef);
+        else
+            pCategoryCopy = pSourceCtDef;
     }
-
-    //make sure the file is okay
-    if (!pFile || -1==CS_ftell(pFile))
+    else
     {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.SaveToFstream", __LINE__, __WFILE__, NULL, L"", NULL);
+        pCategoryCopy = CSnewCategory(NULL);
     }
-    if (ferror(pFile))
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.SaveToFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    previousPosition = CS_ftell(pFile);    //in case of error
 
-    //We write in this order:
-    // 1. Name
-    // 2. Size (actual number of coordinate systems)
-    // 3. File size (ulMinSize; see description above)
-    // 4. The coordinate system names
-    // 5. Blank space (if ulMinSize > size)
+    if (NULL == pCategoryCopy)
+        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.CtorInit", __LINE__, __WFILE__, NULL, L"", NULL);
 
-    //Name.
-    CS_fwrite(m_categoryName.Name(), sizeof(char), knMaxCategoryNameLen, pFile);
+    pToInitialize->m_pCatalog = SAFE_ADDREF(pCatalog);
+    pToInitialize->mp_ctDef = pCategoryCopy;
+}
 
-    //Size.
-    CS_fwrite(reinterpret_cast<char *>(&ulSize), sizeof(ulSize), 1, pFile);
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemCategory::CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog)
+    : mp_ctDef(NULL)
+{
+    CCoordinateSystemCategory::CtorInit(this, pCatalog);
+}
 
-    //Size in file.
-    CS_fwrite(reinterpret_cast<char *>(&ulMinSize), sizeof(ulMinSize), 1, pFile);
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemCategory::CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog, cs_Ctdef_* pCategory)
+    : mp_ctDef(NULL)
+{
+    CCoordinateSystemCategory::CtorInit(this, pCatalog, pCategory, false);
+}
 
-    //Coordinate system names.
-    CSystemNameList::const_iterator iter;
-    for (iter=m_listCoordinateSystemNames.begin(); iter!=m_listCoordinateSystemNames.end(); ++iter)
-    {
-        CS_fwrite((*iter).Name(), sizeof(char), cs_KEYNM_DEF, pFile);
-    }
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemCategory::CCoordinateSystemCategory(CCoordinateSystemCategory const& toCopyFrom)
+    : mp_ctDef(NULL)
+{
+    CCoordinateSystemCategory::CtorInit(this, toCopyFrom.m_pCatalog, toCopyFrom.mp_ctDef);
+}
 
-    //Blank space, if needed
-    assert(ulMinSize >= ulSize);
-    UINT32 ulDiff = ulMinSize - ulSize;
-    if (ulDiff > 0)
-    {
-        //I could just pad the blank space with nulls,
-        //but I anticipate that it may be handy in the
-        //future for diagnostic purposes to be able go into
-        //the category dictionary with a binary editor and
-        //spot where the blanks are.  So I'll pick a distinctive
-        //string that's not likely to crop up elsewhere.
-        CSystemName dummy(/*NOXLATE*/"fnord");
-        for (UINT32 i=0; i<ulDiff; i++)
-        {
-            CS_fwrite(dummy.Name(), sizeof(char), cs_KEYNM_DEF, pFile);
-        }
-    }
-
-    //We're done!  Return success.
-    MG_CATCH(L"MgCoordinateSystemCategory.SaveToFstream")
-    //If we encountered an error, reset to where we started
-    if (0!=ferror(pFile) && -1!=previousPosition)
-    {
-        CS_fseek(pFile, previousPosition, SEEK_SET);
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.SaveToFstream", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemInternalException", NULL);
-    }
-    MG_THROW()
+CCoordinateSystemCategory& CCoordinateSystemCategory::operator=(const CCoordinateSystemCategory& other)
+{
+    this->CopyFrom(&other);
+    return *this;
 }
 
-//Load the object from a file, returning true for success or false for
-//failure.  In case of failure, the object will be cleared to a freshly
-//constructed state, and the stream pointer will be positioned where it was
-//to start with.  In case of success, the stream pointer will be positioned
-//just past the end of the object.
-//
-//See description under CCoordinateSystemCategory::SaveToFstream() for details.
-//
-void CCoordinateSystemCategory::LoadFromFstream(csFILE *pFile)
+CCoordinateSystemCategory::~CCoordinateSystemCategory()
 {
-    long previousPosition = -1;
+    CSrlsCategory(this->mp_ctDef);
+    this->mp_ctDef = NULL;
+}
 
-    MG_TRY()
-
-    UINT32 ulDiff;
-    CSystemName member;
-
-    Clear();
-
-    //make sure the stream is okay
-    assert(pFile && CS_ftell(pFile)>=0);
-    if (!pFile || -1==CS_ftell(pFile))
-    {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    if (ferror(pFile))
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    previousPosition = CS_ftell(pFile);    //in case of error
-
-    //We read in this order:
-    // 1. Name
-    // 2. Size (actual number of coordinate systems)
-    // 3. File size (ulMinSize; see description under SaveToFstream())
-    // 4. The coordinate system names
-    // 5. Blank space (if ulMinSize > size)
-
-    //Name.
-    char tempCharBuffer[knMaxCategoryNameLen] = { '\0' };
-    const size_t expectedReadCount = sizeof(tempCharBuffer) / sizeof(char);
-    size_t nRead=CS_fread(tempCharBuffer, sizeof(char), expectedReadCount, pFile);
-    if (expectedReadCount != nRead)
-    {
-        _ASSERT(0 == nRead); //otherwise something else is going on here...
-
-        //we reached the end of the file
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //copy the category name into our [m_categoryName] TNameStruct
-    m_categoryName = tempCharBuffer;
-
-    //Size.
-    UINT32 ulSize;
-    nRead=CS_fread(reinterpret_cast<char *>(&ulSize), sizeof(ulSize), 1, pFile);
-    if (1!=nRead)
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //Size in file.
-    UINT32 ulMinSize;
-    nRead=CS_fread(reinterpret_cast<char *>(&ulMinSize), sizeof(ulMinSize), 1, pFile);
-    if (1!=nRead)
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    assert(ulMinSize >= ulSize);
-    if (ulMinSize < ulSize)
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    char keyNameBuffer[cs_KEYNM_DEF]  = { '\0' };
-    const size_t expectedBufferCountRead = sizeof(keyNameBuffer) / sizeof(char);
-    //Coordinate system names.
-    for (UINT32 i=0; i<ulSize; i++)
-    {
-        keyNameBuffer[0] = '\0';
-        nRead=CS_fread(keyNameBuffer, sizeof(char), expectedBufferCountRead, pFile);
-        if (expectedBufferCountRead != nRead)
-        {
-            throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-
-        member = keyNameBuffer;
-
-        // TODO - WORKAROUND TO SKIP BAD COORDINATE SYSTEMS IN CURRENT DICTIONARIES
-        if((strcmp(member.Name(), "IGN63/Hiva") != 0) &&
-           (strcmp(member.Name(), "Phoenix") != 0))
-        {
-            m_listCoordinateSystemNames.push_back(member);
-        }
-    }
-
-    //Blank space, if needed
-    assert(ulMinSize >= ulSize);
-    ulDiff = ulMinSize - ulSize;
-    if (ulDiff > 0)
-    {
-        CS_fseek(pFile, CS_ftell(pFile) + ulDiff * (sizeof(keyNameBuffer) / sizeof(char)), SEEK_SET);
-    }
-    if (ferror(pFile))
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //We're done!  Return success.
-    MG_CATCH(L"MgCoordinateSystemCategory.LoadFromFstream")
-    //If we encountered an error, reset to where we started
-    if (ferror(pFile) && -1!=previousPosition)
-    {
-        CS_fseek(pFile, previousPosition, SEEK_SET);
-        Clear();
-        throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemInternalException", NULL);
-    }
-    MG_THROW()
+//MgDisposable
+void CCoordinateSystemCategory::Dispose()
+{
+    delete this;
 }
 
 //Make self into a copy of another category def.  Note that the other
 //def need only support MgCoordinateSystemCategory-- it doesn't necessarily have
 //to be a CCoordinateSystemCategory.
 //
-void CCoordinateSystemCategory::CopyFrom(MgCoordinateSystemCategory *pDef)
+void CCoordinateSystemCategory::CopyFrom(CCoordinateSystemCategory const* pDef)
 {
-    MG_TRY()
-
-    assert(NULL != pDef);
+    _ASSERT(NULL != pDef);
     if (!pDef)
-    {
         throw new MgNullArgumentException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
 
-    Clear();
+    if (!const_cast<CCoordinateSystemCategory*>(pDef)->IsValid())
+        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
 
-    //Copy the name
-    STRING str = pDef->GetName();
-    SetName(str);
+    CCoordinateSystemCategory const* pOtherCategory = dynamic_cast<CCoordinateSystemCategory const*>(pDef);
+    if (NULL == pOtherCategory)
+        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
 
-    //Get an enumerator
-    Ptr<MgCoordinateSystemEnum> pEnum=pDef->GetEnum();
-    if (!pEnum)
-    {
+    cs_Ctdef_* pCategoryCopy = CScpyCategory(pOtherCategory->mp_ctDef);
+    if (NULL == pCategoryCopy)
         throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
 
-    //Add the coordinate systems
-    for ( ; ; )
-    {
-        Ptr<MgStringCollection> pCsNameColl=pEnum->NextName(1);
-        if (1 != pCsNameColl->GetCount()) break;
-        AddCoordinateSystem(pCsNameColl->GetItem(0));
-    }
+    MG_TRY()
+
+        this->Clear();
+        this->mp_ctDef = pCategoryCopy;
+
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.CopyFrom")
 }
 
 //Gets the name of the def.
 STRING CCoordinateSystemCategory::GetName()
 {
-    STRING sName;
+    STRING categoryName;
+    wchar_t* pszwName = NULL;
 
     MG_TRY()
-    wchar_t *pName = Convert_Ascii_To_Wide(m_categoryName.Name());
-    if (!pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetName", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
 
-    sName=pName;
-    delete[] pName;
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetName")
+        pszwName = Convert_Ascii_To_Wide(this->mp_ctDef->ctName);
+        categoryName = pszwName;
 
-    return sName;
+    MG_CATCH(L"MgCoordinateSystemCategory.GetName");
+
+    delete[] pszwName;
+    pszwName = NULL;
+
+    MG_THROW()
+
+    return categoryName;
 }
 
 //Sets the name of the def.
@@ -327,23 +159,24 @@
 //if the specified name is not legal.
 void CCoordinateSystemCategory::SetName(CREFSTRING sName)
 {
+    char* pszNewName = NULL;
+
     MG_TRY()
-    if (!IsLegalName(sName))
-    {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.SetName", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
 
-    char *pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
-    if (!pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.SetName", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+        if (!IsLegalName(sName))
+        {
+            throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.SetName", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
 
-    //assign the name to our internal [TNameStruct]
-    m_categoryName = pName;
+        pszNewName = Convert_Wide_To_Ascii(sName.c_str());
+        CS_stncp(this->mp_ctDef->ctName, pszNewName, cs_CATDEF_CATNMSZ);
 
-    delete [] pName;
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.SetName")
+    MG_CATCH(L"MgCoordinateSystemCategory.SetName")
+
+        delete[] pszNewName;
+        pszNewName = NULL;
+
+    MG_THROW()
 }
 
 //Gets whether the def is "valid."  Validity, in this case, is
@@ -361,7 +194,7 @@
 //
 bool CCoordinateSystemCategory::IsValid()
 {
-    return IsLegalName(m_categoryName.Name());
+    return IsLegalName(this->mp_ctDef->ctName);
 }
 
 //Private member function which returns whether the specified string
@@ -377,7 +210,7 @@
 
     //String can't be empty or too long
     INT32 nLen = static_cast<UINT32>(strlen(kpName));
-    return ((nLen > 0) && (nLen < knMaxCategoryNameLen));
+    return ((nLen > 0) && (nLen < cs_CATDEF_CATNMSZ));
 }
 
 //Tests the specified string to find out whether it's a legal
@@ -385,7 +218,7 @@
 //
 bool CCoordinateSystemCategory::IsLegalName(CREFSTRING sName)
 {
-    return (sName.length() > 0) && (sName.length() < knMaxCategoryNameLen);
+    return (sName.length() > 0) && (sName.length() < cs_CATDEF_CATNMSZ);
 }
 
 //Gets whether the def is usable in the context of the given catalog.
@@ -428,63 +261,41 @@
     }
 
     //Make sure it's a category def
-    MgCoordinateSystemCategory* pCtDef=dynamic_cast<MgCoordinateSystemCategory*>(pDef);
+    CCoordinateSystemCategory* pCtDef=dynamic_cast<CCoordinateSystemCategory*>(pDef);
     if (!pCtDef)
     {
         return false;
     }
 
-    //Get enumerators for doing comparison
-    Ptr<MgCoordinateSystemEnum> pThis=GetEnum();
-    assert(pThis);
-    if (!pThis)
+    //our [mp_ctDef]'s must always be set, we don't delete that; unless we ran into a situation where we deleted
+    //the field and then couldn't create a new instance via CSnewCategory
+    if (NULL == pCtDef->mp_ctDef)
     {
-        return false;
+        _ASSERT(false);
+        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.IsSameAs", __LINE__, __WFILE__, NULL, L"", NULL);
     }
-    pThis->Reset();
 
-    Ptr<MgCoordinateSystemEnum> pThat=pCtDef->GetEnum();
-    assert(pThat);
-    if (!pThat)
+    if (NULL == this->mp_ctDef)
     {
-        return false;
+        _ASSERT(false);
+        throw new MgInvalidOperationException(L"MgCoordinateSystemCategory.IsSameAs", __LINE__, __WFILE__, NULL, L"", NULL);
     }
-    pThat->Reset();
 
-    //Start comparing names.  Even though the enumerators may
-    //allow us to grab many names at one go, we'll do them one
-    //at a time.  This is to avoid the complication of "what do
-    //we do when we ask A for a hundred, and B for a hundred,
-    //and they give us different size chunks?"  Processing speed
-    //isn't much of an issue here, so we'll keep the code simple.
-    for ( ; ; )
+    if (this->mp_ctDef->nameCnt != pCtDef->mp_ctDef->nameCnt)
+        return false;
+
+    //now check, whether all the CRS names are the same
+    for(ulong32_t i = 0; i < this->mp_ctDef->nameCnt; ++i)
     {
-        Ptr<MgStringCollection> pCsNameCollThis=pThis->NextName(1);
-        Ptr<MgStringCollection> pCsNameCollThat=pThat->NextName(1);
-        if ((0 == pCsNameCollThis->GetCount()) && (0 == pCsNameCollThat->GetCount()))
-        {
-            //We've reached the end of the list without
-            //finding any differences.  They're the same.
-            return true;
-        }
-        else if (1==pCsNameCollThis->GetCount() && 1==pCsNameCollThat->GetCount())
-        {
-            //We got a name from each.  Compare them.
-            bool bSameName = (0 == _wcsicmp(pCsNameCollThis->GetItem(0).c_str(), pCsNameCollThat->GetItem(0).c_str()));
-            if (!bSameName)
-            {
-                //Different names!
-                return false;
-            }
-        }
-        else
-        {
-            //The lists are of different length!  Not the same.
-            assert(pCsNameCollThis->GetCount() != pCsNameCollThat->GetCount());
+        char const* pCrsNameThis = (this->mp_ctDef->csNames + i)->csName;
+        char const* pCrsNameOther = (pCtDef->mp_ctDef->csNames + i)->csName;
+
+        if (0 != CS_stricmp(pCrsNameThis, pCrsNameOther))
             return false;
-        }
-    }    //for each coordsys name in the category
+    }
 
+    return true;
+
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.IsSameAs")
 
     return false;
@@ -495,35 +306,22 @@
 //
 MgCoordinateSystemCategory* CCoordinateSystemCategory::CreateClone()
 {
-    Ptr<CCoordinateSystemCategory> pNew;
-
     MG_TRY()
 
-    //Create a clone object
-    pNew = new CCoordinateSystemCategory(m_pCatalog);
+        //Create a clone object
+        return new CCoordinateSystemCategory(*this);
 
-    if (NULL == pNew.p)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.CreateClone", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //Copy the category name
-    pNew->m_categoryName = m_categoryName;
-
-    //Copy the list of coordinate systems
-    pNew->m_listCoordinateSystemNames = m_listCoordinateSystemNames;
-
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.CreateClone")
 
-    //And we're done!  Return success.
-    return pNew.Detach();
+    _ASSERT(false);
+    return NULL;
 }
 
 //Gets the number of coordinate systems listed in the category.
 //
 UINT32 CCoordinateSystemCategory::GetSize()
 {
-    return static_cast<UINT32>(m_listCoordinateSystemNames.size());
+    return static_cast<UINT32>(this->GetAllCsNames().size());
 }
 
 //Gets an enumerator for listing the names of all the coordinate
@@ -532,43 +330,58 @@
 //
 MgCoordinateSystemEnum* CCoordinateSystemCategory::GetEnum()
 {
-    CCoordinateSystemEnumCoordinateSystemInCategory* pNameEnum=NULL;
+    Ptr<CCoordinateSystemEnumCoordinateSystemInCategory> pNameEnum;
 
     MG_TRY()
-    pNameEnum=new CCoordinateSystemEnumCoordinateSystemInCategory(m_pCatalog);
-    if (!pNameEnum)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    pNameEnum->Initialize(&m_listCoordinateSystemNames);
+
+        pNameEnum=new CCoordinateSystemEnumCoordinateSystemInCategory(m_pCatalog);
+        pNameEnum->Initialize(this->GetAllCsNames());
+
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetEnum")
 
-    return pNameEnum;
+    return pNameEnum.Detach();
 }
 
 //-------------------------------------------------------------------------------
+std::vector<STRING>& CCoordinateSystemCategory::GetAllCsNames()
+{
+    MG_TRY()
+
+        if (0 == this->m_listCoordinateSystemNames.size() && this->mp_ctDef->nameCnt > 0)
+        {
+            for(ulong32_t i = 0; i < this->mp_ctDef->nameCnt; ++i)
+            {
+                wchar_t *pszwCsName = Convert_Ascii_To_Wide(this->mp_ctDef->csNames[i].csName);
+                this->m_listCoordinateSystemNames.push_back(pszwCsName);
+                delete[] pszwCsName;
+            }
+        }
+
+    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetAllCsNames")
+
+    return this->m_listCoordinateSystemNames;
+}
+
+//-------------------------------------------------------------------------------
+void CCoordinateSystemCategory::ClearAllCsNames()
+{
+    this->m_listCoordinateSystemNames.clear();
+}
+
+//-------------------------------------------------------------------------------
 MgStringCollection* CCoordinateSystemCategory::GetCoordinateSystems()
 {
     Ptr<MgStringCollection> pCsColl;
+
     MG_TRY()
+    pCsColl = new MgStringCollection;
 
-    pCsColl=new MgStringCollection;
-    if (NULL == pCsColl)
+    std::vector<STRING> const& allCsNames = this->GetAllCsNames();
+    for(size_t i = 0; i < allCsNames.size(); ++i)
     {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
+        pCsColl->Add(allCsNames[0]);
     }
 
-    CSystemNameList::const_iterator iter;
-    for (iter=m_listCoordinateSystemNames.begin(); iter!=m_listCoordinateSystemNames.end(); ++iter)
-    {
-        wchar_t *pName = Convert_Ascii_To_Wide((*iter).Name());    //need to delete [] pName
-        if (NULL == pName)
-        {
-            throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        pCsColl->Add(pName);
-        delete[] pName;
-    }
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetCoordinateSystems")
     return pCsColl.Detach();
 }
@@ -580,36 +393,52 @@
 //
 void CCoordinateSystemCategory::AddCoordinateSystem(CREFSTRING sName)
 {
+    char *pName = NULL;
+
     MG_TRY()
+
+    std::vector<STRING>& allCsNames = this->GetAllCsNames();
+
     //Make sure it's a legal name
-    char *pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
+    pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
     if (NULL == pName)
     {
         throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
     }
+
     if (!IsLegalMentorName(pName))
     {
-        delete [] pName;
         throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    //Make a new member out of it
-    CSystemName newMember(pName);
-    delete [] pName;
-
     //See if it's already present
-    CSystemNameList::iterator itList=std::find(m_listCoordinateSystemNames.begin(), m_listCoordinateSystemNames.end(), newMember);
-    if (itList != m_listCoordinateSystemNames.end())
+    std::vector<STRING>::iterator const& itList = std::find(allCsNames.begin(), allCsNames.end(), sName);
+    if (itList != allCsNames.end())
     {
         //duplicate!
         throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemCategoryDuplicateException", NULL);
     }
 
+    if (CSaddItmNameEx(this->mp_ctDef, pName))
+    {
+        _ASSERT(false); //whatever the problem is here... the name we validated; OOM ? hopefully unlikely
+        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemCategoryDuplicateException", NULL);
+    }
+
     //Try to insert it in our list
-    m_listCoordinateSystemNames.push_back(newMember);
+    allCsNames.push_back(sName);
 
     //Success!
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.AddCoordinateSystem")
+    MG_CATCH(L"MgCoordinateSystemCategory.AddCoordinateSystem")
+
+    delete [] pName;
+    pName = NULL;
+
+    if (NULL != mgException)
+        this->ClearAllCsNames();
+
+    MG_THROW();
+
 }
 
 //Removes the specified coordinate system key name from the category.
@@ -619,33 +448,46 @@
 //
 void CCoordinateSystemCategory::RemoveCoordinateSystem(CREFSTRING sName)
 {
+    char *pName = NULL;
+
     MG_TRY()
 
-    //Make sure it's a legal name
-    char *pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    if (!IsLegalMentorName(pName))
-    {
-        delete [] pName;
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+        std::vector<STRING>& allCsNames = this->GetAllCsNames();
 
-    //Make a member out of it
-    CSystemName member(pName);
+        //Make sure it's a legal name
+        pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
+        _ASSERT(NULL != pName); //would throw an exception otherwise
+
+        if (!IsLegalMentorName(pName))
+            throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
+
+        if (CSrmvItmNameEx(this->mp_ctDef, pName))
+        {
+            if (cs_Error != cs_CT_CS_NOT_IN)
+            {
+                //the name should be valid... the only expected error here would be
+                //that we couldn't find the CS in the category
+                _ASSERT(false);
+                allCsNames.clear();
+            }
+
+            throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        //See if it's already present
+        std::vector<STRING>::iterator const& itList = std::find(allCsNames.begin(), allCsNames.end(), sName);
+        if (itList != allCsNames.end())
+            allCsNames.erase(itList);
+
+    MG_CATCH(L"MgCoordinateSystemCategory.RemoveCoordinateSystem")
+
     delete [] pName;
+    pName = NULL;
 
-    CSystemNameList::iterator itList=std::find(m_listCoordinateSystemNames.begin(), m_listCoordinateSystemNames.end(), member);
-    if (itList != m_listCoordinateSystemNames.end())
-    {
-        //Found it!
-        m_listCoordinateSystemNames.erase(itList);
-    }
+    if (NULL != mgException)
+        this->ClearAllCsNames();
 
-    //Return success.
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.RemoveCoordinateSystem")
+    MG_THROW()
 }
 
 //Tests whether the category contains the specified coordinate system
@@ -653,40 +495,53 @@
 //
 bool CCoordinateSystemCategory::HasCoordinateSystem(CREFSTRING sName)
 {
-    bool bHas=false;
+    bool bHas = false;
+    char *pName = NULL;
 
+    std::vector<STRING>& allCsNames = this->GetAllCsNames();
+
     MG_TRY()
-    //Make sure it's a legal name
-    char *pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.HasCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    if (!IsLegalMentorName(pName))
-    {
-        delete [] pName;
-        return false; //the name is not valid so the category doesn't have it. No assertion since the name might be ok for something else than this coordsys library
-    }
 
-    //Make a member out of it
-    CSystemName member(pName);
-    delete [] pName;
+        //Make sure it's a legal name
+        pName = Convert_Wide_To_Ascii(sName.c_str());
+        if (IsLegalMentorName(pName))
+        {
+            //Try to find it
+            //See if it's already present
+            std::vector<STRING>::iterator const& itList = std::find(allCsNames.begin(), allCsNames.end(), sName);
+            bHas = (itList != allCsNames.end());
+        }
+        //else:
+            //the name is not valid so the category doesn't have it. No assertion since the name might be ok for something else than this coordsys library
 
-    //Try to find it
-    CSystemNameList::iterator itList=std::find(m_listCoordinateSystemNames.begin(), m_listCoordinateSystemNames.end(), member);
-    bHas=(itList != m_listCoordinateSystemNames.end());
+    MG_CATCH(L"MgCoordinateSystemCategory.HasCoordinateSystem")
 
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.HasCoordinateSystem")
+    delete[] pName;
+    pName = NULL;
 
+    MG_THROW()
+
     return bHas;
 }
 
+cs_Ctdef_ const* CCoordinateSystemCategory::GetCategoryDef() const
+{
+    return this->mp_ctDef;
+}
+
 //Clears the object to a freshly constructed state.
 //
 void CCoordinateSystemCategory::Clear()
 {
-    m_categoryName = "\0";
-    m_listCoordinateSystemNames.clear();
+    this->ClearAllCsNames();
+
+    //create the new empty cs_Ctdef_ instance first
+    struct cs_Ctdef_* pNewCategory = CSnewCategory(NULL);
+    if (NULL == pNewCategory)
+        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.MgCoordinateSystemCategory", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    CSrlsCategory(this->mp_ctDef);
+    this->mp_ctDef = pNewCategory;
 }
 
 //*****************************************************************************

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategory.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -18,6 +18,8 @@
 #ifndef _CCOORDINATESYSTEMCATEGORY_H_
 #define _CCOORDINATESYSTEMCATEGORY_H_
 
+struct cs_Ctdef_;
+
 namespace CSLibrary
 {
 
@@ -25,12 +27,13 @@
 {
 public:
     CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog);
+    CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog, cs_Ctdef_* pCategory);
+    CCoordinateSystemCategory(CCoordinateSystemCategory const&);
+    CCoordinateSystemCategory& operator=(const CCoordinateSystemCategory&);
+
     virtual ~CCoordinateSystemCategory();
 
-    char *Name();
-    void SaveToFstream(csFILE *pFile, UINT32 ulMinSize = 0);
-    void LoadFromFstream(csFILE *pFile);
-    void CopyFrom(MgCoordinateSystemCategory *pDef);
+    void CopyFrom(CCoordinateSystemCategory const* pDef);
 
     //MgCoordinateSystemCategory
     virtual STRING GetName();
@@ -49,24 +52,27 @@
     virtual void Clear();
     virtual MgCoordinateSystemCatalog* GetCatalog();
 
+    cs_Ctdef_ const* GetCategoryDef() const;
+
 protected:
     //MgDisposable
     virtual void Dispose();
 
 protected:
     //Data members
-    CCategoryName m_categoryName;
-    CSystemNameList m_listCoordinateSystemNames;
+    std::vector<STRING> m_listCoordinateSystemNames;
     Ptr<MgCoordinateSystemCatalog> m_pCatalog;
 
     //Private member functions
     static bool IsLegalName(const char *kpName);
 
 private:
-    //Unimplemented stuff
-    CCoordinateSystemCategory();
-    CCoordinateSystemCategory(const CCoordinateSystemCategory&);
-    CCoordinateSystemCategory& operator=(const CCoordinateSystemCategory&);
+
+    std::vector<STRING>& GetAllCsNames();
+    void ClearAllCsNames();
+
+    cs_Ctdef_ * mp_ctDef;
+    static void CtorInit(CCoordinateSystemCategory* pToInitialize, MgCoordinateSystemCatalog *pCatalog, cs_Ctdef_* pSourceCtDef = NULL, bool copyDef = true);
 };
 
 } // End of namespace

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -89,21 +89,15 @@
 
 CCategoryNameIndexMap& CCoordinateSystemCategoryDictionary::Index()
 {
-    csFILE* pFile=NULL;
+    _ASSERT(CriticalClass.IsEntered());
 
     MG_TRY()
     if (m_bIndexDirty)
     {
         //if dirty it needs to be regenerated
-        SmartCriticalClass critical(true);
-        pFile=Open(Read);
-        GenerateIndex(pFile);
+        GenerateIndex();
     }
     MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Index")
-    if (pFile)
-    {
-        CS_fclose(pFile);
-    }
     MG_THROW()
 
     return m_index;
@@ -111,290 +105,97 @@
 
 CCategoryNameList& CCoordinateSystemCategoryDictionary::List()
 {
-    csFILE* pFile=NULL;
+    //if dirty it needs to be regenerated
+    SmartCriticalClass critical;
 
     MG_TRY()
-    if (m_bIndexDirty)
-    {
-        //if dirty it needs to be regenerated
-        SmartCriticalClass critical(true);
-        pFile=Open(Read);
-        GenerateIndex(pFile);
-    }
+
+        if (m_bIndexDirty)
+        {
+            GenerateIndex();
+        }
+
     MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Index")
-    if (pFile)
-    {
-        CS_fclose(pFile);
-    }
+
+        if (NULL != mgException)
+            this->InvalidateIndex();
+
     MG_THROW()
 
     return m_list;
 }
 
-//Private member function which generates an index from the specified
-//file, which is assumed to point to an open category dictionary file.
-//Returns true for success, false for failure.
-//
-void CCoordinateSystemCategoryDictionary::GenerateIndex(csFILE *pFile)
+void CCoordinateSystemCategoryDictionary::InvalidateIndex()
 {
-    long previousPos = -1;
-    MG_TRY()
+    _ASSERT(CriticalClass.IsEntered());
 
-    assert(pFile && CS_ftell(pFile)>=0);
-    previousPos = CS_ftell(pFile);
+    CSrlsCategories(); //our index got of synch; make sure, we force CS-Map to release its in-memory list, too
+    m_bIndexDirty = true;
+
     m_index.clear();
     m_list.clear();
-
-    //Position the stream to the start of the first record
-    CS_fseek(pFile, sizeof(klCategoryMagic), SEEK_SET);
-    if (ferror(pFile))
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.GenerateIndex", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //Start reading records.
-    CCoordinateSystemCategory def(m_pCatalog);
-    long curPos=0;
-    while (!feof(pFile))
-    {
-        curPos = CS_ftell(pFile);
-        try
-        {
-            def.LoadFromFstream(pFile);
-        }
-        catch (MgException *pELoad)
-        {
-            SAFE_RELEASE(pELoad);
-            if (feof(pFile)) break;
-        }
-        CCategoryName category(def.Name());
-        m_index.insert(CCategoryNameIndexPair(category, curPos));
-        m_list.push_back(category);
-    }    //for each def in the file
-
-    //Success!
-    m_bIndexDirty=false;
-    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.GenerateIndex")
-    if (mgException != NULL)
-    {
-        m_index.clear();
-    }
-    if (-1!=previousPos)
-    {
-        CS_fseek(pFile, previousPos, SEEK_SET);
-    }
-    MG_THROW()
 }
 
-
-//Private member function.  Rewrites the file.  If pDef is NULL,
-//the def specified by kpDefName will simply be omitted; if not NULL,
-//it will be replaced by the def provided.
+//Private member function which generates an index from the specified
+//file, which is assumed to point to an open category dictionary file.
+//Returns true for success, false for failure.
 //
-//This function is provided to avoid duplicating code between
-//ModifyCategory() and RemoveCategory().
-//
-void CCoordinateSystemCategoryDictionary::RewriteFile(const char *kpDefName, CCoordinateSystemCategory *pDef)
+void CCoordinateSystemCategoryDictionary::GenerateIndex()
 {
-    csFILE *pFile=NULL;
-    CriticalClass.Enter();
-    MG_TRY()
-    assert(NULL != kpDefName);
-    STRING tempName;
-    STRING strPath=GetPath();
+    _ASSERT(CriticalClass.IsEntered());
 
-#ifdef _WIN32
-    //Get a temporary file name
-    wchar_t szDrive[_MAX_DRIVE],
-         szDir[_MAX_DIR],
-         szFname[_MAX_FNAME],
-         szExt[_MAX_EXT],
-         szPath[_MAX_PATH],
-         szTempPath[_MAX_PATH];
-    _tsplitpath(strPath.c_str(), szDrive, szDir, szFname, szExt);
-    _tmakepath(szPath, szDrive, szDir, NULL, NULL);
+    struct cs_Ctdef_ **pAllCategories = NULL;
+    int categoryCount = 0;
 
-    if (!GetTempFileName(szPath, /*NOXLATE*/L"cat", 0, szTempPath))
-    {
-        //couldn't open file
-        throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoCategoryDictionaryException", NULL);
-    }
-    tempName=szTempPath;
-#else
-    tempName = MgFileUtil::GenerateTempFileName();
-#endif
+    MG_TRY()
 
-    //Open the file
-    csFILE *pTemp;
-    char szMode[10];
-    GetFileModes(Write, szMode);
-    pTemp = fopen( MgUtil::WideCharToMultiByte(tempName).c_str(), szMode );
-    if (!pTemp || ferror(pTemp))
-    {
-        //couldn't open file
-        throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoCategoryDictionaryException", NULL);
-    }
+        this->InvalidateIndex();
 
-    //Copy the magic number
-    INT32 lMagic;
-    GetFileModes(Read, szMode);
-    pFile=OpenDictionaryFile(strPath.c_str(), szMode, lMagic, ValidCategoryMagic);
-    CS_fwrite(reinterpret_cast<char *>(&lMagic), sizeof(lMagic), 1, pTemp);
-
-    //Copy the category definitions across
-    CCoordinateSystemCategory curDef(m_pCatalog);
-    CCoordinateSystemCategory *pDefToWrite;
-    bool bFound = false;
-    while (!feof(pFile))
-    {
-        //Get def from original file
-        try
+        categoryCount = CSgetCtDefAll(&pAllCategories);
+        if (categoryCount < 0)
         {
-            curDef.LoadFromFstream(pFile);
+            _ASSERT(NULL == pAllCategories);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GenerateIndex", __LINE__, __WFILE__, NULL, L"", NULL);
         }
-        catch (MgException *pELoad)
-        {
-            SAFE_RELEASE(pELoad);
-            if (feof(pFile)) break;
-            CS_fclose(pTemp);
-            CS_fclose(pFile);
-            pFile=NULL;
-            throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
 
-        //Is it the one we're replacing?
-        pDefToWrite = &curDef;
-        if ((!bFound) && (0 == CS_stricmp(kpDefName, curDef.Name())))
+        for(int i = 0; i < categoryCount; ++i)
         {
-            bFound = true;
-            pDefToWrite = pDef;
+            CCategoryName category(pAllCategories[i]->ctName);
+            m_index.insert(CCategoryNameIndexPair(category, i));
+            m_list.push_back(category);
         }
 
-        if (NULL != pDefToWrite)
-        {
-            //Write appropriate def to output file
-            bool bOk=true;
-            try
-            {
-                pDefToWrite->SaveToFstream(pTemp);
-            }
-            catch (MgException *pESave)
-            {
-                SAFE_RELEASE(pESave);
-                bOk=false;
-            }
-            if (!bOk || ferror(pTemp))
-            {
-                CS_fclose(pFile);
-                pFile=NULL;
-                CS_fclose(pTemp);
-                throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"", NULL);
-            }
-        }
-    }    //until we reach the end of the original file
+        //Success!
+        m_bIndexDirty = false;
 
-    //Okay, we're done.  Switch 'em around.
-    CS_fclose(pFile);
-    pFile=NULL;
-    CS_fclose(pTemp);
-    char* sz_msPath=Convert_Wide_To_Ascii(strPath.c_str());
-    if (!sz_msPath)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    MgFileUtil::DeleteFile( MgUtil::MultiByteToWideChar(sz_msPath) );
-    MgFileUtil::RenameFile( tempName, MgUtil::MultiByteToWideChar(sz_msPath) );
+    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.GenerateIndex")
 
-    GetFileModes(Read, szMode);
-    pFile=fopen(sz_msPath, szMode);
-    delete[] sz_msPath;
-
-    //Since the contents of the file presumably changed,
-    //we need to re-generate the index.
-    GenerateIndex(pFile);
-
-    //Return success.
-    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.RewriteFile")
-    if (pFile)
+    if (NULL != mgException)
     {
-        CS_fclose(pFile);
-        pFile=NULL;
+        this->InvalidateIndex();
     }
-    CriticalClass.Leave();
-    MG_THROW();
-}
 
-//-----------------------------------------------------------------------------
-csFILE* CCoordinateSystemCategoryDictionary::Open(CsDictionaryOpenMode nOpenMode)
-{
-    csFILE* pFile=NULL;
-    MG_TRY()
-
-    //Make sure they've specified a valid mode
-    bool bWriting;
-    switch (nOpenMode)
+    //clean up the array we've got from CS-Map, i.e. ...
+    for(int i = 0; i < categoryCount; ++i)
     {
-    case Read:
-        bWriting = false;
-        break;
-    case Write:
-        bWriting = true;
-        break;
-    default:
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, NULL, L"", NULL);
-        break;
+        //...delete each individual entry...
+        CSrlsCategory(pAllCategories[i]);
+        pAllCategories[i] = NULL;
     }
 
-    //Validate the existence of the file
-    EFileValidity reason;
-    STRING strPath=GetPath();
-    if (!ValidateFile(
-        strPath.c_str(),    //the file to validate
-        true,        //must already exist
-        false,        //mustn't be a directory,
-        bWriting,    //whether we need write access
-        &reason))    //reason for failure
-    {
-        switch (reason)
-        {
-        case kFileInvalidEmptyString:
-            throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, NULL, L"", NULL);
-            break;
-        case kFileInvalidPath:
-        case kFileInvalidDoesNotExist:
-        case kFileInvalidIsADir:
-            {
-            MgStringCollection arguments;
-            arguments.Add(strPath);
-            throw new MgFileNotFoundException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, &arguments, L"", NULL);
-            }
-            break;
-        case kFileInvalidCantWrite:
-            MgStringCollection arguments;
-            arguments.Add(strPath);
-            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemDictionaryReadOnlyException", NULL);
-            break;
-        }
-    }
+    //...and finally delete the entire array
+    CS_free(pAllCategories);
+    pAllCategories = NULL;
 
-    //Try to open the dictionary file
-    char szMode[10];
-    GetFileModes(nOpenMode, szMode);
-    INT32 lDummy;
-    if (NULL==(pFile=OpenDictionaryFile(strPath.c_str(), szMode, lDummy, ValidCategoryMagic)))
-    {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    MG_THROW()
 
-    //And we're done!  Return success.
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.Open")
-    return pFile;
+    return;
 }
 
 //-----------------------------------------------------------------------------
 STRING CCoordinateSystemCategoryDictionary::GetDefaultFileName()
 {
-    return L"Category.CSD";  // NOXLATE
+    return WIDEN(cs_CT_NAME);
 }
 
 //-----------------------------------------------------------------------------
@@ -437,7 +238,7 @@
 
     //set the index flag to dirty so that it will be generated
     //automatically the next time we need it
-    m_bIndexDirty=true;
+    this->InvalidateIndex();
     m_sFileName=sFileName;
 
     MG_CATCH_AND_THROW(L"MgCoordinateSystemDictionary.SetFileName")
@@ -460,9 +261,13 @@
 {
     UINT32 nSize=0;
 
+
     MG_TRY()
-    //Return the size.
-    nSize=static_cast<UINT32>(Index().size());
+
+        SmartCriticalClass csmapLock;
+        //Return the size.
+        nSize=static_cast<UINT32>(Index().size());
+
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.GetSize")
 
     return nSize;
@@ -474,34 +279,23 @@
 //def is not the right kind.  Otherwise, works like AddCategory().
 void CCoordinateSystemCategoryDictionary::Add(MgGuardDisposable *pDefinition)
 {
-    csFILE* pFile=NULL;
-    SmartCriticalClass critical(false);
+    SmartCriticalClass lock;
     MG_TRY()
-    assert(NULL != pDefinition);
+
+    _ASSERT(NULL != pDefinition);
     if (NULL == pDefinition)
     {
         throw new MgNullArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    MgCoordinateSystemCategory* pCategoryDef=dynamic_cast<MgCoordinateSystemCategory*>(pDefinition);
+    CCoordinateSystemCategory* pCategoryDef=dynamic_cast<CCoordinateSystemCategory*>(pDefinition);
     if (!pCategoryDef)
     {
         throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemMismatchException", NULL);
     }
 
-    //Look for it in our index
-    STRING str = pCategoryDef->GetName();
-    if (str.empty())
-    {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    char *pName = Convert_Wide_To_Ascii(str.c_str());    //need to delete [] pName
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
-    delete [] pName;
+    cs_Ctdef_ const* pCsMapDef = pCategoryDef->GetCategoryDef();
+    CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pCsMapDef->ctName));
 
     //Did we find it?
     if (iter != Index().end())
@@ -510,36 +304,31 @@
         throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDuplicateException", NULL);
     }
 
-    //Is it a valid def?
-    bool bValid = pCategoryDef->IsValid();
-    if (!bValid)
+    int updateResult = CS_ctupd(pCsMapDef);
+    if (updateResult < 0)
     {
-        //Invalid def!
+        //the category could not be added to the dictionary
         throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    //Build a CCoordinateSystemCategory out of it.
-    CCoordinateSystemCategory def(m_pCatalog);
-    def.CopyFrom(pCategoryDef);
+    _ASSERT(0 == updateResult); //we must have added it; +1 means "updated"
+    if (0 == updateResult) //otherwise an existing one was updated, i.e. our list should be still in synch, theoretically...
+    {
+        //Add it to our index
+        CCategoryName category(pCsMapDef->ctName);
+        Index().insert(CCategoryNameIndexPair(category, List().size()));
+        List().push_back(category);
+    }
+    else
+    {
+        this->InvalidateIndex();
+    }
 
-    //Try to add it to the end of the list.
-    critical.Enter();
-    pFile=Open(Write);
-    CS_fseek(pFile, 0, SEEK_END);
-    long pos = CS_ftell(pFile);
-    def.SaveToFstream(pFile);
+    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Add")
 
-    //Add it to our index
-    CCategoryName category(def.Name());
-    Index().insert(CCategoryNameIndexPair(category, pos));
-    List().push_back(category);
+        if (NULL != mgException)
+            this->InvalidateIndex();
 
-    //Success!
-    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Add")
-    if (pFile)
-    {
-        CS_fclose(pFile);
-    }
     MG_THROW()
 }
 
@@ -548,14 +337,16 @@
 void CCoordinateSystemCategoryDictionary::Remove(CREFSTRING sName)
 {
     char *pName = NULL;
+    cs_Ctdef_* pCategory = NULL;
+
+    bool bInvalidIndexOnFailure = false;
+
+    SmartCriticalClass critical;
     MG_TRY()
 
     //Look for it in our index
-    pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    pName = Convert_Wide_To_Ascii(sName.c_str());
+
     CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
 
     //Did we find it?
@@ -566,13 +357,56 @@
         throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
     }
 
-    //Rewrite the file, skipping the specified category.
-    //Doing so will re-generate the index as needed,
-    //which will invalidate iter.
-    RewriteFile(pName);
+    bInvalidIndexOnFailure = true;
 
+    pCategory = CS_ctdef(pName);
+    if (NULL == pCategory)
+    {
+        MgStringCollection arguments;
+        arguments.Add(sName);
+        throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+    }
+
+    int deletionResult = CS_ctdel(pCategory);
+    if (deletionResult)
+    {
+        MgStringCollection arguments;
+        arguments.Add(sName);
+        throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemInternalException", NULL);
+    }
+
+    int updateCategoriesResult = CSupdCategories(NULL);
+    if (updateCategoriesResult)
+    {
+        MgStringCollection arguments;
+        arguments.Add(sName);
+        throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemInternalException", NULL);
+    }
+
+    long position = iter->second;
+    CCategoryName const& categoryName = List().at(position);
+    if (0 != CS_stricmp(categoryName.Name(), pName)) //is the category name at the index what we think it is?
+    {
+        _ASSERT(false);
+        this->InvalidateIndex();
+    }
+    else
+    {
+        Index().erase(iter->first);
+        List().erase(List().begin() + position);
+    }
+
     MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Remove")
-    delete [] pName;
+
+        delete [] pName;
+        pName = NULL;
+
+        CSrlsCategory(pCategory);
+        pCategory = NULL;
+
+        if (bInvalidIndexOnFailure && NULL != mgException)
+            InvalidateIndex();
+
     MG_THROW()
 }
 
@@ -582,84 +416,78 @@
 //def is not the right kind.
 void CCoordinateSystemCategoryDictionary::Modify(MgGuardDisposable *pDefinition)
 {
-    CCoordinateSystemCategory def(m_pCatalog);
-    csFILE* pFile=NULL;
-    SmartCriticalClass critical(false);
+    char *pName = NULL;
+    cs_Ctdef_* pCategory = NULL;
 
+    bool invalidIndexOnFailure = false;
+
+    SmartCriticalClass csmapLock;
     MG_TRY()
-    assert(NULL != pDefinition);
-    if (NULL == pDefinition)
-    {
-        throw new MgNullArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
 
-    MgCoordinateSystemCategory* pCategoryDef=dynamic_cast<MgCoordinateSystemCategory*>(pDefinition);
-    if (!pCategoryDef)
-    {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemMismatchException", NULL);
-    }
+        _ASSERT(NULL != pDefinition);
+        if (NULL == pDefinition)
+            throw new MgNullArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
 
-    //Look for it in our index
-    STRING str = pCategoryDef->GetName();
-    if (str.empty())
-    {
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    char *pName = Convert_Wide_To_Ascii(str.c_str());    //need to delete [] pName
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
-    delete [] pName;
+        CCoordinateSystemCategory* pCategoryDef=dynamic_cast<CCoordinateSystemCategory*>(pDefinition);
+        if (!pCategoryDef)
+        {
+            throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemMismatchException", NULL);
+        }
 
-    //Did we find it?
-    if (iter == Index().end())
-    {
-        MgStringCollection arguments;
-        arguments.Add(str);
-        throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
-    }
+        //Look for it in our index
+        STRING str = pCategoryDef->GetName();
+        if (str.empty())
+        {
+            throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        pName = Convert_Wide_To_Ascii(str.c_str());
 
-    //Make a CCoordinateSystemCategory object out of what we're given
-    def.CopyFrom(pCategoryDef);
+        CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
 
-    //If the new definition is smaller than or equal to the existing
-    //definition's space in the file, we can do a simple in-place
-    //replacement in the file.  Otherwise, we'll need to re-write the
-    //whole file to make room.
-    //
-    //Find out how big the existing def is in the file.
-    critical.Enter();
-    pFile=Open(Write);
-    long pos = (*iter).second;
-    UINT32 ulFileSize;
-    CS_fseek(pFile, pos + knMaxCategoryNameLen + sizeof(UINT32), SEEK_SET);
-    size_t nRead=CS_fread(reinterpret_cast<char *>(&ulFileSize), sizeof(ulFileSize), 1, pFile);
-    if (1!=nRead)
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+        //Did we find it?
+        if (iter == Index().end())
+        {
+            MgStringCollection arguments;
+            arguments.Add(str);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+        }
 
-    //Can we do in-place replacement?
-    UINT32 ulSize = def.GetSize();
-    if (ulSize <= ulFileSize)
-    {
-        //Yep.
-        CS_fseek(pFile, pos, SEEK_SET);
-        def.SaveToFstream(pFile, ulFileSize);
-        //Success!  We're done.
-        CS_fclose(pFile);
-        return;
-    }
+        invalidIndexOnFailure = true;
 
+        pCategory = CS_ctdef(pName);
+        if (NULL == pCategory)
+        {
+            MgStringCollection arguments;
+            arguments.Add(str);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+        }
+
+        int updateResult = CS_ctupd(pCategory);
+        if (updateResult < 0)
+        {
+            MgStringCollection arguments;
+            arguments.Add(str);
+            throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemInternalException", NULL);
+        }
+
+        _ASSERT(1 == updateResult);
+        if (0 == updateResult)
+        {
+            //an item was added... something went wrong here; invalidate the index so we re-read it next time
+            this->InvalidateIndex();
+        }
+
     MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Modify")
-    if (pFile)
-    {
-        CS_fclose(pFile);
-    }
-    //No, we can't do in-place replacement.  We have to re-write the file.
-    RewriteFile(def.Name(), &def);
+
+        delete[] pName;
+        pName = NULL;
+
+        CSrlsCategory(pCategory);
+        pCategory = NULL;
+
+        if(invalidIndexOnFailure && NULL != mgException)
+            this->InvalidateIndex();
+
     MG_THROW()
 }
 
@@ -673,54 +501,53 @@
 MgCoordinateSystemCategory* CCoordinateSystemCategoryDictionary::GetCategory(CREFSTRING sName)
 {
     Ptr<CCoordinateSystemCategory> pNew;
-    csFILE* pFile=NULL;
     char *pName = NULL;
-    SmartCriticalClass critical(false);
-    MG_TRY()
+    cs_Ctdef_* pCategory = NULL;
 
-    //Look for it in our index
-    pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
+    bool invalidIndexOnFailure = false;
 
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    SmartCriticalClass critical;
+    MG_TRY()
 
-    CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
+        //Look for it in our index
+        pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
+        CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
 
-    //Did we find it?
-    if (iter == Index().end())
-    {
-        //Nope.
-        MgStringCollection arguments;
-        arguments.Add(sName);
-        throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
-    }
+        //Did we find it?
+        if (iter == Index().end())
+        {
+            //Nope.
+            MgStringCollection arguments;
+            arguments.Add(sName);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+        }
 
-    //Make a new object
-    pNew = new CCoordinateSystemCategory(m_pCatalog);
+        invalidIndexOnFailure = true;
 
-    if (NULL == pNew.p)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+        cs_Ctdef_* pCategory = CS_ctdef(pName);
+        if (NULL == pCategory)
+        {
+            //Nope.
+            MgStringCollection arguments;
+            arguments.Add(sName);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+        }
 
-    //Get the definition out of the file.
-    critical.Enter();
-    pFile=Open(Read);
-    long pos = (*iter).second;
-    CS_fseek(pFile, pos, SEEK_SET);
-    pNew->LoadFromFstream(pFile);
+        //Make a new object with the [cs_Ctdef_] instance we got
+        pNew = new CCoordinateSystemCategory(m_pCatalog, pCategory);
+        pCategory = NULL; //is now owned by [pNew]
 
     MG_CATCH(L"MgCoordinateSystemCategoryDictionary.GetCategory")
 
-    if (pFile)
-    {
-        CS_fclose(pFile);
-    }
+        delete [] pName;
+        pName = NULL;
 
-    delete [] pName;
+        CSrlsCategory(pCategory);
+        pCategory = NULL;
 
+        if (NULL != mgException && invalidIndexOnFailure)
+            this->InvalidateIndex();
+
     MG_THROW()
 
     return pNew.Detach();
@@ -729,21 +556,26 @@
 //Returns whether the set contains a def with the specified name.
 bool CCoordinateSystemCategoryDictionary::Has(CREFSTRING sName)
 {
-    bool bHas=false;
+    char *pName = NULL;
+    bool bHas = false;
 
     MG_TRY()
 
-    //Look in our index
-    char *pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
-    if (NULL == pName)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Has", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
-    delete [] pName;
-    bHas=(iter != Index().end());
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.Has")
+        //Look in our index
+        pName = Convert_Wide_To_Ascii(sName.c_str());    //need to delete [] pName
 
+        SmartCriticalClass csmapLock;
+
+        CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
+        bHas = (iter != Index().end());
+
+    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Has")
+
+        delete pName;
+        pName = NULL;
+
+    MG_THROW()
+
     return bHas;
 }
 
@@ -751,25 +583,19 @@
 //Gets an enumerator for all the defs in the set.
 MgCoordinateSystemEnum* CCoordinateSystemCategoryDictionary::GetEnum()
 {
-    MgCoordinateSystemEnum* pEnum=NULL;
+    Ptr<CCoordinateSystemEnumCategory> pNewEnum;
 
     MG_TRY()
 
     //Make an enumerator object
-    CCoordinateSystemEnumCategory *pNewEnum=new CCoordinateSystemEnumCategory;
+    pNewEnum = new CCoordinateSystemEnumCategory;
+
     //Set it up to use our list
-    //const_cast because "this" will not be modified in the process
-    MgCoordinateSystemCategoryDictionary* pSet=dynamic_cast<MgCoordinateSystemCategoryDictionary*>(this);
-    assert(pSet);
-    pNewEnum->Initialize(pSet, &List());
+    pNewEnum->Initialize(this, &List());
 
-    //Now that we have the new object set up, QI it to get the
-    //proper interface pointer.  This also takes care of reference
-    //counting so that Release() will properly free the new object.
-    pEnum=static_cast<MgCoordinateSystemEnum*>(pNewEnum);
-    assert(pEnum);
     MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.GetEnum")
-    return pEnum;
+
+    return pNewEnum.Detach();
 }
 
 //-----------------------------------------------------------------------------
@@ -784,99 +610,58 @@
 //-----------------------------------------------------------------------------
 void CCoordinateSystemCategoryDictionary::Rename(CREFSTRING sOldName, CREFSTRING sNewName)
 {
-    csFILE* pFile=NULL;
+    char *pOldName = NULL;
+    char *pNewName = NULL;
+    cs_Ctdef_* pCategory = NULL;
 
+    bool invalidIndexOnFailure = false;
+    SmartCriticalClass csmapLock;
+
     MG_TRY()
 
-    //Make sure new name is a valid one
-    CCoordinateSystemCategory def(this->m_pCatalog);
-    bool bLegal = def.IsLegalName(sNewName);
-    if (!bLegal)
-    {
-        MgStringCollection whatArguments;
-        whatArguments.Add(sNewName);
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &whatArguments, L"", NULL);
-    }
+        //Make sure def with old name is present
+        pOldName = Convert_Wide_To_Ascii(sOldName.c_str());
+        CCategoryName oldCategory(pOldName);
 
-    //Make sure def with old name is present
-    char *pName = Convert_Wide_To_Ascii(sOldName.c_str());
-    CCategoryName oldCategory(pName);
-    delete [] pName;
-    CCategoryNameIndexMap::iterator iter = Index().find(oldCategory);
-    if (iter == Index().end())
-    {
-        //nope, not there
-        MgStringCollection arguments;
-        arguments.Add(sOldName);
-        throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
-    }
+        CCategoryNameIndexMap::iterator iter = Index().find(oldCategory);
+        if (iter == Index().end())
+        {
+            //nope, not there
+            MgStringCollection arguments;
+            arguments.Add(sOldName);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+        }
 
-    //Make sure def with new name is *not* present
-    bool bHas = Has(sNewName);
-    if (bHas)
-    {
-        //there's already a def with that name
-        throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDuplicateException", NULL);
-    }
+        invalidIndexOnFailure = true;
+        pCategory = CS_ctdef(pOldName);
+        if (NULL == pCategory)
+        {
+            MgStringCollection arguments;
+            arguments.Add(sOldName);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+        }
 
-    INT32 lMagic;
-    char szMode[10];
-    GetFileModes(Write, szMode);
-    STRING strPath=GetPath();
-    pFile=OpenDictionaryFile(strPath.c_str(), szMode, lMagic, ValidCategoryMagic);
+        pNewName = Convert_Wide_To_Ascii(sNewName.c_str());
+        if (CSrplCatNameEx(pOldName, pNewName))
+            throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNotFoundException", NULL);
 
-    //load our previous def, with the old name
-    long pos = (*iter).second;
-    CS_fseek(pFile, pos, SEEK_SET);
-    def.LoadFromFstream(pFile);
+        if (CSupdCategories(NULL))
+            throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNotFoundException", NULL);
 
-    //Change its name
-    def.SetName(sNewName);
+        long index = iter->second;
+        Index().erase(iter);
+        Index().insert(std::pair<CCategoryName,long>(CCategoryName(pNewName), index));
 
-    //Find out how big the existing def is in the file.
-    UINT32 ulFileSize;
-    CS_fseek(pFile, pos + knMaxCategoryNameLen + sizeof(UINT32), SEEK_SET);
-    size_t nRead=CS_fread(reinterpret_cast<char *>(&ulFileSize), sizeof(ulFileSize), 1, pFile);
-    if (1!=nRead)
-    {
-        throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.rename")
 
-    //Overwrite the def
-    CS_fseek(pFile, pos, SEEK_SET);
-    clearerr(pFile);
-    def.SaveToFstream(pFile, ulFileSize);
+        delete[] pOldName;
+        delete[] pNewName;
+        pOldName = NULL;
+        pNewName = NULL;
 
-    //Update our index as appropriate.
-    pName = Convert_Wide_To_Ascii(sNewName.c_str());
-    CCategoryName newCategory(pName);
-    delete [] pName;
-    try
-    {
-        Index().erase(iter);
-        Index().insert(CCategoryNameIndexPair(newCategory, pos));
-    }
-    catch (std::bad_alloc)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    CCategoryNameList::iterator iterList;
-    for (iterList = List().begin(); iterList != List().end(); ++iterList)
-    {
-        if (oldCategory == *iterList)
-        {
-            *iterList = newCategory;
-            break;
-        }
-    }
+        if (NULL != mgException && invalidIndexOnFailure)
+            this->InvalidateIndex();
 
-    //Success!
-    MG_CATCH(L"MgCoordinateSystemCategoryDictionary.rename")
-    if (pFile)
-    {
-        CS_fclose(pFile);
-        pFile=NULL;
-    }
     MG_THROW()
 }
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysCategoryDictionary.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -66,9 +66,9 @@
     bool m_bIndexDirty;
 
     //Private member functions
-    void GenerateIndex(csFILE *pFile);
-    void RewriteFile(const char *kpDefName, CCoordinateSystemCategory *pDef=NULL);
-    csFILE* Open(CsDictionaryOpenMode nOpenMode);
+    void GenerateIndex();
+    void InvalidateIndex();
+
     CCategoryNameIndexMap& Index();
     CCategoryNameList& List();
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDatumDictionary.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDatumDictionary.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDatumDictionary.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -683,15 +683,21 @@
                 DtKey06,
                 DtDesc06,
                 CS_dtrd06);
-            break;   
+            break;
         case 7:
         case 8:
             //Generate summary for version 7 or 8 datum file.
+
+            //close the file before calling into the [read all CS-Map defs] method
+            if (0 != CS_fclose(pFile))
+                throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
+
+            pFile = NULL;
+
             m_pmapSystemNameDescription = MentorDictionary::GenerateSystemNameDescriptionMap<cs_Dtdef_>(
-                pFile,
                 DtKey,
                 DtDesc,
-                CS_dtrd);
+                CS_dtdefAll);
             break;
         default:
             assert(0);
@@ -747,7 +753,7 @@
         throw new MgInvalidArgumentException(L"CCoordinateSystemDatumDictionary.ReadAllDatums", __LINE__, __WFILE__, NULL, L"", NULL);
 
     //place a lock here - we don't want any interference; what we need is the *current* status of all dictionary files
-    SmartCriticalClass dictionaryLock(true);
+    SmartCriticalClass dictionaryLock;
 
     Ptr<MgCoordinateSystemCatalog> catalog = targetDictionary->GetCatalog();
     Ptr<MgCoordinateSystemEllipsoidDictionary> ellipsoidDictionary = catalog->GetEllipsoidDictionary();
@@ -763,7 +769,7 @@
     //finally, read all "root" coordinate system definitions from the dictionary
     return MentorDictionary::ReadAllDefinitions<MgCoordinateSystemDatum, cs_Dtdef_, CCoordinateSystemDatumDictionary>(
         datumDictionary,
-        CS_dtrd, 
+        CS_dtdefAll, 
         NULL, //no additional processing
         &CCoordinateSystemDatumDictionary::GetDatum,
         &ellipsoidInfos,

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionary.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionary.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionary.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -356,6 +356,8 @@
 //------------------------------------------------------------------------
 void CCoordinateSystemDictionary::SetFileName(CREFSTRING sFileName)
 {
+    char* szCs = NULL;
+
     MG_TRY()
 
     //Make local variables to hold converted strings
@@ -375,22 +377,22 @@
         m_sFileName,
         L"MgCoordinateSystemDictionary.SetFileName");
 
+    SmartCriticalClass csMapLock;
+
     //Okay, everybody opened all right, so update Mentor's global
     //variables appropriately.
-    char* szCs=Convert_Wide_To_Ascii(sFileName.c_str()); //ABA: why use sFileName here?
-    CriticalClass.Enter();
+    szCs = Convert_Wide_To_Ascii(sFileName.c_str());
     CS_csfnm(szCs);
-    CriticalClass.Leave();
-    delete[] szCs; //ABA: where is that deleted in case of an exception
 
-    if (m_pmapSystemNameDescription)
-    {
-        m_pmapSystemNameDescription->clear();
-        delete m_pmapSystemNameDescription;
-        m_pmapSystemNameDescription=NULL;
-    }
+    delete m_pmapSystemNameDescription;
+    m_pmapSystemNameDescription = NULL;
 
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemDictionary.SetFileName")
+    MG_CATCH(L"MgCoordinateSystemDictionary.SetFileName")
+
+        delete[] szCs;
+        szCs = NULL;
+
+    MG_THROW()
 }
 
 //------------------------------------------------------------------------
@@ -692,7 +694,7 @@
     //finally, read all "root" coordinate system definitions from the dictionary
     return MentorDictionary::ReadAllDefinitions<MgCoordinateSystem, cs_Csdef_, CCoordinateSystemDictionary>(
         csDictionary,
-        CS_csrd, 
+        CS_csdefAll, 
         &CCoordinateSystemDictionary::DoCsDefPostReadProcessing,
         &CCoordinateSystemDictionary::GetCoordinateSystem,
         &datumEllipsoidInfos,
@@ -729,8 +731,7 @@
     MG_TRY()
     
     STRING strPath=GetPath();
-    pFile=MentorDictionary::Open(m_lMagic, CoordinateSystemValidMagic, strPath.c_str(), Read);
-
+    pFile = MentorDictionary::Open(m_lMagic, CoordinateSystemValidMagic, strPath.c_str(), Read);
     const int nVersion = CoordinateSystemVersion(m_lMagic);
     assert(nVersion > 0);
 
@@ -760,11 +761,16 @@
         case 7:
         case 8:
             //Generate summary for version 7 or 8 coordsys file.
+            //close the file before calling into the [read all CS-Map defs] method
+            if (0 != CS_fclose(pFile))
+                throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
+
+            pFile = NULL;
+
             m_pmapSystemNameDescription = MentorDictionary::GenerateSystemNameDescriptionMap<cs_Csdef_>(
-                pFile,
                 CsKey,
                 CsDesc,
-                CS_csrd);
+                CS_csdefAll);
             break;
         default:
             assert(0);
@@ -783,11 +789,11 @@
         throw new MgOutOfMemoryException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    if (0!=CS_fclose(pFile))
+    if (pFile && 0 != CS_fclose(pFile))
     {
         throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
     }
-    pFile=NULL;
+    pFile = NULL;
 
     MG_CATCH(L"MgCoordinateSystemDictionary.GetEnum")
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -323,7 +323,6 @@
         dictionaryFile = MentorDictionary::Open(this->dictMagicNumber, definitionAccess->magicNumberCallback, strPath.c_str(), Read);
 
         allDictionaryEntries = MentorDictionary::GenerateSystemNameDescriptionMap<U>(
-            dictionaryFile,
             definitionAccess->readDefinitionName,
             definitionAccess->readDefinitionDescription,
             definitionAccess->readAllDefinitions);

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysDictionaryBase.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -42,7 +42,7 @@
         void (*FullInitialize)(T*, U*, MgCoordinateSystemCatalog* catalog), //fully initializes the Mg API objects from the CS Map API struct
         const char* (*ReadDefinitionName)(const U& definition), //reads the definition's name; the caller has to copy the string's content
         const char* (*ReadDefinitionDescription)(const U& definition), //reads the definition's description; the caller must copy the string's content (if not NULL)
-        int (*ReadAllDefinitions) (csFILE *strm, U* definition, int*), // reads the entire content of a dictionary file; depends on the current file pointer position
+        int (*ReadAllDefinitions) (U** pDefinition[]), // reads the entire content of a dictionary file(s);
         void (*CsMapTargetFileName)(const char *newFileName), //set the target dictionary file name in the CS Map library
         CsDictionaryOpenMode (*MagicNumberCallback)(long)) //returns the correct open mode for a dictionary file taking into account the magic number read from the file; passed in as long
         :
@@ -73,7 +73,7 @@
     void (*fullInitialize)(T*, U*, MgCoordinateSystemCatalog* catalog);
     const char* (*readDefinitionName)(const U& definition);
     const char* (*readDefinitionDescription)(const U& definition);
-    int (*readAllDefinitions) (csFILE *strm, U* definition, int*);
+    int (*readAllDefinitions) (U** pDefinitions[]);
     void (*csMapTargetFileName) (const char *newFileName);
     CsDictionaryOpenMode (*magicNumberCallback)(long);
 };

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -580,16 +580,22 @@
 
     MG_TRY()
     STRING strPath=GetPath();
-    pFile=MentorDictionary::Open(m_lMagic, EllipsoidValidMagic, strPath.c_str(), Read);
+    pFile = MentorDictionary::Open(m_lMagic, EllipsoidValidMagic, strPath.c_str(), Read);
+    _ASSERT(pFile);
 
+    //close the file before calling into the [read all CS-Map defs] method
+    if (0 != CS_fclose(pFile))
+        throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
+
+    pFile = NULL;
+
     //Generate a summary list, if we don't already have one
     if (NULL == m_pmapSystemNameDescription)
     {
         m_pmapSystemNameDescription = MentorDictionary::GenerateSystemNameDescriptionMap<cs_Eldef_>(
-            pFile,
             ElKey,
             ElDesc,
-            CS_elrd);
+            CS_eldefAll);
         if (NULL == m_pmapSystemNameDescription)
         {
             throw new MgInvalidArgumentException(L"MgCoordinateSystemEllipsoidDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
@@ -599,16 +605,13 @@
     //Make an enumerator object
     pNew = new CCoordinateSystemEnumEllipsoid;
 
-    if (NULL == pNew.p)
+    if (pFile && 0 != CS_fclose(pFile))
     {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemEllipsoidDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    if (0!=CS_fclose(pFile))
-    {
         throw new MgFileIoException(L"MgCoordinateSystemEllipsoidDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
     }
-    pFile=NULL;
 
+    pFile = NULL;
+
     MG_CATCH(L"MgCoordinateSystemEllipsoidDictionary.GetEnum")
 
     if (pFile)
@@ -638,7 +641,7 @@
 
     return MentorDictionary::ReadAllDefinitions<MgCoordinateSystemEllipsoid, cs_Eldef_, CCoordinateSystemEllipsoidDictionary>(
         ellipsoidDictionary,
-        CS_elrd, 
+        CS_eldefAll,
         NULL, //no post processing needed
         &CCoordinateSystemEllipsoidDictionary::GetEllipsoid,
         NULL, //no additional info needed/used to create an MgCoordinateSystemEllipsoid object

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCategory.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCategory.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCategory.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -133,7 +133,6 @@
 void CCoordinateSystemEnumCategory::Initialize(
     MgCoordinateSystemCategoryDictionary* pDict,
     CCategoryNameList *kpCategoryNameList)
-
 {
     assert(NULL != kpCategoryNameList);
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -15,6 +15,8 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
+#include <vector>
+
 #include "GeometryCommon.h"
 #include "CoordSysCommon.h"
 
@@ -23,14 +25,26 @@
 #include "MentorUtil.h"                                 //for IsLegalMentorName()
 
 using namespace CSLibrary;
+using namespace std;
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 CCoordinateSystemEnumCoordinateSystemInCategory::CCoordinateSystemEnumCoordinateSystemInCategory(MgCoordinateSystemCatalog *pCatalog)
-    : m_kpListCoordinateSystemNames(NULL)
 {
     m_pCatalog = SAFE_ADDREF(pCatalog);
 }
 
+CCoordinateSystemEnumCoordinateSystemInCategory::CCoordinateSystemEnumCoordinateSystemInCategory(CCoordinateSystemEnumCoordinateSystemInCategory const& copyFrom)
+{
+    this->m_pCatalog = SAFE_ADDREF(copyFrom.m_pCatalog.p);
+    this->Initialize(copyFrom.m_csNames);
+
+    for (size_t i=0; i < copyFrom.m_vectFilter.size(); i++)
+    {
+        this->m_vectFilter.push_back(copyFrom.m_vectFilter[i]);
+        SAFE_ADDREF(this->m_vectFilter[i]);
+    }
+}
+
 CCoordinateSystemEnumCoordinateSystemInCategory::~CCoordinateSystemEnumCoordinateSystemInCategory()
 {
     ClearFilter();
@@ -69,14 +83,10 @@
 //This function must be called on a freshly-constructed CCoordinateSystemEnumCoordinateSystemInCategory
 //object before anything else can be done with it.
 //
-void CCoordinateSystemEnumCoordinateSystemInCategory::Initialize(
-    const CSystemNameList *kpListCoordinateSystemNames)
-
+void CCoordinateSystemEnumCoordinateSystemInCategory::Initialize(std::vector<STRING> const& allCsNames)
 {
-    assert(NULL != kpListCoordinateSystemNames);
-
-    m_kpListCoordinateSystemNames = kpListCoordinateSystemNames;
-    m_iter = m_kpListCoordinateSystemNames->begin();
+    this->m_csNames = allCsNames;
+    this->m_iter = this->m_csNames.begin();
 }
 
 //----------------------------------------------------------
@@ -95,14 +105,14 @@
     {
         throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemEnum.Next", __LINE__, __WFILE__, NULL, L"", NULL);
     }
-    Ptr<MgCoordinateSystemDictionary> pCsDict=m_pCatalog->GetCoordinateSystemDictionary();
+
+    Ptr<MgCoordinateSystemDictionary> pCsDict = m_pCatalog->GetCoordinateSystemDictionary();
     if (!pCsDict)
     {
         throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystem.Next", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoDictionaryException", NULL);
     }
 
-    wchar_t* pstr;
-    for (; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
+    for (; m_iter != this->m_csNames.end(); ++m_iter)
     {
         if (pOutput->GetCount() == ulCount)
         {
@@ -110,31 +120,16 @@
             return pOutput.Detach();
         }
 
-        //get the coordinate system name from the category
-        const char *kpName = (*m_iter).Name();
-
-        assert(IsLegalMentorName(kpName));
-        pstr = Convert_Ascii_To_Wide(kpName);
-        if (NULL == pstr)
-        {
-            throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.Next", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        STRING strCsName(pstr);
-        delete[] pstr;
-
         //now get the definition from the dictionary
-        Ptr<MgGuardDisposable> pCs=pCsDict->Get(strCsName);
-        if (!pCs)
-        {
-            MgStringCollection arguments;
-            arguments.Add(strCsName);
-            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemEnum.Next", __LINE__, __WFILE__, &arguments, L"", NULL);
-        }
+        Ptr<MgGuardDisposable> pCs = pCsDict->Get(m_iter->c_str());
+        _ASSERT(NULL != pCs);
+
         //is it filtered out?
         if (IsFilteredOut(pCs))
         {
             continue;
         }
+
         pOutput->Add(pCs);
     }
 
@@ -150,36 +145,14 @@
 {
     Ptr<MgStringCollection> pOutput;
     MG_TRY()
-    pOutput=new MgStringCollection;
-    if (!pOutput)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextName", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    wchar_t* pstr;
-    for (; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
-    {
-        if (pOutput->GetCount() == ulCount)
-        {
-            //success
-            return pOutput.Detach();
-        }
-        const char *kpName = (*m_iter).Name();
 
-        if (IsFilteredOut(kpName))
+        pOutput=new MgStringCollection;
+        Ptr<MgDisposableCollection> pNextCsObjects = this->Next(ulCount);
+        for(INT32 i = 0; i < pNextCsObjects->GetCount(); ++i)
         {
-            continue;
+            pOutput->Add(Ptr<MgCoordinateSystem>(dynamic_cast<MgCoordinateSystem*>(pNextCsObjects->GetItem(i)))->GetCsCode());
         }
 
-        assert(IsLegalMentorName(kpName));
-        pstr = Convert_Ascii_To_Wide(kpName);
-        if (NULL == pstr)
-        {
-            throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextName", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        pOutput->Add(pstr);
-        delete[] pstr;
-    }
-
     MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.NextName")
     return pOutput.Detach();
 }
@@ -189,61 +162,14 @@
 {
     Ptr<MgStringCollection> pOutput;
     MG_TRY()
-    pOutput=new MgStringCollection;
-    if (!pOutput)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    if (!m_pCatalog)
-    {
-        throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    Ptr<MgCoordinateSystemDictionary> pCsDict=m_pCatalog->GetCoordinateSystemDictionary();
-    if (!pCsDict)
-    {
-        throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystem.NextDescription", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoDictionaryException", NULL);
-    }
 
-    wchar_t* pstr;
-    for (; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
-    {
-        if (pOutput->GetCount() == ulCount)
+        pOutput=new MgStringCollection;
+        Ptr<MgDisposableCollection> pNextCsObjects = this->Next(ulCount);
+        for(INT32 i = 0; i < pNextCsObjects->GetCount(); ++i)
         {
-            //success
-            return pOutput.Detach();
+            pOutput->Add(Ptr<MgCoordinateSystem>(dynamic_cast<MgCoordinateSystem*>(pNextCsObjects->GetItem(i)))->GetDescription());
         }
-        //get the coordinate system name from the category
-        const char *kpName = (*m_iter).Name();
 
-        assert(IsLegalMentorName(kpName));
-        pstr = Convert_Ascii_To_Wide(kpName);
-        if (NULL == pstr)
-        {
-            throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        STRING strCsName(pstr);
-        delete[] pstr;
-
-        //now get the definition from the dictionary
-        Ptr<MgGuardDisposable> pCs=pCsDict->Get(strCsName);
-        if (!pCs)
-        {
-            MgStringCollection arguments;
-            arguments.Add(strCsName);
-            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, &arguments, L"", NULL);
-        }
-        //is it filtered out?
-        if (IsFilteredOut(pCs))
-        {
-            continue;
-        }
-        MgCoordinateSystem* pCsDef=dynamic_cast<MgCoordinateSystem*>(pCs.p);
-        assert(pCsDef);
-        STRING strDescription=pCsDef->GetDescription();
-
-        pOutput->Add(strDescription);
-    }
-
     MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.NextDescription")
     return pOutput.Detach();
 }
@@ -256,16 +182,16 @@
 {
     MG_TRY()
     UINT32 ulSkipped;
-    for (ulSkipped=0; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
+    for (ulSkipped=0; m_iter != m_csNames.end(); ++m_iter)
     {
         if (ulSkipped == ulSkipCount)
         {
             //success
             return;
         }
+
         //get the coordinate system name from the category
-        const char *kpName = (*m_iter).Name();
-        if (IsFilteredOut(kpName))
+        if (IsFilteredOut(m_iter->c_str()))
         {
             continue;
         }
@@ -285,40 +211,13 @@
 //
 void CCoordinateSystemEnumCoordinateSystemInCategory::Reset()
 {
-    m_iter = m_kpListCoordinateSystemNames->begin();
+    m_iter = this->m_csNames.begin();
 }
 
 //This function evaluates the provided def using the current
 //Filter.  If there is no Filter, the result will always
 //be true.
 //
-bool CCoordinateSystemEnumCoordinateSystemInCategory::IsFilteredOut(const char *kpName)
-{
-    bool bIsFiltered=false;
-
-    MG_TRY()
-    assert(NULL != kpName);
-    if (!kpName)
-    {
-        throw new MgNullArgumentException(L"MgCoordinateSystemEnum.IsFilteredOut", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //Get a def from the set for the Filter to work with
-    wchar_t* pStr = Convert_Ascii_To_Wide(kpName);
-    if (NULL == pStr)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.IsFilteredOut", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    bIsFiltered=IsFilteredOut(pStr);
-    delete[] pStr;
-    MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.IsFilteredOut")
-    return bIsFiltered;
-}
-
-//This function evaluates the provided def using the current
-//Filter.  If there is no Filter, the result will always
-//be true.
-//
 bool CCoordinateSystemEnumCoordinateSystemInCategory::IsFilteredOut(const wchar_t *kpName)
 {
     bool bIsFiltered=false;
@@ -398,29 +297,13 @@
 //
 MgCoordinateSystemEnum* CCoordinateSystemEnumCoordinateSystemInCategory::CreateClone()
 {
-    Ptr<CCoordinateSystemEnumCoordinateSystemInCategory> pNew;
-
     MG_TRY()
 
-    //Make a new object
-    pNew = new CCoordinateSystemEnumCoordinateSystemInCategory(m_pCatalog);
+        //Make a new object and return it
+        return new CCoordinateSystemEnumCoordinateSystemInCategory(*this);
 
-    if (NULL == pNew.p)
-    {
-        throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.CreateClone", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
-    //Copy it from this one
-    pNew->m_iter = m_iter;
-    pNew->m_kpListCoordinateSystemNames = m_kpListCoordinateSystemNames;
-    for (size_t i=0; i<m_vectFilter.size(); i++)
-    {
-        pNew->m_vectFilter.push_back(m_vectFilter[i]);
-        SAFE_ADDREF(m_vectFilter[i]);
-    }
-
     MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.CreateClone")
 
-    //And we're done!  Return success.
-    return pNew.Detach();
+    _ASSERT(false);
+    return NULL;
 }

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -25,9 +25,10 @@
 {
 public:
     CCoordinateSystemEnumCoordinateSystemInCategory(MgCoordinateSystemCatalog *pCatalog);
+    CCoordinateSystemEnumCoordinateSystemInCategory(CCoordinateSystemEnumCoordinateSystemInCategory const& copyFrom);
     virtual ~CCoordinateSystemEnumCoordinateSystemInCategory();
 
-    void Initialize(const CSystemNameList *kpListCoordinateSystemNames);
+    void Initialize(std::vector<STRING> const& allCsNames);
 
     virtual MgDisposableCollection* Next(UINT32 ulCount);
     virtual void Skip(UINT32 ulSkipCount);
@@ -42,14 +43,13 @@
 
 protected:
     bool IsFilteredOut(MgGuardDisposable *pDef);
-    bool IsFilteredOut(const char *kpName);
     bool IsFilteredOut(const wchar_t *kpName);
     void ClearFilter();
 
 protected:
     //Data members
-    const CSystemNameList *m_kpListCoordinateSystemNames;
-    CSystemNameList::const_iterator m_iter;
+    std::vector<STRING> m_csNames;
+    std::vector<STRING>::const_iterator m_iter;
     Ptr<MgCoordinateSystemCatalog> m_pCatalog;
     std::vector<MgCoordinateSystemFilter*> m_vectFilter;
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -48,8 +48,9 @@
 
     CCoordinateSystemGeodeticPathDictionary::ReadName,
     CCoordinateSystemGeodeticPathDictionary::ReadDescription,
-    CCoordinateSystemGeodeticPathDictionary::ReadAllGeodeticPaths,
 
+    CS_gpdefAll,
+
     CS_gpfnm,
 
     CCoordinateSystemGeodeticPathDictionary::GetFileOpenMode);
@@ -91,11 +92,6 @@
     return CS_gpupd(csPath);
 }
 
-int CCoordinateSystemGeodeticPathDictionary::ReadAllGeodeticPaths(csFILE *file, cs_GeodeticPath_ *gp_def, int* /*unused*/)
-{
-    return CS_gprd(file, gp_def);
-}
-
 bool CCoordinateSystemGeodeticPathDictionary::SetupCsGeodeticPathStruct(CCoordinateSystemGeodeticPath* mgGeodeticPath, cs_GeodeticPath_& csPath)
 {
     _ASSERT(NULL != mgGeodeticPath);

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -72,7 +72,6 @@
         static const char* ReadDescription(const cs_GeodeticPath_& definition);
 
         static int UpdateGeodeticPath(cs_GeodeticPath_* csPath, int /*unused*/);
-        static int ReadAllGeodeticPaths(csFILE *file, cs_GeodeticPath_ *gp_def, int* /*unused*/);
 
         static bool SetupCsGeodeticPathStruct(CCoordinateSystemGeodeticPath* mgGeodeticPath, cs_GeodeticPath_& csPath);
         static void FullInitialize(CCoordinateSystemGeodeticPath* mgGeodeticPath, cs_GeodeticPath_* csPath, MgCoordinateSystemCatalog* catalog);

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -48,7 +48,7 @@
 
     CCoordinateSystemGeodeticTransformDefDictionary::ReadName,
     CCoordinateSystemGeodeticTransformDefDictionary::ReadDescription,
-    CCoordinateSystemGeodeticTransformDefDictionary::ReadAllGeodeticTransformDefs,
+    CS_gxdefAll,
 
     CS_gxfnm,
 
@@ -200,11 +200,6 @@
     return definition.description;
 }
 
-int CCoordinateSystemGeodeticTransformDefDictionary::ReadAllGeodeticTransformDefs(csFILE *file, cs_GeodeticTransform_* csTransformDef, int* /*unused*/)
-{
-    return CS_gxrd(file, csTransformDef);
-}
-
 CsDictionaryOpenMode CCoordinateSystemGeodeticTransformDefDictionary::GetFileOpenMode(long magicNumberFromFile)
 {
     if (cs_GXDEF_MAGIC == magicNumberFromFile)

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -71,8 +71,6 @@
         static const char* ReadName(const cs_GeodeticTransform_& definition);
         static const char* ReadDescription(const cs_GeodeticTransform_& definition);
 
-        static int ReadAllGeodeticTransformDefs(csFILE *file, cs_GeodeticTransform_* csTransformDef, int* /*unused*/);
-
         static CsDictionaryOpenMode GetFileOpenMode(long magicNumberFromFile);
     };
 

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysUtil.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysUtil.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CoordSysUtil.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -38,8 +38,6 @@
 
 namespace CSLibrary
 {
-const STRING CategoryFilename      = L"Category.CSD";  // NOXLATE
-
 const double ZERO_SCALE = 1e-9;  //-- unit scale smaller than this is considered zero
 const double ZERO_VALUE = 1e-12; //-- value smaller than this is considered zero
 }

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -68,6 +68,19 @@
     ::LeaveCriticalSection(&CritSect);
 }
 
+#ifdef _DEBUG
+    bool CustomCriticalSection::IsEntered()
+    {
+        if (!::TryEnterCriticalSection(&CritSect))
+            return false;
+
+        bool wasHeld = (CritSect.RecursionCount > 0);
+        ::LeaveCriticalSection(&CritSect);
+
+        return wasHeld;
+    }
+#endif
+
 #else //LINUX
 
 CustomCriticalSection::~CustomCriticalSection()
@@ -97,4 +110,11 @@
     pthread_mutex_unlock(&CritSect);
 }
 
-#endif //_WIN32
+#ifdef _DEBUG
+    bool CustomCriticalSection::IsEntered()
+    {
+        return true;
+    }
+#endif
+
+#endif //_WIN32 / LINUX

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CriticalSection.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -31,6 +31,12 @@
     void Enter();
     void Leave();
 
+#ifdef _DEBUG
+
+    bool IsEntered();
+
+#endif
+
 private:
     bool m_bInitialized;
 };

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/CsmapVersion.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/CsmapVersion.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/CsmapVersion.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -19,6 +19,7 @@
 #define __CSMAP_CONSTANTS__
 
 // Windows and Linux will always use the environment variable
-#define MENTOR_DICTIONARY_PATH          "MENTOR_DICTIONARY_PATH"                    // No translate
+#define MENTOR_DICTIONARY_PATH              "MENTOR_DICTIONARY_PATH"                    // No translate
+#define MENTOR_USER_DICTIONARY_PATH         "MENTOR_USER_DICTIONARY_PATH"               // No translate
 
 #endif

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/MentorDictionary.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/MentorDictionary.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/MentorDictionary.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -41,6 +41,37 @@
 
 namespace MentorDictionary
 {
+    template<class TCsMap, class TContainer >
+    class TContainerPtr : public auto_ptr<TContainer>
+    {
+    public:
+        TContainerPtr()
+            : auto_ptr<TContainer>()
+        {
+        }
+
+        TContainerPtr(TContainer* pContainer)
+            : auto_ptr<TContainer>(pContainer)
+        {
+        }
+
+        ~TContainerPtr()
+        {
+            TContainer* pContainer = auto_ptr<TContainer>::get();
+            if (NULL == pContainer)
+                return;
+
+            for(typename TContainer::iterator iter = pContainer->begin();
+                iter != pContainer->end(); ++iter)
+            {
+                if (NULL != *iter)
+                    CS_free(*iter);
+                *iter = NULL;
+            }
+        }
+    };
+
+
     void SetFileName(INT32& lMagic, CsDictionaryOpenMode (*ValidMagic)(long), CREFSTRING sDirectory, CREFSTRING sFileName, REFSTRING sFileNameSet, const wchar_t* kpMethodName);
     csFILE* Open(INT32& lMagic, CsDictionaryOpenMode (*ValidMagic)(long), const wchar_t* kpPath, CsDictionaryOpenMode nOpenMode);
     CsDictionaryOpenMode OpenReadDictionaryOpenCallback(long dictMagicNumber);
@@ -69,7 +100,7 @@
     //iterates through all entries return a vector of definitions in the same order as they've been returned by CsMap
     //return NULL, if the file couldn't be read successfully
     template <class T>
-    vector<T>*
+    vector<T*>*
     ReadDictionaryEntries(
         csFILE *pFile,
         int (*CS_Trd)(csFILE*, T *, int *))
@@ -77,12 +108,17 @@
         //Scan through the file - add an entry for each definition we find
         try
         {
-            auto_ptr<vector<T> > allDictEntries(new vector<T>);
+            TContainerPtr<T, vector<T*> > allDictEntries;
+            allDictEntries.reset(new vector<T*>);
 
             int nCrypt;
-            T def;
+            T* def = NULL;
 
-            while (MentorDictionary::GetNextEntry(pFile, def, nCrypt, CS_Trd))
+            def = (T*) CS_malc(sizeof(T));
+            if (NULL == def)
+                throw new MgOutOfMemoryException(L"MentorDictionary.ReadDictionaryEntries", __LINE__, __WFILE__, NULL, L"", NULL);
+
+            while (MentorDictionary::GetNextEntry(pFile, *def, nCrypt, CS_Trd))
             {
                 allDictEntries->push_back(def);
 
@@ -104,11 +140,13 @@
     //opens a dictionary file for reading and then iterates over all entries and returns them as a vector; the order is the same as returned by CsMap
     //before accessing the file, a global lock is placed through an [SmartCriticalClass] object
     template <class T>
-    vector<T>* ReadDictionaryEntries(
+    vector<T*>* ReadDictionaryEntries(
         /*IN*/ MgCoordinateSystemDictionaryBase* targetDictionary,
         /*IN*/ int (*CS_Trd)(csFILE*, T *, int *))
     {
-        auto_ptr<vector<T> > allDefs;
+	typedef vector<T*> CsMapDefPtrVector;
+        
+	TContainerPtr<T, CsMapDefPtrVector> allDefs;
         csFILE *pFile = NULL;
 
         MG_TRY()
@@ -137,7 +175,7 @@
         return allDefs.release();
     }
 
-    //Template function which generates a summary from a dictionary
+    //Template function(s) which generates a summary from a dictionary
     //file.  The caller is responsible for deleting the returned map.
     //Function returns NULL if it runs out of memory.  Note that this
     //is a fairly expensive function, timewise, since it involves
@@ -145,7 +183,42 @@
     //a megabyte in size.  Template parameter T is a Mentor struct
     //(cs_Csdef_ et al).
     //
+
     template <class T>
+    CSystemNameDescriptionMap*
+    GenerateSystemNameDescriptionMap(
+        vector<T*> const* csMapDefs,
+        const char* (*CS_Tkey)(const T&),
+        const char * (*description)(const T&))
+    {
+        try
+        {
+            //Make a collection to return - we first read all entries from the dictionary file
+            //and use those to fill up the dictionary we're returning
+            auto_ptr<CSystemNameDescriptionMap> pmapSystemNameDescription(new CSystemNameDescriptionMap);
+            for(typename vector<T>::size_type i = 0; i < csMapDefs->size(); ++i)
+            {
+                T* def = csMapDefs->at(i);
+
+                const char* keyName = CS_Tkey(*def);
+                pmapSystemNameDescription->insert(
+                    CSystemNameDescriptionPair(
+                        CSystemName(keyName),
+                        CSystemDescription(description(*def))
+                    )
+                );
+            }
+
+            return pmapSystemNameDescription.release();
+        }
+        catch(std::bad_alloc&)
+        {
+        }
+
+        return NULL;
+    }
+
+    template <class T>
     CSystemNameDescriptionMap *
     GenerateSystemNameDescriptionMap(
         csFILE *pFile,
@@ -166,25 +239,11 @@
             //Make a collection to return - we first read all entries from the dictionary file
             //and use those to fill up the dictionary we're returning
             auto_ptr<CSystemNameDescriptionMap> pmapSystemNameDescription(new CSystemNameDescriptionMap);
-            
-            auto_ptr<vector<T> > allDictEntries(MentorDictionary::ReadDictionaryEntries(pFile, CS_Trd));
+            TContainerPtr<T, vector<T*> > allDictEntries(MentorDictionary::ReadDictionaryEntries(pFile, CS_Trd));
             if (NULL == allDictEntries.get())
                 return NULL;
 
-            for(typename vector<T>::size_type i = 0; i < allDictEntries->size(); i++)
-            {
-                T& def = allDictEntries->at(i);
-                
-                const char* keyName = CS_Tkey(def);
-                pmapSystemNameDescription->insert(
-                    CSystemNameDescriptionPair(
-                        CSystemName(keyName),
-                        CSystemDescription(description(def))
-                    )
-                );
-            }
-
-            return pmapSystemNameDescription.release();
+            return GenerateSystemNameDescriptionMap(allDictEntries.get(), CS_Tkey, description);
         }
         catch(std::bad_alloc&)
         {
@@ -193,6 +252,33 @@
         return NULL;
     }
 
+    template <class T>
+    CSystemNameDescriptionMap *
+    GenerateSystemNameDescriptionMap(
+        const char* (*CS_Tkey)(const T&),
+        const char * (*description)(const T&),
+        int (*CS_TrdAll)(T **[]))
+    {
+	typedef vector<T*> CsMapDefPtrVector;
+
+        TContainerPtr<T*, CsMapDefPtrVector > definitions;
+        definitions.reset(new vector<T*>);
+
+        T**  pAllDefs = NULL;
+        int readStatus = CS_TrdAll(&pAllDefs);
+        if (readStatus < 0)
+            return NULL;
+
+        for(int i = 0; i < readStatus; ++i)
+            definitions->push_back(pAllDefs[i]);
+
+        //free the pointer array only - not the items;
+        //these are now owned by [definitions]
+        CS_free(pAllDefs);
+
+        return GenerateSystemNameDescriptionMap(definitions.get(), CS_Tkey, description);
+    }
+
     //Reads all Mg definitions from the dictionary [targetDictionary] and returns them
     //in the std::map [definitions], where the code is mapped to the MgDisposable
     template <class T>
@@ -264,7 +350,7 @@
     template <class T /* The MgCS type [primaryDictionary] contains*/, class U /* The CsMap struct type*/, class V /* The dictionary type that will return items of type T*/>
     MgDisposableCollection* ReadAllDefinitions(
         /*IN, required*/ V* primaryDictionary, //the primary MgCS dictionary to read the items of type T from
-        /*IN, required*/ int (*CS_Trd)(csFILE*, U *, int *), //The file access method as retrieved from CsMap
+        /*IN, required*/ int (*CS_TrdAll)(U **pDefArray[]), //The CsMap method to read all entries
         /*IN, optional*/ void (V::*PostProcess)(U*), //A method that's being called with the CsMap definition struct just read from the file
         /*IN, required*/ T* (V::*GetMgItem)(const U*, const std::vector<std::map<STRING,Ptr<MgDisposable> >*>* const), //the method on the [primaryDictionary] to read the actual MgCS item from
         /*IN, optional*/ const std::vector<std::map<STRING,Ptr<MgDisposable> >*>* const secondaryDictionaryInfos, //infos that have been read from the dictionaries before; will be passed to [V::*GetMgItem]
@@ -275,28 +361,49 @@
             throw new MgNullArgumentException(L"MentorDictionary.ReadAllDefinitionsCascaded", __LINE__, __WFILE__, NULL, L"", NULL);
 
         //method pointer checks
-        if (NULL == GetMgItem || NULL == CS_Trd)
+        if (NULL == GetMgItem || NULL == CS_TrdAll)
             throw new MgNullArgumentException(L"MentorDictionary.ReadAllDefinitionsCascaded", __LINE__, __WFILE__, NULL, L"", NULL);
 
-        auto_ptr<vector<U> > allDefs(MentorDictionary::ReadDictionaryEntries<U>(primaryDictionary, CS_Trd));
-        if (NULL == allDefs.get()) //[ReadDictionaryEntries] will return NULL, if the dictionary entries couldn't be read
-            throw new MgInvalidArgumentException(L"MgCoordinateSystemDictionary.ReadAllCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
+        U** pDefArray = NULL;
+        const int readStatus = CS_TrdAll(&pDefArray);
+        if (readStatus < 0)
+        {
+            _ASSERT(NULL == pDefArray);
+            throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemDictionary.ReadAllCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
 
         const bool doPostProcess = (NULL != PostProcess);
         Ptr<MgDisposableCollection> filteredDefinitions = new MgDisposableCollection();
 
-        //go through all defs as we've read them from CsMap, do some post processing and finally
-        //retrieve the MgCs item we'll later return to the caller
-        for(typename vector<U>::size_type i = 0; i < allDefs->size(); i++)
-        {
-            U csMapDef = allDefs->at(i); //don't work on the reference
-            if (doPostProcess)
-                CALL_MEMBER_FN(primaryDictionary, PostProcess)(&csMapDef);
+        MG_TRY()
 
-            Ptr<T> mgItem = CALL_MEMBER_FN(primaryDictionary, GetMgItem)(&csMapDef, secondaryDictionaryInfos); //throws an exception, if the entry hasn't been found
-            filteredDefinitions->Add(mgItem);
-        }
+            //go through all defs as we've read them from CsMap, do some post processing and finally
+            //retrieve the MgCs item we'll later return to the caller
+            for(int i = 0; i < readStatus; ++i)
+            {
+                U* csMapDef = pDefArray[i];
+                if (doPostProcess)
+                    CALL_MEMBER_FN(primaryDictionary, PostProcess)(csMapDef);
 
+                Ptr<T> mgItem = CALL_MEMBER_FN(primaryDictionary, GetMgItem)(csMapDef, secondaryDictionaryInfos); //throws an exception, if the entry hasn't been found
+                CS_free(csMapDef);
+                pDefArray[i] = NULL;
+
+                filteredDefinitions->Add(mgItem);
+            }
+
+        MG_CATCH(L"MentorDictionary.ReadAllDefinitions")
+
+            if (NULL != mgException) //the array's elements have been cleaned up otherwise already
+            {
+                for(int i = 0; i < readStatus; ++i)
+                    CS_free(pDefArray[i]);
+            }
+
+            CS_free(pDefArray);
+
+        MG_THROW()
+
         //we might get the same reference back - what isn't a problem as we're using the Ptr<> here
         filteredDefinitions = MentorDictionary::FilterDefinitions<MgCoordinateSystem>(filteredDefinitions, filters);
         return filteredDefinitions.Detach();

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/MentorUtil.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/MentorUtil.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/MentorUtil.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -28,6 +28,7 @@
 struct cs_Eldef_;
 struct cs_Dtdef_;
 struct cs_Csdef_;
+struct cs_Ctdef_;
 struct cs_Datum_;
 struct cs_Csprm_;
 struct cs_Dtcprm_;

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/SmartCriticalClass.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/SmartCriticalClass.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/SmartCriticalClass.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -21,7 +21,7 @@
 class SmartCriticalClass
 {
 public:
-    SmartCriticalClass(bool bEnter);
+    SmartCriticalClass(bool bEnter = true);
     ~SmartCriticalClass();
 
     void Enter();

Modified: sandbox/adsk/2.4k/Common/CoordinateSystem/namestruct.h
===================================================================
--- sandbox/adsk/2.4k/Common/CoordinateSystem/namestruct.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/CoordinateSystem/namestruct.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -43,6 +43,7 @@
 #pragma once
 
 #include <list>
+#include <vector>
 #include <map>
 #include "cs_map.h" //for cs_KEYNM_DEF
 
@@ -111,21 +112,8 @@
 typedef std::map<CSystemName, CSystemDescription> CSystemNameDescriptionMap;
 typedef std::pair<CSystemName, CSystemDescription> CSystemNameDescriptionPair;
 
-//Max length of a category "name" (really, description).
-//The value chosen here is admittedly arbitrary.  This is also
-//a new constraint, as ADE.PRO allowed arbitrarily long category
-//names.  However I scanned the ADE.PRO which shipped with Map 3,
-//and the longest description therein was only 29 characters, so
-//this size should be more than ample.
-//
-//Note:  Be careful about changing this number!  It determines the
-//format of the category dictionary file, so changing this number
-//will render the public API unable to access any category dictionaries
-//which were created using a different number.
-const int knMaxCategoryNameLen = 128;
-
 typedef TNameStruct CCategoryName;
 typedef std::map<CCategoryName, long> CCategoryNameIndexMap;
-typedef std::list<CCategoryName> CCategoryNameList;
+typedef std::vector<CCategoryName> CCategoryNameList;
 
 #endif //MG_NAMESTRUCT_H

Modified: sandbox/adsk/2.4k/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h
===================================================================
--- sandbox/adsk/2.4k/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -48,6 +48,39 @@
     virtual void SetDictionaryDir(CREFSTRING sDirPath)=0;
     virtual STRING GetDictionaryDir()=0;
 
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the default directory path where user defined coordinate system
+    /// definitions can be found or can be written into, respectively.
+    /// If set, this method returns the value of the MENTOR_USER_DICTIONARY_PATH
+    /// environment variable. Returns 'CSIDL_LOCAL_APPDATA\Autodesk\User Geospatial Coordinate Systems'
+    /// on Windows systems or an empty string on non-Windows systems, otherwise.
+    ///
+    /// \remarks
+    /// The directory returned by this function is not guaranteed to exist. If it does, however,
+    /// and is writable, too, the value returned by this function will be used to initialize this catalog of definitions
+    /// on the first initialization.
+    ///
+    virtual STRING GetDefaultUserDictionaryDir()=0;
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Sets the actual directory where user defined coordinate system
+    /// definitions can be found or can be written into. The directory set through this method must exist
+    /// and writeable. If set to an empty string, the catalog's 'user defined coordinate system' directory
+    /// will be unset and any updates will again happen only inside the directory
+    /// as returned by GetDictionaryDir().
+    ///
+    virtual void SetUserDictionaryDir(CREFSTRING sDirPath)=0;
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the current directory where user defined coordinate system
+    /// definitions is obtained from or is written into. Returns an empty string
+    /// if no such directory is currently configured for this catalog.
+    ///
+    virtual STRING GetUserDictionaryDir()=0;
+
     virtual void SetProtectionMode(INT16 nMode)=0;
     virtual INT16 GetProtectionMode()=0;
 

Modified: sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.cpp
===================================================================
--- sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -134,6 +134,8 @@
 const STRING MgConfigProperties::DefaultGeneralPropertyFdoPath                              = L"";
 const STRING MgConfigProperties::GeneralPropertyMentorDictionaryPath                        = L"MentorDictionaryPath";
 const STRING MgConfigProperties::DefaultGeneralPropertyMentorDictionaryPath                 = L"";
+const STRING MgConfigProperties::GeneralPropertyMentorUserDictionaryPath                    = L"MentorUserDictionaryPath";
+const STRING MgConfigProperties::DefaultGeneralPropertyMentorUserDictionaryPath             = L"";
 const STRING MgConfigProperties::GeneralPropertyLicenseServerPath                           = L"LicenseServerPath";
 const STRING MgConfigProperties::DefaultGeneralPropertyLicenseServerPath                    = L"";
 const STRING MgConfigProperties::GeneralPropertyLinuxMemDebug                               = L"LinuxMemDebug";
@@ -565,6 +567,7 @@
     { MgConfigProperties::GeneralPropertyDisplayName                                , MgPropertyType::String    , MG_CONFIG_MIN_OPTIONAL_STRING_LENGTH  , MG_CONFIG_MAX_OPTIONAL_STRING_LENGTH  , MG_CONFIG_FILE_NAME_RESERVED_CHARACTERS   },
     { MgConfigProperties::GeneralPropertyFdoPath                                    , MgPropertyType::String    , MG_CONFIG_MIN_PATH_LENGTH             , MG_CONFIG_MAX_PATH_LENGTH             , MG_CONFIG_PATH_RESERVED_CHARACTERS        },
     { MgConfigProperties::GeneralPropertyMentorDictionaryPath                       , MgPropertyType::String    , MG_CONFIG_MIN_PATH_LENGTH             , MG_CONFIG_MAX_PATH_LENGTH             , MG_CONFIG_PATH_RESERVED_CHARACTERS        },
+    { MgConfigProperties::GeneralPropertyMentorUserDictionaryPath                   , MgPropertyType::String    , MG_CONFIG_MIN_PATH_LENGTH             , MG_CONFIG_MAX_PATH_LENGTH             , MG_CONFIG_PATH_RESERVED_CHARACTERS        },
     { MgConfigProperties::GeneralPropertyLicenseServerPath                          , MgPropertyType::String    , MG_CONFIG_MIN_OPTIONAL_STRING_LENGTH  , MG_CONFIG_MAX_OPTIONAL_STRING_LENGTH  , L""                                       },
     { MgConfigProperties::GeneralPropertyLinuxMemDebug                              , MgPropertyType::Boolean   , 0                                     , 1                                     , L""                                       },
     { MgConfigProperties::GeneralPropertyLogsDelimiter                              , MgPropertyType::String    , 1                                     , 128                                   , L""                                       },

Modified: sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.h
===================================================================
--- sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Common/MapGuideCommon/System/ConfigProperties.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -74,6 +74,10 @@
     static const STRING GeneralPropertyMentorDictionaryPath;            /// value("MentorDictionaryPath")
     static const STRING DefaultGeneralPropertyMentorDictionaryPath;     /// value("")
 
+    /// Mentor User Dictionary Path
+    static const STRING GeneralPropertyMentorUserDictionaryPath;        /// value("MentorUserDictionaryPath")
+    static const STRING DefaultGeneralPropertyMentorUserDictionaryPath; /// value("")
+
     /// Path of the license server
     static const STRING GeneralPropertyLicenseServerPath;               /// value("LicenseServerPath")
     static const STRING DefaultGeneralPropertyLicenseServerPath;        /// value("");

Modified: sandbox/adsk/2.4k/Server/src/Core/Server.cpp
===================================================================
--- sandbox/adsk/2.4k/Server/src/Core/Server.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Server/src/Core/Server.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -721,6 +721,7 @@
     ACE_UNUSED_ARG(args);
     int nResult = 0;
     STRING mentorDictPath;
+    STRING mentorUserDictPath;
 
     MG_TRY()
     {
@@ -882,14 +883,49 @@
             {
                 // Check if path ends with a '/' if not, add one if needed
                 MgFileUtil::AppendSlashToEndOfPath(mentorDictPath);
-                csCatalog->SetDictionaryDir(mentorDictPath);
+                MG_TRY()
+                    csCatalog->SetDictionaryDir(mentorDictPath);
+                MG_CATCH_AND_RELEASE()
+                if (NULL != mgException)
+                {
+                    ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) MgServer::open() - The MentorDictionaryPath setting is invalid. The coordinate system engine could not be initialized.\n")));
+                }
             }
             else
             {
                 mentorDictPath = L"";
-                ACE_DEBUG((LM_INFO, ACE_TEXT("(%t) Warning - No configured dictionary path found. Defaulting to MENTOR_DICTIONARY_PATH environment variable.\n")));
+                ACE_DEBUG((LM_INFO, ACE_TEXT("(%t) MgServer::open() - No configured dictionary path found. Defaulting to [%W].\n"), csCatalog->GetDictionaryDir().c_str()));
             }
 
+            // Update the user dictionary path with our configured value
+            pConfiguration->GetStringValue(MgConfigProperties::GeneralPropertiesSection, MgConfigProperties::GeneralPropertyMentorUserDictionaryPath, mentorUserDictPath, MgConfigProperties::DefaultGeneralPropertyMentorUserDictionaryPath);
+            if (!mentorUserDictPath.empty())
+            {
+                // Check if path ends with a '/' if not, add one if needed
+                MgFileUtil::AppendSlashToEndOfPath(mentorUserDictPath);
+                MG_TRY()
+                    csCatalog->SetUserDictionaryDir(mentorUserDictPath);
+                MG_CATCH_AND_RELEASE()
+                if (NULL != mgException)
+                {
+                    //not being able to initialize the user dictionary path doesn't result in the server not starting up
+                    ACE_DEBUG((LM_WARNING, ACE_TEXT("(%t) MgServer::open() - The MentorUserDictionaryPath setting is invalid. The user dictionary path setting will not be applied.\n")));
+                }
+            }
+            else
+            {
+                mentorUserDictPath = L"";
+                STRING defaultUserPath = csCatalog->GetUserDictionaryDir();
+                if (defaultUserPath.empty())
+                {
+                    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) MgServer::open() - No configured user dictionary path found.\n")));
+                }
+                else
+                {
+                    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) MgServer::open() - No configured user dictionary path found. Defaulting to directory [%W].\n"), defaultUserPath.c_str()));
+                }
+            }
+
             // Did we successfully initialize the coordinate system library?
             LibraryStatus status = csCatalog->GetLibraryStatus();
             if(lsInitialized != status)

Modified: sandbox/adsk/2.4k/Server/src/Core/serverconfig.ini
===================================================================
--- sandbox/adsk/2.4k/Server/src/Core/serverconfig.ini	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Server/src/Core/serverconfig.ini	2012-11-04 20:24:23 UTC (rev 7187)
@@ -70,6 +70,7 @@
 #                                       0 < Value <= 2000000
 # MaxLogFileSizeEnabled            0 = max size disabled, 1 = max size enabled
 # MentorDictionaryPath             The path where the CS-Map Coordinate System Dictionaries are installed
+# MentorUserDictionaryPath         The path where user defined CS-Map Coordinate System Dictionaries are stored
 # PreCacheMaps                     The list of maps to precache at server startup.
 #                                       Value = Map resource name(s) separated by ","
 #                                       Example: Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition
@@ -97,6 +98,7 @@
 MaxLogFileSize                     = 1024
 MaxLogFileSizeEnabled              = 0
 MentorDictionaryPath               = ../../../Oem/CsMap/Dictionaries/
+MentorUserDictionaryPath           =
 PreCacheMaps                       =
 Renderer                           = AGG
 ResourcesPath                      = Resources/

Modified: sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.cpp
===================================================================
--- sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.cpp	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.cpp	2012-11-04 20:24:23 UTC (rev 7187)
@@ -100,6 +100,517 @@
 ///----------------------------------------------------------------------------
 /// Test Case Description:
 ///
+/// The following test cases try reading all types of definitions from the current catalog
+///----------------------------------------------------------------------------
+
+//our helper method to read all definitions from all dictionaries
+#define CALL_MEMBER_FN(object,ptrToMember)  ((object)->*(ptrToMember))
+template<
+    class MgCsType, class MgCsDictionaryType,
+    STRING (MgCsType::*GetCode)(),
+    MgCsDictionaryType* (MgCoordinateSystemCatalog::*MgGetDictionaryFunc)()>
+void TestReadAllDefinitions(wchar_t const* pzswDefType)
+{
+    ACE_DEBUG((LM_INFO, ACE_TEXT("\nReading all %W, ... "), pzswDefType));
+
+    MgCoordinateSystemFactory csFactory;
+    Ptr<MgCoordinateSystemCatalog> pMgCsCatalog = csFactory.GetCatalog();
+
+    Ptr<MgCsDictionaryType> pCsDictionary = CALL_MEMBER_FN(pMgCsCatalog, MgGetDictionaryFunc)();
+    Ptr<MgCoordinateSystemEnum> pCsEnum = pCsDictionary->GetEnum();
+    UINT32 size = pCsDictionary->GetSize();
+
+    CPPUNIT_ASSERT(size > 0); //by default, we're assuming to have 'something' in each dictionary
+
+    std::vector<STRING> allCodes;
+
+    bool firstFullSetDone = false;
+    Ptr<MgDisposableCollection> pNextCsDefinitions;
+    do
+    {
+        pNextCsDefinitions = pCsEnum->Next(size);
+        CPPUNIT_ASSERT(pNextCsDefinitions);
+
+        const INT32 defCount = pNextCsDefinitions->GetCount();
+        if (firstFullSetDone)
+        {
+            CPPUNIT_ASSERT(0 == defCount);
+        }
+        else
+        {
+            firstFullSetDone = true;
+            ACE_DEBUG((LM_INFO, ACE_TEXT("found %d definitions ...\n"), defCount));
+        }
+
+        for(INT32 i = 0; i < defCount; ++i)
+        {
+            Ptr<MgDisposable> pCsDisposable = pNextCsDefinitions->GetItem(i);
+
+            MgCsType* pDefinition = dynamic_cast<MgCsType*>(pCsDisposable.p);
+            CPPUNIT_ASSERT(pDefinition); //the collection must only contain objects of the required type
+
+            STRING code = CALL_MEMBER_FN(pDefinition, GetCode)();
+            CPPUNIT_ASSERT(!code.empty());
+            allCodes.push_back(code);
+        }
+
+    } while (pNextCsDefinitions->GetCount() > 0);
+
+    CPPUNIT_ASSERT(allCodes.size() == pCsDictionary->GetSize());
+
+    for(size_t i = 0; i < allCodes.size(); ++i)
+    {
+        STRING const& code = allCodes[i];
+        Ptr<MgDisposable> pDictionaryDef = pCsDictionary->Get(code);
+        MgCsType *pConcreteDef = dynamic_cast<MgCsType*>(pDictionaryDef.p);
+        CPPUNIT_ASSERT(pConcreteDef);
+
+        STRING codeFromDef = CALL_MEMBER_FN(pConcreteDef, GetCode)();
+        CPPUNIT_ASSERT(0 == _wcsicmp(codeFromDef.c_str(), code.c_str()));
+    }
+}
+
+/// (1) Read all Coordinate systems
+void TestCoordinateSystem::TestCase_ReadAllCoordinateSystems()
+{
+    TestReadAllDefinitions<MgCoordinateSystem, MgCoordinateSystemDictionary,
+        &MgCoordinateSystem::GetCsCode,
+        &MgCoordinateSystemCatalog::GetCoordinateSystemDictionary>(L"Coordinate Systems");
+}
+
+/// (2) Read all datums
+void TestCoordinateSystem::TestCase_ReadAllDatums()
+{
+    TestReadAllDefinitions<MgCoordinateSystemDatum, MgCoordinateSystemDatumDictionary,
+        &MgCoordinateSystemDatum::GetDtCode,
+        &MgCoordinateSystemCatalog::GetDatumDictionary>(L"Datums");
+}
+
+/// (3) Read all ellipsoids
+void TestCoordinateSystem::TestCase_ReadAllEllipsoids()
+{
+    TestReadAllDefinitions<MgCoordinateSystemEllipsoid, MgCoordinateSystemEllipsoidDictionary,
+        &MgCoordinateSystemEllipsoid::GetElCode,
+        &MgCoordinateSystemCatalog::GetEllipsoidDictionary>(L"Ellipsoids");
+}
+
+/// (4) Read all categories
+void TestCoordinateSystem::TestCase_ReadAllCategories()
+{
+    TestReadAllDefinitions<MgCoordinateSystemCategory, MgCoordinateSystemCategoryDictionary,
+        &MgCoordinateSystemCategory::GetName,
+        &MgCoordinateSystemCatalog::GetCategoryDictionary>(L"Categories");
+}
+
+/// (5) Read all geodetic transformations
+void TestCoordinateSystem::TestCase_ReadAllGeodeticTransformations()
+{
+    TestReadAllDefinitions<MgCoordinateSystemGeodeticTransformDef, MgCoordinateSystemGeodeticTransformDefDictionary,
+        &MgCoordinateSystemGeodeticTransformDef::GetTransformName,
+        &MgCoordinateSystemCatalog::GetGeodeticTransformDefDictionary>(L"Geodetic Transformations");
+}
+
+/// (6) Read all geodetic paths
+void TestCoordinateSystem::TestCase_ReadAllGeodeticPaths()
+{
+    TestReadAllDefinitions<MgCoordinateSystemGeodeticPath, MgCoordinateSystemGeodeticPathDictionary,
+        &MgCoordinateSystemGeodeticPath::GetPathName,
+        &MgCoordinateSystemCatalog::GetGeodeticPathDictionary>(L"Geodetic Paths");
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// The following test cases try updating all types of definitions in the current catalog
+///----------------------------------------------------------------------------
+///
+
+//our helper functions
+template<class MgCsType>
+void SetDefinitionUnprotected(MgCsType* pDefinition)
+{
+    pDefinition->SetProtectMode(false);
+}
+
+template<class MgCsType>
+MgCsType* CloneDefinition(MgCsType* pDefinition)
+{
+    return pDefinition->CreateClone();
+}
+
+template<
+    bool TAutoRemove,
+    bool TWithUserDefDir,
+    class MgCsType, class MgCsDictionaryType,
+    STRING (MgCsType::*GetCode)(),
+    void (MgCsType::*SetCode)(CREFSTRING),
+    MgCsDictionaryType* (MgCoordinateSystemCatalog::*MgGetDictionaryFunc)()>
+STRING TestUpdateDefinition(wchar_t const* pzswDefType,
+    void (*UnprotecDefFunc)(MgCsType*) = SetDefinitionUnprotected<MgCsType>,
+    MgCsType* (*CloneDefFunc)(MgCsType*) = NULL)
+{
+    ACE_DEBUG((LM_INFO, ACE_TEXT("\nUpdating a %W definition ... "), pzswDefType));
+
+    MgCoordinateSystemFactory csFactory;
+    Ptr<MgCoordinateSystemCatalog> pMgCsCatalog = csFactory.GetCatalog();
+
+    if (TWithUserDefDir)
+    {
+        TestCoordinateSystem::SetDefaultUserDictionaryDir();
+    }
+    else
+    {
+        if (!pMgCsCatalog->GetUserDictionaryDir().empty())
+            pMgCsCatalog->SetUserDictionaryDir(L"");
+    }
+
+    Ptr<MgCsDictionaryType> pCsDictionary = CALL_MEMBER_FN(pMgCsCatalog, MgGetDictionaryFunc)();
+    Ptr<MgCoordinateSystemEnum> pCsEnum = pCsDictionary->GetEnum();
+    UINT32 size = pCsDictionary->GetSize();
+
+    CPPUNIT_ASSERT(size > 0); //by default, we're assuming to have 'something' in each dictionary
+
+    Ptr<MgDisposableCollection> pNextCsDefinitions;
+    pNextCsDefinitions = pCsEnum->Next(1);
+
+    INT32 definitionCount = pNextCsDefinitions->GetCount();
+    CPPUNIT_ASSERT(1 == definitionCount);
+
+    Ptr<MgDisposable> pMgDefinition = pNextCsDefinitions->GetItem(0);
+    CPPUNIT_ASSERT(pMgDefinition);
+
+    MgCsType* pTypedDef = dynamic_cast<MgCsType*>(pMgDefinition.p);
+    CPPUNIT_ASSERT(NULL != pTypedDef);
+
+    STRING code = CALL_MEMBER_FN(pTypedDef, GetCode)();
+    CPPUNIT_ASSERT(!code.empty());
+
+    ACE_DEBUG((LM_INFO, ACE_TEXT("trying with %W ... "), code.c_str()));
+
+    //get us a definition we can modify
+    if (NULL != UnprotecDefFunc)
+    {
+        UnprotecDefFunc(pTypedDef);
+    }
+    else if (NULL != CloneDefFunc)
+    {
+        pMgDefinition = CloneDefFunc(pTypedDef);
+        pTypedDef = dynamic_cast<MgCsType*>(pMgDefinition.p);
+        CPPUNIT_ASSERT(NULL != pTypedDef);
+    }
+
+    STRING newCode = (code + L"_MOD");
+    CALL_MEMBER_FN(pTypedDef, SetCode)(newCode);
+
+    STRING csdFile = pCsDictionary->GetPath();
+    //backup the current CSD file and automatically restore it after we are done; or delete the newly created CSD file
+    //make sure, we keep the current file
+    TestCoordinateSystem::FileAutoBackup csdFileBackup(csdFile, L".UNIT_TEST_SAVE", true);
+
+    pCsDictionary->Add(pTypedDef);
+
+    Ptr<MgDisposable> pAddedDefinition = pCsDictionary->Get(newCode);
+    CPPUNIT_ASSERT(pAddedDefinition);
+
+    ACE_DEBUG((LM_INFO, ACE_TEXT("OK")));
+
+    CPPUNIT_ASSERT( pCsDictionary->Has(newCode) );
+
+    if (TAutoRemove)
+    {
+        ACE_DEBUG((LM_INFO, ACE_TEXT("... Remove it again... ")));
+        pCsDictionary->Remove(newCode);
+        CPPUNIT_ASSERT( !pCsDictionary->Has(newCode) );
+
+        ACE_DEBUG((LM_INFO, ACE_TEXT("OK")));
+    }
+
+    return newCode;
+}
+
+/// (1) Update a coordinate system
+void TestCoordinateSystem::TestCase_UpdateCoordinateSystems()
+{
+    TestUpdateDefinition<
+        true, /* compile as 'auto-remove function' */
+        false, /* compile as 'no-user-def-dir'*/
+        MgCoordinateSystem, MgCoordinateSystemDictionary,
+        &MgCoordinateSystem::GetCsCode,
+        &MgCoordinateSystem::SetCsCode,
+        &MgCoordinateSystemCatalog::GetCoordinateSystemDictionary>(L"Coordinate System");
+}
+
+/// (2) Update a datum
+void TestCoordinateSystem::TestCase_UpdateDatums()
+{
+    TestUpdateDefinition<
+        true, /* compile as 'auto-remove function' */
+        false, /* compile as 'no-user-def-dir'*/
+        MgCoordinateSystemDatum, MgCoordinateSystemDatumDictionary,
+        &MgCoordinateSystemDatum::GetDtCode,
+        &MgCoordinateSystemDatum::SetDtCode,
+        &MgCoordinateSystemCatalog::GetDatumDictionary>(L"Datum");
+}
+
+/// (3) Update an ellipsoid
+void TestCoordinateSystem::TestCase_UpdateEllipsoids()
+{
+    TestUpdateDefinition<
+        true, /* compile as 'auto-remove function' */
+        false, /* compile as 'no-user-def-dir'*/
+        MgCoordinateSystemEllipsoid, MgCoordinateSystemEllipsoidDictionary,
+        &MgCoordinateSystemEllipsoid::GetElCode,
+        &MgCoordinateSystemEllipsoid::SetElCode,
+        &MgCoordinateSystemCatalog::GetEllipsoidDictionary>(L"Ellipsoid");
+}
+
+/// (4) Update a category
+void TestCoordinateSystem::TestCase_UpdateCategories()
+{
+    TestUpdateDefinition<
+        true, /* compile as 'auto-remove function' */
+        false, /* compile as 'no-user-def-dir'*/
+        MgCoordinateSystemCategory, MgCoordinateSystemCategoryDictionary,
+        &MgCoordinateSystemCategory::GetName,
+        &MgCoordinateSystemCategory::SetName,
+        &MgCoordinateSystemCatalog::GetCategoryDictionary>(L"Category", NULL, NULL);
+}
+
+/// (5) Update a geodetic transformation
+void TestCoordinateSystem::TestCase_UpdateGeodeticTransformations()
+{
+    TestUpdateDefinition<
+        true, /* compile as 'auto-remove function' */
+        false, /* compile as 'no-user-def-dir'*/
+        MgCoordinateSystemGeodeticTransformDef, MgCoordinateSystemGeodeticTransformDefDictionary,
+        &MgCoordinateSystemGeodeticTransformDef::GetTransformName,
+        &MgCoordinateSystemGeodeticTransformDef::SetTransformName,
+        &MgCoordinateSystemCatalog::GetGeodeticTransformDefDictionary>(L"Geodetic Transformation", NULL, CloneDefinition);
+}
+
+/// (5) Update a geodetic path
+void TestCoordinateSystem::TestCase_UpdateGeodeticPaths()
+{
+    TestUpdateDefinition<
+        true, /* compile as 'auto-remove function' */
+        false, /* compile as 'no-user-def-dir'*/
+        MgCoordinateSystemGeodeticPath, MgCoordinateSystemGeodeticPathDictionary,
+        &MgCoordinateSystemGeodeticPath::GetPathName,
+        &MgCoordinateSystemGeodeticPath::SetPathName,
+        &MgCoordinateSystemCatalog::GetGeodeticPathDictionary>(L"Geodetic Path", NULL, CloneDefinition);
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// Tries setting a user dictionary path where to store CS user information into
+///----------------------------------------------------------------------------
+void TestCoordinateSystem::TestCase_InitializeValidUserDictionaryDir()
+{
+    MgCoordinateSystemFactory mgCsFactory;
+    Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+
+    STRING userDictionaryDir = pCsCatalog->GetDefaultUserDictionaryDir();
+    if (userDictionaryDir.empty())
+        return;
+
+    //create the directory to make sure, [SetUserDictionaryDir]
+    //can succeed
+    MgFileUtil::CreateDirectory(userDictionaryDir);
+
+    pCsCatalog->SetUserDictionaryDir(userDictionaryDir);
+    STRING setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+    CPPUNIT_ASSERT(setUserDictionaryDir == userDictionaryDir);
+
+    pCsCatalog->SetUserDictionaryDir(L"");
+    setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+    CPPUNIT_ASSERT(setUserDictionaryDir.empty());
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// Tries setting an invalid user dictionary path where to store CS user information into
+///----------------------------------------------------------------------------
+void TestCoordinateSystem::TestCase_InitializeInvalidUserDictionaryDir()
+{
+    MgCoordinateSystemFactory mgCsFactory;
+    Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+
+    STRING userDictionaryDir = pCsCatalog->GetDefaultUserDictionaryDir();
+    if (userDictionaryDir.empty())
+        return;
+
+    pCsCatalog->SetUserDictionaryDir(userDictionaryDir);
+    STRING setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+
+    MG_TRY()
+
+#ifdef _WIN32
+        pCsCatalog->SetUserDictionaryDir(L"X:\\I am a hopefully not existing path - if I do, changeme");
+#else
+        pCsCatalog->SetUserDictionaryDir(L"/I am a hopefully not existing path - if I do, changeme");
+#endif
+
+    MG_CATCH_AND_RELEASE()
+
+    CPPUNIT_ASSERT(NULL != mgException); //this *must* result in an exception
+
+    STRING currentUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+    CPPUNIT_ASSERT(setUserDictionaryDir == currentUserDictionaryDir); //the current user dictionary path must not have changed
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// The following test cases try updating all types of definitions in the current catalog
+/// with a user dictionary path being set
+///----------------------------------------------------------------------------
+///
+
+bool TestCoordinateSystem::SetDefaultUserDictionaryDir()
+{
+    MgCoordinateSystemFactory mgCsFactory;
+    Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+
+    STRING defUserDictionaryDir = pCsCatalog->GetDefaultUserDictionaryDir();
+    if (defUserDictionaryDir.empty())
+    {
+        defUserDictionaryDir = MgFileUtil::GetTempPath();
+        if (defUserDictionaryDir.empty())
+            return false;
+
+        defUserDictionaryDir += L"User Geospatial Coordinate Systems/";
+    }
+
+     //create the directory to make sure, [SetUserDictionaryDir]
+    //can succeed
+    MgFileUtil::CreateDirectory(defUserDictionaryDir);
+    pCsCatalog->SetUserDictionaryDir(defUserDictionaryDir);
+
+    return true;
+}
+
+template<
+    class MgCsType, class MgCsDictionaryType,
+    STRING (MgCsType::*GetCode)(),
+    void (MgCsType::*SetCode)(CREFSTRING),
+    MgCsDictionaryType* (MgCoordinateSystemCatalog::*MgGetDictionaryFunc)()>
+void TestUpdateUserDefinition(wchar_t const* pzswDefType,
+    void (*UnprotecDefFunc)(MgCsType*) = SetDefinitionUnprotected<MgCsType>,
+    MgCsType* (*CloneDefFunc)(MgCsType*) = NULL)
+{
+    ACE_DEBUG((LM_INFO, ACE_TEXT("\nTrying to set the default user dictionary path ...\n")));
+
+    bool userDirSet = TestCoordinateSystem::SetDefaultUserDictionaryDir();
+    if (!userDirSet)
+    {
+        ACE_DEBUG((LM_WARNING, ACE_TEXT("\nCould not set the default user dictionary path. Current test will be skipped\n")));
+        return;
+    }
+
+    MgCoordinateSystemFactory mgCsFactory;
+    Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+    Ptr<MgCsDictionaryType> pCsDictionary = CALL_MEMBER_FN(pCsCatalog, MgGetDictionaryFunc)();
+
+    const STRING& csCsdFilename = pCsDictionary->GetFileName();
+
+    STRING csCsdFile = pCsDictionary->GetPath();
+    CPPUNIT_ASSERT(!csCsdFile.empty());
+    CPPUNIT_ASSERT(MgFileUtil::IsFile(csCsdFile));
+
+    const INT64 csdFileSize = MgFileUtil::GetFileSize(csCsdFile);
+
+    STRING userDir = pCsCatalog->GetUserDictionaryDir();
+    STRING csCsdUserFile = userDir + csCsdFilename;
+
+    STRING addedCode;
+    {
+        //backup the current user CSD file and automatically restore it after we are done; or delete the newly created CSD file
+        TestCoordinateSystem::FileAutoBackup csdFileBackup(csCsdUserFile, L".UNIT_TEST_SAVE");
+
+        addedCode = TestUpdateDefinition<
+            false /* compile as 'no-auto-remove' */,
+            true /* compile as 'with-user-def-dir' */,
+            MgCsType, MgCsDictionaryType,
+            GetCode,
+            SetCode,
+            MgGetDictionaryFunc>(pzswDefType, UnprotecDefFunc, CloneDefFunc);
+
+        const INT64 updateCsdFileSize = MgFileUtil::GetFileSize(csCsdFile);
+        CPPUNIT_ASSERT(updateCsdFileSize == csdFileSize);
+
+        //the user CSD file now must exist
+        struct _stat fileStatus;
+        bool fileExists = MgFileUtil::GetFileStatus(csCsdUserFile, fileStatus);
+        CPPUNIT_ASSERT(fileExists && fileStatus.st_size);
+
+        CPPUNIT_ASSERT(!addedCode.empty());
+        CPPUNIT_ASSERT(pCsDictionary->Has(addedCode));
+    }
+
+    //now, that the user file had been deleted, our newly added definition must have been gone, too
+    pCsDictionary->SetFileName(pCsDictionary->GetFileName()); //force the Mg dictionary to update is cache
+    CPPUNIT_ASSERT(!pCsDictionary->Has(addedCode));
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserCoordinateSystems()
+{
+    TestUpdateUserDefinition<
+        MgCoordinateSystem, MgCoordinateSystemDictionary,
+        &MgCoordinateSystem::GetCsCode,
+        &MgCoordinateSystem::SetCsCode,
+        &MgCoordinateSystemCatalog::GetCoordinateSystemDictionary>(L"Coordinate System");
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserDatums()
+{
+    TestUpdateUserDefinition<
+        MgCoordinateSystemDatum, MgCoordinateSystemDatumDictionary,
+        &MgCoordinateSystemDatum::GetDtCode,
+        &MgCoordinateSystemDatum::SetDtCode,
+        &MgCoordinateSystemCatalog::GetDatumDictionary>(L"Datum");
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserEllipsoids()
+{
+    TestUpdateUserDefinition<
+        MgCoordinateSystemEllipsoid, MgCoordinateSystemEllipsoidDictionary,
+        &MgCoordinateSystemEllipsoid::GetElCode,
+        &MgCoordinateSystemEllipsoid::SetElCode,
+        &MgCoordinateSystemCatalog::GetEllipsoidDictionary>(L"Ellipsoid");
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserCategories()
+{
+    TestUpdateUserDefinition<
+        MgCoordinateSystemCategory, MgCoordinateSystemCategoryDictionary,
+        &MgCoordinateSystemCategory::GetName,
+        &MgCoordinateSystemCategory::SetName,
+        &MgCoordinateSystemCatalog::GetCategoryDictionary>(L"Category", NULL, NULL);
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserGeodeticTransformations()
+{
+    TestUpdateUserDefinition<
+        MgCoordinateSystemGeodeticTransformDef, MgCoordinateSystemGeodeticTransformDefDictionary,
+        &MgCoordinateSystemGeodeticTransformDef::GetTransformName,
+        &MgCoordinateSystemGeodeticTransformDef::SetTransformName,
+        &MgCoordinateSystemCatalog::GetGeodeticTransformDefDictionary>(L"Geodetic Transformation", NULL, CloneDefinition);
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserGeodeticPaths()
+{
+    TestUpdateUserDefinition<
+        MgCoordinateSystemGeodeticPath, MgCoordinateSystemGeodeticPathDictionary,
+        &MgCoordinateSystemGeodeticPath::GetPathName,
+        &MgCoordinateSystemGeodeticPath::SetPathName,
+        &MgCoordinateSystemCatalog::GetGeodeticPathDictionary>(L"Geodetic Path", NULL, CloneDefinition);
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
 /// This test case loads OGC WKT coordinate systems from an external file and
 /// tries to validate them.
 ///----------------------------------------------------------------------------

Modified: sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.h
===================================================================
--- sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.h	2012-11-02 19:51:19 UTC (rev 7186)
+++ sandbox/adsk/2.4k/Server/src/UnitTesting/TestCoordinateSystem.h	2012-11-04 20:24:23 UTC (rev 7187)
@@ -25,6 +25,30 @@
     CPPUNIT_TEST_SUITE(TestCoordinateSystem);
     CPPUNIT_TEST(TestStart); // This must be the very first unit test
 
+    CPPUNIT_TEST(TestCase_ReadAllCoordinateSystems);
+    CPPUNIT_TEST(TestCase_ReadAllDatums);
+    CPPUNIT_TEST(TestCase_ReadAllEllipsoids);
+    CPPUNIT_TEST(TestCase_ReadAllCategories);
+    CPPUNIT_TEST(TestCase_ReadAllGeodeticTransformations);
+    CPPUNIT_TEST(TestCase_ReadAllGeodeticPaths);
+
+    CPPUNIT_TEST(TestCase_UpdateCoordinateSystems);
+    CPPUNIT_TEST(TestCase_UpdateDatums);
+    CPPUNIT_TEST(TestCase_UpdateEllipsoids);
+    CPPUNIT_TEST(TestCase_UpdateCategories);
+    CPPUNIT_TEST(TestCase_UpdateGeodeticTransformations);
+    CPPUNIT_TEST(TestCase_UpdateGeodeticPaths);
+
+    CPPUNIT_TEST(TestCase_InitializeInvalidUserDictionaryDir);
+    CPPUNIT_TEST(TestCase_InitializeValidUserDictionaryDir);
+
+    CPPUNIT_TEST(TestCase_UpdateUserCoordinateSystems);
+    CPPUNIT_TEST(TestCase_UpdateUserDatums);
+    CPPUNIT_TEST(TestCase_UpdateUserEllipsoids);
+    CPPUNIT_TEST(TestCase_UpdateUserCategories);
+    CPPUNIT_TEST(TestCase_UpdateUserGeodeticTransformations);
+    CPPUNIT_TEST(TestCase_UpdateUserGeodeticPaths);
+
     CPPUNIT_TEST(TestCase_CheckCoordinateSystems);
     CPPUNIT_TEST(TestCase_CreateValidCoordinateSystem);
     CPPUNIT_TEST(TestCase_CreateInvalidCoordinateSystem);
@@ -235,6 +259,31 @@
     void TestStart();
     void TestEnd();
 
+    //check sanity of the dictionaries
+    void TestCase_ReadAllCoordinateSystems();
+    void TestCase_ReadAllDatums();
+    void TestCase_ReadAllEllipsoids();
+    void TestCase_ReadAllCategories();
+    void TestCase_ReadAllGeodeticTransformations();
+    void TestCase_ReadAllGeodeticPaths();
+
+    void TestCase_UpdateCoordinateSystems();
+    void TestCase_UpdateDatums();
+    void TestCase_UpdateEllipsoids();
+    void TestCase_UpdateCategories();
+    void TestCase_UpdateGeodeticTransformations();
+    void TestCase_UpdateGeodeticPaths();
+
+    void TestCase_InitializeInvalidUserDictionaryDir();
+    void TestCase_InitializeValidUserDictionaryDir();
+
+    void TestCase_UpdateUserCoordinateSystems();
+    void TestCase_UpdateUserDatums();
+    void TestCase_UpdateUserEllipsoids();
+    void TestCase_UpdateUserCategories();
+    void TestCase_UpdateUserGeodeticTransformations();
+    void TestCase_UpdateUserGeodeticPaths();
+
     void TestCase_CheckCoordinateSystems();
     void TestCase_CreateValidCoordinateSystem();
     void TestCase_CreateInvalidCoordinateSystem();
@@ -438,6 +487,60 @@
     // Performance
     void TestCase_Benchmark_Transformation();
 
+    static bool SetDefaultUserDictionaryDir();
+
+    class FileAutoBackup
+    {
+    private:
+
+        STRING m_sFilename;
+        STRING m_sRotateSuffix;
+        STRING m_sBackupFilename;
+        bool m_bRotated;
+        bool m_bKeepFile;
+
+    public:
+        FileAutoBackup(const CREFSTRING filename, const CREFSTRING rotateSuffix, bool keepFile = false)
+            : m_sFilename(filename), m_sRotateSuffix(rotateSuffix), m_bRotated(false), m_bKeepFile(keepFile)
+        {
+            struct _stat fileStatus;
+            bool fileExists = MgFileUtil::GetFileStatus(filename, fileStatus);
+
+            this->m_sBackupFilename = (this->m_sFilename + this->m_sRotateSuffix);
+
+            ACE_DEBUG((LM_INFO, ACE_TEXT("\nBacking up file\n%W\n-->\n%W\n"), this->m_sFilename.c_str(), this->m_sBackupFilename.c_str()));
+
+            MgFileUtil::DeleteFile(this->m_sBackupFilename);
+            if (fileExists)
+            {
+                if (!this->m_bKeepFile)
+                {
+                    MgFileUtil::RenameFile(this->m_sFilename, this->m_sBackupFilename);
+                }
+                else
+                {
+                    MgFileUtil::CopyFile(this->m_sFilename, this->m_sBackupFilename);
+                }
+
+                this->m_bRotated = true;
+            }
+        }
+
+        ~FileAutoBackup()
+        {
+            MgFileUtil::DeleteFile(this->m_sFilename);
+            if (this->m_bRotated)
+            {
+                ACE_DEBUG((LM_INFO, ACE_TEXT("\nRestoring file\n%W\n-->\n%W\n"), this->m_sBackupFilename.c_str(), this->m_sFilename.c_str()));
+                MgFileUtil::RenameFile(this->m_sBackupFilename, this->m_sFilename, true);
+            }
+            else
+            {
+                ACE_DEBUG((LM_INFO, ACE_TEXT("\nDid not restore file\n%W\nas it did not exist before\n"), this->m_sFilename.c_str()));
+            }
+        }
+    };
+
 private:
 
     bool CompareCodes(STRING code1, STRING code2);



More information about the mapguide-commits mailing list