[mapguide-commits] r1307 - in trunk/MgDev: Common/MapGuideCommon Common/MapGuideCommon/Exception Common/MapGuideCommon/Resources Common/MapGuideCommon/System Server/src/Common/Manager Server/src/Core Server/src/Services/Feature Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Mar 20 19:03:54 EDT 2007


Author: brucedechant
Date: 2007-03-20 19:03:07 -0400 (Tue, 20 Mar 2007)
New Revision: 1307

Added:
   trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.cpp
   trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.h
Modified:
   trunk/MgDev/Common/MapGuideCommon/Makefile.am
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcproj
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp
   trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res
   trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
   trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
   trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h
   trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
   trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp
   trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h
   trunk/MgDev/Server/src/Core/Server.cpp
   trunk/MgDev/Server/src/Core/serverconfig.ini
   trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h
   trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h
   trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp
Log:
Add improvements to the FDO connection pooling.

These improvements include:
1) Tweaking the caching for more performance
2) Adding a new server configuration property DataConnectionPoolSizeCustom that allows you to specify the exact # of connections to cache on a per provider basis. Providers will still cache the default # if not specified.
3) Enforced the supported FDO thread models the server can use.


Added: trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -0,0 +1,40 @@
+//
+//  Copyright (C) 2004-2007 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "MapGuideCommon.h"
+
+IMPLEMENT_EXCEPTION_DEFAULTS(MgUnsupportedProviderThreadModelException, MgApplicationException)
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Construct a MgUnsupportedProviderThreadModelException object.
+///
+MgUnsupportedProviderThreadModelException::MgUnsupportedProviderThreadModelException(CREFSTRING methodName,
+    INT32 lineNumber, CREFSTRING fileName, MgStringCollection* whatArguments,
+    CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw() :
+    MgApplicationException(methodName, lineNumber, fileName,
+        whatArguments, whyMessageId, whyArguments)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Destruct the object.
+///
+MgUnsupportedProviderThreadModelException::~MgUnsupportedProviderThreadModelException() throw()
+{
+}


Property changes on: trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.cpp
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.h	                        (rev 0)
+++ trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -0,0 +1,69 @@
+//
+//  Copyright (C) 2004-2007 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_UNSUPPORTED_PROVIDER_THREADMODEL_EXCEPTION_H_
+#define MG_UNSUPPORTED_PROVIDER_THREADMODEL_EXCEPTION_H_
+
+/// \ingroup Exceptions_Module
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Thrown when the server does not support the FDO provider thread model.
+///
+class MG_MAPGUIDE_API MgUnsupportedProviderThreadModelException : public MgApplicationException
+{
+    DECLARE_CLASSNAME(MgUnsupportedProviderThreadModelException)
+
+EXTERNAL_API:
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Construct a MgUnsupportedProviderThreadModelException object.
+    ///
+    /// \param methodName
+    /// Name of the method where the exception occurred.
+    /// \param lineNumber
+    /// Line number where the exception occurred.
+    /// \param fileName
+    /// File name where the exception occurred.
+    /// \param whatArguments
+    /// Collection of arguments used to format the message that describes what the exception is.
+    /// \param whyMessageId
+    /// ID of the message that describes why the exception occurs.
+    /// \param whyArguments
+    /// Collection of arguments used to format the message that describes why the exception occurs.
+    ///
+    MgUnsupportedProviderThreadModelException(CREFSTRING methodName, INT32 lineNumber,
+        CREFSTRING fileName, MgStringCollection* whatArguments,
+        CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Destructor for a MgUnsupportedProviderThreadModelException object.
+    ///
+    virtual ~MgUnsupportedProviderThreadModelException() throw();
+
+INTERNAL_API:
+
+    DECLARE_EXCEPTION_DEFAULTS(MgUnsupportedProviderThreadModelException)
+
+CLASS_ID:
+
+    static const INT32 m_cls_id = MapGuide_Exception_MgUnsupportedProviderThreadModelException;
+};
+
+#endif


Property changes on: trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedProviderThreadModelException.h
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/MgDev/Common/MapGuideCommon/Makefile.am
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Makefile.am	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/Makefile.am	2007-03-20 23:03:07 UTC (rev 1307)
@@ -63,6 +63,7 @@
   Exception/SessionNotFoundException.cpp \
   Exception/StylizeLayerFailedException.cpp \
   Exception/UnauthorizedAccessException.cpp \
+  Exception/UnsupportedProviderThreadModelException.cpp \
   Exception/UriFormatException.cpp \
   MapLayer/Layer.cpp \
   MapLayer/Map.cpp \
@@ -178,6 +179,7 @@
   Exception/SessionNotFoundException.h \
   Exception/StylizeLayerFailedException.h \
   Exception/UnauthorizedAccessException.h \
+  Exception/UnsupportedProviderThreadModelException.h \
   Exception/UriFormatException.h \
   MapLayer/Layer.h \
   MapLayer/Map.h \

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -109,6 +109,7 @@
 #include "Exception/SessionNotFoundException.h"
 #include "Exception/StylizeLayerFailedException.h"
 #include "Exception/UnauthorizedAccessException.h"
+#include "Exception/UnsupportedProviderThreadModelException.h"
 #include "Exception/UriFormatException.h"
 
 #include "Net/IOperationHandler.h"

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcproj
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcproj	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcproj	2007-03-20 23:03:07 UTC (rev 1307)
@@ -1588,6 +1588,30 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Exception\UnsupportedProviderThreadModelException.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\Exception\UnsupportedProviderThreadModelException.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Exception\UriFormatException.cpp"
 				>
 				<FileConfiguration

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -70,6 +70,7 @@
 #include  "Exception/SessionNotFoundException.cpp"
 #include  "Exception/StylizeLayerFailedException.cpp"
 #include  "Exception/UnauthorizedAccessException.cpp"
+#include  "Exception/UnsupportedProviderThreadModelException.cpp"
 #include  "Exception/UriFormatException.cpp"
 #include  "MapLayer/Layer.cpp"
 #include  "MapLayer/Map.cpp"

Modified: trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res	2007-03-20 23:03:07 UTC (rev 1307)
@@ -144,6 +144,7 @@
 MgUnauthorizedAccessException                         = Unauthorized access.
 MgUnclassifiedException                               = An unclassified exception occurred.
 MgUnderflowException                                  = Underflow exception.
+MgUnsupportedProviderThreadModelException             = The FDO provider thread model is not supported.
 MgUriFormatException                                  = Uri format exception.
 MgUserNotFoundException                               = The specified user was not found: %1
 MgXmlException                                        = An XML exception occurred.

Modified: trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -35,7 +35,7 @@
 #define MG_CONFIG_MAX_CACHE_SIZE                        MG_CONFIG_MAX_INT32
 
 #define MG_CONFIG_MIN_CONNECTION_POOL_SIZE              1
-#define MG_CONFIG_MAX_CONNECTION_POOL_SIZE              1024
+#define MG_CONFIG_MAX_CONNECTION_POOL_SIZE              100
 
 #define MG_CONFIG_MIN_CONNECTIONS                       1
 #define MG_CONFIG_MAX_CONNECTIONS                       1024
@@ -239,7 +239,9 @@
 const STRING MgConfigProperties::FeatureServicePropertyDataConnectionPoolExcludedProviders  = L"DataConnectionPoolExcludedProviders";
 const STRING MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolExcludedProviders = L""; // This means all providers are cached
 const STRING MgConfigProperties::FeatureServicePropertyDataConnectionPoolSize               = L"DataConnectionPoolSize";
-const INT32  MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize        = 100;
+const INT32  MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize        = 20;
+const STRING MgConfigProperties::FeatureServicePropertyDataConnectionPoolSizeCustom         = L"DataConnectionPoolSizeCustom";
+const STRING MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSizeCustom  = L"";
 const STRING MgConfigProperties::FeatureServicePropertyDataConnectionTimeout                = L"DataConnectionTimeout";
 const INT32  MgConfigProperties::DefaultFeatureServicePropertyDataConnectionTimeout         = 600;
 const STRING MgConfigProperties::FeatureServicePropertyDataConnectionTimerInterval          = L"DataConnectionTimerInterval";
@@ -523,6 +525,7 @@
     { MgConfigProperties::FeatureServicePropertyDataConnectionPoolEnabled           , MgPropertyType::Boolean   , 0                                     , 1                                     , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataConnectionPoolExcludedProviders , MgPropertyType::String    , MG_CONFIG_MIN_FS_CP_EXCLUDED_LENGTH   , MG_CONFIG_MAX_FS_CP_EXCLUDED_LENGTH   , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataConnectionPoolSize              , MgPropertyType::Int32     , MG_CONFIG_MIN_CONNECTION_POOL_SIZE    , MG_CONFIG_MAX_CONNECTION_POOL_SIZE    , L""                                       },
+    { MgConfigProperties::FeatureServicePropertyDataConnectionPoolSizeCustom        , MgPropertyType::String    , MG_CONFIG_MIN_FS_CP_EXCLUDED_LENGTH   , MG_CONFIG_MAX_FS_CP_EXCLUDED_LENGTH   , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataConnectionTimeout               , MgPropertyType::Int32     , MG_CONFIG_MIN_TIMEOUT                 , MG_CONFIG_MAX_TIMEOUT                 , L""                                       },
     { MgConfigProperties::FeatureServicePropertyDataConnectionTimerInterval         , MgPropertyType::Int32     , MG_CONFIG_MIN_TIMER_INTERVAL          , MG_CONFIG_MAX_TIMER_INTERVAL          , L""                                       },
     { MgConfigProperties::FeatureServicePropertyJoinQueryBatchSize                  , MgPropertyType::Int32     , MG_CONFIG_MIN_JOIN_QUERY_BATCH_SIZE   , MG_CONFIG_MAX_JOIN_QUERY_BATCH_SIZE   , L""                                       },

Modified: trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -285,8 +285,12 @@
 
     /// Sets the number of pooled data connections
     static const STRING FeatureServicePropertyDataConnectionPoolSize;           /// value("DataConnectionPoolSize")
-    static const INT32 DefaultFeatureServicePropertyDataConnectionPoolSize;     /// value(100)
+    static const INT32 DefaultFeatureServicePropertyDataConnectionPoolSize;     /// value(20)
 
+    /// Sets the number of pooled data connections for a specific provider
+    static const STRING FeatureServicePropertyDataConnectionPoolSizeCustom;         /// value("DataConnectionPoolSizeCustom")
+    static const STRING DefaultFeatureServicePropertyDataConnectionPoolSizeCustom;  /// value("")
+
     /// Sets the maximum amount of time (in seconds) for data connection idle activity before the data connection is closed
     static const STRING FeatureServicePropertyDataConnectionTimeout;            /// value("DataConnectionTimeout")
     static const INT32 DefaultFeatureServicePropertyDataConnectionTimeout;      /// value(600)

Modified: trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -85,6 +85,7 @@
 #define MapGuide_Exception_MgUriFormatException                         MAPGUIDE_EXCEPTION_ID+50
 #define MapGuide_Exception_MgStylizeLayerFailedException                MAPGUIDE_EXCEPTION_ID+51
 #define MapGuide_Exception_MgSessionNotFoundException                   MAPGUIDE_EXCEPTION_ID+52
+#define MapGuide_Exception_MgUnsupportedProviderThreadModelException    MAPGUIDE_EXCEPTION_ID+53
 
 
 // MapLayer API

Modified: trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -86,6 +86,7 @@
     EXCEPTION_CLASS_CREATOR(MgSessionExpiredException)
     EXCEPTION_CLASS_CREATOR(MgSessionNotFoundException)
     EXCEPTION_CLASS_CREATOR(MgUnauthorizedAccessException)
+    EXCEPTION_CLASS_CREATOR(MgUnsupportedProviderThreadModelException)
     EXCEPTION_CLASS_CREATOR(MgUriFormatException)
 
     fact->Register(MapGuide_MapLayer_Map, MgMap::CreateObject);

Modified: trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -16,6 +16,7 @@
 //
 
 #include "FdoConnectionManager.h"
+#include "System/ConfigProperties.h"
 #include "System/XmlDefs.h"
 #include "System/XmlUtil.h"
 #include "ServiceManager.h"
@@ -24,11 +25,11 @@
 
 ACE_Recursive_Thread_Mutex MgFdoConnectionManager::sm_mutex;
 
-const INT32 MaxFdoConnectionPoolSize = 1000;
-
 // Process-wide MgFdoConnectionManager
 Ptr<MgFdoConnectionManager> MgFdoConnectionManager::sm_fdoConnectionManager = (MgFdoConnectionManager*)NULL;
 
+// Uncomment the next line to debug the FDO Connection Manager cache
+//#define _DEBUG_FDOCONNECTION_MANAGER
 
 // Constructor
 MgFdoConnectionManager::MgFdoConnectionManager(void)
@@ -48,6 +49,20 @@
 
     ClearCache();
 
+    // Clear the provider information collection
+    ProviderInfoCollection::iterator iter = m_ProviderInfoCollection.begin();
+    while(m_ProviderInfoCollection.end() != iter)
+    {
+        ProviderInfo* providerInfo = iter->second;
+        if(providerInfo)
+        {
+            delete providerInfo;
+            providerInfo = NULL;
+        }
+
+        m_ProviderInfoCollection.erase(iter++);
+    }
+
     FDO_SAFE_RELEASE(m_connManager);
 
     MG_FDOCONNECTION_MANAGER_CATCH(L"MgFdoConnectionManager.~MgFdoConnectionManager")
@@ -91,19 +106,20 @@
 /// </summary>
 ///----------------------------------------------------------------------------
 
-void MgFdoConnectionManager::Initialize(bool bFdoConnectionPoolEnabled, INT32 nFdoConnectionPoolSize, INT32 nFdoConnectionTimeout, STRING excludedProviders)
+void MgFdoConnectionManager::Initialize(bool bFdoConnectionPoolEnabled, INT32 nFdoConnectionPoolSize, INT32 nFdoConnectionTimeout, STRING excludedProviders, STRING fdoConnectionPoolSizeCustom)
 {
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager::Initialize()\n")));
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager::Initialize()\n")));
     MG_LOG_TRACE_ENTRY(L"MgFdoConnectionManager::Initialize()");
 
     m_connManager = FdoFeatureAccessManager::GetConnectionManager();
     CHECKNULL(m_connManager, L"MgFdoConnectionManager.Initialize()");
 
-    if((MaxFdoConnectionPoolSize < nFdoConnectionPoolSize) || (1 > nFdoConnectionPoolSize))
+    if((MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize < nFdoConnectionPoolSize) ||
+       (1 > nFdoConnectionPoolSize))
     {
-        nFdoConnectionPoolSize = MaxFdoConnectionPoolSize;
+        nFdoConnectionPoolSize = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize;
     }
 
     m_bFdoConnectionPoolEnabled = bFdoConnectionPoolEnabled;
@@ -113,6 +129,37 @@
     // Parse the comma delimited string into a string collection
     m_excludedProviders = MgStringCollection::ParseCollection(excludedProviders, L",");
 
+    Ptr<MgStringCollection> fdoConnectionPoolSizeCustomCol = MgStringCollection::ParseCollection(fdoConnectionPoolSizeCustom, L",");
+
+    // Update the provider cache size collection
+    for(INT32 i=0;i<fdoConnectionPoolSizeCustomCol->GetCount();i++)
+    {
+        STRING customPoolSize = fdoConnectionPoolSizeCustomCol->GetItem(i);
+
+        STRING provider = customPoolSize;
+        INT32 nCustomPoolSize = nFdoConnectionPoolSize;
+
+        // Parse the format: provider:size
+        // Example: OSGeo.SDF:10
+
+        size_t position = customPoolSize.find(L":", 0); // NOXLATE
+        if(position != string::npos)
+        {
+            provider = customPoolSize.substr(0, position);
+            STRING value = customPoolSize.substr(position+1, customPoolSize.size());
+            nCustomPoolSize = MgUtil::StringToInt32(value);
+        }
+
+        ProviderInfo* providerInfo = new ProviderInfo();
+        if(providerInfo)
+        {
+            providerInfo->cacheSize = nCustomPoolSize;
+            providerInfo->threadModel = (FdoThreadCapability)-1; // Not set yet
+
+            m_ProviderInfoCollection.insert(ProviderInfoCacheEntry_Pair(provider, providerInfo));
+        }
+    }
+
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.Initialize")
 }
 
@@ -149,30 +196,51 @@
 
     if(NULL == pFdoConnection)
     {
-        // Retrieve XML from repository
-        string featureSourceXmlContent;
-        RetrieveFeatureSource(resourceIdentifier, featureSourceXmlContent);
-
         // Parse XML and get properties
 
-        auto_ptr<MdfModel::FeatureSource> featureSource(GetFeatureSource(resourceIdentifier));
+        MdfModel::FeatureSource* featureSource = GetFeatureSource(resourceIdentifier);
 
-        STRING providerName = (STRING)featureSource->GetProvider();
+        STRING provider = (STRING)featureSource->GetProvider();
         STRING configDocumentName = (STRING)featureSource->GetConfigurationDocument();
         STRING longTransactionName = (STRING)featureSource->GetLongTransaction();
 
-        providerName = UpdateProviderName(providerName);
+        provider = UpdateProviderName(provider);
 
         // Update the long transaction name to any active one for the current request
         MgLongTransactionManager::GetLongTransactionName(resourceIdentifier, longTransactionName);
 
         // Create a new connection and add it to the cache
-        pFdoConnection = m_connManager->CreateConnection(providerName.c_str());
+        pFdoConnection = m_connManager->CreateConnection(provider.c_str());
 
+        // Check to see if we already have the capabilities for this provider
+        ProviderInfo* providerInfo = GetProviderInformation(provider);
+        if(providerInfo)
+        {
+            // Check if we have thread model
+            if((FdoThreadCapability)-1 == providerInfo->threadModel)
+            {
+                // Get the connection capabilities
+                FdoPtr<FdoIConnectionCapabilities> ficc = pFdoConnection->GetConnectionCapabilities();
+
+                // Get the thread model
+                FdoThreadCapability ftc = ficc->GetThreadCapability();
+
+                // Update the provider information collection
+                providerInfo->threadModel = ftc;
+            }
+
+            // The server only support FdoThreadCapability_PerConnectionThreaded or better connections
+           if(FdoThreadCapability_SingleThreaded == providerInfo->threadModel)
+            {
+                throw new MgUnsupportedProviderThreadModelException(L"MgFdoConnectionManager.Open",
+                    __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+        }
+
         // Retrieve the properties and open the connection
-        SetConnectionProperties(pFdoConnection, featureSource.get());
+        SetConnectionProperties(pFdoConnection, featureSource);
 
-        SetConfiguration(providerName, pFdoConnection, resourceIdentifier, configDocumentName);
+        SetConfiguration(provider, pFdoConnection, resourceIdentifier, configDocumentName);
 
         Open(pFdoConnection);
 
@@ -182,13 +250,14 @@
         if(m_bFdoConnectionPoolEnabled)
         {
             // Check to see if this provider has been excluded from caching
-            if(!IsExcludedProvider(providerName))
+            if(!IsExcludedProvider(provider))
             {
-                if(!FdoConnectionCacheFull())
+                if(!FdoConnectionCacheFull(provider))
                 {
                     // Add this entry to the cache
-                    CacheFdoConnection(pFdoConnection, resourceIdentifier->ToString(),
-                                       featureSourceXmlContent,
+                    CacheFdoConnection(pFdoConnection, 
+                                       provider, 
+                                       resourceIdentifier->ToString(),
                                        longTransactionName);
                 }
             }
@@ -201,7 +270,7 @@
 }
 
 
-FdoIConnection* MgFdoConnectionManager::Open(CREFSTRING providerName, CREFSTRING connectionString)
+FdoIConnection* MgFdoConnectionManager::Open(CREFSTRING provider, CREFSTRING connectionString)
 {
     ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
 
@@ -215,7 +284,7 @@
 
     // Empty connection string is allowed for ODBC provider to retrieve
     // DataSources
-    if (providerName.empty())
+    if (provider.empty())
     {
         MgStringCollection arguments;
         arguments.Add(L"1");
@@ -225,18 +294,44 @@
             __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
     }
 
-    STRING providerNameNoVersion = UpdateProviderName(providerName);
+    STRING providerNoVersion = UpdateProviderName(provider);
 
     if(m_bFdoConnectionPoolEnabled)
     {
         // Search the cache for an FDO connection matching this provider/connection string
-        pFdoConnection = FindFdoConnection(providerNameNoVersion, connectionString);
+        pFdoConnection = FindFdoConnection(providerNoVersion, connectionString);
     }
 
     if(NULL == pFdoConnection)
     {
         // Create a new connection and add it to the cache
-        pFdoConnection = m_connManager->CreateConnection(providerNameNoVersion.c_str());
+        pFdoConnection = m_connManager->CreateConnection(providerNoVersion.c_str());
+
+        // Check to see if we already have the capabilities for this provider
+        ProviderInfo* providerInfo = GetProviderInformation(providerNoVersion);
+        if(providerInfo)
+        {
+            // Check if we have thread model
+            if((FdoThreadCapability)-1 == providerInfo->threadModel)
+            {
+                // Get the connection capabilities
+                FdoPtr<FdoIConnectionCapabilities> ficc = pFdoConnection->GetConnectionCapabilities();
+
+                // Get the thread model
+                FdoThreadCapability ftc = ficc->GetThreadCapability();
+
+                // Update the provider information collection
+                providerInfo->threadModel = ftc;
+            }
+
+            // The server only support FdoThreadCapability_PerConnectionThreaded or better connections
+           if(FdoThreadCapability_SingleThreaded == providerInfo->threadModel)
+            {
+                throw new MgUnsupportedProviderThreadModelException(L"MgFdoConnectionManager.Open",
+                    __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+        }
+
         // No connection string, no pooling and connection will remain in closed state
         if (!connectionString.empty())
         {
@@ -249,15 +344,13 @@
             if(m_bFdoConnectionPoolEnabled)
             {
                 // Check to see if this provider has been excluded from caching
-                if(!IsExcludedProvider(providerNameNoVersion))
+                if(!IsExcludedProvider(providerNoVersion))
                 {
-                    if(!FdoConnectionCacheFull())
+                    if(!FdoConnectionCacheFull(providerNoVersion))
                     {
                         // Add this entry to the cache
-                        STRING key = providerNameNoVersion + L" - " + connectionString;
-                        string data = "";
                         STRING ltName = L"";
-                        CacheFdoConnection(pFdoConnection, key, data, ltName);
+                        CacheFdoConnection(pFdoConnection, providerNoVersion, connectionString, ltName);
                     }
                 }
             }
@@ -293,60 +386,72 @@
     MG_FDOCONNECTION_MANAGER_TRY()
 
     ACE_Time_Value now = ACE_OS::gettimeofday();
-    FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
 
-    while(m_FdoConnectionCache.end() != iter)
+    // Loop all of the FDO connection caches
+    FdoConnectionCacheCollection::iterator iterFdoConnectionCacheCollection = m_FdoConnectionCacheCollection.begin();
+    while(m_FdoConnectionCacheCollection.end() != iterFdoConnectionCacheCollection)
     {
-        FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
-        if(pFdoConnectionCacheEntry)
+        FdoConnectionCache* fdoConnectionCache = iterFdoConnectionCacheCollection->second;
+        if(fdoConnectionCache)
         {
-            INT32 time = now.sec() - pFdoConnectionCacheEntry->lastUsed.sec();
-            if(time > m_nFdoConnectionTimeout)
+            FdoConnectionCache::iterator iter = fdoConnectionCache->begin();
+
+            while(fdoConnectionCache->end() != iter)
             {
-                // Connection has expired so close it and remove it
-                pFdoConnectionCacheEntry->pFdoConnection->Close();
+                FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
+                if(pFdoConnectionCacheEntry)
+                {
+                    INT32 time = now.sec() - pFdoConnectionCacheEntry->lastUsed.sec();
+                    if(time > m_nFdoConnectionTimeout)
+                    {
+                        // Connection has expired so close it and remove it
+                        pFdoConnectionCacheEntry->pFdoConnection->Close();
 
-                // Release any resource
-                FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
+                        // Release any resource
+                        FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
 
-                delete pFdoConnectionCacheEntry;
-                pFdoConnectionCacheEntry = NULL;
+                        delete pFdoConnectionCacheEntry;
+                        pFdoConnectionCacheEntry = NULL;
 
-                STRING cacheKey = iter->first;
+                        STRING cacheKey = iter->first;
 
-                // Remove any feature service cache entries for this resource
-                MgServiceManager* serviceManager = MgServiceManager::GetInstance();
-                assert(NULL != serviceManager);
+                        // Remove any feature service cache entries for this resource
+                        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+                        assert(NULL != serviceManager);
 
-                try
-                {
-                    Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(cacheKey);
-                    serviceManager->RemoveFeatureServiceCacheEntry(resource);
+                        try
+                        {
+                            Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(cacheKey);
+                            serviceManager->RemoveFeatureServiceCacheEntry(resource);
+                        }
+                        catch(MgInvalidRepositoryTypeException* e)
+                        {
+                            // If this exception is thrown then the key was not a resource identifier string 
+                            // and so there will be no entries in the feature service cache to remove.
+                            SAFE_RELEASE(e);
+                        }
+
+                        fdoConnectionCache->erase(iter++);
+
+                        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager.RemoveExpiredConnections() - Found expired cached FDO connection.\n")));
+                    }
+                    else
+                    {
+                        // Check the next cached connection
+                        iter++;
+                    }
                 }
-                catch(MgInvalidRepositoryTypeException* e)
+                else
                 {
-                    // If this exception is thrown then the key was not a resource identifier string 
-                    // and so there will be no entries in the feature service cache to remove.
-                    SAFE_RELEASE(e);
+                    // NULL Pointer
+                    break;
                 }
-
-                m_FdoConnectionCache.erase(iter++);
-
-                ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager.RemoveExpiredConnections() - Found expired cached FDO connection.\n")));
             }
-            else
-            {
-                // Check the next cached connection
-                iter++;
-            }
         }
-        else
-        {
-            // NULL Pointer
-            break;
-        }
+
+        // Next FDO connection cache
+        iterFdoConnectionCacheCollection++;
     }
-
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.RemoveExpiredConnections")
 }
 
@@ -359,10 +464,12 @@
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    // Retrieve XML from repository
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(resourceIdentifier, featureSourceXmlContent);
+    // Parse feature source XML and get provider
+    MdfModel::FeatureSource* featureSource = GetFeatureSource(resourceIdentifier);
 
+    STRING provider = (STRING)featureSource->GetProvider();
+    provider = UpdateProviderName(provider);
+
     // Get the active long transaction name for the current request
     STRING ltName = L"";
 
@@ -371,17 +478,15 @@
         // No long transaction name cached for the current session or no current session
         // In this case we want to use the requested long transaction of the feature source
 
-        // Parse feature source XML and get long transaction
+        // Get long transaction
 
-        auto_ptr<MdfModel::FeatureSource> featureSource(GetFeatureSource(resourceIdentifier));
-
         STRING longTransactionName = (STRING)featureSource->GetLongTransaction();
 
         ltName = longTransactionName;
     }
 
-    pFdoConnection = SearchFdoConnectionCache(resourceIdentifier->ToString(),
-                                              featureSourceXmlContent,
+    pFdoConnection = SearchFdoConnectionCache(provider, 
+                                              resourceIdentifier->ToString(),
                                               ltName);
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.FindFdoConnection")
@@ -390,18 +495,16 @@
 }
 
 
-FdoIConnection* MgFdoConnectionManager::FindFdoConnection(CREFSTRING providerName, CREFSTRING connectionString)
+FdoIConnection* MgFdoConnectionManager::FindFdoConnection(CREFSTRING provider, CREFSTRING connectionString)
 {
     FdoIConnection* pFdoConnection = NULL;
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    STRING providerNameNoVersion = UpdateProviderName(providerName);
-    STRING key = providerNameNoVersion + L" - " + connectionString;
-    string data = "";
+    STRING providerNoVersion = UpdateProviderName(provider);
     STRING ltName = L"";
 
-    pFdoConnection = SearchFdoConnectionCache(key, data, ltName);
+    pFdoConnection = SearchFdoConnectionCache(providerNoVersion, connectionString, ltName);
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.FindFdoConnection")
 
@@ -409,7 +512,7 @@
 }
 
 
-FdoIConnection* MgFdoConnectionManager::SearchFdoConnectionCache(CREFSTRING key, string& data, CREFSTRING ltName)
+FdoIConnection* MgFdoConnectionManager::SearchFdoConnectionCache(CREFSTRING provider, CREFSTRING key, CREFSTRING ltName)
 {
     ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
 
@@ -417,46 +520,64 @@
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
-
-    while(m_FdoConnectionCache.end() != iter)
+    // Loop all of the FDO connection caches
+    FdoConnectionCacheCollection::iterator iterFdoConnectionCacheCollection = m_FdoConnectionCacheCollection.begin();
+    while(m_FdoConnectionCacheCollection.end() != iterFdoConnectionCacheCollection)
     {
-        STRING cacheKey = iter->first;
-        if(ACE_OS::strcasecmp(cacheKey.c_str(), key.c_str()) == 0)
+        STRING providerCached = iterFdoConnectionCacheCollection->first;
+        if(ACE_OS::strcasecmp(providerCached.c_str(), provider.c_str()) == 0)
         {
-            // We have a key match
-            FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
-            if(pFdoConnectionCacheEntry)
+            FdoConnectionCache* fdoConnectionCache = iterFdoConnectionCacheCollection->second;
+            if(fdoConnectionCache)
             {
-                if(pFdoConnectionCacheEntry->data == data)
+                FdoConnectionCache::iterator iter = fdoConnectionCache->begin();
+
+                while(fdoConnectionCache->end() != iter)
                 {
-                    // We have a data match
-                    if(pFdoConnectionCacheEntry->ltName == ltName)
+                    STRING cacheKey = iter->first;
+                    if(ACE_OS::strcasecmp(cacheKey.c_str(), key.c_str()) == 0)
                     {
-                        // We have a long transaction name match
-                        if(pFdoConnectionCacheEntry->pFdoConnection->GetRefCount() == 1)
+                        // We have a key match
+                        FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
+                        if(pFdoConnectionCacheEntry)
                         {
-                            // It is not in use so claim it
-                            pFdoConnectionCacheEntry->lastUsed = ACE_OS::gettimeofday();
-                            if (FdoConnectionState_Closed == pFdoConnectionCacheEntry->pFdoConnection->GetConnectionState())
+                            if(pFdoConnectionCacheEntry->ltName == ltName)
                             {
-                                pFdoConnectionCacheEntry->pFdoConnection->Open();
+                                // We have a long transaction name match
+                                if(pFdoConnectionCacheEntry->pFdoConnection->GetRefCount() == 1)
+                                {
+                                    // It is not in use so claim it
+                                    pFdoConnectionCacheEntry->lastUsed = ACE_OS::gettimeofday();
+                                    if (FdoConnectionState_Closed == pFdoConnectionCacheEntry->pFdoConnection->GetConnectionState())
+                                    {
+                                        pFdoConnectionCacheEntry->pFdoConnection->Open();
+                                    }
+                                    pFdoConnection = FDO_SAFE_ADDREF(pFdoConnectionCacheEntry->pFdoConnection);
+                                    break;
+                                }
                             }
-                            pFdoConnection = FDO_SAFE_ADDREF(pFdoConnectionCacheEntry->pFdoConnection);
-                            break;
                         }
                     }
+
+                    iter++;
                 }
             }
         }
 
-        iter++;
+        if(pFdoConnection)
+        {
+            // We found a connection
+            break;
+        }
+
+        // Next FDO connection cache
+        iterFdoConnectionCacheCollection++;
     }
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.SearchFdoConnectionCache")
 
-    #ifdef _DEBUG
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("SearchFdoConnectionCache:\nConnection: %@\nKey = %W\nData = %W\nVersion(LT) = %W\n\n"), (void*)pFdoConnection, key.c_str(), data.empty() ? L"(empty)" : L"(data)", ltName.empty() ? L"(empty)" : ltName.c_str()));
+    #ifdef _DEBUG_FDOCONNECTION_MANAGER
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("SearchFdoConnectionCache:\nConnection: %@\nKey = %W\nVersion(LT) = %W\n\n"), (void*)pFdoConnection, key.c_str(), ltName.empty() ? L"(empty)" : ltName.c_str()));
     #endif
 
     return pFdoConnection;
@@ -614,7 +735,6 @@
     return ficc->SupportsConfiguration();
 }
 
-
 void MgFdoConnectionManager::RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent)
 {
     CHECKNULL(resource, L"MgFdoConnectionManager.RetrieveFeatureSource");
@@ -623,7 +743,6 @@
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    FdoConnectionCacheEntry* pFdoConnectionCacheEntry = NULL;
     resourceContent = "";
 
     // Check to see if we have a valid resource
@@ -638,65 +757,32 @@
         SAFE_RELEASE(e);
     }
 
-    if(bValidResource)
-    {
-        STRING key = resource->ToString();
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
 
-        FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
+    // Get the service from service manager
+    Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
+        serviceMan->RequestService(MgServiceType::ResourceService));
+    assert(resourceService != NULL);
 
-        while(m_FdoConnectionCache.end() != iter)
-        {
-            STRING cacheKey = iter->first;
-            if(ACE_OS::strcasecmp(cacheKey.c_str(), key.c_str()) == 0)
-            {
-                // We have a key match
-                pFdoConnectionCacheEntry = iter->second;
-                if(pFdoConnectionCacheEntry)
-                {
-                    resourceContent = pFdoConnectionCacheEntry->data;
-                    break;
-                }
-            }
+    // Get the feature source contents
+    Ptr<MgByteReader> byteReader = resourceService->GetResourceContent(resource, MgResourcePreProcessingType::Substitution);
 
-            iter++;
-        }
-    }
+    Ptr<MgByteSink> byteSink = new MgByteSink((MgByteReader*)byteReader);
+    byteSink->ToStringUtf8(resourceContent);
 
-    if(resourceContent.empty())
-    {
-        MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-        assert(NULL != serviceMan);
+    ValidateFeatureSource(resourceContent);
 
-        // Get the service from service manager
-        Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
-            serviceMan->RequestService(MgServiceType::ResourceService));
-        assert(resourceService != NULL);
-
-        // Get the feature source contents
-        Ptr<MgByteReader> byteReader = resourceService->GetResourceContent(resource, MgResourcePreProcessingType::Substitution);
-
-        Ptr<MgByteSink> byteSink = new MgByteSink((MgByteReader*)byteReader);
-        byteSink->ToStringUtf8(resourceContent);
-
-        ValidateFeatureSource(resourceContent);
-
-        if(pFdoConnectionCacheEntry)
-        {
-            // Update the cache entry with the resource document now that we have it
-            pFdoConnectionCacheEntry->data = resourceContent;
-        }
-    }
-
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.RetrieveFeatureSource")
 }
 
 
-void MgFdoConnectionManager::SetConfiguration(CREFSTRING providerName, FdoIConnection* pFdoConnection, MgResourceIdentifier* resourceIdentifier, STRING& configDataName)
+void MgFdoConnectionManager::SetConfiguration(CREFSTRING provider, FdoIConnection* pFdoConnection, MgResourceIdentifier* resourceIdentifier, STRING& configDataName)
 {
     CHECKNULL(resourceIdentifier, L"MgFdoConnectionManager.SetConfiguration");
     CHECKNULL(pFdoConnection, L"MgFdoConnectionManager.SetConfiguration");
 
-    if (providerName.empty())
+    if (provider.empty())
     {
         MgStringCollection arguments;
         arguments.Add(L"1");
@@ -783,7 +869,6 @@
     return supports;
 }
 
-
 void MgFdoConnectionManager::ValidateFeatureSource(string& featureSourceXmlContent)
 {
     bool isValidFeatureSource = true;
@@ -819,7 +904,6 @@
     }
 }
 
-
 void MgFdoConnectionManager::Open(FdoIConnection* pFdoConnection)
 {
     try
@@ -860,18 +944,13 @@
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    // Retrieve XML from repository
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(resourceIdentifier, featureSourceXmlContent);
+    // Get the feature source
+    MdfModel::FeatureSource* featureSource = GetFeatureSource(resourceIdentifier);
 
-    // Parse XML and get properties
-
-    auto_ptr<MdfModel::FeatureSource> featureSource(GetFeatureSource(resourceIdentifier));
-
     // Get the supplementary spatial context information which defines the coordinate system
     // for spatial contexts that are missing this information
     spatialContextInfoMap = new MgSpatialContextInfoMap();
-    GetSpatialContextInfoFromXml(featureSource.get(), spatialContextInfoMap);
+    GetSpatialContextInfoFromXml(featureSource, spatialContextInfoMap);
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.GetSpatialContextInfo")
 
@@ -879,28 +958,28 @@
 }
 
 
-STRING MgFdoConnectionManager::UpdateProviderName(CREFSTRING providerName)
+STRING MgFdoConnectionManager::UpdateProviderName(CREFSTRING provider)
 {
-    STRING providerNameNoVersion = providerName;
+    STRING providerNoVersion = provider;
 
     // Remove the version from the provider name if it is found
     // ie: OSGeo.SDF.3.0 = OSGeo.SDF
-    STRING::size_type index = providerNameNoVersion.find(L".");
+    STRING::size_type index = providerNoVersion.find(L".");
     if(STRING::npos != index)
     {
         index++;
 
         // Found 1st ".", keep looking for second one
-        index = providerNameNoVersion.find(L".", index);
+        index = providerNoVersion.find(L".", index);
         if(STRING::npos != index)
         {
             // Found 2nd "."
             // Update provider name to not include version
-            providerNameNoVersion = providerNameNoVersion.substr(0, index);
+            providerNoVersion = providerNoVersion.substr(0, index);
         }
     }
 
-    return providerNameNoVersion;
+    return providerNoVersion;
 }
 
 
@@ -914,85 +993,97 @@
     // Protect the cache
     ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, false));
 
