[fdo-commits] r2550 - in trunk: Fdo/Unmanaged/Inc/Geometry/Fgf Fdo/Unmanaged/Src/Common Fdo/Unmanaged/Src/Fdo Fdo/Unmanaged/Src/Geometry/Fgf Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph Providers/GenericRdbms/Src/ODBCDriver Providers/GenericRdbms/Src/UnitTest Providers/GenericRdbms/Src/UnitTest/Common Providers/GenericRdbms/Src/UnitTest/Odbc

svn_fdo at osgeo.org svn_fdo at osgeo.org
Fri Feb 16 13:43:18 EST 2007


Author: gavincramer
Date: 2007-02-16 13:43:18 -0500 (Fri, 16 Feb 2007)
New Revision: 2550

Modified:
   trunk/Fdo/Unmanaged/Inc/Geometry/Fgf/Factory.h
   trunk/Fdo/Unmanaged/Src/Common/ArrayHelper.cpp
   trunk/Fdo/Unmanaged/Src/Fdo/Fdo.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory2.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryImpl.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryThreadData.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Pool.h
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.cpp
   trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.h
   trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.cpp
   trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.h
   trunk/Providers/GenericRdbms/Src/ODBCDriver/users_.c
   trunk/Providers/GenericRdbms/Src/UnitTest/Common/FdoSqlCmdTest.cpp
   trunk/Providers/GenericRdbms/Src/UnitTest/MSTest.mdb
   trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcBaseSetup.cpp
   trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.cpp
   trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.h
Log:
(Ports from 3.2.x branch to trunk)
FDO: Fix Geometry pool sharing objects between threads
ODBC: Connect to Access on Vista
ODBC: Primary keys in views


Modified: trunk/Fdo/Unmanaged/Inc/Geometry/Fgf/Factory.h
===================================================================
--- trunk/Fdo/Unmanaged/Inc/Geometry/Fgf/Factory.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Inc/Geometry/Fgf/Factory.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -49,6 +49,9 @@
     /// The object returned may maintain internal pools
     /// of other objects in this package, for performance.
     /// Pools will be small, tuned to transient object use.
+    /// Objects returned by this factory are safe to pass
+    /// to other threads (i.e. they won't try to interact
+    /// with the originating thread).
     /// 
     /// \return
     /// Returns a FdoFgfGeometryFactory object
@@ -61,7 +64,8 @@
     /// \remarks
     /// This class is its own factory. 
     /// This method will return a new, private instance, with any internal
-    /// object pools tuned to the input parameters.
+    /// object pools tuned to the input parameters.  NOTE:  objects created
+    /// by this factory should NOT be passed between threads.
     /// 
     /// \param numGeometries 
     /// Input Minimum number of geometries to pool.
@@ -544,6 +548,16 @@
     /// 
     FDO_GEOM_API ~FdoFgfGeometryFactory();
 
+/// \cond DOXYGEN-IGNORE
+    /// Constructor for a private instance.
+    FdoFgfGeometryFactory(
+        FdoInt32 numGeometries,
+        FdoInt32 numPositions,
+        FdoInt32 numEnvelopes,
+        FdoInt32 numCurveSegments,
+        FdoInt32 numRings);
+/// \endcond
+
 };
 #endif
 

Modified: trunk/Fdo/Unmanaged/Src/Common/ArrayHelper.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Common/ArrayHelper.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Common/ArrayHelper.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -21,6 +21,7 @@
 
 #define MIN_ALLOC 1
 #define GROWTH_FACTOR 1     /* Proportion of array size to grow when needed. */
+#define POOL_ENTRY_BYTESIZE_LIMIT   (8*1024)    // 8KB limit on pooled FdoByteArray values, to suppress retention of large values in memory.
 
 FdoArrayHelper::GenericArray* FdoArrayHelper::Append(GenericArray* array, FdoInt32 numElements, FdoByte* elements, FdoInt32 elementSize)
 {
@@ -92,6 +93,69 @@
 	return array;
 }
 
+
+////////////////////////////////////////////////////////////////////////////
+// Implement thread-local storage for pooled FdoByteArray instances.
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef _WIN32
+#include <windows.h>
+typedef int FdoCommonThreadDataKey;
+#else
+#include <pthread.h>
+typedef pthread_key_t FdoCommonThreadDataKey;
+#endif
+#include "../Geometry/Fgf/Pool.h"
+
+FDOPOOL_DEFINE(FdoPoolFgfByteArray, FdoByteArray)
+
+static FdoCommonThreadDataKey threadDataKey_S = 0;
+
+struct FdoCommonThreadData
+{
+    FdoPtr<FdoPoolFgfByteArray>         byteArrayPool;
+
+    static FdoCommonThreadData *        GetValue();
+    static void                         ReleaseValue();
+    static FdoCommonThreadDataKey       GetKey()                           { return threadDataKey_S; }
+    static void                         SetKey(FdoCommonThreadDataKey key) { threadDataKey_S = key; }
+};
+
+
+#ifdef _WIN32
+#define GET_VALUE(key)          ((FdoCommonThreadData *) TlsGetValue(key))
+#define SET_VALUE(key, value)   (TlsSetValue((key), (value)))
+#else
+#define GET_VALUE(key)          ((FdoCommonThreadData *) pthread_getspecific(key))
+#define SET_VALUE(key, value)   (pthread_setspecific((key), (value)))
+#endif
+
+FdoCommonThreadData *
+FdoCommonThreadData::GetValue()
+{
+    FdoCommonThreadData *data = GET_VALUE(threadDataKey_S);
+
+	if (NULL == data)
+	{
+        data = new FdoCommonThreadData;
+        if (NULL == data)
+            throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
+        SET_VALUE(threadDataKey_S, data);
+	}
+	return data;
+}
+
+void FdoCommonThreadData::ReleaseValue()
+{
+    FdoCommonThreadData *data = GET_VALUE(threadDataKey_S);
+
+    if (NULL != data)
+    {
+        SET_VALUE(threadDataKey_S, NULL);
+        delete data;
+    }
+}
+
 /*
  * Allocate some more memory for the array.
  * If the given array is NULL, a new array of zero size 
@@ -117,7 +181,7 @@
 			newAlloc *= 1 + GROWTH_FACTOR;
 	}
 
-    FdoInt32 newAllocBytes = (newAlloc*elementSize) + sizeof(Metadata);
+    FdoInt32 newAllocBytes = (newAlloc*elementSize) + sizeof(GenericArray);
 
 	/*
 	 * The main trick: GenericArray's only real "member" data is the metadata.
@@ -128,18 +192,57 @@
      * array content is also composed of struct or class types.
 	 */
 
-	GenericArray* newArray = (GenericArray*) new FdoByte[newAllocBytes];
+    GenericArray* newArray = NULL;
+
+    if (sizeof(FdoByte) == elementSize)
+    {
+        // Try to acquire an FdoByteArray from the pool that is in thread-local storage.
+        // This is faster than going to the heap with the "new" operator.
+        FdoCommonThreadData * threadData = FdoCommonThreadData::GetValue();
+        FdoPoolFgfByteArray * pool = threadData->byteArrayPool;
+        if (NULL == pool)
+        {
+            threadData->byteArrayPool = FdoPoolFgfByteArray::Create(10);
+        }
+        else
+        {
+            GenericArray * pooledArray = (GenericArray*)pool->FindReusableItem();
+            if (NULL != pooledArray)
+            {
+                // The pooling template only knows that the entry is available.  It
+                // doesn't know other attributes, such as adequate size.  We'll test
+                // it here.  If it is not beg enough, we'll delete it and fall through
+                // to a new allocation.
+                if (pooledArray->m_metadata.alloc >= newAlloc)
+                {
+                    newArray = (GenericArray*) pooledArray;
+                }
+                else
+                {
+		            (void) memset(pooledArray, 0xfa, sizeof(GenericArray) + (pooledArray->m_metadata.alloc*elementSize));
+		            delete [] ((FdoByte*) pooledArray);
+		            pooledArray = 0;
+                }
+            }
+        }
+    }
+
+    if (NULL == newArray)
+	    newArray = (GenericArray*) new FdoByte[newAllocBytes];
 	if (0==newArray)
 		throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 	// Copy data from old array.
 	if (0!=array)
 	{
-		newArray->m_metadata = array->m_metadata;
-		if (oldSize > 0)
+        // Copy all metadata.
+        *newArray = *array;
+        // Copy elements.
+        if (oldSize > 0)
 			(void) memcpy( newArray->GetData(), array->GetData(), oldSize*elementSize );
     	// Make sure that stale pointers cannot do much.
-		(void) memset(array, 0xfd, sizeof(Metadata) + (array->m_metadata.alloc*elementSize));
+		(void) memset(array, 0xfd, sizeof(GenericArray) + (array->m_metadata.alloc*elementSize));
+        // Delete old storage.
 		delete [] ((FdoByte*) array);
 		array = 0;
 	}
@@ -155,8 +258,134 @@
 
 void FdoArrayHelper::DisposeOfArray(GenericArray* array, FdoInt32 elementSize)
 {
-	// Make sure that stale pointers cannot do much.
-    (void) memset(array, 0xff, sizeof(Metadata)+ (array->m_metadata.alloc*elementSize));
-	delete [] ((FdoByte*)array);
+    bool isPooled = false;
+
+    if (sizeof(FdoByte) == elementSize && array->m_metadata.alloc <= POOL_ENTRY_BYTESIZE_LIMIT)
+    {
+        // This is an FdoByteArray (or something with the same element size, 
+        // which is all that matters).  See if we can send it into the object pool,
+        // rather that actually freeing it.
+        FdoCommonThreadData * threadData = FdoCommonThreadData::GetValue();
+        if (threadData->byteArrayPool != NULL)
+            isPooled = threadData->byteArrayPool->AddItem((FdoByteArray *)array);
+    }
+    if (!isPooled)
+    {
+	    // Make sure that stale pointers cannot do much.
+        void * destination = array;
+        size_t size = sizeof(GenericArray) + (array->m_metadata.alloc*elementSize);
+        (void) memset(destination, 0xfc, size);
+
+        // Free the memory.
+	    delete [] ((FdoByte*)array);
+    }
 }
 
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+static wchar_t module[MAX_PATH];
+static wchar_t home_dir[MAX_PATH];
+
+/// <summary>
+/// Main entry point for the dll.
+/// </summary>
+/// <param name="hModule">Handle to the DLL module.</param> 
+/// <param name="ul_reason_for_call">Reason for calling function.</param> 
+/// <param name="lpReserved">Reserved.</param> 
+/// <returns>TRUE if it succeeds or FALSE if initialization fails.</returns> 
+BOOL APIENTRY DllMain( HANDLE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+					 )
+{
+    DWORD nchars;
+    wchar_t* last;
+    BOOL ret;
+
+    ret = TRUE;
+    switch (ul_reason_for_call)
+    {
+
+        case DLL_PROCESS_ATTACH:
+        {
+            // hModule - The value is the base address of the DLL.
+            // The HINSTANCE of a DLL is the same as the HMODULE of the DLL,
+            // so hinstDLL can be used in calls to functions that require a module handle.
+            nchars = GetModuleFileNameW ((HINSTANCE)hModule, module, MAX_PATH);
+            if (0 == nchars)
+                ret = FALSE;
+            else
+            {   
+                // scan the string for the last occurrence of a slash
+                wcscpy (home_dir, module);
+                last = wcsrchr (home_dir, L'\\');
+                if (NULL == last)
+                    ret = FALSE;
+                else
+                {
+                    last++; // move past the slash
+                    *last = L'\0'; // null terminate it there
+                }
+            }
+            FdoCommonThreadDataKey tlsIndex = TlsAlloc();
+            FdoCommonThreadData::SetKey(tlsIndex);
+            break;
+        }
+
+
+        case DLL_THREAD_ATTACH: 
+ 
+            // Nothing essential here.  We to defer any pre-allocation
+            // until someone calls FdoCommonThreadData::GetValue().
+ 
+            break; 
+ 
+        case DLL_THREAD_DETACH: 
+
+            FdoCommonThreadData::ReleaseValue();
+            break; 
+ 
+        case DLL_PROCESS_DETACH: 
+ 
+            FdoCommonThreadData::ReleaseValue();
+            TlsFree(FdoCommonThreadData::GetKey());
+            break; 
+
+    }
+
+    return (ret);
+}
+
+#else   // no _WIN32
+
+// This destructor function is called automatically when the
+// threading library destroys a thread key.
+void _FdoCommonThreadDataDestructor(void * voidData)
+{
+    FdoCommonThreadData *data = (FdoCommonThreadData *) voidData;
+                                                                                                           
+    if (NULL != data)
+    {
+        delete data;
+    }
+}
+
+void _loadFdoCommon()
+{
+    FdoCommonThreadDataKey key=0;
+    pthread_key_create(&key, _FdoCommonThreadDataDestructor);
+    FdoCommonThreadData::SetKey(key);
+}
+
+
+void _unloadFdoCommon()
+{
+    FdoCommonThreadDataKey key = FdoCommonThreadData::GetKey();
+    pthread_key_delete(key);
+}
+
+#endif
+

Modified: trunk/Fdo/Unmanaged/Src/Fdo/Fdo.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Fdo/Fdo.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Fdo/Fdo.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -73,10 +73,12 @@
 #else
 void _load();
 void _unload();
+void _loadFdoCommon();
+void _unloadFdoCommon();
 
 /*
-   This is temporary code to call _load/_unload in FdoGeometryDll.cpp
-   when the shared library is loaded/unloaded.
+   This is to call _load/_unload methods in FdoGeometry and FdoCommon
+   packages when the FDO shared library is loaded/unloaded.
 */
 class InitClass
 {
@@ -84,10 +86,12 @@
     InitClass()
     {
         _load();
+        _loadFdoCommon();
     };
     ~InitClass()
     {
         _unload();
+        _unloadFdoCommon();
     };
 };
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -20,6 +20,7 @@
 #include <Geometry/EnvelopeImpl.h>
 #include "CurvePolygon.h"
 #include "Util.h"
+#include "GeometryFactory2.h"
 
 
 /************************************************************************/
@@ -27,10 +28,11 @@
 /************************************************************************/
 FdoFgfCurvePolygon::FdoFgfCurvePolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoIRing* exteriorRing,
     FdoRingCollection* interiorRings
     )
