[mapguide-commits] r7097 - in trunk/MgDev: Common/CoordinateSystem Common/Geometry/CoordinateSystem Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Oct 8 14:27:08 PDT 2012


Author: baertelchen
Date: 2012-10-08 14:27:08 -0700 (Mon, 08 Oct 2012)
New Revision: 7097

Modified:
   trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h
   trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h
   trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp
   trunk/MgDev/Common/CoordinateSystem/CriticalSection.h
   trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h
   trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h
   trunk/MgDev/Common/CoordinateSystem/MentorUtil.h
   trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h
   trunk/MgDev/Common/CoordinateSystem/namestruct.h
   trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h
   trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp
   trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h
Log:
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.

All changes reviewed by Hugues

Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -133,7 +133,6 @@
 void CCoordinateSystemEnumCategory::Initialize(
     MgCoordinateSystemCategoryDictionary* pDict,
     CCategoryNameList *kpCategoryNameList)
-
 {
     assert(NULL != kpCategoryNameList);
 

Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/CriticalSection.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CriticalSection.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CriticalSection.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -31,6 +31,12 @@
     void Enter();
     void Leave();
 
+#ifdef _DEBUG
+
+    bool IsEntered();
+
+#endif
+
 private:
     bool m_bInitialized;
 };

Modified: trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/MentorUtil.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/MentorUtil.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/MentorUtil.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -21,7 +21,7 @@
 class SmartCriticalClass
 {
 public:
-    SmartCriticalClass(bool bEnter);
+    SmartCriticalClass(bool bEnter = true);
     ~SmartCriticalClass();
 
     void Enter();

Modified: trunk/MgDev/Common/CoordinateSystem/namestruct.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/namestruct.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/namestruct.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h
===================================================================
--- trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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: trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp	2012-10-08 21:27:08 UTC (rev 7097)
@@ -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;
+
+    STRING setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+    pCsCatalog->SetUserDictionaryDir(userDictionaryDir);
+
+    MG_TRY()
+
+#ifdef _WIN32
+        pCsCatalog->SetUserDictionaryDir(L"X:\\I am a hopefully not existing path - if I do, changeme");
+#else
+        pCsCatalog->SetUserDictionaryDir(L"/I 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: trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h	2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h	2012-10-08 21:27:08 UTC (rev 7097)
@@ -25,6 +25,29 @@
     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_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 +258,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 +486,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