-    FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
-
-    // We need to search the entire cache because FDO only supports a thread per connection. 
-    // Therefore, there could be more then 1 cached connection to the same FDO provider.
-    while(m_FdoConnectionCache.end() != iter)
+    // Loop all of the FDO connection caches
+    FdoConnectionCacheCollection::iterator iterFdoConnectionCacheCollection = m_FdoConnectionCacheCollection.begin();
+    while(m_FdoConnectionCacheCollection.end() != iterFdoConnectionCacheCollection)
     {
-        STRING cacheKey = iter->first;
-        if(ACE_OS::strcasecmp(cacheKey.c_str(), key.c_str()) == 0)
+        FdoConnectionCache* fdoConnectionCache = iterFdoConnectionCacheCollection->second;
+        if(fdoConnectionCache)
         {
-            connections++;
+            FdoConnectionCache::iterator iter = fdoConnectionCache->begin();
 
-            // We have a key match
-            FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
-            if(pFdoConnectionCacheEntry)
+            // We need to search the entire cache because FDO only supports a thread per connection. 
+            // Therefore, there could be more then 1 cached connection to the same FDO provider.
+            while(fdoConnectionCache->end() != iter)
             {
-                if(pFdoConnectionCacheEntry->pFdoConnection)
+                STRING cacheKey = iter->first;
+                if(ACE_OS::strcasecmp(cacheKey.c_str(), key.c_str()) == 0)
                 {
-                    INT32 refCount = pFdoConnectionCacheEntry->pFdoConnection->GetRefCount();
+                    connections++;
 
-                    // We have a match, is it in use?
-                    if(1 == refCount)
+                    // We have a key match
+                    FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
+                    if(pFdoConnectionCacheEntry)
                     {
-                        // Close the connection
-                        pFdoConnectionCacheEntry->pFdoConnection->Close();
+                        if(pFdoConnectionCacheEntry->pFdoConnection)
+                        {
+                            INT32 refCount = pFdoConnectionCacheEntry->pFdoConnection->GetRefCount();
 
-                        // Release any resource
-                        FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
+                            // We have a match, is it in use?
+                            if(1 == refCount)
+                            {
+                                // Close the connection
+                                pFdoConnectionCacheEntry->pFdoConnection->Close();
 
-                        delete pFdoConnectionCacheEntry;
-                        pFdoConnectionCacheEntry = NULL;
+                                // Release any resource
+                                FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
 
-                        // Remove any feature service cache entries for this resource
-                        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
-                        assert(NULL != serviceManager);
+                                delete pFdoConnectionCacheEntry;
+                                pFdoConnectionCacheEntry = NULL;
 
-                        try
-                        {
-                            Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(key);
-                            serviceManager->RemoveFeatureServiceCacheEntry(resource);
+                                // Remove any feature service cache entries for this resource
+                                MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+                                assert(NULL != serviceManager);
+
+                                try
+                                {
+                                    Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(key);
+                                    serviceManager->RemoveFeatureServiceCacheEntry(resource);
+                                }
+                                catch(MgInvalidRepositoryTypeException* e)
+                                {
+                                    // If this exception is thrown then the key was not a resource identifier string 
+                                    // and so there will be no entries in the feature service cache to remove.
+                                    SAFE_RELEASE(e);
+                                }
+
+                                fdoConnectionCache->erase(iter++);
+
+                                connectionsRemoved++;
+
+                                ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager.RemoveCachedFdoConnection() - Releasing cached FDO connection.\n")));
+                            }
+                            else
+                            {
+                                // The resource is still in use and so it cannot be removed
+                                ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager.RemoveCachedFdoConnection() - FDO connection in use!\n")));
+
+                                // Next cached FDO connection
+                                iter++;
+                            }
                         }
-                        catch(MgInvalidRepositoryTypeException* e)
+                        else
                         {
-                            // If this exception is thrown then the key was not a resource identifier string 
-                            // and so there will be no entries in the feature service cache to remove.
-                            SAFE_RELEASE(e);
+                            // NULL pointer
+                            break;
                         }
-
-                        m_FdoConnectionCache.erase(iter++);
-
-                        connectionsRemoved++;
-
-                        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager.RemoveCachedFdoConnection() - Releasing cached FDO connection.\n")));
                     }
                     else
                     {
-                        // The resource is still in use and so it cannot be removed
-                        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager.RemoveCachedFdoConnection() - FDO connection in use!\n")));
-
-                        // Next cached FDO connection
-                        iter++;
+                        // NULL pointer
+                        break;
                     }
                 }
                 else
                 {
-                    // NULL pointer
-                    break;
+                    // Next cached FDO connection
+                    iter++;
                 }
             }
-            else
-            {
-                // NULL pointer
-                break;
-            }
         }
-        else
-        {
-            // Next cached FDO connection
-            iter++;
-        }
+
+        // Next FDO connection cache
+        iterFdoConnectionCacheCollection++;
     }
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.RemoveCachedFdoConnection")
@@ -1000,7 +1091,7 @@
     return (connections == connectionsRemoved);
 }
 