-    : FdoFgfGeometryImpl<FdoICurvePolygon>(factory)
+    : FdoFgfGeometryImpl<FdoICurvePolygon>(factory, pools)
 {
 	if (NULL == exteriorRing)
          throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_CREATION),
@@ -38,7 +40,7 @@
                                                                 L"exteriorRing"));
 
     // Cannot use smart pointer for updating a FdoArray.
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	// FdoGeometryType
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_CurvePolygon);
@@ -68,11 +70,12 @@
 
 FdoFgfCurvePolygon::FdoFgfCurvePolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoICurvePolygon>(factory)
+    : FdoFgfGeometryImpl<FdoICurvePolygon>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -226,9 +229,11 @@
     const FdoByte ** inputStream,
     const FdoByte * streamEnd ) const
 {
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
 	// StartPosition
 	FdoPtr<FdoIDirectPosition> startPos =
-        FgfUtil::ReadDirectPosition(m_factory, dimensionality, inputStream, streamEnd);
+        FgfUtil::ReadDirectPosition(gf, dimensionality, inputStream, streamEnd);
 
 	// NumRings
 	FdoInt32 numCurveSegments = FgfUtil::ReadInt32(inputStream, streamEnd);
@@ -239,12 +244,12 @@
 	for (FdoInt32 i=0; i<numCurveSegments; i++)
 	{
 		FdoPtr<FdoICurveSegmentAbstract> curveSeg =
-            FgfUtil::ReadCurveSegment(m_factory, dimensionality, startPos, inputStream, streamEnd);
+            FgfUtil::ReadCurveSegment(gf, dimensionality, startPos, inputStream, streamEnd);
         curveSegs->Add(curveSeg);
 		startPos = curveSeg->GetEndPosition();
 	}
 
-	FdoPtr<FdoIRing> ring = m_factory->CreateRing(curveSegs);
+	FdoPtr<FdoIRing> ring = gf->CreateRing(curveSegs);
 
 	return FDO_SAFE_ADDREF(ring.p);
 }
@@ -255,6 +260,7 @@
 /************************************************************************/
 void FdoFgfCurvePolygon::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(CurvePolygon);
 }
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurvePolygon.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -34,13 +34,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfCurvePolygon(FdoFgfGeometryFactory * factory, FdoIRing* exteriorRing, FdoRingCollection* interiorRings);
+	FdoFgfCurvePolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoIRing* exteriorRing, FdoRingCollection* interiorRings);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfCurvePolygon(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfCurvePolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,9 +33,10 @@
 /************************************************************************/
 FdoFgfCurveString::FdoFgfCurveString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoCurveSegmentCollection* curveSegs
     )
-    : FdoFgfGeometryImpl<FdoICurveString>(factory)
+    : FdoFgfGeometryImpl<FdoICurveString>(factory, pools)
 {
 	if ( (NULL == curveSegs) ||
 		  (NULL == factory) ||
@@ -44,7 +45,7 @@
                                                                 L"FdoFgfCurveString",
                                                                 L"curveSegs/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	// Geometrytype
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_CurveString);
@@ -74,11 +75,12 @@
 
 FdoFgfCurveString::FdoFgfCurveString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoICurveString>(factory)
+    : FdoFgfGeometryImpl<FdoICurveString>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -142,8 +144,10 @@
 	// read FdoDimensionality
 	FdoInt32 dimensionality = FgfUtil::ReadInt32(&m_streamPtr, m_streamEnd);
 	
-	// Read startPos
-	return FgfUtil::ReadDirectPosition(m_factory, dimensionality, &m_streamPtr, m_streamEnd);
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
+    // Read startPos
+	return FgfUtil::ReadDirectPosition(gf, dimensionality, &m_streamPtr, m_streamEnd);
 }
 
 /************************************************************************/
@@ -174,7 +178,9 @@
 
     m_streamPtr -= numOrdsPerPos * sizeof(double);       // Back up on stream.
 
-	return FgfUtil::ReadDirectPosition(m_factory, dimensionality, &m_streamPtr, m_streamEnd);
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
+    return FgfUtil::ReadDirectPosition(gf, dimensionality, &m_streamPtr, m_streamEnd);
 }
 
 /************************************************************************/
@@ -237,6 +243,8 @@
 		 (Index < 0) )
 		 throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INDEXOUTOFBOUNDS)));
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
 	/*
 	 *	Note: The first position for the segment to be returned is
 	 *  stored as part of last position of immediately previous segment.
@@ -275,7 +283,7 @@
 
 		// Read Startpos of curvesegment
         FdoPtr<FdoIDirectPosition> startPosPrevSeg =
-            FgfUtil::ReadDirectPosition(m_factory, dimensionality, &m_streamPtr, m_streamEnd);
+            FgfUtil::ReadDirectPosition(gf, dimensionality, &m_streamPtr, m_streamEnd);
 
 		// Skip numSegments
 		FGFUTIL_SKIP_INT32S(&m_streamPtr, m_streamEnd, 1);
@@ -283,7 +291,7 @@
 		// Skip to curve segment just before the one that we need
         FgfUtil::SkipCurveSegments(Index-1, dimensionality, &m_streamPtr, m_streamEnd);
 		FdoPtr<FdoICurveSegmentAbstract> prevCurveSeg =
-            FgfUtil::ReadCurveSegment(m_factory, dimensionality, startPosPrevSeg, &m_streamPtr, m_streamEnd);
+            FgfUtil::ReadCurveSegment(gf, dimensionality, startPosPrevSeg, &m_streamPtr, m_streamEnd);
 
 		// And Read its last position
 		// which will be startPos for the segment
@@ -293,7 +301,7 @@
 
 	// Read the CurveSegment we are interested in
 	// We are already pointing at it
-	FdoPtr<FdoICurveSegmentAbstract> thisCurveSeg = FgfUtil::ReadCurveSegment(m_factory, dimensionality, startPos, &m_streamPtr, m_streamEnd);
+	FdoPtr<FdoICurveSegmentAbstract> thisCurveSeg = FgfUtil::ReadCurveSegment(gf, dimensionality, startPos, &m_streamPtr, m_streamEnd);
 
 	return FDO_SAFE_ADDREF(thisCurveSeg.p);
 }
@@ -324,7 +332,8 @@
 /************************************************************************/
 void FdoFgfCurveString::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(CurveString);
 }
 
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/CurveString.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,13 +33,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfCurveString(FdoFgfGeometryFactory * factory, FdoCurveSegmentCollection* curveSegs);
+	FdoFgfCurveString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoCurveSegmentCollection* curveSegs);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfCurveString(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfCurveString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -42,9 +42,14 @@
         // releases the thread data upon exit.  That happens when
         // code in FdoGeometryDll.cpp calls FdoGeometryThreadData::ReleaseValue().
 
-        threadData->geometryFactory = new FdoFgfGeometryFactory();
-        if (NULL == threadData->geometryFactory)
+        try
+        {
+            threadData->geometryFactory = new FdoFgfGeometryFactory();
+        }
+        catch(...)
+        {
             throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
+        }
     }
 
 	return FDO_SAFE_ADDREF((threadData->geometryFactory).p);
@@ -60,23 +65,61 @@
     // Only a limited implementation is available, which uses defaults for
     // the pool sizes.  The returned object is, however, a private one,
     // i.e. not in thread-local storage.
-    FdoFgfGeometryFactory * gf = new FdoFgfGeometryFactory();
+    FdoFgfGeometryFactory * gf = new FdoFgfGeometryFactory(
+        numGeometries,
+        numPositions,
+        numEnvelopes,
+        numCurveSegments,
+        numRings);
+
     return gf;
 }
 
 
 // Constructor
 FdoFgfGeometryFactory::FdoFgfGeometryFactory()
+:
+    m_private(NULL)
 {
+    try
+    {
+        m_private = new FdoFgfGeometryFactory2(true);
+    }
+    catch(...)
+    {
+        throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
+    }
 #ifdef EXTRA_DEBUG
     char fileName[1000];
     sprintf(fileName, "D:\\temp\\FdoDebugFile0x%lx.log", (long)(this));
-    m_private->m_fdoDebugFile = fopen(fileName, "w+");
+    m_private->m_geometryPools->m_fdoDebugFile = fopen(fileName, "w+");
 #endif
+}
 
-    m_private = new FdoFgfGeometryFactory2();
-    if (NULL == m_private)
+
+// Constructor
+FdoFgfGeometryFactory::FdoFgfGeometryFactory(
+    FdoInt32 numGeometries,
+    FdoInt32 numPositions,
+    FdoInt32 numEnvelopes,
+    FdoInt32 numCurveSegments,
+    FdoInt32 numRings)
+:
+    m_private(NULL)
+{
+    try
+    {
+        m_private = new FdoFgfGeometryFactory2(false);
+    }
+    catch(...)
+    {
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
+    }
+#ifdef EXTRA_DEBUG
+    char fileName[1000];
+    sprintf(fileName, "D:\\temp\\FdoDebugFile0x%lx.log", (long)(this));
+    m_private->m_geometryPools->m_fdoDebugFile = fopen(fileName, "w+");
+#endif
 }
 
 
@@ -84,20 +127,50 @@
 FdoFgfGeometryFactory::~FdoFgfGeometryFactory()
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "FdoFgfGeometryFactory::~FdoFgfGeometryFactory()\n");
-        fflush(m_private->m_fdoDebugFile);
-        m_private->PrintStats(m_private->m_fdoDebugFile);
-        fclose(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "FdoFgfGeometryFactory::~FdoFgfGeometryFactory()\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
+        m_private->m_geometryPools->PrintStats(m_private->m_geometryPools->m_fdoDebugFile);
+        fclose(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 
     delete m_private;
 }
 
+FdoFgfGeometryFactory2::FdoFgfGeometryFactory2(bool useThreadLocal)
+    : m_useThreadLocal(useThreadLocal)
+{
+    try
+    {
+        if (useThreadLocal)
+        {
+            FdoGeometryThreadData * threadData = FdoGeometryThreadData::GetValue();
+            if (NULL == threadData->geometryPools)
+                threadData->geometryPools = new FdoFgfGeometryPools();
+            m_geometryPools = threadData->geometryPools;
+        }
+        else
+        {
+            m_geometryPools = new FdoFgfGeometryPools();
+        }
+    }
+    catch(...)
+    {
+        if (m_geometryPools == NULL)
+            throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
+    }
+}
+
+FdoFgfGeometryFactory2::~FdoFgfGeometryFactory2()
+{
+    if (!m_useThreadLocal)
+        FDO_SAFE_RELEASE(m_geometryPools.p);
+}
+
 #ifdef EXTRA_DEBUG
-void FdoFgfGeometryFactory2::PrintStats(FILE * fileHandle)
+void FdoFgfGeometryPools::PrintStats(FILE * fileHandle)
 {
     if (NULL != fileHandle)
     {
@@ -120,9 +193,9 @@
                 "      LineString Pool stats: %d empty hits, %d reusable hits, %d misses\n",
                 ehits, rhits, misses);
         }
-        if (m_linearRingPool != NULL)
+        if (m_PoolLinearRing != NULL)
         {
-            m_linearRingPool->GetStats(&ehits, &rhits, &misses);
+            m_PoolLinearRing->GetStats(&ehits, &rhits, &misses);
             fprintf(fileHandle,
                 "      LinearRing Pool stats: %d empty hits, %d reusable hits, %d misses\n",
                 ehits, rhits, misses);
@@ -135,18 +208,18 @@
 FdoILineString* FdoFgfGeometryFactory::CreateLineString(FdoDirectPositionCollection * positions)
 {
     FDOPOOL_CREATE_OBJECT(
-        m_private->m_PoolLineString, FdoPoolFgfLineString, 4,
+        m_private->m_geometryPools->m_PoolLineString, FdoPoolFgfLineString, 4,
         FdoFgfLineString,
-        FdoFgfLineString(this, positions),
+        FdoFgfLineString(this, m_private->GetPoolsForGeomCtor(), positions),
         Reset(positions) );
 }
 
 FdoILineString* FdoFgfGeometryFactory::CreateLineString(FdoInt32 dimensionType, FdoInt32 numOrdinates, double* ordinates)
 {
     FDOPOOL_CREATE_OBJECT(
-        m_private->m_PoolLineString, FdoPoolFgfLineString, 4,
+        m_private->m_geometryPools->m_PoolLineString, FdoPoolFgfLineString, 4,
         FdoFgfLineString,
-        FdoFgfLineString(this, dimensionType, numOrdinates, ordinates),
+        FdoFgfLineString(this, m_private->GetPoolsForGeomCtor(), dimensionType, numOrdinates, ordinates),
         Reset(dimensionType, numOrdinates, ordinates) );
 }
 
@@ -154,29 +227,29 @@
 FdoIGeometry * FdoFgfGeometryFactory::CreateGeometry(FdoIGeometry * geometry)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometry(geometry=0x%lx) type=%d IN\n",
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometry(geometry=0x%lx) type=%d IN\n",
             (long)geometry, (int)(geometry->GetDerivedType()));
-        fflush(m_private->m_fdoDebugFile);
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
         try
         {
             //if (geometry->GetDerivedType() == FdoGeometryType_LineString)
             {
                 FdoString * fgftString = geometry->GetText();
-                fprintf(m_private->m_fdoDebugFile, "  fgft='%S'\n", fgftString);
-                fflush(m_private->m_fdoDebugFile);
+                fprintf(m_private->m_geometryPools->m_fdoDebugFile, "  fgft='%S'\n", fgftString);
+                fflush(m_private->m_geometryPools->m_fdoDebugFile);
             }
         }
         catch ( FdoException* e )
         {
-            fprintf(m_private->m_fdoDebugFile, "  Caught FdoException from GetText(): <<%S>>\n", e->GetExceptionMessage());
-            fflush(m_private->m_fdoDebugFile);
+            fprintf(m_private->m_geometryPools->m_fdoDebugFile, "  Caught FdoException from GetText(): <<%S>>\n", e->GetExceptionMessage());
+            fflush(m_private->m_geometryPools->m_fdoDebugFile);
         }
         catch (...)
         {
-            fprintf(m_private->m_fdoDebugFile, "  Caught unknown exception from GetText().\n");
-            fflush(m_private->m_fdoDebugFile);
+            fprintf(m_private->m_geometryPools->m_fdoDebugFile, "  Caught unknown exception from GetText().\n");
+            fflush(m_private->m_geometryPools->m_fdoDebugFile);
         }
 
     }
