/*
 * 
* Copyright (C) 2004-2006  Autodesk, Inc.
* 
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2.1 of the GNU Lesser
* General Public License as published by the Free Software Foundation.
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
* 
 */

#include "Pch.h"
#include "InsertTests.h"

#include <FdoSpatial.h>
#include <FdoCommonFile.h>
#include <ShapeCPG.h> 
#include <ShapeDBF.h> 

#ifdef _WIN32
#define LOCATION L"..\\..\\TestData\\Testing"
#define SCHEMA_NAME L"\\schema.xml"
#define CPG_NAME L"\\Test.cpg"
#define DBG_NAME L"\\Test.dbf"
#else
#define LOCATION L"../../TestData/Testing"
#define SCHEMA_NAME L"/schema.xml"
#define CPG_NAME L"/Test.cpg"
#define DBG_NAME L"/Test.dbf"
#endif

CPPUNIT_TEST_SUITE_REGISTRATION (InsertTests);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION (InsertTests, "InsertTests");

FdoPtr<FdoIConnection> InsertTests::mConnection;

InsertTests::InsertTests (void)
{
}

InsertTests::~InsertTests (void)
{
}

void InsertTests::setUp ()
{
    if (!FdoCommonFile::FileExists (LOCATION))
        FdoCommonFile::MkDir (LOCATION);
    mConnection = ShpTests::GetConnection ();
    ShpTests::sLocation = LOCATION;
    mConnection->SetConnectionString (L"DefaultFileLocation=" LOCATION);
    CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());
}

void InsertTests::tearDown ()
{

    mConnection->Close ();

    // Reopen connection
    mConnection->Open ();

    // Delete old class, if its there:
    TestCommonSchemaUtil::CleanUpClass(mConnection, NULL, L"Test");
    TestCommonSchemaUtil::CleanUpClass(mConnection, NULL, L"Test2");
    TestCommonSchemaUtil::CleanUpClass(mConnection, NULL, L"TestFdoClass");

    mConnection->Close ();
    FDO_SAFE_RELEASE(mConnection.p);

    if (FdoCommonFile::FileExists (LOCATION SCHEMA_NAME))
        FdoCommonFile::Delete (LOCATION SCHEMA_NAME);
    if (FdoCommonFile::FileExists (LOCATION))
        FdoCommonFile::RmDir (LOCATION);
}

void InsertTests::create_schema (FdoGeometricType type, bool elevation, bool measure)
{
    // Delete old class, if its still there:
    TestCommonSchemaUtil::CleanUpClass(mConnection, L"TheSchema", L"Test");
    TestCommonSchemaUtil::CleanUpClass(mConnection, L"TheSchema", L"Test2");
    TestCommonSchemaUtil::CleanUpClass(mConnection, L"TheSchema", L"TestFdoClass");


    // Create the FdoFeatureClass "Test":
    //////////////////////////////////////////////////////////////////////////////////////////////////

    FdoPtr<FdoDataPropertyDefinition> featid = FdoDataPropertyDefinition::Create (L"FeatId", L"integer");
    featid->SetDataType (FdoDataType_Int32);
    featid->SetIsAutoGenerated (true);
    featid->SetNullable (false);

    FdoPtr<FdoDataPropertyDefinition> id = FdoDataPropertyDefinition::Create (L"Id", L"integer");
    id->SetDataType (FdoDataType_Decimal);
    id->SetPrecision(10);
    id->SetScale(0);

    FdoPtr<FdoDataPropertyDefinition> id16 = FdoDataPropertyDefinition::Create (L"IdInt16", L"integer16");
    id16->SetDataType (FdoDataType_Int16);

    FdoPtr<FdoDataPropertyDefinition> id32 = FdoDataPropertyDefinition::Create (L"IdInt32", L"integer32");
    id32->SetDataType (FdoDataType_Int32);

    FdoPtr<FdoDataPropertyDefinition> id64 = FdoDataPropertyDefinition::Create (L"IdInt64", L"integer64");
    id64->SetDataType (FdoDataType_Int64);

    FdoPtr<FdoDataPropertyDefinition> street = FdoDataPropertyDefinition::Create (L"Street", L"text");
    street->SetDataType (FdoDataType_String);
    street->SetLength (64);

    FdoPtr<FdoDataPropertyDefinition> area = FdoDataPropertyDefinition::Create (L"Area", L"decimal");
    area->SetDataType (FdoDataType_Decimal);
    area->SetPrecision(20);
    area->SetScale(8);

    FdoPtr<FdoDataPropertyDefinition> vacant = FdoDataPropertyDefinition::Create (L"Vacant", L"boolean");
    vacant->SetDataType (FdoDataType_Boolean);

    FdoPtr<FdoDataPropertyDefinition> birthday = FdoDataPropertyDefinition::Create (L"Birthday", L"date");
    birthday->SetDataType (FdoDataType_DateTime);

    // build a location geometry property (if requested):
    FdoPtr<FdoGeometricPropertyDefinition> location;
    if (type > 0)
    {
        location = FdoGeometricPropertyDefinition::Create (L"Geometry", L"geometry");
        location->SetGeometryTypes (type);
        location->SetHasElevation (elevation);
        location->SetHasMeasure (measure);
    }

    //// assemble the feature class
    FdoPtr<FdoFeatureClass> feature = FdoFeatureClass::Create (L"Test", L"test class created with apply schema");
    FdoPtr<FdoPropertyDefinitionCollection> properties = feature->GetProperties ();
    FdoPtr<FdoDataPropertyDefinitionCollection> identities = feature->GetIdentityProperties ();
    properties->Add (featid);
    identities->Add (featid);
    properties->Add (id);
    properties->Add (id16);
    properties->Add (id32);
    properties->Add (id64);
    properties->Add (street);
    properties->Add (area);
    properties->Add (vacant);
    properties->Add (birthday);
    if (location)
    {
        properties->Add (location);
        feature->SetGeometryProperty (location);
    }


    // Create the FdoFeatureClass "Test2":  (identical to "Test")
    //////////////////////////////////////////////////////////////////////////////////////////////////

    FdoPtr<FdoFeatureClass> feature2 = FdoFeatureClass::Create (L"Test2", L"test class created with apply schema");
    FdoPtr<FdoPropertyDefinitionCollection> properties2 = feature2->GetProperties ();
    FdoPtr<FdoDataPropertyDefinitionCollection> identities2 = feature2->GetIdentityProperties ();

    FdoPtr<FdoDataPropertyDefinition> featid2 = FdoDataPropertyDefinition::Create (L"FeatId", L"integer");
    featid2->SetDataType (FdoDataType_Int32);
    featid2->SetIsAutoGenerated (true);
    featid2->SetNullable (false);

    FdoPtr<FdoDataPropertyDefinition> id2 = FdoDataPropertyDefinition::Create (L"Id", L"integer");
    id2->SetDataType (FdoDataType_Decimal);
    id2->SetPrecision(10);
    id2->SetScale(0);

    FdoPtr<FdoDataPropertyDefinition> id16_2 = FdoDataPropertyDefinition::Create (L"IdInt16", L"integer16");
    id16_2->SetDataType (FdoDataType_Int16);

    FdoPtr<FdoDataPropertyDefinition> id32_2 = FdoDataPropertyDefinition::Create (L"IdInt32", L"integer32");
    id32_2->SetDataType (FdoDataType_Int32);

    FdoPtr<FdoDataPropertyDefinition> id64_2 = FdoDataPropertyDefinition::Create (L"IdInt64", L"integer64");
    id64_2->SetDataType (FdoDataType_Int64);

    FdoPtr<FdoDataPropertyDefinition> street2 = FdoDataPropertyDefinition::Create (L"Street", L"text");
    street2->SetDataType (FdoDataType_String);
    street2->SetLength (64);

    FdoPtr<FdoDataPropertyDefinition> area2 = FdoDataPropertyDefinition::Create (L"Area", L"decimal");
    area2->SetDataType (FdoDataType_Decimal);
    area2->SetPrecision(20);
    area2->SetScale(8);

    FdoPtr<FdoDataPropertyDefinition> vacant2 = FdoDataPropertyDefinition::Create (L"Vacant", L"boolean");
    vacant->SetDataType (FdoDataType_Boolean);

    FdoPtr<FdoDataPropertyDefinition> birthday2 = FdoDataPropertyDefinition::Create (L"Birthday", L"date");
    birthday2->SetDataType (FdoDataType_DateTime);

    // build a location geometry property
    FdoPtr<FdoGeometricPropertyDefinition> location2;
    if (type > 0)
    {
        location2 = FdoGeometricPropertyDefinition::Create (L"Geometry", L"geometry");
        location2->SetGeometryTypes (type);
        location2->SetHasElevation (elevation);
        location2->SetHasMeasure (measure);
    }

    properties2->Add (featid2);
    identities2->Add (featid2);
    properties2->Add (id2);
    properties2->Add (id16_2);
    properties2->Add (id32_2);
    properties2->Add (id64_2);
    properties2->Add (street2);
    properties2->Add (area2);
    properties2->Add (vacant2);
    properties2->Add (birthday2);
    if (type > 0)
    {
        properties2->Add (location2);
        feature2->SetGeometryProperty (location2);
    }


    // Create the FdoClass "TestFdoClass":
    //////////////////////////////////////////////////////////////////////////////////////////////////

    featid = FdoDataPropertyDefinition::Create (L"FeatId", L"integer");
    featid->SetDataType (FdoDataType_Int32);
    featid->SetIsAutoGenerated (true);
    featid->SetNullable (false);

    id = FdoDataPropertyDefinition::Create (L"Id", L"integer");
    id->SetDataType (FdoDataType_Decimal);
    id->SetPrecision(10);
    id->SetScale(0);

    street = FdoDataPropertyDefinition::Create (L"Street", L"text");
    street->SetDataType (FdoDataType_String);
    street->SetLength (64);

    area = FdoDataPropertyDefinition::Create (L"Area", L"decimal");
    area->SetDataType (FdoDataType_Decimal);
    area->SetPrecision(20);
    area->SetScale(8);

    vacant = FdoDataPropertyDefinition::Create (L"Vacant", L"boolean");
    vacant->SetDataType (FdoDataType_Boolean);

    birthday = FdoDataPropertyDefinition::Create (L"Birthday", L"date");
    birthday->SetDataType (FdoDataType_DateTime);

    //// assemble the feature class
    FdoPtr<FdoClass> fdoclass1 = FdoClass::Create (L"TestFdoClass", L"test class created with apply schema");
    properties = fdoclass1->GetProperties ();
    identities = fdoclass1->GetIdentityProperties ();
    properties->Add (featid);
    identities->Add (featid);
    properties->Add (id);
    properties->Add (street);
    properties->Add (area);
    properties->Add (vacant);
    properties->Add (birthday);


    // Create the new schema:
    //////////////////////////////////////////////////////////////////////////////////////////////////

    FdoPtr<FdoFeatureSchema> schema = FdoFeatureSchema::Create (L"TheSchema", L"test schema");
    FdoPtr<FdoClassCollection> classes = schema->GetClasses ();
    classes->Add (feature);
    classes->Add (feature2);
    classes->Add (fdoclass1);

    FdoPtr<FdoIApplySchema> apply = (FdoIApplySchema*)mConnection->CreateCommand (FdoCommandType_ApplySchema);
    apply->SetFeatureSchema (schema);
    apply->Execute ();
    SaveSchema(mConnection);
}