-void MgFdoConnectionManager::CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING key, string& data, CREFSTRING ltName)
+void MgFdoConnectionManager::CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING provider, CREFSTRING key, CREFSTRING ltName)
 {
     MG_FDOCONNECTION_MANAGER_TRY()
 
@@ -1011,17 +1102,50 @@
     FdoConnectionCacheEntry* pFdoConnectionCacheEntry = new FdoConnectionCacheEntry;
     if(pFdoConnectionCacheEntry)
     {
-        pFdoConnectionCacheEntry->data = data;
         pFdoConnectionCacheEntry->ltName = ltName;
         pFdoConnectionCacheEntry->pFdoConnection = pFdoConnection;
         pFdoConnectionCacheEntry->lastUsed = ACE_OS::gettimeofday();
 
-        #ifdef _DEBUG
-        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("CacheFdoConnection:\nConnection: %@\nKey = %W\nData = %W\nVersion(LT) = %W\n\n"), (void*)pFdoConnection, key.c_str(), data.empty() ? L"(empty)" : L"(data)", ltName.empty() ? L"(empty)" : ltName.c_str()));
+        #ifdef _DEBUG_FDOCONNECTION_MANAGER
+        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("CacheFdoConnection:\nConnection: %@\nProvider = %W\nKey = %W\nVersion(LT) = %W\n\n"), (void*)pFdoConnection, provider.c_str(), key.c_str(), ltName.empty() ? L"(empty)" : ltName.c_str()));
         #endif
 