@@ -192,11 +265,11 @@
     newByteArray = NULL;
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometry() OUT\n",
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometry() OUT\n",
             (long)geometry);
-        fflush(m_private->m_fdoDebugFile);
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(newGeometry.p);
@@ -218,11 +291,11 @@
                                                                L"byteArray/byteArrayData/count"));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometryFromFgf(0x%lx, 0x%lx, count=%d) IN\n",
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometryFromFgf(0x%lx, 0x%lx, count=%d) IN\n",
             (long)byteArray, (long)byteArrayData, count);
-        fflush(m_private->m_fdoDebugFile);
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	FdoPtr<FdoIGeometry> newGeometry;
@@ -242,21 +315,20 @@
 
 	FdoGeometryType geometryType = (FdoGeometryType) FgfUtil::ReadInt32(&streamPtr, streamEnd);
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "FdoFgfGeometryFactory::CreateGeometryFromFgf GeometryType=%d\n", (int) geometryType);
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "FdoFgfGeometryFactory::CreateGeometryFromFgf GeometryType=%d\n", (int) geometryType);
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 
 #define CASE_CREATE_POOLED_GEOMETRY(type) \
     case FdoGeometryType_##type: \
-        newGeometry = m_private->Create##type(this, byteArray, byteArrayData, count); \
+        newGeometry = m_private->m_geometryPools->Create##type(this, m_private->GetPoolsForGeomCtor(), byteArray, byteArrayData, count); \
         break;
 
-    // Call SetFgf() on the appropriate type.  Unfortunately, we cannot call it
-    // directly on the base FdoFgfGeometryImpl type because it's a template on an 
-    // abstract type (FdoIGeometry).
+    // Acquire (from a pool or 'new') a geometry of the needed
+    // type, making it point to the given byte array.
     switch ( geometryType )
     {
     CASE_CREATE_POOLED_GEOMETRY(LineString);
@@ -277,10 +349,10 @@
     }
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometryFromFgf() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometryFromFgf() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     return FDO_SAFE_ADDREF(newGeometry.p);
@@ -304,10 +376,10 @@
 FdoByteArray * FdoFgfGeometryFactory::GetFgf(FdoIGeometry * geometry)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "FdoFgfGeometryFactory::GetFgf() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "FdoFgfGeometryFactory::GetFgf() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	FdoPtr<FdoByteArray> array = 0;
@@ -370,10 +442,10 @@
 	}
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "FdoFgfGeometryFactory::GetFgf() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "FdoFgfGeometryFactory::GetFgf() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(array.p);
@@ -485,10 +557,10 @@
 FdoIGeometry * FdoFgfGeometryFactory::CreateGeometryFromWkb(FdoByteArray * byteArray)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometryFromWkb() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometryFromWkb() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 #define MIN_WKB_SIZE (sizeof(FdoByte)+sizeof(FdoInt32)+sizeof(FdoInt32))    // endian byte, geometry type, at least an integer of data
@@ -519,10 +591,10 @@
     FdoPtr<FdoIGeometry> geometry = this->CreateGeometryFromFgf(fgfByteArray);
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometryFromWkb() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometryFromWkb() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     return FDO_SAFE_ADDREF(geometry.p);
@@ -532,10 +604,10 @@
 FdoByteArray * FdoFgfGeometryFactory::GetWkb(FdoIGeometry * geometry)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "FdoFgfGeometryFactory::GetWkb() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "FdoFgfGeometryFactory::GetWkb() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     if (NULL == geometry)
@@ -610,10 +682,10 @@
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_10_UNSUPPORTEDGEOMETRYTYPE)));
 	}
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "FdoFgfGeometryFactory::GetWkb() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "FdoFgfGeometryFactory::GetWkb() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return wkb;
@@ -627,10 +699,10 @@
 FdoIPoint* FdoFgfGeometryFactory::CreatePoint(FdoIDirectPosition* position)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreatePoint() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreatePoint() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if (NULL == position)
@@ -638,14 +710,14 @@
                                                                L"FdoIPoint",
                                                                L"position"));
 
-	FdoPtr<FdoIPoint> point = new FdoFgfPoint(this, position);
+	FdoPtr<FdoIPoint> point = new FdoFgfPoint(this, m_private->GetPoolsForGeomCtor(), position);
     if (point == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreatePoint() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreatePoint() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(point.p);
@@ -658,24 +730,24 @@
 FdoIPoint* FdoFgfGeometryFactory::CreatePoint(FdoInt32 dimensionality, double* ordinates)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreatePoint() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreatePoint() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if (NULL == ordinates)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_CREATION),
                                                                L"ordinates"));
 
-	FdoPtr<FdoIPoint> point = new FdoFgfPoint(this, dimensionality, ordinates);
+	FdoPtr<FdoIPoint> point = new FdoFgfPoint(this, m_private->GetPoolsForGeomCtor(), dimensionality, ordinates);
     if (point == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreatePoint() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreatePoint() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(point.p);
@@ -688,9 +760,9 @@
 FdoILinearRing* FdoFgfGeometryFactory::CreateLinearRing(FdoDirectPositionCollection * positions)
 {
     FDOPOOL_CREATE_OBJECT(
-        m_private->m_linearRingPool, FdoFgfLinearRingPool, 4,
+        m_private->m_geometryPools->m_PoolLinearRing, FdoPoolFgfLinearRing, 4,
         FdoFgfLinearRing,
-        FdoFgfLinearRing(this, positions),
+        FdoFgfLinearRing(this, m_private->GetPoolsForGeomCtor(), positions),
         Reset(positions) );
 }
 
@@ -701,9 +773,9 @@
 FdoILinearRing* FdoFgfGeometryFactory::CreateLinearRing(FdoInt32 dimtype, FdoInt32 numOrdinates, double* ordinates)
 {
     FDOPOOL_CREATE_OBJECT(
-        m_private->m_linearRingPool, FdoFgfLinearRingPool, 4,
+        m_private->m_geometryPools->m_PoolLinearRing, FdoPoolFgfLinearRing, 4,
         FdoFgfLinearRing,
-        FdoFgfLinearRing(this, dimtype, numOrdinates, ordinates),
+        FdoFgfLinearRing(this, m_private->GetPoolsForGeomCtor(), dimtype, numOrdinates, ordinates),
         Reset(dimtype, numOrdinates, ordinates) );
 }
 
@@ -715,10 +787,10 @@
 FdoILineStringSegment* FdoFgfGeometryFactory::CreateLineStringSegment(FdoDirectPositionCollection * positions)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateLineStringSegment() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateLineStringSegment() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == positions) ||
@@ -733,10 +805,10 @@
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateLineStringSegment() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateLineStringSegment() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     return FDO_SAFE_ADDREF(lineSegment.p);
@@ -750,10 +822,10 @@
 FdoILineStringSegment* FdoFgfGeometryFactory::CreateLineStringSegment(FdoInt32 dimensionality, FdoInt32 numOrdinates, double* ordinates)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateLineStringSegment() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateLineStringSegment() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == ordinates) ||
@@ -768,10 +840,10 @@
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateLineStringSegment() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateLineStringSegment() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     return FDO_SAFE_ADDREF(lineSegment.p);
@@ -784,10 +856,10 @@
 FdoIPolygon* FdoFgfGeometryFactory::CreatePolygon(FdoILinearRing* exteriorRing, FdoLinearRingCollection* interiorRings)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreatePolygon() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreatePolygon() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if (NULL == exteriorRing)
@@ -795,16 +867,16 @@
                                                                L"FdoIPolygon",
                                                                L"exteriorRing"));
 
-	FdoPtr<FdoFgfPolygon> polygon = new FdoFgfPolygon(this, exteriorRing, interiorRings);
+	FdoPtr<FdoFgfPolygon> polygon = new FdoFgfPolygon(this, m_private->GetPoolsForGeomCtor(), exteriorRing, interiorRings);
 
     if (polygon == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreatePolygon() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreatePolygon() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(polygon.p);
@@ -818,10 +890,10 @@
 FdoIMultiPoint* FdoFgfGeometryFactory::CreateMultiPoint(FdoPointCollection* points)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiPoint() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiPoint() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == points) ||
@@ -830,16 +902,16 @@
                                                                L"FdoIMultiPoint",
                                                                L"points"));
 
-	FdoPtr<FdoFgfMultiPoint> multiPoint =  new FdoFgfMultiPoint(this, points);
+	FdoPtr<FdoFgfMultiPoint> multiPoint =  new FdoFgfMultiPoint(this, m_private->GetPoolsForGeomCtor(), points);
 
     if (multiPoint == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiPoint() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiPoint() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiPoint.p);
@@ -853,10 +925,10 @@
 FdoIMultiPoint* FdoFgfGeometryFactory::CreateMultiPoint(FdoInt32 dimensionality, FdoInt32 numOrdinates, double* ordinates)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiPoint() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiPoint() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == ordinates) ||
@@ -865,16 +937,16 @@
                                                                L"FdoIMultiPoint",
                                                                L"ordinates/numOrdinates"));
 
-	FdoPtr<FdoFgfMultiPoint> multiPoint =  new FdoFgfMultiPoint(this, dimensionality, numOrdinates, ordinates);
+	FdoPtr<FdoFgfMultiPoint> multiPoint =  new FdoFgfMultiPoint(this, m_private->GetPoolsForGeomCtor(), dimensionality, numOrdinates, ordinates);
 
     if (multiPoint == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiPoint() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiPoint() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiPoint.p);
@@ -888,10 +960,10 @@
 FdoIMultiGeometry* FdoFgfGeometryFactory::CreateMultiGeometry(FdoGeometryCollection* geometries)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiGeometry() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiGeometry() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == geometries) ||
@@ -900,16 +972,16 @@
                                                                L"FdoIMultiGeometry",
                                                                L"geometries"));
 
-	FdoPtr<FdoFgfMultiGeometry> multiGeometry =  new FdoFgfMultiGeometry(this, geometries);
+	FdoPtr<FdoFgfMultiGeometry> multiGeometry =  new FdoFgfMultiGeometry(this, m_private->GetPoolsForGeomCtor(), geometries);
 
     if (multiGeometry == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiGeometry() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiGeometry() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiGeometry.p);
@@ -923,10 +995,10 @@
 FdoIMultiLineString* FdoFgfGeometryFactory::CreateMultiLineString(FdoLineStringCollection* lineStrings)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiLineString() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiLineString() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == lineStrings) ||
@@ -935,16 +1007,16 @@
                                                                L"FdoIMultiLineString",
                                                                L"lineStrings"));
 
-	FdoPtr<FdoFgfMultiLineString> multiLineString =  new FdoFgfMultiLineString(this, lineStrings);
+	FdoPtr<FdoFgfMultiLineString> multiLineString =  new FdoFgfMultiLineString(this, m_private->GetPoolsForGeomCtor(), lineStrings);
 
     if (multiLineString == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiLineString() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiLineString() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiLineString.p);
@@ -959,10 +1031,10 @@
 FdoIMultiPolygon* FdoFgfGeometryFactory::CreateMultiPolygon(FdoPolygonCollection* polygons)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiPolygon() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiPolygon() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == polygons) ||
@@ -971,16 +1043,16 @@
                                                                L"FdoIMultiPolygon",
                                                                L"polygons"));
 
-	FdoPtr<FdoFgfMultiPolygon> multiPolygon =  new FdoFgfMultiPolygon(this, polygons);
+	FdoPtr<FdoFgfMultiPolygon> multiPolygon =  new FdoFgfMultiPolygon(this, m_private->GetPoolsForGeomCtor(), polygons);
 
     if (multiPolygon == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiPolygon() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiPolygon() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiPolygon.p);
@@ -993,10 +1065,10 @@
 FdoICircularArcSegment* FdoFgfGeometryFactory::CreateCircularArcSegment(FdoIDirectPosition* startPoint, FdoIDirectPosition* midPoint, FdoIDirectPosition* endPoint)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateCircularArcSegment() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateCircularArcSegment() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == startPoint) ||
@@ -1012,10 +1084,10 @@
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateCircularArcSegment() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateCircularArcSegment() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(circArcSegment.p);
@@ -1029,10 +1101,10 @@
 FdoICurveString* FdoFgfGeometryFactory::CreateCurveString(FdoCurveSegmentCollection* curveSegments)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateCurveString() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateCurveString() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == curveSegments) ||
@@ -1041,16 +1113,16 @@
                                                                L"FdoICurveString",
                                                                L"curveSegments"));
 
-	FdoPtr<FdoFgfCurveString> curveString = new FdoFgfCurveString(this, curveSegments);
+	FdoPtr<FdoFgfCurveString> curveString = new FdoFgfCurveString(this, m_private->GetPoolsForGeomCtor(), curveSegments);
 
     if (curveString == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateCurveString() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateCurveString() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(curveString.p);
@@ -1064,10 +1136,10 @@
 FdoIMultiCurveString* FdoFgfGeometryFactory::CreateMultiCurveString(FdoCurveStringCollection* curveStrings)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiCurveString() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiCurveString() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     if ( (NULL == curveStrings) || (0 == curveStrings->GetCount()) )
@@ -1075,16 +1147,16 @@
                                                                L"FdoIMultiCurveString",
                                                                L"curveStrings"));
 
-	FdoPtr<FdoFgfMultiCurveString> multiCurveString = new FdoFgfMultiCurveString(this, curveStrings);
+	FdoPtr<FdoFgfMultiCurveString> multiCurveString = new FdoFgfMultiCurveString(this, m_private->GetPoolsForGeomCtor(), curveStrings);
 
     if (multiCurveString == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiCurveString() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiCurveString() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiCurveString.p);