void InsertTests::insert_with_locale ()
{
    char  locale[50];
    strcpy(locale, setlocale(LC_ALL, ""));
    if (VERBOSE) printf("locale= %s\n", locale);

#ifdef _WIN32
    insert_locale(locale, ".28591", L"88591", L"sgshlweeppa");
    insert_locale(locale, "English", L"1252", L"sgshlweeppa");
    insert_locale(locale, "French", L"1252",  L"\x00E9l\x00E9ments");
    insert_locale(locale, "Japanese", L"932", L"\x30F3\x30C6\x30F3\x30C4\x304C\x3042\x308B\x30C7\x30A3\x30EC\x30AF\x30C8\x30EA");

#else
    insert_locale(locale, "en_US.iso88591", L"88591", L"sgshlweeppa");
    insert_locale(locale, "en_US.utf8", L"UTF-8", L"sgshlweeppa");
    insert_locale(locale, "fr_FR.iso88591", L"88591",  L"\x00E9l\x00E9ments");
    insert_locale(locale, "ja_JP.eucjp", L"EUC", L"\x30F3\x30C6\x30F3\x30C4\x304C\x3042\x308B\x30C7\x30A3\x30EC\x30AF\x30C8\x30EA");
#endif
}


void InsertTests::insert_locale (char *orig_locale, char *new_locale, FdoString *expected_cpg, const wchar_t *a_value )
{
    if (VERBOSE) printf("..locale: %s \n", new_locale);

    try
    {
        setlocale(LC_ALL, new_locale);

        // Creates fileset plus .CPG
        create_schema (FdoGeometricType_Point, true, true);

        int status;

        // This throws exception if not found.
        ShapeCPG  *cpg = new ShapeCPG( LOCATION CPG_NAME, status );

        // This throws exception if not found.
        ShapeDBF  *dbf = new ShapeDBF( LOCATION DBG_NAME );

        FdoString *esriCodepage = (FdoString *)cpg->GetCodePage();
        if (VERBOSE) printf("CPG: %ls\n", (FdoString*)esriCodepage );

#pragma message ("TODO: Test on LINUX. ")

#ifdef _WIN32
        CPPUNIT_ASSERT_MESSAGE ("incorrect value for ESRI codepage", wcscmp( esriCodepage, expected_cpg)==0);
#endif
        delete cpg;

        FdoString *esriCodepage2 = dbf->GetCodePage();
        if (VERBOSE) printf("LDID: %ls\n", (FdoString*)esriCodepage2 );

        // Apparenttly LDID supports code pages <= 1257
        FdoStringP    codepage = FdoStringP(expected_cpg);

#ifdef _WIN32
        if ( codepage.ToLong() <= 1257 )
            CPPUNIT_ASSERT_MESSAGE ("incorrect value for ESRI codepage2", wcscmp( esriCodepage2, expected_cpg)==0);
#endif
        delete dbf;

        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"TheSchema:Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);

        FdoStringP  a_value2 = FdoStringP::Format(L"'%ls'", a_value);
        expression = (FdoValueExpression*)FdoExpression::Parse ((FdoString *)a_value2);
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);

        // Parsing will return a truncated value when decimal separator different from '.'
        //expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"971.456", FdoDataType_Decimal);
        expression = FdoDecimalValue::Create(971.456);

        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);

        // add NULL geometry value:
        FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
        geometry->SetNullValue ();
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);

        // Execute Insert
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        CPPUNIT_ASSERT_MESSAGE("featid should be 1-based", featid==1);


        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"TheSchema:Test");

        reader = select->Execute ();

        while (reader->ReadNext ())
        {

            CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street nullness", !reader->IsNull (L"Street"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (a_value, reader->GetString (L"Street")));
            double area = reader->GetDouble (L"Area");
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", TestCommonMiscUtil::FuzzyEqual(971.456, area));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (a_value, reader->GetString (L"Street")));
            double area = reader->GetDouble (L"Area");
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", TestCommonMiscUtil::FuzzyEqual(971.456, area));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();

        // Restore the locale.  
        setlocale(LC_ALL, orig_locale);
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::wide2multibyte(char *mb, wchar_t *in, int cpgWin, char *cpgLinux)
{        
    // This is a macro!
#ifdef _WIN32
    wide_to_multibyte_cpg(mb,in,cpgWin);
#else
    wide_to_multibyte_cpg(mb,in,cpgLinux);
#endif
}


void InsertTests::wide2mbPerformaceTest()
{
    try
    {
    int N=100000;
    wchar_t in[] = L"\x30F3\x30C6\x30F3\x30C4\x304C\x3042\x308B\x30C7\x30A3\x30EC\x30AF\x30C8\x30EA";

    char    out[200];
    size_t  outsize = 200;

    /////////////// Test setlocale() //////////////////////////

    clock_t start = clock();
    for (int i=0; i < N; i++)
    {
        char save[50];

        char *locale =setlocale(LC_CTYPE, "");
        strcpy(save, locale);
#ifdef _WIN32    
        setlocale(LC_CTYPE, ".51932");
#else
         setlocale(LC_CTYPE, "ja_JP.eucjp");
#endif                                                                                                                          
        wcstombs(out, in, outsize);

        setlocale(LC_CTYPE, save);
    }

    clock_t end = clock();
    double  passed =  (double)(end-start)/CLOCKS_PER_SEC;
    if (VERBOSE) printf("passed wcstombs: %lf (%lf per sec)\n", passed, passed/N);

    /////////////// Wide_to_multibyte_cpg() //////////////////////////
    start = clock();
    for (int i=0; i < N; i++)
    {
        char *mb=NULL;
#ifdef _WIN32
        wide2multibyte(mb,in, 932, NULL);
#else
        wide2multibyte(mb,in, -1, "EUC-JP");
#endif
    }

    end = clock();
    passed =  (double)(end-start)/CLOCKS_PER_SEC;
    if (VERBOSE) printf("passed w2m_cpg: %lf (%lf per sec)\n", passed, passed/N);
    
    /////////////// Test native conversion with codepage
    start = clock();
#ifdef _WIN32
    // Test WideCharToMultiByte() 
    const wchar_t* p = (in);
    size_t s = wcslen (p);
    s++;
    char *mb = (char*)malloc (s * 6);

    for (int i=0; i < N; i++)
    {
        int k = WideCharToMultiByte (
            932, // Japanese
            0,
            p,
            (int)s,
            mb,
            (int)s * 6,
            NULL,
            NULL);
    }
    delete[] mb;
    
    end = clock();
    passed =  (double)(end-start)/CLOCKS_PER_SEC;
    if (VERBOSE) printf("passed WideCharToMultiByte(): %lf (%lf per sec)\n", passed, passed/N);

#else
    /// Test iconv() 
    for (int i=0; i < N; i++)
    {
        iconv_t cd = iconv_open( "EUC-JP", "WCHAR_T"); 
    
        if (cd == (iconv_t)-1)
            CPPUNIT_FAIL ("iconv_open() failed");
    
        size_t  insize = (wcslen(in) + 1)* sizeof(wchar_t);
        size_t  insize2 = insize;
        char  *w = (char *)in;
        char  *mb = (char *)out;
        size_t outsize2 = outsize;
        
        size_t s = iconv(cd, (char**)&w, &insize2, (char**)&mb,
        &outsize2 ); 
        
        iconv_close(cd);

        if (s == (size_t)-1)
            CPPUNIT_FAIL ("iconv() failed");            
    }

    end = clock();
    passed =  (double)(end-start)/CLOCKS_PER_SEC;
    printf("passed iconv: %lf (%lf per sec)\n", passed, passed/N);

#endif
   }
   catch (FdoException* ge) 
   {
           TestCommonFail (ge);
   }
}

struct ddd
{
    union
    {
        FdoInt64 i;
        double     d;
    } val;
};

void InsertTests::insert ()
{
   try
   {
        create_schema (FdoGeometricType_Point, true, true);

        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"TheSchema:Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        // add NULL geometry value:
        FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
        geometry->SetNullValue ();
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        CPPUNIT_ASSERT_MESSAGE("featid should be 1-based", featid==1);

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"TheSchema:Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value as double", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value as int32", 24 == reader->GetInt32 (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value as int64", 24 == reader->GetInt64 (L"Id"));

            CPPUNIT_ASSERT_MESSAGE ("incorrect street nullness", !reader->IsNull (L"Street"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();

        #pragma message ("TODO: What is the bounding box for a shape file with only NullShapes in it?")

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xy ()
{
    try
    {
        create_schema (FdoGeometricType_Point, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"TheSchema:Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        // add real geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XY ( 9.99 18.56 )')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"TheSchema:Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"TheSchema:Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xyz ()
{
    try
    {
        create_schema (FdoGeometricType_Point, true, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"98.3", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-21'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XYZ ( 7171.723 8282.99 65.87)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xym ()
{
    try
    {
        create_schema (FdoGeometricType_Point, false, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"-24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'O''Connor Avenue'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"-8e6", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-10-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with measure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XYM ( 7171.723 8282.99 65.87)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_point_xyzm ()
{
    try
    {
        create_schema (FdoGeometricType_Point, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"00024", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'O\"Connor Avenue'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"8.82828e12", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation and mesaure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XYZM ( 7171.723 8282.99 6824.82 65.87)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xy ()
{
    try
    {
        create_schema (FdoGeometricType_Point, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        // add real geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XY (999000 999000, 929200 928929, 923932 949494)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int count = before->GetCount ();
            int test = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", count == test);
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xyz ()
{
    try
    {
        create_schema (FdoGeometricType_Point, true, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"98.3", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-21'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XYZ (7171.723 8282.99 65.87, 7221.62 8737.82 69.828, 7828.23 8729.25 65.98)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 98.3 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 03 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 21 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xym ()
{
    try
    {
        create_schema (FdoGeometricType_Point, false, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"-24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'O''Connor Avenue'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"-8e6", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-10-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with measure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XYM (7171.723 8282.99 65.87, 7272.82 7987.72 75.76, 7626.82 8925.73 84.89)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", -24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O'Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8e6 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 10 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_points_xyzm ()
{
    try
    {
        create_schema (FdoGeometricType_Point, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"00024", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'O\"Connor Avenue'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"8.82828e12", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation and mesaure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('MULTIPOINT XYZM (7171.723 8282.99 6824.82 65.87, 9929.82 4567.92 8921.88 69.28, 10010.7 9992.929 6278.92 87.90))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"O\"Connor Avenue", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 8.82828e12 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xy ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create (INT_MAX);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'~!@#$%^&*()'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"-8.8282e12", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-2'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MAX == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"~!@#$%^&*()", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8.8282e12 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MAX == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"~!@#$%^&*()", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -8.8282e12 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xyz ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, true, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create (INT_MIN / 10);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'0123456789012345678901234567890123456789012345678901234567890123'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (/*-fNO_DATA*/ 1E38 - 1e-6);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-12-2'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XYZ ( 7171.723 8282.99 52.990, 6824.82 6545.87 57.712, 8920.5 9929.77 62.882)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MIN / 10 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"0123456789012345678901234567890123456789012345678901234567890123", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (1E38 - 1e-6) == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", INT_MIN / 10 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"0123456789012345678901234567890123456789012345678901234567890123", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (1E38 - 1e-6) == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1957 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xym ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"00000", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'2611 Misener Crescent'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (/*fNO_DATA*/ -1E38 + 1e-6);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"TRUE");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1492-12-2'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with measure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XYM ( 7171.723 8282.99 52.990, 6824.82 6545.87 57.712, 8920.5 9929.77 62.882)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 0 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"2611 Misener Crescent", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (-1E38 + 1e-6) == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1492 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 0 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"2611 Misener Crescent", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", (-1E38 + 1e-6) == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 1492 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_line_xyzm ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"100000", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'/<>?.,\"'';:\\|][}{=-'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (-4);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"FALSE");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2048-12-31'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation and measure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XYZM ( 7171.723 8282.99 52.990 9, 6824.82 6545.87 57.712 8, 8920.5 9929.77 62.882 7)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 100000 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"/<>?.,\"';:\\|][}{=-", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -4 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2048 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 31 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 100000 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"/<>?.,\"';:\\|][}{=-", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", -4 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2048 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 12 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 31 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xy ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5108.8 5104.7, 5109 5104, 5109 5105, 5108.8 5104.7))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
         select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xyz ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, true, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XYZ ((5108.8 5104.7 89.002, 5109 5104 93.828, 5109 5105 75.828, 5108.8 5104.7 89.002))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xym ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, false, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XYM ((5108.8 5104.7 89.002, 5109 5104 93.828, 5109 5105 75.828, 5108.8 5104.7 89.002))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_polygon_xyzm ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value with elevation and measure:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('POLYGON XYZM ((5108.8 5104.7 5020.99 89.002, 5109.82 5104.82 5021.88 93.828, 5109.82 5105.61 5024.82 75.828, 5108.8 5104.7 5020.99 89.002))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xy ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XY ((5020.99 89.002, 5124.45 93.78, 5067.62 92.45), (5389.67 88.67, 5690.67 95.78, 5899.89 104.67, 5478.12 101.45))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xyz ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, true, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XYZ ((5020.99 89.002 1004.67, 5124.45 93.78 1289.72, 5067.62 92.45 1182.52), (5389.67 88.67 1156.32, 5690.67 95.78 1178.84, 5899.89 104.67 1172.72, 5478.12 101.45 1901.71))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xym ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XYM ((5020.99 89.002 1004.67, 5124.45 93.78 1289.72, 5067.62 92.45 1182.52), (5389.67 88.67 1156.32, 5690.67 95.78 1178.84, 5899.89 104.67 1172.72, 5478.12 101.45 1901.71))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multilinestring_xyzm ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTILINESTRING XYZM ((5020.99 89.002 1004.67 6.934, 5124.45 93.78 1289.72 7.9192, 5067.62 92.45 1182.52 5.9292), (5389.67 88.67 1156.32 9.78278, 5690.67 95.78 1178.84 8.8383, 5899.89 104.67 1172.72 7.8282, 5478.12 101.45 1901.71 8.626))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xy ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XY (((5100 5230, 5100 5030, 5300 5030, 5300 5230, 5100 5230), (5239 5119, 5239 5141, 5261 5141, 5261 5119, 5239 5119), (5141 5135, 5141 5153, 5159 5153, 5159 5135, 5141 5135)), ((6100 5230, 6100 5030, 6300 5030, 6300 5230, 6100 5230), (6239 5119, 6239 5141, 6261 5141, 6261 5119, 6239 5119), (6141 5135, 6141 5153, 6159 5153, 6159 5135, 6141 5135)))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);

        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();

            FdoPtr<FdoGeometryValue> geometryAfter = FdoGeometryValue::Create(after);

            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xyz ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, true, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XYZ (((5100 5230 21.828, 5100 5030 22.2828, 5300 5030 20.28282, 5300 5230 21.28282, 5100 5230 21.828), (5239 5119 20, 5239 5141 20, 5261 5141 20, 5261 5119 20, 5239 5119 20), (5141 5135 20, 5141 5153 20, 5159 5153 20, 5159 5135 20, 5141 5135 20)), ((6100 5230 20, 6100 5030 20, 6300 5030 20, 6300 5230 20, 6100 5230 20), (6239 5119 20, 6239 5141 20, 6261 5141 20, 6261 5119 20, 6239 5119 20), (6141 5135 20, 6141 5153 20, 6159 5153 20, 6159 5135 20, 6141 5135 20)))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);

        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();

            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();

            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xym ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, false, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XYM (((5100 5230 1, 5100 5030 2, 5300 5030 3, 5300 5230 1, 5100 5230 1), (5239 5119 1, 5239 5141 2, 5261 5141 3, 5261 5119 1, 5239 5119 1), (5141 5135 1, 5141 5153 2, 5159 5153 3, 5159 5135 1, 5141 5135 1)), ((6100 5230 1, 6100 5030 2, 6300 5030 3, 6300 5230 1, 6100 5230 1), (6239 5119 1, 6239 5141 2, 6261 5141 3, 6261 5119 1, 6239 5119 1), (6141 5135 1, 6141 5153 2, 6159 5153 3, 6159 5135 1, 6141 5135 1)))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);

        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_geometry_multipolygon_xyzm ()
{
    try
    {
        create_schema (FdoGeometricType_Surface, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'Linux Loop'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = FdoDecimalValue::Create (99.9999);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"true");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'2005-03-22'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GeomFromText('MULTIPOLYGON XYZM (((5100 5230 20 1, 5100 5030 20 2, 5300 5030 20 3, 5300 5230 20 1, 5100 5230 20 1), (5239 5119 20 1, 5239 5141 20 2, 5261 5141 20 3, 5261 5119 20 1, 5239 5119 20 1), (5141 5135 20 1, 5141 5153 20 2, 5159 5153 20 3, 5159 5135 20 1, 5141 5135 20 1)), ((6100 5230 20 1, 6100 5030 20 2, 6300 5030 20 3, 6300 5230 20 1, 6100 5230 20 1), (6239 5119 20 1, 6239 5141 20 2, 6261 5141 20 3, 6261 5119 20 1, 6239 5119 20 1), (6141 5135 20 1, 6141 5153 20 2, 6159 5153 20 3, 6159 5135 20 1, 6141 5135 20 1)))')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);

        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"Linux Loop", reader->GetString (L"Street")));
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 99.9999 == reader->GetDouble (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 3 == reader->GetDateTime (L"Birthday").month);
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 22 == reader->GetDateTime (L"Birthday").day);
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
            int count = before->GetCount ();
            for (int i = 0; i < count; i++)
            {
                FdoByte left = before->GetData ()[i];
                FdoByte right = after->GetData ()[i];
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}


void InsertTests::insert_invalid_polygons()
{
    try
    {
        create_schema (FdoGeometricType_Surface, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression;
        FdoPtr<FdoPropertyValue> value;

        // Add geometry value that contains multiple invalid loops;
        // Obsolete: such polygons need to roundtrip without errors/modification according to ECO 10400:
        // Actual: according to RFC 38 the type of the output geometry is not guarranteed. In this case
        // a multi-polygon should be returned instead.
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (
            L"GeomFromText('POLYGON XYZM ("
            L"(1100 1100 20 1, 1200 1100 20 2, 1200 1200 20 3, 1100 1200 20 1, 1100 1100 20 1),"  // inner ring as first ring
            L"(1000 1000 20 1, 2000 1000 20 2, 2000 2000 20 3, 1000 2000 20 1, 1000 1000 20 1),"  // outer ring as second ring
            L"(1000 1000 20 1, 1000 1000 20 2, 1000 1000 20 3, 1000 1000 20 1, 1000 1000 20 1),"  // degenerate ring (all points equal)
            L"(3000 3000 20 1, 4000 4000 20 2, 3000 4000 20 3, 4000 3000 20 1, 3000 3000 20 1),"  // self-intersecting ring
            L"(1000 1000 20 1, 1000 2000 20 1, 2000 2000 20 3, 2000 1000 20 2, 1000 1000 20 1)"   // opposite vertex order compared to scond ring, and fully overlapping
            L")')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();

            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b != a);
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
            FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
            FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
            int b = before->GetCount ();
            int a = after->GetCount ();

            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b != a);
         }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}


/* Batch insert tests */
void InsertTests::batch_insert ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();

        // Set up the property value collection:
        FdoPtr<FdoPropertyValue> value;
        FdoPtr<FdoLiteralValue> expression;
        FdoPtr<FdoParameter>  parameter;

        parameter = FdoParameter::Create (L"Param0");
        value = FdoPropertyValue::Create (L"Id", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param1");
        value = FdoPropertyValue::Create (L"Street", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param2");
        value = FdoPropertyValue::Create (L"Area", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param3");
        value = FdoPropertyValue::Create (L"Vacant", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param4");
        value = FdoPropertyValue::Create (L"Birthday", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param5");
        value = FdoPropertyValue::Create (L"Geometry", parameter);
        values->Add (value);

        // fill the batch parameter value collection with multiple (2) rows of data
        FdoPtr<FdoBatchParameterValueCollection> parameters = insert->GetBatchParameterValues ();
        FdoPtr<FdoParameterValue> parameterValue;

        // row 1
        FdoPtr<FdoParameterValueCollection> collection = FdoParameterValueCollection::Create ();
        FdoPtr<FdoLiteralValue> valueExpression = (FdoLiteralValue*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'4 Linux Loop'");
        parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
        collection->Add (parameterValue);
        valueExpression = FdoDecimalValue::Create (256.00);
        parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"true");
        parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-18'");
        parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
        collection->Add (parameterValue);
        FdoPtr<FdoGeometryValue> geometry1 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
        parameterValue = FdoParameterValue::Create (L"Param5", geometry1);
        collection->Add (parameterValue);
        parameters->Add (collection);

        // row 2
        collection = FdoParameterValueCollection::Create ();
        valueExpression = (FdoLiteralValue*)ShpTests::ParseByDataType (L"11", FdoDataType_Decimal);
        parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'84 Windows Way'");
        parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
        collection->Add (parameterValue);
        valueExpression = FdoDecimalValue::Create (128.00);
        parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"false");
        parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-16'");
        parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
        collection->Add (parameterValue);
        FdoPtr<FdoGeometryValue> geometry2 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 6677.99 7820.89, 6272.90 7020.20, 7012.82 7516.91)')");
        parameterValue = FdoParameterValue::Create (L"Param5", geometry2);
        collection->Add (parameterValue);
        parameters->Add (collection);

        // perform the batch insert
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

        // check the id's
        FdoInt32 featid1;
        FdoInt32 featid2;
        featid1 = -1;
        featid2 = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid1)
                if (-1 != featid2)
                    CPPUNIT_FAIL ("too many features inserted");
                else
                    featid2 = reader->GetInt32 (L"FeatId");
            else
                featid1 = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid2)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        selectCmd->SetFeatureClassName (L"Test");
        reader = selectCmd->Execute ();
        while (reader->ReadNext ())
        {
            if (featid1 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            else if (featid2 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        selectCmd->SetFeatureClassName (L"Test");
        reader = selectCmd->Execute ();
        while (reader->ReadNext ())
        {
            if (featid1 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            else if (featid2 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

/* null insert tests */
void InsertTests::null_geometry_insert ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, false);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();

        // Set up the property value collection:
        FdoPtr<FdoPropertyValue> value;
        FdoPtr<FdoLiteralValue> expression;
        FdoPtr<FdoParameter>  parameter;

        parameter = FdoParameter::Create (L"Param0");
        value = FdoPropertyValue::Create (L"Id", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param1");
        value = FdoPropertyValue::Create (L"Street", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param2");
        value = FdoPropertyValue::Create (L"Area", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param3");
        value = FdoPropertyValue::Create (L"Vacant", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param4");
        value = FdoPropertyValue::Create (L"Birthday", parameter);
        values->Add (value);

        parameter = FdoParameter::Create (L"Param5");
        value = FdoPropertyValue::Create (L"Geometry", parameter);
        values->Add (value);

        // fill the batch parameter value collection with multiple (3) rows of data,
        // one of which has a null geometry
        FdoPtr<FdoBatchParameterValueCollection> parameters = insert->GetBatchParameterValues ();
        FdoPtr<FdoParameterValue> parameterValue;

        // row 1
        FdoPtr<FdoParameterValueCollection> collection = FdoParameterValueCollection::Create ();
        FdoPtr<FdoLiteralValue> valueExpression = (FdoLiteralValue*)ShpTests::ParseByDataType (L"7", FdoDataType_Decimal);
        parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'4 Linux Loop'");
        parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
        collection->Add (parameterValue);
        valueExpression = FdoDecimalValue::Create (256.00);
        parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"true");
        parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-18'");
        parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
        collection->Add (parameterValue);
        FdoPtr<FdoGeometryValue> geometry1 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
        parameterValue = FdoParameterValue::Create (L"Param5", geometry1);
        collection->Add (parameterValue);
        parameters->Add (collection);

        // row 2
        collection = FdoParameterValueCollection::Create ();
        valueExpression = (FdoLiteralValue*)ShpTests::ParseByDataType (L"11", FdoDataType_Decimal);
        parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'84 Windows Way'");
        parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
        collection->Add (parameterValue);
        valueExpression = FdoDecimalValue::Create (128.00);
        parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"false");
        parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-16'");
        parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
        collection->Add (parameterValue);
        // insert a NULL geometry
        parameters->Add (collection);

        // row 3
        collection = FdoParameterValueCollection::Create ();
        valueExpression = (FdoLiteralValue*)ShpTests::ParseByDataType (L"11", FdoDataType_Decimal);
        parameterValue = FdoParameterValue::Create (L"Param0", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"'84 Windows Way'");
        parameterValue = FdoParameterValue::Create (L"Param1", valueExpression);
        collection->Add (parameterValue);
        valueExpression = FdoDecimalValue::Create (128.00);
        parameterValue = FdoParameterValue::Create (L"Param2", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"false");
        parameterValue = FdoParameterValue::Create (L"Param3", valueExpression);
        collection->Add (parameterValue);
        valueExpression = (FdoLiteralValue*)FdoExpression::Parse (L"DATE'2005-04-16'");
        parameterValue = FdoParameterValue::Create (L"Param4", valueExpression);
        collection->Add (parameterValue);
        FdoPtr<FdoGeometryValue> geometry2 = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 6677.99 7820.89, 6272.90 7020.20, 7012.82 7516.91)')");
        parameterValue = FdoParameterValue::Create (L"Param5", geometry2);
        collection->Add (parameterValue);
        parameters->Add (collection);

        // perform the batch insert
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

        // check the id's
        FdoInt32 featid1;
        FdoInt32 featid2;
        FdoInt32 featid3;
        featid1 = -1;
        featid2 = -1;
        featid3 = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid1)
                if (-1 != featid2)
                    if (-1 != featid3)
                        CPPUNIT_FAIL ("too many features inserted");
                    else
                        featid3 = reader->GetInt32 (L"FeatId");
                else
                    featid2 = reader->GetInt32 (L"FeatId");
            else
                featid1 = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid3)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        selectCmd->SetFeatureClassName (L"Test");
        reader = selectCmd->Execute ();
        while (reader->ReadNext ())
        {
            if (featid1 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            else if (featid2 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is not null", reader->IsNull (L"Geometry"));
            }
            else if (featid3 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        selectCmd = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        selectCmd->SetFeatureClassName (L"Test");
        reader = selectCmd->Execute ();
        while (reader->ReadNext ())
        {
            if (featid1 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 7 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"4 Linux Loop", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 256.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 18 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry1->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            else if (featid2 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is not null", reader->IsNull (L"Geometry"));
            }
            else if (featid3 == reader->GetInt32 (L"FeatId"))
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 11 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"84 Windows Way", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", 128.00 == reader->GetDouble (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", !reader->GetBoolean (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 2005 == reader->GetDateTime (L"Birthday").year);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 4 == reader->GetDateTime (L"Birthday").month);
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", 16 == reader->GetDateTime (L"Birthday").day);
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry2->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                int b = before->GetCount ();
                int a = after->GetCount ();
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", b == a);
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::null_data_insert ()
{
    try
    {
        create_schema (FdoGeometricType_Point, true, true);
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create();  //NULL
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = FdoStringValue::Create(); // NULL
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        // add NULL geometry value:
        FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
        geometry->SetNullValue ();
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", reader->IsNull (L"Id"));             // explicitly inserted NULL
            CPPUNIT_ASSERT_MESSAGE ("incorrect street value", reader->IsNull(L"Street"));      // explicitly inserted NULL
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));         // implicitly inserted NULL
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));     // implicitly inserted NULL
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday")); // implicitly inserted NULL
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry")); // explicitly inserted NULL
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}



void InsertTests::insert_large_first_geometry ()
{
    try
    {
        for (int ii=0; ii<1; ii++)  // can add mroe iterations if desired, but it doesnt seem to help reproduce the problem
        {
            create_schema (FdoGeometricType_Curve, false, false);

            FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
            insert->SetFeatureClassName (L"TheSchema:Test");
            FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
            FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"24", FdoDataType_Decimal);
            FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
            values->Add (value);
            expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
            value = FdoPropertyValue::Create (L"Street", expression);
            values->Add (value);
            // add real geometry value (that is over 5k, so to exceed the buffer size minimum of 5k):
            FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ("
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,"
                L"1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0,1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9,0 0"
                L")')");
            value = FdoPropertyValue::Create (L"Geometry", geometry);
            values->Add (value);
            FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
            FdoInt32 featid;
            featid = -1;

            while (reader->ReadNext ())
            {
                if (-1 != featid)
                    CPPUNIT_FAIL ("too many features inserted");
                featid = reader->GetInt32 (L"FeatId");
            }
            reader->Close ();
            if (-1 == featid)
                CPPUNIT_FAIL ("too few features inserted");

            // Insert the same large geometry a few more times:
            reader = insert->Execute ();
            reader->Close();
            reader = insert->Execute ();
            reader->Close();
            reader = insert->Execute ();
            reader->Close();


            // check by doing a select
            FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (L"TheSchema:Test");
            reader = select->Execute ();
            if (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();

            // close and reopen the connection
            mConnection->Close ();
            CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

            // check by doing a select
            select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
            select->SetFeatureClassName (L"TheSchema:Test");
            reader = select->Execute ();
            if (reader->ReadNext ())
            {
                CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"1147 Trafford Drive", reader->GetString (L"Street")));
                CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
                CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
                CPPUNIT_ASSERT_MESSAGE ("geometry is null", !reader->IsNull (L"Geometry"));
                FdoPtr<FdoByteArray> before = geometry->GetGeometry ();
                FdoPtr<FdoByteArray> after = reader->GetGeometry (L"Geometry");
                CPPUNIT_ASSERT_MESSAGE ("incorrect geometry size", before->GetCount () == after->GetCount ());
                int count = before->GetCount ();
                for (int i = 0; i < count; i++)
                {
                    FdoByte left = before->GetData ()[i];
                    FdoByte right = after->GetData ()[i];
                    CPPUNIT_ASSERT_MESSAGE ("incorrect geometry content", left == right);
                }
            }
            reader->Close ();
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}



void InsertTests::TestGeometrylessClass(FdoString* schemaName, FdoString* className, FdoClassType classType)
{
    FdoStringP classQName = FdoStringP::Format(L"%ls:%ls", schemaName, className);

    // Insert some data:
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
    insert->SetFeatureClassName (classQName);
    FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
    FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"24", FdoDataType_Decimal);
    FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
    values->Add (value);
    expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
    value = FdoPropertyValue::Create (L"Street", expression);
    values->Add (value);
    FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
    FdoInt32 featid;
    featid = -1;
    while (reader->ReadNext ())
    {
        if (-1 != featid)
            CPPUNIT_FAIL ("too many features inserted");
        featid = reader->GetInt32 (L"FeatId");
    }
    reader->Close ();
    if (-1 == featid)
        CPPUNIT_FAIL ("too few features inserted");


    // Update some data:
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoIUpdate> update = (FdoIUpdate*)mConnection->CreateCommand (FdoCommandType_Update);
    update->SetFeatureClassName (classQName);
    values = update->GetPropertyValues ();
    expression = (FdoValueExpression*)FdoExpression::Parse (L"'123 Smithereen Lane'");
    value = FdoPropertyValue::Create (L"Street", expression);
    values->Add (value);
    FdoInt32 updatedRowCount = update->Execute ();


    // Check by doing a select:
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
    select->SetFeatureClassName (classQName);
    reader = select->Execute ();
    while (reader->ReadNext ())
    {
        CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect street nullness", !reader->IsNull (L"Street"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"123 Smithereen Lane", reader->GetString (L"Street")));
        CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));

        try
        {
            bool bDummy = reader->IsNull (L"Geometry");
            CPPUNIT_FAIL("Geometry property was found, but should not exist");
        }
        catch (FdoException *e)
        {
            e->Release();
        }
    }
    reader->Close ();


    // close and reopen the connection
    ///////////////////////////////////////////////////////////////////////

    mConnection->Close ();
    CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());


    // Do a DescribeSchema to ensure there is no geometry property
    ///////////////////////////////////////////////////////////////////////

    FdoPtr<FdoIDescribeSchema> descSchema = (FdoIDescribeSchema*)mConnection->CreateCommand(FdoCommandType_DescribeSchema);
    FdoPtr<FdoFeatureSchemaCollection> schemas = descSchema->Execute();
    FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(schemaName);
    FdoPtr<FdoClassCollection> classes = schema->GetClasses();
    FdoPtr<FdoClassDefinition> classDef = classes->GetItem(className);
    CPPUNIT_ASSERT_MESSAGE("Wrong class type", classDef->GetClassType() == classType);
    if (classType == FdoClassType_FeatureClass)
    {
        FdoFeatureClass* featureClass = (FdoFeatureClass*)classDef.p;
        FdoPtr<FdoGeometricPropertyDefinition> geomProp = featureClass->GetGeometryProperty();
        CPPUNIT_ASSERT_MESSAGE("Expected no geometry property", geomProp == NULL);
    }
    FdoPtr<FdoPropertyDefinitionCollection> props = classDef->GetProperties();
    for (int i=0; i<props->GetCount(); i++)
    {
        FdoPtr<FdoPropertyDefinition> prop = props->GetItem(i);
        CPPUNIT_ASSERT_MESSAGE("Expected no geometry properties", prop->GetPropertyType() != FdoPropertyType_GeometricProperty);
    }


    // check by doing a select
    ///////////////////////////////////////////////////////////////////////

    select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
    select->SetFeatureClassName (classQName);
    reader = select->Execute ();
    while (reader->ReadNext ())
    {
        CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect street value", 0 == wcscmp (L"123 Smithereen Lane", reader->GetString (L"Street")));
        CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
        CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));

        try
        {
            bool bDummy = reader->IsNull (L"Geometry");
            CPPUNIT_FAIL("Geometry property was found, but should not exist");
        }
        catch (FdoException *e)
        {
            e->Release();
        }
    }
    reader->Close ();
    reader = NULL;
}


void InsertTests::insert_no_geometry ()
{
    try
    {
        // Create shapefiles without geometry:
        create_schema ((FdoGeometricType)0, true, true);

        // Test FdoFeatureClass "Test":
        TestGeometrylessClass(L"TheSchema", L"Test", FdoClassType_FeatureClass);

        // Test FdoClass "testFdoClass":
        TestGeometrylessClass(L"TheSchema", L"TestFdoClass", FdoClassType_Class);
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_2connects ()
{
    try
    {
        create_schema (FdoGeometricType_Point, false, false);

        // Do Describe schema of 1st connection and Insert on second.
        FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)mConnection->CreateCommand (FdoCommandType_DescribeSchema);
        FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute ();

        // Do an insert on 2nd connection 
        FdoPtr<FdoIConnection>    pConnection2 = ShpTests::GetConnection ();
        pConnection2->SetConnectionString (L"DefaultFileLocation=" LOCATION);
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == pConnection2->Open ());

        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        FdoPtr<FdoIInsert> insert2 = (FdoIInsert*)pConnection2->CreateCommand (FdoCommandType_Insert);

        // Insert on conn #2
        insert_connection( pConnection2, insert2, L"TheSchema:Test", L"200");
#ifdef _WIN32
        try 
        {
            // Trying to insert on conn #1 in the same class will fail since conn #1 has locked the fileset
            insert_connection( mConnection, insert, L"TheSchema:Test", L"100");
            CPPUNIT_FAIL ("Expected access violation");
        }
        catch (FdoException* ge) 
        {
            ge->Release();
        }
#else
#pragma message("Investigate why no Expected access violation")
#endif

        CPPUNIT_ASSERT_MESSAGE ("Wrong number of features in TheSchema:Test", get_count( pConnection2, L"TheSchema:Test" )== 1); 

        // Switch insert conn #1 to another class
        // This should be possible since conn #2 didn't lock the files.
        insert_connection( mConnection, insert, L"TheSchema:Test2", L"100");

        // Do one more insert
        insert_connection( mConnection, insert, L"TheSchema:Test2", L"102");

        CPPUNIT_ASSERT_MESSAGE ("Wrong number of features in TheSchema:Test2", get_count( mConnection, L"TheSchema:Test2" )== 2); 
    
        // Cleanup - it makes a difference if the insert is released before connection or the insert is properly freed.
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

void InsertTests::insert_2connects_flush ()
{
    try
    {
        create_schema (FdoGeometricType_Curve, false, false);

        // Do Describe schema of 1st connection and Insert on second.
        FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)mConnection->CreateCommand (FdoCommandType_DescribeSchema);
        FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute ();

        // Create 2 connections on the same fileset
        FdoPtr<FdoIConnection>    pConnection1 = ShpTests::GetConnection ();
        pConnection1->SetConnectionString (L"DefaultFileLocation=" LOCATION);
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == pConnection1->Open ());

        FdoPtr<FdoIConnection>    pConnection2 = ShpTests::GetConnection ();
        pConnection2->SetConnectionString (L"DefaultFileLocation=" LOCATION);
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == pConnection2->Open ());

        // Do an insert on 1st connection 
        FdoPtr<FdoIInsert> insert = (FdoIInsert*)pConnection2->CreateCommand (FdoCommandType_Insert);

        insert->SetFeatureClassName (L"Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = FdoDecimalValue::Create (INT_MAX);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"'~!@#$%^&*()'");
        value = FdoPropertyValue::Create (L"Street", expression);
        values->Add (value);
        expression = (FdoValueExpression*)ShpTests::ParseByDataType (L"-8.8282e12", FdoDataType_Decimal);
        value = FdoPropertyValue::Create (L"Area", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"false");
        value = FdoPropertyValue::Create (L"Vacant", expression);
        values->Add (value);
        expression = (FdoValueExpression*)FdoExpression::Parse (L"DATE'1957-3-2'");
        value = FdoPropertyValue::Create (L"Birthday", expression);
        values->Add (value);

        // add geometry value:
        FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('LINESTRING XY ( 7171.723 8282.99, 6824.82 6545.87, 8920.5 9929.77)')");
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();

        CPPUNIT_ASSERT_MESSAGE ("Conn1: Wrong number of features in TheSchema:Test after flush", get_count( pConnection1, L"TheSchema:Test" )== 1); 

        //////////// Now the 2nd connection should see the updates on the same class
        pConnection1->Flush();

        CPPUNIT_ASSERT_MESSAGE ("Conn2: Wrong number of features in TheSchema:Test", get_count( pConnection2, L"TheSchema:Test" )== 1); 
    
        // Check the extents - This should suffice since it's just one geometry.
        FdoPtr<FdoISelectAggregates> advsel = (FdoISelectAggregates*)(pConnection2->CreateCommand(FdoCommandType_SelectAggregates));
        advsel->SetFeatureClassName(L"TheSchema:Test");
        
        FdoPtr<FdoIdentifierCollection> ids = advsel->GetPropertyNames();
        FdoPtr<FdoExpression> expr = FdoExpression::Parse(L"SpatialExtents(Geometry)");
        FdoPtr<FdoComputedIdentifier> cid = FdoComputedIdentifier::Create(L"MBR", expr);
        ids->Add(cid);

        FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
        FdoPtr<FdoIDataReader> rdr = advsel->Execute();

        FdoPtr<FdoIEnvelope> extents;
        while (rdr->ReadNext())
        {
            if ( rdr->IsNull(L"MBR") )
                CPPUNIT_FAIL("Expected not-null envelope for SpatialExtents() result");

            FdoPtr<FdoByteArray> geomBytes = rdr->GetGeometry(L"MBR");
            FdoPtr<FdoIGeometry> geom = gf->CreateGeometryFromFgf(geomBytes);

            FdoGeometryType geomType = geom->GetDerivedType();
            if (geomType != FdoGeometryType_Polygon)
                CPPUNIT_FAIL("Expected Polygon geometry for SpatialExtents() result");

            extents = geom->GetEnvelope();
            if (extents->GetIsEmpty())
                CPPUNIT_FAIL("Expected non-empty envelope for SpatialExtents() result");
        }
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}

int InsertTests::get_count( FdoIConnection* connection, FdoString* class_name )
{
    FdoPtr<FdoISelect> select = (FdoISelect*)connection->CreateCommand (FdoCommandType_Select);
    select->SetFeatureClassName (class_name);
    FdoPtr<FdoIFeatureReader> reader = select->Execute ();

    int count = 0;
    while (reader->ReadNext ())
    {
        count++;
    }
    reader->Close ();

    return count;
}

void InsertTests::insert_connection( FdoIConnection* connection, FdoIInsert *insert2, FdoString* className, FdoString* id )
{
    insert2->SetFeatureClassName (className);
    FdoPtr<FdoPropertyValueCollection> values = insert2->GetPropertyValues ();
    FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType (id, FdoDataType_Decimal);
    FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
    values->Add (value);
    expression = (FdoValueExpression*)FdoExpression::Parse (L"'1147 Trafford Drive'");
    value = FdoPropertyValue::Create (L"Street", expression);
    values->Add (value);
    // add real geometry value:
    FdoPtr<FdoGeometryValue> geometry = (FdoGeometryValue*)FdoExpression::Parse (L"GEOMFROMTEXT ('POINT XY ( 9.99 18.56 )')");
    value = FdoPropertyValue::Create (L"Geometry", geometry);
    values->Add (value);
    FdoPtr<FdoIFeatureReader> reader = insert2->Execute ();

    FdoInt32 featid;
    featid = -1;
    while (reader->ReadNext ())
    {
        if (-1 != featid)
            CPPUNIT_FAIL ("too many features inserted");
        featid = reader->GetInt32 (L"FeatId");
    }
    reader->Close ();
    if (-1 == featid)
        CPPUNIT_FAIL ("too few features inserted");
}

void InsertTests::insert_integers ()
{
   try
   {
        create_schema (FdoGeometricType_Point, false, false);

        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"TheSchema:Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);

        // Integer values (not natively supported, see RFC 55)
         expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"-32767", FdoDataType_Int16);
        value = FdoPropertyValue::Create (L"IdInt16", expression);
        values->Add (value);

        expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"-2147483647", FdoDataType_Int32);
        value = FdoPropertyValue::Create (L"IdInt32", expression);
        values->Add (value);

        expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"-9223372036854775807", FdoDataType_Int64);
        value = FdoPropertyValue::Create (L"IdInt64", expression);
        values->Add (value);

        // add NULL geometry value:
        FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
        geometry->SetNullValue ();
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        CPPUNIT_ASSERT_MESSAGE("featid should be 1-based", featid==1);

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"TheSchema:Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetInt32 (L"Id"));  // get decimal as Int

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 nullness", !reader->IsNull (L"IdInt16"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 value", reader->GetInt16 (L"IdInt16") == -32767);

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 nullness", !reader->IsNull (L"IdInt32"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 value", reader->GetInt32 (L"IdInt32") == -2147483647);

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 nullness", !reader->IsNull (L"IdInt64"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 value", reader->GetInt64 (L"IdInt64") == -9223372036854775807LL);

            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();

        // close and reopen the connection
        mConnection->Close ();
        CPPUNIT_ASSERT_MESSAGE ("connection state not open", FdoConnectionState_Open == mConnection->Open ());

        // check by doing a select
        select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetDouble (L"Id"));

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 value", reader->GetInt16 (L"IdInt16") == -32767);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 value", reader->GetInt32 (L"IdInt32") == -2147483647);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 value", reader->GetInt64 (L"IdInt64") == -9223372036854775807LL);
    
            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();
    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}
void InsertTests::insert_integers2 ()
{
   try
   {
        create_schema (FdoGeometricType_Point, false, false);

        FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert);
        insert->SetFeatureClassName (L"TheSchema:Test");
        FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues ();
        FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)ShpTests::ParseByDataType(L"24", FdoDataType_Decimal);
        FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (L"Id", expression);
        values->Add (value);

        // We'll insert a value then try to fetch it as compatible types 
        FdoString* VAL = L"999";
        FdoInt16   nVAL = 999;

        // Integer values (not natively supported, see RFC 55)
         expression = (FdoValueExpression*)ShpTests::ParseByDataType(VAL, FdoDataType_Int16);
        value = FdoPropertyValue::Create (L"IdInt16", expression);
        values->Add (value);

        expression = (FdoValueExpression*)ShpTests::ParseByDataType(VAL, FdoDataType_Int32);
        value = FdoPropertyValue::Create (L"IdInt32", expression);
        values->Add (value);

        expression = (FdoValueExpression*)ShpTests::ParseByDataType(VAL, FdoDataType_Int64);
        value = FdoPropertyValue::Create (L"IdInt64", expression);
        values->Add (value);

        // add NULL geometry value:
        FdoPtr<FdoGeometryValue> geometry = FdoGeometryValue::Create ();
        geometry->SetNullValue ();
        value = FdoPropertyValue::Create (L"Geometry", geometry);
        values->Add (value);
        FdoPtr<FdoIFeatureReader> reader = insert->Execute ();
        FdoInt32 featid;
        featid = -1;
        while (reader->ReadNext ())
        {
            if (-1 != featid)
                CPPUNIT_FAIL ("too many features inserted");
            featid = reader->GetInt32 (L"FeatId");
        }
        reader->Close ();
        if (-1 == featid)
            CPPUNIT_FAIL ("too few features inserted");

        CPPUNIT_ASSERT_MESSAGE("featid should be 1-based", featid==1);

        // check by doing a select
        FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select);
        select->SetFeatureClassName (L"TheSchema:Test");
        reader = select->Execute ();
        while (reader->ReadNext ())
        {
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid nullness", !reader->IsNull (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect featid value", featid == reader->GetInt32 (L"FeatId"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id nullness", !reader->IsNull (L"Id"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect id value", 24 == reader->GetInt32 (L"Id"));  // get decimal as Int

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 nullness", !reader->IsNull (L"IdInt16"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 value", reader->GetInt16 (L"IdInt16") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 value as int32", reader->GetInt32 (L"IdInt16") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 value as int64", reader->GetInt64 (L"IdInt16") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt16 value as double", reader->GetDouble (L"IdInt16") == nVAL);

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 nullness", !reader->IsNull (L"IdInt32"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 value", reader->GetInt32 (L"IdInt32") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 value as int16", reader->GetInt16 (L"IdInt32") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 value as int64", reader->GetInt64 (L"IdInt32") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt32 value as double", reader->GetDouble (L"IdInt32") == nVAL);

            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 nullness", !reader->IsNull (L"IdInt64"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 value", reader->GetInt64 (L"IdInt64") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 value as int32", reader->GetInt16 (L"IdInt64") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 value as int64", reader->GetInt32 (L"IdInt64") == nVAL);
            CPPUNIT_ASSERT_MESSAGE ("incorrect idInt64 value as double", reader->GetDouble (L"IdInt64") == nVAL);

            CPPUNIT_ASSERT_MESSAGE ("incorrect area value", reader->IsNull (L"Area"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect vacant value", reader->IsNull (L"Vacant"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect birthday value", reader->IsNull (L"Birthday"));
            CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", reader->IsNull (L"Geometry"));
        }
        reader->Close ();

    }
    catch (FdoException* ge) 
    {
        TestCommonFail (ge);
    }
}