-        m_FdoConnectionCache.insert(FdoConnectionCache_Pair(key, pFdoConnectionCacheEntry));
+        bool bConnectionCached = false;
 
+        // Get the appropriate provider cache
+        // Loop all of the FDO connection caches
+        FdoConnectionCacheCollection::iterator iterFdoConnectionCacheCollection = m_FdoConnectionCacheCollection.begin();
+        while(m_FdoConnectionCacheCollection.end() != iterFdoConnectionCacheCollection)
+        {
+            STRING providerCached = iterFdoConnectionCacheCollection->first;
+            if(ACE_OS::strcasecmp(providerCached.c_str(), provider.c_str()) == 0)
+            {
+                FdoConnectionCache* fdoConnectionCache = iterFdoConnectionCacheCollection->second;
+                if(fdoConnectionCache)
+                {
+                    fdoConnectionCache->insert(FdoConnectionCacheEntry_Pair(key, pFdoConnectionCacheEntry));
+                    bConnectionCached = true;
+                    break;
+                }
+            }
+
+            // Next FDO connection cache
+            iterFdoConnectionCacheCollection++;
+        }
+
+        // Check to see if the entry was cached. An entry will not be cached above if
+        // the cache doesn't exist for the specified provider
+        if(!bConnectionCached)
+        {
+            // Create the FDO connection cache for the specified provider
+            FdoConnectionCache* fdoConnectionCache = new FdoConnectionCache();
+            if(fdoConnectionCache)
+            {
+                fdoConnectionCache->insert(FdoConnectionCacheEntry_Pair(key, pFdoConnectionCacheEntry));
+                m_FdoConnectionCacheCollection.insert(FdoConnectionCache_Pair(provider, fdoConnectionCache));
+            }
+        }
+
         // Increase the reference count before returning it because this entry has been cached
         FDO_SAFE_ADDREF(pFdoConnection);
     }