@@ -1098,10 +1170,10 @@
 FdoIRing* FdoFgfGeometryFactory::CreateRing(FdoCurveSegmentCollection* curveSegments)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateRing() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateRing() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if ( (NULL == curveSegments) ||
@@ -1116,10 +1188,10 @@
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateRing() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateRing() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(ring.p);
@@ -1134,10 +1206,10 @@
 FdoICurvePolygon* FdoFgfGeometryFactory::CreateCurvePolygon(FdoIRing* exteriorRing, FdoRingCollection* interiorRings)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateCurvePolygon() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateCurvePolygon() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	if (NULL == exteriorRing)
@@ -1145,16 +1217,16 @@
                                                                L"FdoICurvePolygon",
                                                                L"exteriorRing"));
 
-	FdoPtr<FdoFgfCurvePolygon> curvePolygon = new FdoFgfCurvePolygon(this, exteriorRing, interiorRings);
+	FdoPtr<FdoFgfCurvePolygon> curvePolygon = new FdoFgfCurvePolygon(this, m_private->GetPoolsForGeomCtor(), exteriorRing, interiorRings);
 
     if (curvePolygon == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateCurvePolygon() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateCurvePolygon() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(curvePolygon.p);
@@ -1169,10 +1241,10 @@
 FdoIMultiCurvePolygon* FdoFgfGeometryFactory::CreateMultiCurvePolygon(FdoCurvePolygonCollection* curvePolygons)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiCurvePolygon() IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiCurvePolygon() IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     if ( (NULL == curvePolygons) || 0 == curvePolygons->GetCount() )
@@ -1180,16 +1252,16 @@
                                                                L"FdoIMultiCurvePolygon",
                                                                L"curvePolygons"));
 
-	FdoPtr<FdoFgfMultiCurvePolygon> multiCurvePolygon = new FdoFgfMultiCurvePolygon(this, curvePolygons);
+	FdoPtr<FdoFgfMultiCurvePolygon> multiCurvePolygon = new FdoFgfMultiCurvePolygon(this, m_private->GetPoolsForGeomCtor(), curvePolygons);
 
     if (multiCurvePolygon == NULL)
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_BADALLOC)));
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateMultiCurvePolygon() OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateMultiCurvePolygon() OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(multiCurvePolygon.p);
@@ -1200,10 +1272,10 @@
 FdoIGeometry * FdoFgfGeometryFactory::CreateGeometry(FdoIEnvelope * envelope)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometry(envelope) IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometry(envelope) IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     int dimensionality = FdoDimensionality_XY;
@@ -1246,10 +1318,10 @@
     FdoPtr<FdoIPolygon> geometry = CreatePolygon(ring, NULL);
 
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometry(envelope) OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometry(envelope) OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
     return FDO_SAFE_ADDREF(geometry.p);
@@ -1258,10 +1330,10 @@
 FdoIGeometry* FdoFgfGeometryFactory::CreateGeometry(FdoString* fgft)
 {
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometry(fgft) IN\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometry(fgft) IN\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	FdoPtr<FdoIGeometry>	geometry;
@@ -1280,58 +1352,95 @@
 		delete parse;
 	}
 #ifdef EXTRA_DEBUG
-    if (NULL != m_private->m_fdoDebugFile)
+    if (NULL != m_private->m_geometryPools->m_fdoDebugFile)
     {
-        fprintf(m_private->m_fdoDebugFile, "CreateGeometry(fgft) OUT\n");
-        fflush(m_private->m_fdoDebugFile);
+        fprintf(m_private->m_geometryPools->m_fdoDebugFile, "CreateGeometry(fgft) OUT\n");
+        fflush(m_private->m_geometryPools->m_fdoDebugFile);
     }
 #endif
 	return FDO_SAFE_ADDREF(geometry.p);
 }
 
-FdoByteArray * FdoFgfGeometryFactory::GetByteArray()
+
+FdoByteArray * FdoFgfGeometryPools::GetByteArray()
 {
-    if (m_private->m_byteArrayPool == NULL)
-        m_private->m_byteArrayPool = FdoByteArrayPool::Create(10);
+    if (m_PoolByteArray == NULL)
+        m_PoolByteArray = FdoPoolFgfByteArray::Create(10);
 
-    // Acquire or create a byte array, whose ownership we'll hand completely 
-    // over to the writer.  Updateable FdoArray types cannot have shared ownership,
-    // since they can move around in memory.  We also avoid smart pointers with
-    // updateable FdoArray types for the same reason.
+    // We avoid smart pointers because updateable FdoArray types cannot have
+    // shared ownership, since they can move around in memory.
 
     FdoByteArray * byteArray = NULL;
-    byteArray = m_private->m_byteArrayPool->FindReusableItem();
+    byteArray = m_PoolByteArray->FindReusableItem();
 
     if (byteArray == NULL)
     {
 	    byteArray = FdoByteArray::Create(172); // A guess: endian+type+dim+20ordinates
 #ifdef EXTRA_DEBUG
-        m_private->m_numByteArraysCreated++;
+        m_numByteArraysCreated++;
 #endif
     }
     else
     {
-        byteArray = FdoByteArray::SetSize(byteArray, 0);
+        byteArray = byteArray->SetSize(byteArray, 0);
     }
 
     return byteArray;
 }
 
+FdoByteArray * FdoFgfGeometryFactory::GetByteArray()
+{
+    return this->m_private->m_geometryPools->GetByteArray();
+}
 
-void FdoFgfGeometryFactory::TakeReleasedByteArray(FdoByteArray * byteArray)
+void FdoFgfGeometryPools::TakeReleasedByteArray(FdoByteArray * byteArray)
 {
 	if (0 == byteArray)
 		throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_FUNCTION),
                                                                L"FdoFgfGeometryFactory::TakeReleasedByteArray",
                                                                L"byteArray"));
 
-    if (m_private->m_byteArrayPool == NULL)
-        m_private->m_byteArrayPool = FdoByteArrayPool::Create(10);
+    if (m_PoolByteArray == NULL)
+        m_PoolByteArray = FdoPoolFgfByteArray::Create(10);
 
-    m_private->m_byteArrayPool->AddItem(byteArray);
+    m_PoolByteArray->AddItem((FdoByteArray *)byteArray);
 }
 
+void FdoFgfGeometryFactory::TakeReleasedByteArray(FdoByteArray * byteArray)
+{
+    this->m_private->m_geometryPools->TakeReleasedByteArray(byteArray);
+}
 
+
+#define DEFINE_CREATE_POOLED_GEOMETRY(type) \
+    FdoI##type * FdoFgfGeometryPools::Create##type( \
+        FdoFgfGeometryFactory * factory, \
+        FdoFgfGeometryPools * pools, \
+        FdoByteArray * byteArray, \
+        const FdoByte * data, \
+        FdoInt32 count \
+        ) \
+    { \
+        FDOPOOL_CREATE_OBJECT( \
+            m_Pool##type, FdoPoolFgf##type, 4, \
+            FdoFgf##type, \
+            FdoFgf##type(factory, pools, byteArray, data, count), \
+            Reset(byteArray, data, count) ); \
+    }
+
+DEFINE_CREATE_POOLED_GEOMETRY(LineString);
+DEFINE_CREATE_POOLED_GEOMETRY(Point);
+DEFINE_CREATE_POOLED_GEOMETRY(Polygon);
+DEFINE_CREATE_POOLED_GEOMETRY(MultiPoint);
+DEFINE_CREATE_POOLED_GEOMETRY(MultiGeometry);
+DEFINE_CREATE_POOLED_GEOMETRY(MultiLineString);
+DEFINE_CREATE_POOLED_GEOMETRY(MultiPolygon);
+DEFINE_CREATE_POOLED_GEOMETRY(CurveString);
+DEFINE_CREATE_POOLED_GEOMETRY(MultiCurveString);
+DEFINE_CREATE_POOLED_GEOMETRY(CurvePolygon);
+DEFINE_CREATE_POOLED_GEOMETRY(MultiCurvePolygon);
+
+
 /************************************************************************/
 /* Dispose()                                                                     */
 /************************************************************************/

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory2.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory2.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryFactory2.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -45,8 +45,8 @@
 #include "MultiCurvePolygon.h"
 
 
-FDOPOOL_DEFINE(FdoByteArrayPool,            FdoByteArray)
-FDOPOOL_DEFINE(FdoFgfLinearRingPool,        FdoFgfLinearRing)
+FDOPOOL_DEFINE(FdoPoolFgfByteArray,         FdoByteArray)
+FDOPOOL_DEFINE(FdoPoolFgfLinearRing,        FdoFgfLinearRing)
 FDOPOOL_DEFINE(FdoPoolFgfLineString,        FdoFgfLineString)
 FDOPOOL_DEFINE(FdoPoolFgfPoint,             FdoFgfPoint)
 FDOPOOL_DEFINE(FdoPoolFgfPolygon,           FdoFgfPolygon)
@@ -65,10 +65,11 @@
 /// <summary>This defines private data for the FdoFgfGeometryFactory class.
 /// Changes can be made here without affecting the public interface.
 /// </summary>
-struct FdoFgfGeometryFactory2
+class FdoFgfGeometryPools : public FdoDisposable
 {
-    FdoPtr<FdoByteArrayPool>            m_byteArrayPool;    // For fast re-creation.
-    FdoPtr<FdoFgfLinearRingPool>        m_linearRingPool;   // For fast re-creation.
+public:
+    FDO_GEOM_POOL_DECLARE(ByteArray);
+    FDO_GEOM_POOL_DECLARE(LinearRing);
     FDO_GEOM_POOL_DECLARE(LineString);
     FDO_GEOM_POOL_DECLARE(Point);
     FDO_GEOM_POOL_DECLARE(Polygon);
@@ -86,20 +87,25 @@
     void PrintStats(FILE * fileHandle);
     FILE * m_fdoDebugFile;
 #endif
-    FdoFgfGeometryFactory2()
+    FdoFgfGeometryPools()
 #ifdef EXTRA_DEBUG
         : m_numByteArraysCreated(0),
           m_fdoDebugFile(NULL)
 #endif
     {
     };
-    ~FdoFgfGeometryFactory2()
+    ~FdoFgfGeometryPools()
     {
+        Clear();
+    };
+
+    void Clear()
+    {
         // Geometry object destructors may try to hand back byte arrays
-        // to the factory.  Rather than let automatic destruction do this
+        // to the pool.  Rather than let automatic destruction do this
         // in an undefined order, we'll do it manually here to ensure that
         // the byte array pool is still defined until the last step.
-        m_linearRingPool = NULL;
+        FDO_GEOM_POOL_NULLIFY(LinearRing);
         FDO_GEOM_POOL_NULLIFY(LineString);
         FDO_GEOM_POOL_NULLIFY(Point);
         FDO_GEOM_POOL_NULLIFY(Polygon);
@@ -111,38 +117,57 @@
         FDO_GEOM_POOL_NULLIFY(MultiCurveString);
         FDO_GEOM_POOL_NULLIFY(CurvePolygon);
         FDO_GEOM_POOL_NULLIFY(MultiCurvePolygon);
-        m_byteArrayPool = NULL;
-    };
+        FDO_GEOM_POOL_NULLIFY(ByteArray);
+    }
 
     // Internal methods for FdoFgfGeometryFactory's use.
 
-#define DEFINE_CREATE_POOLED_GEOMETRY(type) \
+#define DECLARE_CREATE_POOLED_GEOMETRY(type) \
     FdoI##type * Create##type( \
         FdoFgfGeometryFactory * factory, \
+        FdoFgfGeometryPools * pools, \
         FdoByteArray * byteArray, \
         const FdoByte * data, \
         FdoInt32 count \
-        ) \
-    { \
-        FDOPOOL_CREATE_OBJECT( \
-            m_Pool##type, FdoPoolFgf##type, 4, \
-            FdoFgf##type, \
-            FdoFgf##type(factory, byteArray, data, count), \
-            Reset(byteArray, data, count) ); \
+        )
+
+    DECLARE_CREATE_POOLED_GEOMETRY(LineString);
+    DECLARE_CREATE_POOLED_GEOMETRY(Point);
+    DECLARE_CREATE_POOLED_GEOMETRY(Polygon);
+    DECLARE_CREATE_POOLED_GEOMETRY(MultiPoint);
+    DECLARE_CREATE_POOLED_GEOMETRY(MultiGeometry);
+    DECLARE_CREATE_POOLED_GEOMETRY(MultiLineString);
+    DECLARE_CREATE_POOLED_GEOMETRY(MultiPolygon);
+    DECLARE_CREATE_POOLED_GEOMETRY(CurveString);
+    DECLARE_CREATE_POOLED_GEOMETRY(MultiCurveString);
+    DECLARE_CREATE_POOLED_GEOMETRY(CurvePolygon);
+    DECLARE_CREATE_POOLED_GEOMETRY(MultiCurvePolygon);
+
+    /// Get an empty (possibly pooled) byte array.
+    virtual FdoByteArray * GetByteArray();
+
+    /// Pool this array, released from some geometry.
+    virtual void TakeReleasedByteArray(FdoByteArray * byteArray);
+
+};
+
+struct FdoFgfGeometryFactory2
+{
+    FdoPtr<FdoFgfGeometryPools>  m_geometryPools;
+    bool                         m_useThreadLocal;
+
+    FdoFgfGeometryFactory2(bool useThreadLocal);
+
+    inline FdoFgfGeometryPools * GetPoolsForGeomCtor()
+    {
+        FdoFgfGeometryPools * pools = NULL;    // Lightweight (no reference count)
+        if (!m_useThreadLocal)
+            pools = m_geometryPools;
+        return pools;
     }
 
-    DEFINE_CREATE_POOLED_GEOMETRY(LineString);
-    DEFINE_CREATE_POOLED_GEOMETRY(Point);
-    DEFINE_CREATE_POOLED_GEOMETRY(Polygon);
-    DEFINE_CREATE_POOLED_GEOMETRY(MultiPoint);
-    DEFINE_CREATE_POOLED_GEOMETRY(MultiGeometry);
-    DEFINE_CREATE_POOLED_GEOMETRY(MultiLineString);
-    DEFINE_CREATE_POOLED_GEOMETRY(MultiPolygon);
-    DEFINE_CREATE_POOLED_GEOMETRY(CurveString);
-    DEFINE_CREATE_POOLED_GEOMETRY(MultiCurveString);
-    DEFINE_CREATE_POOLED_GEOMETRY(CurvePolygon);
-    DEFINE_CREATE_POOLED_GEOMETRY(MultiCurvePolygon);
+    virtual ~FdoFgfGeometryFactory2();
+};
 
