[mapguide-commits] r6904 - in branches/2.4/MgDev/Desktop: MgDesktop MgDesktop/Services MgDesktop/Services/Feature/Commands UnitTest

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sun Jul 15 14:07:05 PDT 2012


Author: jng
Date: 2012-07-15 14:07:04 -0700 (Sun, 15 Jul 2012)
New Revision: 6904

Added:
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.h
Modified:
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h
   branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp
   branches/2.4/MgDev/Desktop/UnitTest/main.cpp
Log:
mg-desktop: Update the implementations of various MgFeatureService APIs to use the commands added in the previous submission. This fixes #2074 as we now use the exact MapGuide Server implementation of SelectFeatures

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-07-15 21:07:04 UTC (rev 6904)
@@ -760,6 +760,42 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\Commands\DescribeSchema.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\DrawingService.cpp"
 				>
 				<FileConfiguration
@@ -1012,6 +1048,42 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\Commands\ExtendedSelectCommand.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\FdoConnection.cpp"
 				>
 				<FileConfiguration
@@ -4798,6 +4870,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\Commands\DescribeSchema.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\DoubleDataReaderCreator.h"
 				>
 			</File>
@@ -4834,6 +4910,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\Commands\ExtendedSelectCommand.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\FdoConnection.h"
 				>
 			</File>

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -77,6 +77,8 @@
 #include "Services/Feature/TransformCache.cpp"
 #include "Services/Feature/Commands/ApplySchema.cpp"
 #include "Services/Feature/Commands/DeleteCommand.cpp"
+#include "Services/Feature/Commands/DescribeSchema.cpp"
+#include "Services/Feature/Commands/ExtendedSelectCommand.cpp"
 #include "Services/Feature/Commands/FeatureManipulationCommand.cpp"
 #include "Services/Feature/Commands/FeatureServiceCommand.cpp"
 #include "Services/Feature/Commands/GetConnectionPropertyValues.cpp"

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -22,24 +22,24 @@
 #include "Services/Feature/FeatureServiceCache.h"
 
 //////////////////////////////////////////////////////////////////
-MgServerApplySchema::MgServerApplySchema()
+MgApplySchema::MgApplySchema()
 {
 }
 
 //////////////////////////////////////////////////////////////////
-MgServerApplySchema::~MgServerApplySchema()
+MgApplySchema::~MgApplySchema()
 {
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-void MgServerApplySchema::ApplySchema(MgResourceIdentifier* resource,
+void MgApplySchema::ApplySchema(MgResourceIdentifier* resource,
     MgFeatureSchema* schema)
 {
     MG_FEATURE_SERVICE_TRY()
 
     if (NULL == resource || NULL == schema)
     {
-        throw new MgNullArgumentException(L"MgServerApplySchema.ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgNullArgumentException(L"MgApplySchema.ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     // Connect to provider
@@ -57,17 +57,17 @@
         {
             // TODO: specify which argument and message, once we have the mechanism
             STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-            throw new MgInvalidOperationException(L"MgServerApplySchema.ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgInvalidOperationException(L"MgApplySchema.ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
         FdoPtr<FdoIDescribeSchema> fdoDecribeSchemaCmd = (FdoIDescribeSchema*) fdoConn->CreateCommand(FdoCommandType_DescribeSchema);
-        CHECKNULL((FdoIDescribeSchema*)fdoDecribeSchemaCmd, L"MgServerApplySchema.ApplySchema");
+        CHECKNULL((FdoIDescribeSchema*)fdoDecribeSchemaCmd, L"MgApplySchema.ApplySchema");
 
         FdoPtr<FdoFeatureSchemaCollection> schemas = fdoDecribeSchemaCmd->Execute();
-        CHECKNULL((FdoFeatureSchemaCollection*)schemas, L"MgServerApplySchema.ApplySchema");
+        CHECKNULL((FdoFeatureSchemaCollection*)schemas, L"MgApplySchema.ApplySchema");
 
         FdoPtr<FdoIApplySchema> fdoApplySchemaCmd = (FdoIApplySchema*)fdoConn->CreateCommand(FdoCommandType_ApplySchema);
-        CHECKNULL((FdoIApplySchema*)fdoApplySchemaCmd, L"MgServerApplySchema.ApplySchema");
+        CHECKNULL((FdoIApplySchema*)fdoApplySchemaCmd, L"MgApplySchema.ApplySchema");
 
         STRING schemaName = schema->GetName();
         FdoPtr<FdoFeatureSchema> fdoOldSchema = schemas->FindItem(schemaName.c_str());

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -24,12 +24,12 @@
 #include "Fdo.h"
 #include "FSDSAX2Parser.h"
 
-class MgServerApplySchema
+class MgApplySchema
 {
 /// Constructors/Destructor
 public:
-    MgServerApplySchema();
-    ~MgServerApplySchema();
+    MgApplySchema();
+    ~MgApplySchema();
 public:
     void ApplySchema(MgResourceIdentifier* resource, MgFeatureSchema* schema);
 };

Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.cpp	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -0,0 +1,1517 @@
+//
+//  Copyright (C) 2004-2011 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 "Services/Feature/FeatureDefs.h"
+#include "DescribeSchema.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/FeatureReader.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "FdoExpressionEngine.h"
+#include "FdoExpressionEngineCopyFilter.h"
+#include "Services/Feature/FeatureServiceCache.h"
+
+//////////////////////////////////////////////////////////////////
+MgDescribeSchema::MgDescribeSchema()
+{
+    m_featureServiceCache = MgFeatureServiceCache::GetInstance();
+}
+
+//////////////////////////////////////////////////////////////////
+MgDescribeSchema::~MgDescribeSchema()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+FdoFeatureSchemaCollection* MgDescribeSchema::DescribeFdoSchema(MgResourceIdentifier* resource,
+    CREFSTRING schemaName, MgStringCollection* classNames, bool& classNameHintUsed)
+{
+    // IMPORTANT INFORMATION
+    // FDO objects cannot be cached as they are not thread safe.
+    // This is not an issue because we create a MapGuide wrapper of this information that is thread safe.
+    FdoPtr<FdoFeatureSchemaCollection> ffsc;
+    ffsc = NULL;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    // Connect to provider
+    Ptr<MgFeatureConnection> connection = new MgFeatureConnection(resource);
+
+    if ((NULL != connection.p) && (connection->IsConnectionOpen()))
+    {
+        // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+        // otherwise it leaves the FDO connection marked as still in use.
+        FdoPtr<FdoIConnection> fdoConn = connection->GetConnection();
+        FdoPtr<FdoIDescribeSchema> fdoCommand = (FdoIDescribeSchema*)fdoConn->CreateCommand(FdoCommandType_DescribeSchema);
+
+        classNameHintUsed = IsClassNameHintUsed(fdoCommand);
+
+        if (!schemaName.empty())
+        {
+            fdoCommand->SetSchemaName(schemaName.c_str());
+        }
+
+        FdoPtr<FdoStringCollection> fdoClassNames = MgFeatureUtil::MgToFdoStringCollection(classNames, false);
+
+        if (NULL != fdoClassNames.p && fdoClassNames->GetCount() > 0)
+        {
+            fdoCommand->SetClassNames(fdoClassNames.p);
+        }
+
+        // Execute the command
+        ffsc = fdoCommand->Execute();
+        CHECKNULL((FdoFeatureSchemaCollection*)ffsc, L"MgDescribeSchema.DescribeFdoSchema");
+
+        // Finished with primary feature source, so now cycle through any secondary sources
+        if (NULL == m_featureSourceCacheItem.p)
+        {
+            m_featureSourceCacheItem = m_featureServiceCache->GetFeatureSource(resource);
+        }
+
+        MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+        CHECKNULL(featureSource, L"MgDescribeSchema.DescribeFdoSchema");
+        MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+        CHECKNULL(extensions, L"MgDescribeSchema.DescribeFdoSchema");
+        int extensionCount = extensions->GetCount();
+
+        for (int i = 0; i < extensionCount; i++)
+        {
+            MdfModel::Extension* extension = extensions->GetAt(i);
+            CHECKNULL(extension, L"MgDescribeSchema.DescribeFdoSchema");
+
+            // Get the extension name
+            STRING extensionName = (STRING)extension->GetName();
+
+            // Determine the number of secondary sources (AttributeRelates)
+            MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
+            CHECKNULL(attributeRelates, L"MgDescribeSchema.DescribeFdoSchema");
+            int nAttributeRelates = attributeRelates->GetCount();
+
+            for (int arIndex = 0; arIndex < nAttributeRelates; arIndex++)
+            {
+                MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(arIndex);
+                CHECKNULL(attributeRelate, L"MgDescribeSchema.DescribeFdoSchema");
+
+                // get the resource id of the secondary feature source
+                STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
+
+                // get the name for the join relationship (attribute relate name)
+                STRING attributeRelateName = (STRING)attributeRelate->GetName();
+
+                // Get the secondary feature class (AttributeClass)
+                STRING attributeClass = (STRING)attributeRelate->GetAttributeClass();
+
+                // Parse the schema name from the classname;
+                STRING secSchemaName, secClassName;
+                MgUtil::ParseQualifiedClassName(attributeClass, secSchemaName, secClassName);
+
+                // Establish connection to provider for secondary feature source
+                Ptr<MgResourceIdentifier> secondaryFeatureSource = new MgResourceIdentifier(secondaryResourceId);
+
+                if (NULL != secondaryFeatureSource)
+                {
+                    FdoPtr<FdoFeatureSchemaCollection> ffsc2;
+                    Ptr<MgFeatureConnection> connection2 = new MgFeatureConnection(secondaryFeatureSource);
+
+                    if ((NULL != connection2.p) && ( connection2->IsConnectionOpen() ))
+                    {
+                        // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+                        // otherwise it leaves the FDO connection marked as still in use.
+                        FdoPtr<FdoIConnection> fdoConn2 = connection2->GetConnection();
+                        // Check whether this command is supported by the provider
+                        FdoPtr<FdoIDescribeSchema> fdoCommand2 = (FdoIDescribeSchema*)fdoConn2->CreateCommand(FdoCommandType_DescribeSchema);
+                        CHECKNULL((FdoIDescribeSchema*)fdoCommand2, L"MgDescribeSchema.DescribeFdoSchema");
+
+                        if (!secSchemaName.empty())
+                        {
+                            fdoCommand2->SetSchemaName(secSchemaName.c_str());
+                        }
+
+                        if (!secClassName.empty())
+                        {
+                            FdoPtr<FdoStringCollection> fdoClassNames2 = FdoStringCollection::Create();
+
+                            fdoClassNames2->Add(secClassName.c_str());
+                            fdoCommand2->SetClassNames(fdoClassNames2.p);
+                        }
+
+                        // Execute the command
+                        ffsc2 = fdoCommand2->Execute();
+                        CHECKNULL((FdoFeatureSchemaCollection*)ffsc2, L"MgDescribeSchema.DescribeFdoSchema");
+
+                        if (!secSchemaName.empty())
+                        {
+                            fdoCommand2->SetSchemaName(secSchemaName.c_str());
+                        }
+
+                        if (!secClassName.empty())
+                        {
+                            FdoPtr<FdoStringCollection> fdoClassNames2 = FdoStringCollection::Create();
+
+                            fdoClassNames2->Add(secClassName.c_str());
+                            fdoCommand2->SetClassNames(fdoClassNames2.p);
+                        }
+
+                        // Extract the schemas from the secondary collection and add them to the main collection
+                        // Get schema count
+                        FdoInt32 cnt = ffsc2->GetCount();
+                        for (FdoInt32 i = 0; i < cnt; i++)
+                        {
+                            FdoPtr<FdoFeatureSchema> ffs = ffsc2->GetItem(i);
+                            STRING fdoSchemaName = (wchar_t*)ffs->GetName();
+
+                            if (fdoSchemaName != secSchemaName)
+                            {
+                                continue;
+                            }
+
+                            // Prefix the schema name with the extension and attribute relate names
+                            STRING modifiedSchemaName;
+                            modifiedSchemaName = L"[" + extensionName + L"]";
+                            modifiedSchemaName += L"[" + attributeRelateName + L"]";
+                            modifiedSchemaName += fdoSchemaName;
+                            FdoString* msn = modifiedSchemaName.c_str();
+                            ffs->SetName(msn);
+
+                            // Add this schema to the collection if it isn't already there
+                            if (!ffsc->Contains(ffs))
+                            {
+                                ffsc->Add(ffs);
+                            }
+                        }
+                    }
+                    else
+                    {
+                        throw new MgConnectionFailedException(L"MgDescribeSchema.DescribeFdoSchema", __LINE__, __WFILE__, NULL, L"", NULL);
+                    }
+                }
+
+            }  // End of the for-loop that iterates thru the secondary sources
+
+        }  // End of for loop that iterates thru the extensions in the feature source
+    }
+    else
+    {
+        throw new MgConnectionFailedException(L"MgDescribeSchema.DescribeFdoSchema", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgDescribeSchema.DescribeFdoSchema")
+
+    return ffsc.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgFeatureSchemaCollection* MgDescribeSchema::DescribeSchema(MgResourceIdentifier* resource,
+    CREFSTRING schemaName, MgStringCollection* classNames, bool serialize)
+{
+    Ptr<MgFeatureSchemaCollection> fsCollection;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    fsCollection = m_featureServiceCache->GetSchemas(resource, schemaName, classNames, serialize);
+
+    if (NULL == fsCollection.p)
+    {
+        fsCollection = new MgFeatureSchemaCollection();
+
+        bool classNameHintUsed = true;
+        FdoPtr<FdoFeatureSchemaCollection> ffsc =
+            DescribeFdoSchema(resource, schemaName, classNames, classNameHintUsed);
+        CHECKNULL(ffsc.p, L"MgDescribeSchema.DescribeSchema");
+
+        // Get schema count
+        FdoInt32 schemaCount = ffsc->GetCount();
+
+        //
+        // A new MgFeatureSchema needs to be created for each primary schema in FDO schemas.
+        //
+
+        Ptr<MgFeatureSchema> schema;
+        Ptr<MgClassDefinitionCollection> classCol;
+
+        for (int nSchemaIndex = 0; nSchemaIndex < schemaCount; nSchemaIndex++)
+        {
+            // Retrieve schema from the collection
+            FdoPtr<FdoFeatureSchema> ffs = ffsc->GetItem(nSchemaIndex);
+            STRING currSchemaName = (wchar_t*)ffs->GetName();
+
+            // Check if this schema is from secondary source which will be prefixed with [ExtensionName][RelationName],
+            // ie [ExtensionName][RelationName]SchemaName
+            if (currSchemaName.find(L"[") == 0)
+            {
+                // Found a schema for secondary source, so just skip over it for now
+                continue;
+            }
+
+            schema = new MgFeatureSchema();
+            classCol = schema->GetClasses();
+
+            // Set the schema name and description
+            FdoStringP fSchemaName = ffs->GetName();
+            schema->SetName(STRING(fSchemaName));
+
+            FdoStringP fSchemaDesc = ffs->GetDescription();
+            schema->SetDescription(STRING(fSchemaDesc));
+
+            // Get all classes for the schema
+            FdoPtr<FdoClassCollection> fcc = ffs->GetClasses();
+            FdoInt32 classCount = fcc->GetCount();
+
+            // Add the primary class definitions to the MgClassDefinitionCollection
+            for (FdoInt32 nClassIndex = 0; nClassIndex < classCount; nClassIndex++)
+            {
+                FdoPtr<FdoClassDefinition> fc = fcc->GetItem(nClassIndex);
+
+                FdoStringP qname = fc->GetQualifiedName();
+                FdoStringP name = fc->GetName();
+
+                if (name != NULL && qname != NULL)
+                {
+                    Ptr<MgClassDefinition> classDefinition = MgFeatureUtil::GetMgClassDefinition(fc, serialize);
+                    classCol->Add(classDefinition);
+                }
+            }
+
+            //
+            // A new MgClassDefinition needs to be created for each extension and added to the MgClassCollection
+            //
+
+            if (NULL == m_featureSourceCacheItem.p)
+            {
+                m_featureSourceCacheItem = m_featureServiceCache->GetFeatureSource(resource);
+            }
+
+            MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+            CHECKNULL(featureSource, L"MgDescribeSchema.DescribeSchema");
+            MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+            CHECKNULL(extensions, L"MgDescribeSchema.DescribeSchema");
+            int extensionCount = extensions->GetCount();
+
+            for (int i = 0; i < extensionCount; i++)
+            {
+                Ptr<MgClassDefinition> extClassDefinition;
+                FdoPtr<FdoClassDefinition> originalClassDef;
+
+                MdfModel::Extension* extension = extensions->GetAt(i);
+                CHECKNULL(extension, L"MgDescribeSchema.DescribeSchema");
+
+                // Get the extension name
+                STRING extensionName = (STRING)extension->GetName();
+
+                // get FeatureClass element - this tells us which class is extended (SchemaName:ClassName)
+                STRING featureClass = (STRING)extension->GetFeatureClass();
+
+                // Parse the schemaName from the className
+                STRING primSchemaName, primClassName;
+                MgUtil::ParseQualifiedClassName(featureClass, primSchemaName, primClassName);
+
+                if (currSchemaName != primSchemaName)
+                {
+                    continue;
+                }
+
+                // Cycle thru FDO schemas for schemaName.
+                for (int nIndex = 0; nIndex < schemaCount; nIndex++)
+                {
+                    FdoPtr<FdoFeatureSchema> ffs = ffsc->GetItem(nIndex);
+                    STRING currSchemaName = (wchar_t*)ffs->GetName();
+
+                    // Check if this schema is from secondary source
+                    if (currSchemaName.find(L"[") == 0)
+                    {
+                        // Found a schema for secondary source, so just skip over it
+                        continue;
+                    }
+
+                    // get the class collection for this schema
+                    FdoPtr<FdoClassCollection> fcc = ffs->GetClasses();
+                    FdoInt32 classCount = fcc->GetCount();
+
+                    for (int nClassIndex = 0; nClassIndex < classCount; nClassIndex++)
+                    {
+                        originalClassDef = fcc->GetItem(nClassIndex);
+
+                        STRING className = (wchar_t*)originalClassDef->GetName();
+                        if (className == primClassName)
+                        {
+                            // get the class definition
+                            extClassDefinition = MgFeatureUtil::GetMgClassDefinition(originalClassDef, serialize);
+                            break;
+                        }
+                    }
+
+                    if(NULL != extClassDefinition)
+                    {
+                        break;
+                    }
+                }
+
+                if (NULL == extClassDefinition)
+                {
+                    continue;
+                }
+
+                CalculatedPropertyCollection* calcPropsColl = extension->GetCalculatedProperties();
+                if (calcPropsColl != NULL && calcPropsColl->GetCount() != 0)
+                {
+                    FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
+                    for (int idx = 0; idx < calcPropsColl->GetCount(); idx++)
+                    {
+                        CalculatedProperty* calcProp = calcPropsColl->GetAt(idx);
+                        FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
+                        FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
+                        idList->Add(idfCalc);
+                    }
+
+                    Ptr<MgPropertyDefinitionCollection> mpdcLocal = extClassDefinition->GetProperties();
+                    for(int idx = 0; idx < calcPropsColl->GetCount(); idx++)
+                    {
+                        CalculatedProperty* calcProp = calcPropsColl->GetAt(idx);
+                        if (calcProp != NULL)
+                        {
+                            MdfString nameExpr = calcProp->GetName();
+                            MdfString valueExpr = calcProp->GetExpression();
+                            if (nameExpr.size() != 0 && valueExpr.size() != 0)
+                            {
+                                FdoPropertyType retPropType = FdoPropertyType_DataProperty;
+                                FdoDataType retDataType = FdoDataType_Double;
+                                FdoPtr<FdoExpression> expr = FdoExpression::Parse(valueExpr.c_str());
+                                FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expr, idList);
+                                FdoExpressionEngine::GetExpressionType(originalClassDef, expandedExpression, retPropType, retDataType);
+                                if (retPropType == FdoPropertyType_DataProperty)
+                                {
+                                    STRING namePropStr = STRING(nameExpr.c_str());
+                                    Ptr<MgDataPropertyDefinition> propDefExpr = new MgDataPropertyDefinition(namePropStr);
+                                    propDefExpr->SetDataType(MgFeatureUtil::GetMgPropertyType(retDataType));
+                                    propDefExpr->SetNullable(true);
+                                    propDefExpr->SetReadOnly(true);
+                                    propDefExpr->SetAutoGeneration(false);
+                                    mpdcLocal->Add(propDefExpr);
+                                }
+                            }
+                        }
+                    }
+                }
+                //
+                // Finished adding primary class properties to the extension class definition
+                // Now add the secondary class properties
+                //
+
+                // Determine the number of secondary sources (AttributeRelates)
+                MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
+                CHECKNULL(attributeRelates, L"MgDescribeSchema.DescribeSchema");
+                int nAttributeRelateCount = attributeRelates->GetCount();
+
+                for (int arIndex = 0; arIndex < nAttributeRelateCount; arIndex++)
+                {
+                    // get the attribute relate
+                    MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(arIndex);
+                    CHECKNULL(attributeRelate, L"MgDescribeSchema.DescribeSchema");
+
+                    // Get the name of the secondary feature class (AttributeClass)
+                    STRING attributeClass = (STRING)attributeRelate->GetAttributeClass();
+
+                    // Parse the schema name from the class name;
+                    STRING secSchemaName, secClassName;
+                    MgUtil::ParseQualifiedClassName(attributeClass, secSchemaName, secClassName);
+
+                    // Get the relation name
+                    STRING relationName = (STRING)attributeRelate->GetName();
+
+                    // Get the attributeName delimiter ( if none specified, default will be "" (blank) )
+                    STRING attributeNameDelimiter = (STRING)attributeRelate->GetAttributeNameDelimiter();
+
+                    // Get the resource id of the secondary feature source
+                    STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
+
+                    // Establish connection to provider for secondary feature source
+                    Ptr<MgResourceIdentifier> secondaryFeatureSource = new MgResourceIdentifier(secondaryResourceId);
+                    if (NULL != secondaryFeatureSource)
+                    {
+                        FdoPtr<FdoFeatureSchemaCollection> ffsc2;
+                        Ptr<MgFeatureConnection> connection2 = new MgFeatureConnection(secondaryFeatureSource);
+
+                        if ((NULL != connection2.p) && ( connection2->IsConnectionOpen() ))
+                        {
+                            // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+                            // otherwise it leaves the FDO connection marked as still in use.
+                            FdoPtr<FdoIConnection> fdoConn2 = connection2->GetConnection();
+                            // Get the schema collection for the secondary resource
+                            FdoPtr<FdoIDescribeSchema> fdoCommand2  = (FdoIDescribeSchema*)fdoConn2->CreateCommand(FdoCommandType_DescribeSchema);
+                            CHECKNULL((FdoIDescribeSchema*)fdoCommand2, L"MgDescribeSchema.DescribeSchema");
+
+                            if (!secSchemaName.empty())
+                            {
+                                fdoCommand2->SetSchemaName(secSchemaName.c_str());
+                            }
+
+                            if (!secClassName.empty())
+                            {
+                                FdoPtr<FdoStringCollection> fdoClassNames2 = FdoStringCollection::Create();
+
+                                fdoClassNames2->Add(secClassName.c_str());
+                                fdoCommand2->SetClassNames(fdoClassNames2.p);
+                            }
+
+                            // Execute the command
+                            ffsc2 = fdoCommand2->Execute();
+                            CHECKNULL((FdoFeatureSchemaCollection*)ffsc2, L"MgDescribeSchema.DescribeSchema");
+
+                            int nSecSchemaCnt = (int)ffsc2->GetCount();
+
+                            // cycle thru FdoFeatureSchemaCollection for secSchemaName
+                            for (int nSecSchemaIndex = 0; nSecSchemaIndex < nSecSchemaCnt; nSecSchemaIndex++)
+                            {
+                                // retrieve the schema
+                                FdoPtr<FdoFeatureSchema> ffs = ffsc2->GetItem(nSecSchemaIndex);
+                                STRING fdoSchemaName = (wchar_t*)ffs->GetName();
+
+                                if (fdoSchemaName != secSchemaName)
+                                {
+                                    continue;
+                                }
+
+                                // get the class collection for schema
+                                FdoPtr<FdoClassCollection> fcc = ffs->GetClasses();
+                                FdoInt32 classCount = fcc->GetCount();
+
+                                // cycle thru class collection for secClassName
+                                for (int nClassIndex = 0; nClassIndex < classCount; nClassIndex++)
+                                {
+                                    Ptr<MgPropertyDefinitionCollection> mpdc = extClassDefinition->GetProperties();
+
+                                    FdoPtr<FdoClassDefinition> fc = fcc->GetItem(nClassIndex);
+
+                                    STRING qualifiedName = (const wchar_t*)fc->GetQualifiedName();
+                                    STRING className = (wchar_t*)fc->GetName();
+
+                                    if (className != secClassName)
+                                    {
+                                        continue;
+                                    }
+
+                                    // Set the parent name for the secondary class definition
+                                    FdoPtr<FdoSchemaElement> parent = fc->GetParent();
+                                    if (!secSchemaName.empty())
+                                    {
+                                        parent->SetName(secSchemaName.c_str());
+                                    }
+
+                                    // get the secondary class definition
+                                    Ptr<MgClassDefinition> classDefinition = MgFeatureUtil::GetMgClassDefinition(fc, serialize);
+
+                                    // retrieve the secondary properties and prefix them with the relation name
+                                    Ptr<MgPropertyDefinitionCollection> mpdc2 = classDefinition->GetProperties();
+                                    INT32 mpdc2Count = mpdc2->GetCount();
+
+                                    // Prefix the secondary properties with relationName and add to the extClassDefinition
+                                    for (INT32 secPropIndex = 0; secPropIndex < mpdc2Count; secPropIndex++)
+                                    {
+                                        Ptr<MgPropertyDefinition> propDef = mpdc2->GetItem(secPropIndex);
+                                        if ( MgFeaturePropertyType::GeometricProperty != propDef->GetPropertyType()
+                                            && MgFeaturePropertyType::RasterProperty != propDef->GetPropertyType() )
+                                        {
+                                            STRING secPropName = propDef->GetName();
+                                            secPropName = relationName + attributeNameDelimiter + secPropName;
+                                            propDef->SetName(secPropName);
+                                            mpdc->Add(propDef);
+                                        }
+                                    }
+
+                                    break;
+
+                                }  // end loop thru secondary class collection
+
+                                break;
+
+                            }  // end loop thru secondary schemas
+                        }
+                        else
+                        {
+                            throw new MgConnectionFailedException(L"MgDescribeSchema.DescribeSchema", __LINE__, __WFILE__, NULL, L"", NULL);
+                        }
+
+                    }  // end if (NULL != secFeatureSource)
+
+                }  // end loop thru all attribute relates (joins)
+
+                if (!extensionName.empty())
+                {
+                    extClassDefinition->SetName(extensionName);
+                }
+
+                // Add the extension class definition to the MgClassDefinitionCollection
+                classCol->Add(extClassDefinition);
+
+            }  // Repeat for all extensions
+
+            // Add the schema to the MgFeatureSchemaCollection
+            fsCollection->Add(schema);
+
+        }  // End loop thru all schemas
+
+        m_featureServiceCache->SetSchemas(resource, schemaName, classNames, serialize, fsCollection.p);
+    }
+    else
+    {
+        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+    }
+
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgDescribeSchema.DescribeSchema")
+
+    return fsCollection.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Executes the describe schema command and serializes the schema to XML
+///
+STRING MgDescribeSchema::DescribeSchemaAsXml(MgResourceIdentifier* resource,
+    CREFSTRING schemaName, MgStringCollection* classNames)
+{
+    STRING schemaXml;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    schemaXml = m_featureServiceCache->GetSchemaXml(resource, schemaName, classNames);
+
+    if (schemaXml.empty())
+    {
+        MgStringCollection* classNameCol = NULL;
+
+        // Since the FDO provider does not know about the join information,
+        // get the full schema if the feature source has joins.
+        if (CheckExtendedFeatureClasses(resource, classNames))
+        {
+            schemaXml = m_featureServiceCache->GetSchemaXml(resource, schemaName, NULL);
+        }
+        else
+        {
+            classNameCol = classNames;
+        }
+
+        if (schemaXml.empty())
+        {
+            // The schema XML can be retrieved from either the serialized
+            // schemas or the unserialized ones. So, try to get the serialized
+            // schemas from the cache first then the unserialized ones later.
+            Ptr<MgFeatureSchemaCollection> schemas = m_featureServiceCache->GetSchemas(
+                resource, schemaName, classNameCol, true);
+
+            if (NULL == schemas.p)
+            {
+                schemas = DescribeSchema(resource, schemaName, classNameCol, false);
+            }
+            else
+            {
+                //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+            }
+
+            // Get the schema XML.
+            schemaXml = SchemaToXml(schemas);
+
+            m_featureServiceCache->SetSchemaXml(resource, schemaName, classNameCol, schemaXml);
+        }
+        else
+        {
+            //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+        }
+    }
+    else
+    {
+        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+    }
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgDescribeSchema.DescribeSchemaAsXml", resource)
+
+    return schemaXml;
+}
+
+
+//////////////////////////////////////////////////////////////////
+// Converts MgFeatureSchemaCollection to XML
+STRING MgDescribeSchema::SchemaToXml(MgFeatureSchemaCollection* schema)
+{
+    STRING xmlSchema;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    if (NULL == schema)
+    {
+        throw new MgNullArgumentException(L"MgDescribeSchema.SchemaToXml", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    CHECKNULL((MgFeatureSchemaCollection*)schema, L"MgDescribeSchema.SchemaToXml");
+
+    FdoPtr<FdoFeatureSchemaCollection> fdoSchemaCol = MgFeatureUtil::GetFdoFeatureSchemaCollection(schema);
+
+    xmlSchema = GetSerializedXml(fdoSchemaCol);
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgDescribeSchema.SchemaToXml")
+
+    return xmlSchema;
+}
+
+//////////////////////////////////////////////////////////////////
+// Converts MgFeatureSchemaCollection to XML with specified namespacePrefix and namespaceURL (Just used for OGC WFS certification)
+STRING MgDescribeSchema::SchemaToXml(MgFeatureSchemaCollection* schema, CREFSTRING namespacePrefix, CREFSTRING namespaceUrl)
+{
+    STRING xmlSchema;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    if (NULL == schema)
+    {
+        throw new MgNullArgumentException(L"MgDescribeSchema.SchemaToXml", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    CHECKNULL((MgFeatureSchemaCollection*)schema, L"MgDescribeSchema.SchemaToXml");
+
+    FdoPtr<FdoFeatureSchemaCollection> fdoSchemaCol = MgFeatureUtil::GetFdoFeatureSchemaCollection(schema);
+
+    FdoPtr<FdoXmlFlags> flags = FdoXmlFlags::Create();
+
+    if(!namespacePrefix.empty() && !namespaceUrl.empty())
+    {
+        FdoPtr<FdoPhysicalSchemaMappingCollection> fdoPhysicalSchemaMappingCol = FdoPhysicalSchemaMappingCollection::Create();
+        for(int i = 0; i<fdoSchemaCol->GetCount(); i++)
+        {
+            FdoPtr<FdoFeatureSchema> fdoSchema = fdoSchemaCol->GetItem(i);
+            FdoPtr<FdoXmlSchemaMapping> fdoSchemaMapping = FdoXmlSchemaMapping::Create(fdoSchema->GetName());
+            fdoSchemaMapping->SetTargetNamespacePrefix(namespacePrefix.c_str());
+            fdoSchemaMapping->SetTargetNamespace(namespaceUrl.c_str());
+            fdoPhysicalSchemaMappingCol->Add(fdoSchemaMapping);
+        }
+        flags->SetSchemaMappings(fdoPhysicalSchemaMappingCol);
+    }
+
+
+    xmlSchema = GetSerializedXml(fdoSchemaCol,flags);
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgDescribeSchema.SchemaToXml")
+
+    return xmlSchema;
+}
+
+//////////////////////////////////////////////////////////////////
+MgFeatureSchemaCollection* MgDescribeSchema::XmlToSchema(CREFSTRING xml)
+{
+    Ptr<MgFeatureSchemaCollection> mgSchemaCol;
+
+    MG_FEATURE_SERVICE_TRY()
+    mgSchemaCol = new MgFeatureSchemaCollection();
+
+    string mbString = MgUtil::WideCharToMultiByte(xml);
+
+    size_t len = mbString.length();
+
+    FdoByte* gisBytes = (FdoByte*) mbString.c_str();
+
+    FdoPtr<FdoIoMemoryStream> stream = FdoIoMemoryStream::Create();
+    stream->Write(gisBytes, (FdoSize)len);
+
+    FdoPtr<FdoFeatureSchemaCollection> fdoSchemaCol = FdoFeatureSchemaCollection::Create((FdoSchemaElement*)NULL);
+    stream->Reset();
+    fdoSchemaCol->ReadXml(stream);
+
+    // Get schema count
+    FdoInt32 cnt = fdoSchemaCol->GetCount();
+    for (FdoInt32 i = 0; i < cnt; i++)
+    {
+        FdoPtr<FdoFeatureSchema> fdoSchema = fdoSchemaCol->GetItem(i);
+        FdoStringP name = fdoSchema->GetName();
+        CHECKNULL(name, L"MgDescribeSchema.XmlToSchema");
+
+        FdoStringP description = fdoSchema->GetDescription();
+
+        STRING tmpName(name);
+        STRING tmpDesc(description);
+
+        Ptr<MgFeatureSchema> mgSchema = new MgFeatureSchema(tmpName, tmpDesc);
+        Ptr<MgClassDefinitionCollection> classCol = mgSchema->GetClasses();
+
+        // Get all classes for a schema
+        FdoPtr<FdoClassCollection> fdoClassCol = fdoSchema->GetClasses();
+        FdoInt32 classCount = fdoClassCol->GetCount();
+
+        for (FdoInt32 j = 0; j < classCount; j++)
+        {
+            FdoPtr<FdoClassDefinition> fdoClassDef = fdoClassCol->GetItem(j);
+            // TODO: Should we return qualified or non-qualified name
+            FdoStringP qname = fdoClassDef->GetQualifiedName();
+            FdoStringP name = fdoClassDef->GetName();
+
+            if (name != NULL && qname != NULL)
+            {
+                Ptr<MgClassDefinition> classDefinition = MgFeatureUtil::GetMgClassDefinition(fdoClassDef, true);
+                classCol->Add(classDefinition);
+            }
+        }
+        mgSchemaCol->Add(mgSchema);
+    }
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgDescribeSchema.XmlToSchema")
+
+    return mgSchemaCol.Detach();
+}
+
+
+//////////////////////////////////////////////////////////////////
+STRING MgDescribeSchema::GetSerializedXml(FdoFeatureSchemaCollection* fdoSchemaCol)
+{
+    STRING serializedXml;
+
+    MG_FEATURE_SERVICE_TRY()
+    CHECKNULL(fdoSchemaCol, L"MgDescribeSchema.GetSerializedXml");
+
+    FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
+    CHECKNULL((FdoIoMemoryStream*)fmis, L"MgDescribeSchema.GetSerializedXml");
+
+    // Write to memory stream
+    fdoSchemaCol->WriteXml(fmis);
+    fmis->Reset(); // TODO: We should not be calling reset here. A defect in FDO should be fixed.
+
+    FdoInt64 len = fmis->GetLength();
+    FdoByte *bytes = new FdoByte[(size_t)len];
+    CHECKNULL(bytes, L"MgDescribeSchema.GetSerializedXml");
+
+    fmis->Read(bytes, (FdoSize)len);
+
+    Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)bytes, (INT32)len);
+    byteSource->SetMimeType(MgMimeType::Xml);
+    Ptr<MgByteReader> byteReader = byteSource->GetReader();
+
+    string out = MgUtil::GetTextFromReader(byteReader);
+    serializedXml = MgUtil::MultiByteToWideChar(out);
+
+    delete [] bytes;
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgDescribeSchema.GetSerializedXml")
+
+    return serializedXml;
+}
+
+//////////////////////////////////////////////////////////////////
+STRING MgDescribeSchema::GetSerializedXml(FdoFeatureSchemaCollection* fdoSchemaCol, FdoXmlFlags* flags)
+{
+    STRING serializedXml;
+
+    MG_FEATURE_SERVICE_TRY()
+    CHECKNULL(fdoSchemaCol, L"MgDescribeSchema.GetSerializedXml");
+
+    FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
+    CHECKNULL((FdoIoMemoryStream*)fmis, L"MgDescribeSchema.GetSerializedXml");
+
+    // Write to memory stream
+    fdoSchemaCol->WriteXml(fmis,flags);
+    fmis->Reset(); // TODO: We should not be calling reset here. A defect in FDO should be fixed.
+
+    FdoInt64 len = fmis->GetLength();
+    FdoByte *bytes = new FdoByte[(size_t)len];
+    CHECKNULL(bytes, L"MgDescribeSchema.GetSerializedXml");
+
+    fmis->Read(bytes, (FdoSize)len);
+
+    Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)bytes, (INT32)len);
+    byteSource->SetMimeType(MgMimeType::Xml);
+    Ptr<MgByteReader> byteReader = byteSource->GetReader();
+
+    string out = MgUtil::GetTextFromReader(byteReader);
+    serializedXml = MgUtil::MultiByteToWideChar(out);
+
+    delete [] bytes;
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgDescribeSchema.GetSerializedXml")
+
+    return serializedXml;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgStringCollection* MgDescribeSchema::GetSchemas(MgResourceIdentifier* resource)
+{
+    Ptr<MgStringCollection> schemaNames;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    schemaNames = m_featureServiceCache->GetSchemaNames(resource);
+
+    if (NULL == schemaNames.p)
+    {
+        // Connect to provider.
+        Ptr<MgFeatureConnection> connection = new MgFeatureConnection(resource);
+
+        if ((NULL != connection.p) && (connection->IsConnectionOpen()))
+        {
+            if (connection->SupportsCommand((INT32)FdoCommandType_GetSchemaNames))
+            {
+                //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+
+                // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up
+                // before the parent object, otherwise it leaves the FDO connection marked as still in use.
+                FdoPtr<FdoIConnection> fdoConn = connection->GetConnection();
+                FdoPtr<FdoIGetSchemaNames> fdoCommand = (FdoIGetSchemaNames*)fdoConn->CreateCommand(FdoCommandType_GetSchemaNames);
+                CHECKNULL(fdoCommand.p, L"MgDescribeSchema.GetSchemas");
+
+                // Execute the command.
+                FdoPtr<FdoStringCollection> schemas = fdoCommand->Execute();
+                CHECKNULL(schemas.p, L"MgDescribeSchema.GetSchemas");
+
+                // Get the schema names.
+                schemaNames = MgFeatureUtil::FdoToMgStringCollection(schemas.p, false);
+            }
+            else // Fall back on using the DescribeSchema API.
+            {
+                // Release the connection so that it can be reused via the DescribeSchema API.
+                connection = NULL;
+
+                // The schema names can be retrieved from either the serialized
+                // schemas or the unserialized ones. So, try to get the serialized
+                // schemas from the cache first then the unserialized ones later.
+                Ptr<MgFeatureSchemaCollection> schemas = m_featureServiceCache->GetSchemas(
+                    resource, L"", NULL, true);
+
+                if (NULL == schemas.p)
+                {
+                    schemas = DescribeSchema(resource, L"", NULL, false);
+                }
+                else
+                {
+                    //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+                }
+
+                // Get the schema names.
+                schemaNames = GetSchemaNames(schemas.p);
+            }
+        }
+        else
+        {
+            throw new MgConnectionFailedException(L"MgDescribeSchema.GetSchemas",
+                __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        m_featureServiceCache->SetSchemaNames(resource, schemaNames.p);
+    }
+    else
+    {
+        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+    }
+
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgDescribeSchema.GetSchemas")
+
+    return schemaNames.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgStringCollection* MgDescribeSchema::GetClasses(MgResourceIdentifier* resource, CREFSTRING schemaName)
+{
+    Ptr<MgStringCollection> classNames;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    classNames = m_featureServiceCache->GetClassNames(resource, schemaName);
+
+    if (NULL == classNames.p)
+    {
+        // Connect to provider.
+        Ptr<MgFeatureConnection> connection = new MgFeatureConnection(resource);
+
+        if ((NULL != connection.p) && (connection->IsConnectionOpen()))
+        {
+            // Fall back on using the DescribeSchema API to retrieve the class names
+            // if the FDO provider does not support the GetClassNames command
+            // or the feature source has joins.
+            bool useSchema = true;
+
+            if (connection->SupportsCommand((INT32)FdoCommandType_GetClassNames))
+            {
+                if (NULL == m_featureSourceCacheItem.p)
+                {
+                    m_featureSourceCacheItem = m_featureServiceCache->GetFeatureSource(resource);
+                }
+
+                MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+                CHECKNULL(featureSource, L"MgDescribeSchema.GetClasses");
+                MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+                CHECKNULL(extensions, L"MgDescribeSchema.GetClasses");
+
+                useSchema = (extensions->GetCount() > 0);
+            }
+
+            // TODO: The performance could be improved by getting the
+            //       class names from the primary and secondary feature
+            //       sources separately, then combining the results together.
+            if (useSchema)
+            {
+                // Release the connection so that it can be reused via the DescribeSchema API.
+                connection = NULL;
+
+                // The class names can be retrieved from either the serialized
+                // schemas or the unserialized ones. So, try to get the serialized
+                // schemas from the cache first then the unserialized ones later.
+                Ptr<MgFeatureSchemaCollection> schemas = m_featureServiceCache->GetSchemas(
+                    resource, schemaName, NULL, true);
+
+                if (NULL == schemas.p)
+                {
+                    schemas = DescribeSchema(resource, schemaName, NULL, false);
+                }
+                else
+                {
+                    //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+                }
+
+                // Get the class names.
+                classNames = GetClassNames(schemas.p, schemaName);
+            }
+            else
+            {
+                //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+
+                // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up
+                // before the parent object, otherwise it leaves the FDO connection marked as still in use.
+                FdoPtr<FdoIConnection> fdoConn = connection->GetConnection();
+                FdoPtr<FdoIGetClassNames> fdoCommand = (FdoIGetClassNames*)fdoConn->CreateCommand(FdoCommandType_GetClassNames);
+                CHECKNULL(fdoCommand.p, L"MgDescribeSchema.GetClasses");
+
+                if (!schemaName.empty())
+                {
+                    fdoCommand->SetSchemaName(schemaName.c_str());
+                }
+
+                // Execute the command.
+                FdoPtr<FdoStringCollection> classes = fdoCommand->Execute();
+                CHECKNULL(classes.p, L"MgDescribeSchema.GetClasses");
+
+                // Get the class names.
+                classNames = MgFeatureUtil::FdoToMgStringCollection(classes.p, false);
+            }
+        }
+        else
+        {
+            throw new MgConnectionFailedException(L"MgDescribeSchema.GetClasses",
+                __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        m_featureServiceCache->SetClassNames(resource, schemaName, classNames.p);
+    }
+    else
+    {
+        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+    }
+
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgDescribeSchema.GetClasses")
+
+    return classNames.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgClassDefinition* MgDescribeSchema::GetClassDefinition(  MgResourceIdentifier* resource,
+                                                                CREFSTRING schemaName,
+                                                                CREFSTRING className,
+                                                                bool serialize)
+{
+    Ptr<MgClassDefinition> classDefinition;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    if (className.empty())
+    {
+        throw new MgClassNotFoundException(
+            L"MgDescribeSchema.GetClassDefinition",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    classDefinition = m_featureServiceCache->GetClassDefinition(resource, schemaName, className);
+
+    if (NULL == classDefinition.p)
+    {
+        Ptr<MgStringCollection> classNames;
+
+        // Since the FDO provider does not know about the join information,
+        // use the full schema to retrieve the class definition if the feature source has joins.
+        if (!CheckExtendedFeatureClass(resource, className))
+        {
+            classNames = new MgStringCollection();
+            classNames->Add(className);
+        }
+
+        Ptr<MgFeatureSchemaCollection> schemas = DescribeSchema(
+            resource, schemaName, classNames, serialize);
+
+        // Get the class definition.
+        classDefinition = GetClassDefinition(schemas.p, schemaName, className);
+
+        if (NULL == classDefinition.p)
+        {
+            throw new MgClassNotFoundException(
+                L"MgDescribeSchema.GetClassDefinition",
+                __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        else
+        {
+            m_featureServiceCache->SetClassDefinition(resource, schemaName, className, classDefinition.p);
+        }
+    }
+    else
+    {
+        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+    }
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgDescribeSchema.GetClassDefinition", resource)
+
+    return classDefinition.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Returns the collection of identity properties for the specified class.
+/// If the schemaName is empty, then the className needs to be fully qualified.
+///
+MgClassDefinitionCollection* MgDescribeSchema::GetIdentityProperties(
+    MgResourceIdentifier* resource, CREFSTRING schemaName, MgStringCollection* classNames)
+{
+    Ptr<MgClassDefinitionCollection> classDefs = new MgClassDefinitionCollection();
+
+    MG_FEATURE_SERVICE_TRY()
+
+    if (NULL == classNames || classNames->GetCount() == 0)
+    {
+        throw new MgClassNotFoundException(
+            L"MgDescribeSchema.GetIdentityProperties",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    Ptr<MgStringCollection> uncachedClasses = new MgStringCollection();
+
+    // Try pulling identity properties directly from the MapGuide cache first
+    for (int i = 0; i < classNames->GetCount(); i++)
+    {
+        STRING className = classNames->GetItem(i);
+        Ptr<MgPropertyDefinitionCollection> idProps = m_featureServiceCache->GetClassIdentityProperties(resource, schemaName, className);
+        if (NULL != idProps.p)
+        {
+            // Identity properties found.  Add class to collection
+            Ptr<MgClassDefinition> classDef = new MgClassDefinition();
+            classDef->SetName(className);
+            Ptr<MgPropertyDefinitionCollection> propDefs = classDef->GetIdentityProperties();
+            for (int j = 0; j < idProps->GetCount(); j++)
+            {
+                Ptr<MgPropertyDefinition> idProp = idProps->GetItem(j);
+                propDefs->Add(idProp);
+            }
+            classDefs->Add(classDef);
+        }
+        else
+        {
+            uncachedClasses->Add(className);
+        }
+    }
+
+    if (uncachedClasses->GetCount() > 0)
+    {
+        // We did not find all the classes in our cache.  Query Fdo for them.
+
+        // Since FDO does not know about joined feature sources,
+        // use full schema to get the class identity properties
+        // if any class is extended.
+        bool classNameHintUsed = true;
+        Ptr<MgStringCollection> emptyNames = new MgStringCollection();
+        MgStringCollection* getNames = uncachedClasses;
+        for (int i = 0; i < uncachedClasses->GetCount(); i++)
+        {
+            if (CheckExtendedFeatureClass(resource, uncachedClasses->GetItem(i)))
+            {
+                getNames = emptyNames;
+                classNameHintUsed = false;
+                break;
+            }
+        }
+
+        // IMPORTANT INFORMATION
+        // FDO objects cannot be cached as they are not thread safe.
+        // This is not an issue because we create a MapGuide wrapper of this information that is thread safe.
+        FdoPtr<FdoFeatureSchemaCollection> fdoSchemas;
+        fdoSchemas = NULL;
+
+        // The class identity properties can be retrieved from either the serialized
+        // schemas or the unserialized ones. So, try to get the serialized
+        // schemas from the cache first then the unserialized ones later.
+        Ptr<MgFeatureSchemaCollection> mgSchemas = m_featureServiceCache->GetSchemas(
+            resource, schemaName, getNames, true);
+
+        if (NULL == mgSchemas.p)
+        {
+            mgSchemas = m_featureServiceCache->GetSchemas(
+                resource, schemaName, getNames, false);
+        }
+
+        if (NULL == mgSchemas.p)
+        {
+            fdoSchemas = DescribeFdoSchema(resource, schemaName, getNames, classNameHintUsed);
+        }
+        else
+        {
+            //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
+            fdoSchemas = MgFeatureUtil::GetFdoFeatureSchemaCollection(mgSchemas.p);
+        }
+
+        for (int j = 0; j < uncachedClasses->GetCount(); j++)
+        {
+            STRING className = uncachedClasses->GetItem(j);
+
+            // #1403: Identity properties or not, the class itself should be always returned
+
+            // Add class to collection
+            Ptr<MgClassDefinition> classDef = new MgClassDefinition();
+            classDef->SetName(className);
+
+            // Get the class identity properties.
+            Ptr<MgPropertyDefinitionCollection> idProps = GetIdentityProperties(fdoSchemas.p, resource, schemaName, className);
+            if (NULL != idProps.p && idProps->GetCount() > 0)
+            {
+                m_featureServiceCache->SetClassIdentityProperties(resource, schemaName, className, idProps.p);
+
+                Ptr<MgPropertyDefinitionCollection> propDefs = classDef->GetIdentityProperties();
+                for (int k = 0; k < idProps->GetCount(); k++)
+                {
+                    Ptr<MgPropertyDefinition> idProp = idProps->GetItem(k);
+                    propDefs->Add(idProp);
+                }
+            }
+
+            classDefs->Add(classDef);
+        }
+    }
+
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgDescribeSchema.GetIdentityProperties", resource)
+
+    return classDefs.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool MgDescribeSchema::GetIdentityProperties(CREFSTRING className,
+    FdoClassCollection* classCol, MgPropertyDefinitionCollection* idProps)
+{
+    bool hasIdProps = false;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    if (NULL == classCol || NULL == idProps)
+    {
+        throw new MgNullArgumentException(L"MgDescribeSchema.GetIdentityProperties",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    FdoInt32 classCount = classCol->GetCount();
+
+    for (FdoInt32 i = 0; i < classCount; ++i)
+    {
+        FdoPtr<FdoClassDefinition> classDef = classCol->GetItem(i);
+        FdoStringP qname = classDef->GetQualifiedName();
+        FdoStringP name = classDef->GetName();
+
+        // Class name can be either fully qualified or non-qualified name.
+        int idx1 = ::wcscmp(className.c_str(), qname);
+        int idx2 = ::wcscmp(className.c_str(), name);
+
+        if (0 == idx1 || 0 == idx2)
+        {
+            // Get identity properties for only the primary source (ie extensionName is blank).
+            STRING qualifiedName = (const wchar_t*)qname;
+            STRING::size_type nExtensionStart = qualifiedName.find(L"[");
+
+            if (STRING::npos == nExtensionStart)
+            {
+                // Retrieve identity properties from FDO.
+                FdoPtr<FdoDataPropertyDefinitionCollection> propDefCol =
+                    classDef->GetIdentityProperties();
+
+                MgFeatureUtil::GetClassProperties(idProps, propDefCol);
+                hasIdProps = true;
+                break;
+            }
+        }
+    }
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgDescribeSchema.GetIdentityProperties")
+
+    return hasIdProps;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Determine whether or not the provider supports the Class Name hint for the
+/// Describe Schema command.
+///
+bool MgDescribeSchema::IsClassNameHintUsed(FdoIDescribeSchema* fdoCommand)
+{
+    CHECKNULL(fdoCommand, L"MgDescribeSchema.IsClassNameHintUsed");
+
+    FdoPtr<FdoStringCollection> classNames = fdoCommand->GetClassNames();
+    bool classNameHintUsed = (NULL != classNames.p);
+
+    return classNameHintUsed;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgStringCollection* MgDescribeSchema::GetSchemaNames(MgFeatureSchemaCollection* schemas)
+{
+    CHECKNULL(schemas, L"MgDescribeSchema.GetSchemaNames");
+
+    Ptr<MgStringCollection> schemaNames = new MgStringCollection();
+    INT32 schemaCount = schemas->GetCount();
+
+    for (INT32 i = 0; i < schemaCount; ++i)
+    {
+        Ptr<MgFeatureSchema> currSchema = schemas->GetItem(i);
+        STRING currSchemaName = currSchema->GetName();
+
+        if (!currSchemaName.empty())
+        {
+            schemaNames->Add(currSchemaName);
+        }
+    }
+
+    return schemaNames.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgStringCollection* MgDescribeSchema::GetClassNames(MgFeatureSchemaCollection* schemas, CREFSTRING schemaName)
+{
+    CHECKNULL(schemas, L"MgDescribeSchema.GetClassNames");
+
+    Ptr<MgStringCollection> classNames = new MgStringCollection();
+    INT32 schemaCount = schemas->GetCount();
+
+    for (INT32 i = 0; i < schemaCount; ++i)
+    {
+        Ptr<MgFeatureSchema> currSchema = schemas->GetItem(i);
+        STRING currSchemaName = currSchema->GetName();
+        bool schemaNameFound = false;
+
+        if (schemaName.empty() || (schemaNameFound = (schemaName == currSchemaName)))
+        {
+            Ptr<MgClassDefinitionCollection> currClasses = currSchema->GetClasses();
+            INT32 classCount = currClasses->GetCount();
+
+            for (INT32 j = 0; j < classCount; ++j)
+            {
+                Ptr<MgClassDefinition> currClass = currClasses->GetItem(j);
+                STRING currClassName = currClass->GetName();
+                STRING currQualifiedName;
+
+                MgUtil::FormatQualifiedClassName(currSchemaName, currClassName, currQualifiedName);
+                classNames->Add(currQualifiedName);
+            }
+        }
+
+        if (schemaNameFound)
+        {
+            break;
+        }
+    }
+
+    return classNames.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgClassDefinition* MgDescribeSchema::GetClassDefinition(MgFeatureSchemaCollection* schemas, CREFSTRING schemaName, CREFSTRING className)
+{
+    CHECKNULL(schemas, L"MgDescribeSchema.GetClassDefinition");
+
+    Ptr<MgClassDefinition> classDef;
+    INT32 schemaCount = schemas->GetCount();
+
+    for (INT32 i = 0; i < schemaCount; ++i)
+    {
+        Ptr<MgFeatureSchema> currSchema = schemas->GetItem(i);
+        STRING currSchemaName = currSchema->GetName();
+        bool schemaNameFound = false;
+
+        if (schemaName.empty() || (schemaNameFound = (schemaName == currSchemaName)))
+        {
+            Ptr<MgClassDefinitionCollection> currClasses = currSchema->GetClasses();
+            INT32 classCount = currClasses->GetCount();
+
+            for (INT32 j = 0; j < classCount; ++j)
+            {
+                Ptr<MgClassDefinition> currClass = currClasses->GetItem(j);
+                STRING currClassName = currClass->GetName();
+
+                if (className == currClassName)
+                {
+                    classDef = currClass;
+                    break;
+                }
+                else
+                {
+                    STRING parsedSchemaName, parsedClassName;
+                    MgUtil::ParseQualifiedClassName(className, parsedSchemaName, parsedClassName);
+
+                    if (parsedClassName == currClassName)
+                    {
+                        classDef = currClass;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (schemaNameFound || NULL != classDef.p)
+        {
+            break;
+        }
+    }
+
+    return classDef.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgPropertyDefinitionCollection* MgDescribeSchema::GetIdentityProperties(
+    FdoFeatureSchemaCollection* schemas, MgResourceIdentifier* resource,
+    CREFSTRING schemaName, CREFSTRING className)
+{
+    CHECKNULL(schemas, L"MgDescribeSchema.GetIdentityProperties");
+
+    Ptr<MgPropertyDefinitionCollection> idProps = new MgPropertyDefinitionCollection();
+    INT32 schemaCount = schemas->GetCount();
+
+    // There should be at least one schema for the primary feature source.
+    for (INT32 schemaIndex = 0; schemaIndex < schemaCount; ++schemaIndex)
+    {
+        // Retrieve the schema for the primary feature source.
+        FdoPtr<FdoFeatureSchema> currSchema = schemas->GetItem(schemaIndex);
+        STRING currSchemaName = currSchema->GetName();
+        bool schemaNameFound = false;
+
+        if (schemaName.empty() || (schemaNameFound = (schemaName == currSchemaName)))
+        {
+            // Get all classes for a schema.
+            FdoPtr<FdoClassCollection> currClass = currSchema->GetClasses();
+            INT32 classCount = currClass->GetCount();
+
+            // Find identity properties for the specified class.
+            if (classCount > 0 &&
+                !GetIdentityProperties(className, currClass.p, idProps.p))
+            {
+                // If cannot find matching class in the class collection,
+                // it must be an extension class. So get the identity properties
+                // from the primary feature class source.
+                if (NULL == m_featureSourceCacheItem.p)
+                {
+                    m_featureSourceCacheItem = m_featureServiceCache->GetFeatureSource(resource);
+                }
+
+                // Get the class name for the primary source that is being extended.
+                MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+                CHECKNULL(featureSource, L"MgDescribeSchema.GetIdentityProperties");
+                MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+                CHECKNULL(extensions, L"MgDescribeSchema.GetIdentityProperties");
+                STRING extensionFeatureClass;
+                int extensionCount = extensions->GetCount();
+
+                // Find identity properties for the extension class.
+                for (int i = 0; i < extensionCount; ++i)
+                {
+                    MdfModel::Extension* extension = extensions->GetAt(i);
+                    CHECKNULL(extension, L"MgDescribeSchema.GetIdentityProperties");
+
+                    // Get the extension name.
+                    STRING extensionName = (STRING)extension->GetName();
+
+                    if (className == extensionName)
+                    {
+                        extensionFeatureClass = (STRING)extension->GetFeatureClass();
+                        GetIdentityProperties(extensionFeatureClass, currClass.p, idProps.p);
+                    }
+                }
+            }
+        }
+
+        if (schemaNameFound)
+        {
+            break;
+        }
+    }
+
+    return idProps.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool MgDescribeSchema::CheckExtendedFeatureClass(MgResourceIdentifier* resource,
+    CREFSTRING className)
+{
+    bool extended = false;
+
+    if (!className.empty())
+    {
+        STRING parsedSchemaName, parsedClassName;
+        MgUtil::ParseQualifiedClassName(className, parsedSchemaName, parsedClassName);
+
+        if (NULL == m_featureSourceCacheItem.p)
+        {
+            m_featureSourceCacheItem = m_featureServiceCache->GetFeatureSource(resource);
+        }
+
+        MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+        CHECKNULL(featureSource, L"MgDescribeSchema.CheckExtendedFeatureClass");
+        MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+        CHECKNULL(extensions, L"MgDescribeSchema.CheckExtendedFeatureClass");
+        int extensionCount = extensions->GetCount();
+
+        for (int i = 0; i < extensionCount; ++i)
+        {
+            MdfModel::Extension* extension = extensions->GetAt(i);
+            CHECKNULL(extension, L"MgDescribeSchema.CheckExtendedFeatureClass");
+            STRING extensionName = (STRING)extension->GetName();
+
+            STRING currSchemaName, currClassName;
+            MgUtil::ParseQualifiedClassName(extensionName, currSchemaName, currClassName);
+
+            if (currClassName == parsedClassName)
+            {
+                extended = true;
+                break;
+            }
+        }
+    }
+
+    return extended;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool MgDescribeSchema::CheckExtendedFeatureClasses(MgResourceIdentifier* resource,
+    MgStringCollection* classNames)
+{
+    bool extended = false;
+
+    if (NULL != classNames)
+    {
+        INT32 classCount = classNames->GetCount();
+
+        for (INT32 i = 0; i < classCount; ++i)
+        {
+            STRING currClassName = classNames->GetItem(i);
+
+            if (CheckExtendedFeatureClass(resource, currClassName))
+            {
+                extended = true;
+                break;
+            }
+        }
+    }
+
+    return extended;
+}

Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.h	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DescribeSchema.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -0,0 +1,81 @@
+//
+//  Copyright (C) 2004-2011 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_SERVER_DESCRIBE_SCHEMA_H_
+#define MG_SERVER_DESCRIBE_SCHEMA_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+#include "FSDSAX2Parser.h"
+#include "Services/Feature/FeatureServiceCache.h"
+
+class MgDescribeSchema
+{
+/// Constructors/Destructor
+
+public:
+
+    MgDescribeSchema();
+    ~MgDescribeSchema();
+
+/// Methods
+
+public:
+
+    MgFeatureSchemaCollection* DescribeSchema(MgResourceIdentifier* resource,
+        CREFSTRING schemaName, MgStringCollection* classNames, bool serialize = true);
+    STRING DescribeSchemaAsXml(MgResourceIdentifier* resource,
+        CREFSTRING schemaName, MgStringCollection* classNames);
+    MgStringCollection* GetSchemas(MgResourceIdentifier* resource);
+    MgStringCollection* GetClasses(MgResourceIdentifier* resource, CREFSTRING schemaName);
+    MgClassDefinition*  GetClassDefinition(MgResourceIdentifier* resource, CREFSTRING schemaName, CREFSTRING className, bool serialize = true);
+    STRING SchemaToXml(MgFeatureSchemaCollection* schema);
+    STRING SchemaToXml(MgFeatureSchemaCollection* schema, CREFSTRING namespacePrefix, CREFSTRING namespaceUrl);
+    MgFeatureSchemaCollection* XmlToSchema(CREFSTRING xml);
+    MgClassDefinitionCollection* GetIdentityProperties(MgResourceIdentifier* resource, CREFSTRING schemaName, MgStringCollection* classNames);
+
+private:
+    FdoFeatureSchemaCollection* DescribeFdoSchema(MgResourceIdentifier* resource,
+        CREFSTRING schemaName, MgStringCollection* classNames, bool& classNameHintUsed);
+    STRING GetSerializedXml(FdoFeatureSchemaCollection* fdoSchemaCol);
+    STRING GetSerializedXml(FdoFeatureSchemaCollection* fdoSchemaCol, FdoXmlFlags* flags);
+    bool GetIdentityProperties(CREFSTRING className,
+        FdoClassCollection* classCol, MgPropertyDefinitionCollection* idProps);
+
+    bool IsClassNameHintUsed(FdoIDescribeSchema* fdoCommand);
+    MgStringCollection* GetSchemaNames(MgFeatureSchemaCollection* schemas);
+    MgStringCollection* GetClassNames(MgFeatureSchemaCollection* schemas, CREFSTRING schemaName);
+    MgClassDefinition* GetClassDefinition(MgFeatureSchemaCollection* schemas,
+        CREFSTRING schemaName, CREFSTRING className);
+    MgPropertyDefinitionCollection* GetIdentityProperties(FdoFeatureSchemaCollection* schemas,
+        MgResourceIdentifier* resource, CREFSTRING schemaName, CREFSTRING className);
+
+public:
+    bool CheckExtendedFeatureClass(MgResourceIdentifier* resource, CREFSTRING className);
+    bool CheckExtendedFeatureClasses(MgResourceIdentifier* resource, MgStringCollection* classNames);
+
+/// Data Members
+
+private:
+
+    MgFeatureServiceCache* m_featureServiceCache;
+    Ptr<MgFeatureSourceCacheItem> m_featureSourceCacheItem;
+};
+
+#endif

Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.cpp	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -0,0 +1,255 @@
+//
+//  Copyright (C) 2004-2011 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 "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "FeatureServiceCommand.h"
+#include "ExtendedSelectCommand.h"
+#include "SelectAggregateCommand.h"
+#include "Services/FeatureReader.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FdoFeatureReader.h"
+#include "Services/Feature/FdoFilterCollection.h"
+#include "Services/Feature/FdoReaderCollection.h"
+
+// The maximum size of the subfilter for a selection query.  Tune this value for optimal selection perfomance.
+#define MG_MAX_SUBFILTER_SIZE  250
+
+MgExtendedSelectCommand::MgExtendedSelectCommand(MgResourceIdentifier* resource)
+{
+    CHECKNULL((MgResourceIdentifier*)resource, L"MgExtendedSelectCommand.MgExtendedSelectCommand");
+
+    // Connect to provider
+    m_connection = new MgFeatureConnection(resource);
+    if ((NULL != m_connection.p) && ( m_connection->IsConnectionOpen() ))
+    {
+        m_providerName = m_connection->GetProviderName();
+    }
+    else
+    {
+        throw new MgConnectionFailedException(L"MgExtendedSelectCommand.MgExtendedSelectCommand", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+    // Create FdoIExtendedSelect command
+    FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+    m_command = (FdoIExtendedSelect*)fdoConn->CreateCommand(FdoCommandType_ExtendedSelect);
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.MgExtendedSelectCommand");
+}
+
+MgExtendedSelectCommand::~MgExtendedSelectCommand()
+{
+    m_command = NULL;
+    m_filter = NULL;
+}
+
+FdoIdentifierCollection* MgExtendedSelectCommand::GetPropertyNames()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetPropertyNames");
+    return m_command->GetPropertyNames();
+}
+
+void MgExtendedSelectCommand::SetDistinct(bool value)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetDistinct");
+    // This operation is not supported by FdoIExtendedSelect
+    // m_command->SetDistinct(value);
+
+    // throw new MgInvalidOperationException(L"MgExtendedSelectCommand.SetDistinct", __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+bool MgExtendedSelectCommand::GetDistinct()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetDistinct");
+    // This operation is not supported by FdoIExtendedSelect
+    // return m_command->GetDistinct();
+
+    // throw new MgInvalidOperationException(L"MgExtendedSelectCommand.GetDistinct", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    return false;
+}
+
+void MgExtendedSelectCommand::SetFetchSize(FdoInt32 fetchSize)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetFetchSize");
+    m_command->SetFetchSize(fetchSize);
+}
+
+FdoInt32 MgExtendedSelectCommand::GetFetchSize()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetFetchSize");
+    return m_command->GetFetchSize();
+}
+
+FdoIdentifierCollection* MgExtendedSelectCommand::GetOrdering()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetOrdering");
+    return m_command->GetOrdering();
+}
+
+void MgExtendedSelectCommand::SetOrderingOption(FdoOrderingOption option)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetOrderingOption");
+    ((FdoISelect*)m_command)->SetOrderingOption(option);
+}
+
+FdoOrderingOption MgExtendedSelectCommand::GetOrderingOption()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetOrderingOption");
+    return ((FdoISelect*)m_command)->GetOrderingOption();
+}
+
+void MgExtendedSelectCommand::SetOrderingOption(FdoString* name, FdoOrderingOption option)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetOrderingOption");
+    m_command->SetOrderingOption(name, option);
+}
+
+FdoOrderingOption MgExtendedSelectCommand::GetOrderingOption(FdoString* name)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetOrderingOption");
+    return m_command->GetOrderingOption(name);
+}
+
+FdoIdentifierCollection* MgExtendedSelectCommand::GetGrouping()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetGrouping");
+    // This operation is not supported by FdoIExtendedSelect
+    // return m_command->GetGrouping();
+
+    // throw new MgInvalidOperationException(L"MgExtendedSelectCommand.GetGrouping", __LINE__, __WFILE__, NULL, L"", NULL);
+    return NULL;
+}
+
+void MgExtendedSelectCommand::SetGroupingFilter(FdoFilter* filter)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetGroupingFilter");
+    // This operation is not supported by FdoIExtendedSelect
+    // m_command->SetGroupingFilter(filter);
+
+    // throw new MgInvalidOperationException(L"MgExtendedSelectCommand.SetGroupingFilter", __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+FdoFilter* MgExtendedSelectCommand::GetGroupingFilter()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetGroupingFilter");
+    // This operation is not supported by FdoIExtendedSelect
+    // return m_command->GetGroupingFilter(filter);
+
+    // throw new MgInvalidOperationException(L"MgExtendedSelectCommand.GetGroupingFilter", __LINE__, __WFILE__, NULL, L"", NULL);
+    return NULL;
+}
+
+void MgExtendedSelectCommand::SetFeatureClassName(FdoString* value)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetFeatureClassName");
+    m_command->SetFeatureClassName(value);
+}
+
+void MgExtendedSelectCommand::SetFilter(FdoString* value)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetFilter");
+    m_command->SetFilter(value);
+}
+
+void MgExtendedSelectCommand::SetFilter(FdoFilter* value)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetFilter");
+    m_command->SetFilter(value);
+
+    m_filter = FDO_SAFE_ADDREF(value);
+}
+
+MgReader* MgExtendedSelectCommand::Execute()
+{
+    FdoPtr<FdoIScrollableFeatureReader> reader;
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.Execute");
+
+    reader = m_command->ExecuteScrollable();
+    return new MgdScrollableFeatureReader(m_connection, reader);
+}
+
+MgReader* MgExtendedSelectCommand::ExecuteWithLock()
+{
+    FdoPtr<FdoIFeatureReader> reader;
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.Execute");
+
+    reader = m_command->ExecuteWithLock();
+    return new MgdFeatureReader(m_connection, reader);
+}
+
+bool MgExtendedSelectCommand::IsSupportedFunction(FdoFunction* fdoFunc)
+{
+    FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+    return this->IsFdoSupportedFunction(fdoConn, fdoFunc);
+}
+
+bool MgExtendedSelectCommand::SupportsSelectGrouping()
+{
+    FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+    return MgFeatureServiceCommand::SupportsSelectGrouping(fdoConn);
+}
+
+bool MgExtendedSelectCommand::SupportsSelectOrdering()
+{
+    FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+    return MgFeatureServiceCommand::SupportsSelectOrdering(fdoConn);
+}
+
+bool MgExtendedSelectCommand::SupportsSelectDistinct()
+{
+    FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+    return MgFeatureServiceCommand::SupportsSelectDistinct(fdoConn);
+}
+
+FdoFilter* MgExtendedSelectCommand::GetFilter()
+{
+    return FDO_SAFE_ADDREF(m_filter.p);
+}
+
+FdoJoinCriteriaCollection* MgExtendedSelectCommand::GetJoinCriteria()
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.GetJoinCriteria");
+    return m_command->GetJoinCriteria();
+}
+
+void MgExtendedSelectCommand::SetAlias(FdoString* alias)
+{
+    CHECKNULL((FdoIExtendedSelect*)m_command, L"MgExtendedSelectCommand.SetDistinct");
+    m_command->SetAlias(alias);
+}
+
+MgReader* MgExtendedSelectCommand::ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne)
+{
+    Ptr<MgReader> ret;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    FdoPtr<FdoIFeatureReader> fdoReader = m_command->Execute();
+    if (bForceOneToOne)
+    {
+        FdoPtr<FdoStringCollection> names = MgFeatureUtil::MgToFdoStringCollection(idPropNames, false);
+        FdoPtr<FdoIFeatureReader> forcedReader = new MgFdoForcedOneToOneFeatureReader(fdoReader, names); 
+        ret = new MgdFeatureReader(m_connection, forcedReader);
+    }
+    else
+    {
+        ret = new MgdFeatureReader(m_connection, fdoReader);
+    }
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgExtendedSelectCommand.ExecuteJoined")
+
+    return ret.Detach();
+}

Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.h	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ExtendedSelectCommand.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -0,0 +1,84 @@
+#ifndef DESKTOP_EXTENDED_SELECT_COMMAND_H
+#define DESKTOP_EXTENDED_SELECT_COMMAND_H
+
+//
+//  Copyright (C) 2004-2011 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
+//
+
+class MgFdoFeatureReader;
+class MgFdoReaderCollection;
+class MgFdoFilterCollection;
+
+class MgExtendedSelectCommand : public MgFeatureServiceCommand
+{
+    DECLARE_CLASSNAME(MgExtendedSelectCommand)
+
+public:
+    MgExtendedSelectCommand(MgResourceIdentifier* resource);
+    virtual ~MgExtendedSelectCommand();
+
+    virtual FdoIdentifierCollection* GetPropertyNames();
+
+    virtual void SetDistinct( bool value );
+    virtual bool GetDistinct( );
+
+    virtual void SetFetchSize(FdoInt32 fetchSize);
+    virtual FdoInt32 GetFetchSize();
+
+    virtual FdoIdentifierCollection* GetOrdering();
+    virtual void SetOrderingOption( FdoOrderingOption  option );
+    virtual FdoOrderingOption GetOrderingOption( );
+
+    void SetOrderingOption( FdoString* name, FdoOrderingOption  option );
+    FdoOrderingOption GetOrderingOption( FdoString* name );
+
+    virtual FdoIdentifierCollection* GetGrouping();
+    virtual void SetGroupingFilter( FdoFilter* filter );
+    virtual FdoFilter* GetGroupingFilter( );
+
+    virtual void SetFeatureClassName(FdoString* value);
+    virtual void SetFilter(FdoString* value);
+    virtual void SetFilter(FdoFilter* value);
+
+    virtual FdoFilter* GetFilter();
+
+    virtual MgReader* Execute();
+    virtual MgReader* ExecuteWithLock();
+
+    virtual bool IsSupportedFunction(FdoFunction* fdoFunc);
+
+    virtual bool SupportsSelectGrouping();
+    virtual bool SupportsSelectOrdering();
+    virtual bool SupportsSelectDistinct();
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    MgReader* ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne);
+    virtual FdoJoinCriteriaCollection* GetJoinCriteria();
+    virtual void SetAlias(FdoString* alias);
+
+private:
+    Ptr<MgFeatureConnection> m_connection;
+    STRING m_providerName;
+    FdoPtr<FdoIExtendedSelect> m_command;
+
+    FdoPtr<FdoFilter> m_filter;
+};
+
+#endif
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -19,6 +19,7 @@
 #include "MgDesktop.h"
 #include "Services/FeatureService.h"
 #include "FeatureServiceCommand.h"
+#include "ExtendedSelectCommand.h"
 #include "SelectCommand.h"
 #include "SelectAggregateCommand.h"
 
@@ -37,6 +38,11 @@
             command = new MgSelectAggregateCommand(resource);
             break;
         }
+        case FdoCommandType_ExtendedSelect:
+        {
+            command = new MgExtendedSelectCommand(resource);
+            break;
+        }
     }
     return command.Detach();
 }

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -51,6 +51,7 @@
     virtual bool SupportsSelectDistinct() = 0;
 
     virtual MgReader* Execute() = 0;
+    virtual MgReader* ExecuteWithLock() = 0;
 
 protected:
 

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -21,16 +21,16 @@
 #include "Services/Feature/FeatureUtil.h"
 #include "Services/CryptoDefs.h"
 
-MgServerGetConnectionPropertyValues::MgServerGetConnectionPropertyValues()
+MgGetConnectionPropertyValues::MgGetConnectionPropertyValues()
 {
 }
 
-MgServerGetConnectionPropertyValues::~MgServerGetConnectionPropertyValues()
+MgGetConnectionPropertyValues::~MgGetConnectionPropertyValues()
 {
 }
 
 // Executes the describe schema command and serializes the schema to XML
-MgStringCollection* MgServerGetConnectionPropertyValues::GetConnectionPropertyValues( CREFSTRING providerName,
+MgStringCollection* MgGetConnectionPropertyValues::GetConnectionPropertyValues( CREFSTRING providerName,
                                                                                       CREFSTRING propertyName,
                                                                                       CREFSTRING partialConnString )
 {
@@ -44,7 +44,7 @@
         arguments.Add(L"1");
         arguments.Add(MgResources::BlankArgument);
 
-        throw new MgInvalidArgumentException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues",
+        throw new MgInvalidArgumentException(L"MgGetConnectionPropertyValues.GetConnectionPropertyValues",
             __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
     }
 
@@ -54,7 +54,7 @@
         arguments.Add(L"2");
         arguments.Add(MgResources::BlankArgument);
 
-        throw new MgInvalidArgumentException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues",
+        throw new MgInvalidArgumentException(L"MgGetConnectionPropertyValues.GetConnectionPropertyValues",
             __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
     }
 
@@ -72,7 +72,7 @@
         cryptoUtil.DecryptString(cipherText, plainText);
         MgUtil::MultiByteToWideChar(plainText, decryptedPartialConnString);
 
-        MG_CRYPTOGRAPHY_CATCH(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues")
+        MG_CRYPTOGRAPHY_CATCH(L"MgGetConnectionPropertyValues.GetConnectionPropertyValues")
 
         if (cryptographyException != NULL)
         {
@@ -90,21 +90,21 @@
     {
         if(NULL == msfc.p)
         {
-            throw new MgConnectionFailedException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgConnectionFailedException(L"MgGetConnectionPropertyValues.GetConnectionPropertyValues", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
         // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
         // otherwise it leaves the FDO connection marked as still in use.
         FdoPtr<FdoIConnection> fdoConn = msfc->GetConnection();
-        CHECKNULL((FdoIConnection*)fdoConn, L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues");
+        CHECKNULL((FdoIConnection*)fdoConn, L"MgGetConnectionPropertyValues.GetConnectionPropertyValues");
 
         // Get Connection Info
         FdoPtr<FdoIConnectionInfo> connInfo = fdoConn->GetConnectionInfo();
-        CHECKNULL((FdoIConnectionInfo*)connInfo, L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues");
+        CHECKNULL((FdoIConnectionInfo*)connInfo, L"MgGetConnectionPropertyValues.GetConnectionPropertyValues");
 
         // Get Connection Property Dictionary
         FdoPtr<FdoIConnectionPropertyDictionary> fdoConnPropDict = connInfo->GetConnectionProperties();
-        CHECKNULL((FdoIConnectionPropertyDictionary*)fdoConnPropDict, L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues");
+        CHECKNULL((FdoIConnectionPropertyDictionary*)fdoConnPropDict, L"MgGetConnectionPropertyValues.GetConnectionPropertyValues");
 
         bool enumerable = fdoConnPropDict->IsPropertyEnumerable((FdoString*)propertyName.c_str());
         if (!enumerable)
@@ -113,7 +113,7 @@
             arguments.Add(L"2");
             arguments.Add(propertyName);
 
-            throw new MgInvalidArgumentException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues",
+            throw new MgInvalidArgumentException(L"MgGetConnectionPropertyValues.GetConnectionPropertyValues",
                 __LINE__, __WFILE__, &arguments, L"MgPropertyNotEnumerable", NULL);
         }
 
@@ -130,7 +130,7 @@
         }
     }
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgGetConnectionPropertyValues.GetConnectionPropertyValues")
 
     return stringCol.Detach();
 }

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -23,11 +23,11 @@
 #include "System/XmlUtil.h"
 #include "Fdo.h"
 
-class MgServerGetConnectionPropertyValues
+class MgGetConnectionPropertyValues
 {
 public:
-    MgServerGetConnectionPropertyValues();
-    ~MgServerGetConnectionPropertyValues();
+    MgGetConnectionPropertyValues();
+    ~MgGetConnectionPropertyValues();
     MgStringCollection* GetConnectionPropertyValues( CREFSTRING providerName,
                                                      CREFSTRING propertyName,
                                                      CREFSTRING partialConnString );

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -18,27 +18,27 @@
 #include "Services/Feature/FeatureDefs.h"
 #include "GetFeatureProviders.h"
 
-MgServerGetFeatureProviders::MgServerGetFeatureProviders()
+MgGetFeatureProviders::MgGetFeatureProviders()
 {
     FdoPtr<IProviderRegistry> providerReg = FdoFeatureAccessManager::GetProviderRegistry();
-    CHECKNULL(providerReg, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+    CHECKNULL(providerReg, L"MgGetFeatureProviders.MgGetFeatureProviders()");
 
     FdoPtr<IConnectionManager> connManager = FdoFeatureAccessManager::GetConnectionManager();
-    CHECKNULL(connManager, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+    CHECKNULL(connManager, L"MgGetFeatureProviders.MgGetFeatureProviders()");
 
     m_fdoProviderCol = providerReg->GetProviders();
-    CHECKNULL(m_fdoProviderCol, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+    CHECKNULL(m_fdoProviderCol, L"MgGetFeatureProviders.MgGetFeatureProviders()");
 
     // this XML follows the FeatureProviderRegistry-1.0.0.xsd schema
     m_xmlUtil = new MgXmlUtil("FeatureProviderRegistry" /* NOXLATE */);
-    CHECKNULL(m_xmlUtil, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+    CHECKNULL(m_xmlUtil, L"MgGetFeatureProviders.MgGetFeatureProviders()");
 
     // no more risk of exceptions, so we can now assign these
     m_providerReg = providerReg.Detach();
     m_connManager = connManager.Detach();
 }
 
-MgServerGetFeatureProviders::~MgServerGetFeatureProviders()
+MgGetFeatureProviders::~MgGetFeatureProviders()
 {
     FDO_SAFE_RELEASE(m_providerReg);
     FDO_SAFE_RELEASE(m_connManager);
@@ -50,7 +50,7 @@
 }
 
 
-MgByteReader* MgServerGetFeatureProviders::GetFeatureProviders()
+MgByteReader* MgGetFeatureProviders::GetFeatureProviders()
 {
     Ptr<MgByteReader> byteReader;
 
@@ -59,14 +59,14 @@
     CreateFeatureProvidersDocument();
     byteReader = m_xmlUtil->ToReader();
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetFeatureProviders.GetFeatureProviders")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgGetFeatureProviders.GetFeatureProviders")
 
     return byteReader.Detach();
 }
 
-void MgServerGetFeatureProviders::CreateFeatureProvidersDocument()
+void MgGetFeatureProviders::CreateFeatureProvidersDocument()
 {
-    CHECKNULL(m_fdoProviderCol, L"MgServerGetFeatureProviders.CreateFeatureProvidersDocument");
+    CHECKNULL(m_fdoProviderCol, L"MgGetFeatureProviders.CreateFeatureProvidersDocument");
 
     INT32 cnt = m_fdoProviderCol->GetCount();
     for (INT32 i = 0; i < cnt; i++)
@@ -107,16 +107,16 @@
     }
 }
 
-void MgServerGetFeatureProviders::AddConnectionProperties(DOMElement* providerElem, FdoString* providerName)
+void MgGetFeatureProviders::AddConnectionProperties(DOMElement* providerElem, FdoString* providerName)
 {
-    CHECKNULL(providerElem, L"MgServerGetFeatureProviders.AddConnectionProperties");
+    CHECKNULL(providerElem, L"MgGetFeatureProviders.AddConnectionProperties");
 
     // Get Properties
     FdoInt32 totalProperties = 0;
 
     // Add ConnnectionProperties element (mandatory element)
     DOMElement* connPropRootElem = m_xmlUtil->AddChildNode(providerElem, "ConnectionProperties" /* NOXLATE */ );
-    CHECKNULL(connPropRootElem, L"MgServerGetFeatureProviders.AddConnectionProperties");
+    CHECKNULL(connPropRootElem, L"MgGetFeatureProviders.AddConnectionProperties");
 
     // We ignore any exception thrown here so that even if client dll/so is missing, GetFeatureProviders
     // will continue to work.
@@ -125,35 +125,35 @@
     // Get FdoIConnection instance
     // TODO: Should this connection be cached?
     FdoPtr<FdoIConnection> fdoConn = m_connManager->CreateConnection(providerName);
-    CHECKNULL((FdoIConnection*)fdoConn, L"MgServerGetFeatureProviders.AddConnectionProperties");
+    CHECKNULL((FdoIConnection*)fdoConn, L"MgGetFeatureProviders.AddConnectionProperties");
 
     // Get FdoIConnectionInfo
     FdoPtr<FdoIConnectionInfo> fdoConnInfo = fdoConn->GetConnectionInfo();
-    CHECKNULL((FdoIConnectionInfo*)fdoConnInfo, L"MgServerGetFeatureProviders.AddConnectionProperties");
+    CHECKNULL((FdoIConnectionInfo*)fdoConnInfo, L"MgGetFeatureProviders.AddConnectionProperties");
 
     // Get FdoIConnectionPropertyDictionary
     FdoPtr<FdoIConnectionPropertyDictionary> fdoConnPropertyDict = fdoConnInfo->GetConnectionProperties();
-    CHECKNULL((FdoIConnectionPropertyDictionary*)fdoConnPropertyDict, L"MgServerGetFeatureProviders.AddConnectionProperties");
+    CHECKNULL((FdoIConnectionPropertyDictionary*)fdoConnPropertyDict, L"MgGetFeatureProviders.AddConnectionProperties");
 
     // Get list of all properties
     FdoString** properties = fdoConnPropertyDict->GetPropertyNames(totalProperties);
-    CHECKNULL(properties, L"MgServerGetFeatureProviders.AddConnectionProperties");
+    CHECKNULL(properties, L"MgGetFeatureProviders.AddConnectionProperties");
 
     for ( FdoInt32 i=0; i < totalProperties; i++ )
     {
         AddConnectionProperty(connPropRootElem, properties[i], fdoConnPropertyDict);
     }
 
-    MG_FEATURE_SERVICE_CATCH(L"MgServerGetFeatureProviders.GetFeatureProviders") // do not rethrow so that GetFeatureProviders works
+    MG_FEATURE_SERVICE_CATCH(L"MgGetFeatureProviders.GetFeatureProviders") // do not rethrow so that GetFeatureProviders works
 }
 
-void MgServerGetFeatureProviders::AddConnectionProperty(DOMElement* connPropRootElem,
+void MgGetFeatureProviders::AddConnectionProperty(DOMElement* connPropRootElem,
                                                    FdoString* propertyName,
                                                    FdoIConnectionPropertyDictionary* fdoConnPropertyDict)
 {
-    CHECKNULL(connPropRootElem,     L"MgServerGetFeatureProviders.AddConnectionProperty");
-    CHECKNULL(propertyName,         L"MgServerGetFeatureProviders.AddConnectionProperty");
-    CHECKNULL(fdoConnPropertyDict,  L"MgServerGetFeatureProviders.AddConnectionProperty");
+    CHECKNULL(connPropRootElem,     L"MgGetFeatureProviders.AddConnectionProperty");
+    CHECKNULL(propertyName,         L"MgGetFeatureProviders.AddConnectionProperty");
+    CHECKNULL(fdoConnPropertyDict,  L"MgGetFeatureProviders.AddConnectionProperty");
 
     DOMElement* connPropElem = m_xmlUtil->AddChildNode(connPropRootElem, "ConnectionProperty"  /* NOXLATE */ );
 

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -23,11 +23,11 @@
 #include "System/XmlUtil.h"
 #include "Fdo.h"
 
-class MgServerGetFeatureProviders
+class MgGetFeatureProviders
 {
 public:
-    MgServerGetFeatureProviders();
-    ~MgServerGetFeatureProviders();
+    MgGetFeatureProviders();
+    ~MgGetFeatureProviders();
 
 
     MgByteReader* GetFeatureProviders();

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -21,16 +21,16 @@
 #include "Services/Feature/FeatureUtil.h"
 #include <math.h>
 
-MgServerGetLongTransactions::MgServerGetLongTransactions()
+MgGetLongTransactions::MgGetLongTransactions()
 {
 }
 
-MgServerGetLongTransactions::~MgServerGetLongTransactions()
+MgGetLongTransactions::~MgGetLongTransactions()
 {
 }
 
 // Executes the get long transactions command and serializes the schema to XML
-MgLongTransactionReader* MgServerGetLongTransactions::GetLongTransactions(MgResourceIdentifier* resId, bool bActiveOnly)
+MgLongTransactionReader* MgGetLongTransactions::GetLongTransactions(MgResourceIdentifier* resId, bool bActiveOnly)
 {
     Ptr<MgLongTransactionReader> mgLongTransactionReader;
     mgLongTransactionReader = NULL;
@@ -39,7 +39,7 @@
 
     if (NULL == resId)
     {
-        throw new MgNullArgumentException(L"MgServerGetLongTransactions.GetLongTransactions", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgNullArgumentException(L"MgGetLongTransactions.GetLongTransactions", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     // Connect to provider
@@ -58,15 +58,15 @@
         {
             // TODO: specify which argument and message, once we have the mechanism
             STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-            throw new MgInvalidOperationException(L"MgServerGetLongTransactions.GetLongTransactions", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgInvalidOperationException(L"MgGetLongTransactions.GetLongTransactions", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
         FdoPtr<FdoIGetLongTransactions> fdoCommand = (FdoIGetLongTransactions*)fdoConn->CreateCommand(FdoCommandType_GetLongTransactions);
-        CHECKNULL((FdoIGetLongTransactions*)fdoCommand, L"MgServerGetLongTransactions.GetLongTransactions");
+        CHECKNULL((FdoIGetLongTransactions*)fdoCommand, L"MgGetLongTransactions.GetLongTransactions");
 
         // Execute the command
         FdoPtr<FdoILongTransactionReader> longTransactionReader = fdoCommand->Execute();
-        CHECKNULL((FdoILongTransactionReader*)longTransactionReader, L"MgServerGetLongTransactions.GetLongTransactions");
+        CHECKNULL((FdoILongTransactionReader*)longTransactionReader, L"MgGetLongTransactions.GetLongTransactions");
 
         mgLongTransactionReader = new MgLongTransactionReader();
         while (longTransactionReader->ReadNext())
@@ -83,7 +83,7 @@
 
             // Add transaction data to the long transaction reader
             Ptr<MgLongTransactionData> longTransactionData = GetLongTransactionData(longTransactionReader);
-            CHECKNULL((MgLongTransactionData*)longTransactionData, L"MgServerGetLongTransactions.GetLongTransactions");
+            CHECKNULL((MgLongTransactionData*)longTransactionData, L"MgGetLongTransactions.GetLongTransactions");
             mgLongTransactionReader->AddLongTransactionData(longTransactionData);
 
             // If only active long transaction is required skip all others
@@ -96,21 +96,21 @@
     }
     else
     {
-        throw new MgConnectionFailedException(L"MgServerGetLongTransactions::GetLongTransactions()", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgConnectionFailedException(L"MgGetLongTransactions::GetLongTransactions()", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resId, L"MgServerGetLongTransactions.GetLongTransactions")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resId, L"MgGetLongTransactions.GetLongTransactions")
 
     return mgLongTransactionReader.Detach();
 }
 
-MgLongTransactionData* MgServerGetLongTransactions::GetLongTransactionData(FdoILongTransactionReader* longTransactionReader)
+MgLongTransactionData* MgGetLongTransactions::GetLongTransactionData(FdoILongTransactionReader* longTransactionReader)
 {
     Ptr<MgLongTransactionData> longTransactionData = new MgLongTransactionData();
 
     // Name must exist
     FdoString* name = longTransactionReader->GetName();
-    CHECKNULL((FdoString*)name, L"MgServerGetLongTransactions.GetLongTransactions");
+    CHECKNULL((FdoString*)name, L"MgGetLongTransactions.GetLongTransactions");
     longTransactionData->SetName(STRING(name));
 
     // Desc for long transaction

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -23,11 +23,11 @@
 #include "System/XmlUtil.h"
 #include "Fdo.h"
 
-class MgServerGetLongTransactions
+class MgGetLongTransactions
 {
 public:
-    MgServerGetLongTransactions();
-    ~MgServerGetLongTransactions();
+    MgGetLongTransactions();
+    ~MgGetLongTransactions();
     MgLongTransactionReader* GetLongTransactions(MgResourceIdentifier* resId, bool bActiveOnly);
     MgLongTransactionData* GetLongTransactionData(FdoILongTransactionReader* longTransactionReader);
 

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -20,7 +20,6 @@
 #include "Services/Feature/FeatureConnection.h"
 #include "Services/Feature/FeatureUtil.h"
 
-/*
 static std::map<FdoThreadCapability, std::string>          s_FdoThreadCapability;
 static std::map<FdoSpatialContextExtentType, std::string>  s_FdoSpatialContextExtentType;
 static std::map<FdoClassType, std::string>                 s_FdoClassType;
@@ -34,12 +33,11 @@
 static std::map<FdoExpressionType,  std::string>           s_FdoExpressionType;
 static std::map<FdoGeometryType,  std::string>             s_FdoGeometryType;
 static std::map<FdoGeometryComponentType,  std::string>    s_FdoGeometryComponentType;
-*/
 
-bool MgServerGetProviderCapabilities::m_isInitialized = MgServerGetProviderCapabilities::Initialize();
+bool MgGetProviderCapabilities::m_isInitialized = MgGetProviderCapabilities::Initialize();
 
 
-MgServerGetProviderCapabilities::MgServerGetProviderCapabilities(CREFSTRING providerName, CREFSTRING connectionString)
+MgGetProviderCapabilities::MgGetProviderCapabilities(CREFSTRING providerName, CREFSTRING connectionString)
 {
     if (providerName.empty())
     {
@@ -47,12 +45,12 @@
         arguments.Add(L"1");
         arguments.Add(MgResources::BlankArgument);
 
-        throw new MgInvalidArgumentException(L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities",
+        throw new MgInvalidArgumentException(L"MgGetProviderCapabilities.MgGetProviderCapabilities",
             __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
     }
 
     FdoPtr<IConnectionManager> connManager = FdoFeatureAccessManager::GetConnectionManager();
-    CHECKNULL(connManager, L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities");
+    CHECKNULL(connManager, L"MgGetProviderCapabilities.MgGetProviderCapabilities");
 
     // Remove the version from the provider name
     FdoPtr<FdoProviderNameTokens> tokens = FdoProviderNameTokens::Create(providerName.c_str());
@@ -77,10 +75,10 @@
         fdoConn->Open();
     }
 
-    CHECKNULL(fdoConn, L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities");
+    CHECKNULL(fdoConn, L"MgGetProviderCapabilities.MgGetProviderCapabilities");
 
     m_xmlUtil = new MgXmlUtil();
-    CHECKNULL(m_xmlUtil, L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities");
+    CHECKNULL(m_xmlUtil, L"MgGetProviderCapabilities.MgGetProviderCapabilities");
 
     m_xmlCap = NULL;
 
@@ -89,7 +87,7 @@
     m_providerName = providerNoVersion;
 }
 
-MgServerGetProviderCapabilities::~MgServerGetProviderCapabilities()
+MgGetProviderCapabilities::~MgGetProviderCapabilities()
 {
     // Check if the connection needs to be closed
     if(m_fdoConn->GetConnectionState() == FdoConnectionState_Open)
@@ -104,9 +102,9 @@
 }
 
 
-MgByteReader* MgServerGetProviderCapabilities::GetProviderCapabilities()
+MgByteReader* MgGetProviderCapabilities::GetProviderCapabilities()
 {
-    CHECKNULL(m_xmlUtil, L"MgServerGetProviderCapabilities.GetProviderCapabilities");
+    CHECKNULL(m_xmlUtil, L"MgGetProviderCapabilities.GetProviderCapabilities");
     Ptr<MgByteReader> byteReader;
 
     MG_FEATURE_SERVICE_TRY()
@@ -119,17 +117,17 @@
         byteReader = m_xmlCap->ToReader();
     }
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetProviderCapabilities.GetProviderCapabilities")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgGetProviderCapabilities.GetProviderCapabilities")
 
     return byteReader.Detach();
 }
 
-void MgServerGetProviderCapabilities::CreateCapabilitiesDocument()
+void MgGetProviderCapabilities::CreateCapabilitiesDocument()
 {
     // Root node element created
     // this XML follows the FdoProviderCapabilities-1.0.0.xsd schema
     m_xmlCap = new MgXmlUtil("FeatureProviderCapabilities");
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateCapabilitiesDocument");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateCapabilitiesDocument");
     DOMElement* root = m_xmlCap->GetRootNode();
 
     // Provide name element and its attribute
@@ -153,19 +151,19 @@
 
 
 
-void MgServerGetProviderCapabilities::CreateConnectionCapabilities()
+void MgGetProviderCapabilities::CreateConnectionCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateConnectionCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateConnectionCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateConnectionCapabilities");
 
     DOMElement* connNode = m_xmlCap->AddChildNode(root, "Connection");
-    CHECKNULL(connNode, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+    CHECKNULL(connNode, L"MgGetProviderCapabilities::CreateConnectionCapabilities");
 
     FdoPtr<FdoIConnectionCapabilities> ficc = m_fdoConn->GetConnectionCapabilities();
-    CHECKNULL((FdoIConnectionCapabilities*)ficc, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+    CHECKNULL((FdoIConnectionCapabilities*)ficc, L"MgGetProviderCapabilities::CreateConnectionCapabilities");
 
     // Thread
     FdoThreadCapability ftc = ficc->GetThreadCapability();
@@ -178,7 +176,7 @@
     if (cnt > 0 && fscet != NULL)
     {
         DOMElement* scNode = m_xmlCap->AddChildNode(connNode, "SpatialContextExtent");
-        CHECKNULL(scNode, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+        CHECKNULL(scNode, L"MgGetProviderCapabilities::CreateConnectionCapabilities");
 
         for (FdoInt32 i = 0; i < cnt; i++)
         {
@@ -211,19 +209,19 @@
 }
 
 
-void MgServerGetProviderCapabilities::CreateSchemaCapabilities()
+void MgGetProviderCapabilities::CreateSchemaCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
     FdoPtr<FdoISchemaCapabilities> fsc = m_fdoConn->GetSchemaCapabilities();
-    CHECKNULL((FdoISchemaCapabilities*)fsc, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+    CHECKNULL((FdoISchemaCapabilities*)fsc, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
     DOMElement* schemaNode = m_xmlCap->AddChildNode(root, "Schema");
-    CHECKNULL(schemaNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+    CHECKNULL(schemaNode, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
     // Add all class types
     FdoInt32 cnt = 0;
@@ -231,7 +229,7 @@
     if (cnt > 0 && fct != NULL)
     {
         DOMElement* classNode = m_xmlCap->AddChildNode(schemaNode, "Class");
-        CHECKNULL(classNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+        CHECKNULL(classNode, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -246,7 +244,7 @@
     if (cnt > 0 && fdt != NULL)
     {
         DOMElement* dataNode = m_xmlCap->AddChildNode(schemaNode, "Data");
-        CHECKNULL(dataNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+        CHECKNULL(dataNode, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -285,7 +283,7 @@
     if (cnt > 0 && sagt != NULL)
     {
         DOMElement* sagtNode = m_xmlCap->AddChildNode(schemaNode, "SupportedAutoGeneratedTypes");
-        CHECKNULL(sagtNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+        CHECKNULL(sagtNode, L"MgGetProviderCapabilities::CreateSchemaCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -298,19 +296,19 @@
     m_xmlCap->AddTextNode(schemaNode, "SupportsSchemaModification", supportsSchemaModification);
 }
 
-void MgServerGetProviderCapabilities::CreateCommandCapabilities()
+void MgGetProviderCapabilities::CreateCommandCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateCommandCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateCommandCapabilities");
 
     FdoPtr<FdoICommandCapabilities> fcc = m_fdoConn->GetCommandCapabilities();
-    CHECKNULL((FdoICommandCapabilities*)fcc, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+    CHECKNULL((FdoICommandCapabilities*)fcc, L"MgGetProviderCapabilities::CreateCommandCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateCommandCapabilities");
 
     DOMElement* cmdNode = m_xmlCap->AddChildNode(root, "Command");
-    CHECKNULL(cmdNode, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+    CHECKNULL(cmdNode, L"MgGetProviderCapabilities::CreateCommandCapabilities");
 
     // Add all command types
     FdoInt32 cnt = 0;
@@ -318,7 +316,7 @@
     if (cnt > 0 && fcmd != NULL)
     {
         DOMElement* scNode = m_xmlCap->AddChildNode(cmdNode, "SupportedCommands");
-        CHECKNULL(scNode, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+        CHECKNULL(scNode, L"MgGetProviderCapabilities::CreateCommandCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -384,19 +382,19 @@
     m_xmlCap->AddTextNode(cmdNode, "SupportsSelectGrouping", supportsSelectGrouping);
 }
 
-void MgServerGetProviderCapabilities::CreateFilterCapabilities()
+void MgGetProviderCapabilities::CreateFilterCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateFilterCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
     FdoPtr<FdoIFilterCapabilities> ffc = m_fdoConn->GetFilterCapabilities();
-    CHECKNULL((FdoIFilterCapabilities*)ffc, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+    CHECKNULL((FdoIFilterCapabilities*)ffc, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
     DOMElement* filterNode = m_xmlCap->AddChildNode(root, "Filter");
-    CHECKNULL(filterNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+    CHECKNULL(filterNode, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
     // Add all condition types
     FdoInt32 cnt = 0;
@@ -404,7 +402,7 @@
     if (cnt > 0 && fct != NULL)
     {
         DOMElement* condNode = m_xmlCap->AddChildNode(filterNode, "Condition");
-        CHECKNULL(condNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+        CHECKNULL(condNode, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -419,7 +417,7 @@
     if (cnt > 0 && fso != NULL)
     {
         DOMElement* fsoNode = m_xmlCap->AddChildNode(filterNode, "Spatial");
-        CHECKNULL(fsoNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+        CHECKNULL(fsoNode, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -434,7 +432,7 @@
     if (cnt > 0 && fdo != NULL)
     {
         DOMElement* distNode = m_xmlCap->AddChildNode(filterNode, "Distance");
-        CHECKNULL(distNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+        CHECKNULL(distNode, L"MgGetProviderCapabilities::CreateFilterCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -452,19 +450,19 @@
     m_xmlCap->AddTextNode(filterNode, "SupportsNonLiteralGeometricOperations", supportsNonLiteralGeometricOperations);
 }
 
-void MgServerGetProviderCapabilities::CreateExpressionCapabilities()
+void MgGetProviderCapabilities::CreateExpressionCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     FdoPtr<FdoIExpressionCapabilities> fec = m_fdoConn->GetExpressionCapabilities();
-    CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     DOMElement* expressionNode = m_xmlCap->AddChildNode(root, "Expression");
-    CHECKNULL(expressionNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(expressionNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     // Add all expression types
     FdoInt32 cnt = 0;
@@ -472,7 +470,7 @@
     if (cnt > 0 && fet != NULL)
     {
         DOMElement* typeNode = m_xmlCap->AddChildNode(expressionNode, "Type");
-        CHECKNULL(typeNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+        CHECKNULL(typeNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -491,16 +489,16 @@
         {
             // Add function definition collection element if there are any functions available
             DOMElement* funcDefColNode = m_xmlCap->AddChildNode(expressionNode, "FunctionDefinitionList");
-            CHECKNULL(funcDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+            CHECKNULL(funcDefColNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
             for (FdoInt32 i=0; i < funcCnt; i++)
             {
                 // Add function definition element
                 FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
-                CHECKNULL((FdoFunctionDefinition*)ffd, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                CHECKNULL((FdoFunctionDefinition*)ffd, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                 DOMElement* funcDefNode = m_xmlCap->AddChildNode(funcDefColNode, "FunctionDefinition");
-                CHECKNULL(funcDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                CHECKNULL(funcDefNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                 const char* strName = MgUtil::WideCharToMultiByte(ffd->GetName());
                 const char* strDesc = MgUtil::WideCharToMultiByte(ffd->GetDescription());
@@ -524,16 +522,16 @@
                     {
                         // Add ArgumentDefinitionCollection if there are arguments
                         DOMElement* argDefColNode = m_xmlCap->AddChildNode(funcDefNode, "ArgumentDefinitionList");
-                        CHECKNULL(argDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                        CHECKNULL(argDefColNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                         for (FdoInt32 j=0; j < argCnt; j++)
                         {
                             // Add ArgumentDefinition for each argument
                             FdoPtr<FdoArgumentDefinition> fad = argCol->GetItem(j);
-                            CHECKNULL((FdoArgumentDefinition*)fad, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                            CHECKNULL((FdoArgumentDefinition*)fad, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                             DOMElement* argDefNode = m_xmlCap->AddChildNode(argDefColNode, "ArgumentDefinition");
-                            CHECKNULL(argDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                            CHECKNULL(argDefNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                             const char* strArgName = MgUtil::WideCharToMultiByte(fad->GetName());
                             const char* strArgDesc = MgUtil::WideCharToMultiByte(fad->GetDescription());
@@ -556,19 +554,19 @@
 }
 
 
-void MgServerGetProviderCapabilities::CreateExpressionCapabilities2()
+void MgGetProviderCapabilities::CreateExpressionCapabilities2()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     FdoPtr<FdoIExpressionCapabilities> fec = m_fdoConn->GetExpressionCapabilities();
-    CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     DOMElement* expressionNode = m_xmlCap->AddChildNode(root, "Expression");
-    CHECKNULL(expressionNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+    CHECKNULL(expressionNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
     // Add all expression types
     FdoInt32 cnt = 0;
@@ -576,7 +574,7 @@
     if (cnt > 0 && fet != NULL)
     {
         DOMElement* typeNode = m_xmlCap->AddChildNode(expressionNode, "Type");
-        CHECKNULL(typeNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+        CHECKNULL(typeNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -595,16 +593,16 @@
         {
             // Add function definition collection element if there are any functions available
             DOMElement* funcDefColNode = m_xmlCap->AddChildNode(expressionNode, "FunctionDefinitionList");
-            CHECKNULL(funcDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+            CHECKNULL(funcDefColNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
             for (FdoInt32 i=0; i < funcCnt; i++)
             {
                 // Add function definition element
                 FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
-                CHECKNULL((FdoFunctionDefinition*)ffd, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                CHECKNULL((FdoFunctionDefinition*)ffd, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                 DOMElement* funcDefNode = m_xmlCap->AddChildNode(funcDefColNode, "FunctionDefinition");
-                CHECKNULL(funcDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                CHECKNULL(funcDefNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                 const char* strName = MgUtil::WideCharToMultiByte(ffd->GetName());
                 const char* strDesc = MgUtil::WideCharToMultiByte(ffd->GetDescription());
@@ -630,16 +628,16 @@
                     {
 
                         DOMElement* signDefColNode = m_xmlCap->AddChildNode(funcDefNode, "SignatureDefinitionCollection");
-                        CHECKNULL(signDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                        CHECKNULL(signDefColNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
                         for (FdoInt32 j=0; j < signaturesCnt; j++)
                         {
 
                             // Add SignatureDefinition for each signature
                             FdoPtr<FdoSignatureDefinition> fsd = signatures->GetItem(j);
-                            CHECKNULL((FdoSignatureDefinition*)fsd, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                            CHECKNULL((FdoSignatureDefinition*)fsd, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                             DOMElement* signDefNode = m_xmlCap->AddChildNode(signDefColNode, "SignatureDefinition");
-                            CHECKNULL(signDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                            CHECKNULL(signDefNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                             FdoPropertyType eSignPropertyDataType = fsd->GetReturnPropertyType();
                             string strSignPropertyType = s_FdoPropertyTypeAsString[eSignPropertyDataType];
@@ -655,7 +653,7 @@
                                 m_xmlCap->AddTextNode(signDefNode, "DataType",  strSignDataType.c_str());
 
                             DOMElement* argDefColNode = m_xmlCap->AddChildNode(signDefNode, "ArgumentDefinitionList");
-                            CHECKNULL(argDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                            CHECKNULL(argDefColNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                             FdoPtr<FdoReadOnlyArgumentDefinitionCollection> fads = fsd->GetArguments();
                             if (NULL != (FdoReadOnlyArgumentDefinitionCollection *) fads)
@@ -666,10 +664,10 @@
                                     for (int k=0; k<argCnt; k++)
                                     {
                                         FdoPtr<FdoArgumentDefinition> fad = fads->GetItem(k);
-                                        CHECKNULL((FdoArgumentDefinition*)fad, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                                        CHECKNULL((FdoArgumentDefinition*)fad, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                                         DOMElement* argDefNode = m_xmlCap->AddChildNode(argDefColNode, "ArgumentDefinition");
-                                        CHECKNULL(argDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                                        CHECKNULL(argDefNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                                         const char* strArgName = MgUtil::WideCharToMultiByte(fad->GetName());
                                         const char* strArgDesc = MgUtil::WideCharToMultiByte(fad->GetDescription());
@@ -698,7 +696,7 @@
                                             if (fpvc->GetConstraintType() == FdoPropertyValueConstraintType_List)
                                             {
                                                 DOMElement* propValueConstListNode = m_xmlCap->AddChildNode(argDefNode, "PropertyValueConstraintList");
-                                                CHECKNULL(propValueConstListNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                                                CHECKNULL(propValueConstListNode, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
 
                                                 FdoPropertyValueConstraintType eConstraintType = fpvc->GetConstraintType();
 
@@ -711,7 +709,7 @@
                                                         for (int l=0; l<dvCnt; l++)
                                                         {
                                                             FdoPtr<FdoDataValue> dv = dvc->GetItem(l);
-                                                            CHECKNULL((FdoDataValue*)dv, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+                                                            CHECKNULL((FdoDataValue*)dv, L"MgGetProviderCapabilities::CreateExpressionCapabilities");
                                                             FdoDataType dataType = dv->GetDataType();
                                                             // FdoDataType_String is the only supported type
                                                             if (dataType == FdoDataType_String)
@@ -738,19 +736,19 @@
     }
 }
 
-void MgServerGetProviderCapabilities::CreateRasterCapabilities()
+void MgGetProviderCapabilities::CreateRasterCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateRasterCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateRasterCapabilities");
 
     FdoPtr<FdoIRasterCapabilities> frc = m_fdoConn->GetRasterCapabilities();
-    CHECKNULL((FdoIRasterCapabilities*)frc, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+    CHECKNULL((FdoIRasterCapabilities*)frc, L"MgGetProviderCapabilities::CreateRasterCapabilities");
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateRasterCapabilities");
 
     DOMElement* rasterNode = m_xmlCap->AddChildNode(root, "Raster");
-    CHECKNULL(rasterNode, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+    CHECKNULL(rasterNode, L"MgGetProviderCapabilities::CreateRasterCapabilities");
 
     // Supports Raster
     bool supportsRaster = frc->SupportsRaster();
@@ -765,10 +763,10 @@
 
 }
 
-void MgServerGetProviderCapabilities::CreateTopologyCapabilities()
+void MgGetProviderCapabilities::CreateTopologyCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities::CreateTopologyCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities::CreateTopologyCapabilities");
 
     MG_FEATURE_SERVICE_TRY()
 
@@ -781,10 +779,10 @@
     }
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities::CreateTopologyCapabilities");
 
     DOMElement* topologyNode = m_xmlCap->AddChildNode(root, "Topology");
-    CHECKNULL(topologyNode, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+    CHECKNULL(topologyNode, L"MgGetProviderCapabilities::CreateTopologyCapabilities");
 
     // Supports Topology
     bool supportsTopology = frc->SupportsTopology();
@@ -804,14 +802,14 @@
     m_xmlCap->AddTextNode(topologyNode, "ConstrainsFeatureMovements", constrainsFeatureMovements);
 
     // TODO: Change this to CATCH_AND_THROW when SimpleDB stops throwing exception of not implemented
-    MG_FEATURE_SERVICE_CATCH(L"MgServerGetProviderCapabilities.CreateTopologyCapabilities")
+    MG_FEATURE_SERVICE_CATCH(L"MgGetProviderCapabilities.CreateTopologyCapabilities")
 
 }
 
-void MgServerGetProviderCapabilities::CreateGeometryCapabilities()
+void MgGetProviderCapabilities::CreateGeometryCapabilities()
 {
-    CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+    CHECKNULL(m_xmlCap, L"MgGetProviderCapabilities.CreateGeometryCapabilities");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities.CreateGeometryCapabilities");
 
     MG_FEATURE_SERVICE_TRY()
 
@@ -824,17 +822,17 @@
     }
 
     DOMElement* root = m_xmlCap->GetRootNode();
-    CHECKNULL(root, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+    CHECKNULL(root, L"MgGetProviderCapabilities.CreateGeometryCapabilities");
 
     DOMElement* geometryNode = m_xmlCap->AddChildNode(root, "Geometry");
-    CHECKNULL(geometryNode, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+    CHECKNULL(geometryNode, L"MgGetProviderCapabilities.CreateGeometryCapabilities");
 
     FdoInt32 cnt = 0;
     FdoGeometryType* geomType = fgc->GetGeometryTypes(cnt);
     if (cnt > 0 && geomType != NULL)
     {
         DOMElement* geometryTypeNode = m_xmlCap->AddChildNode(geometryNode, "Types");
-        CHECKNULL(geometryTypeNode, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+        CHECKNULL(geometryTypeNode, L"MgGetProviderCapabilities.CreateGeometryCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -847,7 +845,7 @@
     if (cnt > 0 && geomCompType != NULL)
     {
         DOMElement* geometryCompNode = m_xmlCap->AddChildNode(geometryNode, "Components");
-        CHECKNULL(geometryCompNode, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+        CHECKNULL(geometryCompNode, L"MgGetProviderCapabilities.CreateGeometryCapabilities");
 
         for (FdoInt32 i=0; i < cnt; i++)
         {
@@ -863,12 +861,12 @@
 
     m_xmlCap->AddTextNode(geometryNode, "Dimensionality", &buff[0]);
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetProviderCapabilities.CreateGeometryCapabilities")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgGetProviderCapabilities.CreateGeometryCapabilities")
 }
 
-bool MgServerGetProviderCapabilities::IsConnectionOpen()
+bool MgGetProviderCapabilities::IsConnectionOpen()
 {
-    CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities.IsConnectionOpen");
+    CHECKNULL(m_fdoConn, L"MgGetProviderCapabilities.IsConnectionOpen");
 
     FdoConnectionState state = m_fdoConn->GetConnectionState();
     if (state != FdoConnectionState_Open)
@@ -877,7 +875,7 @@
     return true;
 }
 
-bool MgServerGetProviderCapabilities::Initialize()
+bool MgGetProviderCapabilities::Initialize()
 {
     // Thread Capability
     s_FdoThreadCapability[FdoThreadCapability_SingleThreaded]           = "SingleThreaded";

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -23,11 +23,11 @@
 #include "System/XmlUtil.h"
 #include "Fdo.h"
 
-class MgServerGetProviderCapabilities
+class MgGetProviderCapabilities
 {
 public:
-    MgServerGetProviderCapabilities(CREFSTRING providerName, CREFSTRING connectionString);
-    ~MgServerGetProviderCapabilities();
+    MgGetProviderCapabilities(CREFSTRING providerName, CREFSTRING connectionString);
+    ~MgGetProviderCapabilities();
     MgByteReader* GetProviderCapabilities();
 
 private:

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -19,19 +19,19 @@
 #include "GetSchemaMapping.h"
 #include "Services/Resource/UnmanagedDataManager.h"
 
-MgServerGetSchemaMapping::MgServerGetSchemaMapping() :
+MgGetSchemaMapping::MgGetSchemaMapping() :
     m_bytes(NULL)
 {
 }
 
-MgServerGetSchemaMapping::~MgServerGetSchemaMapping()
+MgGetSchemaMapping::~MgGetSchemaMapping()
 {
     delete [] m_bytes;
     m_bytes = NULL;
 }
 
 
-MgByteReader* MgServerGetSchemaMapping::GetSchemaMapping(CREFSTRING providerName, CREFSTRING partialConnString)
+MgByteReader* MgGetSchemaMapping::GetSchemaMapping(CREFSTRING providerName, CREFSTRING partialConnString)
 {
     Ptr<MgByteReader> byteReader;
 
@@ -51,7 +51,7 @@
 
         // Create the memory stream
         FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
-        CHECKNULL((FdoIoMemoryStream*)fmis, L"MgServerGetSchemaMapping.GetSchemaMapping");
+        CHECKNULL((FdoIoMemoryStream*)fmis, L"MgGetSchemaMapping.GetSchemaMapping");
 
         FdoXmlWriterP writer = FdoXmlWriter::Create(fmis);
 
@@ -69,26 +69,26 @@
 
         // Get the schema
         FdoPtr<FdoIDescribeSchema> fdoDescribeSchemaCommand = (FdoIDescribeSchema*)fdoConnection->CreateCommand(FdoCommandType_DescribeSchema);
-        CHECKNULL((FdoIDescribeSchema*)fdoDescribeSchemaCommand, L"MgServerGetSchemaMapping.GetSchemaMapping");
+        CHECKNULL((FdoIDescribeSchema*)fdoDescribeSchemaCommand, L"MgGetSchemaMapping.GetSchemaMapping");
 
         // Execute the command
         FdoPtr<FdoFeatureSchemaCollection> fdoFeatureSchemaCollection;
         fdoFeatureSchemaCollection = fdoDescribeSchemaCommand->Execute();
-        CHECKNULL((FdoFeatureSchemaCollection*)fdoFeatureSchemaCollection, L"MgServerGetSchemaMapping.GetSchemaMapping");
+        CHECKNULL((FdoFeatureSchemaCollection*)fdoFeatureSchemaCollection, L"MgGetSchemaMapping.GetSchemaMapping");
 
         // Write to memory stream
         fdoFeatureSchemaCollection->WriteXml(writer);
 
         // Get the schema mapping
         FdoPtr<FdoIDescribeSchemaMapping> fdoDescribeSchemaMappingCommand = (FdoIDescribeSchemaMapping*)fdoConnection->CreateCommand(FdoCommandType_DescribeSchemaMapping);
-        CHECKNULL((FdoIDescribeSchemaMapping*)fdoDescribeSchemaMappingCommand, L"MgServerGetSchemaMapping.GetSchemaMapping");
+        CHECKNULL((FdoIDescribeSchemaMapping*)fdoDescribeSchemaMappingCommand, L"MgGetSchemaMapping.GetSchemaMapping");
 
         fdoDescribeSchemaMappingCommand->SetIncludeDefaults(true);
 
         // Execute the command
         FdoPtr<FdoPhysicalSchemaMappingCollection> fdoPhysicalSchemaMappingCollection;
         fdoPhysicalSchemaMappingCollection = fdoDescribeSchemaMappingCommand->Execute();
-        CHECKNULL((FdoPhysicalSchemaMappingCollection*)fdoPhysicalSchemaMappingCollection, L"MgServerGetSchemaMapping.GetSchemaMapping");
+        CHECKNULL((FdoPhysicalSchemaMappingCollection*)fdoPhysicalSchemaMappingCollection, L"MgGetSchemaMapping.GetSchemaMapping");
 
         // Write to memory stream
         fdoPhysicalSchemaMappingCollection->WriteXml(writer);
@@ -100,7 +100,7 @@
 
         FdoInt64 len = fmis->GetLength();
         m_bytes = new FdoByte[(size_t)len];
-        CHECKNULL(m_bytes, L"MgServerGetSchemaMapping.GetSchemaMapping");
+        CHECKNULL(m_bytes, L"MgGetSchemaMapping.GetSchemaMapping");
 
         fmis->Read(m_bytes, (FdoSize)len);
 
@@ -110,10 +110,10 @@
     }
     else
     {
-        throw new MgConnectionFailedException(L"MgServerGetSchemaMapping::GetSchemaMapping()", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgConnectionFailedException(L"MgGetSchemaMapping::GetSchemaMapping()", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetSchemaMapping.GetSchemaMapping")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgGetSchemaMapping.GetSchemaMapping")
 
     return byteReader.Detach();
 }

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -23,11 +23,11 @@
 #include "System/XmlUtil.h"
 #include "Fdo.h"
 
-class MgServerGetSchemaMapping
+class MgGetSchemaMapping
 {
 public:
-    MgServerGetSchemaMapping();
-    ~MgServerGetSchemaMapping();
+    MgGetSchemaMapping();
+    ~MgGetSchemaMapping();
 
 
     MgByteReader* GetSchemaMapping(CREFSTRING providerName, CREFSTRING partialConnString);

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -22,18 +22,18 @@
 #include "Services/Feature/FeatureServiceCache.h"
 #include "GeometryCommon.h"
 
-MgServerGetSpatialContexts::MgServerGetSpatialContexts()
+MgGetSpatialContexts::MgGetSpatialContexts()
 {
     m_featureServiceCache = MgFeatureServiceCache::GetInstance();
 }
 
-MgServerGetSpatialContexts::~MgServerGetSpatialContexts()
+MgGetSpatialContexts::~MgGetSpatialContexts()
 {
 }
 
 // Executes the GetSpatialContext command and creates a reader
 
-MgSpatialContextReader* MgServerGetSpatialContexts::GetSpatialContexts(MgResourceIdentifier* resId)
+MgSpatialContextReader* MgGetSpatialContexts::GetSpatialContexts(MgResourceIdentifier* resId)
 {
     Ptr<MgSpatialContextReader> mgSpatialContextReader;
 
@@ -62,15 +62,15 @@
             {
                 // TODO: specify which argument and message, once we have the mechanism
                 STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-                throw new MgInvalidOperationException(L"MgServerGetSpatialContexts.GetSpatialContexts", __LINE__, __WFILE__, NULL, L"", NULL);
+                throw new MgInvalidOperationException(L"MgGetSpatialContexts.GetSpatialContexts", __LINE__, __WFILE__, NULL, L"", NULL);
             }
 
             FdoPtr<FdoIGetSpatialContexts> fdoCommand = (FdoIGetSpatialContexts*)fdoConn->CreateCommand(FdoCommandType_GetSpatialContexts);
-            CHECKNULL((FdoIGetSpatialContexts*)fdoCommand, L"MgServerGetSpatialContexts.GetSpatialContexts");
+            CHECKNULL((FdoIGetSpatialContexts*)fdoCommand, L"MgGetSpatialContexts.GetSpatialContexts");
 
             // Execute the command
             FdoPtr<FdoISpatialContextReader> spatialReader = fdoCommand->Execute();
-            CHECKNULL((FdoISpatialContextReader*)spatialReader, L"MgServerGetSpatialContexts.GetSpatialContexts");
+            CHECKNULL((FdoISpatialContextReader*)spatialReader, L"MgGetSpatialContexts.GetSpatialContexts");
 
             mgSpatialContextReader = new MgSpatialContextReader();
             while (spatialReader->ReadNext())
@@ -79,7 +79,7 @@
                 mgSpatialContextReader->SetProviderName(m_providerName);
 
                 Ptr<MgSpatialContextData> spatialData = GetSpatialContextData(spatialReader, spatialContextInfo);
-                CHECKNULL((MgSpatialContextData*)spatialData, L"MgServerGetSpatialContexts.GetSpatialContexts");
+                CHECKNULL((MgSpatialContextData*)spatialData, L"MgGetSpatialContexts.GetSpatialContexts");
 
                 // Add spatial data to the spatialcontext reader
                 mgSpatialContextReader->AddSpatialData(spatialData);
@@ -89,7 +89,7 @@
         }
         else
         {
-            throw new MgConnectionFailedException(L"MgServerGetSpatialContexts.GetSpatialContexts()", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgConnectionFailedException(L"MgGetSpatialContexts.GetSpatialContexts()", __LINE__, __WFILE__, NULL, L"", NULL);
         }
     }
     else
@@ -97,19 +97,19 @@
         //MgCacheManager::GetInstance()->CheckPermission(resId, MgResourcePermission::ReadOnly);
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resId, L"MgServerGetSpatialContexts.GetSpatialContexts")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resId, L"MgGetSpatialContexts.GetSpatialContexts")
 
     return mgSpatialContextReader.Detach();
 }
 
-MgSpatialContextData* MgServerGetSpatialContexts::GetSpatialContextData(
+MgSpatialContextData* MgGetSpatialContexts::GetSpatialContextData(
     FdoISpatialContextReader* spatialReader, MgSpatialContextInfo* spatialContextInfo)
 {
     Ptr<MgSpatialContextData> spatialData = new MgSpatialContextData();
 
     // Name must exist
     FdoString* name = spatialReader->GetName();
-    CHECKNULL((FdoString*)name, L"MgServerGetSpatialContexts.GetSpatialContexts");
+    CHECKNULL((FdoString*)name, L"MgGetSpatialContexts.GetSpatialContexts");
     spatialData->SetName(STRING(name));
 
     STRING coordSysName = L"";
@@ -263,7 +263,7 @@
     return spatialData.Detach();
 }
 
-bool MgServerGetSpatialContexts::IsEpsgCodeRepresentation (FdoString *coordSysName)
+bool MgGetSpatialContexts::IsEpsgCodeRepresentation (FdoString *coordSysName)
 {
     // If the given coordinate system name is NULL or not NULL but empty
     // return false as those cases do not represent an EPSG code.

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -25,11 +25,11 @@
 
 class MgFeatureServiceCache;
 
-class MgServerGetSpatialContexts
+class MgGetSpatialContexts
 {
 public:
-    MgServerGetSpatialContexts();
-    ~MgServerGetSpatialContexts();
+    MgGetSpatialContexts();
+    ~MgGetSpatialContexts();
     MgSpatialContextReader* GetSpatialContexts(MgResourceIdentifier* resId);
 
 private:

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -55,6 +55,8 @@
     virtual bool SupportsSelectOrdering();
     virtual bool SupportsSelectDistinct();
 
+    virtual MgReader* ExecuteWithLock() { NOT_IMPLEMENTED(L"MgSelectAggregateCommand::ExecuteWithLock"); }
+
     virtual void Dispose()
     {
         delete this;

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -188,6 +188,15 @@
     return new MgdFeatureReader(m_connection, featureReader);
 }
 
+MgReader* MgSelectCommand::ExecuteWithLock()
+{
+    FdoPtr<FdoIFeatureReader> reader;
+    CHECKNULL((FdoISelect*)m_command, L"MgExtendedSelectCommand.Execute");
+
+    reader = m_command->ExecuteWithLock();
+    return new MgdFeatureReader(m_connection, reader);
+}
+
 bool MgSelectCommand::IsSupportedFunction(FdoFunction* fdoFunc)
 {
     FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -24,7 +24,7 @@
 
 class MgSelectCommand : public MgFeatureServiceCommand
 {
-    DECLARE_CLASSNAME(MgServerSqlProcessor)
+    DECLARE_CLASSNAME(MgSelectCommand)
 
 public:
     MgSelectCommand(MgResourceIdentifier* resource);
@@ -53,6 +53,7 @@
     virtual FdoFilter* GetFilter();
 
     virtual MgReader* Execute();
+    virtual MgReader* ExecuteWithLock();
 
     virtual bool IsSupportedFunction(FdoFunction* fdoFunc);
 

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -71,12 +71,16 @@
 
 // Executes the select features command and serializes the reader
 MgReader* MgSelectFeatures::SelectFeatures(MgResourceIdentifier* resource,
-                                                 CREFSTRING className,
-                                                 MgFeatureQueryOptions* options,
-                                                 bool executeSelectAggregate)
+                                           CREFSTRING className,
+                                           MgFeatureQueryOptions* options,
+                                           bool executeSelectAggregate,
+                                           bool isExtended,
+                                           bool withLock)
 {
     Ptr<MgReader> mgReader;
     bool isSelectAggregate = executeSelectAggregate;
+    assert(!(isSelectAggregate && isExtended));
+    assert(!(withLock && isExtended));
 
     MG_FEATURE_SERVICE_TRY()
 
@@ -118,8 +122,20 @@
     STRING fsIdStr = resource->ToString();
     ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) Testing Feature Source (%W, %W) for FDO join optimization"), fsIdStr.c_str(), className.c_str()));
 #endif  
-    if (!isSelectAggregate && bFeatureJoinProperties)
+
+    if (isExtended)
     {
+        if (bFeatureJoinProperties)
+        {
+            throw new MgInvalidOperationException(L"MgSelectFeatures.SelectFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        m_command = MgFeatureServiceCommand::CreateCommand(resource, FdoCommandType_ExtendedSelect);
+        m_command->SetFeatureClassName((FdoString*)className.c_str());
+        mgReader = SelectExtended();
+    }
+    else if (!isSelectAggregate && bFeatureJoinProperties)
+    {
         if (bSupportsFdoJoin)
         {
 #ifdef DEBUG_FDO_JOIN
@@ -302,7 +318,10 @@
         ValidateConstraintsOnCustomFunctions();
 
         // Execute the command
-        reader = m_command->Execute();
+        if (withLock)
+            reader = m_command->ExecuteWithLock();
+        else
+            reader = m_command->Execute();
 
         CHECKNULL((MgReader*)reader, L"MgServerSelectFeatures.SelectFeatures");
 
@@ -736,11 +755,7 @@
 
 void MgSelectFeatures::ValidateParam(MgResourceIdentifier* resource, CREFSTRING className)
 {
-    // className and resource identifier can not be NULL
-    if (resource == NULL)
-    {
-        throw new MgNullArgumentException(L"MgSelectFeatures::ValidateParam()", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgSelectFeatures::ValidateParam");
 
     if (className.empty())
     {
@@ -2216,3 +2231,12 @@
         }
     }
 }
+
+MgdScrollableFeatureReader* MgSelectFeatures::SelectExtended()
+{
+    Ptr<MgdScrollableFeatureReader> scrollReader;
+    ApplyQueryOptions(false);
+    scrollReader = dynamic_cast<MgdScrollableFeatureReader*>(m_command->Execute());
+    CHECKNULL(scrollReader.p, L"MgSelectFeatures::SelectExtended");
+    return scrollReader.Detach();
+}
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -36,7 +36,9 @@
     MgReader* SelectFeatures(MgResourceIdentifier* resource,
                              CREFSTRING className,
                              MgFeatureQueryOptions* options,
-                             bool isSelectAggregate);
+                             bool isSelectAggregate,
+                             bool isExtended = false,
+                             bool withLock = false);
 
 private:
     void  ApplyQueryOptions(bool isSelectAggregate);
@@ -47,6 +49,8 @@
     void  ApplyOrderingOptions();
     void  ApplyFetchSize();
 
+    MgdScrollableFeatureReader* SelectExtended();
+
     //bool HasCustomProperty() { return m_customPropertyFound; }
     //FdoFunction* GetCustomFunction() { return FDO_SAFE_ADDREF(m_customFunction); }
     //STRING GetCustomPropertyName() { return m_customPropertyName; }

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -23,11 +23,11 @@
 #include "Services/Feature/FeatureUtil.h"
 #include "Services/Transaction.h"
 
-MgServerSqlCommand::MgServerSqlCommand()
+MgSqlCommand::MgSqlCommand()
 {
 }
 
-MgServerSqlCommand::~MgServerSqlCommand()
+MgSqlCommand::~MgSqlCommand()
 {
     MG_TRY()
 
@@ -36,7 +36,7 @@
     MG_CATCH_AND_RELEASE()
 }
 
-void MgServerSqlCommand::CloseConnection()
+void MgSqlCommand::CloseConnection()
 {
     // The FDO connection must be released before the parent object is released
     m_fdoConn = NULL;
@@ -44,7 +44,7 @@
 }
 
 // Executes the describe schema command and serializes the schema to XML
-MgSqlDataReader* MgServerSqlCommand::ExecuteQuery(
+MgSqlDataReader* MgSqlCommand::ExecuteQuery(
     MgResourceIdentifier* resource,
     CREFSTRING sqlStatement,
     MgParameterCollection* params,
@@ -60,7 +60,7 @@
 
     // Create the SQL command
     FdoPtr<FdoISQLCommand> fdoCommand = (FdoISQLCommand*)m_fdoConn->CreateCommand(FdoCommandType_SQLCommand);
-    CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgServerSqlCommand.ExecuteQuery");
+    CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgSqlCommand.ExecuteQuery");
 
     // Set SQL statement
     fdoCommand->SetSQLStatement((FdoString*)sqlStatement.c_str());
@@ -78,22 +78,22 @@
 
     // Execute the command
     FdoPtr<FdoISQLDataReader> sqlReader = fdoCommand->ExecuteReader();
-    CHECKNULL((FdoISQLDataReader*)sqlReader, L"MgServerSqlCommand.ExecuteQuery");
+    CHECKNULL((FdoISQLDataReader*)sqlReader, L"MgSqlCommand.ExecuteQuery");
 
     // Update parameter whose direction is InputOutput, Output, or Return.
     if (NULL != params && params->GetCount() > 0)
         MgFeatureUtil::UpdateParameterCollection(fdoParams, params);
 
     mgSqlDataReader = new MgdSqlDataReader(m_featureConnection, sqlReader); //, m_providerName);
-    CHECKNULL((MgSqlDataReader*)mgSqlDataReader, L"MgServerSqlCommand.ExecuteQuery");
+    CHECKNULL((MgSqlDataReader*)mgSqlDataReader, L"MgSqlCommand.ExecuteQuery");
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerSqlCommand.ExecuteQuery")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgSqlCommand.ExecuteQuery")
 
     return mgSqlDataReader.Detach();
 }
 
 // Executes the describe schema command and serializes the schema to XML
-INT32 MgServerSqlCommand::ExecuteNonQuery(
+INT32 MgSqlCommand::ExecuteNonQuery(
     MgResourceIdentifier* resource,
     CREFSTRING sqlStatement,
     MgParameterCollection* params,
@@ -108,7 +108,7 @@
 
     // Create the SQL command
     FdoPtr<FdoISQLCommand> fdoCommand = (FdoISQLCommand*)m_fdoConn->CreateCommand(FdoCommandType_SQLCommand);
-    CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgServerSqlCommand.ExecuteQuery");
+    CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgSqlCommand.ExecuteQuery");
 
     // Set SQL statement
     fdoCommand->SetSQLStatement((FdoString*)sqlStatement.c_str());
@@ -128,18 +128,18 @@
     if (NULL != params && params->GetCount() > 0)
         MgFeatureUtil::UpdateParameterCollection(fdoParams, params);
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerSqlCommand.ExecuteQuery")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgSqlCommand.ExecuteQuery")
 
     return rowsAffected;
 }
 
 
-void MgServerSqlCommand::Validate(MgResourceIdentifier* resource, CREFSTRING sqlStatement, INT32 commandType, MgTransaction* transaction)
+void MgSqlCommand::Validate(MgResourceIdentifier* resource, CREFSTRING sqlStatement, INT32 commandType, MgTransaction* transaction)
 {
     // SQL statement can not be empty
     if (resource == NULL)
     {
-        throw new MgNullArgumentException(L"MgServerSqlCommand.Validate", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgNullArgumentException(L"MgSqlCommand.Validate", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     if (sqlStatement.empty())
@@ -148,7 +148,7 @@
         arguments.Add(L"2");
         arguments.Add(MgResources::BlankArgument);
 
-        throw new MgInvalidArgumentException(L"MgServerSqlCommand.Validate",
+        throw new MgInvalidArgumentException(L"MgSqlCommand.Validate",
             __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
     }
 
@@ -178,11 +178,11 @@
         {
             // TODO: specify which argument and message, once we have the mechanism
             STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-            throw new MgInvalidOperationException(L"MgServerSqlCommand.Validate", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgInvalidOperationException(L"MgSqlCommand.Validate", __LINE__, __WFILE__, NULL, L"", NULL);
         }
     }
     else
     {
-        throw new MgConnectionFailedException(L"MgServerSqlCommand::Validate", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgConnectionFailedException(L"MgSqlCommand::Validate", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 }

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -25,11 +25,11 @@
 
 class MgFeatureConnection;
 
-class MgServerSqlCommand
+class MgSqlCommand
 {
 public:
-    MgServerSqlCommand();
-    ~MgServerSqlCommand();
+    MgSqlCommand();
+    ~MgSqlCommand();
     MgSqlDataReader* ExecuteQuery(
                         MgResourceIdentifier* resource,
                         CREFSTRING sqlStatement,

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -24,16 +24,16 @@
 #include "Services/Feature/FeatureServiceCache.h"
 #include "Services/Transaction.h"
 
-MgServerUpdateFeatures::MgServerUpdateFeatures()
+MgUpdateFeaturesCommand::MgUpdateFeaturesCommand()
 {
     m_SrvrFeatConn = NULL;
 }
 
-MgServerUpdateFeatures::~MgServerUpdateFeatures()
+MgUpdateFeaturesCommand::~MgUpdateFeaturesCommand()
 {
 }
 
-void MgServerUpdateFeatures::Connect(MgResourceIdentifier* resource, MgTransaction* transaction)
+void MgUpdateFeaturesCommand::Connect(MgResourceIdentifier* resource, MgTransaction* transaction)
 {
     if (NULL == transaction)
     {
@@ -48,13 +48,13 @@
     if ((NULL != m_SrvrFeatConn.p) && ( !m_SrvrFeatConn->IsConnectionOpen() ))
     {
 
-        throw new MgConnectionFailedException(L"MgServerUpdateFeatures::MgServerUpdateFeatures()",
+        throw new MgConnectionFailedException(L"MgUpdateFeaturesCommand::MgUpdateFeaturesCommand()",
             __LINE__, __WFILE__, NULL, L"", NULL);
     }
 }
 
 // Executes the commands
-MgPropertyCollection* MgServerUpdateFeatures::Execute(MgResourceIdentifier* resource,
+MgPropertyCollection* MgUpdateFeaturesCommand::Execute(MgResourceIdentifier* resource,
                                                       MgFeatureCommandCollection* commands,
                                                       bool useTransaction)
 {
@@ -66,7 +66,7 @@
 
     if (resource == NULL || commands == NULL)
     {
-        throw new MgNullArgumentException(L"MgServerUpdateFeatures.UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgNullArgumentException(L"MgUpdateFeaturesCommand.UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     INT32 cnt = commands->GetCount();
@@ -76,7 +76,7 @@
         arguments.Add(L"2");
         arguments.Add(L"0");
 
-        throw new MgInvalidArgumentException(L"MgServerUpdateFeatures.UpdateFeatures",
+        throw new MgInvalidArgumentException(L"MgUpdateFeaturesCommand.UpdateFeatures",
             __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
     }
 
@@ -101,7 +101,7 @@
         // Execute the manipulation command
         result = fmServerCommand->Execute();
 
-        MG_FEATURE_SERVICE_CATCH(L"MgServerUpdateFeatures.UpdateFeatures")
+        MG_FEATURE_SERVICE_CATCH(L"MgUpdateFeaturesCommand.UpdateFeatures")
 
         if (transaction != NULL)
         {
@@ -135,7 +135,7 @@
         commited = true;
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerUpdateFeatures.UpdateFeatures")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgUpdateFeaturesCommand.UpdateFeatures")
 
     if (transaction != NULL && !commited)
     {
@@ -148,7 +148,7 @@
 }
 
 // Executes the commands
-MgPropertyCollection* MgServerUpdateFeatures::Execute(MgResourceIdentifier* resource,
+MgPropertyCollection* MgUpdateFeaturesCommand::Execute(MgResourceIdentifier* resource,
                                                       MgFeatureCommandCollection* commands,
                                                       MgTransaction* transaction)
 {
@@ -158,7 +158,7 @@
 
     if (resource == NULL || commands == NULL)
     {
-        throw new MgNullArgumentException(L"MgServerUpdateFeatures.UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgNullArgumentException(L"MgUpdateFeaturesCommand.UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     INT32 cnt = commands->GetCount();
@@ -168,7 +168,7 @@
         arguments.Add(L"2");
         arguments.Add(L"0");
 
-        throw new MgInvalidArgumentException(L"MgServerUpdateFeatures.UpdateFeatures",
+        throw new MgInvalidArgumentException(L"MgUpdateFeaturesCommand.UpdateFeatures",
             __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
     }
 
@@ -187,7 +187,7 @@
         // Execute the manipulation command
         result = fmServerCommand->Execute();
 
-        MG_FEATURE_SERVICE_CATCH(L"MgServerUpdateFeatures.UpdateFeatures")
+        MG_FEATURE_SERVICE_CATCH(L"MgUpdateFeaturesCommand.UpdateFeatures")
 
         if (transaction != NULL)
         {
@@ -215,7 +215,278 @@
         }
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerUpdateFeatures.UpdateFeatures")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgUpdateFeaturesCommand.UpdateFeatures")
 
     return propCol.Detach();
 }
+
+MgFeatureReader* MgUpdateFeaturesCommand::ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues, MgTransaction* trans)
+{
+    Ptr<MgFeatureReader> reader;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgUpdateFeaturesCommand::ExecuteInsert");
+	CHECKARGUMENTNULL(propertyValues, L"MgUpdateFeaturesCommand::ExecuteInsert");
+	if (className.empty())
+		throw new MgNullArgumentException(L"MgUpdateFeaturesCommand::ExecuteInsert", __LINE__, __WFILE__, NULL, L"", NULL);
+	
+    Ptr<MgFeatureConnection> connWrap;
+	FdoPtr<FdoIConnection> conn;
+    FdoPtr<FdoITransaction> fdoTrans;
+    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
+    if (NULL != mgTrans)
+    {
+        SAFE_ADDREF(mgTrans.p);
+        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
+        //Check that the transaction originates from the same feature source
+        if (origFeatureSource->ToString() != resource->ToString())
+            throw new MgInvalidArgumentException(L"MgUpdateFeaturesCommand::ExecuteInsert", __LINE__, __WFILE__, NULL, L"", NULL);
+
+        connWrap = mgTrans->GetConnection(); //Connection is already open
+        fdoTrans = mgTrans->GetFdoTransaction();
+    }
+    else
+    {    
+        connWrap = new MgFeatureConnection(resource);
+    }
+
+    conn = connWrap->GetConnection();
+	FdoPtr<FdoIInsert> insert = (FdoIInsert*)conn->CreateCommand(FdoCommandType_Insert);
+	
+	insert->SetFeatureClassName(className.c_str());
+
+	FdoPtr<FdoPropertyValueCollection> propVals = insert->GetPropertyValues();
+	for (INT32 i = 0; i < propertyValues->GetCount(); i++)
+	{
+		Ptr<MgProperty> mgp = propertyValues->GetItem(i);
+		FdoPtr<FdoPropertyValue> pv = MgFeatureUtil::MgPropertyToFdoProperty(mgp);
+
+		propVals->Add(pv);
+	}
+
+    if (NULL != fdoTrans.p)
+        insert->SetTransaction(fdoTrans);
+
+	FdoPtr<FdoIFeatureReader> insertRes = insert->Execute();
+
+	reader = new MgdFeatureReader(connWrap, insertRes);
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgUpdateFeaturesCommand::ExecuteInsert", resource)
+
+    return reader.Detach();
+}
+
+
+MgPropertyCollection* MgUpdateFeaturesCommand::ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans)
+{
+    Ptr<MgPropertyCollection> ret;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgUpdateFeaturesCommand::ExecuteInsert");
+	CHECKARGUMENTNULL(batchPropertyValues, L"MgUpdateFeaturesCommand::ExecuteInsert");
+	if (className.empty())
+		throw new MgNullArgumentException(L"MgUpdateFeaturesCommand::ExecuteInsert", __LINE__, __WFILE__, NULL, L"", NULL);
+	
+    ret = new MgPropertyCollection();
+
+    Ptr<MgFeatureConnection> connWrap;
+	FdoPtr<FdoIConnection> conn;
+    FdoPtr<FdoITransaction> fdoTrans;
+    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
+    if (NULL != mgTrans)
+    {
+        SAFE_ADDREF(mgTrans.p);
+        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
+        //Check that the transaction originates from the same feature source
+        if (origFeatureSource->ToString() != resource->ToString())
+            throw new MgInvalidArgumentException(L"MgUpdateFeaturesCommand::ExecuteInsert", __LINE__, __WFILE__, NULL, L"", NULL);
+
+        connWrap = mgTrans->GetConnection(); //Connection is already open
+        fdoTrans = mgTrans->GetFdoTransaction();
+    }
+    else
+    {    
+        connWrap = new MgFeatureConnection(resource);
+    }
+
+    conn = connWrap->GetConnection();
+	FdoPtr<FdoIInsert> insert = (FdoIInsert*)conn->CreateCommand(FdoCommandType_Insert);
+	
+	insert->SetFeatureClassName(className.c_str());
+
+	FdoPtr<FdoPropertyValueCollection> propVals = insert->GetPropertyValues();
+	
+    if (NULL != fdoTrans.p)
+        insert->SetTransaction(fdoTrans);
+
+    //TODO: Support batch parameters, the main beneficiary of this API. Even then,
+    //the value flipping approach employed here has performance benefits for certain
+    //providers, like SQLite
+
+    for (INT32 i = 0; i < batchPropertyValues->GetCount(); i++)
+    {
+        Ptr<MgPropertyCollection> propertyValues = batchPropertyValues->GetItem(i);
+
+        //First feature, set up the FDO property value collection
+        if (i == 0)
+        {
+            for (INT32 i = 0; i < propertyValues->GetCount(); i++)
+	        {
+		        Ptr<MgProperty> mgp = propertyValues->GetItem(i);
+		        FdoPtr<FdoPropertyValue> pv = MgFeatureUtil::MgPropertyToFdoProperty(mgp);
+
+		        propVals->Add(pv);
+	        }
+        }
+        else //Feature after the first
+        {
+            //Set all to null
+            for (INT32 i = 0; i < propVals->GetCount(); i++)
+            {
+                FdoPtr<FdoPropertyValue> fp = propVals->GetItem(i);
+                FdoPtr<FdoValueExpression> expr = fp->GetValue();
+                FdoDataValue* fdv = dynamic_cast<FdoDataValue*>(expr.p);
+                FdoGeometryValue* fgv = dynamic_cast<FdoGeometryValue*>(expr.p);
+                if (fdv)
+                {
+                    fdv->SetNull();
+                }
+                else if (fgv)
+                {
+                    fgv->SetNullValue();
+                }
+            }
+
+            //Now set the appropriate values. MgFeatureUtil does the work
+            for (INT32 i = 0; i < propertyValues->GetCount(); i++)
+	        {
+                Ptr<MgNullableProperty> mgp = (MgNullableProperty*)propertyValues->GetItem(i);
+                if (!mgp->IsNull())
+                {
+                    FdoPtr<FdoPropertyValue> fp = propVals->GetItem(mgp->GetName().c_str());
+                    MgFeatureUtil::UpdateFdoPropertyValue(fp, mgp);
+                }
+            }
+        }
+
+        STRING sIndex;
+        MgUtil::Int32ToString(i, sIndex);
+
+        //Insert and stash the result in the property collection
+	    FdoPtr<FdoIFeatureReader> insertRes = insert->Execute();
+
+	    Ptr<MgFeatureReader> fr = new MgdFeatureReader(connWrap, insertRes);
+        Ptr<MgFeatureProperty> fp = new MgFeatureProperty(sIndex, fr);
+        ret->Add(fp);
+    }
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgUpdateFeaturesCommand::ExecuteInsert", resource)
+
+    return ret.Detach();
+}
+
+int MgUpdateFeaturesCommand::ExecuteUpdate(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues, CREFSTRING filter, MgTransaction* trans)
+{
+    int updated = 0;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgUpdateFeaturesCommand::ExecuteUpdate");
+	CHECKARGUMENTNULL(propertyValues, L"MgUpdateFeaturesCommand::ExecuteUpdate");
+	if (className.empty())
+		throw new MgNullArgumentException(L"MgUpdateFeaturesCommand::ExecuteUpdate", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    Ptr<MgFeatureConnection> connWrap;
+	FdoPtr<FdoIConnection> conn;
+    FdoPtr<FdoITransaction> fdoTrans;
+    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
+    if (NULL != mgTrans)
+    {
+        SAFE_ADDREF(mgTrans.p);
+        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
+        //Check that the transaction originates from the same feature source
+        if (origFeatureSource->ToString() != resource->ToString())
+            throw new MgInvalidArgumentException(L"MgUpdateFeaturesCommand::ExecuteUpdate", __LINE__, __WFILE__, NULL, L"", NULL);
+
+        connWrap = mgTrans->GetConnection(); //Connection is already open
+        fdoTrans = mgTrans->GetFdoTransaction();
+    }
+    else
+    {
+        connWrap = new MgFeatureConnection(resource);
+    }
+
+    conn = connWrap->GetConnection();
+	FdoPtr<FdoIUpdate> update = (FdoIUpdate*)conn->CreateCommand(FdoCommandType_Update);
+	update->SetFeatureClassName(className.c_str());
+	
+	if (!filter.empty())
+		update->SetFilter(filter.c_str());
+
+    if (NULL != fdoTrans.p)
+        update->SetTransaction(fdoTrans);
+
+	FdoPtr<FdoPropertyValueCollection> propVals = update->GetPropertyValues();
+	for (INT32 i = 0; i < propertyValues->GetCount(); i++)
+	{
+		Ptr<MgProperty> mgp = propertyValues->GetItem(i);
+		FdoPtr<FdoPropertyValue> pv = MgFeatureUtil::MgPropertyToFdoProperty(mgp);
+
+		propVals->Add(pv);
+	}
+
+	updated = update->Execute();
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgUpdateFeaturesCommand::ExecuteUpdate", resource)
+
+    return updated;
+}
+
+int MgUpdateFeaturesCommand::ExecuteDelete(MgResourceIdentifier* resource, CREFSTRING className, CREFSTRING filter, MgTransaction* trans)
+{
+    int deleted = 0;
+
+    MG_FEATURE_SERVICE_TRY()
+
+    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgUpdateFeaturesCommand::ExecuteDelete");
+	if (className.empty())
+		throw new MgNullArgumentException(L"MgUpdateFeaturesCommand::ExecuteDelete", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    Ptr<MgFeatureConnection> connWrap;
+	FdoPtr<FdoIConnection> conn;
+    FdoPtr<FdoITransaction> fdoTrans;
+
+    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
+    if (NULL != mgTrans)
+    {
+        SAFE_ADDREF(mgTrans.p);
+        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
+        //Check that the transaction originates from the same feature source
+        if (origFeatureSource->ToString() != resource->ToString())
+            throw new MgInvalidArgumentException(L"MgUpdateFeaturesCommand::ExecuteDelete", __LINE__, __WFILE__, NULL, L"", NULL);
+
+        connWrap = mgTrans->GetConnection(); //Connection is already open
+        fdoTrans = mgTrans->GetFdoTransaction();
+    }
+    else
+    {
+        connWrap = new MgFeatureConnection(resource);
+    }
+
+    conn = connWrap->GetConnection();
+	FdoPtr<FdoIDelete> fdoDelete = (FdoIDelete*)conn->CreateCommand(FdoCommandType_Delete);
+	fdoDelete->SetFeatureClassName(className.c_str());
+    if (!filter.empty())
+	    fdoDelete->SetFilter(filter.c_str());
+    
+    if (NULL != fdoTrans.p)
+        fdoDelete->SetTransaction(fdoTrans);
+
+	deleted = fdoDelete->Execute();
+
+    MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgUpdateFeaturesCommand::ExecuteDelete", resource)
+
+    return deleted;
+}

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -27,11 +27,11 @@
 class MgFeatureCommandCollection;
 class MgIntCollection;
 
-class MgServerUpdateFeatures
+class MgUpdateFeaturesCommand
 {
 public:
-    MgServerUpdateFeatures();
-    ~MgServerUpdateFeatures();
+    MgUpdateFeaturesCommand();
+    ~MgUpdateFeaturesCommand();
     MgPropertyCollection* Execute(MgResourceIdentifier* resource,
                                   MgFeatureCommandCollection* commands,
                                   bool useTransaction);
@@ -40,6 +40,22 @@
                                   MgFeatureCommandCollection* commands,
                                   MgTransaction* transaction);
 
+    MgFeatureReader* ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues);
+
+    MgFeatureReader* ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues, MgTransaction* trans);
+
+    MgPropertyCollection* ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues);
+
+    MgPropertyCollection* ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans);
+
+	int ExecuteUpdate(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues, CREFSTRING filter);
+
+    int ExecuteUpdate(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues, CREFSTRING filter, MgTransaction* trans);
+
+	int ExecuteDelete(MgResourceIdentifier* resource, CREFSTRING className, CREFSTRING filter);
+
+	int ExecuteDelete(MgResourceIdentifier* resource, CREFSTRING className, CREFSTRING filter, MgTransaction* trans);
+
 private:
     void Connect(MgResourceIdentifier* resource, MgTransaction* transaction);
 

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -24,42 +24,21 @@
 #include "Services/Feature/GwsConnectionPool.h"
 #include "GwsQueryEngineImp.h"
 
-static std::map<FdoThreadCapability, std::string>          s_FdoThreadCapability;
-static std::map<FdoSpatialContextExtentType, std::string>  s_FdoSpatialContextExtentType;
-static std::map<FdoClassType, std::string>                 s_FdoClassType;
-static std::map<FdoDataType,  std::string>                 s_FdoDataType;
-static std::map<FdoPropertyType,  std::string>             s_FdoPropertyTypeAsString;
-static std::map<FdoFunctionCategoryType,  std::string>     s_FdoFunctionCategoryType;
-static std::map<FdoCommandType,  std::string>              s_FdoCommandType;
-static std::map<FdoConditionType,  std::string>            s_FdoConditionType;
-static std::map<FdoSpatialOperations,  std::string>        s_FdoSpatialOperations;
-static std::map<FdoDistanceOperations,  std::string>       s_FdoDistanceOperations;
-static std::map<FdoExpressionType,  std::string>           s_FdoExpressionType;
-static std::map<FdoGeometryType,  std::string>             s_FdoGeometryType;
-static std::map<FdoGeometryComponentType,  std::string>    s_FdoGeometryComponentType;
+#include "Services/Feature/Commands/ApplySchema.h"
+#include "Services/Feature/Commands/DescribeSchema.h"
+#include "Services/Feature/Commands/GetConnectionPropertyValues.h"
+#include "Services/Feature/Commands/GetFeatureProviders.h"
+#include "Services/Feature/Commands/GetLongTransactions.h"
+#include "Services/Feature/Commands/GetProviderCapabilities.h"
+#include "Services/Feature/Commands/GetSchemaMapping.h"
+#include "Services/Feature/Commands/GetSpatialContexts.h"
+#include "Services/Feature/Commands/SelectFeatures.h"
+#include "Services/Feature/Commands/SqlCommand.h"
+#include "Services/Feature/Commands/UpdateFeatures.h"
 
-bool MgdFeatureService::m_isInitialized = MgdFeatureService::Initialize();
-
 MgdFeatureService::MgdFeatureService() 
 : MgFeatureService()
 { 
-	// Set a default join query batch size
-    m_nJoinQueryBatchSize = MgConfigProperties::DefaultFeatureServicePropertyJoinQueryBatchSize;
-
-    MgConfiguration* config = MgConfiguration::GetInstance();
-    if(config)
-    {
-        // Get the join batch size
-        config->GetIntValue(MgConfigProperties::FeatureServicePropertiesSection,
-                            MgConfigProperties::FeatureServicePropertyJoinQueryBatchSize,
-                            m_nJoinQueryBatchSize,
-                            MgConfigProperties::DefaultFeatureServicePropertyJoinQueryBatchSize);
-        // Get data cache size
-        config->GetIntValue(MgConfigProperties::FeatureServicePropertiesSection,
-                            MgConfigProperties::FeatureServicePropertyDataCacheSize,
-                            m_nDataCacheSize,
-                            MgConfigProperties::DefaultFeatureServicePropertyDataCacheSize);
-    }
 }
 
 MgdFeatureService::~MgdFeatureService() 
@@ -67,165 +46,6 @@
 	
 }
 
-bool MgdFeatureService::Initialize()
-{
-    // Thread Capability
-    s_FdoThreadCapability[FdoThreadCapability_SingleThreaded]           = "SingleThreaded";
-    s_FdoThreadCapability[FdoThreadCapability_PerConnectionThreaded]    = "PerConnectionThreaded";
-    s_FdoThreadCapability[FdoThreadCapability_PerCommandThreaded]       = "PerCommandThreaded";
-    s_FdoThreadCapability[FdoThreadCapability_MultiThreaded]            = "MultiThreaded";
-
-    // Spatial Extent type
-    s_FdoSpatialContextExtentType[FdoSpatialContextExtentType_Static]   = "Static";
-    s_FdoSpatialContextExtentType[FdoSpatialContextExtentType_Dynamic]  = "Dynamic";
-
-    // Class Types
-    s_FdoClassType[FdoClassType_Class]                  = "Class";
-    s_FdoClassType[FdoClassType_FeatureClass]           = "FeatureClass";
-    s_FdoClassType[FdoClassType_NetworkClass]           = "NetworkClass";
-    s_FdoClassType[FdoClassType_NetworkLayerClass]      = "NetworkLayerClass";
-    s_FdoClassType[FdoClassType_NetworkNodeClass]       = "NetworkNodeClass";
-
-    // Data types
-    s_FdoDataType[FdoDataType_Boolean]     = "Boolean";
-    s_FdoDataType[FdoDataType_Byte]        = "Byte";
-    s_FdoDataType[FdoDataType_DateTime]    = "DateTime";
-    // Implementation Note:  FdoDataType_Decimal is currently mapped to MgPropertyType::Double.
-    // An MgDecimalProperty class should be implemented in a future release.
-    s_FdoDataType[FdoDataType_Decimal]     = "Double";
-    s_FdoDataType[FdoDataType_Double]      = "Double";
-    s_FdoDataType[FdoDataType_Int16]       = "Int16";
-    s_FdoDataType[FdoDataType_Int32]       = "Int32";
-    s_FdoDataType[FdoDataType_Int64]       = "Int64";
-    s_FdoDataType[FdoDataType_Single]      = "Single";
-    s_FdoDataType[FdoDataType_String]      = "String";
-    s_FdoDataType[FdoDataType_BLOB]        = "BLOB";
-    s_FdoDataType[FdoDataType_CLOB]        = "CLOB";
-
-    s_FdoPropertyTypeAsString[FdoPropertyType_DataProperty]     = "Data";
-    s_FdoPropertyTypeAsString[FdoPropertyType_GeometricProperty]        = "Geometry";
-    s_FdoPropertyTypeAsString[FdoPropertyType_ObjectProperty]        = "Object";
-    s_FdoPropertyTypeAsString[FdoPropertyType_AssociationProperty]        = "Association";
-    s_FdoPropertyTypeAsString[FdoPropertyType_RasterProperty]        = "Raster";
-
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Aggregate] = "Aggregate";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Conversion] = "Conversion";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Custom] = "Custom";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Date] = "Date";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Geometry] = "Geometry";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Math] = "Math";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Numeric] = "Numeric";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_String] = "String";
-    s_FdoFunctionCategoryType[FdoFunctionCategoryType_Unspecified] = "Unspecified";
-
-    // Commands
-    s_FdoCommandType[FdoCommandType_Select]                             = "Select";
-    s_FdoCommandType[FdoCommandType_Insert]                             = "Insert";
-    s_FdoCommandType[FdoCommandType_Delete]                             = "Delete";
-    s_FdoCommandType[FdoCommandType_Update]                             = "Update";
-    //s_FdoCommandType[FdoCommandType_ExtendedSelect]                     = "ExtendedSelect";
-    s_FdoCommandType[FdoCommandType_DescribeSchema]                     = "DescribeSchema";
-    s_FdoCommandType[FdoCommandType_DescribeSchemaMapping]              = "DescribeSchemaMapping";
-    s_FdoCommandType[FdoCommandType_ApplySchema]                        = "ApplySchema";
-    s_FdoCommandType[FdoCommandType_DestroySchema]                      = "DestroySchema";
-    s_FdoCommandType[FdoCommandType_ActivateSpatialContext]             = "ActivateSpatialContext";
-    s_FdoCommandType[FdoCommandType_CreateSpatialContext]               = "CreateSpatialContext";
-    s_FdoCommandType[FdoCommandType_DestroySpatialContext]              = "DestroySpatialContext";
-    s_FdoCommandType[FdoCommandType_GetSpatialContexts]                 = "GetSpatialContexts";
-    s_FdoCommandType[FdoCommandType_CreateMeasureUnit]                  = "CreateMeasureUnit";
-    s_FdoCommandType[FdoCommandType_DestroyMeasureUnit]                 = "DestroyMeasureUnit";
-    s_FdoCommandType[FdoCommandType_GetMeasureUnits]                    = "GetMeasureUnits";
-    s_FdoCommandType[FdoCommandType_SQLCommand]                         = "SQLCommand";
-    s_FdoCommandType[FdoCommandType_AcquireLock]                        = "AcquireLock";
-    s_FdoCommandType[FdoCommandType_GetLockInfo]                        = "GetLockInfo";
-    s_FdoCommandType[FdoCommandType_GetLockedObjects]                   = "GetLockedObjects";
-    s_FdoCommandType[FdoCommandType_GetLockOwners]                      = "GetLockOwners";
-    s_FdoCommandType[FdoCommandType_ReleaseLock]                        = "ReleaseLock";
-    s_FdoCommandType[FdoCommandType_ActivateLongTransaction]            = "ActivateLongTransaction";
-    s_FdoCommandType[FdoCommandType_DeactivateLongTransaction]          = "DeactivateLongTransaction";
-    s_FdoCommandType[FdoCommandType_CommitLongTransaction]              = "CommitLongTransaction";
-    s_FdoCommandType[FdoCommandType_CreateLongTransaction]              = "CreateLongTransaction";
-    s_FdoCommandType[FdoCommandType_GetLongTransactions]                = "GetLongTransactions";
-    s_FdoCommandType[FdoCommandType_FreezeLongTransaction]              = "FreezeLongTransaction";
-    s_FdoCommandType[FdoCommandType_RollbackLongTransaction]            = "RollbackLongTransaction";
-    s_FdoCommandType[FdoCommandType_ActivateLongTransactionCheckpoint]  = "ActivateLongTransactionCheckpoint";
-    s_FdoCommandType[FdoCommandType_CreateLongTransactionCheckpoint]    = "CreateLongTransactionCheckpoint";
-    s_FdoCommandType[FdoCommandType_GetLongTransactionCheckpoints]      = "GetLongTransactionCheckpoints";
-    s_FdoCommandType[FdoCommandType_RollbackLongTransactionCheckpoint]  = "RollbackLongTransactionCheckpoint";
-    s_FdoCommandType[FdoCommandType_ChangeLongTransactionPrivileges]    = "ChangeLongTransactionPrivileges";
-    s_FdoCommandType[FdoCommandType_GetLongTransactionPrivileges]       = "GetLongTransactionPrivileges";
-    s_FdoCommandType[FdoCommandType_ChangeLongTransactionSet]           = "ChangeLongTransactionSet";
-    s_FdoCommandType[FdoCommandType_GetLongTransactionsInSet]           = "GetLongTransactionsInSet";
-    s_FdoCommandType[FdoCommandType_NetworkShortestPath]                = "NetworkShortestPath";
-    s_FdoCommandType[FdoCommandType_NetworkAllPaths]                    = "NetworkAllPaths";
-    s_FdoCommandType[FdoCommandType_NetworkReachableNodes]              = "NetworkReachableNodes";
-    s_FdoCommandType[FdoCommandType_NetworkReachingNodes]               = "NetworkReachingNodes";
-    s_FdoCommandType[FdoCommandType_NetworkNearestNeighbors]            = "NetworkNearestNeighbors";
-    s_FdoCommandType[FdoCommandType_NetworkWithinCost]                  = "NetworkWithinCost";
-    s_FdoCommandType[FdoCommandType_NetworkTSP]                         = "NetworkTSP";
-    s_FdoCommandType[FdoCommandType_ActivateTopologyArea]               = "ActivateTopologyArea";
-    s_FdoCommandType[FdoCommandType_DeactivateTopologyArea]             = "DeactivateTopologyArea";
-    s_FdoCommandType[FdoCommandType_ActivateTopologyInCommandResult]    = "ActivateTopologyInCommandResult";
-    s_FdoCommandType[FdoCommandType_DeactivateTopologyInCommandResults] = "DeactivateTopologyInCommandResults";
-    s_FdoCommandType[FdoCommandType_SelectAggregates]                   = "SelectAggregates";
-    s_FdoCommandType[FdoCommandType_CreateDataStore]                    = "CreateDataStore";
-    s_FdoCommandType[FdoCommandType_DestroyDataStore]                   = "DestroyDataStore";
-    s_FdoCommandType[FdoCommandType_ListDataStores]                     = "ListDataStores";
-    s_FdoCommandType[FdoCommandType_FirstProviderCommand]               = "FirstProviderCommand";
-
-    // Condition types
-    s_FdoConditionType[FdoConditionType_Comparison]                     = "Comparison";
-    s_FdoConditionType[FdoConditionType_Like]                           = "Like";
-    s_FdoConditionType[FdoConditionType_In]                             = "In";
-    s_FdoConditionType[FdoConditionType_Null]                           = "Null";
-    s_FdoConditionType[FdoConditionType_Spatial]                        = "Spatial";
-    s_FdoConditionType[FdoConditionType_Distance]                       = "Distance";
-
-    // Spatial Operations
-    s_FdoSpatialOperations[FdoSpatialOperations_Contains]               = "Contains";
-    s_FdoSpatialOperations[FdoSpatialOperations_Crosses]                = "Crosses";
-    s_FdoSpatialOperations[FdoSpatialOperations_Disjoint]               = "Disjoint";
-    s_FdoSpatialOperations[FdoSpatialOperations_Equals]                 = "Equals";
-    s_FdoSpatialOperations[FdoSpatialOperations_Intersects]             = "Intersects";
-    s_FdoSpatialOperations[FdoSpatialOperations_Overlaps]               = "Overlaps";
-    s_FdoSpatialOperations[FdoSpatialOperations_Touches]                = "Touches";
-    s_FdoSpatialOperations[FdoSpatialOperations_Within]                 = "Within";
-    s_FdoSpatialOperations[FdoSpatialOperations_CoveredBy]              = "CoveredBy";
-    s_FdoSpatialOperations[FdoSpatialOperations_Inside]                 = "Inside";
-    s_FdoSpatialOperations[FdoSpatialOperations_EnvelopeIntersects]     = "EnvelopeIntersects";
-
-    // Distance Operation
-    s_FdoDistanceOperations[FdoDistanceOperations_Beyond]               = "Beyond";
-    s_FdoDistanceOperations[FdoDistanceOperations_Within]               = "Within";
-
-    // Expression Type
-    s_FdoExpressionType[FdoExpressionType_Basic]                        = "Basic";
-    s_FdoExpressionType[FdoExpressionType_Function]                     = "Function";
-    s_FdoExpressionType[FdoExpressionType_Parameter]                    = "Parameter";
-
-    // Geometry Type
-    s_FdoGeometryType[FdoGeometryType_None]                     = "None";
-    s_FdoGeometryType[FdoGeometryType_Point]                    = "Point";
-    s_FdoGeometryType[FdoGeometryType_LineString]               = "LineString";
-    s_FdoGeometryType[FdoGeometryType_Polygon]                  = "Polygon";
-    s_FdoGeometryType[FdoGeometryType_MultiPoint]               = "MultiPoint";
-    s_FdoGeometryType[FdoGeometryType_MultiLineString]          = "MultiLineString";
-    s_FdoGeometryType[FdoGeometryType_MultiPolygon]             = "MultiPolygon";
-    s_FdoGeometryType[FdoGeometryType_MultiGeometry]            = "MultiGeometry";
-    s_FdoGeometryType[FdoGeometryType_CurveString]              = "CurveString";
-    s_FdoGeometryType[FdoGeometryType_CurvePolygon]             = "CurvePolygon";
-    s_FdoGeometryType[FdoGeometryType_MultiCurveString]         = "MultiCurveString";
-    s_FdoGeometryType[FdoGeometryType_MultiCurvePolygon]        = "MultiCurvePolygon";
-
-    // Geometry component type
-    s_FdoGeometryComponentType[FdoGeometryComponentType_LinearRing]         = "LinearRing";
-    s_FdoGeometryComponentType[FdoGeometryComponentType_CircularArcSegment] = "ArcSegment";
-    s_FdoGeometryComponentType[FdoGeometryComponentType_LineStringSegment]  = "LinearSegment";
-    s_FdoGeometryComponentType[FdoGeometryComponentType_Ring]               = "CurveRing";
-
-    return true;
-}
-
 MgByteReader* MgdFeatureService::GetFeatureProviders() 
 { 
     Ptr<MgByteReader> reader;
@@ -234,154 +54,9 @@
 
     MG_FEATURE_SERVICE_TRY()
 
-    MG_LOG_OPERATION_MESSAGE_INIT(MG_API_VERSION(1, 0, 0), 0);
-    MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
-    MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+    MgGetFeatureProviders getProviders;
+    reader = getProviders.GetFeatureProviders();
 
-    MG_LOG_TRACE_ENTRY(L"MgdFeatureService::GetFeatureProviders()");
-
-    STRING xml = L"<FeatureProviderRegistry>\n";
-
-    FdoPtr<IProviderRegistry> reg = FdoFeatureAccessManager::GetProviderRegistry();
-    const FdoProviderCollection* providers = reg->GetProviders();
-    FdoPtr<IConnectionManager> connMgr = FdoFeatureAccessManager::GetConnectionManager();
-
-    for (INT32 i = 0; i < providers->GetCount(); i++)
-    {
-        FdoPtr<FdoProvider> provider;
-        FdoString* name = NULL;
-        FdoString* disp = NULL;
-        FdoString* desc = NULL;
-        FdoString* ver = NULL;
-        FdoString* fdoVer = NULL;
-
-        FdoPtr<FdoIConnection> conn;
-        FdoPtr<FdoIConnectionInfo> connInfo;
-        FdoPtr<FdoIConnectionPropertyDictionary> connDict;
-
-        bool ok = false;
-        try 
-        {
-            provider = providers->GetItem(i);
-            name = provider->GetName();
-            disp = provider->GetDisplayName();
-            desc = provider->GetDescription();
-            ver = provider->GetVersion();
-            fdoVer = provider->GetFeatureDataObjectsVersion();
-
-            conn = connMgr->CreateConnection(name);
-            connInfo = conn->GetConnectionInfo();
-            connDict = connInfo->GetConnectionProperties();
-
-            ok = true;
-        }
-        catch(FdoException* ex) //Creating a FDO provider connection with missing third party dependencies
-        {
-            ex->Release();
-            ok = false;
-        }
-        catch (...)
-        {
-            ok = false;
-        }
-
-        if (!ok)
-            continue;
-
-        xml += L"\t<FeatureProvider>\n";
-        
-        xml += L"\t\t<Name>";
-        xml += name;
-        xml += L"</Name>\n";
-
-        xml += L"\t\t<DisplayName>";
-        xml += disp;
-        xml += L"</DisplayName>\n";
-
-        xml += L"\t\t<Description>";
-        xml += desc;
-        xml += L"</Description>\n";
-
-        xml += L"\t\t<Version>";
-        xml += ver;
-        xml += L"</Version>\n";
-
-        xml += L"\t\t<FeatureDataObjectsVersion>";
-        xml += fdoVer;
-        xml += L"</FeatureDataObjectsVersion>\n";
-
-        xml += L"\t\t<ConnectionProperties>\n";
-        
-        FdoInt32 pCount;
-        FdoString** propNames = connDict->GetPropertyNames(pCount);
-        for (INT32 j = 0; j < pCount; j++)
-        {
-            FdoString* pName = propNames[j];
-            FdoString* plName = connDict->GetLocalizedName(pName);
-            FdoString* pDefault = connDict->GetPropertyDefault(pName);
-
-            bool pRequired = connDict->IsPropertyRequired(pName);
-            bool pProtected = connDict->IsPropertyProtected(pName);
-            bool pEnumerable = connDict->IsPropertyEnumerable(pName);
-
-            xml += L"\t\t\t<ConnectionProperty ";
-            xml += L"Required=\"";
-            xml += pRequired ? L"true" : L"false";
-            xml += L"\" Protected=\"";
-            xml += pProtected ? L"true" : L"false";
-            xml += L"\" Enumerable=\"";
-            xml += pEnumerable ? L"true" : L"false";
-            xml += L"\">\n";
-
-            xml += L"\t\t<Name>";
-            xml += pName;
-            xml += L"</Name>\n";
-
-            xml += L"\t\t<LocalizedName>";
-            xml += disp;
-            xml += L"</LocalizedName>\n";
-
-            xml += L"\t\t<DefaultValue>";
-            xml += desc;
-            xml += L"</DefaultValue>\n";
-
-            if (pEnumerable)
-            {
-                try 
-                {
-                    FdoInt32 pvCount;
-                    FdoString** pValues = connDict->EnumeratePropertyValues(pName, pvCount);
-
-                    for (INT32 k = 0; k < pvCount; k++)
-                    {
-                        FdoString* pVal = pValues[k];
-
-                        xml += L"\t\t<Value>";
-                        xml += pVal;
-                        xml += L"</Value>\n";
-                    }
-                }
-                catch (FdoException* ex)
-                {
-                    ex->Release();
-                }
-            }
-            xml += L"\t\t\t</ConnectionProperty>\n";
-        }
-
-        xml += L"\t\t</ConnectionProperties>\n";
-
-        xml += L"\t</FeatureProvider>\n";
-    }
-
-    xml += L"</FeatureProviderRegistry>\n";
-
-    std::string cxml = MgUtil::WideCharToMultiByte(xml);
-
-    Ptr<MgByteSource> source = new MgByteSource((unsigned char*)cxml.c_str(), (INT32)cxml.length());
-    source->SetMimeType(MgMimeType::Xml);
-    reader = source->GetReader();
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -403,8 +78,8 @@
 }
 
 MgStringCollection* MgdFeatureService::GetConnectionPropertyValues(CREFSTRING providerName,
-                                                        CREFSTRING propertyName,
-                                                        CREFSTRING partialConnString) 
+                                                                   CREFSTRING propertyName,
+                                                                   CREFSTRING partialConnString) 
 { 
     Ptr<MgStringCollection> values;
     MG_LOG_OPERATION_MESSAGE(L"GetConnectionPropertyValues");
@@ -422,30 +97,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::GetConnectionPropertyValues()");
 
-    if (providerName.empty())
-        throw new MgInvalidArgumentException(L"MgdFeatureService::GetConnectionPropertyValues", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgGetConnectionPropertyValues cmd;
+    values = cmd.GetConnectionPropertyValues(providerName, propertyName, partialConnString);
 
-    if (propertyName.empty())
-        throw new MgInvalidArgumentException(L"MgdFeatureService::GetConnectionPropertyValues", __LINE__, __WFILE__, NULL, L"", NULL);
-
-    Ptr<MgFeatureConnection> connWrapper = new MgFeatureConnection(providerName, partialConnString);
-    {
-        FdoPtr<FdoIConnection> conn = connWrapper->GetConnection();
-        FdoPtr<FdoIConnectionInfo> connInfo = conn->GetConnectionInfo();
-        FdoPtr<FdoIConnectionPropertyDictionary> connDict = connInfo->GetConnectionProperties();
-
-        FdoInt32 pCount;
-        FdoString** pValues = connDict->EnumeratePropertyValues(propertyName.c_str(), pCount);
-
-        values = new MgStringCollection();
-
-        for (INT32 i = 0; i < pCount; i++)
-        {
-            STRING val = pValues[i];
-            values->Add(val);
-        }
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -546,588 +200,6 @@
 	return ok;
 }
 
-void MgdFeatureService::WriteCommandCapabilities(MgXmlUtil* caps, FdoICommandCapabilities* fcc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteCommandCapabilities");
-
-    CHECKNULL(fcc, L"MgdFeatureService::WriteCommandCapabilities");
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteCommandCapabilities");
-
-    DOMElement* cmdNode = caps->AddChildNode(root, "Command");
-    CHECKNULL(cmdNode, L"MgdFeatureService::WriteCommandCapabilities");
-
-    // Add all command types
-    FdoInt32 cnt = 0;
-    FdoInt32* fcmd = fcc->GetCommands(cnt);
-    if (cnt > 0 && fcmd != NULL)
-    {
-        DOMElement* scNode = caps->AddChildNode(cmdNode, "SupportedCommands");
-        CHECKNULL(scNode, L"MgdFeatureService::WriteCommandCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string cmdStr = s_FdoCommandType[(FdoCommandType)fcmd[i]];
-            if (!cmdStr.empty())
-            {
-                switch (fcmd[i])
-                {
-                    case FdoCommandType_DescribeSchemaMapping:
-                    case FdoCommandType_NetworkShortestPath:
-                    case FdoCommandType_NetworkAllPaths:
-                    case FdoCommandType_NetworkReachableNodes:
-                    case FdoCommandType_NetworkReachingNodes:
-                    case FdoCommandType_NetworkNearestNeighbors:
-                    case FdoCommandType_NetworkWithinCost:
-                    case FdoCommandType_NetworkTSP:
-                    case FdoCommandType_ActivateTopologyArea:
-                    case FdoCommandType_DeactivateTopologyArea:
-                    case FdoCommandType_ActivateTopologyInCommandResult:
-                    case FdoCommandType_DeactivateTopologyInCommandResults:
-                    case FdoCommandType_SelectAggregates:
-                    case FdoCommandType_CreateDataStore:
-                    case FdoCommandType_DestroyDataStore:
-                    case FdoCommandType_ListDataStores:
-                        break;
-                        // these enumerates were added for version 2
-                        // fall thru to write this command
-                    default:
-                        caps->AddTextNode(scNode, "Name", cmdStr.c_str());
-                        break;
-                }
-            }
-        }
-    }
-
-    // Supports Parameters
-    bool supportsParameters = fcc->SupportsParameters();
-    caps->AddTextNode(cmdNode, "SupportsParameters", supportsParameters);
-
-    // Supports Timeout
-    bool supportsTimeout = fcc->SupportsTimeout();
-    caps->AddTextNode(cmdNode, "SupportsTimeout", supportsTimeout);
-
-    // Supports SupportsSelectExpressions
-    bool supportsSelectExpressions = fcc->SupportsSelectExpressions();
-    caps->AddTextNode(cmdNode, "SupportsSelectExpressions", supportsSelectExpressions);
-
-    // Supports SupportsSelectFunctions
-    bool supportsSelectFunctions = fcc->SupportsSelectFunctions();
-    caps->AddTextNode(cmdNode, "SupportsSelectFunctions", supportsSelectFunctions);
-
-    // Supports SupportsSelectDistinct
-    bool supportsSelectDistinct = fcc->SupportsSelectDistinct();
-    caps->AddTextNode(cmdNode, "SupportsSelectDistinct", supportsSelectDistinct);
-
-    // Supports SupportsSelectOrdering
-    bool supportsSelectOrdering = fcc->SupportsSelectOrdering();
-    caps->AddTextNode(cmdNode, "SupportsSelectOrdering", supportsSelectOrdering);
-
-    // Supports SupportsSelectGrouping
-    bool supportsSelectGrouping = fcc->SupportsSelectGrouping();
-    caps->AddTextNode(cmdNode, "SupportsSelectGrouping", supportsSelectGrouping);
-}
-
-void MgdFeatureService::WriteConnectionCapabilities(MgXmlUtil* caps, FdoIConnectionCapabilities* ficc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteConnectionCapabilities");
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteConnectionCapabilities");
-
-    DOMElement* connNode = caps->AddChildNode(root, "Connection");
-    CHECKNULL(connNode, L"MgdFeatureService::WriteConnectionCapabilities");
-
-    CHECKNULL((FdoIConnectionCapabilities*)ficc, L"MgdFeatureService::WriteConnectionCapabilities");
-
-    // Thread
-    FdoThreadCapability ftc = ficc->GetThreadCapability();
-    string str = s_FdoThreadCapability[ftc];
-    caps->AddTextNode(connNode, "ThreadCapability", str.c_str());
-
-    // Spatial Context
-    FdoInt32 cnt;
-    FdoSpatialContextExtentType* fscet = ficc->GetSpatialContextTypes(cnt);
-    if (cnt > 0 && fscet != NULL)
-    {
-        DOMElement* scNode = caps->AddChildNode(connNode, "SpatialContextExtent");
-        CHECKNULL(scNode, L"MgdFeatureService::WriteConnectionCapabilities");
-
-        for (FdoInt32 i = 0; i < cnt; i++)
-        {
-            string scStr = s_FdoSpatialContextExtentType[fscet[i]];
-            caps->AddTextNode(scNode, "Type", scStr.c_str());
-        }
-    }
-
-    // Locking
-    bool supportsLocking = ficc->SupportsLocking();
-    caps->AddTextNode(connNode, "SupportsLocking", supportsLocking);
-
-    bool supportsTimeout = ficc->SupportsTimeout();
-    caps->AddTextNode(connNode, "SupportsTimeout", supportsTimeout);
-
-    bool supportsTransactions = ficc->SupportsTransactions();
-    caps->AddTextNode(connNode, "SupportsTransactions", supportsTransactions);
-
-    bool supportsLongTransactions = ficc->SupportsLongTransactions();
-    caps->AddTextNode(connNode, "SupportsLongTransactions", supportsLongTransactions);
-
-    bool supportsSQL = ficc->SupportsSQL();
-    caps->AddTextNode(connNode, "SupportsSQL", supportsSQL);
-
-    bool supportsConfiguration = ficc->SupportsConfiguration();
-    caps->AddTextNode(connNode, "SupportsConfiguration", supportsConfiguration);
-}
-
-void MgdFeatureService::WriteFilterCapabilities(MgXmlUtil* caps, FdoIFilterCapabilities* ffc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteFilterCapabilities");
-
-    CHECKNULL((FdoIFilterCapabilities*)ffc, L"MgdFeatureService::WriteFilterCapabilities");
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteFilterCapabilities");
-
-    DOMElement* filterNode = caps->AddChildNode(root, "Filter");
-    CHECKNULL(filterNode, L"MgdFeatureService::WriteFilterCapabilities");
-
-    // Add all condition types
-    FdoInt32 cnt = 0;
-    FdoConditionType* fct = ffc->GetConditionTypes(cnt);
-    if (cnt > 0 && fct != NULL)
-    {
-        DOMElement* condNode = caps->AddChildNode(filterNode, "Condition");
-        CHECKNULL(condNode, L"MgdFeatureService::WriteFilterCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string condStr = s_FdoConditionType[fct[i]];
-            caps->AddTextNode(condNode, "Type", condStr.c_str());
-        }
-    }
-
-    // All spatial operations
-    cnt = 0;
-    FdoSpatialOperations* fso = ffc->GetSpatialOperations(cnt);
-    if (cnt > 0 && fso != NULL)
-    {
-        DOMElement* fsoNode = caps->AddChildNode(filterNode, "Spatial");
-        CHECKNULL(fsoNode, L"MgdFeatureService::WriteFilterCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string operStr = s_FdoSpatialOperations[fso[i]];
-            caps->AddTextNode(fsoNode, "Operation", operStr.c_str());
-        }
-    }
-
-    // All distance operations
-    cnt = 0;
-    FdoDistanceOperations* fdo = ffc->GetDistanceOperations(cnt);
-    if (cnt > 0 && fdo != NULL)
-    {
-        DOMElement* distNode = caps->AddChildNode(filterNode, "Distance");
-        CHECKNULL(distNode, L"MgdFeatureService::WriteFilterCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string fdoStr = s_FdoDistanceOperations[fdo[i]];
-            caps->AddTextNode(distNode, "Operation", fdoStr.c_str());
-        }
-    }
-
-    // supports Geodesic Distance
-    bool supportsGeodesicDistance = ffc->SupportsGeodesicDistance();
-    caps->AddTextNode(filterNode, "SupportsGeodesicDistance", supportsGeodesicDistance);
-
-    // supports NonLiteral Geometric Operations
-    bool supportsNonLiteralGeometricOperations = ffc->SupportsNonLiteralGeometricOperations();
-    caps->AddTextNode(filterNode, "SupportsNonLiteralGeometricOperations", supportsNonLiteralGeometricOperations);
-}
-
-void MgdFeatureService::WriteGeometryCapabilities(MgXmlUtil* caps, FdoIGeometryCapabilities* fgc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteGeometryCapabilities");
-
-    MG_FEATURE_SERVICE_TRY()
-
-    // Provider has no geometric capabilities
-    if (NULL == (FdoIGeometryCapabilities*)fgc)
-    {
-        return;
-    }
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteGeometryCapabilities");
-
-    DOMElement* geometryNode = caps->AddChildNode(root, "Geometry");
-    CHECKNULL(geometryNode, L"MgdFeatureService::WriteGeometryCapabilities");
-
-    FdoInt32 cnt = 0;
-    FdoGeometryType* geomType = fgc->GetGeometryTypes(cnt);
-    if (cnt > 0 && geomType != NULL)
-    {
-        DOMElement* geometryTypeNode = caps->AddChildNode(geometryNode, "Types");
-        CHECKNULL(geometryTypeNode, L"MgdFeatureService::WriteGeometryCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string geomTypeStr = s_FdoGeometryType[geomType[i]];
-            caps->AddTextNode(geometryTypeNode, "Type", geomTypeStr.c_str());
-        }
-    }
-
-    FdoGeometryComponentType* geomCompType = fgc->GetGeometryComponentTypes(cnt);
-    if (cnt > 0 && geomCompType != NULL)
-    {
-        DOMElement* geometryCompNode = caps->AddChildNode(geometryNode, "Components");
-        CHECKNULL(geometryCompNode, L"MgdFeatureService::WriteGeometryCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string geomCompStr = s_FdoGeometryComponentType[geomCompType[i]];
-            caps->AddTextNode(geometryCompNode, "Type", geomCompStr.c_str());
-        }
-    }
-
-    FdoInt32 dim = fgc->GetDimensionalities();
-
-    char buff[8]; buff[0] = 0;
-    sprintf(buff, "%d", dim);
-
-    caps->AddTextNode(geometryNode, "Dimensionality", &buff[0]);
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::WriteGeometryCapabilities")
-}
-
-void MgdFeatureService::WriteExpressionCapabilities(MgXmlUtil* caps, FdoIExpressionCapabilities* fec)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteExpressionCapabilities");
-
-    CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgdFeatureService::WriteExpressionCapabilities");
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteExpressionCapabilities");
-
-    DOMElement* expressionNode = caps->AddChildNode(root, "Expression");
-    CHECKNULL(expressionNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-    // Add all expression types
-    FdoInt32 cnt = 0;
-    FdoExpressionType* fet = fec->GetExpressionTypes(cnt);
-    if (cnt > 0 && fet != NULL)
-    {
-        DOMElement* typeNode = caps->AddChildNode(expressionNode, "Type");
-        CHECKNULL(typeNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string typeStr = s_FdoExpressionType[fet[i]];
-            caps->AddTextNode(typeNode, "Name", typeStr.c_str());
-        }
-    }
-
-    // Add all functions available
-    cnt = 0;
-    FdoPtr<FdoFunctionDefinitionCollection> ffdc = fec->GetFunctions();
-    if (NULL != (FdoFunctionDefinitionCollection*)ffdc)
-    {
-        FdoInt32 funcCnt = ffdc->GetCount();
-        if (funcCnt > 0)
-        {
-            // Add function definition collection element if there are any functions available
-            DOMElement* funcDefColNode = caps->AddChildNode(expressionNode, "FunctionDefinitionList");
-            CHECKNULL(funcDefColNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-            for (FdoInt32 i=0; i < funcCnt; i++)
-            {
-                // Add function definition element
-                FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
-                CHECKNULL((FdoFunctionDefinition*)ffd, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                DOMElement* funcDefNode = caps->AddChildNode(funcDefColNode, "FunctionDefinition");
-                CHECKNULL(funcDefNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                const char* strName = MgUtil::WideCharToMultiByte(ffd->GetName());
-                const char* strDesc = MgUtil::WideCharToMultiByte(ffd->GetDescription());
-
-                FdoFunctionCategoryType eFdoFunctionCategoryType = ffd->GetFunctionCategoryType();
-                string strFunctionCategoryType = s_FdoFunctionCategoryType[eFdoFunctionCategoryType];
-
-                caps->AddTextNode(funcDefNode, "Name", strName);
-                caps->AddTextNode(funcDefNode, "Description", strDesc);
-                caps->AddTextNode(funcDefNode, "CategoryType",  strFunctionCategoryType.c_str());
-                caps->AddTextNode(funcDefNode, "IsAggregate",  ffd->IsAggregate());
-                caps->AddTextNode(funcDefNode, "IsSupportsVariableArgumentsList",  ffd->SupportsVariableArgumentsList());
-
-                delete[] strName;
-                delete[] strDesc;
-
-                // Add argument of each functions if there are any
-                FdoPtr<FdoReadOnlySignatureDefinitionCollection> signatures = ffd->GetSignatures();
-                if (NULL != (FdoReadOnlySignatureDefinitionCollection*)signatures)
-                {
-                    FdoInt32 signaturesCnt = signatures->GetCount();
-                    if (signaturesCnt > 0)
-                    {
-
-                        DOMElement* signDefColNode = caps->AddChildNode(funcDefNode, "SignatureDefinitionCollection");
-                        CHECKNULL(signDefColNode, L"MgdFeatureService::WriteExpressionCapabilities");
-                        for (FdoInt32 j=0; j < signaturesCnt; j++)
-                        {
-
-                            // Add SignatureDefinition for each signature
-                            FdoPtr<FdoSignatureDefinition> fsd = signatures->GetItem(j);
-                            CHECKNULL((FdoSignatureDefinition*)fsd, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                            DOMElement* signDefNode = caps->AddChildNode(signDefColNode, "SignatureDefinition");
-                            CHECKNULL(signDefNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                            FdoPropertyType eSignPropertyDataType = fsd->GetReturnPropertyType();
-                            string strSignPropertyType = s_FdoPropertyTypeAsString[eSignPropertyDataType];
-                            string strSignDataType;
-                            if (eSignPropertyDataType == FdoPropertyType_DataProperty)
-                            {
-                                FdoDataType eSignDataType = fsd->GetReturnType();
-                                strSignDataType = s_FdoDataType[eSignDataType];
-                            }
-
-                            caps->AddTextNode(signDefNode, "PropertyType", strSignPropertyType.c_str());
-                            if (eSignPropertyDataType == FdoPropertyType_DataProperty)
-                                caps->AddTextNode(signDefNode, "DataType",  strSignDataType.c_str());
-
-                            DOMElement* argDefColNode = caps->AddChildNode(signDefNode, "ArgumentDefinitionList");
-                            CHECKNULL(argDefColNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                            FdoPtr<FdoReadOnlyArgumentDefinitionCollection> fads = fsd->GetArguments();
-                            if (NULL != (FdoReadOnlyArgumentDefinitionCollection *) fads)
-                            {
-                                FdoInt32 argCnt = fads->GetCount();
-                                if (argCnt > 0)
-                                {
-                                    for (int k=0; k<argCnt; k++)
-                                    {
-                                        FdoPtr<FdoArgumentDefinition> fad = fads->GetItem(k);
-                                        CHECKNULL((FdoArgumentDefinition*)fad, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                                        DOMElement* argDefNode = caps->AddChildNode(argDefColNode, "ArgumentDefinition");
-                                        CHECKNULL(argDefNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                                        const char* strArgName = MgUtil::WideCharToMultiByte(fad->GetName());
-                                        const char* strArgDesc = MgUtil::WideCharToMultiByte(fad->GetDescription());
-
-                                        FdoPropertyType eArgPropertyDataType = fad->GetPropertyType();
-                                        string strArgPropertyType = s_FdoPropertyTypeAsString[eArgPropertyDataType];
-                                        string strArgDataType;
-                                        if (eArgPropertyDataType == FdoPropertyType_DataProperty)
-                                        {
-                                            FdoDataType eArgDataType = fad->GetDataType();
-                                            strArgDataType = s_FdoDataType[eArgDataType];
-                                        }
-
-                                        caps->AddTextNode(argDefNode, "Name", strArgName);
-                                        caps->AddTextNode(argDefNode, "Description", strArgDesc);
-                                        caps->AddTextNode(argDefNode, "PropertyType", strArgPropertyType.c_str());
-                                        if (eArgPropertyDataType == FdoPropertyType_DataProperty)
-                                            caps->AddTextNode(argDefNode, "DataType",  strArgDataType.c_str());
-
-                                        delete[] strArgName;
-                                        delete[] strArgDesc;
-
-                                        FdoPtr<FdoPropertyValueConstraintList> fpvc = fad->GetArgumentValueList();
-                                        if (NULL != (FdoPropertyValueConstraintList *) fpvc)
-                                        {
-                                            if (fpvc->GetConstraintType() == FdoPropertyValueConstraintType_List)
-                                            {
-                                                DOMElement* propValueConstListNode = caps->AddChildNode(argDefNode, "PropertyValueConstraintList");
-                                                CHECKNULL(propValueConstListNode, L"MgdFeatureService::WriteExpressionCapabilities");
-
-                                                FdoPropertyValueConstraintType eConstraintType = fpvc->GetConstraintType();
-
-                                                FdoPtr<FdoDataValueCollection> dvc = fpvc->GetConstraintList();
-                                                if (NULL != (FdoDataValueCollection *) dvc)
-                                                {
-                                                    FdoInt32 dvCnt = dvc->GetCount();
-                                                    if (dvCnt > 0)
-                                                    {
-                                                        for (int l=0; l<dvCnt; l++)
-                                                        {
-                                                            FdoPtr<FdoDataValue> dv = dvc->GetItem(l);
-                                                            CHECKNULL((FdoDataValue*)dv, L"MgdFeatureService::WriteExpressionCapabilities");
-                                                            FdoDataType dataType = dv->GetDataType();
-                                                            // FdoDataType_String is the only supported type
-                                                            if (dataType == FdoDataType_String)
-                                                            {
-                                                                FdoStringValue *stringValue = (FdoStringValue *) dv.p;
-                                                                FdoString* xmlValue = stringValue->GetString();
-                                                                const char* strDataValue = MgUtil::WideCharToMultiByte(stringValue->GetString());
-                                                                caps->AddTextNode(propValueConstListNode, "Value", xmlValue);
-                                                                delete[] strDataValue;
-                                                            }
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-void MgdFeatureService::WriteSchemaCapabilities(MgXmlUtil* caps, FdoISchemaCapabilities* fsc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteSchemaCapabilities");
-    CHECKNULL((FdoISchemaCapabilities*)fsc, L"MgdFeatureService::WriteSchemaCapabilities");
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteSchemaCapabilities");
-
-    DOMElement* schemaNode = caps->AddChildNode(root, "Schema");
-    CHECKNULL(schemaNode, L"MgdFeatureService::WriteSchemaCapabilities");
-
-    // Add all class types
-    FdoInt32 cnt = 0;
-    FdoClassType* fct = fsc->GetClassTypes(cnt);
-    if (cnt > 0 && fct != NULL)
-    {
-        DOMElement* classNode = caps->AddChildNode(schemaNode, "Class");
-        CHECKNULL(classNode, L"MgdFeatureService::WriteSchemaCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string scStr = s_FdoClassType[fct[i]];
-            caps->AddTextNode(classNode, "Type", scStr.c_str());
-        }
-    }
-
-    // Add all data types
-    cnt = 0;
-    FdoDataType* fdt = fsc->GetDataTypes(cnt);
-    if (cnt > 0 && fdt != NULL)
-    {
-        DOMElement* dataNode = caps->AddChildNode(schemaNode, "Data");
-        CHECKNULL(dataNode, L"MgdFeatureService::WriteSchemaCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string dtStr = s_FdoDataType[fdt[i]];
-            caps->AddTextNode(dataNode, "Type", dtStr.c_str());
-        }
-    }
-
-    // Supports Inheritance
-    bool supportsInheritance        = fsc->SupportsInheritance();
-    caps->AddTextNode(schemaNode, "SupportsInheritance", supportsInheritance);
-
-    // Supports Multiple Schemas
-    bool supportsMultipleSchemas    = fsc->SupportsMultipleSchemas();
-    caps->AddTextNode(schemaNode, "SupportsMultipleSchemas", supportsMultipleSchemas);
-
-    bool supportsObjectProperties   = fsc->SupportsObjectProperties();
-    caps->AddTextNode(schemaNode, "SupportsObjectProperties", supportsObjectProperties);
-
-    bool supportsAssociationProperties = fsc->SupportsAssociationProperties();
-    caps->AddTextNode(schemaNode, "SupportsAssociationProperties", supportsAssociationProperties);
-
-    bool supportsSchemaOverrides =  fsc->SupportsSchemaOverrides();
-    caps->AddTextNode(schemaNode, "SupportsSchemaOverrides", supportsSchemaOverrides);
-
-    bool supportsNetworkModel  = fsc->SupportsNetworkModel();
-    caps->AddTextNode(schemaNode, "SupportsNetworkModel", supportsNetworkModel);
-
-    bool supportsAutoIdGeneration  = fsc->SupportsAutoIdGeneration();
-    caps->AddTextNode(schemaNode, "SupportsAutoIdGeneration", supportsAutoIdGeneration);
-
-    bool supportsDataStoreScopeUniqueIdGeneration  = fsc->SupportsDataStoreScopeUniqueIdGeneration();
-    caps->AddTextNode(schemaNode, "SupportsDataStoreScopeUniqueIdGeneration", supportsDataStoreScopeUniqueIdGeneration);
-
-    FdoDataType* sagt = fsc->GetSupportedAutoGeneratedTypes(cnt);
-    if (cnt > 0 && sagt != NULL)
-    {
-        DOMElement* sagtNode = caps->AddChildNode(schemaNode, "SupportedAutoGeneratedTypes");
-        CHECKNULL(sagtNode, L"MgdFeatureService::WriteSchemaCapabilities");
-
-        for (FdoInt32 i=0; i < cnt; i++)
-        {
-            string sagtStr = s_FdoDataType[sagt[i]];
-            caps->AddTextNode(sagtNode, "Type", sagtStr.c_str());
-        }
-    }
-
-    bool supportsSchemaModification  = fsc->SupportsSchemaModification();
-    caps->AddTextNode(schemaNode, "SupportsSchemaModification", supportsSchemaModification);
-}
-
-void MgdFeatureService::WriteRasterCapabilities(MgXmlUtil* caps, FdoIRasterCapabilities* frc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteRasterCapabilities");
-    CHECKNULL((FdoIRasterCapabilities*)frc, L"MgdFeatureService::WriteRasterCapabilities");
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteRasterCapabilities");
-
-    DOMElement* rasterNode = caps->AddChildNode(root, "Raster");
-    CHECKNULL(rasterNode, L"MgdFeatureService::WriteRasterCapabilities");
-
-    // Supports Raster
-    bool supportsRaster = frc->SupportsRaster();
-    caps->AddTextNode(rasterNode, "SupportsRaster", supportsRaster);
-
-    // Supports Stitching
-    bool supportsStitching = frc->SupportsStitching();
-    caps->AddTextNode(rasterNode, "SupportsStitching", supportsStitching);
-
-    bool supportsSubsampling = frc->SupportsSubsampling();
-    caps->AddTextNode(rasterNode, "SupportsSubsampling", supportsSubsampling);
-}
-
-void MgdFeatureService::WriteTopologyCapabilities(MgXmlUtil* caps, FdoITopologyCapabilities* frc)
-{
-    CHECKNULL(caps, L"MgdFeatureService::WriteTopologyCapabilities");
-
-    MG_FEATURE_SERVICE_TRY()
-    // Provider has no topology capabilities
-    if (NULL == (FdoITopologyCapabilities*)frc)
-    {
-        return;
-    }
-
-    DOMElement* root = caps->GetRootNode();
-    CHECKNULL(root, L"MgdFeatureService::WriteTopologyCapabilities");
-
-    DOMElement* topologyNode = caps->AddChildNode(root, "Topology");
-    CHECKNULL(topologyNode, L"MgdFeatureService::WriteTopologyCapabilities");
-
-    // Supports Topology
-    bool supportsTopology = frc->SupportsTopology();
-    caps->AddTextNode(topologyNode, "SupportsTopology", supportsTopology);
-
-    // Supports Stitching
-    bool supportsTopologicalHierarchy = frc->SupportsTopologicalHierarchy();
-    caps->AddTextNode(topologyNode, "SupportsTopologicalHierarchy", supportsTopologicalHierarchy);
-
-    bool breaksCurveCrossingsAutomatically = frc->BreaksCurveCrossingsAutomatically();
-    caps->AddTextNode(topologyNode, "BreaksCurveCrossingsAutomatically", breaksCurveCrossingsAutomatically);
-
-    bool activatesTopologyByArea = frc->ActivatesTopologyByArea();
-    caps->AddTextNode(topologyNode, "ActivatesTopologyByArea", activatesTopologyByArea);
-
-    bool constrainsFeatureMovements = frc->ConstrainsFeatureMovements();
-    caps->AddTextNode(topologyNode, "ConstrainsFeatureMovements", constrainsFeatureMovements);
-
-    // TODO: Change this to CATCH_AND_THROW when SimpleDB stops throwing exception of not implemented
-    MG_FEATURE_SERVICE_CATCH(L"MgdFeatureService::WriteTopologyCapabilities")
-
-}
-
 MgByteReader* MgdFeatureService::GetCapabilities(CREFSTRING providerName) 
 {
     Ptr<MgByteReader> ret;
@@ -1182,43 +254,8 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::GetCapabilities()");
 
-    if (providerName.empty())
-        throw new MgInvalidArgumentException(L"MgdFeatureService::GetCapabilities", __LINE__, __WFILE__, NULL, L"", NULL);
-
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(providerName, connectionString);
-    {
-        FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
-
-        // Root node element created
-        // this XML follows the FdoProviderCapabilities-1.0.0.xsd schema
-        std::auto_ptr<MgXmlUtil> xml(new MgXmlUtil("FeatureProviderCapabilities"));
-        CHECKNULL(xml.get(), L"MgdFeatureService::GetCapabilities");
-        DOMElement* root = xml->GetRootNode();
-
-        // Provide name element and its attribute
-        DOMElement* providerNode = xml->AddChildNode(root, "Provider");
-        xml->SetAttribute(providerNode, "Name", providerName.c_str());
-
-        FdoPtr<FdoICommandCapabilities> cmdCaps = conn->GetCommandCapabilities();
-        FdoPtr<FdoIConnectionCapabilities> connCaps = conn->GetConnectionCapabilities();
-        FdoPtr<FdoIExpressionCapabilities> exprCaps = conn->GetExpressionCapabilities();
-        FdoPtr<FdoIFilterCapabilities> filterCaps = conn->GetFilterCapabilities();
-        FdoPtr<FdoIGeometryCapabilities> geomCaps = conn->GetGeometryCapabilities();
-        FdoPtr<FdoIRasterCapabilities> rasterCaps = conn->GetRasterCapabilities();
-        FdoPtr<FdoISchemaCapabilities> schemaCaps = conn->GetSchemaCapabilities();
-        FdoPtr<FdoITopologyCapabilities> topoCaps = conn->GetTopologyCapabilities();
-
-        WriteConnectionCapabilities(xml.get(), connCaps);
-        WriteSchemaCapabilities(xml.get(), schemaCaps);
-        WriteCommandCapabilities(xml.get(), cmdCaps);
-        WriteFilterCapabilities(xml.get(), filterCaps);
-        WriteExpressionCapabilities(xml.get(), exprCaps);
-        WriteRasterCapabilities(xml.get(), rasterCaps);
-        WriteTopologyCapabilities(xml.get(), topoCaps);
-        WriteGeometryCapabilities(xml.get(), geomCaps);
-
-        caps = xml->ToReader();
-    }
+    MgGetProviderCapabilities getCaps(providerName, connectionString);
+    caps = getCaps.GetProviderCapabilities();
     
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -1258,67 +295,9 @@
     CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::ApplySchema");
     CHECKARGUMENTNULL(schema, L"MgdFeatureService::ApplySchema");
 
-    // Connect to provider
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-    {
-        FdoPtr<FdoIConnection> fdoConn = connWrap->GetConnection();
-        
-        FdoPtr<FdoICommandCapabilities> cmdCaps = fdoConn->GetCommandCapabilities();
+    MgApplySchema apply;
+    apply.ApplySchema(resource, schema);
 
-        // connection must be open
-        bool bRefresh = false;
-        bool bApplySchema = connWrap->SupportsCommand(FdoCommandType_ApplySchema);
-        bool bDescribeSchema = connWrap->SupportsCommand(FdoCommandType_DescribeSchema);;
-
-        // Check whether command is supported by provider
-        if (!bApplySchema || !bDescribeSchema)
-        {
-            // TODO: specify which argument and message, once we have the mechanism
-            STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-            throw new MgInvalidOperationException(L"MgdFeatureService::ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-
-        FdoPtr<FdoIDescribeSchema> fdoDecribeSchemaCmd = (FdoIDescribeSchema*) fdoConn->CreateCommand(FdoCommandType_DescribeSchema);
-        CHECKNULL((FdoIDescribeSchema*)fdoDecribeSchemaCmd, L"MgdFeatureService::ApplySchema");
-
-        FdoPtr<FdoFeatureSchemaCollection> schemas = fdoDecribeSchemaCmd->Execute();
-        CHECKNULL((FdoFeatureSchemaCollection*)schemas, L"MgdFeatureService::ApplySchema");
-
-        FdoPtr<FdoIApplySchema> fdoApplySchemaCmd = (FdoIApplySchema*)fdoConn->CreateCommand(FdoCommandType_ApplySchema);
-        CHECKNULL((FdoIApplySchema*)fdoApplySchemaCmd, L"MgdFeatureService::ApplySchema");
-
-        STRING schemaName = schema->GetName();
-        FdoPtr<FdoFeatureSchema> fdoOldSchema = schemas->FindItem(schemaName.c_str());
-        if (NULL == fdoOldSchema)
-        {
-            if (!schema->IsDeleted())
-            {
-                FdoPtr<FdoFeatureSchema> fdoNewSchema = MgFeatureUtil::GetFdoFeatureSchema(schema);
-                fdoApplySchemaCmd->SetFeatureSchema(fdoNewSchema);
-                fdoApplySchemaCmd->Execute();
-                bRefresh = true;
-            }
-        }
-        else
-        {
-            if (!schema->IsDeleted())
-                MgFeatureUtil::UpdateFdoFeatureSchema(schema, fdoOldSchema);
-            else
-                fdoOldSchema->Delete();
-
-            fdoApplySchemaCmd->SetFeatureSchema(fdoOldSchema);
-            fdoApplySchemaCmd->Execute();
-            bRefresh = true;
-        }
-
-        // Clear the cached schema so that MgFeatureService::DescribeSchema
-        // can return the correct schema
-        if (bRefresh)
-        {
-            MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-            cache->RemoveEntry(resource);
-        }
-    }
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -1391,362 +370,30 @@
     Ptr<MgFeatureSchemaCollection> clone;
     MG_FEATURE_SERVICE_TRY()
 
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    fsCollection = cache->GetSchemas(resource, schemaName, findClassNames, serialize);
-
-    Ptr<MgFeatureSourceCacheItem> fsCache = cache->GetFeatureSource(resource);
-    MdfModel::FeatureSource* featureSource = fsCache->Get();
-    CHECKNULL(featureSource, L"MgdFeatureService::DescribeSchema");
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::DescribeSchema");
-    int extensionCount = extensions->GetCount();
-
-    //Weed out extended class names because FDO won't know anything about them
-    Ptr<MgStringCollection> classNames;
+    MgDescribeSchema describe;
+    MgStringCollection extendedClassNames;
+    //Need to weed out extended class names as this API is not extended class aware.
+    //TODO: Put this logic into DescribeSchema proper
     if (NULL != findClassNames)
     {
-        classNames = new MgStringCollection();
         for (INT32 i = 0; i < findClassNames->GetCount(); i++)
         {
-            STRING clsName = findClassNames->GetItem(i);
-            bool bIsExtendedClassName = false;
-            for (INT32 j = 0; j < extensionCount; j++)
+            STRING name = findClassNames->GetItem(i);
+            if (describe.CheckExtendedFeatureClass(resource, name))
             {
-                MdfModel::Extension* extension = extensions->GetAt(j);
-                CHECKNULL(extension, L"MgdFeatureService::DescribeSchema");
-                STRING extName = (STRING)extension->GetName();
-                if (clsName == extName)
-                    bIsExtendedClassName = true;
+                extendedClassNames.Add(name);
             }
-
-            if (!bIsExtendedClassName)
-                classNames->Add(clsName);
         }
-    }
-
-    if (NULL == fsCollection.p)
-    {
-        fsCollection = new MgFeatureSchemaCollection();
-
-        bool classNameHintUsed = true;
-        FdoPtr<FdoFeatureSchemaCollection> ffsc =
-            DescribeFdoSchema(resource, schemaName, classNames, classNameHintUsed);
-        CHECKNULL(ffsc.p, L"MgdFeatureService::DescribeSchema");
-
-        // Get schema count
-        FdoInt32 schemaCount = ffsc->GetCount();
-
-        //
-        // A new MgFeatureSchema needs to be created for each primary schema in FDO schemas.
-        //
-        Ptr<MgFeatureSchema> schema;
-        Ptr<MgClassDefinitionCollection> classCol;
-
-        for (int nSchemaIndex = 0; nSchemaIndex < schemaCount; nSchemaIndex++)
+        for (INT32 i = 0; i < extendedClassNames.GetCount(); i++)
         {
-            // Retrieve schema from the collection
-            FdoPtr<FdoFeatureSchema> ffs = ffsc->GetItem(nSchemaIndex);
-            STRING currSchemaName = (wchar_t*)ffs->GetName();
-
-            // Check if this schema is from secondary source which will be prefixed with [ExtensionName][RelationName],
-            // ie [ExtensionName][RelationName]SchemaName
-            if (currSchemaName.find(L"[") == 0)
-            {
-                // Found a schema for secondary source, so just skip over it for now
-                continue;
-            }
-
-            schema = new MgFeatureSchema();
-            classCol = schema->GetClasses();
-
-            // Set the schema name and description
-            FdoStringP fSchemaName = ffs->GetName();
-            schema->SetName(STRING(fSchemaName));
-
-            FdoStringP fSchemaDesc = ffs->GetDescription();
-            schema->SetDescription(STRING(fSchemaDesc));
-
-            // Get all classes for the schema
-            FdoPtr<FdoClassCollection> fcc = ffs->GetClasses();
-            FdoInt32 classCount = fcc->GetCount();
-
-            // Add the primary class definitions to the MgClassDefinitionCollection
-            for (FdoInt32 nClassIndex = 0; nClassIndex < classCount; nClassIndex++)
-            {
-                FdoPtr<FdoClassDefinition> fc = fcc->GetItem(nClassIndex);
-
-                FdoStringP qname = fc->GetQualifiedName();
-                FdoStringP name = fc->GetName();
-
-                if (name != NULL && qname != NULL)
-                {
-                    Ptr<MgClassDefinition> classDefinition = MgFeatureUtil::GetMgClassDefinition(fc, serialize);
-                    classCol->Add(classDefinition);
-                }
-            }
-
-            //
-            // A new MgClassDefinition needs to be created for each extension and added to the MgClassCollection
-            //
-            for (int i = 0; i < extensionCount; i++)
-            {
-                Ptr<MgClassDefinition> extClassDefinition;
-                FdoPtr<FdoClassDefinition> originalClassDef;
-
-                MdfModel::Extension* extension = extensions->GetAt(i);
-                CHECKNULL(extension, L"MgdFeatureService::DescribeSchema");
-
-                // Get the extension name
-                STRING extensionName = (STRING)extension->GetName();
-
-                // get FeatureClass element - this tells us which class is extended (SchemaName:ClassName)
-                STRING featureClass = (STRING)extension->GetFeatureClass();
-
-                // Parse the schemaName from the className
-                STRING primSchemaName, primClassName;
-                MgUtil::ParseQualifiedClassName(featureClass, primSchemaName, primClassName);
-
-                if (currSchemaName != primSchemaName)
-                {
-                    continue;
-                }
-
-                // Cycle thru FDO schemas for schemaName.
-                for (int nIndex = 0; nIndex < schemaCount; nIndex++)
-                {
-                    FdoPtr<FdoFeatureSchema> ffs = ffsc->GetItem(nIndex);
-                    STRING currSchemaName = (wchar_t*)ffs->GetName();
-
-                    // Check if this schema is from secondary source
-                    if (currSchemaName.find(L"[") == 0)
-                    {
-                        // Found a schema for secondary source, so just skip over it
-                        continue;
-                    }
-
-                    // get the class collection for this schema
-                    FdoPtr<FdoClassCollection> fcc = ffs->GetClasses();
-                    FdoInt32 classCount = fcc->GetCount();
-
-                    for (int nClassIndex = 0; nClassIndex < classCount; nClassIndex++)
-                    {
-                        originalClassDef = fcc->GetItem(nClassIndex);
-
-                        STRING className = (wchar_t*)originalClassDef->GetName();
-                        if (className == primClassName)
-                        {
-                            // get the class definition
-                            extClassDefinition = MgFeatureUtil::GetMgClassDefinition(originalClassDef, serialize);
-                            break;
-                        }
-                    }
-
-                    if (NULL != extClassDefinition)
-                    {
-                        break;
-                    }
-                }
-
-                if (NULL == extClassDefinition)
-                {
-                    continue;
-                }
-
-                CalculatedPropertyCollection* calcPropsColl = extension->GetCalculatedProperties();
-                if (calcPropsColl != NULL && calcPropsColl->GetCount() != 0)
-                {
-                    FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
-                    for (int idx = 0; idx < calcPropsColl->GetCount(); idx++)
-                    {
-                        CalculatedProperty* calcProp = calcPropsColl->GetAt(idx);
-                        FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
-                        FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
-                        idList->Add(idfCalc);
-                    }
-
-                    Ptr<MgPropertyDefinitionCollection> mpdcLocal = extClassDefinition->GetProperties();
-                    for(int idx = 0; idx < calcPropsColl->GetCount(); idx++)
-                    {
-                        CalculatedProperty* calcProp = calcPropsColl->GetAt(idx);
-                        if (calcProp != NULL)
-                        {
-                            MdfString nameExpr = calcProp->GetName();
-                            MdfString valueExpr = calcProp->GetExpression();
-                            if (nameExpr.size() != 0 && valueExpr.size() != 0)
-                            {
-                                FdoPropertyType retPropType = FdoPropertyType_DataProperty;
-                                FdoDataType retDataType = FdoDataType_Double;
-                                FdoPtr<FdoExpression> expr = FdoExpression::Parse(valueExpr.c_str());
-                                FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expr, idList);
-                                FdoExpressionEngine::GetExpressionType(originalClassDef, expandedExpression, retPropType, retDataType);
-                                if (retPropType == FdoPropertyType_DataProperty)
-                                {
-                                    STRING namePropStr = STRING(nameExpr.c_str());
-                                    Ptr<MgDataPropertyDefinition> propDefExpr = new MgDataPropertyDefinition(namePropStr);
-                                    propDefExpr->SetDataType(MgFeatureUtil::GetMgPropertyType(retDataType));
-                                    propDefExpr->SetNullable(true);
-                                    propDefExpr->SetReadOnly(true);
-                                    propDefExpr->SetAutoGeneration(false);
-                                    mpdcLocal->Add(propDefExpr);
-                                }
-                            }
-                        }
-                    }
-                }
-                //
-                // Finished adding primary class properties to the extension class definition
-                // Now add the secondary class properties
-                //
-
-                // Determine the number of secondary sources (AttributeRelates)
-                MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
-                CHECKNULL(attributeRelates, L"MgDescribeSchema.DescribeSchema");
-                int nAttributeRelateCount = attributeRelates->GetCount();
-
-                for (int arIndex = 0; arIndex < nAttributeRelateCount; arIndex++)
-                {
-                    // get the attribute relate
-                    MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(arIndex);
-                    CHECKNULL(attributeRelate, L"MgDescribeSchema.DescribeSchema");
-
-                    // Get the name of the secondary feature class (AttributeClass)
-                    STRING attributeClass = (STRING)attributeRelate->GetAttributeClass();
-
-                    // Parse the schema name from the class name;
-                    STRING secSchemaName, secClassName;
-                    MgUtil::ParseQualifiedClassName(attributeClass, secSchemaName, secClassName);
-
-                    // Get the relation name
-                    STRING relationName = (STRING)attributeRelate->GetName();
-
-                    // Get the attributeName delimiter ( if none specified, default will be "" (blank) )
-                    STRING attributeNameDelimiter = (STRING)attributeRelate->GetAttributeNameDelimiter();
-
-                    // Get the resource id of the secondary feature source
-                    STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
-
-                    // Establish connection to provider for secondary feature source
-                    Ptr<MgResourceIdentifier> secondaryFeatureSource = new MgResourceIdentifier(secondaryResourceId);
-                    if (NULL != secondaryFeatureSource)
-                    {
-                        FdoPtr<FdoFeatureSchemaCollection> ffsc2;
-                        Ptr<MgFeatureConnection> connection2 = new MgFeatureConnection(secondaryFeatureSource);
-
-                        if ((NULL != connection2.p) && ( connection2->IsConnectionOpen() ))
-                        {
-                            // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
-                            // otherwise it leaves the FDO connection marked as still in use.
-                            FdoPtr<FdoIConnection> fdoConn2 = connection2->GetConnection();
-                            // Get the schema collection for the secondary resource
-                            FdoPtr<FdoIDescribeSchema> fdoCommand2  = (FdoIDescribeSchema*)fdoConn2->CreateCommand(FdoCommandType_DescribeSchema);
-                            CHECKNULL((FdoIDescribeSchema*)fdoCommand2, L"MgDescribeSchema.DescribeSchema");
-
-                            if (!secSchemaName.empty())
-                            {
-                                fdoCommand2->SetSchemaName(secSchemaName.c_str());
-                            }
-
-                            if (!secClassName.empty())
-                            {
-                                FdoPtr<FdoStringCollection> fdoClassNames2 = FdoStringCollection::Create();
-
-                                fdoClassNames2->Add(secClassName.c_str());
-                                fdoCommand2->SetClassNames(fdoClassNames2.p);
-                            }
-
-                            // Execute the command
-                            ffsc2 = fdoCommand2->Execute();
-                            CHECKNULL((FdoFeatureSchemaCollection*)ffsc2, L"MgdFeatureService::DescribeSchema");
-
-                            int nSecSchemaCnt = (int)ffsc2->GetCount();
-
-                            // cycle thru FdoFeatureSchemaCollection for secSchemaName
-                            for (int nSecSchemaIndex = 0; nSecSchemaIndex < nSecSchemaCnt; nSecSchemaIndex++)
-                            {
-                                // retrieve the schema
-                                FdoPtr<FdoFeatureSchema> ffs = ffsc2->GetItem(nSecSchemaIndex);
-                                STRING fdoSchemaName = (wchar_t*)ffs->GetName();
-
-                                if (fdoSchemaName != secSchemaName)
-                                {
-                                    continue;
-                                }
-
-                                // get the class collection for schema
-                                FdoPtr<FdoClassCollection> fcc = ffs->GetClasses();
-                                FdoInt32 classCount = fcc->GetCount();
-
-                                // cycle thru class collection for secClassName
-                                for (int nClassIndex = 0; nClassIndex < classCount; nClassIndex++)
-                                {
-                                    Ptr<MgPropertyDefinitionCollection> mpdc = extClassDefinition->GetProperties();
-
-                                    FdoPtr<FdoClassDefinition> fc = fcc->GetItem(nClassIndex);
-
-                                    STRING qualifiedName = (const wchar_t*)fc->GetQualifiedName();
-                                    STRING className = (wchar_t*)fc->GetName();
-
-                                    if (className != secClassName)
-                                    {
-                                        continue;
-                                    }
-
-                                    // Set the parent name for the secondary class definition
-                                    FdoPtr<FdoSchemaElement> parent = fc->GetParent();
-                                    if (!secSchemaName.empty())
-                                    {
-                                        parent->SetName(secSchemaName.c_str());
-                                    }
-
-                                    // get the secondary class definition
-                                    Ptr<MgClassDefinition> classDefinition = MgFeatureUtil::GetMgClassDefinition(fc, serialize);
-
-                                    // retrieve the secondary properties and prefix them with the relation name
-                                    Ptr<MgPropertyDefinitionCollection> mpdc2 = classDefinition->GetProperties();
-                                    INT32 mpdc2Count = mpdc2->GetCount();
-
-                                    // Prefix the secondary properties with relationName and add to the extClassDefinition
-                                    for (INT32 secPropIndex = 0; secPropIndex < mpdc2Count; secPropIndex++)
-                                    {
-                                        Ptr<MgPropertyDefinition> propDef = mpdc2->GetItem(secPropIndex);
-                                        if ( MgFeaturePropertyType::GeometricProperty != propDef->GetPropertyType()
-                                            && MgFeaturePropertyType::RasterProperty != propDef->GetPropertyType() )
-                                        {
-                                            STRING secPropName = propDef->GetName();
-                                            secPropName = relationName + attributeNameDelimiter + secPropName;
-                                            propDef->SetName(secPropName);
-                                            mpdc->Add(propDef);
-                                        }
-                                    }
-                                    break;
-                                }  // end loop thru secondary class collection
-                                break;
-                            }  // end loop thru secondary schemas
-                        }
-                        else
-                        {
-                            throw new MgConnectionFailedException(L"MgdFeatureService::DescribeSchema", __LINE__, __WFILE__, NULL, L"", NULL);
-                        }
-                    }  // end if (NULL != secFeatureSource)
-                }  // end loop thru all attribute relates (joins)
-                if (!extensionName.empty())
-                {
-                    extClassDefinition->SetName(extensionName);
-                }
-                // Add the extension class definition to the MgClassDefinitionCollection
-                classCol->Add(extClassDefinition);
-            }  // Repeat for all extensions
-            // Add the schema to the MgFeatureSchemaCollection
-            fsCollection->Add(schema);
-        }  // End loop thru all schemas
-        cache->SetSchemas(resource, schemaName, classNames, serialize, fsCollection.p);
+            findClassNames->Remove(extendedClassNames.GetItem(i));
+        }
     }
-    else
-    {
-        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
-    }
-
-    //Clone this result and return it
+    fsCollection = describe.DescribeSchema(resource, schemaName, findClassNames, serialize);
+    
+    //In MapGuide Server returning this potentially cached copy is okay as a new instance is created
+    //travelling the server/webtier boundary. This is not the case in mg-desktop so we have to clone
+    //this result and return the clone instead.
     clone = new MgFeatureSchemaCollection();
     for (INT32 i = 0; i < fsCollection->GetCount(); i++)
     {
@@ -1755,199 +402,28 @@
         clone->Add(clonedSchema);
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdFeatureService::DescribeSchema")
+    //TODO: Multiple schemas without class names?
+    Ptr<MgFeatureSchema> schema = fsCollection->GetItem(0);
+    Ptr<MgClassDefinitionCollection> parentClasses = schema->GetClasses();
 
-    return clone.Detach();
-}
-
-FdoFeatureSchemaCollection* MgdFeatureService::DescribeFdoSchema(MgResourceIdentifier* resource,
-                                                                 CREFSTRING schemaName, 
-                                                                 MgStringCollection* classNames, 
-                                                                 bool& classNameHintUsed)
-{
-    // IMPORTANT INFORMATION
-    // FDO objects cannot be cached as they are not thread safe.
-    // This is not an issue because we create a MapGuide wrapper of this information that is thread safe.
-    FdoPtr<FdoFeatureSchemaCollection> ffsc;
-    ffsc = NULL;
-
-    MG_FEATURE_SERVICE_TRY()
-
-    // Connect to provider
-    Ptr<MgFeatureConnection> connection = new MgFeatureConnection(resource);
-
-    if ((NULL != connection.p) && (connection->IsConnectionOpen()))
+    //Add extended classes
+    if (extendedClassNames.GetCount() > 0)
     {
-        MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-
-        // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
-        // otherwise it leaves the FDO connection marked as still in use.
-        FdoPtr<FdoIConnection> fdoConn = connection->GetConnection();
-        FdoPtr<FdoIDescribeSchema> fdoCommand = (FdoIDescribeSchema*)fdoConn->CreateCommand(FdoCommandType_DescribeSchema);
-
-        classNameHintUsed = IsClassNameHintUsed(fdoCommand);
-
-        if (!schemaName.empty())
+        for (INT32 i = 0; i < extendedClassNames.GetCount(); i++)
         {
-            fdoCommand->SetSchemaName(schemaName.c_str());
+            STRING clsName = extendedClassNames.GetItem(i);
+            //This API is extended class aware
+            Ptr<MgClassDefinition> klass = GetClassDefinition(resource, schemaName, clsName);
+            Ptr<MgClassDefinition> cloneCls = MgFeatureUtil::CloneMgClassDefinition(klass);
+            parentClasses->Add(cloneCls);
         }
-
-        FdoPtr<FdoStringCollection> fdoClassNames = MgFeatureUtil::MgToFdoStringCollection(classNames, false);
-
-        if (NULL != fdoClassNames.p && fdoClassNames->GetCount() > 0)
-        {
-            fdoCommand->SetClassNames(fdoClassNames.p);
-        }
-
-        // Execute the command
-        ffsc = fdoCommand->Execute();
-        CHECKNULL((FdoFeatureSchemaCollection*)ffsc, L"MgdFeatureService::DescribeFdoSchema");
-
-        // Finished with primary feature source, so now cycle through any secondary sources
-        Ptr<MgFeatureSourceCacheItem> fsCache = cache->GetFeatureSource(resource);
-
-        MdfModel::FeatureSource* featureSource = fsCache->Get();
-        CHECKNULL(featureSource, L"MgdFeatureService::DescribeFdoSchema");
-        MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-        CHECKNULL(extensions, L"MgdFeatureService::DescribeFdoSchema");
-        int extensionCount = extensions->GetCount();
-
-        for (int i = 0; i < extensionCount; i++)
-        {
-            MdfModel::Extension* extension = extensions->GetAt(i);
-            CHECKNULL(extension, L"MgdFeatureService::DescribeFdoSchema");
-
-            // Get the extension name
-            STRING extensionName = (STRING)extension->GetName();
-
-            // Determine the number of secondary sources (AttributeRelates)
-            MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
-            CHECKNULL(attributeRelates, L"MgdFeatureService::DescribeFdoSchema");
-            int nAttributeRelates = attributeRelates->GetCount();
-
-            for (int arIndex = 0; arIndex < nAttributeRelates; arIndex++)
-            {
-                MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(arIndex);
-                CHECKNULL(attributeRelate, L"MgdFeatureService::DescribeFdoSchema");
-
-                // get the resource id of the secondary feature source
-                STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
-
-                // get the name for the join relationship (attribute relate name)
-                STRING attributeRelateName = (STRING)attributeRelate->GetName();
-
-                // Get the secondary feature class (AttributeClass)
-                STRING attributeClass = (STRING)attributeRelate->GetAttributeClass();
-
-                // Parse the schema name from the classname;
-                STRING secSchemaName, secClassName;
-                MgUtil::ParseQualifiedClassName(attributeClass, secSchemaName, secClassName);
-
-                // Establish connection to provider for secondary feature source
-                Ptr<MgResourceIdentifier> secondaryFeatureSource = new MgResourceIdentifier(secondaryResourceId);
-
-                if (NULL != secondaryFeatureSource)
-                {
-                    FdoPtr<FdoFeatureSchemaCollection> ffsc2;
-                    Ptr<MgFeatureConnection> connection2 = new MgFeatureConnection(secondaryFeatureSource);
-
-                    if ((NULL != connection2.p) && ( connection2->IsConnectionOpen() ))
-                    {
-                        // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
-                        // otherwise it leaves the FDO connection marked as still in use.
-                        FdoPtr<FdoIConnection> fdoConn2 = connection2->GetConnection();
-                        // Check whether this command is supported by the provider
-                        FdoPtr<FdoIDescribeSchema> fdoCommand2 = (FdoIDescribeSchema*)fdoConn2->CreateCommand(FdoCommandType_DescribeSchema);
-                        CHECKNULL((FdoIDescribeSchema*)fdoCommand2, L"MgDescribeSchema.DescribeFdoSchema");
-
-                        if (!secSchemaName.empty())
-                        {
-                            fdoCommand2->SetSchemaName(secSchemaName.c_str());
-                        }
-
-                        if (!secClassName.empty())
-                        {
-                            FdoPtr<FdoStringCollection> fdoClassNames2 = FdoStringCollection::Create();
-
-                            fdoClassNames2->Add(secClassName.c_str());
-                            fdoCommand2->SetClassNames(fdoClassNames2.p);
-                        }
-
-                        // Execute the command
-                        ffsc2 = fdoCommand2->Execute();
-                        CHECKNULL((FdoFeatureSchemaCollection*)ffsc2, L"MgdFeatureService::DescribeFdoSchema");
-
-                        if (!secSchemaName.empty())
-                        {
-                            fdoCommand2->SetSchemaName(secSchemaName.c_str());
-                        }
-
-                        if (!secClassName.empty())
-                        {
-                            FdoPtr<FdoStringCollection> fdoClassNames2 = FdoStringCollection::Create();
-
-                            fdoClassNames2->Add(secClassName.c_str());
-                            fdoCommand2->SetClassNames(fdoClassNames2.p);
-                        }
-
-                        // Extract the schemas from the secondary collection and add them to the main collection
-                        // Get schema count
-                        FdoInt32 cnt = ffsc2->GetCount();
-                        for (FdoInt32 i = 0; i < cnt; i++)
-                        {
-                            FdoPtr<FdoFeatureSchema> ffs = ffsc2->GetItem(i);
-                            STRING fdoSchemaName = (wchar_t*)ffs->GetName();
-
-                            if (fdoSchemaName != secSchemaName)
-                            {
-                                continue;
-                            }
-
-                            // Prefix the schema name with the extension and attribute relate names
-                            STRING modifiedSchemaName;
-                            modifiedSchemaName = L"[" + extensionName + L"]";
-                            modifiedSchemaName += L"[" + attributeRelateName + L"]";
-                            modifiedSchemaName += fdoSchemaName;
-                            FdoString* msn = modifiedSchemaName.c_str();
-                            ffs->SetName(msn);
-
-                            // Add this schema to the collection if it isn't already there
-                            if (!ffsc->Contains(ffs))
-                            {
-                                ffsc->Add(ffs);
-                            }
-                        }
-                    }
-                    else
-                    {
-                        throw new MgConnectionFailedException(L"MgdFeatureService::DescribeFdoSchema", __LINE__, __WFILE__, NULL, L"", NULL);
-                    }
-                }
-
-            }  // End of the for-loop that iterates thru the secondary sources
-
-        }  // End of for loop that iterates thru the extensions in the feature source
     }
-    else
-    {
-        throw new MgConnectionFailedException(L"MgdFeatureService::DescribeFdoSchema", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdFeatureService::DescribeFdoSchema")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdFeatureService::DescribeSchema")
 
-    return ffsc.Detach();
+    return clone.Detach();
 }
 
-bool MgdFeatureService::IsClassNameHintUsed(FdoIDescribeSchema* fdoCommand)
-{
-    CHECKNULL(fdoCommand, L"MgdFeatureService::IsClassNameHintUsed");
-
-    FdoPtr<FdoStringCollection> classNames = fdoCommand->GetClassNames();
-    bool classNameHintUsed = (NULL != classNames.p);
-
-    return classNameHintUsed;
-}
-
 MgFeatureSchemaCollection* MgdFeatureService::DescribeSchema(MgResourceIdentifier* resource,
                                                              CREFSTRING schemaName) 
 { 
@@ -2010,55 +486,9 @@
 
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::DescribeSchemaAsXml");
 
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    schemaXml = cache->GetSchemaXml(resource, schemaName, classNames);
+    MgDescribeSchema describe;
+    describe.DescribeSchemaAsXml(resource, schemaName, classNames);
 
-    if (schemaXml.empty())
-    {
-        MgStringCollection* classNameCol = NULL;
-
-        // Since the FDO provider does not know about the join information,
-        // get the full schema if the feature source has joins.
-        if (CheckExtendedFeatureClasses(resource, classNames))
-        {
-            schemaXml = cache->GetSchemaXml(resource, schemaName, NULL);
-        }
-        else
-        {
-            classNameCol = classNames;
-        }
-
-        if (schemaXml.empty())
-        {
-            // The schema XML can be retrieved from either the serialized
-            // schemas or the unserialized ones. So, try to get the serialized
-            // schemas from the cache first then the unserialized ones later.
-            Ptr<MgFeatureSchemaCollection> schemas = cache->GetSchemas(resource, schemaName, classNameCol, true);
-
-            if (NULL == schemas.p)
-            {
-                schemas = DescribeSchema(resource, schemaName, classNameCol, false);
-            }
-            else
-            {
-                //cache->CheckPermission(resource, MgResourcePermission::ReadOnly);
-            }
-
-            // Get the schema XML.
-            schemaXml = SchemaToXml(schemas);
-
-            cache->SetSchemaXml(resource, schemaName, classNameCol, schemaXml);
-        }
-        else
-        {
-            //cache->CheckPermission(resource, MgResourcePermission::ReadOnly);
-        }
-    }
-    else
-    {
-        //cache->CheckPermission(resource, MgResourcePermission::ReadOnly);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -2118,102 +548,6 @@
     return ret;
 }
 
-bool MgdFeatureService::CheckExtendedFeatureClasses(MgResourceIdentifier* resource, MgStringCollection* classNames)
-{
-    bool extended = false;
-
-    if (NULL != classNames)
-    {
-        INT32 classCount = classNames->GetCount();
-
-        for (INT32 i = 0; i < classCount; ++i)
-        {
-            STRING currClassName = classNames->GetItem(i);
-
-            if (CheckExtendedFeatureClass(resource, currClassName))
-            {
-                extended = true;
-                break;
-            }
-        }
-    }
-
-    return extended;
-}
-
-bool MgdFeatureService::CheckExtendedFeatureClass(MgResourceIdentifier* resource, CREFSTRING className)
-{
-    bool extended = false;
-
-    if (!className.empty())
-    {
-        STRING parsedSchemaName, parsedClassName;
-        MgUtil::ParseQualifiedClassName(className, parsedSchemaName, parsedClassName);
-
-        MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-
-        Ptr<MgFeatureSourceCacheItem> cacheItem = cache->GetFeatureSource(resource);
-
-        MdfModel::FeatureSource* featureSource = cacheItem->Get();
-        CHECKNULL(featureSource, L"MgdFeatureService::CheckExtendedFeatureClass");
-        MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-        CHECKNULL(extensions, L"MgdFeatureService::CheckExtendedFeatureClass");
-        int extensionCount = extensions->GetCount();
-
-        for (int i = 0; i < extensionCount; ++i)
-        {
-            MdfModel::Extension* extension = extensions->GetAt(i);
-            CHECKNULL(extension, L"MgdFeatureService::CheckExtendedFeatureClass");
-            STRING extensionName = (STRING)extension->GetName();
-
-            STRING currSchemaName, currClassName;
-            MgUtil::ParseQualifiedClassName(extensionName, currSchemaName, currClassName);
-
-            if (currClassName == parsedClassName)
-            {
-                extended = true;
-                break;
-            }
-        }
-    }
-
-    return extended;
-}
-
-STRING MgdFeatureService::FdoSchemaToXml(FdoFeatureSchemaCollection* schemas)
-{
-	STRING serializedXml;
-
-    MG_FEATURE_SERVICE_TRY()
-    CHECKARGUMENTNULL(schemas, L"MgdFeatureService::FdoSchemaToXml");
-
-    FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
-    CHECKARGUMENTNULL((FdoIoMemoryStream*)fmis, L"MgdFeatureService::FdoSchemaToXml");
-
-    // Write to memory stream
-    schemas->WriteXml(fmis);
-    fmis->Reset(); // TODO: We should not be calling reset here. A defect in FDO should be fixed.
-
-    FdoInt64 len = fmis->GetLength();
-    FdoByte *bytes = new FdoByte[(size_t)len];
-    CHECKARGUMENTNULL(bytes, L"MgdFeatureService::FdoSchemaToXml");
-
-    fmis->Read(bytes, (FdoSize)len);
-
-    Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)bytes, (INT32)len);
-    byteSource->SetMimeType(MgMimeType::Xml);
-    Ptr<MgByteReader> byteReader = byteSource->GetReader();
-
-    string out = MgUtil::GetTextFromReader(byteReader);
-    serializedXml = MgUtil::MultiByteToWideChar(out);
-
-    delete [] bytes;
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::FdoSchemaToXml")
-
-    return serializedXml;
-}
-
 STRING MgdFeatureService::SchemaToXml(MgFeatureSchemaCollection* schemas) 
 { 
     STRING serializedXml;
@@ -2230,31 +564,9 @@
 
     CHECKARGUMENTNULL(schemas, L"MgdFeatureService::SchemaToXml");
 
-    FdoPtr<FdoFeatureSchemaCollection> fdoSchemaCol = MgFeatureUtil::GetFdoFeatureSchemaCollection(schemas);
-    CHECKNULL(fdoSchemaCol, L"MgdFeatureService::SchemaToXml");
+    MgDescribeSchema describe;
+    serializedXml = describe.SchemaToXml(schemas);
 
-    FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
-    CHECKNULL((FdoIoMemoryStream*)fmis, L"MgdFeatureService::SchemaToXml");
-
-    // Write to memory stream
-    fdoSchemaCol->WriteXml(fmis);
-    fmis->Reset(); // TODO: We should not be calling reset here. A defect in FDO should be fixed.
-
-    FdoInt64 len = fmis->GetLength();
-    FdoByte *bytes = new FdoByte[(size_t)len];
-    CHECKNULL(bytes, L"MgdFeatureService::SchemaToXml");
-
-    fmis->Read(bytes, (FdoSize)len);
-
-    Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)bytes, (INT32)len);
-    byteSource->SetMimeType(MgMimeType::Xml);
-    Ptr<MgByteReader> byteReader = byteSource->GetReader();
-
-    string out = MgUtil::GetTextFromReader(byteReader);
-    serializedXml = MgUtil::MultiByteToWideChar(out);
-
-    delete [] bytes;
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -2290,57 +602,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::XmlToSchema()");
 
-    mgSchemaCol = new MgFeatureSchemaCollection();
+    MgDescribeSchema describe;
+    mgSchemaCol = describe.XmlToSchema(xml);
 
-    string mbString = MgUtil::WideCharToMultiByte(xml);
-
-    size_t len = mbString.length();
-
-    FdoByte* gisBytes = (FdoByte*) mbString.c_str();
-
-    FdoPtr<FdoIoMemoryStream> stream = FdoIoMemoryStream::Create();
-    stream->Write(gisBytes, (FdoSize)len);
-
-    FdoPtr<FdoFeatureSchemaCollection> fdoSchemaCol = FdoFeatureSchemaCollection::Create((FdoSchemaElement*)NULL);
-    stream->Reset();
-    fdoSchemaCol->ReadXml(stream);
-
-    // Get schema count
-    FdoInt32 cnt = fdoSchemaCol->GetCount();
-    for (FdoInt32 i = 0; i < cnt; i++)
-    {
-        FdoPtr<FdoFeatureSchema> fdoSchema = fdoSchemaCol->GetItem(i);
-        FdoStringP name = fdoSchema->GetName();
-        CHECKNULL(name, L"MgdFeatureService::XmlToSchema");
-
-        FdoStringP description = fdoSchema->GetDescription();
-
-        STRING tmpName(name);
-        STRING tmpDesc(description);
-
-        Ptr<MgFeatureSchema> mgSchema = new MgFeatureSchema(tmpName, tmpDesc);
-        Ptr<MgClassDefinitionCollection> classCol = mgSchema->GetClasses();
-
-        // Get all classes for a schema
-        FdoPtr<FdoClassCollection> fdoClassCol = fdoSchema->GetClasses();
-        FdoInt32 classCount = fdoClassCol->GetCount();
-
-        for (FdoInt32 j = 0; j < classCount; j++)
-        {
-            FdoPtr<FdoClassDefinition> fdoClassDef = fdoClassCol->GetItem(j);
-            // TODO: Should we return qualified or non-qualified name
-            FdoStringP qname = fdoClassDef->GetQualifiedName();
-            FdoStringP name = fdoClassDef->GetName();
-
-            if (name != NULL && qname != NULL)
-            {
-                Ptr<MgClassDefinition> classDefinition = MgFeatureUtil::GetMgClassDefinition(fdoClassDef, true);
-                classCol->Add(classDefinition);
-            }
-        }
-        mgSchemaCol->Add(mgSchema);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -2380,9 +644,15 @@
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"MgFeatureQueryOptions");
     MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
-    MG_LOG_TRACE_ENTRY(L"MgdFeatureService::SelectFeatures()");
+    MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::Trace, L"MgdFeatureService::SelectFeatures", mgStackParams);
+    logDetail.AddResourceIdentifier(L"Resource", resource);
+    logDetail.AddString(L"ClassName", className);
+    logDetail.AddObject(L"Options", options);
+    logDetail.Create();
 
-    ret = SelectFeaturesInternal(resource, className, options, L"", false, false);
+    MgSelectFeatures select;
+    ret = dynamic_cast<MgFeatureReader*>(select.SelectFeatures(resource, className, options, false));
+    CHECKNULL(ret.p, L"MgdFeatureService::SelectFeatures");
 
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -2425,10 +695,62 @@
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"STRING");
     MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
-    MG_LOG_TRACE_ENTRY(L"MgdFeatureService::SelectFeatures()");
+	MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::Trace, L"MgdFeatureService::SelectFeatures", mgStackParams);
+    logDetail.AddResourceIdentifier(L"Resource", resource);
+    logDetail.AddString(L"ClassName", className);
+    logDetail.AddObject(L"Options", options);
+    logDetail.AddString(L"CoordinateSystem", coordinateSystem);
+    logDetail.Create();
 
-	ret = SelectFeaturesInternal(resource, className, options, coordinateSystem, false, false);
+    MgSelectFeatures select;
+    Ptr<MgFeatureReader> innerReader = dynamic_cast<MgFeatureReader*>(select.SelectFeatures(resource, className, options, false));
+    CHECKNULL(innerReader.p, L"MgdFeatureService::SelectFeatures");
+
+    //If coordinate system specified, set up a CS Transform to pass to the feature reader
+    Ptr<MgCoordinateSystemTransform> xform;
+    if (!coordinateSystem.empty())
+    {
+        Ptr<MgClassDefinition> clsDef = innerReader->GetClassDefinition();
+        if (NULL != clsDef)
+        {
+            Ptr<MgPropertyDefinitionCollection> clsProps = clsDef->GetProperties();
+            STRING geomProp = clsDef->GetDefaultGeometryPropertyName();
+            if (!geomProp.empty() && clsProps->IndexOf(geomProp) >= 0)
+            {
+                Ptr<MgGeometricPropertyDefinition> geomPropDef = static_cast<MgGeometricPropertyDefinition*>(clsProps->GetItem(geomProp));
+                STRING scName = geomPropDef->GetSpatialContextAssociation();
+                Ptr<MgSpatialContextReader> scReader = GetSpatialContexts(resource, false);
+                while (scReader->ReadNext())
+                {
+                    if (scReader->GetName() == scName)
+                    {
+                        //TODO: Some FDO providers don't even use WKTs for spatial context. Capabilities
+                        //should tell us the correct way to construct our MgCoordinateSystem object
+
+                        STRING wkt = scReader->GetCoordinateSystemWkt();
+
+                        Ptr<MgCoordinateSystemFactory> fact = new MgCoordinateSystemFactory();
+
+                        Ptr<MgCoordinateSystem> source = fact->Create(wkt);
+                        Ptr<MgCoordinateSystem> target = fact->Create(coordinateSystem);
+
+                        xform = fact->GetTransform(source, target);
+                        break;
+                    }
+                }
+            }
+        }
+    }
     
+    if (NULL != xform)
+    {
+        ret = new MgProjectedFeatureReader(innerReader, xform);
+    }
+    else
+    {
+        ret = innerReader;
+    }
+    
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -2469,7 +791,15 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::SelectFeaturesExtended()");
 
-    ret = static_cast<MgdScrollableFeatureReader*>(SelectFeaturesInternal(resource, className, options, L"", false, true));
+    MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::Trace, L"MgdFeatureService::SelectFeaturesExtended", mgStackParams);
+    logDetail.AddResourceIdentifier(L"Resource", resource);
+    logDetail.AddString(L"ClassName", className);
+    logDetail.AddObject(L"Options", options);
+    logDetail.Create();
+
+    MgSelectFeatures select;
+    ret = dynamic_cast<MgdScrollableFeatureReader*>(select.SelectFeatures(resource, className, options, false, true));
+    CHECKNULL(ret.p, L"MgdFeatureService::SelectFeaturesExtended");
     
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -2491,1246 +821,6 @@
     return ret.Detach();
 }
 
-MgFeatureReader* MgdFeatureService::SelectFeaturesInternal(MgResourceIdentifier* resource,
-														   CREFSTRING className,
-														   MgFeatureQueryOptions* options,
-														   CREFSTRING coordinateSystem,
-														   bool withLock,
-                                                           bool asScrollable)
-{
-	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::SelectFeatures");
-	//CHECKARGUMENTNULL(options, L"MgdFeatureService::SelectFeatures");
-    if (className.empty())
-        throw new MgInvalidArgumentException(L"MgdFeatureService::SelectFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
-
-    //Cannot both be true at the same time
-    assert(!(withLock && asScrollable));
-
-    Ptr<MgFeatureReader> reader;
-    MG_FEATURE_SERVICE_TRY()
-    
-    MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::InternalTrace, L"MgdFeatureService::SelectFeaturesInternal", mgStackParams);
-    logDetail.AddResourceIdentifier(L"resource", resource);
-    logDetail.AddString(L"className", className);
-    logDetail.AddString(L"coordinateSystem", coordinateSystem);
-    logDetail.AddBool(L"withLock", withLock);
-    logDetail.AddBool(L"asScrollable", asScrollable);
-
-	Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-    {
-        FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
-
-        FdoPtr<FdoISelect> select;
-        if (asScrollable)
-            select = (FdoIExtendedSelect*)conn->CreateCommand(FdoCommandType_ExtendedSelect);
-        else
-            select = (FdoISelect*)conn->CreateCommand(FdoCommandType_Select);
-        
-        if (NULL != (MgFeatureQueryOptions*)options)
-        {
-            Ptr<MgStringCollection> props = options->GetClassProperties();
-            Ptr<MgStringPropertyCollection> computed = options->GetComputedProperties();
-            Ptr<MgStringCollection> orderByProperties = options->GetOrderingProperties();
-            INT32 orderOption = options->GetOrderOption();
-
-            INT32 propCount = props->GetCount();
-            INT32 compCount = computed->GetCount();
-            INT32 orderCount = 0;
-            if (NULL != (MgStringCollection*)orderByProperties)
-            {
-                orderCount = orderByProperties->GetCount();
-            }
-
-            FdoPtr<FdoIdentifierCollection> fdoProps = select->GetPropertyNames();
-            if (propCount > 0)
-            {
-	            for (INT32 i = 0; i < propCount; i++)
-	            {
-		            FdoPtr<FdoIdentifier> name = FdoIdentifier::Create(props->GetItem(i).c_str());
-		            fdoProps->Add(name);
-	            }
-            }
-            if (compCount > 0)
-            {
-	            for (INT32 i = 0; i < compCount; i++)
-	            {
-		            Ptr<MgStringProperty> comp = computed->GetItem(i);
-		            FdoPtr<FdoExpression> expr = FdoExpression::Parse(comp->GetValue().c_str());
-		            FdoPtr<FdoComputedIdentifier> name= FdoComputedIdentifier::Create(comp->GetName().c_str(), expr);
-
-		            fdoProps->Add(name);
-	            }
-            }
-            FdoPtr<FdoIdentifierCollection> orderBy = select->GetOrdering();
-            if (orderCount > 0)
-            {
-                for (INT32 i = 0; i < orderCount; i++)
-	            {
-		            FdoPtr<FdoIdentifier> name = FdoIdentifier::Create(orderByProperties->GetItem(i).c_str());
-		            orderBy->Add(name);
-	            }
-                switch(orderOption)
-                {
-                case MgOrderingOption::Ascending:
-                    select->SetOrderingOption(FdoOrderingOption_Ascending);
-                    break;
-                case MgOrderingOption::Descending:
-                    select->SetOrderingOption(FdoOrderingOption_Descending);
-                    break;
-                }
-            }
-
-            FdoPtr<FdoFilter> regularFilter;
-            FdoPtr<FdoFilter> spatialFilter;
-            FdoPtr<FdoFilter> combineFilter;
-            FdoBinaryLogicalOperations bOper = FdoBinaryLogicalOperations_And;
-
-            // Build regular filter
-            STRING filterText = options->GetFilter();
-            if (!filterText.empty())
-            {
-                regularFilter = FdoFilter::Parse(filterText.c_str());
-                #ifdef _DEBUG
-                ACE_DEBUG((LM_ERROR, ACE_TEXT("FILTER(size=%d):\n%W\n\n"), filterText.length(), filterText.c_str()));
-                #endif
-            }
-
-            // Build spatial filter
-            bool isAnd = options->GetBinaryOperator();
-            Ptr<MgGeometry> geom = options->GetGeometry();
-            INT32 spatialOp = options->GetSpatialOperation();
-
-            STRING geomProp = options->GetGeometryProperty();
-
-            if (!isAnd) // Apply OR operator
-            {
-                bOper = FdoBinaryLogicalOperations_Or;
-            }
-
-            // Check whether we have valid geometric filter
-            if (!geomProp.empty() && (geom != NULL))
-            {
-                MgAgfReaderWriter agfWriter;
-
-                Ptr<MgByteReader> reader = agfWriter.Write(geom);
-                Ptr<MgByteSink> sink = new MgByteSink(reader);
-                Ptr<MgByte> bytes = sink->ToBuffer();
-
-                FdoByte* gisBytes = bytes->Bytes();
-                INT32 len = bytes->GetLength();
-
-                FdoPtr<FdoByteArray> byteArray = FdoByteArray::Create(gisBytes, (FdoInt32)len);
-
-                #ifdef _DEBUG
-                // Get the spatial filter geometry text
-                FdoPtr<FdoFgfGeometryFactory> geometryFactory = FdoFgfGeometryFactory::GetInstance();
-                if(geometryFactory)
-                {
-                    FdoPtr<FdoIGeometry> geometry = geometryFactory->CreateGeometryFromFgf(byteArray);
-                    STRING geomText = geometry->GetText();
-                    ACE_DEBUG((LM_INFO, ACE_TEXT("(%t) SPATIAL FILTER:\n%W\n\n"), geomText.c_str()));
-                }
-                #endif
-
-                FdoPtr<FdoGeometryValue> geomValue = FdoGeometryValue::Create(byteArray);
-                if (geomValue != NULL)
-                {
-                    FdoSpatialOperations fdoSpatialOp = MgFeatureUtil::GetFdoSpatialOperation(spatialOp);
-                    spatialFilter = FdoSpatialCondition::Create((FdoString*)geomProp.c_str(), fdoSpatialOp, (FdoExpression*)geomValue);
-                }
-            }
-
-            // Determine which one to apply
-            if ((regularFilter != NULL) && (spatialFilter != NULL))
-            {
-                // Both filter exists, combine them
-                combineFilter = FdoFilter::Combine(regularFilter, bOper, spatialFilter);
-            }
-            else
-            {
-                if (regularFilter != NULL)
-                {
-                    // Only regular filter exists
-                    combineFilter = FDO_SAFE_ADDREF((FdoFilter*)regularFilter);
-                }
-                else if (spatialFilter != NULL)
-                {
-                    // Only spatial filter exists
-                    combineFilter = FDO_SAFE_ADDREF((FdoFilter*)spatialFilter);
-                }
-            }
-
-            // Apply the filter
-            if (combineFilter != NULL)
-            {
-                select->SetFilter(combineFilter);
-                STRING filterText = combineFilter->ToString();
-                logDetail.AddString(L"Filter", filterText);
-            }
-
-            if (asScrollable)
-            {
-                //TODO: Apply single property ordering option. Obviously then needs its own custom query options object
-            }
-        }
-        // Check if a feature join is to be performed by inspecting the resource for join properties
-        bool bFeatureJoinProperties = FindFeatureJoinProperties(resource, className);
-        // Check if a feature join is only a calculation
-        bool bFeatureCalculation = FindFeatureCalculation(resource, className);
-
-        logDetail.AddBool(L"IsFeatureJoinClass", bFeatureJoinProperties);
-        logDetail.AddBool(L"IsCalculationClass", bFeatureCalculation);
-        logDetail.Create();
-
-        if (bFeatureJoinProperties)
-        {
-            FdoPtr<FdoFilter> fdoFilter = select->GetFilter();
-            reader = SelectFeaturesJoined(resource, className, fdoFilter);
-        }
-        else
-        {
-            select->SetFeatureClassName(className.c_str());
-            if (asScrollable)
-            {
-                FdoPtr<FdoIScrollableFeatureReader> scrollReader;
-                FdoIExtendedSelect* extSelect = static_cast<FdoIExtendedSelect*>(select.p);
-                scrollReader = extSelect->ExecuteScrollable();
-
-                reader = new MgdScrollableFeatureReader(connWrap, scrollReader);
-            }
-            else
-            {
-                FdoPtr<FdoIFeatureReader> fdoReader;
-                if (withLock)
-	                fdoReader = select->ExecuteWithLock();
-                else
-	                fdoReader = select->Execute();
-                
-                //If coordinate system specified, set up a CS Transform to pass to the feature reader
-                Ptr<MgCoordinateSystemTransform> xform;
-                if (!coordinateSystem.empty())
-                {
-                    FdoPtr<FdoFeatureClass> clsDef = dynamic_cast<FdoFeatureClass*>(fdoReader->GetClassDefinition());
-                    if (NULL != clsDef)
-                    {
-                        FdoPtr<FdoGeometricPropertyDefinition> geom = clsDef->GetGeometryProperty();
-                        if (NULL != geom)
-                        {
-                            FdoString* scName = geom->GetSpatialContextAssociation();
-                            FdoPtr<FdoIGetSpatialContexts> gsc = (FdoIGetSpatialContexts*)conn->CreateCommand(FdoCommandType_GetSpatialContexts);
-                            FdoPtr<FdoISpatialContextReader> scReader = gsc->Execute();
-                            while (scReader->ReadNext())
-                            {
-                                if (wcscmp(scReader->GetName(), scName) == 0)
-                                {
-                                    //TODO: Some FDO providers don't even use WKTs for spatial context. Capabilities
-                                    //should tell us the correct way to construct our MgCoordinateSystem object
-
-                                    STRING wkt = scReader->GetCoordinateSystemWkt();
-
-                                    Ptr<MgCoordinateSystemFactory> fact = new MgCoordinateSystemFactory();
-
-                                    Ptr<MgCoordinateSystem> source = fact->Create(wkt);
-                                    Ptr<MgCoordinateSystem> target = fact->Create(coordinateSystem);
-
-                                    xform = fact->GetTransform(source, target);
-                                    break;
-                                }
-                            }
-                        }
-                    }
-                }
-
-                if (NULL == xform)
-                {
-                    reader = new MgdFeatureReader(connWrap, fdoReader);   
-                }
-                else
-                {
-                    //Wrap the feature reader in a projected feature reader
-                    Ptr<MgFeatureReader> fr = new MgdFeatureReader(connWrap, fdoReader);
-                    reader = new MgProjectedFeatureReader(fr, xform);
-                }
-            }
-        }
-    }
-
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdFeatureService::SelectFeaturesInternal")
-
-	return reader.Detach();
-}
-
-MgFeatureReader* MgdFeatureService::SelectFeaturesJoined(MgResourceIdentifier* featureSourceIdentifier, 
-                                                         CREFSTRING extensionName, 
-                                                         FdoFilter* filter)
-{
-    Ptr<MgdGwsFeatureReader> gwsFeatureReader;
-
-    MG_FEATURE_SERVICE_TRY()
-
-    FdoPtr<IGWSQueryDefinition> qd;
-    FdoPtr<MgGwsConnectionPool> pool = MgGwsConnectionPool::Create();
-
-    MgFeatureServiceCache* cacheManager = MgFeatureServiceCache::GetInstance();
-    Ptr<MgFeatureSourceCacheItem> fsCacheItem = cacheManager->GetFeatureSource(featureSourceIdentifier);
-
-    CHECKNULL(fsCacheItem.p, L"MgdFeatureService::JoinFeatures");
-    MdfModel::FeatureSource* featureSource = fsCacheItem->Get();
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::JoinFeatures");
-
-    for (int i = 0; i < extensions->GetCount(); i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::JoinFeatures");
-        STRING name = (STRING)extension->GetName();
-
-        STRING parsedSchemaName, parsedExtensionName;
-        MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
-
-        if (parsedExtensionName != name)
-        {
-            continue;
-        }
-        else
-        {
-            // Establish connection to provider for primary feature source
-            STRING primaryConnectionName;
-            MgUtil::GenerateUuid(primaryConnectionName);
-            Ptr<MgFeatureConnection> leftConn = new MgFeatureConnection(featureSourceIdentifier);
-            
-            STRING fsIdStr = featureSourceIdentifier->ToString();
-            bool bSupportsFdoJoinOptimization = SupportsFdoJoins(leftConn, extension);
-
-            MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::InternalTrace, L"MgdFeatureService::SelectFeaturesJoined", mgStackParams);
-            logDetail.AddBool(L"SupportsFdoJoinOptimization", bSupportsFdoJoinOptimization);
-            logDetail.Create();
-
-            // See if we can use the FDO join optimization
-            if (bSupportsFdoJoinOptimization)
-            {
-#ifdef DEBUG_FDOJOIN
-                STRING fsIdStr = featureSourceIdentifier->ToString();
-                ACE_DEBUG((LM_INFO, ACE_TEXT("\nFeature Source (%W) supports FDO join optimization"), fsIdStr.c_str()));
-#endif
-                Ptr<MgFeatureReader> joinReader = SelectFdoJoin(leftConn, extension, filter);
-                return joinReader.Detach();
-            }
-#ifdef DEBUG_FDOJOIN
-            ACE_DEBUG((LM_INFO, ACE_TEXT("\nFeature Source (%W) does not support the FDO join optimization. Using GwsQueryEngine"), fsIdStr.c_str()));
-#endif
-
-
-            if ((NULL != leftConn.p) && ( leftConn->IsConnectionOpen() ))
-            {
-                pool->AddConnection(primaryConnectionName.c_str(), leftConn);
-            }
-            else
-            {
-                throw new MgConnectionFailedException(L"MgdFeatureService::JoinFeatures",
-                    __LINE__, __WFILE__, NULL, L"", NULL);
-            }
-
-            // Retrieve the primary feature class
-            STRING featureClass = (STRING)extension->GetFeatureClass();
-
-            // Parse the qualifed classname
-            STRING primaryFsSchema, primaryFsClassName;
-            MgUtil::ParseQualifiedClassName(featureClass, primaryFsSchema, primaryFsClassName);
-
-            // Create primary query definition
-            FdoPtr<FdoIdentifierCollection> lsellist;
-            FdoPtr<FdoFilter> lfilter;
-
-            // in case we have calculations we must add all properties + computed properties to the selection list
-            MdfModel::CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
-            if (calcProps != NULL && calcProps->GetCount() != 0)
-            {
-                FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
-                for (int idx = 0; idx < calcProps->GetCount(); idx++)
-                {
-                    CalculatedProperty* calcProp = calcProps->GetAt(idx);
-                    FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
-                    FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
-                    idList->Add(idfCalc);
-                }
-                lsellist = FdoIdentifierCollection::Create();
-                for (int idx = 0; idx < calcProps->GetCount(); idx++)
-                {
-                    CalculatedProperty* calcProp = calcProps->GetAt(idx);
-                    FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(calcProp->GetName().c_str()));
-                    FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
-                    FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
-
-                    FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expandedExpression);
-                    lsellist->Add(newIdf);
-                }
-                FdoPtr<FdoIConnection> conn = leftConn->GetConnection();
-                FdoPtr<FdoIDescribeSchema>  descSchema = (FdoIDescribeSchema *) conn->CreateCommand (FdoCommandType_DescribeSchema);
-
-                STRING fullClassName = extension->GetFeatureClass();
-                STRING schemaName, className;
-                MgUtil::ParseQualifiedClassName(fullClassName, schemaName, className);
-
-                if (!parsedSchemaName.empty())
-                {
-                    descSchema->SetSchemaName(parsedSchemaName.c_str());
-                }
-
-                if (!className.empty())
-                {
-                    FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
-
-                    classNames->Add(className.c_str());
-                    descSchema->SetClassNames(classNames.p);
-                }
-
-                FdoPtr<FdoFeatureSchemaCollection> schemas = (FdoFeatureSchemaCollection *) descSchema->Execute ();
-                FdoPtr<FdoFeatureSchema> schema = (FdoFeatureSchema *)schemas->GetItem (parsedSchemaName.c_str());
-                FdoPtr<FdoClassCollection> classes = schema->GetClasses();
-
-                FdoPtr<FdoClassDefinition> activeClass = classes->GetItem(className.c_str());
-                FdoPtr<FdoPropertyDefinitionCollection> properties = activeClass->GetProperties();
-                for(int i = 0; i < properties->GetCount(); i++)
-                {
-                    FdoPtr<FdoPropertyDefinition> activeProperty = properties->GetItem(i);
-                    FdoPtr<FdoIdentifier> idf = FdoIdentifier::Create(activeProperty->GetName());
-                    lsellist->Add(idf);
-                }
-                FdoPtr<FdoReadOnlyPropertyDefinitionCollection> baseProps = activeClass->GetBaseProperties();
-                if (baseProps != NULL)
-                {
-                    for(int i = 0; i < baseProps->GetCount(); i++)
-                    {
-                        FdoPtr<FdoPropertyDefinition>prop = baseProps->GetItem(i);
-                        if( prop->GetIsSystem() )
-                            continue;
-                        lsellist->Add( FdoPtr<FdoIdentifier>(FdoIdentifier::Create( prop->GetName() ) ) );
-                    }
-                }
-            }
-
-            FdoPtr<IGWSQueryDefinition> lqd = IGWSFeatureQueryDefinition::Create(
-                lsellist,
-                GWSQualifiedName(primaryConnectionName.c_str(), primaryFsSchema.c_str(), primaryFsClassName.c_str()),
-                lfilter);
-            CHECKNULL(lqd, L"MgdFeatureService::JoinFeatures");
-            qd = lqd;
-
-            IGWSJoinQueryDefinition* jqd = NULL;
-
-            MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
-            CHECKNULL(attributeRelates, L"MgdFeatureService::JoinFeatures");
-
-            bool bForceOneToOne = true;
-            Ptr<MgStringCollection> attributeNameDelimiters = new MgStringCollection();
-
-            //Store all the secondary's name, and if the filter property doesn't contain secondary's name,
-            //it applies only to the primary.
-            Ptr<MgStringCollection> secondaryNames = new MgStringCollection();
-
-            // For each join (attributeRelate) to a secondary source need to do the following
-            for (int attributeRelateIndex = 0; attributeRelateIndex < attributeRelates->GetCount(); attributeRelateIndex++)
-            {
-                MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(attributeRelateIndex);
-                CHECKNULL(attributeRelate, L"MgdFeatureService::JoinFeatures");
-
-                // Get the secondary resource id
-                STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
-
-                // Get the name for the join relationship
-                STRING attributeRelateName = (STRING)attributeRelate->GetName();
-                STRING secondaryConnectionName = attributeRelateName;
-
-                if(!secondaryNames->Contains(attributeRelateName))
-                    secondaryNames->Add(attributeRelateName);
-
-                // Get the RelateType (join type).  Default is Left Outer join.
-                MdfModel::AttributeRelate::RelateType relateType = attributeRelate->GetRelateType();
-
-                // Get the ForceOneToOne field, which specifies if multiple matching secondary features
-                // are retrieved via a 1-to-1 or 1-to-many relationship.  Default is 1-to-1 relationship.
-                bool forceOneToOne = attributeRelate->GetForceOneToOne();
-                // If there is at least one relation is defined as one-to-many, then the one-to-many result will apply to all join results.
-                if (!forceOneToOne)
-                {
-                    bForceOneToOne = false;
-                }
-
-                // Get the AttributeNameDelimiter field, which specifies the delimiter between the JoinName (attribute relate name)
-                // and the property name for an extended property.  Default delimiter is "" (blank).
-                STRING attributeNameDelimiter = (STRING)attributeRelate->GetAttributeNameDelimiter();
-                attributeNameDelimiters->Add(attributeNameDelimiter);
-
-                // Establish connection to provider for secondary feature source
-                Ptr<MgResourceIdentifier> secondaryFeatureSource = new MgResourceIdentifier(secondaryResourceId);
-
-                if (NULL != secondaryFeatureSource)
-                {
-                    Ptr<MgFeatureConnection> fdoRightConn = new MgFeatureConnection(secondaryFeatureSource);
-                    
-                    if ((NULL != fdoRightConn.p) && ( fdoRightConn->IsConnectionOpen() ))
-                    {
-                        pool->AddConnection(secondaryConnectionName.c_str(), fdoRightConn);
-                    }
-                    else
-                    {
-                        throw new MgConnectionFailedException(L"MgdFeatureService::JoinFeatures",
-                            __LINE__, __WFILE__, NULL, L"", NULL);
-                    }
-                }
-
-                // Get the secondary featureClassName (qualified className)
-                STRING secondaryClassName = (STRING)attributeRelate->GetAttributeClass();
-
-                // Parse the qualified classname
-                STRING secondaryFsSchema, secondaryFsClassName;
-                MgUtil::ParseQualifiedClassName(secondaryClassName, secondaryFsSchema, secondaryFsClassName);
-
-                // Create secondary query definition
-                FdoPtr<FdoIdentifierCollection> rsellist;
-                FdoPtr<FdoFilter> rfilter;
-
-                FdoPtr<IGWSQueryDefinition> rqd  = IGWSFeatureQueryDefinition::Create(
-                    rsellist,
-                    GWSQualifiedName(secondaryConnectionName.c_str(), secondaryFsSchema.c_str(), secondaryFsClassName.c_str()),
-                    rfilter);
-                CHECKNULL(rqd, L"MgdFeatureService::JoinFeatures");
-
-                // Get Join Attributes
-                FdoPtr<FdoStringCollection> lattrs = FdoStringCollection::Create();
-                FdoPtr<FdoStringCollection> rattrs = FdoStringCollection::Create();
-
-                // Determine the number of RelateProperties (attributes)
-                MdfModel::RelatePropertyCollection* relateProperties = attributeRelate->GetRelateProperties();
-                CHECKNULL(relateProperties, L"MgdFeatureService::JoinFeatures");
-                int nRelatePropertyCount = relateProperties->GetCount();
-
-                // For each RelateProperty need to do the following
-                for (int relatePropertyIndex = 0; relatePropertyIndex < nRelatePropertyCount; relatePropertyIndex++)
-                {
-                    MdfModel::RelateProperty* relateProperty = relateProperties->GetAt(relatePropertyIndex);
-                    CHECKNULL(relateProperty, L"MgdFeatureService::JoinFeatures");
-
-                    // Get the FeatureClassProperty (primary attribute)
-                    STRING primaryAttribute = (STRING)relateProperty->GetFeatureClassProperty();
-
-                    // Add to the primary attribute String collection
-                    lattrs->Add(primaryAttribute.c_str());
-
-                    // Get the AttributeClassProperty (secondary attribute)
-                    STRING secondaryAttribute = (STRING)relateProperty->GetAttributeClassProperty();
-
-                    // Add to the secondary attribute String collection
-                    rattrs->Add(secondaryAttribute.c_str());
-                }
-
-                // Create the QueryDefinition
-                if (NULL != rqd)
-                {
-                    FdoString* joinName = attributeRelateName.c_str();
-                    FdoString* joinDelimiter = L".";
-                    if (MdfModel::AttributeRelate::Inner == relateType)
-                    {
-                        jqd = IGWSEqualJoinQueryDefinition::Create(joinName, joinDelimiter, bForceOneToOne, lqd, rqd, lattrs, rattrs);
-                    }
-                    else  // if (RelateType::LeftOuter == relateType)
-                    {
-                        jqd = IGWSLeftJoinQueryDefinition::Create(joinName, joinDelimiter, bForceOneToOne, lqd, rqd, lattrs, rattrs);
-                    }
-                    lqd = jqd;
-                }
-
-            }  // Repeat for each secondary source
-            qd = lqd;
-
-            FdoPtr<IGWSQuery> query = IGWSQuery::Create(pool, qd, NULL);
-            // This encapsulates our join query results
-            FdoPtr<IGWSFeatureIterator> iter;
-            // This copy is used to construct the Class Definition that the GWS Feature Reader returns
-            FdoPtr<IGWSFeatureIterator> iterCopy;
-
-            // Set batch size as it may be needed
-            CGwsBatchSortedBlockJoinQueryResults::sm_nBatchSize = m_nJoinQueryBatchSize;
-
-            // Prepare and Execute Query
-            query->Prepare();
-            
-            // Search the filter to see if it contains the extension name
-            // If the extension name is not found it means that the filter involves attribute(s) only from the primary
-            if(NULL != filter)
-            {
-                FdoString* filterText = filter->ToString();
-                if(NULL != filterText)
-                {
-                    bool match = false;
-                    for(int i = 0; i < secondaryNames->GetCount(); i ++)
-                    {
-                        STRING secondaryName = secondaryNames->GetItem(i);
-                        if(NULL != wcsstr(filterText, secondaryName.c_str()))
-                        {
-                            match = true;
-                            break;
-                        }
-                    }
-                    if(!match)
-                    {
-                        // Add the filter to the query because it only applies to the primary
-                        query->SetFilter(filter);
-                    }
-                }
-            }
-
-            // Execute the query
-            query->Execute(&iter, true);
-            query->Execute(&iterCopy, true);
-
-            FdoPtr<FdoStringCollection> fsNames = qd->FeatureSourceNames();
-
-            gwsFeatureReader = new MgdGwsFeatureReader(pool, iter, iterCopy, parsedExtensionName, fsNames, bForceOneToOne, attributeNameDelimiters);
-            gwsFeatureReader->SetFilter(filter);
-            break;
-        }
-    }
-
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceIdentifier, L"MgdFeatureService::JoinFeatures")
-
-    // Now that the reader has been created we will need to mark all of the connections it uses as OwnReader() because the GWS reader will be
-    // taking ownership of the connections. We have to do it this late in the code in case an exception is thrown somewhere before this.
-    // We want to avoid a deadlock of the connection :)
-    gwsFeatureReader->OwnsConnections();
-
-    return gwsFeatureReader.Detach();
-}
-
-bool MgdFeatureService::SupportsFdoJoins(MgFeatureConnection* conn, MdfModel::Extension* extension)
-{
-    bool bSupported = false;
-
-    MG_FEATURE_SERVICE_TRY()
-
-    //Get the easy checks out of the way
-    if (!conn->SupportsJoins())
-    {
-#ifdef DEBUG_FDOJOIN
-        ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Connection does not support FDO joins")));
-#endif
-        return false;
-    }
-
-    FdoJoinType jtypes = conn->GetJoinTypes();
-
-    //Now ascertain if all participating feature classes originate from the same feature source
-    Ptr<MgResourceIdentifier> fsId = conn->GetFeatureSource();
-    MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
-
-    //We've yet to figure out chained joins
-    if (relates->GetCount() > 1)
-    {
-#ifdef DEBUG_FDOJOIN
-        ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Multiple joins not yet supported")));
-#endif
-        return false;
-    }
-
-    for (INT32 i = 0; i < relates->GetCount(); i++)
-    {
-        MdfModel::AttributeRelate* relate = relates->GetAt(i);
-        const MdfModel::MdfString& featureSourceId = relate->GetResourceId();
-
-        //Different feature sources
-        if (fsId->ToString() != featureSourceId)
-        {
-#ifdef DEBUG_FDOJOIN
-            ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Not joining to class from same feature source")));
-#endif
-            return false;
-        }
-
-        MdfModel::RelatePropertyCollection* relProps = relate->GetRelateProperties();
-
-        //Check if the join type is supported. Given FDO exposes more join types than
-        //the ones specified here, the chances are real good that we'll have a match
-        MdfModel::AttributeRelate::RelateType rtype = relate->GetRelateType();
-        switch(rtype)
-        {
-        case MdfModel::AttributeRelate::Inner:
-            if ((jtypes & FdoJoinType_Inner) != FdoJoinType_Inner)
-            {
-#ifdef DEBUG_FDOJOIN
-                ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Unsupported join type")));
-#endif
-                return false;
-            }
-            break;
-        case MdfModel::AttributeRelate::LeftOuter:
-            if ((jtypes & FdoJoinType_LeftOuter) != FdoJoinType_LeftOuter)
-            {
-#ifdef DEBUG_FDOJOIN
-                ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Unsupported join type")));
-#endif
-                return false;
-            }
-            break;
-        case MdfModel::AttributeRelate::RightOuter:
-            if ((jtypes & FdoJoinType_RightOuter) != FdoJoinType_RightOuter)
-            {
-#ifdef DEBUG_FDOJOIN
-                ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Unsupported join type")));
-#endif
-                return false;
-            }
-            break;
-        default:
-            {
-#ifdef DEBUG_FDOJOIN
-                ACE_DEBUG((LM_INFO, ACE_TEXT("\n[FDO Join Test]: Unrecognised join type")));
-#endif
-                return false;
-            }
-        }
-    }
-
-    //Still here? You pass the test
-    bSupported = true;
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::SupportsFdoJoin")
-
-    return bSupported;
-}
-
-MgFeatureReader* MgdFeatureService::SelectFdoJoin(MgFeatureConnection* conn, MdfModel::Extension* extension, FdoFilter* filter)
-{
-    Ptr<MgFeatureReader> ret;
-
-    MG_FEATURE_SERVICE_TRY()
-
-    FdoPtr<FdoIConnection> fdoConn = conn->GetConnection();
-    FdoPtr<FdoISelect> selExt = static_cast<FdoISelect*>(fdoConn->CreateCommand(FdoCommandType_Select));
-
-    const MdfModel::MdfString& primaryClassName = extension->GetFeatureClass();
-    selExt->SetFeatureClassName(primaryClassName.c_str());
-
-    if (NULL != filter)
-        selExt->SetFilter(filter);
-
-    STRING primarySchema;
-    STRING primaryClass;
-    MgUtil::ParseQualifiedClassName(primaryClassName, primarySchema, primaryClass);
-    selExt->SetAlias(primaryClass.c_str());
-    FdoPtr<FdoIdentifierCollection> propNames = selExt->GetPropertyNames();
-
-    //These two maps will allow us to resolve an Extended Feature Class Property
-    //to the form [Alias].[PropertyName]
-    //
-    //TODO: How does FDO escape property names with spaces? Double quotes doesn't work 
-    //(as stupid and ridiculous as it is from a data modeling perspective)
-
-    Ptr<MgStringCollection> idPropNames = new MgStringCollection();
-
-    FdoPtr<FdoJoinCriteriaCollection> joinCriteria = selExt->GetJoinCriteria();
-    
-    //Include all primary class properties (data/geometry) in query
-    Ptr<MgResourceIdentifier> fsId = conn->GetFeatureSource();
-    Ptr<MgClassDefinition> primaryClassDef = GetClassDefinition(fsId, primarySchema, primaryClass);
-    Ptr<MgPropertyDefinitionCollection> primaryClassProps = primaryClassDef->GetProperties();
-    for (INT32 i = 0; i < primaryClassProps->GetCount(); i++)
-    {
-        Ptr<MgPropertyDefinition> propDef = primaryClassProps->GetItem(i);
-        if (propDef->GetPropertyType() == MgFeaturePropertyType::DataProperty ||
-            propDef->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
-        {
-            STRING pn = primaryClass + L"." + propDef->GetName();
-            FdoString* expr = pn.c_str();
-            FdoPtr<FdoIdentifier> propName = FdoIdentifier::Create(expr);
-            //Include in query
-            propNames->Add(propName);
-
-#ifdef DEBUG_FDOJOIN
-            ACE_DEBUG((LM_INFO, ACE_TEXT("\nAdd Property to join query: %W"), expr));
-#endif
-        }
-    }
-    Ptr<MgPropertyDefinitionCollection> idClassProps = primaryClassDef->GetIdentityProperties();
-    for (INT32 i = 0; i < idClassProps->GetCount(); i++)
-    {
-        Ptr<MgPropertyDefinition> propDef = idClassProps->GetItem(i);
-        idPropNames->Add(propDef->GetName());
-    }
-
-    //Process the joins
-    MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
-    
-    bool bForceOneToOne = false;
-    //SupportsFdoJoin() has vetted that relates->GetCount() == 1
-    //It's coded in this fashion to facilitate support for additional cases (eg. Chained joins)
-    //in the future
-    for (INT32 i = 0; i < relates->GetCount(); i++)
-    {
-        MdfModel::AttributeRelate* relate = relates->GetAt(i);
-        const MdfModel::MdfString& prefix = relate->GetName();
-        FdoPtr<FdoJoinCriteria> criteria;
-
-        const MdfModel::MdfString& attrClassName = relate->GetAttributeClass();
-        FdoPtr<FdoIdentifier> joinClass = FdoIdentifier::Create(attrClassName.c_str());
-
-        FdoJoinType jtype = FdoJoinType_None;
-        switch(relate->GetRelateType())
-        {
-        case MdfModel::AttributeRelate::Inner:
-            jtype = FdoJoinType_Inner;
-            break;
-        case MdfModel::AttributeRelate::LeftOuter:
-            jtype = FdoJoinType_LeftOuter;
-            break;
-        case MdfModel::AttributeRelate::RightOuter:
-            jtype = FdoJoinType_RightOuter;
-            break;
-        }
-
-        STRING joinSchemaName;
-        STRING joinClassName;
-        MgUtil::ParseQualifiedClassName(attrClassName, joinSchemaName, joinClassName);
-
-        MdfModel::RelatePropertyCollection* relProps = relate->GetRelateProperties();
-
-        if (relate->GetForceOneToOne())
-        {
-            bForceOneToOne = true;
-        }
-
-        //NOTE: Sadly, the extended class definition does not explicity specify the list of join properties
-        //only the ones to join on. So grab the join class definition to compile this list
-        Ptr<MgResourceIdentifier> joinResId = new MgResourceIdentifier(relate->GetResourceId());
-        Ptr<MgClassDefinition> joinClassDef = GetClassDefinition(joinResId, joinSchemaName, joinClassName);
-
-        //Compile mappings
-        Ptr<MgPropertyDefinitionCollection> joinClassProps = joinClassDef->GetProperties();
-        for (INT32 j = 0; j < joinClassProps->GetCount(); j++)
-        {
-            Ptr<MgPropertyDefinition> propDef = joinClassProps->GetItem(j);
-            if (propDef->GetPropertyType() == MgFeaturePropertyType::DataProperty ||
-                propDef->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
-            {
-                //[joinAlias].[propertyName] AS [readerPropName]
-                STRING readerPropName = prefix + propDef->GetName();
-                STRING exprText = joinClassName + L"." + propDef->GetName();
-                FdoPtr<FdoExpression> expr = FdoExpression::Parse(exprText.c_str());
-                FdoPtr<FdoComputedIdentifier> propName = FdoComputedIdentifier::Create(readerPropName.c_str(), expr);
-                //Include in query
-                propNames->Add(propName);
-
-#ifdef DEBUG_FDOJOIN
-                ACE_DEBUG((LM_INFO, ACE_TEXT("\nAdd Property to join query: %W AS %W"), exprText.c_str(), readerPropName.c_str()));
-#endif
-            }
-        }
-
-        STRING filterText;
-
-        //Set filter for this join
-        for (INT32 j = 0; j < relProps->GetCount(); j++)
-        {
-            MdfModel::RelateProperty* prop = relProps->GetAt(j);
-            if (!filterText.empty())
-            {
-                filterText += L" AND ";
-            }
-
-            //[PrimaryClass].[PropertyName] = [JoinClass].[PropertyName]
-            filterText += primaryClass;
-            filterText += L".";
-            filterText += prop->GetFeatureClassProperty();
-            filterText += L" = ";
-            filterText += joinClassName;
-            filterText += L".";
-            filterText += prop->GetAttributeClassProperty();
-        }
-
-#ifdef DEBUG_FDOJOIN
-        ACE_DEBUG((LM_INFO, ACE_TEXT("\nAdd Join Filter: %W"), filterText.c_str()));
-#endif
-        FdoPtr<FdoFilter> filter = FdoFilter::Parse(filterText.c_str());
-        if (prefix.empty())
-            criteria = FdoJoinCriteria::Create(joinClass, jtype, filter);
-        else
-            criteria = FdoJoinCriteria::Create(joinClassName.c_str(), joinClass, jtype, filter);
-
-        joinCriteria->Add(criteria);
-    }
-
-    FdoPtr<FdoIFeatureReader> fdoFr = selExt->Execute();
-    if (bForceOneToOne) {
-        FdoPtr<FdoStringCollection> propNames = MgFeatureUtil::MgToFdoStringCollection(idPropNames, false);
-        FdoPtr<FdoIFeatureReader> forcedReader = new MgFdoForcedOneToOneFeatureReader(fdoFr, propNames);
-        ret = new MgdFeatureReader(conn, forcedReader);
-    } else {
-        ret = new MgdFeatureReader(conn, fdoFr);
-    }
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::SelectFdoJoin")
-
-    return ret.Detach();
-}
-
-bool MgdFeatureService::FindFeatureJoinProperties(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
-{
-    bool bJoinPropertiesExists = false;
-
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    Ptr<MgFeatureSourceCacheItem> fsCacheItem = cache->GetFeatureSource(featureSourceId);
-
-    CHECKNULL(fsCacheItem.p, L"MgdFeatureService::FindFeatureJoinProperties");
-    MdfModel::FeatureSource* featureSource = fsCacheItem->Get();
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::FindFeatureJoinProperties");
-
-    for (int i = 0; i < extensions->GetCount(); i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::FindFeatureJoinProperties");
-        STRING name = (STRING)extension->GetName();
-
-        STRING parsedSchemaName, parsedExtensionName;
-        MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
-
-        if (parsedExtensionName != name)
-        {
-            continue;
-        }
-        else
-        {
-            AttributeRelateCollection* relates = extension->GetAttributeRelates();
-            bJoinPropertiesExists = (relates != NULL && relates->GetCount() != 0);
-            break;
-        }
-    }
-
-    return bJoinPropertiesExists;
-}
-
-bool MgdFeatureService::FindFeatureCalculation(MgResourceIdentifier* resourceId, CREFSTRING extensionName)
-{
-    bool bCalculationExists = false;
-
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    Ptr<MgFeatureSourceCacheItem> fsCacheItem = cache->GetFeatureSource(resourceId);
-
-    CHECKNULL(fsCacheItem.p, L"MgdFeatureService::FindFeatureCalculation");
-    MdfModel::FeatureSource* featureSource = fsCacheItem->Get();
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::FindFeatureCalculation");
-
-    for (int i = 0; i < extensions->GetCount(); i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::FindFeatureCalculation");
-        STRING name = (STRING)extension->GetName();
-
-        STRING parsedSchemaName, parsedExtensionName;
-        MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
-
-        if (parsedExtensionName != name)
-        {
-            continue;
-        }
-        else
-        {
-            CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
-            // we don't have joins but we have calculations
-            bCalculationExists = (calcProps != NULL && calcProps->GetCount() != 0);
-            break;
-        }
-    }
-
-    return bCalculationExists;
-}
-
-void MgdFeatureService::UpdateCommandOnCalculation(FdoIBaseSelect* command, MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
-{
-    MG_FEATURE_SERVICE_TRY()
-
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    Ptr<MgFeatureSourceCacheItem> fsCacheItem = cache->GetFeatureSource(featureSourceId);
-
-    CHECKNULL(fsCacheItem.p, L"MgdFeatureService::UpdateCommandOnCalculation");
-    MdfModel::FeatureSource* featureSource = fsCacheItem->Get();
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::UpdateCommandOnCalculation");
-
-    for (int i = 0; i < extensions->GetCount(); i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::UpdateCommandOnCalculation");
-        STRING name = (STRING)extension->GetName();
-
-        STRING parsedSchemaName, parsedExtensionName;
-        ParseQualifiedClassNameForCalculation(extension, extensionName, parsedSchemaName, parsedExtensionName);
-
-        if (parsedExtensionName != name)
-        {
-            continue;
-        }
-        else
-        {
-            command->SetFeatureClassName(extension->GetFeatureClass().c_str());
-            CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
-            if (calcProps == NULL || calcProps->GetCount() == 0)
-                break;
-            FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
-            for (int idx = 0; idx < calcProps->GetCount(); idx++)
-            {
-                CalculatedProperty* calcProp = calcProps->GetAt(idx);
-                FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
-                FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
-                idList->Add(idfCalc);
-            }
-            FdoPtr<FdoFilter> filter = command->GetFilter();
-            if (filter != NULL)
-            {
-                FdoPtr<FdoFilter> newFilter = FdoExpressionEngineCopyFilter::Copy(filter, idList);
-                command->SetFilter(newFilter);
-            }
-
-            FdoPtr<FdoIdentifierCollection> fic = command->GetPropertyNames();
-            bool addAllProps = (fic->GetCount() == 0);
-            for (int idx = 0; idx < calcProps->GetCount(); idx++)
-            {
-                CalculatedProperty* calcProp = calcProps->GetAt(idx);
-                FdoPtr<FdoIdentifier> idf = fic->FindItem(calcProp->GetName().c_str());
-                if (idf != NULL)
-                {
-                    // replace calculated properties provided as identifiers to computed identifiers
-                    FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(idf->GetName()));
-                    FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
-                    FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
-
-                    int idfIndex = fic->IndexOf(idf);
-                    FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(idf->GetName(), expandedExpression);
-                    fic->SetItem(idfIndex, newIdf);
-                }
-                else
-                {
-                    if (addAllProps)
-                    {
-                        FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(calcProp->GetName().c_str()));
-                        FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
-                        FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
-
-                        FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expandedExpression);
-                        fic->Add(newIdf);
-                    }
-                }
-                if (addAllProps)
-                {
-                    Ptr<MgFeatureConnection> conn = new MgFeatureConnection(featureSourceId);
-                    if ((NULL != conn.p) && ( conn->IsConnectionOpen() ))
-                    {
-                        FdoPtr<FdoIConnection> fdoConn = conn->GetConnection();
-                        // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
-                        // otherwise it leaves the FDO connection marked as still in use.
-                        //FdoPtr<FdoIConnection> conn = fcConnection->GetConnection();
-                        FdoPtr<FdoIDescribeSchema>  descSchema = (FdoIDescribeSchema *) fdoConn->CreateCommand (FdoCommandType_DescribeSchema);
-
-                        STRING fullClassName = extension->GetFeatureClass();
-                        STRING schemaName, className;
-                        MgUtil::ParseQualifiedClassName(fullClassName, schemaName, className);
-
-                        if (!parsedSchemaName.empty())
-                        {
-                            descSchema->SetSchemaName(parsedSchemaName.c_str());
-                        }
-
-                        if (!className.empty())
-                        {
-                            FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
-
-                            classNames->Add(className.c_str());
-                            descSchema->SetClassNames(classNames.p);
-                        }
-
-                        FdoPtr <FdoFeatureSchemaCollection> schemas = (FdoFeatureSchemaCollection *) descSchema->Execute ();
-                        FdoPtr<FdoFeatureSchema> schema = (FdoFeatureSchema *)schemas->GetItem (parsedSchemaName.c_str());
-                        FdoPtr<FdoClassCollection> classes = schema->GetClasses();
-
-                        FdoPtr<FdoClassDefinition> activeClass = classes->GetItem(className.c_str());
-                        FdoPtr<FdoPropertyDefinitionCollection> properties = activeClass->GetProperties();
-                        for(int i = 0; i < properties->GetCount(); i++)
-                        {
-                            FdoPtr<FdoPropertyDefinition> activeProperty = properties->GetItem(i);
-                            FdoPtr<FdoIdentifier> idf = fic->FindItem(activeProperty->GetName());
-                            if (idf == NULL)
-                            {
-                                idf = FdoIdentifier::Create(activeProperty->GetName());
-                                fic->Add(idf);
-                            }
-                        }
-                        FdoPtr<FdoReadOnlyPropertyDefinitionCollection> baseProps = activeClass->GetBaseProperties();
-                        if (baseProps != NULL)
-                        {
-                            for(int i = 0; i < baseProps->GetCount(); i++)
-                            {
-                                FdoPtr<FdoPropertyDefinition>prop = baseProps->GetItem(i);
-                                if( prop->GetIsSystem() )
-                                    continue;
-                                fic->Add( FdoPtr<FdoIdentifier>(FdoIdentifier::Create( prop->GetName() ) ) );
-                            }
-                        }
-                    }
-                }
-            }
-            break;
-        }
-    }
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgdFeatureService::UpdateCommandOnCalculation")
-}
-
-void MgdFeatureService::UpdateCommandOnJoinCalculation(FdoIBaseSelect* command, MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
-{
-    MG_FEATURE_SERVICE_TRY()
-
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    Ptr<MgFeatureSourceCacheItem> fsCacheItem = cache->GetFeatureSource(featureSourceId);
-
-    CHECKNULL(fsCacheItem.p, L"MgdFeatureService::UpdateCommandOnJoinCalculation");
-    MdfModel::FeatureSource* featureSource = fsCacheItem->Get();
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::UpdateCommandOnJoinCalculation");
-
-    for (int i = 0; i < extensions->GetCount(); i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::UpdateCommandOnJoinCalculation");
-        STRING name = (STRING)extension->GetName();
-
-        STRING parsedSchemaName, parsedExtensionName;
-        ParseQualifiedClassNameForCalculation(extension, extensionName, parsedSchemaName, parsedExtensionName);
-
-        if (parsedExtensionName != name)
-        {
-            continue;
-        }
-        else
-        {
-            CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
-            if (calcProps == NULL || calcProps->GetCount() == 0)
-                break;
-            FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
-            for (int idx = 0; idx < calcProps->GetCount(); idx++)
-            {
-                CalculatedProperty* calcProp = calcProps->GetAt(idx);
-                FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
-                FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
-                idList->Add(idfCalc);
-            }
-            FdoPtr<FdoFilter> filter = command->GetFilter();
-            if (filter != NULL)
-            {
-                FdoPtr<FdoFilter> newFilter = FdoExpressionEngineCopyFilter::Copy(filter, idList);
-                command->SetFilter(newFilter);
-            }
-
-            FdoPtr<FdoIdentifierCollection> fic = command->GetPropertyNames();
-            if (fic->GetCount() != 0)
-            {
-                // replace calculated properties provided as identifiers to computed identifiers
-                for (int idx = 0; idx < calcProps->GetCount(); idx++)
-                {
-                    CalculatedProperty* calcProp = calcProps->GetAt(idx);
-                    FdoPtr<FdoIdentifier> idf = fic->FindItem(calcProp->GetName().c_str());
-                    if (idf != NULL)
-                    {
-                        FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(idf->GetName()));
-                        FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
-                        FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
-
-                        int idfIndex = fic->IndexOf(idf);
-                        FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(idf->GetName(), expandedExpression);
-                        fic->SetItem(idfIndex, newIdf);
-                    }
-                }
-            }
-            break;
-        }
-    }
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgdFeatureService::UpdateCommandOnJoinCalculation")
-}
-
-void MgdFeatureService::ParseQualifiedClassNameForCalculation(MdfModel::Extension* extension, CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className)
-{
-    CHECKNULL(extension, L"MgdFeatureService::ParseQualifiedClassNameForCalculation");
-
-    MgUtil::ParseQualifiedClassName(qualifiedClassName, schemaName, className);
-
-    if (schemaName.empty())
-    {
-        STRING dummyStr;
-
-        MgUtil::ParseQualifiedClassName(extension->GetFeatureClass(), schemaName, dummyStr);
-    }
-}
-
-MgResourceIdentifier* MgdFeatureService::GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName)
-{
-    Ptr<MgResourceIdentifier> secResId;
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    Ptr<MgFeatureSourceCacheItem> fsCacheItem = cache->GetFeatureSource(primResId);
-
-    CHECKNULL(fsCacheItem.p, L"MgdFeatureService::GetSecondaryResourceIdentifier");
-    MdfModel::FeatureSource* featureSource = fsCacheItem->Get();
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::GetSecondaryResourceIdentifier");
-
-    for (int i = 0; i < extensions->GetCount(); i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::GetSecondaryResourceIdentifier");
-
-        // Get the extension name
-        STRING name = (STRING)extension->GetName();
-
-        STRING parsedSchemaName, parsedExtensionName;
-        MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
-
-        if (parsedExtensionName != name)
-        {
-            continue;
-        }
-        else
-        {
-            // Determine the number of secondary sources (AttributeRelates)
-            MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
-            CHECKNULL(attributeRelates, L"MgdFeatureService::GetSecondaryResourceIdentifier");
-            int nAttributeRelateCount = attributeRelates->GetCount();
-
-            // Find the specified relation name
-            {
-                for (int attributeRelateIndex = 0; attributeRelateIndex < nAttributeRelateCount; attributeRelateIndex++)
-                {
-                    MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(attributeRelateIndex);
-                    CHECKNULL(attributeRelate, L"MgdFeatureService::GetSecondaryResourceIdentifier");
-
-                    // Get the name for the join relationship
-                    STRING attributeRelateName = (STRING)attributeRelate->GetName();
-
-                    if (attributeRelateName != relationName)
-                    {
-                        continue;
-                    }
-                    else
-                    {
-                        // Get the secondary resource id
-                        STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
-                        secResId = new MgResourceIdentifier(secondaryResourceId);
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    return secResId.Detach();
-}
-
 MgDataReader* MgdFeatureService::SelectAggregate(MgResourceIdentifier* resource,
                                                  CREFSTRING className,
                                                  MgFeatureAggregateOptions* options) 
@@ -3749,20 +839,19 @@
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"MgFeatureAggregateOptions");
     MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
-    MG_LOG_TRACE_ENTRY(L"MgdFeatureService::SelectAggregate()");
+    MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::Trace, L"MgdFeatureService::SelectAggregate", mgStackParams);
+    logDetail.AddResourceIdentifier(L"Resource", resource);
+    logDetail.AddString(L"ClassName", className);
+    logDetail.AddObject(L"Options", options);
+    logDetail.Create();
 
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::SelectAggregate");
 	CHECKARGUMENTNULL(options, L"MgdFeatureService::SelectAggregate");
-    if (className.empty())
-        throw new MgInvalidArgumentException(L"MgdFeatureService::SelectAggregate", __LINE__, __WFILE__, NULL, L"", NULL);
+    
+    MgSelectFeatures select;
+    reader = dynamic_cast<MgDataReader*>(select.SelectFeatures(resource, className, options, true));
+    CHECKNULL(reader.p, L"MgdFeatureService::SelectAggregate");
 
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-    bool bFeatureJoin = FindFeatureJoinProperties(resource, className);
-    if (bFeatureJoin)
-        reader = SelectAggregateJoined(connWrap, className, options);
-    else
-        reader = SelectAggregateNormal(connWrap, className, options);
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -3783,210 +872,6 @@
 	return reader.Detach();
 }
 
-MgDataReader* MgdFeatureService::SelectAggregateNormal(MgFeatureConnection* connWrap, CREFSTRING className, MgFeatureAggregateOptions* options)
-{
-    Ptr<MgDataReader> reader;
-    MG_FEATURE_SERVICE_TRY()
-    
-    CHECKNULL(options, L"MgdFeatureService::SelectAggregateNormal");
-    CHECKNULL(connWrap, L"MgdFeatureService::SelectAggregateNormal");
-    FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
-
-    FdoPtr<FdoISelectAggregates> select = (FdoISelectAggregates*)conn->CreateCommand(FdoCommandType_SelectAggregates);
-    select->SetFeatureClassName(className.c_str());
-
-    STRING filter = options->GetFilter();
-    if (!filter.empty())
-        select->SetFilter(filter.c_str());
-
-    Ptr<MgStringCollection> props = options->GetClassProperties();
-    Ptr<MgStringPropertyCollection> computed = options->GetComputedProperties();
-
-    INT32 propCount = props->GetCount();
-    INT32 compCount = computed->GetCount();
-	
-    bool bCustomPropertyFound = false;
-    FdoFunction* customFunc = NULL;
-    STRING customPropName;
-
-    FdoPtr<FdoIdentifierCollection> fdoProps = select->GetPropertyNames();
-    if (propCount > 0)
-    {
-        for (INT32 i = 0; i < propCount; i++)
-        {
-            FdoPtr<FdoIdentifier> name = FdoIdentifier::Create(props->GetItem(i).c_str());
-            fdoProps->Add(name);
-        }
-    }
-    if (compCount > 0)
-    {
-        for (INT32 i = 0; i < compCount; i++)
-        {
-            Ptr<MgStringProperty> comp = computed->GetItem(i);
-		    STRING aliasName = comp->GetName();
-            FdoPtr<FdoExpression> expr = FdoExpression::Parse(comp->GetValue().c_str());
-	        
-		    if (ContainsUdf(connWrap, expr))
-		    {
-			    // If property is already found, two custom properties are not supported and therefore throw exception
-			    if (bCustomPropertyFound)
-			    {
-				    STRING message = MgFeatureUtil::GetMessage(L"MgOnlyOnePropertyAllowed");
-
-				    MgStringCollection arguments;
-				    arguments.Add(message);
-				    throw new MgFeatureServiceException(L"MgdFeatureService::SelectAggregate", __LINE__, __WFILE__, &arguments, L"", NULL);
-			    }
-
-			    // Downcast to FdoFunction
-			    FdoFunction* function = dynamic_cast<FdoFunction*>(expr.p);
-
-			    if (function != NULL)
-			    {
-				    FdoString* expName = aliasName.c_str();
-				    if (expName != NULL)
-				    {
-					    FdoPtr<FdoExpressionCollection> exprCol = function->GetArguments();
-					    FdoInt32 cnt = exprCol->GetCount();
-					    FdoPtr<FdoExpression> expr;
-					    if (cnt > 0)
-					    {
-						    expr = exprCol->GetItem(0);   // Property Name
-					    }
-
-					    // Just pass in the property name
-					    // FdoPtr<FdoComputedIdentifier> fdoIden = FdoComputedIdentifier::Create(expName, expr);
-
-					    // NOTE: Each provider has its own rule for supporting computed properties, select and select aggregate
-					    // functionality. Therefore we just work with simple select command, fetch the property and do the needed
-					    // calculations. Therefore, we are not adding them as computed properties.
-
-					    FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p);
-
-					    if (propName != NULL)
-						    fdoProps->Add(propName);
-
-					    customPropName = aliasName;
-					    bCustomPropertyFound = true;
-					    customFunc = FDO_SAFE_ADDREF(function);
-				    }
-			    }
-		    }
-		    else
-		    {
-			    FdoPtr<FdoComputedIdentifier> name = FdoComputedIdentifier::Create(comp->GetName().c_str(), expr);
-			    fdoProps->Add(name);
-		    }
-        }
-    }
-
-    if (options->GetDistinct())
-        select->SetDistinct(true);
-
-    STRING groupFilter = options->GetGroupFilter();
-    if (!groupFilter.empty())
-    {
-        FdoPtr<FdoFilter> grpFilter = FdoFilter::Parse(groupFilter.c_str());
-        select->SetGroupingFilter(grpFilter);
-    }
-    FdoPtr<FdoIdentifierCollection> fdoGroupBy = select->GetGrouping();
-    Ptr<MgStringCollection> mgGroupBy = options->GetGroupingProperties();
-    if (NULL != mgGroupBy && mgGroupBy->GetCount() > 0)
-    {
-        for (INT32 i = 0; i < mgGroupBy->GetCount(); i++)
-        {
-            STRING name = mgGroupBy->GetItem(i);
-            FdoPtr<FdoIdentifier> fdoId = FdoIdentifier::Create(name.c_str());
-
-            fdoGroupBy->Add(fdoId);
-        }
-    }
-
-    FdoPtr<FdoIDataReader> fdoReader = select->Execute();
-    if (bCustomPropertyFound) 
-    {
-	    Ptr<MgReader> origReader = new MgdDataReader(connWrap, fdoReader);
-	    Ptr<MgDataReader> customReader = dynamic_cast<MgDataReader*>(this->GetCustomReader(origReader, customFunc, customPropName));
-	    origReader->Close();
-	    reader = customReader;
-    }
-    else
-    {
-	    reader = new MgdDataReader(connWrap, fdoReader);
-    }
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::SelectAggregateNormal")
-
-    return reader.Detach();
-}
-
-MgDataReader* MgdFeatureService::SelectAggregateJoined(MgFeatureConnection* connWrap, CREFSTRING className, MgFeatureAggregateOptions* options)
-{
-    Ptr<MgDataReader> reader;
-
-    MG_FEATURE_SERVICE_TRY()
-
-    NOT_IMPLEMENTED(L"MgdFeatureService::SelectAggregateJoined");
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::SelectAggregateJoined")
-
-    return reader.Detach();
-}
-
-// Convert reader into a custom MgDataReader
-MgReader* MgdFeatureService::GetCustomReader(MgReader* reader, FdoFunction* customFunc, CREFSTRING propertyName)
-{
-    Ptr<MgReader> distReader;
-    Ptr<MgFeatureDistribution> featureDist =
-        MgFeatureDistribution::CreateDistributionFunction(reader, customFunc, propertyName);
-
-    distReader = featureDist->Execute();
-    return distReader.Detach();
-}
-
-bool MgdFeatureService::ContainsUdf(MgFeatureConnection* conn, FdoExpression* expression)
-{
-    bool isUdf = false;
-    bool fdoSupported = false;
-
-    // Downcast to FdoFunction
-    FdoFunction* function = dynamic_cast<FdoFunction*>(expression);
-
-    // If we are unable to downcast, it means it is not a function, it is just
-    // an expression. We do not do anything with this. We just pass it to FDO
-    if (function != NULL)
-    {
-        if (conn != NULL)
-        {
-            // Check if FDO supports this function, if so, let FDO handle it
-            fdoSupported = conn->IsSupportedFunction(function);
-        }
-
-        if (!fdoSupported)
-        {
-            // If function is not supported, then check if it is a custom function.
-            isUdf = IsCustomFunction(function);
-        }
-    }
-
-    return isUdf;
-}
-
-
-bool MgdFeatureService::IsCustomFunction(FdoFunction* fdoFunc)
-{
-    bool customFunc = false;
-
-    FdoString* funcNameAllowed = fdoFunc->GetName();
-    if (funcNameAllowed != NULL)
-    {
-        INT32 funcIndex = -1;
-        customFunc = MgFeatureUtil::FindCustomFunction(STRING(funcNameAllowed),funcIndex);
-    }
-
-    return customFunc;
-}
-
 MgPropertyCollection* MgdFeatureService::UpdateFeatures(MgResourceIdentifier* resource,
                                                         MgFeatureCommandCollection* commands,
                                                         bool useTransaction) 
@@ -4010,18 +895,9 @@
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::UpdateFeatures");
     CHECKARGUMENTNULL(commands, L"MgdFeatureService::UpdateFeatures");
 
-    Ptr<MgTransaction> trans;
-    if (useTransaction)
-    {
-        trans = BeginTransaction(resource);
-    }
+    MgUpdateFeaturesCommand cmd;
+    result = cmd.Execute(resource, commands, useTransaction);
 
-    result = UpdateFeatures(resource, commands, trans);
-    if (useTransaction && NULL != trans)
-    {
-        trans->Commit();
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -4065,145 +941,9 @@
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::UpdateFeatures");
     CHECKARGUMENTNULL(commands, L"MgdFeatureService::UpdateFeatures");
 
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(transaction);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::InsertFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgUpdateFeaturesCommand cmd;
+    ret = cmd.Execute(resource, commands, transaction);
 
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-    }
-    else
-    {    
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-
-    ret = new MgPropertyCollection();
-
-    INT32 cmdCount = commands->GetCount();
-    if (cmdCount == 0)
-    {
-        MgStringCollection arguments;
-        arguments.Add(L"2");
-        arguments.Add(L"0");
-
-        throw new MgInvalidArgumentException(L"MgdFeatureService::UpdateFeatures",
-            __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
-    }
-
-    FdoPtr<FdoICommandCapabilities> cmdCaps = conn->GetCommandCapabilities();
-    FdoInt32 sCmdCount;
-    FdoInt32* supportedCmds = cmdCaps->GetCommands(sCmdCount);
-
-    for (INT32 i = 0; i < cmdCount; i++)
-    {
-        STRING sIndex;
-        MgUtil::Int32ToString(i, sIndex);
-        Ptr<MgFeatureCommand> fc = commands->GetItem(i);
-        INT32 cmdType = fc->GetCommandType();
-        switch(cmdType)
-        {
-        case MgFeatureCommandType::InsertFeatures:
-            {
-                bool supports = false;
-                for (FdoInt32 j = 0; j < sCmdCount; j++)
-                {
-                    if (supportedCmds[j] == FdoCommandType_Insert)
-                    {
-                        supports = true;
-                        break;
-                    }
-                }
-                if (!supports)
-                {
-                    STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-                    MgStringCollection arguments;
-                    arguments.Add(message);
-                    throw new MgFeatureServiceException(L"MgdFeatureService::UpdateFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
-                }
-
-                Ptr<MgInsertFeatures> insert = dynamic_cast<MgInsertFeatures*>(fc.p);
-                SAFE_ADDREF(insert.p);
-
-                Ptr<MgPropertyCollection> properties = insert->GetPropertyValues();
-                Ptr<MgFeatureReader> reader = InsertFeatures(resource, insert->GetFeatureClassName(), properties, transaction);
-
-                Ptr<MgFeatureProperty> result = new MgFeatureProperty(sIndex, reader);
-                ret->Add(result);
-            }
-            break;
-        case MgFeatureCommandType::DeleteFeatures:
-            {
-                bool supports = false;
-                for (FdoInt32 j = 0; j < sCmdCount; j++)
-                {
-                    if (supportedCmds[j] == FdoCommandType_Delete)
-                    {
-                        supports = true;
-                        break;
-                    }
-                }
-                if (!supports)
-                {
-                    STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-                    MgStringCollection arguments;
-                    arguments.Add(message);
-                    throw new MgFeatureServiceException(L"MgdFeatureService::UpdateFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
-                }
-
-                Ptr<MgDeleteFeatures> deleteCmd = dynamic_cast<MgDeleteFeatures*>(fc.p);
-                SAFE_ADDREF(deleteCmd.p);
-
-                int deleted = DeleteFeatures(resource, deleteCmd->GetFeatureClassName(), deleteCmd->GetFilterText(), transaction);
-
-                Ptr<MgInt32Property> result = new MgInt32Property(sIndex, deleted);
-                ret->Add(result);
-            }
-            break;
-        case MgFeatureCommandType::UpdateFeatures:
-            {
-                bool supports = false;
-                for (FdoInt32 j = 0; j < sCmdCount; j++)
-                {
-                    if (supportedCmds[j] == FdoCommandType_Update)
-                    {
-                        supports = true;
-                        break;
-                    }
-                }
-                if (!supports)
-                {
-                    STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-                    MgStringCollection arguments;
-                    arguments.Add(message);
-                    throw new MgFeatureServiceException(L"MgdFeatureService::UpdateFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
-                }
-
-                Ptr<MgUpdateFeatures> update = dynamic_cast<MgUpdateFeatures*>(fc.p);
-                SAFE_ADDREF(update.p);
-
-                Ptr<MgPropertyCollection> properties = update->GetPropertyValues();
-                int updated = UpdateFeatures(resource, update->GetFeatureClassName(), properties, update->GetFilterText(), transaction);
-
-                Ptr<MgInt32Property> result = new MgInt32Property(sIndex, updated);
-                ret->Add(result);
-            }
-            break;
-        default:
-            STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-            MgStringCollection arguments;
-            arguments.Add(message);
-            throw new MgFeatureServiceException(L"MgdFeatureService::UpdateFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
-        }
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -4242,7 +982,8 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::InsertFeatures()");
 
-	ret = InsertFeatures(resource, className, propertyValues, NULL);
+	MgUpdateFeaturesCommand cmd;
+    ret = cmd.ExecuteInsert(resource, className, propertyValues, NULL);
 
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -4284,52 +1025,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::InsertFeatures()");
 
-    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::InsertFeatures");
-	CHECKARGUMENTNULL(propertyValues, L"MgdFeatureService::InsertFeatures");
-	if (className.empty())
-		throw new MgNullArgumentException(L"MgdFeatureService::InsertFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
-	
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    FdoPtr<FdoITransaction> fdoTrans;
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::InsertFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgUpdateFeaturesCommand cmd;
+    reader = cmd.ExecuteInsert(resource, className, propertyValues, trans);
 
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-        fdoTrans = mgTrans->GetFdoTransaction();
-    }
-    else
-    {    
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-	FdoPtr<FdoIInsert> insert = (FdoIInsert*)conn->CreateCommand(FdoCommandType_Insert);
-	
-	insert->SetFeatureClassName(className.c_str());
-
-	FdoPtr<FdoPropertyValueCollection> propVals = insert->GetPropertyValues();
-	for (INT32 i = 0; i < propertyValues->GetCount(); i++)
-	{
-		Ptr<MgProperty> mgp = propertyValues->GetItem(i);
-		FdoPtr<FdoPropertyValue> pv = MgFeatureUtil::MgPropertyToFdoProperty(mgp);
-
-		propVals->Add(pv);
-	}
-
-    if (NULL != fdoTrans.p)
-        insert->SetTransaction(fdoTrans);
-
-	FdoPtr<FdoIFeatureReader> insertRes = insert->Execute();
-
-	reader = new MgdFeatureReader(connWrap, insertRes);
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -4368,7 +1066,8 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::InsertFeatures()");
 
-    ret = InsertFeatures(resource, className, batchPropertyValues, NULL);
+    MgUpdateFeaturesCommand cmd;
+    ret = cmd.ExecuteInsert(resource, className, batchPropertyValues, NULL);
     
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -4409,104 +1108,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::InsertFeatures()");
 
-    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::InsertFeatures");
-	CHECKARGUMENTNULL(batchPropertyValues, L"MgdFeatureService::InsertFeatures");
-	if (className.empty())
-		throw new MgNullArgumentException(L"MgdFeatureService::InsertFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
-	
-    ret = new MgPropertyCollection();
+    MgUpdateFeaturesCommand cmd;
+    ret = cmd.ExecuteInsert(resource, className, batchPropertyValues, trans);
 
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    FdoPtr<FdoITransaction> fdoTrans;
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::InsertFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
-
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-        fdoTrans = mgTrans->GetFdoTransaction();
-    }
-    else
-    {    
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-	FdoPtr<FdoIInsert> insert = (FdoIInsert*)conn->CreateCommand(FdoCommandType_Insert);
-	
-	insert->SetFeatureClassName(className.c_str());
-
-	FdoPtr<FdoPropertyValueCollection> propVals = insert->GetPropertyValues();
-	
-    if (NULL != fdoTrans.p)
-        insert->SetTransaction(fdoTrans);
-
-    //TODO: Support batch parameters, the main beneficiary of this API. Even then,
-    //the value flipping approach employed here has performance benefits for certain
-    //providers, like SQLite
-
-    for (INT32 i = 0; i < batchPropertyValues->GetCount(); i++)
-    {
-        Ptr<MgPropertyCollection> propertyValues = batchPropertyValues->GetItem(i);
-
-        //First feature, set up the FDO property value collection
-        if (i == 0)
-        {
-            for (INT32 i = 0; i < propertyValues->GetCount(); i++)
-	        {
-		        Ptr<MgProperty> mgp = propertyValues->GetItem(i);
-		        FdoPtr<FdoPropertyValue> pv = MgFeatureUtil::MgPropertyToFdoProperty(mgp);
-
-		        propVals->Add(pv);
-	        }
-        }
-        else //Feature after the first
-        {
-            //Set all to null
-            for (INT32 i = 0; i < propVals->GetCount(); i++)
-            {
-                FdoPtr<FdoPropertyValue> fp = propVals->GetItem(i);
-                FdoPtr<FdoValueExpression> expr = fp->GetValue();
-                FdoDataValue* fdv = dynamic_cast<FdoDataValue*>(expr.p);
-                FdoGeometryValue* fgv = dynamic_cast<FdoGeometryValue*>(expr.p);
-                if (fdv)
-                {
-                    fdv->SetNull();
-                }
-                else if (fgv)
-                {
-                    fgv->SetNullValue();
-                }
-            }
-
-            //Now set the appropriate values. MgFeatureUtil does the work
-            for (INT32 i = 0; i < propertyValues->GetCount(); i++)
-	        {
-                Ptr<MgNullableProperty> mgp = (MgNullableProperty*)propertyValues->GetItem(i);
-                if (!mgp->IsNull())
-                {
-                    FdoPtr<FdoPropertyValue> fp = propVals->GetItem(mgp->GetName().c_str());
-                    MgFeatureUtil::UpdateFdoPropertyValue(fp, mgp);
-                }
-            }
-        }
-
-        STRING sIndex;
-        MgUtil::Int32ToString(i, sIndex);
-
-        //Insert and stash the result in the property collection
-	    FdoPtr<FdoIFeatureReader> insertRes = insert->Execute();
-
-	    Ptr<MgFeatureReader> fr = new MgdFeatureReader(connWrap, insertRes);
-        Ptr<MgFeatureProperty> fp = new MgFeatureProperty(sIndex, fr);
-        ret->Add(fp);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -4567,7 +1171,7 @@
     return ret;
 }
 
-int MgdFeatureService::UpdateFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* propertyValues, CREFSTRING filter, MgTransaction* trans)
+int MgdFeatureService::UpdateFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* batchPropertyValues, CREFSTRING filter, MgTransaction* trans)
 {
     int updated = 0;
     MG_LOG_OPERATION_MESSAGE(L"UpdateFeatures");
@@ -4589,52 +1193,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::UpdateFeatures()");
 
-    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::UpdateFeatures");
-	CHECKARGUMENTNULL(propertyValues, L"MgdFeatureService::UpdateFeatures");
-	if (className.empty())
-		throw new MgNullArgumentException(L"MgdFeatureService::UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgUpdateFeaturesCommand cmd;
+    updated = cmd.ExecuteUpdate(resource, className, batchPropertyValues, filter, trans);
 
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    FdoPtr<FdoITransaction> fdoTrans;
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
-
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-        fdoTrans = mgTrans->GetFdoTransaction();
-    }
-    else
-    {
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-	FdoPtr<FdoIUpdate> update = (FdoIUpdate*)conn->CreateCommand(FdoCommandType_Update);
-	update->SetFeatureClassName(className.c_str());
-	
-	if (!filter.empty())
-		update->SetFilter(filter.c_str());
-
-    if (NULL != fdoTrans.p)
-        update->SetTransaction(fdoTrans);
-
-	FdoPtr<FdoPropertyValueCollection> propVals = update->GetPropertyValues();
-	for (INT32 i = 0; i < propertyValues->GetCount(); i++)
-	{
-		Ptr<MgProperty> mgp = propertyValues->GetItem(i);
-		FdoPtr<FdoPropertyValue> pv = MgFeatureUtil::MgPropertyToFdoProperty(mgp);
-
-		propVals->Add(pv);
-	}
-
-	updated = update->Execute();
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -4657,7 +1218,7 @@
 
 int MgdFeatureService::DeleteFeatures(MgResourceIdentifier* resource, CREFSTRING className, CREFSTRING filter)
 {
-    int ret = 0;
+    int deleted = 0;
     MG_LOG_OPERATION_MESSAGE(L"DeleteFeatures");
 
     MG_FEATURE_SERVICE_TRY()
@@ -4673,7 +1234,8 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::DeleteFeatures()");
 
-	ret = DeleteFeatures(resource, className, filter, NULL);
+	MgUpdateFeaturesCommand cmd;
+    deleted = cmd.ExecuteDelete(resource, className, filter, NULL);
     
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -4691,7 +1253,7 @@
     MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
 
     MG_FEATURE_SERVICE_THROW()
-    return ret;
+    return deleted;
 }
 
 int MgdFeatureService::DeleteFeatures(MgResourceIdentifier* resource, CREFSTRING className, CREFSTRING filter, MgTransaction* trans)
@@ -4714,42 +1276,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::DeleteFeatures()");
 
-    CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::DeleteFeatures");
-	if (className.empty())
-		throw new MgNullArgumentException(L"MgdFeatureService::DeleteFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgUpdateFeaturesCommand cmd;
+    deleted = cmd.ExecuteDelete(resource, className, filter, trans);
 
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    FdoPtr<FdoITransaction> fdoTrans;
-
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::DeleteFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
-
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-        fdoTrans = mgTrans->GetFdoTransaction();
-    }
-    else
-    {
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-	FdoPtr<FdoIDelete> fdoDelete = (FdoIDelete*)conn->CreateCommand(FdoCommandType_Delete);
-	fdoDelete->SetFeatureClassName(className.c_str());
-    if (!filter.empty())
-	    fdoDelete->SetFilter(filter.c_str());
-    
-    if (NULL != fdoTrans.p)
-        fdoDelete->SetTransaction(fdoTrans);
-
-	deleted = fdoDelete->Execute();
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -4825,7 +1354,9 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::GetLockedFeatures()");
 
-	ret = SelectFeaturesInternal(resource, className, options, L"", true, false);
+	MgSelectFeatures select;
+    ret = dynamic_cast<MgFeatureReader*>(select.SelectFeatures(resource, className, options, false, false, true));
+    CHECKNULL(ret.p, L"MgdFeatureService::GetLockedFeatures");
 
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -4958,7 +1489,8 @@
 
     MG_LOG_TRACE_ENTRY(L"MgdFeatureService::ExecuteSqlQuery()");
 
-    ret = ExecuteSqlQuery(resource, sqlStatement, params, trans, m_nDataCacheSize);
+    MgSqlCommand cmd;
+    ret = cmd.ExecuteQuery(resource, sqlStatement, params, trans);
 
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
@@ -4995,56 +1527,9 @@
     CHECKARGUMENTNULL(params, L"MgdFeatureService::ExecuteSqlQuery");
     CHECKARGUMENTNULL(trans, L"MgdFeatureService::ExecuteSqlQuery");
 
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    FdoPtr<FdoITransaction> fdoTrans;
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::InsertFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgSqlCommand cmd;
+    reader = cmd.ExecuteQuery(resource, sqlStatement, params, trans, fetchSize);
 
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-        fdoTrans = mgTrans->GetFdoTransaction();
-    }
-    else
-    {    
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-
-    // Create the SQL command
-    FdoPtr<FdoISQLCommand> fdoCommand = (FdoISQLCommand*)conn->CreateCommand(FdoCommandType_SQLCommand);
-    CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgdFeatureService::ExecuteSqlQuery");
-
-    // Set SQL statement
-    fdoCommand->SetSQLStatement((FdoString*)sqlStatement.c_str());
-
-    // Set fetch size
-    fdoCommand->SetFetchSize(fetchSize);
-
-    // Set parameters
-    FdoPtr<FdoParameterValueCollection> fdoParams = NULL;
-    if (NULL != params && params->GetCount() > 0)
-    {
-        fdoParams = fdoCommand->GetParameterValues();
-        MgFeatureUtil::FillFdoParameterCollection(params, fdoParams);
-    }
-
-    // Execute the command
-    FdoPtr<FdoISQLDataReader> sqlReader = fdoCommand->ExecuteReader();
-    CHECKNULL((FdoISQLDataReader*)sqlReader, L"MgdFeatureService::ExecuteSqlQuery");
-
-    // Update parameter whose direction is InputOutput, Output, or Return.
-    if (NULL != params && params->GetCount() > 0)
-        MgFeatureUtil::UpdateParameterCollection(fdoParams, params);
-
-    reader = new MgdSqlDataReader(connWrap, sqlReader);
-
     MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdFeatureService::ExecuteSqlQuery")
     return reader.Detach();
 }
@@ -5079,50 +1564,9 @@
     CHECKARGUMENTNULL(params, L"MgdFeatureService::ExecuteSqlQuery");
     CHECKARGUMENTNULL(trans, L"MgdFeatureService::ExecuteSqlQuery");
 
-    Ptr<MgFeatureConnection> connWrap;
-	FdoPtr<FdoIConnection> conn;
-    FdoPtr<FdoITransaction> fdoTrans;
-    Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans);
-    if (NULL != mgTrans)
-    {
-        SAFE_ADDREF(mgTrans.p);
-        Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource();
-        //Check that the transaction originates from the same feature source
-        if (origFeatureSource->ToString() != resource->ToString())
-            throw new MgInvalidArgumentException(L"MgdFeatureService::ExecuteSqlNonQuery", __LINE__, __WFILE__, NULL, L"", NULL);
+    MgSqlCommand cmd;
+    ret = cmd.ExecuteNonQuery(resource, sqlNonSelectStatement, params, trans);
 
-        connWrap = mgTrans->GetConnection(); //Connection is already open
-        fdoTrans = mgTrans->GetFdoTransaction();
-    }
-    else
-    {    
-        connWrap = new MgFeatureConnection(resource);
-    }
-
-    conn = connWrap->GetConnection();
-
-    // Create the SQL command
-    FdoPtr<FdoISQLCommand> fdoCommand = (FdoISQLCommand*)conn->CreateCommand(FdoCommandType_SQLCommand);
-    CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgdFeatureService::ExecuteSqlNonQuery");
-
-    // Set SQL statement
-    fdoCommand->SetSQLStatement((FdoString*)sqlNonSelectStatement.c_str());
-
-    // Set parameters
-    FdoPtr<FdoParameterValueCollection> fdoParams = NULL;
-    if (NULL != params && params->GetCount() > 0)
-    {
-        fdoParams = fdoCommand->GetParameterValues();
-        MgFeatureUtil::FillFdoParameterCollection(params, fdoParams);
-    }
-
-    // Execute the command
-    ret = fdoCommand->ExecuteNonQuery();
-
-    // Update parameter whose direction is InputOutput, Output, or Return.
-    if (NULL != params && params->GetCount() > 0)
-        MgFeatureUtil::UpdateParameterCollection(fdoParams, params);
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -5163,14 +1607,9 @@
     if (sqlNonSelectStatement.empty())
         throw new MgInvalidArgumentException(L"MgdFeatureService::ExecuteSqlNonQuery", __LINE__, __WFILE__, NULL, L"", NULL);
 
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-	FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
+    MgSqlCommand cmd;
+    ret = cmd.ExecuteNonQuery(resource, sqlNonSelectStatement, NULL, NULL);
 
-	FdoPtr<FdoISQLCommand> sql = (FdoISQLCommand*)conn->CreateCommand(FdoCommandType_SQLCommand);
-	sql->SetSQLStatement(sqlNonSelectStatement.c_str());
-
-    ret = sql->ExecuteNonQuery();
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -5205,69 +1644,16 @@
     MG_LOG_OPERATION_MESSAGE_ADD_BOOL(bActiveOnly);
     MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
-    MG_LOG_TRACE_ENTRY(L"MgdFeatureService::GetSpatialContexts()");
+    MgLogDetail logDetail(MgServiceType::FeatureService, MgLogDetail::Trace, L"MgdFeatureService::GetSpatialContexts", mgStackParams);
+    logDetail.AddResourceIdentifier(L"Id", resId);
+    logDetail.AddBool(L"ActiveOnly", bActiveOnly);
+    logDetail.Create();
 
 	CHECK_FEATURE_SOURCE_ARGUMENT(resId, L"MgdFeatureService::GetSpatialContexts");
 	
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    mgSpatialContextReader = cache->GetSpatialContextReader(resId);
+    MgGetSpatialContexts cmd;
+    mgSpatialContextReader = cmd.GetSpatialContexts(resId);
 
-    if (NULL == mgSpatialContextReader.p)
-    {
-        // Connect to provider
-        Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(resId);
-
-        // Connection must be open to retrieve a list of available contexts.
-        if ((NULL != msfc.p) && ( msfc->IsConnectionOpen() ))
-        {
-            // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
-            // otherwise it leaves the FDO connection marked as still in use.
-            FdoPtr<FdoIConnection> fdoConn = msfc->GetConnection();
-            STRING providerName = msfc->GetProviderName();
-
-            Ptr<MgSpatialContextCacheItem> cacheItem = cache->GetSpatialContextInfo(resId);
-            MgSpatialContextInfo* spatialContextInfo = cacheItem->Get();
-
-            // Check whether command is supported by provider
-            if (!msfc->SupportsCommand((INT32)FdoCommandType_GetSpatialContexts))
-            {
-                // TODO: specify which argument and message, once we have the mechanism
-                STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
-                throw new MgInvalidOperationException(L"MgdFeatureService::GetSpatialContexts", __LINE__, __WFILE__, NULL, L"", NULL);
-            }
-
-            FdoPtr<FdoIGetSpatialContexts> fdoCommand = (FdoIGetSpatialContexts*)fdoConn->CreateCommand(FdoCommandType_GetSpatialContexts);
-            CHECKNULL((FdoIGetSpatialContexts*)fdoCommand, L"MgdFeatureService::GetSpatialContexts");
-
-            // Execute the command
-            FdoPtr<FdoISpatialContextReader> spatialReader = fdoCommand->Execute();
-            CHECKNULL((FdoISpatialContextReader*)spatialReader, L"MgdFeatureService::GetSpatialContexts");
-
-            mgSpatialContextReader = new MgSpatialContextReader();
-            while (spatialReader->ReadNext())
-            {
-                // Set providername for which spatial reader is executed
-                mgSpatialContextReader->SetProviderName(providerName);
-
-                Ptr<MgSpatialContextData> spatialData = GetSpatialContextData(spatialReader, spatialContextInfo);
-                CHECKNULL((MgSpatialContextData*)spatialData, L"MgdFeatureService::GetSpatialContexts");
-
-                // Add spatial data to the spatialcontext reader
-                mgSpatialContextReader->AddSpatialData(spatialData);
-            }
-
-            cache->SetSpatialContextReader(resId, mgSpatialContextReader.p);
-        }
-        else
-        {
-            throw new MgConnectionFailedException(L"MgdFeatureService::GetSpatialContexts()", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-    }
-    else
-    {
-        //cache->CheckPermission(resId, MgResourcePermission::ReadOnly);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -5288,200 +1674,6 @@
     return mgSpatialContextReader.Detach();
 }
 
-MgSpatialContextData* MgdFeatureService::GetSpatialContextData(FdoISpatialContextReader* spatialReader, MgSpatialContextInfo* spatialContextInfo)
-{
-    Ptr<MgSpatialContextData> spatialData;
-    MG_FEATURE_SERVICE_TRY()
-
-    spatialData = new MgSpatialContextData();
-
-    // Name must exist
-    FdoString* name = spatialReader->GetName();
-    CHECKNULL((FdoString*)name, L"MgdFeatureService::GetSpatialContexts");
-    spatialData->SetName(STRING(name));
-
-    STRING coordSysName = L"";
-    FdoString* csName = spatialReader->GetCoordinateSystem();
-
-    Ptr<MgCoordinateSystemFactory> csFactory;
-    // WKT for co-ordinate system
-    FdoString* csWkt = NULL;
-    STRING srsWkt = L"";
-
-    bool haveValidCoordSys = false;
-    if(NULL != csName && *csName != '\0')
-    {
-        coordSysName = STRING(csName);
-    }
-    else
-    {
-        csWkt = spatialReader->GetCoordinateSystemWkt();
-        if (csWkt != NULL && *csWkt != '\0')
-        {
-            srsWkt = csWkt;
-            try
-            {
-                csFactory = new MgCoordinateSystemFactory();
-                coordSysName = csFactory->ConvertWktToCoordinateSystemCode(srsWkt);
-                haveValidCoordSys = (coordSysName.size() != 0);
-            }
-            catch (MgException* e)
-            {
-                SAFE_RELEASE(e);
-            }
-            catch(...)
-            {
-            }
-        }
-    }
-
-    bool spatialContextDefined = !coordSysName.empty();
-    bool coordSysOverridden = false;
-
-    // look for coordinate system override
-    if (NULL != spatialContextInfo)
-    {
-        // Perform substitution of missing coordinate system with
-        // the spatial context mapping defined in feature source document
-        MgSpatialContextInfo::const_iterator iter = spatialContextInfo->find(name);
-
-        if (spatialContextInfo->end() != iter)
-        {
-            csName = (iter->second).c_str();
-            coordSysOverridden = true;
-        }
-    }
-
-    if (csName != NULL && *csName != '\0')
-    {
-        spatialData->SetCoordinateSystem(STRING(csName));
-    }
-
-    // Desc for spatial context
-    STRING desc = L"";
-
-    // This flag is obsolete and will be deprecated.
-    bool isActive = spatialReader->IsActive();
-
-    if (coordSysOverridden)
-    {
-        srsWkt = csName;
-        desc = MgFeatureUtil::GetMessage(L"MgCoordinateSystemOverridden");
-    }
-    else if (spatialContextDefined && !coordSysOverridden)
-    {
-        // avoid looking one more time after CS in case we have a valid one...
-        if (!haveValidCoordSys)
-        {
-            csWkt = spatialReader->GetCoordinateSystemWkt();
-            if(NULL != csWkt && *csWkt != '\0')
-                srsWkt = csWkt;
-
-            if (srsWkt.empty())
-            {
-                try
-                {
-                    if (csFactory == NULL)
-                        csFactory = new MgCoordinateSystemFactory();
-
-                    // Check if the spatial context coordinate system data represents an EPSG
-                    // code. If this is the case the WKT data for the EPSG code has to be
-                    // retrieved.
-                    if (IsEpsgCodeRepresentation(csName))
-                    {
-                        // This is an EPSG code
-                        FdoString* p = NULL;
-                        if ((csName[0] == L'E') || (csName[0] == L'e'))
-                            p = csName+5;
-                        else
-                            p = csName;
-
-                        INT32 epsgCode = (INT32)wcstol(p, NULL, 10);
-
-                        // Convert the EPSG numerical code to WKT
-                        srsWkt = csFactory->ConvertEpsgCodeToWkt(epsgCode);
-                    }
-                    else
-                    {
-                        srsWkt = csFactory->ConvertCoordinateSystemCodeToWkt(STRING(csName));
-                    }
-                }
-                catch (MgException* e)
-                {
-                    SAFE_RELEASE(e);
-                }
-                catch(...)
-                {
-                    // Just use the empty WKT.
-                }
-            }
-        }
-        FdoString* fdoDesc = spatialReader->GetDescription();
-        if(NULL != fdoDesc)
-            desc = STRING(fdoDesc);
-    }
-
-    // retrieve other values from spatialReader
-    FdoSpatialContextExtentType extentType = spatialReader->GetExtentType();
-    FdoPtr<FdoByteArray> byteArray = spatialReader->GetExtent();
-    double xyTol = spatialReader->GetXYTolerance();
-    double zTol = spatialReader->GetZTolerance();
-
-    spatialData->SetCoordinateSystemWkt(srsWkt);
-    spatialData->SetDescription(desc);
-    spatialData->SetExtentType((INT32)extentType);
-
-    if (byteArray.p != NULL)
-    {
-        INT32 size = (INT32)byteArray->GetCount();
-        BYTE_ARRAY_IN bytes = (BYTE_ARRAY_IN)byteArray->GetData();
-        Ptr<MgByte> extent = new MgByte(bytes, size);
-        spatialData->SetExtent(extent);
-    }
-
-    // XY Tolerance
-    spatialData->SetXYTolerance(xyTol);
-
-    // Z Tolerance
-    spatialData->SetZTolerance(zTol);
-
-    // This flag is obsolete and will be deprecated.
-    spatialData->SetActiveStatus(isActive);
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::GetSpatialContextData")
-    return spatialData.Detach();
-}
-
-bool MgdFeatureService::IsEpsgCodeRepresentation (FdoString *coordSysName)
-{
-    // If the given coordinate system name is NULL or not NULL but empty
-    // return false as those cases do not represent an EPSG code.
-    if ((coordSysName == NULL) || (coordSysName[0] == L'\0'))
-        return false;
-
-    // Check if the string contains a coded EPSG number ("EPSG:<num>"). If this
-    // is the case return true;
-    size_t coordSysNameLength  = wcslen(coordSysName);
-    if (coordSysNameLength  > 5)
-        if (((coordSysName[0] == L'E') || (coordSysName[0] == L'e')) &&
-            ((coordSysName[1] == L'P') || (coordSysName[1] == L'p')) &&
-            ((coordSysName[2] == L'S') || (coordSysName[2] == L's')) &&
-            ((coordSysName[3] == L'G') || (coordSysName[3] == L'g')) &&
-            (coordSysName[4] == L':')                                   )
-            return true;
-
-    // The string does not contain a coded EPSG number. Next, check if the
-    // string represents a numeric value. If this is the case then the value
-    // represents an EPSG code and the routine has to return true.
-    for (size_t i = 0; i < coordSysNameLength; i++)
-        if (!iswdigit(coordSysName[i]))
-            return false;
-
-    // This is an EPSG code. Indicate so.
-    return true;
-}
-
-
 MgLongTransactionReader* MgdFeatureService::GetLongTransactions(MgResourceIdentifier* resource,
                                                                 bool bActiveOnly) 
 { 
@@ -5499,29 +1691,9 @@
 
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::GetLongTransactions");
 	
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-	FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
+    MgGetLongTransactions getTrans;
+    reader = getTrans.GetLongTransactions(resource, bActiveOnly);
 
-	FdoPtr<FdoIGetLongTransactions> list = (FdoIGetLongTransactions*)conn->CreateCommand(FdoCommandType_GetLongTransactions);
-	FdoPtr<FdoILongTransactionReader> ltReader = list->Execute();
-
-	reader = new MgLongTransactionReader();
-
-	while (ltReader->ReadNext())
-	{
-		Ptr<MgLongTransactionData> data = new MgLongTransactionData();
-		data->SetActiveStatus(ltReader->IsActive());
-		FdoDateTime fdt = ltReader->GetCreationDate();
-		data->SetCreationDate(new MgDateTime(fdt.year, fdt.month, fdt.day, fdt.hour, fdt.minute, fdt.seconds, 0));
-		data->SetDescription(ltReader->GetDescription());
-		data->SetFrozenStatus(ltReader->IsFrozen());
-		data->SetName(ltReader->GetName());
-		data->SetOwner(ltReader->GetOwner());
-	
-		reader->AddLongTransactionData(data);
-	}
-	ltReader->Close();
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -5587,30 +1759,6 @@
 	return ok;
 }
 
-bool MgdFeatureService::SupportsPartialSchemaDiscovery(FdoIConnection* conn)
-{
-	CHECKARGUMENTNULL(conn, L"MgdFeatureService::SupportsPartialSchemaDiscovery");
-
-    bool getClassNames = false;
-	bool getSchemaNames = false;
-
-    MG_FEATURE_SERVICE_TRY()
-	FdoPtr<FdoICommandCapabilities> caps = conn->GetCommandCapabilities();
-
-	FdoInt32 cmdCount;
-	FdoInt32* cmds = caps->GetCommands(cmdCount);
-	for (FdoInt32 i = 0; i < cmdCount; i++)
-	{
-		if (cmds[i] == FdoCommandType_GetClassNames)
-			getClassNames = true;
-		else if (cmds[i] == FdoCommandType_GetSchemaNames)
-			getSchemaNames = true;
-	}
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::SupportsPartialSchemaDiscovery")
-
-	return getClassNames && getSchemaNames;
-}
-
 MgStringCollection* MgdFeatureService::GetSchemas(MgResourceIdentifier* resource) 
 {
     Ptr<MgStringCollection> schemaNames;
@@ -5625,32 +1773,9 @@
 
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::GetSchemas");
 
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-	FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
+    MgDescribeSchema describe;
+    schemaNames = describe.GetSchemas(resource);
 
-	if (SupportsPartialSchemaDiscovery(conn))
-	{
-		FdoPtr<FdoIGetSchemaNames> fetch = (FdoIGetSchemaNames*)conn->CreateCommand(FdoCommandType_GetSchemaNames);
-		FdoPtr<FdoStringCollection> names = fetch->Execute();
-
-		schemaNames = MgFeatureUtil::FdoToMgStringCollection(names, false);
-	}
-	else
-	{
-		Ptr<MgStringCollection> names = new MgStringCollection();
-		FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)conn->CreateCommand(FdoCommandType_DescribeSchema);
-		FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute();
-
-		for (INT32 i = 0; i < schemas->GetCount(); i++)
-		{
-			FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(i);
-			STRING name = schema->GetName();
-			names->Add(name);
-		}
-
-		schemaNames = names;
-	}
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -5686,92 +1811,10 @@
     MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
 	CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::GetClasses");
-	//if (schemaName.empty())
-	//	throw new MgInvalidArgumentException(L"MgdFeatureService::GetClasses", __LINE__, __WFILE__, NULL, L"", NULL);
+	
+    MgDescribeSchema describe;
+    classNames = describe.GetClasses(resource, schemaName);
 
-    Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
-	FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
-
-    STRING theSchemaName = schemaName;
-
-	if (SupportsPartialSchemaDiscovery(conn))
-	{
-		FdoPtr<FdoIGetClassNames> fetch = (FdoIGetClassNames*)conn->CreateCommand(FdoCommandType_GetClassNames);
-        if (!schemaName.empty())
-		    fetch->SetSchemaName(schemaName.c_str());
-		FdoPtr<FdoStringCollection> names = fetch->Execute();
-
-		classNames = MgFeatureUtil::FdoToMgStringCollection(names, false);
-	}
-	else
-	{
-		Ptr<MgStringCollection> names = new MgStringCollection();
-		FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)conn->CreateCommand(FdoCommandType_DescribeSchema);
-		FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute();
-
-		for (INT32 i = 0; i < schemas->GetCount(); i++)
-		{
-			FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(i);
-			STRING name = schema->GetName();
-			if (!schemaName.empty() && name != schemaName)
-				continue;
-
-			FdoPtr<FdoClassCollection> classes = schema->GetClasses();
-
-			for (INT32 j = 0; j < classes->GetCount(); j++)
-			{
-				FdoPtr<FdoClassDefinition> cls = classes->GetItem(j);
-				STRING clsName = cls->GetName();
-				names->Add(clsName);
-			}
-		}
-
-		classNames = names;
-	}
-
-    //In case an empty schema name was specified, get the schema name
-    //from the first result.
-    if (theSchemaName.empty())
-    {
-        INT32 clsCount = classNames->GetCount();
-        if (clsCount > 0)
-        {
-            for (INT32 i = 0; i < clsCount; i++)
-            {
-                STRING qn = classNames->GetItem(i);
-                STRING sn;
-                STRING cn;
-                MgUtil::ParseQualifiedClassName(qn, sn, cn);
-                
-                theSchemaName = sn;
-                break;
-            }
-        }
-    }
-
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    // Add extended feature class names
-    Ptr<MgFeatureSourceCacheItem> fsCache = cache->GetFeatureSource(resource);
-    MdfModel::FeatureSource* featureSource = fsCache->Get();
-    CHECKNULL(featureSource, L"MgdFeatureService::GetClasses");
-    MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgdFeatureService::GetClasses");
-    int extensionCount = extensions->GetCount();
-    for (int i = 0; i < extensionCount; i++)
-    {
-        MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgdFeatureService::GetClasses");
-
-        // Get the extension name
-        STRING extensionName = (STRING)extension->GetName();
-
-        STRING extendedClassName = theSchemaName;
-        extendedClassName += L":";
-        extendedClassName += extensionName;
-
-        classNames->Add(extendedClassName);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -5845,50 +1888,12 @@
 
     MG_FEATURE_SERVICE_TRY()
 
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    if (className.empty())
-    {
-        throw new MgClassNotFoundException(
-            L"MgdFeatureService::GetClassDefinition",
-            __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    MgDescribeSchema describe;
+    classDefinition = describe.GetClassDefinition(resource, schemaName, className, serialize);
 
-    classDefinition = cache->GetClassDefinition(resource, schemaName, className);
-
-    if (NULL == classDefinition.p)
-    {
-        Ptr<MgStringCollection> classNames;
-
-        // Since the FDO provider does not know about the join information,
-        // use the full schema to retrieve the class definition if the feature source has joins.
-        if (!CheckExtendedFeatureClass(resource, className))
-        {
-            classNames = new MgStringCollection();
-            classNames->Add(className);
-        }
-
-        Ptr<MgFeatureSchemaCollection> schemas = DescribeSchema(
-            resource, schemaName, classNames, serialize);
-
-        // Get the class definition.
-        classDefinition = GetClassDefinition(schemas.p, schemaName, className);
-
-        if (NULL == classDefinition.p)
-        {
-            throw new MgClassNotFoundException(
-                L"MgdFeatureService::GetClassDefinition",
-                __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        else
-        {
-            cache->SetClassDefinition(resource, schemaName, className, classDefinition.p);
-        }
-    }
-    else
-    {
-        //m_cacheManager->CheckPermission(resource, MgResourcePermission::ReadOnly);
-    }
-
+    //In MapGuide Server returning this potentially cached copy is okay as a new instance is created
+    //travelling the server/webtier boundary. This is not the case in mg-desktop so we have to clone
+    //this result and return the clone instead.
     clone = MgFeatureUtil::CloneMgClassDefinition(classDefinition);
 
     MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgdFeatureService::GetClassDefinition", resource)
@@ -5896,63 +1901,6 @@
     return clone.Detach();
 }
 
-MgClassDefinition* MgdFeatureService::GetClassDefinition(MgFeatureSchemaCollection* schemas, 
-                                                         CREFSTRING schemaName, 
-                                                         CREFSTRING className)
-{
-    CHECKNULL(schemas, L"MgdFeatureService::GetClassDefinition");
-
-    Ptr<MgClassDefinition> classDef;
-
-    MG_FEATURE_SERVICE_TRY()
-    INT32 schemaCount = schemas->GetCount();
-
-    for (INT32 i = 0; i < schemaCount; ++i)
-    {
-        Ptr<MgFeatureSchema> currSchema = schemas->GetItem(i);
-        STRING currSchemaName = currSchema->GetName();
-        bool schemaNameFound = false;
-
-        if (schemaName.empty() || (schemaNameFound = (schemaName == currSchemaName)))
-        {
-            Ptr<MgClassDefinitionCollection> currClasses = currSchema->GetClasses();
-            INT32 classCount = currClasses->GetCount();
-
-            for (INT32 j = 0; j < classCount; ++j)
-            {
-                Ptr<MgClassDefinition> currClass = currClasses->GetItem(j);
-                STRING currClassName = currClass->GetName();
-
-                if (className == currClassName)
-                {
-                    classDef = currClass;
-                    break;
-                }
-                else
-                {
-                    STRING parsedSchemaName, parsedClassName;
-                    MgUtil::ParseQualifiedClassName(className, parsedSchemaName, parsedClassName);
-
-                    if (parsedClassName == currClassName)
-                    {
-                        classDef = MgFeatureUtil::CloneMgClassDefinition(currClass);
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (schemaNameFound || NULL != classDef.p)
-        {
-            break;
-        }
-    }
-
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureService::GetClassDefinition")
-
-    return classDef.Detach();
-}
-
 void MgdFeatureService::CreateFeatureSource(MgResourceIdentifier* resource, MgFeatureSourceParams* sourceParams) 
 { 
     MG_LOG_OPERATION_MESSAGE(L"CreateFeatureSource");
@@ -6115,80 +2063,9 @@
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(partialConnString.c_str());
     MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
-    Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(providerName, partialConnString);
-    
-    if ((NULL != msfc.p) && (( msfc->IsConnectionOpen() ) || ( msfc->IsConnectionPending() )))
-    {
-        // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
-        // otherwise it leaves the FDO connection marked as still in use.
-        FdoPtr<FdoIConnection> fdoConnection;
-        fdoConnection = msfc->GetConnection();
+    MgGetSchemaMapping descMapping;
+    byteReader = descMapping.GetSchemaMapping(providerName, partialConnString);
 
-        // Create the memory stream
-        FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
-        CHECKNULL((FdoIoMemoryStream*)fmis, L"MgdFeatureService::GetSchemaMapping");
-
-        FdoXmlWriterP writer = FdoXmlWriter::Create(fmis);
-
-        FdoPtr<FdoXmlSpatialContextFlags> flags = FdoXmlSpatialContextFlags::Create();
-        flags->SetIncludeDefault(true);
-
-        // Serialize the spatial contexts
-        FdoXmlSpatialContextSerializer::XmlSerialize(
-            fdoConnection,
-            FdoXmlSpatialContextWriterP(
-                FdoXmlSpatialContextWriter::Create(writer)
-            ),
-            flags
-        );
-
-        // Get the schema
-        FdoPtr<FdoIDescribeSchema> fdoDescribeSchemaCommand = (FdoIDescribeSchema*)fdoConnection->CreateCommand(FdoCommandType_DescribeSchema);
-        CHECKNULL((FdoIDescribeSchema*)fdoDescribeSchemaCommand, L"MgdFeatureService::GetSchemaMapping");
-
-        // Execute the command
-        FdoPtr<FdoFeatureSchemaCollection> fdoFeatureSchemaCollection;
-        fdoFeatureSchemaCollection = fdoDescribeSchemaCommand->Execute();
-        CHECKNULL((FdoFeatureSchemaCollection*)fdoFeatureSchemaCollection, L"MgdFeatureService::GetSchemaMapping");
-
-        // Write to memory stream
-        fdoFeatureSchemaCollection->WriteXml(writer);
-
-        // Get the schema mapping
-        FdoPtr<FdoIDescribeSchemaMapping> fdoDescribeSchemaMappingCommand = (FdoIDescribeSchemaMapping*)fdoConnection->CreateCommand(FdoCommandType_DescribeSchemaMapping);
-        CHECKNULL((FdoIDescribeSchemaMapping*)fdoDescribeSchemaMappingCommand, L"MgdFeatureService::GetSchemaMapping");
-
-        fdoDescribeSchemaMappingCommand->SetIncludeDefaults(true);
-
-        // Execute the command
-        FdoPtr<FdoPhysicalSchemaMappingCollection> fdoPhysicalSchemaMappingCollection;
-        fdoPhysicalSchemaMappingCollection = fdoDescribeSchemaMappingCommand->Execute();
-        CHECKNULL((FdoPhysicalSchemaMappingCollection*)fdoPhysicalSchemaMappingCollection, L"MgdFeatureService::GetSchemaMapping");
-
-        // Write to memory stream
-        fdoPhysicalSchemaMappingCollection->WriteXml(writer);
-
-        // Close the XML writer
-        writer->Close();
-
-        fmis->Reset(); // TODO: We should not be calling reset here. A defect in FDO should be fixed.
-
-        FdoInt64 len = fmis->GetLength();
-        FdoPtr<FdoByteArray> bytes = FdoByteArray::Create((FdoInt32)len);
-        //FdoByte* bytes = new FdoByte[(size_t)len];
-        FdoByte* data = bytes->GetData();
-        CHECKNULL(data, L"MgdFeatureService::GetSchemaMapping");
-        fmis->Read(data, (FdoSize)len);
-
-        Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)data, (INT32)len);
-        byteSource->SetMimeType(MgMimeType::Xml);
-        byteReader = byteSource->GetReader();
-    }
-    else
-    {
-        throw new MgConnectionFailedException(L"MgdFeatureService::GetSchemaMapping()", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -6311,31 +2188,17 @@
 
     CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::GetIdentityProperties");
     
-    if (className.empty())
+    MgDescribeSchema describe;
+    Ptr<MgStringCollection> classNames = new MgStringCollection();
+    classNames->Add(className);
+    Ptr<MgClassDefinitionCollection> classDefs = describe.GetIdentityProperties(resource, schemaName, classNames);
+    if (classDefs->GetCount() != 1)
     {
-        throw new MgClassNotFoundException(
-            L"MgdFeatureService::GetIdentityProperties",
-            __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgClassNotFoundException(L"MgdFeatureService::GetIdentityProperties", __LINE__, __WFILE__, NULL, L"", NULL);
     }
+    Ptr<MgClassDefinition> classDef = classDefs->GetItem(0);
+    propDefs = classDef->GetIdentityProperties();
 
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    propDefs = cache->GetClassIdentityProperties(resource, schemaName, className);
-    if (NULL == propDefs)
-    {
-        Ptr<MgClassDefinition> clsDef = cache->GetClassDefinition(resource, schemaName, className);
-        if (NULL == clsDef)
-        {
-            clsDef = GetClassDefinition(resource, schemaName, className);
-
-            //Cache for future calls
-            cache->SetClassDefinition(resource, schemaName, className, clsDef);
-        }
-
-        propDefs = clsDef->GetIdentityProperties();
-        //Cache for future calls
-        cache->SetClassIdentityProperties(resource, schemaName, className, propDefs);
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 
@@ -6351,6 +2214,7 @@
     // Add access log entry for operation
     MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
 
+    MG_FEATURE_SERVICE_THROW()
 
     return propDefs.Detach();
 }
@@ -6377,73 +2241,9 @@
 
     CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::GetIdentityProperties");
     
-    classDefs = new MgClassDefinitionCollection();
-    if (NULL == classNames || classNames->GetCount() == 0)
-    {
-        throw new MgClassNotFoundException(
-            L"MgdFeatureService::GetIdentityProperties",
-            __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    MgDescribeSchema describe;
+    classDefs = describe.GetIdentityProperties(resource, schemaName, classNames);
 
-    MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
-    Ptr<MgStringCollection> uncachedClasses = new MgStringCollection();
-
-    for (INT32 i = 0; i < classNames->GetCount(); i++)
-    {
-        STRING clsName = classNames->GetItem(i);
-        Ptr<MgPropertyDefinitionCollection> propDefs = cache->GetClassIdentityProperties(resource, schemaName, clsName);
-        if (NULL == propDefs)
-        {
-            uncachedClasses->Add(clsName);
-        }
-        else
-        {
-            Ptr<MgClassDefinition> clsCopy = new MgClassDefinition();
-            clsCopy->SetName(clsName);
-            Ptr<MgPropertyDefinitionCollection> idProps = clsCopy->GetIdentityProperties();
-            for (INT32 k = 0; k < propDefs->GetCount(); k++)
-            {
-                Ptr<MgPropertyDefinition> idProp = propDefs->GetItem(k);
-                idProps->Add(idProp);
-            }
-            classDefs->Add(clsCopy);
-        }
-    }
-
-    if (uncachedClasses->GetCount() > 0)
-    {
-        Ptr<MgFeatureSchemaCollection> schemas = DescribeSchema(resource, schemaName, uncachedClasses);
-        for (INT32 i = 0; i < schemas->GetCount(); i++)
-        {
-            Ptr<MgFeatureSchema> schema = schemas->GetItem(i);
-            Ptr<MgClassDefinitionCollection> classes = schema->GetClasses();
-
-            for (INT32 j = 0; j < classes->GetCount(); j++)
-            {
-                Ptr<MgClassDefinition> cls = classes->GetItem(j);
-
-                //Cache it
-                cache->SetClassDefinition(resource, schema->GetName(), cls->GetName(), cls);
-
-                Ptr<MgClassDefinition> clsCopy = new MgClassDefinition();
-                clsCopy->SetName(cls->GetName());
-                Ptr<MgPropertyDefinitionCollection> idProps = clsCopy->GetIdentityProperties();
-                Ptr<MgPropertyDefinitionCollection> propDefs = cls->GetIdentityProperties();
-
-                //Cache it
-                cache->SetClassIdentityProperties(resource, schema->GetName(), cls->GetName(), propDefs);
-
-                for (INT32 k = 0; k < propDefs->GetCount(); k++)
-                {
-                    Ptr<MgPropertyDefinition> idProp = propDefs->GetItem(k);
-                    idProps->Add(idProp);
-                }
-
-                classDefs->Add(clsCopy);
-            }
-        }
-    }
-
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h	2012-07-15 21:07:04 UTC (rev 6904)
@@ -264,81 +264,6 @@
 
 protected:
     virtual INT32 GetClassId() { return m_cls_id; }
-
-private:
-	MgFeatureReader* SelectFeaturesInternal(MgResourceIdentifier* resource,
-                                            CREFSTRING className,
-                                            MgFeatureQueryOptions* options,
-											CREFSTRING coordinateSystem,
-											bool withLock,
-                                            bool asScrollable);
-
-    MgDataReader* SelectAggregateNormal(MgFeatureConnection* conn,
-                                        CREFSTRING className,
-                                        MgFeatureAggregateOptions* options);
-
-    MgDataReader* SelectAggregateJoined(MgFeatureConnection* conn,
-                                        CREFSTRING className,
-                                        MgFeatureAggregateOptions* options);
-
-	bool ContainsUdf(MgFeatureConnection* conn, FdoExpression* expression);
-	bool IsCustomFunction(FdoFunction* fdoFunc);
-	MgReader* GetCustomReader(MgReader* reader, FdoFunction* customFunc, CREFSTRING propertyName);
-
-    static MgSpatialContextData* GetSpatialContextData(FdoISpatialContextReader* spatialReader, MgSpatialContextInfo* spatialContextInfo);
-
-    // Methods for describe schema
-    static MgClassDefinition* GetClassDefinition(MgFeatureSchemaCollection* schemas, 
-                                                 CREFSTRING schemaName, 
-                                                 CREFSTRING className);
-
-    static FdoFeatureSchemaCollection* DescribeFdoSchema(MgResourceIdentifier* resource,
-                                                         CREFSTRING schemaName, 
-                                                         MgStringCollection* classNames, 
-                                                         bool& classNameHintUsed);
-    
-    static bool IsClassNameHintUsed(FdoIDescribeSchema* fdoCommand);
-
-    // Methods for Feature Join
-    static bool FindFeatureJoinProperties(MgResourceIdentifier* resourceId, CREFSTRING extensionName);
-    static bool FindFeatureCalculation(MgResourceIdentifier* resourceId, CREFSTRING extensionName);
-    static void UpdateCommandOnCalculation(FdoIBaseSelect* command, MgResourceIdentifier* featureSourceId, CREFSTRING extensionName);
-    static void UpdateCommandOnJoinCalculation(FdoIBaseSelect* command, MgResourceIdentifier* featureSourceId, CREFSTRING extensionName);
-    static void ParseQualifiedClassNameForCalculation(MdfModel::Extension* extension, CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className);
-    static MgResourceIdentifier* GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName);
-
-    MgFeatureReader* SelectFeaturesJoined(MgResourceIdentifier* featureSourceIdentifier, 
-                                              CREFSTRING extensionName, 
-                                              FdoFilter* filter);
-
-    // Methods for FDO join
-    bool SupportsFdoJoins(MgFeatureConnection* conn, MdfModel::Extension* extension);
-    MgFeatureReader* SelectFdoJoin(MgFeatureConnection* conn, MdfModel::Extension* extension, FdoFilter* filter);
-
-	static bool m_isInitialized;
-    static bool Initialize();
-
-    //Methods for capabilities
-    static void WriteCommandCapabilities(MgXmlUtil* caps, FdoICommandCapabilities* cmdCaps);
-    static void WriteConnectionCapabilities(MgXmlUtil* caps, FdoIConnectionCapabilities* connCaps);
-    static void WriteFilterCapabilities(MgXmlUtil* caps, FdoIFilterCapabilities* filterCaps);
-    static void WriteGeometryCapabilities(MgXmlUtil* caps, FdoIGeometryCapabilities* geomCaps);
-    static void WriteExpressionCapabilities(MgXmlUtil* caps, FdoIExpressionCapabilities* exprCaps);
-    static void WriteSchemaCapabilities(MgXmlUtil* caps, FdoISchemaCapabilities* schemaCaps);
-    static void WriteRasterCapabilities(MgXmlUtil* caps, FdoIRasterCapabilities* rasterCaps);
-    static void WriteTopologyCapabilities(MgXmlUtil* caps, FdoITopologyCapabilities* topoCaps);
-
-    //Methods for describe schema
-    static bool CheckExtendedFeatureClass(MgResourceIdentifier* resource, CREFSTRING className);
-    static bool CheckExtendedFeatureClasses(MgResourceIdentifier* resource, MgStringCollection* classNames);
-	static STRING FdoSchemaToXml(FdoFeatureSchemaCollection* schemas);
-	static MgFeatureSchemaCollection* FdoToMgSchemaCollection(FdoFeatureSchemaCollection* schemas);
-	static bool SupportsPartialSchemaDiscovery(FdoIConnection* conn);
-
-    static bool IsEpsgCodeRepresentation (FdoString *coordSysName);
-
-    INT32 m_nJoinQueryBatchSize;
-    INT32 m_nDataCacheSize;
 };
 
 #endif
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -2743,7 +2743,7 @@
 
         //Custom aggregates should also work
         Ptr<MgFeatureAggregateOptions> agg = new MgFeatureAggregateOptions();
-        agg->AddComputedProperty(L"EXTENT", L"EXTENTS(SHPGEOM)");
+        agg->AddComputedProperty(L"THE_EXTENT", L"EXTENT(SHPGEOM)");
         Ptr<MgDataReader> dr = pService->SelectAggregate(lFeatureSource, L"Ext1", agg);
         bool bRead = dr->ReadNext();
         dr->Close();

Modified: branches/2.4/MgDev/Desktop/UnitTest/main.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/main.cpp	2012-07-15 16:59:27 UTC (rev 6903)
+++ branches/2.4/MgDev/Desktop/UnitTest/main.cpp	2012-07-15 21:07:04 UTC (rev 6904)
@@ -25,13 +25,13 @@
 */
 
 #define TEST_COORDINATE_SYSTEM  0
-#define TEST_LOG_MANAGER        0
-#define TEST_RESOURCE_SERVICE   0
+#define TEST_LOG_MANAGER        1
+#define TEST_RESOURCE_SERVICE   1
 #define TEST_FEATURE_SERVICE    1
-#define TEST_MAPPING_SERVICE    0
-#define TEST_PROFILING_SERVICE  0
-#define TEST_RENDERING_SERVICE  0
-#define TEST_TILE_SERVICE       0
+#define TEST_MAPPING_SERVICE    1
+#define TEST_PROFILING_SERVICE  1
+#define TEST_RENDERING_SERVICE  1
+#define TEST_TILE_SERVICE       1
 
 int main(int argc, char** argv)
 {



More information about the mapguide-commits mailing list