@@ -1030,7 +1154,7 @@
 }
 
 
-bool MgFdoConnectionManager::FdoConnectionCacheFull(void)
+bool MgFdoConnectionManager::FdoConnectionCacheFull(CREFSTRING provider)
 {
     bool bCacheFull = false;
 
@@ -1039,48 +1163,94 @@
     // Protect the cache
     ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, true));
 
-    if((INT32)m_FdoConnectionCache.size() >= m_nFdoConnectionPoolSize)
+    FdoConnectionCache* fdoConnectionCache = NULL;
+    INT32 fdoConnectionCacheSize = m_nFdoConnectionPoolSize; // Set to default
+
+    // Loop all of the FDO connection caches
+    FdoConnectionCacheCollection::iterator iterFdoConnectionCacheCollection = m_FdoConnectionCacheCollection.begin();
+    while(m_FdoConnectionCacheCollection.end() != iterFdoConnectionCacheCollection)
     {
-        // We are full, but are all entries in use?
-        bCacheFull = true;
+        STRING providerCached = iterFdoConnectionCacheCollection->first;
+        if(ACE_OS::strcasecmp(providerCached.c_str(), provider.c_str()) == 0)
+        {
+            // Found the cache we are interested in
+            fdoConnectionCache = iterFdoConnectionCacheCollection->second;
+            break;
+        }
+
+        // Next cache entry
+        iterFdoConnectionCacheCollection++;
     }
 