-};
 #endif
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryImpl.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryImpl.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryImpl.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -24,6 +24,9 @@
 #include "../GeometryImpl.h"
 
 #include <Geometry/Fgf/Factory.h>
+//#include "GeometryFactory2.h"
+class FdoFgfGeometryPools;  // Forward declaration
+#include "Util.h"
 
 // This template extends FdoGeometryImpl with some common code, also in aid
 // of avoiding "diamond inheritance", but is specifically for FGF-related
@@ -34,21 +37,6 @@
 
 public:
 
-    // Constructor that just latches onto a stream (of FGF data).
-    FdoFgfGeometryImpl(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count)
-        : FdoGeometryImpl<FDO_GEOMETRY_CLASS>(), m_factory(factory),
-          m_data(NULL), m_streamEnd(NULL), m_streamPtr(NULL)
-    {
-        if ((NULL == byteArray && NULL == data) ||
-            (NULL != byteArray && byteArray->GetCount() <= 0) ||
-            (NULL != data && count <= 0))
-		    throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_CREATION),
-                                                                   L"FdoFgfGeometryImpl",
-                                                                   L"byteArray/data/count"));
-
-	    SetFgf(byteArray, data, count);
-    }
-
 	// Get the FGF array from the geometry.
 	virtual FdoByteArray * GetFgf()
     {
@@ -77,7 +65,7 @@
 	virtual void SetFgf(FdoByteArray * fgf, const FdoByte* fgfData, FdoInt32 count)
     {
         if (m_byteArray != NULL)
-            m_factory->TakeReleasedByteArray(m_byteArray);
+            FgfUtil::GetPoolsNoRef(m_pools)->TakeReleasedByteArray(m_byteArray);
 
         if (NULL != fgf)
         {
@@ -111,7 +99,8 @@
         }
     }
 
-    FdoFgfGeometryFactory *        m_factory;  // FGF geometry factory (lightweight to avoid circular reference)
+    FdoFgfGeometryFactory *         m_factoryy;  // FGF geometry factory (lightweight to avoid circular reference)
+    FdoFgfGeometryPools *           m_pools;  // Geometry pools (lightweight to avoid circular reference)
 
 
 	// Storage of FGF bytestream data (non-NULL if the data is at least partly owned here)
@@ -131,10 +120,10 @@
     // Protect default constructor so that a factory must be used.
     FdoFgfGeometryImpl() {};
 
-    // This constructor is extended by some geometry types that copy an input
-    // FGF data stream.
-    FdoFgfGeometryImpl(FdoFgfGeometryFactory * factory)
-        : FdoGeometryImpl<FDO_GEOMETRY_CLASS>(), m_factory(factory),
+    // This constructor is used during auto-initialization in most 
+    // geometry types.
+    FdoFgfGeometryImpl(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools)
+        : FdoGeometryImpl<FDO_GEOMETRY_CLASS>(), m_factoryy(factory), m_pools(pools),
           m_data(NULL), m_streamEnd(NULL), m_streamPtr(NULL)
     {
     };
@@ -142,9 +131,31 @@
     // Destructor
 	virtual ~FdoFgfGeometryImpl()
     {
+        SurrenderByteArray();
     }
+
+    // Get pointer to geometry factory.
+    inline FdoFgfGeometryFactory * GetFactory() const
+    {
+        FdoFgfGeometryFactory * factory =
+            (NULL == m_factoryy) ?
+            FdoFgfGeometryFactory::GetInstance() :
+            factory = FDO_SAFE_ADDREF(m_factoryy);
+
+        return factory;
+    }
+
+    inline void SurrenderByteArray()
+    {
+        if (m_byteArray != NULL)
+        {
+            FdoFgfGeometryPools * pools = FgfUtil::GetPoolsNoRef(m_pools);
+            if (NULL != pools)
+                pools->TakeReleasedByteArray(m_byteArray);
+            m_byteArray = NULL;
+        }
+    }
 };
 
-
 #endif
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryThreadData.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryThreadData.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/GeometryThreadData.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -31,11 +31,13 @@
 struct FdoGeometryThreadData
 {
     FdoPtr<FdoFgfGeometryFactory> geometryFactory;
+    FdoPtr<FdoFgfGeometryPools>   geometryPools;
 
     static FdoGeometryThreadData *      GetValue();
     static void                         ReleaseValue();
     static FdoGeometryThreadDataKey     GetKey();
     static void                         SetKey(FdoGeometryThreadDataKey key);
+    static FdoFgfGeometryPools *        GetPoolsNoRef();
 };
 
 #endif

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -23,16 +23,18 @@
 #include "LineString.h"
 #include "Util.h"
 #include <Geometry/DirectPositionImpl.h>
+#include "GeometryThreadData.h"
 
 
 /************************************************************************/
 /* Constructor                                                                     */
 /************************************************************************/
 FdoFgfLineString::FdoFgfLineString(
-    FdoFgfGeometryFactory * factory, 
+    FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools, 
     FdoDirectPositionCollection* positions
     )
-    : FdoFgfGeometryImpl<FdoILineString>(factory), m_previousPositionIndex(-1)
+    : FdoFgfGeometryImpl<FdoILineString>(factory, pools), m_previousPositionIndex(-1)
 {
     Reset(positions);
 }
@@ -45,7 +47,7 @@
                                                                L"FdoFgfLineString::Reset",
                                                                L"positions"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
     m_previousPositionIndex = -1;
 
@@ -76,11 +78,12 @@
 /************************************************************************/
 FdoFgfLineString::FdoFgfLineString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoInt32 dimensionType,
     FdoInt32 numOrdinates,
     double * ordinates
     )
-    : FdoFgfGeometryImpl<FdoILineString>(factory), m_previousPositionIndex(-1)
+    : FdoFgfGeometryImpl<FdoILineString>(factory, pools), m_previousPositionIndex(-1)
 {
     Reset(dimensionType, numOrdinates, ordinates);
 }
@@ -91,7 +94,7 @@
 		 (NULL == ordinates) )
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_2_BADPARAMETER)));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
     m_previousPositionIndex = -1;
 
@@ -114,11 +117,12 @@
 /************************************************************************/
 FdoFgfLineString::FdoFgfLineString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoILineString>(factory), m_previousPositionIndex(-1)
+    : FdoFgfGeometryImpl<FdoILineString>(factory, pools), m_previousPositionIndex(-1)
 {
     Reset(byteArray, data, count);
 }
@@ -229,7 +233,8 @@
 
 	FGFUTIL_SKIP_DIRECTPOSITIONS(&m_streamPtr, m_streamEnd, numOrdsPerPos, index);
 
-	FdoPtr<FdoIDirectPosition> pos = FgfUtil::ReadDirectPosition(m_factory, dimension, &m_streamPtr, m_streamEnd);
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+	FdoPtr<FdoIDirectPosition> pos = FgfUtil::ReadDirectPosition(gf, dimension, &m_streamPtr, m_streamEnd);
 
 	return FDO_SAFE_ADDREF(pos.p);
 }
@@ -330,6 +335,7 @@
 
 void FdoFgfLineString::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(LineString);
 }
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LineString.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -38,13 +38,13 @@
      */
 
 	// Copy the positions.  Dimensionality is taken from the first position.
-	FdoFgfLineString(FdoFgfGeometryFactory * factory, FdoDirectPositionCollection* positions);
+	FdoFgfLineString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoDirectPositionCollection* positions);
 
 	// Copy the ordinates.
-	FdoFgfLineString(FdoFgfGeometryFactory * factory, FdoInt32 dimensionType, FdoInt32 numOrdinates, double* ordinates);
+	FdoFgfLineString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoInt32 dimensionType, FdoInt32 numOrdinates, double* ordinates);
 
 	// (internal use) Just latch onto the data stream.
-	FdoFgfLineString(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfLineString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructors.
 	void Reset(FdoDirectPositionCollection* positions);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -19,7 +19,8 @@
 
 
 #include "LinearRing.h"
-#include "GeometryFactory2.h"
+#include "GeometryThreadData.h"
+#include "Util.h"
 
 
 /************************************************************************/
@@ -27,9 +28,11 @@
 /************************************************************************/
 FdoFgfLinearRing::FdoFgfLinearRing(
     FdoFgfGeometryFactory * factory, 
+    FdoFgfGeometryPools * pools,
     FdoInt32 dimensionType,
     FdoInt32 numOrdinates,
     double* ordinates)
+    : m_pools(pools)
 {
 	if ( (NULL == ordinates) ||
 		 (NULL == factory) )
@@ -81,7 +84,9 @@
 /************************************************************************/
 FdoFgfLinearRing::FdoFgfLinearRing(
     FdoFgfGeometryFactory * factory, 
+    FdoFgfGeometryPools * pools,
     FdoDirectPositionCollection* positions)
+    : m_pools(pools)
 {
     if ( NULL == positions || positions->GetCount() < 3)
 		throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_CREATION),
@@ -278,6 +283,6 @@
 /************************************************************************/
 void FdoFgfLinearRing::Dispose()
 {
-	delete this;
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(LinearRing);
 }
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/LinearRing.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -24,6 +24,7 @@
 #include <Geometry/ILinearRing.h>
 #include <Geometry/ILineString.h>
 
+class FdoFgfGeometryPools;  // Forward declaration
 class FdoFgfGeometryFactory;   // Forward declaration
 
 
@@ -35,8 +36,8 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfLinearRing(FdoFgfGeometryFactory * factory, FdoInt32 dimensionType, FdoInt32 numOrdinates, double* ordinates);
-	FdoFgfLinearRing(FdoFgfGeometryFactory * factory, FdoDirectPositionCollection* positions);
+	FdoFgfLinearRing(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoInt32 dimensionType, FdoInt32 numOrdinates, double* ordinates);
+	FdoFgfLinearRing(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoDirectPositionCollection* positions);
 
 	virtual ~FdoFgfLinearRing();
 
@@ -61,12 +62,12 @@
 	FdoFgfLinearRing() {}; // Default constructor to satisfy FdoPtr on Linux
 
 	FdoPtr<FdoILineString>	m_lineString;
+    FdoFgfGeometryPools *   m_pools;  // Geometry pools (lightweight to avoid circular reference)
 
 	bool IsClosed(FdoInt32 dimensionality, FdoInt32 numOrdinates, double* ordinates) const;
 
 	void Dispose();
 
-
 };
 #endif
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -20,15 +20,17 @@
 #include "MultiCurvePolygon.h"
 #include "Util.h"
 #include <Geometry/EnvelopeImpl.h>
+#include "GeometryFactory2.h"
 
 /************************************************************************/
 /* Constructor                                                                     */
 /************************************************************************/
 FdoFgfMultiCurvePolygon::FdoFgfMultiCurvePolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoCurvePolygonCollection* curvePolygons
     )