-    // See if we can make room in the FDO connection cache by removing an unused connection
-    if(bCacheFull)
+    // Loop all of the FDO connection caches size
+    ProviderInfoCollection::iterator iterProviderInfo = m_ProviderInfoCollection.begin();
+    while(m_ProviderInfoCollection.end() != iterProviderInfo)
     {
-        FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
+        STRING providerCached = iterProviderInfo->first;
+        if(ACE_OS::strcasecmp(providerCached.c_str(), provider.c_str()) == 0)
+        {
+            ProviderInfo* providerInfo = iterProviderInfo->second;
+            if(providerInfo)
+            {
+                fdoConnectionCacheSize = providerInfo->cacheSize;
+            }
+            break;
+        }
 
-        while(m_FdoConnectionCache.end() != iter)
+        // Next cache entry
+        iterProviderInfo++;
+    }
+
+    if(fdoConnectionCache)
+    {
+        if((INT32)fdoConnectionCache->size() >= fdoConnectionCacheSize)
         {
-            FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
-            if(pFdoConnectionCacheEntry)
+            // We are full, but are all entries in use?
+            bCacheFull = true;
+        }
+
+        // See if we can make room in the FDO connection cache by removing an unused connection
+        if(bCacheFull)
+        {
+            FdoConnectionCache::iterator iter = fdoConnectionCache->begin();
+
+            while(fdoConnectionCache->end() != iter)
             {
-                // Is it in use?
-                if(pFdoConnectionCacheEntry->pFdoConnection)
+                FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
+                if(pFdoConnectionCacheEntry)
                 {
-                    INT32 refCount = pFdoConnectionCacheEntry->pFdoConnection->GetRefCount();
-                    
                     // Is it in use?
-                    if(1 == refCount)
+                    if(pFdoConnectionCacheEntry->pFdoConnection)
                     {
-                        // Close the connection
-                        pFdoConnectionCacheEntry->pFdoConnection->Close();
+                        INT32 refCount = pFdoConnectionCacheEntry->pFdoConnection->GetRefCount();
+                        
+                        // Is it in use?
+                        if(1 == refCount)
+                        {
+                            // Close the connection
+                            pFdoConnectionCacheEntry->pFdoConnection->Close();
 
-                        // Release any resource
-                        FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
+                            // Release any resource
+                            FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
 
-                        delete pFdoConnectionCacheEntry;
-                        pFdoConnectionCacheEntry = NULL;
+                            delete pFdoConnectionCacheEntry;
+                            pFdoConnectionCacheEntry = NULL;
 
-                        m_FdoConnectionCache.erase(iter++);
+                            fdoConnectionCache->erase(iter++);
 
-                        bCacheFull = false;
-                        break;
+                            bCacheFull = false;
+                            break;
+                        }
+                        else
+                        {
+                            // Next cached connection
+                            iter++;
+                        }
                     }
                     else
                     {
-                        // Next cached connection
-                        iter++;
+                        // NULL pointer
+                        break;
                     }
                 }
                 else
@@ -1089,11 +1259,6 @@
                     break;
                 }
             }
-            else
-            {
-                // NULL pointer
-                break;
-            }
         }
     }
 
@@ -1107,77 +1272,109 @@
 {
     ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
 
-#ifdef _DEBUG
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager::ClearCache() - FDO cache BEFORE\n")));
+#ifdef _DEBUG_FDOCONNECTION_MANAGER
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager::ClearCache() - FDO cache BEFORE\n")));
     ShowCache();
 #endif
 
-    size_t cacheSize = m_FdoConnectionCache.size();
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager::ClearCache()\n")));
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) Releasing %d cached FDO connections.\n"), cacheSize));
+    size_t cacheCollectionSize = m_FdoConnectionCacheCollection.size();
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager::ClearCache()\n")));
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("FDO connection caches: %d.\n"), cacheCollectionSize));
 
-    // Cleanup the FDO connection cache
-    FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
-
-    while(m_FdoConnectionCache.end() != iter)
+    // Loop all of the FDO connection caches
+    FdoConnectionCacheCollection::iterator iterFdoConnectionCacheCollection = m_FdoConnectionCacheCollection.begin();
+    while(m_FdoConnectionCacheCollection.end() != iterFdoConnectionCacheCollection)
     {
-        STRING key = iter->first;
-        FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
-        if(pFdoConnectionCacheEntry)
+        // Cleanup the FDO connection cache
+        STRING provider = iterFdoConnectionCacheCollection->first;
+        FdoConnectionCache* fdoConnectionCache = iterFdoConnectionCacheCollection->second;
+        if(fdoConnectionCache)
         {
-            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    %W - "), key.c_str()));
+            size_t cacheSize = fdoConnectionCache->size();
+            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Releasing %d cached %W FDO connections.\n"), cacheSize, provider.c_str()));
 
-            if(pFdoConnectionCacheEntry->pFdoConnection)
+            FdoConnectionCache::iterator iter = fdoConnectionCache->begin();
+            while(fdoConnectionCache->end() != iter)
             {
-                INT32 refCount = pFdoConnectionCacheEntry->pFdoConnection->GetRefCount();
-
-                if(1 == refCount)
+                STRING key = iter->first;
+                FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
+                if(pFdoConnectionCacheEntry)
                 {
-                    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Removed\n")));
+                    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    %W - "), key.c_str()));
 
-                    // The FDO cache is the only one with a reference
-                    // Close the connection
-                    pFdoConnectionCacheEntry->pFdoConnection->Close();
+                    if(pFdoConnectionCacheEntry->pFdoConnection)
+                    {
+                        INT32 refCount = pFdoConnectionCacheEntry->pFdoConnection->GetRefCount();
 
-                    // Release any resource
-                    FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
+                        if(1 == refCount)
+                        {
+                            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Removed\n")));
 
-                    delete pFdoConnectionCacheEntry;
-                    pFdoConnectionCacheEntry = NULL;
+                            // The FDO cache is the only one with a reference
+                            // Close the connection
+                            pFdoConnectionCacheEntry->pFdoConnection->Close();
 
-                    m_FdoConnectionCache.erase(iter++);
+                            // Release any resource
+                            FDO_SAFE_RELEASE(pFdoConnectionCacheEntry->pFdoConnection);
+
+                            delete pFdoConnectionCacheEntry;
+                            pFdoConnectionCacheEntry = NULL;
+
+                            fdoConnectionCache->erase(iter++);
+                        }
+                        else
+                        {
+                            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Still in use!!\n")));
+                            // Next cached connection
+                            iter++;
+                        }
+                    }
+                    else
+                    {
+                        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Removed (NULL connection)\n")));
+
+                        // Remove NULL FDO connection entry
+                        delete pFdoConnectionCacheEntry;
+                        pFdoConnectionCacheEntry = NULL;
+
+                        fdoConnectionCache->erase(iter++);
+                    }
                 }
                 else
                 {
-                    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Still in use!!\n")));
-                    // Next cached connection
-                    iter++;
+                    // NULL pointer
+                    break;
                 }
             }
-            else
-            {
-                ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Removed (NULL connection)\n")));
 
-                // Remove NULL FDO connection entry
-                delete pFdoConnectionCacheEntry;
-                pFdoConnectionCacheEntry = NULL;
+#ifdef _DEBUG_FDOCONNECTION_MANAGER
+            cacheSize = fdoConnectionCache->size();
+            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("%W FDO cached connections still in use %d.\n"), provider.c_str(), cacheSize));
+#endif
 
-                m_FdoConnectionCache.erase(iter++);
-            }
         }
-        else
-        {
-            // NULL pointer
-            break;
-        }
+
+        // Next FDO connection cache
+        iterFdoConnectionCacheCollection++;
     }
 
-#ifdef _DEBUG
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager::ClearCache() - FDO cache AFTER\n")));
+#ifdef _DEBUG_FDOCONNECTION_MANAGER
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager::ClearCache() - FDO cache AFTER\n")));
     ShowCache();
-    cacheSize = m_FdoConnectionCache.size();
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) FDO cached connections still in use %d.\n"), cacheSize));
 #endif
+
+    // Clear the feature source cache
+    FeatureSourceCache::iterator iterFeatureSource = m_FeatureSourceCache.begin();
+    while(m_FeatureSourceCache.end() != iterFeatureSource)
+    {
+        MdfModel::FeatureSource* featureSource = iterFeatureSource->second;
+        if(featureSource)
+        {
+            delete featureSource;
+        }
+
+        m_FeatureSourceCache.erase(iterFeatureSource++);
+    }
 }
 
 
@@ -1186,19 +1383,38 @@
 {
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    size_t cacheSize = m_FdoConnectionCache.size();
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager::ShowCache()\n")));
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) Cached FDO connections = %d\n"), cacheSize));
+    size_t cacheCollectionSize = m_FdoConnectionCacheCollection.size();
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("MgFdoConnectionManager::ShowCache()\n")));
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("FDO connection caches: %d.\n"), cacheCollectionSize));
 
-    // Show the contents of the FDO connection cache
-    int nIndex = 1;
-    for (FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();iter != m_FdoConnectionCache.end(); iter++)
+    // Show the contents of the FDO connection cache collection
+    INT32 nIndex = 1;
+    for (FdoConnectionCacheCollection::iterator iterCol = m_FdoConnectionCacheCollection.begin();iterCol != m_FdoConnectionCacheCollection.end(); iterCol++)
     {
-        STRING key = iter->first;
-        FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
-        if(pFdoConnectionCacheEntry)
+        STRING provider = iterCol->first;
+        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("%2d) %W\n"), nIndex++, provider.c_str()));
+
+        FdoConnectionCache* fdoConnectionCache = iterCol->second;
+        if(fdoConnectionCache)
         {
-            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("  %4d) %W\n"), nIndex++, key.c_str()));
+            INT32 entry = 1;
+            size_t cacheSize = fdoConnectionCache->size();
+            if(cacheSize > 0)
+            {
+                for (FdoConnectionCache::iterator iter = fdoConnectionCache->begin();iter != fdoConnectionCache->end(); iter++)
+                {
+                    STRING key = iter->first;
+                    FdoConnectionCacheEntry* pFdoConnectionCacheEntry = iter->second;
+                    if(pFdoConnectionCacheEntry)
+                    {
+                        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("  %2d) %W\n"), entry++, key.c_str()));
+                    }
+                }
+            }
+            else
+            {
+                ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    No cached entries.\n")));
+            }
         }
     }
 
@@ -1209,13 +1425,13 @@
 #endif
 
 
-bool MgFdoConnectionManager::IsExcludedProvider(CREFSTRING providerName)
+bool MgFdoConnectionManager::IsExcludedProvider(CREFSTRING provider)
 {
     bool bResult = false;
 
     if(m_excludedProviders.p)
     {
-        bResult = m_excludedProviders->Contains(providerName);
+        bResult = m_excludedProviders->Contains(provider);
     }
 
     return bResult;
@@ -1223,21 +1439,85 @@
 
 MdfModel::FeatureSource* MgFdoConnectionManager::GetFeatureSource(MgResourceIdentifier* resId)
 {
-    // Retrieve XML from repository
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(resId, featureSourceXmlContent);
+    MdfModel::FeatureSource* featureSource = NULL;
 
-    MdfParser::FSDSAX2Parser parser;
-    parser.ParseString(featureSourceXmlContent.c_str(),
-        (unsigned int)(featureSourceXmlContent.length()*sizeof(char)));
+    if (resId->GetRepositoryType().empty())
+    {
+        throw new MgInvalidRepositoryTypeException(
+            L"MgFdoConnectionManager.GetFeatureSource", __LINE__,  __WFILE__, NULL, L"", NULL);
+    }
 
-    assert(parser.GetSucceeded());
+    STRING resourceId = resId->ToString();
 
-    // detach the feature source from the parser - it's
-    // now the caller's responsibility to delete it
-    MdfModel::FeatureSource* fs = parser.DetachFeatureSource();
+    FeatureSourceCache::iterator iter = m_FeatureSourceCache.begin();
+    while(m_FeatureSourceCache.end() != iter)
+    {
+        STRING resIdCached = iter->first;
+        if(ACE_OS::strcasecmp(resIdCached.c_str(), resourceId.c_str()) == 0)
+        {
+            featureSource = iter->second;
+            break;
+        }
 
-    assert(fs != NULL);
-    return fs;
+        // Next feature source
+        iter++;
+    }
+
+    if(NULL == featureSource)
+    {
+        // Retrieve XML from repository
+        string featureSourceXmlContent;
+        RetrieveFeatureSource(resId, featureSourceXmlContent);
+
+        MdfParser::FSDSAX2Parser parser;
+        parser.ParseString(featureSourceXmlContent.c_str(),
+            (unsigned int)(featureSourceXmlContent.length()*sizeof(char)));
+
+        assert(parser.GetSucceeded());
+
+        // detach the feature source from the parser - it's
+        // now the caller's responsibility to delete it
+        featureSource = parser.DetachFeatureSource();
+
+        // Store this feature source in the feature source cache
+        m_FeatureSourceCache.insert(FeatureSourceCacheEntry_Pair(resourceId, featureSource));
+    }
+
+    assert(featureSource != NULL);
+    return featureSource;
 }
 
+ProviderInfo* MgFdoConnectionManager::GetProviderInformation(CREFSTRING provider)
+{
+    ProviderInfo* providerInfo = NULL;
+
+    ProviderInfoCollection::iterator iter = m_ProviderInfoCollection.begin();
+    while(m_ProviderInfoCollection.end() != iter)
+    {
+        STRING providerCached = iter->first;
+        if(ACE_OS::strcasecmp(providerCached.c_str(), provider.c_str()) == 0)
+        {
+            // Found it
+            providerInfo = iter->second;
+            break;
+        }
+
+        // Next cache entry
+        iter++;
+    }
+
+    if(NULL == providerInfo)
+    {
+        // Create new entry
+        providerInfo = new ProviderInfo();
+        if(providerInfo)
+        {
+            providerInfo->cacheSize = m_nFdoConnectionPoolSize;
+            providerInfo->threadModel = (FdoThreadCapability)-1; // Not set yet
+
+            m_ProviderInfoCollection.insert(ProviderInfoCacheEntry_Pair(provider, providerInfo));
+        }
+    }
+
+    return providerInfo;
+}

Modified: trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -38,18 +38,38 @@
 #define MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(methodName)   MG_FEATURE_SERVICE_CATCH_AND_THROW(methodName)
 
 typedef struct {
-    string data;    // Feature source XML content
-    STRING ltName;  // current long transaction name for this connection
+    STRING ltName;                              // Current long transaction name for this connection
     FdoIConnection* pFdoConnection;
     ACE_Time_Value lastUsed;
 
 } FdoConnectionCacheEntry;
 
+// Feature Source Cache
+typedef std::map<STRING, MdfModel::FeatureSource*> FeatureSourceCache;
+typedef std::pair<STRING, MdfModel::FeatureSource*> FeatureSourceCacheEntry_Pair;
+
+// FDO Connection Cache
 typedef std::multimap<STRING, FdoConnectionCacheEntry*> FdoConnectionCache;
-typedef std::pair<STRING, FdoConnectionCacheEntry*> FdoConnectionCache_Pair;
+typedef std::pair<STRING, FdoConnectionCacheEntry*> FdoConnectionCacheEntry_Pair;
+
+// FDO Connection Cache Collection
+typedef std::map<STRING, FdoConnectionCache*> FdoConnectionCacheCollection;
+typedef std::pair<STRING, FdoConnectionCache*> FdoConnectionCache_Pair;
+
+// Spatial Context
 typedef std::map<STRING, STRING> MgSpatialContextInfoMap;
 typedef std::pair<STRING, STRING> MgSpatialContextInfoPair;
 
+
+typedef struct {
+    INT32 cacheSize;
+    FdoThreadCapability threadModel;
+} ProviderInfo;
+
+// Provider Information Collection
+typedef std::map<STRING, ProviderInfo*> ProviderInfoCollection;
+typedef std::pair<STRING, ProviderInfo*> ProviderInfoCacheEntry_Pair;
+
 class MG_SERVER_MANAGER_API MgFdoConnectionManager : public MgGuardDisposable
 {
     DECLARE_CLASSNAME(MgFdoConnectionManager)
@@ -63,16 +83,16 @@
     static MgFdoConnectionManager* GetInstance(void);
 
     // This initializes the FDO connection manager
-    void Initialize(bool bFdoConnectionPoolEnabled, INT32 nFdoConnectionPoolSize, INT32 nFdoConnectionTimeout, STRING excludedProviders);
+    void Initialize(bool bFdoConnectionPoolEnabled, INT32 nFdoConnectionPoolSize, INT32 nFdoConnectionTimeout, STRING excludedProviders, STRING fdoConnectionPoolSizeCustom);
     static void Terminate();
     void ClearCache();
 
     FdoIConnection* Open(MgResourceIdentifier* resourceIdentifier);
-    FdoIConnection* Open(CREFSTRING providerName, CREFSTRING connectionString);
+    FdoIConnection* Open(CREFSTRING provider, CREFSTRING connectionString);
     void Close(FdoIConnection* pFdoConnection);
 
     MgSpatialContextInfoMap* GetSpatialContextInfo(MgResourceIdentifier* resourceIdentifier);
-    STRING UpdateProviderName(CREFSTRING providerName);
+    STRING UpdateProviderName(CREFSTRING provider);
 
     void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
 
@@ -90,14 +110,14 @@
     MgFdoConnectionManager(void);
 
     FdoIConnection* FindFdoConnection(MgResourceIdentifier* resourceIdentifier);
-    FdoIConnection* FindFdoConnection(CREFSTRING providerName, CREFSTRING connectionString);
-    FdoIConnection* SearchFdoConnectionCache(CREFSTRING key, string& data, CREFSTRING ltName);
-    void CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING key, string& data, CREFSTRING ltName);
-    bool FdoConnectionCacheFull(void);
+    FdoIConnection* FindFdoConnection(CREFSTRING provider, CREFSTRING connectionString);
+    FdoIConnection* SearchFdoConnectionCache(CREFSTRING provider, CREFSTRING key, CREFSTRING ltName);
+    void CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING provider, CREFSTRING key, CREFSTRING ltName);
+    bool FdoConnectionCacheFull(CREFSTRING provider);
 
     void GetSpatialContextInfoFromXml(MdfModel::FeatureSource* pFeatureSource, MgSpatialContextInfoMap* spatialContextInfoMap);
 
-    void SetConfiguration(CREFSTRING providerName, FdoIConnection* pFdoConnection, MgResourceIdentifier* resourceIdentifier, STRING& configDataName);
+    void SetConfiguration(CREFSTRING provider, FdoIConnection* pFdoConnection, MgResourceIdentifier* resourceIdentifier, STRING& configDataName);
     void SetConnectionProperties(FdoIConnection* pFdoConnection, MgXmlUtil* pXmlUtil);
     void SetConnectionProperties(FdoIConnection* pFdoConnection, MdfModel::FeatureSource* pFeatureSource);
 
@@ -109,13 +129,16 @@
     void ValidateFeatureSource(string& featureSourceXmlContent);
     void Open(FdoIConnection* pFdoConnection);
 
-    bool IsExcludedProvider(CREFSTRING providerName);
+    bool IsExcludedProvider(CREFSTRING provider);
+    ProviderInfo* GetProviderInformation(CREFSTRING provider);
 
     static Ptr<MgFdoConnectionManager> sm_fdoConnectionManager;
     static ACE_Recursive_Thread_Mutex  sm_mutex;
     IConnectionManager*                m_connManager;
 
-    FdoConnectionCache m_FdoConnectionCache;
+    FdoConnectionCacheCollection m_FdoConnectionCacheCollection;
+    FeatureSourceCache m_FeatureSourceCache;
+    ProviderInfoCollection m_ProviderInfoCollection;
 
     bool m_bFdoConnectionPoolEnabled;
     INT32 m_nFdoConnectionPoolSize;

Modified: trunk/MgDev/Server/src/Core/Server.cpp
===================================================================
--- trunk/MgDev/Server/src/Core/Server.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Core/Server.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -852,10 +852,12 @@
             bool bDataConnectionPoolEnabled = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolEnabled;
             INT32 nDataConnectionPoolSize = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize;
             STRING dataConnectionPoolExcludedProviders = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolExcludedProviders;