-    : FdoFgfGeometryImpl<FdoIMultiCurvePolygon>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiCurvePolygon>(factory, pools)
 {
 	if ( (NULL == curvePolygons) ||
          (0 == curvePolygons->GetCount()) ||
@@ -37,7 +39,7 @@
                                                                L"FdoFgfMultiCurvePolygon",
                                                                L"curvePolygons/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
     // FdoGeometryType
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_MultiCurvePolygon);
@@ -60,11 +62,12 @@
 
 FdoFgfMultiCurvePolygon::FdoFgfMultiCurvePolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIMultiCurvePolygon>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiCurvePolygon>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -142,8 +145,10 @@
 {
 	m_streamPtr = m_data;
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
     FdoPtr<FdoIGeometry> geometry =
-        FgfUtil::ReadGeometryFromAggregate(m_factory, Index, FdoGeometryType_CurvePolygon, &m_streamPtr, m_streamEnd);
+        FgfUtil::ReadGeometryFromAggregate(gf, Index, FdoGeometryType_CurvePolygon, &m_streamPtr, m_streamEnd);
 
     // Smart pointer assignments have problems with non-identical types.  Work around...
     FdoICurvePolygon * derivedGeometry = static_cast<FdoICurvePolygon *>(geometry.p);
@@ -157,7 +162,8 @@
 /************************************************************************/
 void FdoFgfMultiCurvePolygon::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(MultiCurvePolygon);
 }
 
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurvePolygon.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,13 +33,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfMultiCurvePolygon(FdoFgfGeometryFactory * factory, FdoCurvePolygonCollection* curvePolygons);
+	FdoFgfMultiCurvePolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoCurvePolygonCollection* curvePolygons);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfMultiCurvePolygon(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfMultiCurvePolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -29,9 +29,10 @@
 /************************************************************************/
 FdoFgfMultiCurveString::FdoFgfMultiCurveString(
     FdoFgfGeometryFactory * factory, 
+    FdoFgfGeometryPools * pools,
     FdoCurveStringCollection* curveStrings
     )
-    : FdoFgfGeometryImpl<FdoIMultiCurveString>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiCurveString>(factory, pools)
 {
 	if ( (NULL == curveStrings) ||
          (0 == curveStrings->GetCount()) )
@@ -39,7 +40,7 @@
                                                                L"FdoFgfMultiCurveString",
                                                                L"curveStrings"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	// FdoGeometryType
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_MultiCurveString);
@@ -61,11 +62,12 @@
 
 FdoFgfMultiCurveString::FdoFgfMultiCurveString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIMultiCurveString>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiCurveString>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -143,8 +145,10 @@
 {
 	m_streamPtr = m_data;
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
     FdoPtr<FdoIGeometry> geometry =
-        FgfUtil::ReadGeometryFromAggregate(m_factory, Index, FdoGeometryType_CurveString, &m_streamPtr, m_streamEnd);
+        FgfUtil::ReadGeometryFromAggregate(gf, Index, FdoGeometryType_CurveString, &m_streamPtr, m_streamEnd);
 
     // Smart pointer assignments have problems with non-identical types.  Work around...
     FdoICurveString * derivedGeometry = static_cast<FdoICurveString *>(geometry.p);
@@ -158,7 +162,8 @@
 /************************************************************************/
 void FdoFgfMultiCurveString::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(MultiCurveString);
 }
 
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiCurveString.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,13 +33,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfMultiCurveString(FdoFgfGeometryFactory * factory, FdoCurveStringCollection* curveStrings);
+	FdoFgfMultiCurveString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoCurveStringCollection* curveStrings);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfMultiCurveString(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfMultiCurveString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -44,9 +44,10 @@
 /************************************************************************/
 FdoFgfMultiGeometry::FdoFgfMultiGeometry(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoGeometryCollection* geometries
     )
-    : FdoFgfGeometryImpl<FdoIMultiGeometry>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiGeometry>(factory, pools)
 {
 	if ( (NULL == geometries) ||
          (0 == geometries->GetCount()) ||
@@ -55,7 +56,7 @@
                                                                L"FdoFgfMultiGeometry",
                                                                L"geometries/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
     FdoInt32 numGeometries = geometries->GetCount();
 
@@ -74,11 +75,12 @@
 
 FdoFgfMultiGeometry::FdoFgfMultiGeometry(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIMultiGeometry>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiGeometry>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -158,8 +160,10 @@
 {
 	m_streamPtr = m_data;
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
     FdoPtr<FdoIGeometry> geometry =
-        FgfUtil::ReadGeometryFromAggregate(m_factory, Index, FdoGeometryType_None, &m_streamPtr, m_streamEnd);
+        FgfUtil::ReadGeometryFromAggregate(gf, Index, FdoGeometryType_None, &m_streamPtr, m_streamEnd);
 
     return FDO_SAFE_ADDREF(geometry.p);
 }
@@ -170,7 +174,8 @@
 /************************************************************************/
 void FdoFgfMultiGeometry::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(MultiGeometry);
 }
 
 /************************************************************************/

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiGeometry.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,13 +33,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfMultiGeometry(FdoFgfGeometryFactory * factory, FdoGeometryCollection* geometries);
+	FdoFgfMultiGeometry(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoGeometryCollection* geometries);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfMultiGeometry(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfMultiGeometry(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -21,6 +21,7 @@
 #include "LineString.h"
 #include <Geometry/EnvelopeImpl.h>
 #include "Util.h"
+#include "GeometryFactory2.h"
 
 
 /************************************************************************/
@@ -28,9 +29,10 @@
 /************************************************************************/
 FdoFgfMultiLineString::FdoFgfMultiLineString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoLineStringCollection* lineStrings
     )
-    : FdoFgfGeometryImpl<FdoIMultiLineString>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiLineString>(factory, pools)
 {
 	if ( (NULL == lineStrings) ||
          (0 == lineStrings->GetCount()) ||
@@ -39,7 +41,7 @@
                                                                L"FdoFgfMultiLineString",
                                                                L"lineStrings/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	// FdoGeometryType
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_MultiLineString);
@@ -61,11 +63,12 @@
 
 FdoFgfMultiLineString::FdoFgfMultiLineString(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIMultiLineString>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiLineString>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -140,8 +143,10 @@
 {
 	m_streamPtr = m_data;
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
     FdoPtr<FdoIGeometry> geometry =
-        FgfUtil::ReadGeometryFromAggregate(m_factory, Index, FdoGeometryType_LineString, &m_streamPtr, m_streamEnd);
+        FgfUtil::ReadGeometryFromAggregate(gf, Index, FdoGeometryType_LineString, &m_streamPtr, m_streamEnd);
 
     // Smart pointer assignments have problems with non-identical types.  Work around...
     FdoILineString * derivedGeometry = static_cast<FdoILineString *>(geometry.p);
@@ -155,7 +160,8 @@
 /************************************************************************/
 void FdoFgfMultiLineString::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(MultiLineString);
 }
 
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiLineString.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -34,13 +34,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfMultiLineString(FdoFgfGeometryFactory * factory, FdoLineStringCollection* lineStrings);
+	FdoFgfMultiLineString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoLineStringCollection* lineStrings);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfMultiLineString(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfMultiLineString(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -21,6 +21,7 @@
 #include <Geometry/DirectPositionImpl.h>
 #include <Geometry/EnvelopeImpl.h>
 #include "Util.h"
+#include "GeometryFactory2.h"
 
 
 /************************************************************************/
@@ -28,11 +29,12 @@
 /************************************************************************/
 FdoFgfMultiPoint::FdoFgfMultiPoint(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoInt32 dimensionality,
     FdoInt32 numOrdinates, 
     double* ordinates
     )
-    : FdoFgfGeometryImpl<FdoIMultiPoint>(factory),
+    : FdoFgfGeometryImpl<FdoIMultiPoint>(factory, pools),
       m_ordinates(NULL)
 {
 	if ( (NULL == ordinates) ||
@@ -41,7 +43,7 @@
                                                                L"FdoFgfMultiPoint",
                                                                L"ordinates/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	FdoPtr<FdoDirectPositionImpl> pos = FdoDirectPositionImpl::Create();
 	pos->SetDimensionality(dimensionality);
@@ -79,9 +81,10 @@
 /************************************************************************/
 FdoFgfMultiPoint::FdoFgfMultiPoint(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoPointCollection* points
     )
-    : FdoFgfGeometryImpl<FdoIMultiPoint>(factory),
+    : FdoFgfGeometryImpl<FdoIMultiPoint>(factory, pools),
       m_ordinates(NULL)
 {
 	if ( (NULL == points) ||
@@ -91,7 +94,7 @@
                                                                L"FdoFgfMultiPoint",
                                                                L"points/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_MultiPoint);
 
@@ -114,11 +117,12 @@
 
 FdoFgfMultiPoint::FdoFgfMultiPoint(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIMultiPoint>(factory),
+    : FdoFgfGeometryImpl<FdoIMultiPoint>(factory, pools),
       m_ordinates(NULL)
 {
     Reset(byteArray, data, count);
@@ -152,7 +156,8 @@
 /************************************************************************/
 void FdoFgfMultiPoint::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(MultiPoint);
 }
 
 /************************************************************************/
@@ -192,8 +197,10 @@
 {
 	m_streamPtr = m_data;
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
     FdoPtr<FdoIGeometry> geometry =
-        FgfUtil::ReadGeometryFromAggregate(m_factory, Index, FdoGeometryType_Point, &m_streamPtr, m_streamEnd);
+        FgfUtil::ReadGeometryFromAggregate(gf, Index, FdoGeometryType_Point, &m_streamPtr, m_streamEnd);
 
     // Smart pointer assignments have problems with non-identical types.  Work around...
     FdoIPoint * derivedGeometry = static_cast<FdoIPoint *>(geometry.p);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPoint.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,14 +33,14 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfMultiPoint(FdoFgfGeometryFactory * factory, FdoInt32 dimensionality, FdoInt32 numOrdinates, double* ordinates);
-	FdoFgfMultiPoint(FdoFgfGeometryFactory * factory, FdoPointCollection* points);
+	FdoFgfMultiPoint(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoInt32 dimensionality, FdoInt32 numOrdinates, double* ordinates);
+	FdoFgfMultiPoint(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoPointCollection* points);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfMultiPoint(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfMultiPoint(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -20,6 +20,7 @@
 #include "MultiPolygon.h"
 #include <Geometry/EnvelopeImpl.h>
 #include "Util.h"
+#include "GeometryFactory2.h"
 
 
 /************************************************************************/
@@ -27,9 +28,10 @@
 /************************************************************************/
 FdoFgfMultiPolygon::FdoFgfMultiPolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoPolygonCollection* polygons
     )
-    : FdoFgfGeometryImpl<FdoIMultiPolygon>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiPolygon>(factory, pools)
 {
 	if ( (NULL == polygons) ||
          (0 == polygons->GetCount()) ||
@@ -38,7 +40,7 @@
                                                                L"FdoFgfMultiPolygon",
                                                                L"polygons/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
     FdoInt32 numPolygons = polygons->GetCount();
 
@@ -57,11 +59,12 @@
 
 FdoFgfMultiPolygon::FdoFgfMultiPolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIMultiPolygon>(factory)
+    : FdoFgfGeometryImpl<FdoIMultiPolygon>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -137,8 +140,10 @@
 {
     m_streamPtr = m_data;
 
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+
     FdoPtr<FdoIGeometry> geometry =
-        FgfUtil::ReadGeometryFromAggregate(m_factory, Index, FdoGeometryType_Polygon, &m_streamPtr, m_streamEnd);
+        FgfUtil::ReadGeometryFromAggregate(gf, Index, FdoGeometryType_Polygon, &m_streamPtr, m_streamEnd);
 
     // Smart pointer assignments have problems with non-identical types.  Work around...
     FdoIPolygon * derivedGeometry = static_cast<FdoIPolygon *>(geometry.p);
@@ -152,7 +157,8 @@
 /************************************************************************/
 void FdoFgfMultiPolygon::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(MultiPolygon);
 }
 
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/MultiPolygon.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -33,13 +33,13 @@
      * Constructors matching public factory methods.
      */
 
-	FdoFgfMultiPolygon(FdoFgfGeometryFactory * factory, FdoPolygonCollection* polygons);
+	FdoFgfMultiPolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoPolygonCollection* polygons);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfMultiPolygon(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfMultiPolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -22,6 +22,7 @@
 #include <Geometry/DirectPositionImpl.h>
 #include <Geometry/EnvelopeImpl.h>
 #include "Util.h"
+#include "GeometryThreadData.h"
 
 
 /************************************************************************/
@@ -29,10 +30,11 @@
 /************************************************************************/
 FdoFgfPoint::FdoFgfPoint(
         FdoFgfGeometryFactory * factory,
+        FdoFgfGeometryPools * pools,
         FdoInt32 dimensionType,
         double* ordinates
         )
-    : FdoFgfGeometryImpl<FdoIPoint>(factory)
+    : FdoFgfGeometryImpl<FdoIPoint>(factory, pools)
 {
 	if ( (NULL == factory) ||
 		 (NULL == ordinates) )
@@ -41,7 +43,7 @@
                                                                L"ordinates/factory"));
 
     // Cannot use smart pointer for updating a FdoArray.
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_Point);
 	FGFUTIL_WRITE_INT32(&newByteArray, dimensionType);
@@ -60,9 +62,10 @@
 /************************************************************************/
 FdoFgfPoint::FdoFgfPoint(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoIDirectPosition* position
     )
-    : FdoFgfGeometryImpl<FdoIPoint>(factory)
+    : FdoFgfGeometryImpl<FdoIPoint>(factory, pools)
 {
 	if ( (NULL == factory) ||
 		 (NULL == position) )
@@ -70,7 +73,7 @@
                                                                L"FdoFgfPoint",
                                                                L"position/factory"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_Point);
 	FGFUTIL_WRITE_INT32(&newByteArray, position->GetDimensionality());
@@ -82,11 +85,12 @@
 
 FdoFgfPoint::FdoFgfPoint(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIPoint>(factory)
+    : FdoFgfGeometryImpl<FdoIPoint>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -118,7 +122,8 @@
 	FdoInt32 dimensionality = GetDimensionality();
 	m_streamPtr = m_data;
 	FGFUTIL_SKIP_INT32S(&m_streamPtr, m_streamEnd, 2);      // Skip over geomtype and dimtype
-    return FgfUtil::ReadDirectPosition(m_factory, dimensionality, &m_streamPtr, m_streamEnd);
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+    return FgfUtil::ReadDirectPosition(gf, dimensionality, &m_streamPtr, m_streamEnd);
 }
 
 void FdoFgfPoint::GetPositionByMembers(double *x, double *y, double *z, double *m, FdoInt32 *dimensionality) const
@@ -180,6 +185,7 @@
 /************************************************************************/
 void FdoFgfPoint::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(Point);
 }
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Point.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -34,17 +34,17 @@
      */
 
 	// Copy the ordinates.
-	FdoFgfPoint(FdoFgfGeometryFactory * factory, FdoInt32 dimensionType, double* ordinates);
+	FdoFgfPoint(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoInt32 dimensionType, double* ordinates);
 
 	//	Copy from a DirectPosition
-	FdoFgfPoint(FdoFgfGeometryFactory * factory, FdoIDirectPosition* position);
+	FdoFgfPoint(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoIDirectPosition* position);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
 	// Just latch onto the data stream.
-	FdoFgfPoint(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfPoint(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -21,6 +21,7 @@
 #include "LinearRing.h"
 #include <Geometry/EnvelopeImpl.h>
 #include "Util.h"
+#include "GeometryFactory2.h"
 
 
 /************************************************************************/
@@ -28,17 +29,18 @@
 /************************************************************************/
 FdoFgfPolygon::FdoFgfPolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoILinearRing* exteriorRing,
     FdoLinearRingCollection* interiorRings
     )
-    : FdoFgfGeometryImpl<FdoIPolygon>(factory)
+    : FdoFgfGeometryImpl<FdoIPolygon>(factory, pools)
 {
 	if (NULL == exteriorRing)
 		throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_CREATION),
                                                                L"FdoFgfPolygon",
                                                                L"exteriorRing"));
 
-    FdoByteArray * newByteArray = m_factory->GetByteArray();
+    FdoByteArray * newByteArray = FgfUtil::GetPoolsNoRef(m_pools)->GetByteArray();
 
 	// FdoGeometryType
 	FGFUTIL_WRITE_INT32(&newByteArray, FdoGeometryType_Polygon);
@@ -67,11 +69,12 @@
 
 FdoFgfPolygon::FdoFgfPolygon(
     FdoFgfGeometryFactory * factory,
+    FdoFgfGeometryPools * pools,
     FdoByteArray * byteArray,
     const FdoByte * data,
     FdoInt32 count
     )
-    : FdoFgfGeometryImpl<FdoIPolygon>(factory)
+    : FdoFgfGeometryImpl<FdoIPolygon>(factory, pools)
 {
     Reset(byteArray, data, count);
 }
@@ -99,7 +102,8 @@
 /************************************************************************/
 void FdoFgfPolygon::Dispose()
 {
-	delete this;
+    SurrenderByteArray();
+    FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(Polygon);
 }
 
 
@@ -229,7 +233,8 @@
 	double * ords = (double *)(*inputStream);
     *inputStream += numBytes;
 
-    FdoPtr<FdoILinearRing> lRing = m_factory->CreateLinearRing(dimensionality, numOrds, ords);
+    FdoPtr<FdoFgfGeometryFactory> gf = GetFactory();
+    FdoPtr<FdoILinearRing> lRing = gf->CreateLinearRing(dimensionality, numOrds, ords);
 
 	return FDO_SAFE_ADDREF(lRing.p);
 }

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Polygon.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -34,13 +34,13 @@
      */
 
 	// Copy the rings.
-	FdoFgfPolygon(FdoFgfGeometryFactory * factory, FdoILinearRing* exteriorRing, FdoLinearRingCollection* interiorRings);
+	FdoFgfPolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoILinearRing* exteriorRing, FdoLinearRingCollection* interiorRings);
 
     /*
      * Constructors supporting internal needs of this package.
      */
 
-	FdoFgfPolygon(FdoFgfGeometryFactory * factory, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
+	FdoFgfPolygon(FdoFgfGeometryFactory * factory, FdoFgfGeometryPools * pools, FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);
 
     // Support object re-use, matching the constructor.
 	void Reset(FdoByteArray * byteArray, const FdoByte * data, FdoInt32 count);

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Pool.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Pool.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Pool.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -26,156 +26,135 @@
 
 #include <Common/Collection.h>
 
-#define GET_REFCOUNT(obj)   ((obj)->GetRefCount())
-
 /// <library>FdoGeometry.lib</library>
 
-/// <summary>FdoPool supports a fixed-size cache of objects.  Because this type extends
-/// FdoCollection, the cached objects must descend from FdoIDisposable.
+/// <summary>
+/// FdoPool supports a fixed-size pool of instantiated objects.  This is
+/// appropriate for writing high-performance code in a style that would
+/// normally involve many expensive heap interactions.
 /// </summary>
+/// <remarks>
+/// Don't panic.  This template just augments FdoCollection with two new methods
+/// to use it as a stack.  Some handy macros are provided to simplify calling
+/// code.
+///
+/// An FdoPool can be used in two distinct ways:
+/// <ol>
+/// <li> The pool owner can manually control it.  Contained objects
+/// do not control being pooled.
+/// <li> The pool owner can set it up and fetch from it, but the objects
+/// add themselves to it when warranted.
+/// </ol>
+/// The conventions for pooled objects are:
+/// <ol>
+/// <li> Support the required methods of FdoIDisposable -- 
+/// AddRef, Release, GetRefCount and Dispose().  Actually deriving from
+/// FdoIDisposable is not required.
+/// <li> Support at least one method to reset the object for re-use, possibly
+/// with parameters matching the object's constructors.  Ideally, the matching
+/// constructor would just call the matching reset method too.
+/// <li> If the object-adds-itself approach is used, Dispose() should try
+/// calling FdoPool's "AddItem" method before using "delete".
+/// E.g. "if (!myPool->AddItem(this)) delete this;".
+/// To support this, the object should either keep a lightweight pointer to
+/// its pool, or use thread-local storage for the pool.
+/// </ol>
+/// 
+/// See the FDOPOOL_* macros below, which  provide some shorthand for using
+/// pools in calling code.
+/// </remarks>
 template <class OBJ, class EXC> class FdoPool : public FdoCollection <OBJ, EXC>
 {
 public:
-    ///<summary>Find a re-usable item from the cache, if cache is full.</summary>
+    ///<summary>Find a re-usable item from the pool.</summary>
     /// <remarks> 
-    /// This method actually tries NOT to find a re-usable item, so that the cache
-    /// can fill up with them during heavy use.  A re-usable item
-    /// is one which only the cache owns (its reference count is 1).  This method will 
-    /// behave as follows (in order):
-	/// <ol>
-    /// <li> If the cache is not full, it returns NULL.
-    /// <li> If the cache is full, but a re-usable item is found, that item is returned,
-    /// and is RELEASED from the cache.
-    /// <li> If the cache is full with non-re-usable items, NULL is returned.
-	/// </ol>
+    /// This method finds a re-usable item in the pool, if there is one.
+    /// It returns NULL if there are none available.
     ///
     /// From the caller's perspective, receiving NULL from this method should be
     /// followed by the creation of a new object; receiving a re-usable item from this 
-    /// method should be followed by whatever is required to re-use the object.  In BOTH
-    /// cases, the caller should call AddItem() to put the object back into the cache.
+    /// method should be followed by calling the appropriate "reset" method, if that
+    /// convention has been followed.
     ///
-    /// Performance will be best if interaction with this class is one object at a time, 
-    /// i.e. call FindReusableItem() and then AddItem() for the same object.
-    ///
-    /// When returning a re-usable object, this method releases it from the cache in order
-    /// to give the caller unshared ownership.  This allows the caller full authority
-    /// to change the object's state as needed, or even to re-allocate it if this is later
-    /// found to be necessary.
+    /// When returning a re-usable object, this method releases it from the pool in order
+    /// to give the caller unshared ownership.  This method will ONLY return an object
+    /// that is unshared.
     /// </remarks>
-    /// <returns>A re-usable item from the cache, or NULL if the caller should create a new object.</returns> 
+    /// <returns>A re-usable item from the pool, or NULL if the caller should create a new object.</returns> 
     virtual OBJ* FindReusableItem()
     {
-        FdoInt32 freeIndex = -1;
-        FdoInt32 reusableIndex = -1;
-        FdoInt32 startIndex = m_LastVisitedIndex+1;
-        FdoPtr<OBJ> reusableItem;
-        FdoInt32 count = FdoCollection <OBJ, EXC>::GetCount();
+        OBJ * reusableItem = NULL;
+        FdoInt32 count = FdoCollection<OBJ, EXC>::GetCount();
+        FdoInt32 reusableIndex = count - 1;
 
-        // Nothing notably clever here -- linear search for re-usable item, also
-        // noting a free entry, if found.
-        for (FdoInt32 i=startIndex;  -1 == reusableIndex && i < count;  i++)
+        // Search backwards from the end of the collection.
+        // Get rid of any NULL or shared entries; they only would have gotten
+        // here due to a caller's activities that are not appropriate for pooling.
+
+        while ( reusableIndex >= 0 &&
+                NULL == reusableItem )
         {
-            FdoPtr<OBJ> candidate = FdoCollection<OBJ, EXC>::GetItem(i);
-            if (candidate != NULL && -1 == reusableIndex && 2 == GET_REFCOUNT(candidate.p))   // '2' == 1 for cache + 1 for 'candidate'
+            reusableItem = FdoCollection<OBJ, EXC>::GetItem(reusableIndex);
+
+            if (NULL != reusableItem && reusableItem->GetRefCount() > 2)
             {
-                reusableIndex = i;
-                reusableItem = candidate;
+                // Item is shared.
+                reusableItem->Release();
+                reusableItem = NULL;
             }
-            else if (candidate == NULL && -1 == freeIndex)
-            {
-                freeIndex = i;
-            }
+            FdoCollection<OBJ, EXC>::RemoveAt(reusableIndex);
+            reusableIndex--;
         }
-        for (FdoInt32 i=0;  -1 == reusableIndex && i < startIndex;  i++)
-        {
-            FdoPtr<OBJ> candidate = FdoCollection<OBJ, EXC>::GetItem(i);
-            if (candidate != NULL && -1 == reusableIndex && 2 == GET_REFCOUNT(candidate.p))   // '2' == 1 for cache + 1 for 'candidate'
-            {
-                reusableIndex = i;
-                reusableItem = candidate;
-            }
-            else if (candidate == NULL && -1 == freeIndex)
-            {
-                freeIndex = i;
-            }
-        }
 
-        if (reusableItem != NULL)
-        {
-            // We found a re-usable item.
-            // Remember where we found it and release our ownership.
-            m_LastVisitedIndex = reusableIndex;
-            FDO_SAFE_ADDREF(reusableItem.p);    // This increases share for the return value.
-            FdoCollection<OBJ, EXC>::SetItem(reusableIndex, NULL);
 #ifdef EXTRA_DEBUG
+        if (NULL != reusableItem)
             m_ReusableHits++;
-#endif
-        }
-        else if (-1 != freeIndex)
-        {
-            // We found an empty entry in the cache.  We'll return NULL,
-            // and internally remember where we found the entry for when
-            // the caller calls AddItem().
-            reusableItem = NULL;
-            m_LastVisitedIndex = freeIndex;
-#ifdef EXTRA_DEBUG
-            m_EmptyHits++;
-#endif
-        }
         else
-        {
-            // We didn't find anything we wanted.  Release the next entry,
-            // effecting a round-robin procedure for a full pool.
-            m_LastVisitedIndex++;
-            if (m_LastVisitedIndex >= count)
-                m_LastVisitedIndex = 0;
-            FdoCollection<OBJ, EXC>::SetItem(m_LastVisitedIndex, NULL);
-#ifdef EXTRA_DEBUG
             m_Misses++;
 #endif
-        }
 
         return reusableItem;
     }
 
-    ///<summary>Adds the specified item to the cache. Depending on the state of the
-    /// cache, this may result in an actual addition to the cache, or the replacement
-    /// of a cache entry.</summary>
+    ///<summary>Adds the specified item to the pool, if there is room.
+    /// </summary>
+    /// <remarks> 
+    /// We do not check for a shared object here, because the caller might still have
+    /// a brief hold on it.  We check later, though, in FindReusableItem().
+    /// </remarks>
     /// <param name="value">Input value</param> 
-    /// <returns>Returns nothing</returns> 
-    virtual void AddItem(OBJ* value)
+    /// <returns>Returns true if the object was added; false otherwise</returns> 
+    virtual bool AddItem(OBJ* value)
     {
-        FdoPtr<OBJ> oldItem = FdoCollection<OBJ, EXC>::GetItem(m_LastVisitedIndex);
-
-        if (oldItem != NULL)
+        bool ret = false;
+        if (m_AllowAdds && value->GetRefCount() <= 1)
         {
-            // The entry is not empty.  The caller didn't precede with
-            // FindReusableItem().  We'll do it anyway, ignoring the 
-            // result and using the intended hint in m_LastVisitedIndex.
-            FdoPtr<OBJ> dummyItem = FindReusableItem();
+            FdoInt32 count = FdoCollection <OBJ, EXC>::GetCount();
+            if (count < m_MaxSize)
+            {
+                FdoCollection <OBJ, EXC>::Add(value);
+                ret = true;
+            }
         }
-
-        FdoCollection<OBJ, EXC>::SetItem(m_LastVisitedIndex, value);
+        return ret;
     }
 
 #ifdef EXTRA_DEBUG
     void GetStats(FdoInt32 * emptyHits, FdoInt32 * reusableHits, FdoInt32 * misses)
     {
-        if (NULL != emptyHits)
-            *emptyHits = m_EmptyHits;
-        if (NULL != emptyHits)
+        if (NULL != reusableHits)
             *reusableHits = m_ReusableHits;
-        if (NULL != emptyHits)
+        if (NULL != misses)
             *misses = m_Misses;
     }
 #endif
 
 protected:
+    // Constructor.  As a debugging aid, m_AllowAdds to false to disable pooling.
     FdoPool( FdoInt32 size )
-        : m_LastVisitedIndex(0)
+        : m_MaxSize(size), m_AllowAdds(true)
 #ifdef EXTRA_DEBUG
-        ,m_EmptyHits(0),
-        m_ReusableHits(0),
+        , m_ReusableHits(0),
         m_Misses(0)
 #endif
     {
@@ -184,24 +163,27 @@
                                                           L"FdoPool",
                                                           L"size"));
 
-        // Set exact size.
+        // FdoCollection doesn't support manual setting of allocation size
+        //, but we can do the same by adding NULL values.
 
-        if (size < FdoCollection <OBJ, EXC>::GetCount())
-            FdoCollection <OBJ, EXC>::Clear();
-
         while (FdoCollection <OBJ, EXC>::GetCount() < size)
             FdoCollection <OBJ, EXC>::Add(NULL);
+
+        // Clear collection for zero size (though allocated space remains).
+        FdoCollection <OBJ, EXC>::Clear();
     }
 
     FdoPool() {} // Default constructor to satisfy FdoPtr on Linux
 
     virtual ~FdoPool(void)
     {
+        m_AllowAdds = false;
+        Clear();
     }
 private:
-    FdoInt32    m_LastVisitedIndex; // Slight performance help, plus guarantees rotating cache.
+    FdoInt32    m_MaxSize;  // Maximum number of objects in the pool.
+    bool        m_AllowAdds;    // Suppress new items (during destruction)
 #ifdef EXTRA_DEBUG
-    FdoInt32    m_EmptyHits;
     FdoInt32    m_ReusableHits;
     FdoInt32    m_Misses;   // No available, re-usable entries.
 #endif
@@ -258,8 +240,6 @@
         ret->resetCall_I; \
     } \
  \
-    (pool_I)->AddItem(ret); \
- \
     return ret; \
 }
 

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.cpp
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -19,7 +19,24 @@
 
 
 #include "Util.h"
-#include "GeometryUtility.h"
+#include "GeometryThreadData.h"
+#include <Geometry/DirectPositionImpl.h>
+#include <Geometry/EnvelopeImpl.h>
+#include "LineString.h"
+#include "Point.h"
+#include "LinearRing.h"
+#include "LineStringSegment.h"
+#include "Polygon.h"
+#include "MultiGeometry.h"
+#include "MultiPoint.h"
+#include "MultiLineString.h"
+#include "MultiPolygon.h"
+#include "CircularArcSegment.h"
+#include "CurveString.h"
+#include "MultiCurveString.h"
+#include "Ring.h"
+#include "CurvePolygon.h"
+#include "MultiCurvePolygon.h"
 
 
 /************************************************************************/
@@ -581,3 +598,14 @@
 	} // of for
 }
 
+FdoFgfGeometryPools * FgfUtil::GetPoolsNoRef(
+          FdoFgfGeometryPools *   privatePools)
+{
+    FdoFgfGeometryPools * pools = privatePools;
+    if (NULL == pools)
+    {
+        FdoGeometryThreadData * threadData = FdoGeometryThreadData::GetValue();
+        pools = threadData->geometryPools;
+    }
+    return pools;
+}

Modified: trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.h
===================================================================
--- trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Fdo/Unmanaged/Src/Geometry/Fgf/Util.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -22,7 +22,9 @@
 #endif
 
 #include <Geometry/GeometryStd.h>
-#include "GeometryFactory2.h"
+#include "GeometryUtility.h"
+#include <Geometry/Fgf/Factory.h>
+class FdoFgfGeometryPools;   // Forward declaration
 
 // Use lots of macros here, rather than inline functions, to force inline expansion
 // of code for performance.
@@ -131,6 +133,17 @@
     (*streamPtr) = FdoByteArray::Append(*(streamPtr), (numValues) * sizeof(double), (FdoByte*) values); \
 }
 
+#define FGFUTIL_DISPOSE_TO_POOL_OR_HEAP(type) \
+{ \
+    FdoFgfGeometryPools * pools = FgfUtil::GetPoolsNoRef(m_pools); \
+    if (NULL == pools || \
+        pools->m_Pool##type == NULL || \
+        !pools->m_Pool##type->AddItem(this)) \
+    { \
+        delete this; \
+    } \
+}
+
 class FgfUtil
 {
 public:
@@ -188,6 +201,12 @@
 
         FGFUTIL_WRITE_DOUBLES(outputStream, numDimensions, ordinates);
     }
+
+    // Get object pools (no ref counting, for performance).
+    static FdoFgfGeometryPools * GetPoolsNoRef(
+          FdoFgfGeometryPools *   privatePools);
+
 };
+
 #endif
 

Modified: trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.cpp
===================================================================
--- trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -23,6 +23,7 @@
 #include "Rd/OraColumnReader.h"
 #include "Rd/DbObjectReader.h"
 #include "Sm/Ph/Rd/DbObjectReader.h"
+#include "Rd/PkeyReader.h"
 #include "ColumnChar.h"
 #include "ColumnBool.h"
 #include "ColumnByte.h"
@@ -265,3 +266,11 @@
     else
         return new FdoSmPhRdOdbcColumnReader( GetManager(), FDO_SAFE_ADDREF(this) );
 }
+
+FdoPtr<FdoSmPhRdPkeyReader> FdoSmPhOdbcDbObject::CreatePkeyReader() const
+{
+    FdoSmPhOdbcDbObject* pDbObject = (FdoSmPhOdbcDbObject*) this;
+
+    return new FdoSmPhRdOdbcPkeyReader( pDbObject->GetManager(), FDO_SAFE_ADDREF(pDbObject) );
+}
+

Modified: trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.h
===================================================================
--- trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/ODBC/SchemaMgr/Ph/DbObject.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -180,6 +180,8 @@
     // Column reader creator implementation.
     virtual FdoPtr<FdoSmPhRdColumnReader> CreateColumnReader();
 
+    virtual FdoPtr<FdoSmPhRdPkeyReader> CreatePkeyReader() const;
+
 protected:
 
     // Overrideable settings:

Modified: trunk/Providers/GenericRdbms/Src/ODBCDriver/users_.c
===================================================================
--- trunk/Providers/GenericRdbms/Src/ODBCDriver/users_.c	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/ODBCDriver/users_.c	2007-02-16 18:43:18 UTC (rev 2550)
@@ -64,6 +64,8 @@
 	int rdbi_status = RDBI_GENERIC_ERROR;
 	int target_set;
     SQLUINTEGER schemaUsages = 0;
+    int schemaUsagesSupported = TRUE;
+    short	_odbcValue = SQL_ERROR;
     // vectors can be used as SQLCHAR
     wchar_t    schemaToGet[10];
     SQLWCHAR    szSchemaBuf[ODBCDR_MAX_BUFF_SIZE];
@@ -96,14 +98,15 @@
 	_check_status;
 
     if (context->odbcdr_UseUnicode){
-        ODBCDR_ODBC_ERR( SQLGetInfoW(connData->hDbc, SQL_SCHEMA_USAGE, (SQLPOINTER)&schemaUsages,
-            0, NULL),SQL_HANDLE_DESC, connData->hDbc, "SQLGetInfo", "Fetching schemas" );
+	    _odbcValue = SQLGetInfoW(connData->hDbc, SQL_SCHEMA_USAGE, (SQLPOINTER)&schemaUsages, 0, NULL);
     }else{
-        ODBCDR_ODBC_ERR( SQLGetInfo(connData->hDbc, SQL_SCHEMA_USAGE, (SQLPOINTER)&schemaUsages,
-            0, NULL),SQL_HANDLE_DESC, connData->hDbc, "SQLGetInfo", "Fetching schemas" );
+        _odbcValue = SQLGetInfo(connData->hDbc, SQL_SCHEMA_USAGE, (SQLPOINTER)&schemaUsages, 0, NULL);
     }
 
-    if (schemaUsages & SQL_SU_DML_STATEMENTS)
+    if (_odbcValue != ODBCDR_SUCCESS)
+        schemaUsagesSupported = FALSE;
+
+    if (schemaUsagesSupported && (schemaUsages & SQL_SU_DML_STATEMENTS))
     {
 	    c = connData->users;
 

Modified: trunk/Providers/GenericRdbms/Src/UnitTest/Common/FdoSqlCmdTest.cpp
===================================================================
--- trunk/Providers/GenericRdbms/Src/UnitTest/Common/FdoSqlCmdTest.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/UnitTest/Common/FdoSqlCmdTest.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -354,10 +354,10 @@
                 break;
 
             case FdoDataType_DateTime:
-                {
-                 FdoDateTime  time = myReader->GetDateTime( name );
-                 DBG(printf("%s ", ctime((const time_t*)&time )));
-                }
+				{
+				 FdoDateTime  time = myReader->GetDateTime( name );
+				 DBG(printf("year=%d, month=%d, day=%d, hour=%d, minute=%d, seconds=%d", time.year, time.month, time.day, time.hour, time.minute, time.seconds));
+				}
                 break;
 
             case FdoDataType_Decimal:

Modified: trunk/Providers/GenericRdbms/Src/UnitTest/MSTest.mdb
===================================================================
(Binary files differ)

Modified: trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcBaseSetup.cpp
===================================================================
--- trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcBaseSetup.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcBaseSetup.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -346,6 +346,8 @@
 	L"( FEATID1, NAME, X, Y )",
 	L" values ",
 	L"( 2, 'His''Name', 20, 25 );",
+    L"",
+	L"create view VIEW1 as select FEATID1, NAME, X, Y from TABLE1;",
 #ifdef _WIN32
     L"",
 	L"create table ALLDBTYPES (",

Modified: trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.cpp
===================================================================
--- trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.cpp	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.cpp	2007-02-16 18:43:18 UTC (rev 2550)
@@ -144,6 +144,55 @@
     }
 }
 
+void OdbcOracleFdoSelectTest::View1Test()
+{
+    if( mConnection != NULL )
+    {
+        try
+        {
+            FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand(FdoCommandType_Select);
+
+            selectCmd->SetFeatureClassName(L"VIEW1");
+
+            FdoPtr<FdoIFeatureReader> reader = selectCmd->Execute();
+
+            FdoPtr<FdoClassDefinition> classDef = reader->GetClassDefinition();
+            CPPUNIT_ASSERT_MESSAGE("Class should not have IsComputed=true", !classDef->GetIsComputed());
+            FdoFeatureSchemaP pSchema =  classDef->GetFeatureSchema(); 
+            FdoPtr<FdoDataPropertyDefinitionCollection> idPropDefs = classDef->GetIdentityProperties();
+            FdoInt32 numIdProps = 0;
+            if (idPropDefs != NULL)
+            {
+                numIdProps = idPropDefs->GetCount();
+                for (FdoInt32 i=0;  i < numIdProps;  i++)
+                {
+                    FdoPtr<FdoDataPropertyDefinition> idPropDef = idPropDefs->GetItem(i);
+                    printf("    Found identity property '%ls'.\n", idPropDef->GetName());
+                }
+                printf("  Found total %d identity properties.\n", numIdProps);
+                CPPUNIT_ASSERT_MESSAGE("Expected no identity properties", 0==numIdProps);
+            }
+
+            // read through all the features
+            int numFeatures = 0;
+            while (reader->ReadNext())
+            {
+                numFeatures++;
+                UnitTestUtil::ProcessFeature(reader);
+            }
+
+            printf("   %i feature(s) read\n", numFeatures);
+
+            // close the reader
+            reader->Close();
+        }
+        catch (FdoException* e)
+        {
+            TestCommonFail (e);
+        }
+    }
+}
+
 void OdbcMySqlFdoSelectTest::ConfigFileTest()
 {
     if( mConnection != NULL ) try
@@ -454,6 +503,114 @@
     }
 }
 
+void OdbcAccessFdoSelectTest::View1Test()
+{
+    if( mConnection != NULL )
+    {
+        try
+        {
+            FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand(FdoCommandType_Select);
+
+            // must set the feature class name
+            FdoStringP fcn = GetSchemaName();
+            fcn += L":";
+            fcn += L"VIEW1";
+            selectCmd->SetFeatureClassName(fcn);
+
+            // execute the command
+            FdoPtr<FdoIFeatureReader> reader = selectCmd->Execute();
+
+            FdoPtr<FdoClassDefinition> classDef = reader->GetClassDefinition();
+            CPPUNIT_ASSERT_MESSAGE("Class should not have IsComputed=true", !classDef->GetIsComputed());
+            FdoFeatureSchemaP pSchema =  classDef->GetFeatureSchema(); 
+            FdoPtr<FdoDataPropertyDefinitionCollection> idPropDefs = classDef->GetIdentityProperties();
+            FdoInt32 numIdProps = 0;
+            if (idPropDefs != NULL)
+            {
+                numIdProps = idPropDefs->GetCount();
+                for (FdoInt32 i=0;  i < numIdProps;  i++)
+                {
+                    FdoPtr<FdoDataPropertyDefinition> idPropDef = idPropDefs->GetItem(i);
+                    printf("    Found identity property '%ls'.\n", idPropDef->GetName());
+                }
+                printf("  Found total %d identity properties.\n", numIdProps);
+                CPPUNIT_ASSERT_MESSAGE("Expected no identity properties", 0==numIdProps);
+            }
+
+            // read through all the features
+            int numFeatures = 0;
+            while (reader->ReadNext())
+            {
+                numFeatures++;
+                UnitTestUtil::ProcessFeature(reader);
+            }
+
+            printf("   %i feature(s) read\n", numFeatures);
+
+            // close the reader
+            reader->Close();
+        }
+        catch (FdoException* e)
+        {
+            TestCommonFail (e);
+        }
+    }
+}
+
+void OdbcAccessFdoSelectTest::View2Test()
+{
+    if( mConnection != NULL )
+    {
+        try
+        {
+            FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand(FdoCommandType_Select);
+
+            // must set the feature class name
+            FdoStringP fcn = GetSchemaName();
+            fcn += L":";
+            fcn += L"VIEW2";
+            selectCmd->SetFeatureClassName(fcn);
+
+            // execute the command
+            FdoPtr<FdoIFeatureReader> reader = selectCmd->Execute();
+
+            FdoPtr<FdoClassDefinition> classDef = reader->GetClassDefinition();
+            CPPUNIT_ASSERT_MESSAGE("Class should not have IsComputed=true", !classDef->GetIsComputed());
+            FdoFeatureSchemaP pSchema =  classDef->GetFeatureSchema(); 
+            FdoPtr<FdoDataPropertyDefinitionCollection> idPropDefs = classDef->GetIdentityProperties();
+            FdoInt32 numIdProps = 0;
+            if (idPropDefs != NULL)
+            {
+                numIdProps = idPropDefs->GetCount();
+                for (FdoInt32 i=0;  i < numIdProps;  i++)
+                {
+                    FdoPtr<FdoDataPropertyDefinition> idPropDef = idPropDefs->GetItem(i);
+                    printf("    Found identity property '%ls'.\n", idPropDef->GetName());
+                }
+                printf("  Found total %d identity properties.\n", numIdProps);
+                CPPUNIT_ASSERT_MESSAGE("Expected 1 identity property", 1==numIdProps);
+            }
+
+            // read through all the features
+            int numFeatures = 0;
+            while (reader->ReadNext())
+            {
+                numFeatures++;
+                UnitTestUtil::ProcessFeature(reader);
+            }
+
+            printf("   %i feature(s) read\n", numFeatures);
+
+            // close the reader
+            reader->Close();
+        }
+        catch (FdoException* e)
+        {
+            TestCommonFail (e);
+        }
+    }
+}
+
 void OdbcAccessFdoSelectTest::TestDefect779194()
 {
     if( mConnection != NULL )

Modified: trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.h
===================================================================
--- trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.h	2007-02-16 14:13:32 UTC (rev 2549)
+++ trunk/Providers/GenericRdbms/Src/UnitTest/Odbc/OdbcFdoSelectTest.h	2007-02-16 18:43:18 UTC (rev 2550)
@@ -53,6 +53,7 @@
 class OdbcOracleFdoSelectTest : public OdbcFdoSelectTest
 {
     CPPUNIT_TEST_SUB_SUITE (OdbcOracleFdoSelectTest, OdbcFdoSelectTest);
+    CPPUNIT_TEST (View1Test);
     CPPUNIT_TEST_SUITE_END ();
 
 public:
@@ -85,6 +86,8 @@
 
         TestCommonFeatureCommands::secondComputedIdTest(mConnection, fcn, L"CLASSID");
     }
+
+    virtual void View1Test();
 };
 
 class OdbcMySqlFdoSelectTest : public OdbcFdoSelectTest
@@ -137,7 +140,9 @@
     CPPUNIT_TEST_SUB_SUITE (OdbcAccessFdoSelectTest, OdbcFdoSelectTest);
     CPPUNIT_TEST (TestDefect889655);
     CPPUNIT_TEST (Table1Test);
-    //CPPUNIT_TEST (Table2Test);
+    CPPUNIT_TEST (Table2Test);
+    CPPUNIT_TEST (View1Test);
+    CPPUNIT_TEST (View2Test);
     CPPUNIT_TEST (ComparisonFilterTable1Test);
     CPPUNIT_TEST (RestrictedPropertiesTable1Test);
     CPPUNIT_TEST (TestDateFilter);
@@ -150,6 +155,8 @@
     virtual void Table1Test();
     virtual void TestDefect889655();
     void Table2Test();
+    void View1Test();
+    void View2Test();
     void ComparisonFilterTable1Test();  // Contains a spatial query
     void RestrictedPropertiesTable1Test();
     void TestDefect779194();



More information about the fdo-commits mailing list