+            STRING dataConnectionPoolSizeCustom = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSizeCustom;
 
             pConfiguration->GetBoolValue(MgConfigProperties::FeatureServicePropertiesSection, MgConfigProperties::FeatureServicePropertyDataConnectionPoolEnabled, bDataConnectionPoolEnabled, MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolEnabled);
             pConfiguration->GetIntValue(MgConfigProperties::FeatureServicePropertiesSection, MgConfigProperties::FeatureServicePropertyDataConnectionPoolSize, nDataConnectionPoolSize, MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize);
             pConfiguration->GetStringValue(MgConfigProperties::FeatureServicePropertiesSection, MgConfigProperties::FeatureServicePropertyDataConnectionPoolExcludedProviders, dataConnectionPoolExcludedProviders, MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolExcludedProviders);
+            pConfiguration->GetStringValue(MgConfigProperties::FeatureServicePropertiesSection, MgConfigProperties::FeatureServicePropertyDataConnectionPoolSizeCustom, dataConnectionPoolSizeCustom, MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSizeCustom);
 
             // Add additional font mappings to the FontManager
             ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) MgServer::open() - Adding Font Manager Mappings.\n")));
@@ -940,7 +942,7 @@
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgServer::open() - Initializing FDO Connection Manager.\n")));
             MgEventTimer& dataConnectionTimer = m_eventTimerManager.GetEventTimer(MgEventTimer::DataConnectionTimeout);
             MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
-            pFdoConnectionManager->Initialize(bDataConnectionPoolEnabled, nDataConnectionPoolSize, dataConnectionTimer.GetEventTimeout(), dataConnectionPoolExcludedProviders);
+            pFdoConnectionManager->Initialize(bDataConnectionPoolEnabled, nDataConnectionPoolSize, dataConnectionTimer.GetEventTimeout(), dataConnectionPoolExcludedProviders, dataConnectionPoolSizeCustom);
 
             // Initialize the Feature Service Cache
             INT32 cacheLimit;
@@ -999,6 +1001,7 @@
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    Data Connection Pool Enabled           : %s\n"), bDataConnectionPoolEnabled == true ? ACE_TEXT("true") : ACE_TEXT("false")));
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    Data Connection Pool Excluded Providers: %s\n"), MG_WCHAR_TO_TCHAR(dataConnectionPoolExcludedProviders)));
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    Data Connection Pool Size              : %d\n"), nDataConnectionPoolSize));
+            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    Data Connection Pool Size Custom       : %s\n"), MG_WCHAR_TO_TCHAR(dataConnectionPoolSizeCustom)));
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    Data Connection Timeout                : %d\n"), dataConnectionTimer.GetEventTimeout()));
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("    Data Connection Timer Interval         : %d\n"), dataConnectionTimer.GetInterval()));
             ACE_DEBUG ((LM_DEBUG, ACE_TEXT("\n  Mapping Service Properties:\n")));

Modified: trunk/MgDev/Server/src/Core/serverconfig.ini
===================================================================
--- trunk/MgDev/Server/src/Core/serverconfig.ini	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Core/serverconfig.ini	2007-03-20 23:03:07 UTC (rev 1307)
@@ -237,8 +237,11 @@
 #                                      connection pooling.
 #                                      Value = provider name(s) separated by ","
 #                                      Example: OSGeo.SDF,OSGeo.SHP
-# DataConnectionPoolSize           # of connections to cache
+# DataConnectionPoolSize           Default # of FDO connections to cache per provider
+#                                       0 < Value <= 100
+# DataConnectionPoolSizeCustom     Custom # of FDO connections to cache for specified provider
 #                                       0 < Value <= 1024
+#                                      Example: OSGeo.SDF:10,OSGeo.SHP:10
 # DataConnectionTimeout            Time duration in seconds for when an idle
 #                                  connection is dropped
 #                                       0 < Value <= 86400
@@ -255,6 +258,7 @@
 DataConnectionPoolEnabled          = 1
 DataConnectionPoolExcludedProviders= OSGeo.SDF,OSGeo.SHP
 DataConnectionPoolSize             = 20
+DataConnectionPoolSizeCustom       = 
 DataConnectionTimeout              = 600
 DataConnectionTimerInterval        = 60
 JoinQueryBatchSize                 = 100

Modified: trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -35,11 +35,6 @@
 //////////////////////////////////////////////////////////////////
 MgServerDescribeSchema::~MgServerDescribeSchema()
 {
-    if (m_featureSource != NULL)
-    {
-        delete m_featureSource;
-        m_featureSource = NULL;
-    }
 }
 
 
@@ -72,9 +67,10 @@
     CHECKNULL((FdoFeatureSchemaCollection*)ffsc, L"MgServerDescribeSchema.ExecuteDescribeSchema");
 
     // Finished with primary feature source, so now cycle through any secondary sources
-    // Retrieve XML from repository
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(resource, featureSourceXmlContent);
+    if (m_featureSource == NULL)
+    {
+        m_featureSource = GetFeatureSource(resource);
+    }
 
     CHECKNULL(m_featureSource, L"MgServerDescribeSchema.ExecuteDescribeSchema");
 
@@ -260,9 +256,10 @@
             // A new MgClassDefinition needs to be created for each extension and added to the classCollection
             //
 
-            // Retrieve XML from repository
-            string featureSourceXmlContent;
-            RetrieveFeatureSource(resource, featureSourceXmlContent);
+            if (m_featureSource == NULL)
+            {
+                m_featureSource = GetFeatureSource(resource);
+            }
 
             CHECKNULL(m_featureSource, L"MgServerDescribeSchema.DescribeSchema");
 
@@ -1517,9 +1514,10 @@
             if (!bHaveIdProps && classCnt > 0)
             {
                 // Get the className for the primary source that is being extended
-                // Retrieve XML from repository
-                string featureSourceXmlContent;
-                RetrieveFeatureSource(resource, featureSourceXmlContent);
+                if (m_featureSource == NULL)
+                {
+                    m_featureSource = GetFeatureSource(resource);
+                }
 
                 CHECKNULL(m_featureSource, L"MgServerDescribeSchema.GetIdentityProperties");
 
@@ -1581,25 +1579,6 @@
     return idProps.Detach();
 }
 
-void MgServerDescribeSchema::RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent)
-{
-    CHECKNULL(resource, L"MgServerDescribeSchema.RetrieveFeatureSource");
-
-    resourceContent = "";
-
-    // Get the feature source XML content document from the FDO connection manager.
-    MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
-    if(pFdoConnectionManager)
-    {
-         pFdoConnectionManager->RetrieveFeatureSource(resource, resourceContent);
-    }
-
-    if (m_featureSource == NULL)
-    {
-        m_featureSource = GetFeatureSource(resource);
-    }
-}
-
 MdfModel::FeatureSource* MgServerDescribeSchema::GetFeatureSource(MgResourceIdentifier* resource)
 {
     CHECKNULL(resource, L"MgServerDescribeSchema.GetFeatureSource");

Modified: trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -60,7 +60,6 @@
     FdoFeatureSchemaCollection* ExecuteDescribeSchema(MgResourceIdentifier* resource, CREFSTRING schemaName);
     STRING GetSerializedXml(FdoFeatureSchemaCollection* fdoSchemaCol);
 
-    void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
     MdfModel::FeatureSource* GetFeatureSource(MgResourceIdentifier* resource);
 
     MdfModel::FeatureSource* m_featureSource;

Modified: trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -63,12 +63,6 @@
 MgServerSelectFeatures::~MgServerSelectFeatures()
 {
     FDO_SAFE_RELEASE(m_customFunction);
-
-    if (m_featureSource != NULL)
-    {
-        delete m_featureSource;
-        m_featureSource = NULL;
-    }
 }
 
 // Executes the select features command and serializes the reader
@@ -85,9 +79,11 @@
     // Validate parameters
     ValidateParam(resource,className);
 
-    // Retrieve the feature source XML document
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(resource, featureSourceXmlContent);
+    // Retrieve the feature source
+    if (m_featureSource == NULL)
+    {
+        m_featureSource = GetFeatureSource(resource);
+    }
 
     // Check if a feature join is to be performed by inspecting the resource for join properties
     bool bFeatureJoinProperties = FindFeatureJoinProperties(resource, className);
@@ -1038,27 +1034,6 @@
     return gwsFeatureReader.Detach();
 }
 
-void MgServerSelectFeatures::RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent)
-{
-    CHECKNULL(resource, L"MgServerSelectFeatures.RetrieveFeatureSource");
-
-    resourceContent = "";
-
-    // Get the feature source XML content document from the FDO connection manager.
-    MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
-    if(pFdoConnectionManager)
-    {
-         pFdoConnectionManager->RetrieveFeatureSource(resource, resourceContent);
-    }
-
-    if (m_featureSource == NULL)
-    {
-        m_featureSource = GetFeatureSource(resource);
-    }
-
-}
-
-
 void MgServerSelectFeatures::ParseQualifiedClassName(CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className)
 {
     STRING::size_type nIndex = qualifiedClassName.rfind(CLASSNAME_QUALIFIER);

Modified: trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h	2007-03-20 23:03:07 UTC (rev 1307)
@@ -81,7 +81,6 @@
     // Methods for Feature Join
     bool FindFeatureJoinProperties(MgResourceIdentifier* resourceId, CREFSTRING extensionName);
     MgServerGwsFeatureReader* JoinFeatures(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName, FdoFilter* filter);
-    void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
     void ParseQualifiedClassName(CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className);
     MgResourceIdentifier* GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName);
 

Modified: trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp	2007-03-20 21:06:33 UTC (rev 1306)
+++ trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp	2007-03-20 23:03:07 UTC (rev 1307)
@@ -368,7 +368,7 @@
         pManager->Close(pFdoConnection2);
 
         // Force removal from the FDO connection cache
-        STRING key = provider + L" - " + connectionString;
+        STRING key = connectionString;
         pManager->RemoveCachedFdoConnection(key);
     }
     catch(MgException* e)



More information about the mapguide-commits mailing list