/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Collections.Generic;

namespace Apache.Geode.Client.UnitTests
{
  using NUnit.Framework;
  using Apache.Geode.DUnitFramework;
  using Apache.Geode.Client;

  #region Helper class

  public class CacheableHelper
  {
    #region Constants and statics

    private static uint[] CRC32Table = {
      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
      0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
      0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
      0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
      0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
      0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
      0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
      0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
      0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
      0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
      0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
      0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
      0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
      0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
      0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
      0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
      0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
      0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
      0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
      0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
      0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
      0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
      0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
      0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
      0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
      0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
      0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
      0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
      0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
      0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
      0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
      0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
      0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
      0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
      0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
    };

    #endregion

    /// <summary>
    /// Generate a random <c>CData</c> structure.
    /// </summary>
    public static CData RandCData()
    {
      long rnd = (long)Util.Rand(int.MaxValue);
      rnd = (rnd << 32) + (long)Util.Rand(int.MaxValue);
      return new CData(Util.Rand(int.MaxValue), rnd);
    }

    public static PdxCData RandPdxCData()
    {
      long rnd = (long)Util.Rand(int.MaxValue);
      rnd = (rnd << 32) + (long)Util.Rand(int.MaxValue);
      return new PdxCData(Util.Rand(int.MaxValue), rnd);
    }

    public static uint CRC32(byte[] buffer)
    {
      if (buffer == null || buffer.Length == 0)
      {
        return 0;
      }

      uint crc32 = 0xffffffff;

      for (int i = 0; i < buffer.Length; i++)
      {
        crc32 = ((crc32 >> 8) & 0x00ffffff) ^
          CRC32Table[(crc32 ^ buffer[i]) & 0xff];
      }
      return ~crc32;
    }

    public static bool IsContainerTypeId(uint typeId)
    {
      return (typeId == GeodeClassIds.CacheableObjectArray) ||
        (typeId == GeodeClassIds.CacheableVector) ||
        (typeId == GeodeClassIds.CacheableArrayList) ||
        (typeId == GeodeClassIds.CacheableStack) ||
        (typeId == GeodeClassIds.CacheableHashMap) ||
        (typeId == GeodeClassIds.CacheableIdentityHashMap) ||
        (typeId == GeodeClassIds.CacheableHashTable) ||
        (typeId == GeodeClassIds.CacheableLinkedHashSet) ||
        (typeId == GeodeClassIds.CacheableHashSet);
    }

    public static bool IsUnhandledType(uint typeId)
    {
      // TODO: [sumedh] skipping CacheableFileName for now since it will
      // not work on Windows without significant workarounds; also see
      // the corresponding comment in C++ testThinClientCacheables.
      // Also skipping C# specific classes.
      return (typeId == GeodeClassIds.CacheableFileName) ||
        (typeId == GeodeClassIds.CacheableManagedObject) ||
        (typeId == GeodeClassIds.CacheableManagedObjectXml);
    }
    public static long ConstantDateTime = 0;
    public static void RegisterBuiltins(long dateTime)
    {
      ConstantDateTime = dateTime;
      CacheableWrapperFactory.ClearStaticVaraiables();
      #region Cacheable keys

      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableBoolean,
        typeof(CacheableBooleanWrapper), CacheableBooleanWrapper.Create, typeof(bool));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableByte,
        typeof(CacheableByteWrapper), CacheableByteWrapper.Create, typeof(sbyte));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableCharacter,
        typeof(CacheableCharacterWrapper), CacheableCharacterWrapper.Create, typeof(Char));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableDate,
        typeof(CacheableDateWrapper), CacheableDateWrapper.Create, typeof(DateTime));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableDouble,
        typeof(CacheableDoubleWrapper), CacheableDoubleWrapper.Create, typeof(Double));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableFileName,
        typeof(CacheableFileNameWrapper), CacheableFileNameWrapper.Create, typeof(CacheableFileName));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableFloat,
        typeof(CacheableFloatWrapper), CacheableFloatWrapper.Create, typeof(float));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt16,
        typeof(CacheableInt16Wrapper), CacheableInt16Wrapper.Create, typeof(Int16));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt32,
        typeof(CacheableInt32Wrapper), CacheableInt32Wrapper.Create, typeof(Int32));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt64,
        typeof(CacheableInt64Wrapper), CacheableInt64Wrapper.Create, typeof(Int64));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableASCIIString,
        typeof(CacheableStringWrapper), CacheableStringWrapper.Create, typeof(string));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableString,
        typeof(CacheableUnicodeStringWrapper), CacheableUnicodeStringWrapper.Create);
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableASCIIStringHuge,
        typeof(CacheableHugeStringWrapper), CacheableHugeStringWrapper.Create);
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableStringHuge,
        typeof(CacheableHugeUnicodeStringWrapper), CacheableHugeUnicodeStringWrapper.Create);
      CacheableWrapperFactory.RegisterKeyType(10001,
      typeof(PdxCDataWrapper), PdxCDataWrapper.Create, typeof(PdxCData));

      //need to register pdx type
      Assert.NotNull(CacheHelper.DCache);
      CacheHelper.DCache.TypeRegistry.RegisterPdxType(PdxCData.CreateDeserializable);

      #endregion

      #region Other cacheables

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableBytes,
        typeof(CacheableBytesWrapper), CacheableBytesWrapper.Create, typeof(byte[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableDoubleArray,
        typeof(CacheableDoubleArrayWrapper), CacheableDoubleArrayWrapper.Create, typeof(Double[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableFloatArray,
        typeof(CacheableFloatArrayWrapper), CacheableFloatArrayWrapper.Create, typeof(float[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashMap,
        typeof(CacheableHashMapWrapper), CacheableHashMapWrapper.Create, typeof(Dictionary<object, object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashTable,
        typeof(CacheableHashTableWrapper), CacheableHashTableWrapper.Create, typeof(System.Collections.Hashtable));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableIdentityHashMap,
        typeof(CacheableIdentityHashMapWrapper), CacheableIdentityHashMapWrapper.Create, typeof(Dictionary<object, object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashSet,
        typeof(CacheableHashSetWrapper), CacheableHashSetWrapper.Create, typeof(CacheableHashSet));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableLinkedHashSet,
        typeof(CacheableLinkedHashSetWrapper), CacheableLinkedHashSetWrapper.Create, typeof(CacheableLinkedHashSet));

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt16Array,
        typeof(CacheableInt16ArrayWrapper), CacheableInt16ArrayWrapper.Create, typeof(Int16[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt32Array,
        typeof(CacheableInt32ArrayWrapper), CacheableInt32ArrayWrapper.Create, typeof(Int32[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt64Array,
        typeof(CacheableInt64ArrayWrapper), CacheableInt64ArrayWrapper.Create, typeof(Int64[]));
      {//old one
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableNullString,
        //  typeof(CacheableNullStringWrapper), CacheableNullStringWrapper.Create);
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableASCIIString,
        //  typeof(CacheableEmptyStringWrapper), CacheableEmptyStringWrapper.Create);
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableString,
        //  typeof(CacheableEmptyUnicodeStringWrapper), CacheableEmptyUnicodeStringWrapper.Create);
      }
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableStringArray,
        typeof(CacheableStringArrayWrapper), CacheableStringArrayWrapper.Create, typeof(string[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableUndefined,
        typeof(CacheableUndefinedWrapper), CacheableUndefinedWrapper.Create, typeof(CacheableUndefined));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableVector,
        typeof(CacheableVectorWrapper), CacheableVectorWrapper.Create, typeof(System.Collections.ArrayList));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableObjectArray,
        typeof(CacheableObjectArrayWrapper), CacheableObjectArrayWrapper.Create, typeof(CacheableObjectArray));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableArrayList,
        typeof(CacheableArrayListWrapper), CacheableArrayListWrapper.Create, typeof(List<object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableStack,
        typeof(CacheableStackWrapper), CacheableStackWrapper.Create, typeof(Stack<object>));

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableManagedObject,
        typeof(CacheableObjectWrapper), CacheableObjectWrapper.Create, typeof(CacheableObject));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableManagedObjectXml,
        typeof(CacheableObjectXmlWrapper), CacheableObjectXmlWrapper.Create, typeof(CacheableObjectXml));



      #endregion
    }

    public static void RegisterBuiltinsJavaHashCode(long dateTime)
    {
      ConstantDateTime = dateTime;
      CacheableWrapperFactory.ClearStaticVaraiables();
      #region Cacheable keys

      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableBoolean,
        typeof(CacheableBooleanWrapper), CacheableBooleanWrapper.Create, typeof(bool));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableByte,
        typeof(CacheableByteWrapper), CacheableByteWrapper.Create, typeof(sbyte));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableCharacter,
        typeof(CacheableCharacterWrapper), CacheableCharacterWrapper.Create, typeof(Char));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableDate,
        typeof(CacheableDateWrapper), CacheableDateWrapper.Create, typeof(DateTime));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableDouble,
        typeof(CacheableDoubleWrapper), CacheableDoubleWrapper.Create, typeof(Double));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableFileName,
        typeof(CacheableFileNameWrapper), CacheableFileNameWrapper.Create, typeof(CacheableFileName));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableFloat,
        typeof(CacheableFloatWrapper), CacheableFloatWrapper.Create, typeof(float));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt16,
        typeof(CacheableInt16Wrapper), CacheableInt16Wrapper.Create, typeof(Int16));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt32,
        typeof(CacheableInt32Wrapper), CacheableInt32Wrapper.Create, typeof(Int32));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt64,
        typeof(CacheableInt64Wrapper), CacheableInt64Wrapper.Create, typeof(Int64));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableASCIIString,
        typeof(CacheableStringWrapper), CacheableStringWrapper.Create, typeof(string));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableString,
        typeof(CacheableUnicodeStringWrapper), CacheableUnicodeStringWrapper.Create);
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableASCIIStringHuge,
        typeof(CacheableHugeStringWrapper), CacheableHugeStringWrapper.Create);
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableStringHuge,
        typeof(CacheableHugeUnicodeStringWrapper), CacheableHugeUnicodeStringWrapper.Create);

      //need to register pdx type
      Assert.NotNull(CacheHelper.DCache);
      CacheHelper.DCache.TypeRegistry.RegisterPdxType(PdxCData.CreateDeserializable);

      #endregion

      #region Other cacheables

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableBytes,
        typeof(CacheableBytesWrapper), CacheableBytesWrapper.Create, typeof(byte[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableDoubleArray,
        typeof(CacheableDoubleArrayWrapper), CacheableDoubleArrayWrapper.Create, typeof(Double[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableFloatArray,
        typeof(CacheableFloatArrayWrapper), CacheableFloatArrayWrapper.Create, typeof(float[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashMap,
        typeof(CacheableHashMapWrapper), CacheableHashMapWrapper.Create, typeof(Dictionary<object, object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashTable,
        typeof(CacheableHashTableWrapper), CacheableHashTableWrapper.Create, typeof(System.Collections.Hashtable));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableIdentityHashMap,
        typeof(CacheableIdentityHashMapWrapper), CacheableIdentityHashMapWrapper.Create, typeof(Dictionary<object, object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashSet,
        typeof(CacheableHashSetWrapper), CacheableHashSetWrapper.Create, typeof(CacheableHashSet));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableLinkedHashSet,
        typeof(CacheableLinkedHashSetWrapper), CacheableLinkedHashSetWrapper.Create, typeof(CacheableLinkedHashSet));

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt16Array,
        typeof(CacheableInt16ArrayWrapper), CacheableInt16ArrayWrapper.Create, typeof(Int16[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt32Array,
        typeof(CacheableInt32ArrayWrapper), CacheableInt32ArrayWrapper.Create, typeof(Int32[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt64Array,
        typeof(CacheableInt64ArrayWrapper), CacheableInt64ArrayWrapper.Create, typeof(Int64[]));
      {//old one
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableNullString,
        //  typeof(CacheableNullStringWrapper), CacheableNullStringWrapper.Create);
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableASCIIString,
        //  typeof(CacheableEmptyStringWrapper), CacheableEmptyStringWrapper.Create);
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableString,
        //  typeof(CacheableEmptyUnicodeStringWrapper), CacheableEmptyUnicodeStringWrapper.Create);
      }
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableStringArray,
        typeof(CacheableStringArrayWrapper), CacheableStringArrayWrapper.Create, typeof(string[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableUndefined,
        typeof(CacheableUndefinedWrapper), CacheableUndefinedWrapper.Create, typeof(CacheableUndefined));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableVector,
        typeof(CacheableVectorWrapper), CacheableVectorWrapper.Create, typeof(System.Collections.ArrayList));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableObjectArray,
        typeof(CacheableObjectArrayWrapper), CacheableObjectArrayWrapper.Create, typeof(CacheableObjectArray));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableArrayList,
        typeof(CacheableArrayListWrapper), CacheableArrayListWrapper.Create, typeof(List<object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableStack,
        typeof(CacheableStackWrapper), CacheableStackWrapper.Create, typeof(Stack<object>));

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableManagedObject,
        typeof(CacheableObjectWrapper), CacheableObjectWrapper.Create, typeof(CacheableObject));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableManagedObjectXml,
        typeof(CacheableObjectXmlWrapper), CacheableObjectXmlWrapper.Create, typeof(CacheableObjectXml));



      #endregion
    }

    public static void RegisterBuiltinsAD(long dateTime)
    {
      ConstantDateTime = dateTime;
      CacheableWrapperFactory.ClearStaticVaraiables();
      #region Cacheable keys

      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableBoolean,
        typeof(CacheableBooleanWrapper), CacheableBooleanWrapper.Create, typeof(bool));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableByte,
        typeof(CacheableByteWrapper), CacheableByteWrapper.Create, typeof(sbyte));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableCharacter,
        typeof(CacheableCharacterWrapper), CacheableCharacterWrapper.Create, typeof(Char));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableDate,
        typeof(CacheableDateWrapper), CacheableDateWrapper.Create, typeof(DateTime));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableDouble,
        typeof(CacheableDoubleWrapper), CacheableDoubleWrapper.Create, typeof(Double));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableFileName,
        typeof(CacheableFileNameWrapper), CacheableFileNameWrapper.Create, typeof(CacheableFileName));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableFloat,
        typeof(CacheableFloatWrapper), CacheableFloatWrapper.Create, typeof(float));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt16,
        typeof(CacheableInt16Wrapper), CacheableInt16Wrapper.Create, typeof(Int16));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt32,
        typeof(CacheableInt32Wrapper), CacheableInt32Wrapper.Create, typeof(Int32));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableInt64,
        typeof(CacheableInt64Wrapper), CacheableInt64Wrapper.Create, typeof(Int64));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableASCIIString,
        typeof(CacheableStringWrapper), CacheableStringWrapper.Create, typeof(string));
      CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableString,
        typeof(CacheableUnicodeStringWrapper), CacheableUnicodeStringWrapper.Create);
      {
        //CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableASCIIStringHuge,
        //  typeof(CacheableHugeStringWrapper), CacheableHugeStringWrapper.Create);
        //CacheableWrapperFactory.RegisterKeyType(GeodeClassIds.CacheableStringHuge,
        //  typeof(CacheableHugeUnicodeStringWrapper), CacheableHugeUnicodeStringWrapper.Create);
      }
      CacheableWrapperFactory.RegisterKeyType(10001,
     typeof(PdxCDataWrapper), PdxCDataWrapper.Create, typeof(PdxCData));

      //need to register pdx type
      CacheHelper.DCache.TypeRegistry.RegisterPdxType(PdxCData.CreateDeserializable);


      #endregion

      #region Other cacheables

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableBytes,
        typeof(CacheableBytesWrapper), CacheableBytesWrapper.Create, typeof(byte[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableDoubleArray,
        typeof(CacheableDoubleArrayWrapper), CacheableDoubleArrayWrapper.Create, typeof(Double[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableFloatArray,
        typeof(CacheableFloatArrayWrapper), CacheableFloatArrayWrapper.Create, typeof(float[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashMap,
        typeof(CacheableHashMapWrapper), CacheableHashMapWrapper.Create, typeof(Dictionary<object, object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashTable,
        typeof(CacheableHashTableWrapper), CacheableHashTableWrapper.Create, typeof(System.Collections.Hashtable));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableIdentityHashMap,
        typeof(CacheableIdentityHashMapWrapper), CacheableIdentityHashMapWrapper.Create, typeof(Dictionary<object, object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableHashSet,
        typeof(CacheableHashSetWrapper), CacheableHashSetWrapper.Create, typeof(CacheableHashSet));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableLinkedHashSet,
        typeof(CacheableLinkedHashSetWrapper), CacheableLinkedHashSetWrapper.Create, typeof(CacheableLinkedHashSet));

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt16Array,
        typeof(CacheableInt16ArrayWrapper), CacheableInt16ArrayWrapper.Create, typeof(Int16[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt32Array,
        typeof(CacheableInt32ArrayWrapper), CacheableInt32ArrayWrapper.Create, typeof(Int32[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableInt64Array,
        typeof(CacheableInt64ArrayWrapper), CacheableInt64ArrayWrapper.Create, typeof(Int64[]));
      {//old one
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableNullString,
        //  typeof(CacheableNullStringWrapper), CacheableNullStringWrapper.Create);
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableASCIIString,
        //  typeof(CacheableEmptyStringWrapper), CacheableEmptyStringWrapper.Create);
        //CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableString,
        //  typeof(CacheableEmptyUnicodeStringWrapper), CacheableEmptyUnicodeStringWrapper.Create);
      }
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableStringArray,
        typeof(CacheableStringArrayWrapper), CacheableStringArrayWrapper.Create, typeof(string[]));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableUndefined,
        typeof(CacheableUndefinedWrapper), CacheableUndefinedWrapper.Create, typeof(CacheableUndefined));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableVector,
        typeof(CacheableVectorWrapper), CacheableVectorWrapper.Create, typeof(System.Collections.ArrayList));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableObjectArray,
        typeof(CacheableObjectArrayWrapper), CacheableObjectArrayWrapper.Create, typeof(CacheableObjectArray));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableArrayList,
        typeof(CacheableArrayListWrapper), CacheableArrayListWrapper.Create, typeof(List<object>));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableStack,
        typeof(CacheableStackWrapper), CacheableStackWrapper.Create, typeof(Stack<object>));

      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableManagedObject,
        typeof(CacheableObjectWrapper), CacheableObjectWrapper.Create, typeof(CacheableObject));
      CacheableWrapperFactory.RegisterType(GeodeClassIds.CacheableManagedObjectXml,
        typeof(CacheableObjectXmlWrapper), CacheableObjectXmlWrapper.Create, typeof(CacheableObjectXml));


      #endregion
    }
  }

  #endregion

  #region Builtin cacheable keys

  public class CacheableBooleanWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableBooleanWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return 2;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      bool value = (keyIndex % 2 == 1 ? true : false);
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      bool value = (Util.Rand(byte.MaxValue) % 2 == 1 ? true : false);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      //Util.Log("cacheableObject Type = {0}", cacheableObject.GetType());
      bool value = (bool)cacheableObject;
      Assert.IsNotNull(value, "GetChecksum: Null object.");
      return (uint)(value ? 1 : 0);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      bool val = (bool)cacheableObject;
      if (val) return 1231;
      else return 1237;
    }

    #endregion
  }

  public class CacheableByteWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableByteWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return byte.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      sbyte value = (sbyte)keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      sbyte value = (sbyte)Util.Rand(byte.MaxValue);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      sbyte value = (sbyte)cacheableObject;
      Assert.IsNotNull(value, "GetChecksum: Null object.");
      byte[] buffer = new byte[1];
      buffer[0] = (byte)value;
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      sbyte val = (sbyte)cacheableObject;
      return val;
    }

    #endregion
  }

  public class CacheableCharacterWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableCharacterWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return char.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      char value = (char)keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      char value = (char)Util.Rand(char.MaxValue);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      char obj = (char)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");
      char value = obj;
      int numBytes = sizeof(char);
      byte[] buffer = new byte[numBytes];
      for (int i = 0; i < numBytes; i++)
      {
        buffer[i] = (byte)(value & 0xff);
        value = (char)(value >> 8);
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      char val = (char)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableDateWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableDateWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      //m_cacheableObject = DateTime.Today.AddMinutes(keyIndex % 0xFFFF);
      DateTime dt = new DateTime(CacheableHelper.ConstantDateTime + keyIndex * TimeSpan.TicksPerMinute);
      m_cacheableObject = dt;
      Util.Log(" datevalue initkey " + dt.ToString());
    }

    private DateTime createRoundOffDTVal(DateTime dt)
    {
      long ticksToAdd = dt.Ticks % TimeSpan.TicksPerMillisecond;
      ticksToAdd = (ticksToAdd >= (TimeSpan.TicksPerMillisecond / 2) ?
        (TimeSpan.TicksPerMillisecond - ticksToAdd) : -ticksToAdd);
      dt = dt.AddTicks(ticksToAdd);
      return dt;
    }

    public override void InitRandomValue(int maxSize)
    {
      int rnd = Util.Rand(int.MaxValue);
      //DateTime value = DateTime.Now.AddMilliseconds(rnd % 2 == 0 ? rnd : -rnd);
      DateTime value = new DateTime(CacheableHelper.ConstantDateTime);
      m_cacheableObject = value;
      Util.Log(" datevalue InitRandomValue " + value.ToString());
    }

    public override uint GetChecksum(object cacheableObject)
    {
      //CacheableDate obj = cacheableObject as CacheableDate;
      DateTime obj = (DateTime)cacheableObject;
      Util.Log(" datevalue getchecksum " + obj.ToString());
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      obj = createRoundOffDTVal(obj);
      long value = obj.Ticks;
      int numBytes = sizeof(long);
      byte[] buffer = new byte[numBytes];
      for (int i = 0; i < numBytes; i++)
      {
        buffer[i] = (byte)(value & 0xff);
        value = value >> 8;
      }
      uint cks = CacheableHelper.CRC32(buffer);
      Util.Log(" datevalue getchecksum  " + cks);
      return cks;
    }

    #endregion
  }

  public class CacheableDoubleWrapper : CacheableKeyWrapper
  {
    #region Private constants

    private const double MaxError = 1E-20;

    #endregion

    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableDoubleWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      double value = (double)keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      double value = Util.Rand() * double.MaxValue;
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      double value = (double)cacheableObject;
      Assert.IsNotNull(value, "GetChecksum: Null object.");
      return CacheableHelper.CRC32(BitConverter.GetBytes(value));
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      double val = (double)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableFileNameWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableFileNameWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of key should be greater than zero.");
      if (maxSize < 11)
      {
        maxSize = 11;
      }
      string value = "C:\\" + new string('\x0905', maxSize - 13) +
        keyIndex.ToString("D10");
      m_cacheableObject = CacheableFileName.Create(value);
    }

    public override void InitRandomValue(int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of value should be greater than zero.");
      byte[] buffer = Util.RandBytes(maxSize / 2);
      char[] value = new char[maxSize / 2];
      for (int i = 0; i < maxSize / 2; i++)
      {
        value[i] = (char)((int)buffer[i] + 0x0901);
      }
      m_cacheableObject = CacheableFileName.Create(value);
    }

    public override uint GetChecksum(object cacheableObject)
    {
      CacheableFileName obj = cacheableObject as CacheableFileName;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      string value = obj.Value;
      byte[] buffer = new byte[value.Length * 2];
      for (int i = 0; i < value.Length; i++)
      {
        char c = value[i];
        buffer[i * 2] = (byte)(c & 0xff);
        buffer[i * 2 + 1] = (byte)((c >> 8) & 0xff);
      }
      return CacheableHelper.CRC32(buffer);
    }

    #endregion
  }

  public class CacheableFloatWrapper : CacheableKeyWrapper
  {
    #region Private constants

    private const float MaxError = 1E-10F;

    #endregion

    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableFloatWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      float value = (float)keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      float value = (float)Util.Rand() * float.MaxValue;
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      float value = (float)cacheableObject;
      Assert.IsNotNull(value, "GetChecksum: Null object.");
      return CacheableHelper.CRC32(BitConverter.GetBytes(value));
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      float val = (float)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableInt16Wrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableInt16Wrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return short.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      short value = (short)keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      short value = (short)Util.Rand(short.MaxValue);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Int16 obj = (Int16)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");
      short value = obj;
      int numBytes = sizeof(short);
      byte[] buffer = new byte[numBytes];
      for (int i = 0; i < numBytes; i++)
      {
        buffer[i] = (byte)(value & 0xff);
        value = (short)(value >> 8);
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      Int16 val = (Int16)cacheableObject;
      return val;
    }
    #endregion
  }

  public class CacheableInt32Wrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableInt32Wrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      int value = keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      int value = Util.Rand(int.MaxValue);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Int32 obj = (Int32)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      int value = obj;
      int numBytes = sizeof(int);
      byte[] buffer = new byte[numBytes];
      for (int i = 0; i < numBytes; i++)
      {
        buffer[i] = (byte)(value & 0xff);
        value = value >> 8;
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      Int32 val = (Int32)cacheableObject;
      return val;
    }
    #endregion
  }

  public class CacheableInt64Wrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableInt64Wrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      long value = (long)keyIndex;
      m_cacheableObject = value;
    }

    public override void InitRandomValue(int maxSize)
    {
      long value = Util.Rand(int.MaxValue);
      value = (value << 32) + Util.Rand(int.MaxValue);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Int64 obj = (Int64)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");
      long value = obj;
      int numBytes = sizeof(long);
      byte[] buffer = new byte[numBytes];
      for (int i = 0; i < numBytes; i++)
      {
        buffer[i] = (byte)(value & 0xff);
        value = value >> 8;
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      Int64 val = (Int64)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableStringWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableStringWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of key should be greater than zero.");
      if (maxSize < 11)
      {
        maxSize = 11;
      }
      if (keyIndex == 0)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        string value = new string('A', maxSize - 10) + keyIndex.ToString("D10");
        m_cacheableObject = value;
      }
    }

    public override void InitRandomValue(int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of value should be greater than zero.");
      maxSize = (maxSize / 2) > 1 ? (maxSize / 2) : 2;
      Util.Log(" in cacheable string wrapper maxsize = " + maxSize);
      if (maxSize == 2)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        byte[] buffer = Util.RandBytes(maxSize);
        string value = BitConverter.ToString(buffer).Replace("-", string.Empty);
        Util.Log("cacheable string wrapper " + value);
        m_cacheableObject = value;
      }
    }

    public override uint GetChecksum(object cacheableObject)
    {
      string obj = (string)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      string value = obj;
      if (value != null)
      {
        byte[] buffer = new byte[value.Length];
        for (int i = 0; i < value.Length; i++)
        {
          buffer[i] = (byte)value[i];
        }
        return CacheableHelper.CRC32(buffer);
      }
      return 0;
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      string val = (string)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableUnicodeStringWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableUnicodeStringWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of key should be greater than zero.");
      if (maxSize < 11)
      {
        maxSize = 11;
      }
      if (keyIndex == 0)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        string value = new string('\x0905', maxSize - 10) + keyIndex.ToString("D10");
        m_cacheableObject = value;
      }
    }

    public override void InitRandomValue(int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of value should be greater than zero.");
      if (maxSize == 2)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        byte[] buffer = Util.RandBytes(maxSize / 2);
        char[] value = new char[maxSize / 2];
        for (int i = 0; i < maxSize / 2; i++)
        {
          value[i] = (char)((int)buffer[i] + 0x0901);
        }
        m_cacheableObject = new string(value);
      }
    }

    public override uint GetChecksum(object cacheableObject)
    {
      string obj = (string)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      string value = obj;
      byte[] buffer = new byte[value.Length * 2];
      for (int i = 0; i < value.Length; i++)
      {
        char c = value[i];
        buffer[i * 2] = (byte)(c & 0xff);
        buffer[i * 2 + 1] = (byte)((c >> 8) & 0xff);
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      string val = (string)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableHugeStringWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableHugeStringWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of key should be greater than zero.");
      if (maxSize < 0xFFFF)
      {
        maxSize += 0xFFFF + 1;
      }
      if (keyIndex == 0)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        string value = new string('A', maxSize - 10) + keyIndex.ToString("D10");
        m_cacheableObject = value;
      }
    }

    public override void InitRandomValue(int maxSize)
    {
      if (maxSize < 0xFFFF)
      {
        maxSize += 0xFFFF + 1;
      }
      Assert.Greater(maxSize, 0, "Size of value should be greater than zero.");
      if (maxSize < 0xFFFF + 10)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        byte[] buffer = Util.RandBytes(maxSize);
        string value = BitConverter.ToString(buffer).Replace("-", string.Empty);
        m_cacheableObject = value;
      }
    }

    public override uint GetChecksum(object cacheableObject)
    {
      string obj = (string)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      string value = obj;
      byte[] buffer = new byte[value.Length];
      for (int i = 0; i < value.Length; i++)
      {
        buffer[i] = (byte)value[i];
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      string val = (string)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableHugeUnicodeStringWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new CacheableHugeUnicodeStringWrapper();
    }

    #endregion

    #region CacheableKeyWrapper Members

    public override int MaxKeys
    {
      get
      {
        return int.MaxValue;
      }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      Assert.Greater(maxSize, 0, "Size of key should be greater than zero.");
      if (maxSize < 0xFFFF)
      {
        maxSize += 0xFFFF + 1;
      }
      if (keyIndex == 0)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        string value = new string('\x0905', maxSize - 10) + keyIndex.ToString("D10");
        m_cacheableObject = value;
      }
    }

    public override void InitRandomValue(int maxSize)
    {
      if (maxSize < 0xFFFF)
      {
        maxSize += 0xFFFF + 1;
      }
      Assert.Greater(maxSize, 0, "Size of value should be greater than zero.");
      if (maxSize < 0xFFFF + 10)
      {
        m_cacheableObject = string.Empty;
      }
      else
      {
        byte[] buffer = Util.RandBytes(maxSize);
        char[] value = new char[maxSize];
        for (int i = 0; i < maxSize; i++)
        {
          value[i] = (char)((int)buffer[i] + 0x0901);
        }
        m_cacheableObject = new string(value);
      }
    }

    public override uint GetChecksum(object cacheableObject)
    {
      string obj = (string)cacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      string value = obj;
      byte[] buffer = new byte[value.Length * 2];
      for (int i = 0; i < value.Length; i++)
      {
        char c = value[i];
        buffer[i * 2] = (byte)(c & 0xff);
        buffer[i * 2 + 1] = (byte)((c >> 8) & 0xff);
      }
      return CacheableHelper.CRC32(buffer);
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      string val = (string)cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  #endregion

  #region Builtin cacheables that are not keys

  public class CacheableBytesWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableBytesWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      byte[] value = Util.RandBytes(maxSize);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      byte[] value = (byte[])cacheableObject;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      return CacheableHelper.CRC32(value);
    }
    public override int GetHashCodeN(object cacheableObject)
    {
      byte[] val = (byte[])cacheableObject;
      return val.GetHashCode();
    }

    #endregion
  }

  public class CacheableDoubleArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableDoubleArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      int arraySize = maxSize / sizeof(double);
      arraySize = arraySize > 1 ? arraySize : 2;
      double[] value = new double[arraySize];
      for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
      {
        value[arrayIndex] = Util.Rand() * double.MaxValue;
      }
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Double[] obj = cacheableObject as Double[];
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      double[] value = obj;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      foreach (double v in value)
      {
        byte[] buffer = BitConverter.GetBytes(v);
        ms.Write(buffer, 0, buffer.Length);
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      double[] val = (double[])cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableFloatArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableFloatArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      int arraySize = maxSize / sizeof(float);
      arraySize = arraySize > 1 ? arraySize : 2;
      float[] value = new float[arraySize];
      for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
      {
        value[arrayIndex] = (float)Util.Rand() * float.MaxValue;
      }
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      float[] obj = cacheableObject as float[];
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      float[] value = obj;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      foreach (float v in value)
      {
        byte[] buffer = BitConverter.GetBytes(v);
        ms.Write(buffer, 0, buffer.Length);
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      float[] val = (float[])cacheableObject;
      return val.GetHashCode();
    }
    #endregion
  }

  public class CacheableHashMapWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableHashMapWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //CacheableHashMap map = new CacheableHashMap();
      Dictionary<object, object> map = new Dictionary<object, object>();
      ICollection<UInt32> keyTypeIds =
        CacheableWrapperFactory.GetRegisteredKeyTypeIds();
      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      int keySize = 16;
      maxSize = maxSize / (keyTypeIds.Count * valueTypeIds.Count) + 1;
      CacheableKeyWrapper keyWrapper;
      CacheableWrapper valueWrapper;
      foreach (UInt32 keyTypeId in keyTypeIds)
      {
        int index = 0;
        foreach (UInt32 valueTypeId in valueTypeIds)
        {
          if ((valueTypeId == GeodeClassIds.CacheableASCIIStringHuge ||
            valueTypeId == GeodeClassIds.CacheableStringHuge)
              && !(keyTypeId == GeodeClassIds.CacheableBoolean))
          {
            continue;
          }
          if ((keyTypeId == GeodeClassIds.CacheableASCIIStringHuge ||
            keyTypeId == GeodeClassIds.CacheableStringHuge)
              && !(valueTypeId == GeodeClassIds.CacheableBoolean))
          {
            continue;
          }
          // null object does not work on server side during deserialization
          if (valueTypeId == GeodeClassIds.CacheableNullString)
          {
            continue;
          }

          keyWrapper = CacheableWrapperFactory.CreateKeyInstance(keyTypeId);
          Assert.IsNotNull(keyWrapper, "CacheableHashMapWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", keyTypeId);
          if (keyWrapper.MaxKeys <= index)
          {
            break;
          }
          keyWrapper.InitKey((int)(keyTypeId << 8) + index, keySize);
          if (!CacheableHelper.IsContainerTypeId(valueTypeId) &&
            !CacheableHelper.IsUnhandledType(valueTypeId))
          {
            valueWrapper = CacheableWrapperFactory.CreateInstance(valueTypeId);
            Assert.IsNotNull(valueWrapper, "CacheableHashMapWrapper.InitRandomValue:" +
              " Could not create an instance of typeId [{0}].", valueTypeId);
            valueWrapper.InitRandomValue(maxSize);
            Util.Log(" updating map " + keyWrapper.CacheableKey + " : " + valueWrapper.Cacheable);
            map.Add(keyWrapper.CacheableKey, valueWrapper.Cacheable);
          }
          index++;
        }
      }
      m_cacheableObject = map;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      //CacheableHashMap value = cacheableObject as CacheableHashMap;
      Dictionary<object, object> value = cacheableObject as Dictionary<object, object>;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableKeyWrapper keyWrapper;
      CacheableWrapper valueWrapper;
      foreach (KeyValuePair<object, object> pair in value)
      {
        Util.Log(" pair " + pair.Key.GetType() + " : " + pair.Value.GetType());
        keyWrapper = CacheableWrapperFactory.CreateKeyInstance((pair.Key));
        Assert.IsNotNull(keyWrapper, "CacheableHashMap.GetChecksum:" +
          " Could not create an instance of typeId [{0}].",
          keyWrapper.TypeId);
        valueWrapper = CacheableWrapperFactory.CreateInstance(
          pair.Value);
        Assert.IsNotNull(valueWrapper, "CacheableHashMap.GetChecksum:" +
          " Could not create an instance of typeId [{0}].",
          valueWrapper.TypeId);

        ckSum ^= (keyWrapper.GetChecksum(pair.Key) ^
          valueWrapper.GetChecksum(pair.Value));
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableHashTableWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableHashTableWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //CacheableHashTable table = new CacheableHashTable();
      System.Collections.Hashtable table = new System.Collections.Hashtable();
      ICollection<UInt32> keyTypeIds =
        CacheableWrapperFactory.GetRegisteredKeyTypeIds();
      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      int keySize = 16;
      maxSize = maxSize / (keyTypeIds.Count * valueTypeIds.Count) + 1;
      CacheableKeyWrapper keyWrapper;
      CacheableWrapper valueWrapper;
      foreach (UInt32 keyTypeId in keyTypeIds)
      {
        int index = 0;
        foreach (UInt32 valueTypeId in valueTypeIds)
        {
          if ((valueTypeId == GeodeClassIds.CacheableASCIIStringHuge ||
            valueTypeId == GeodeClassIds.CacheableStringHuge)
            && !(keyTypeId == GeodeClassIds.CacheableBoolean))
          {
            continue;
          }
          if ((keyTypeId == GeodeClassIds.CacheableASCIIStringHuge ||
            keyTypeId == GeodeClassIds.CacheableStringHuge)
            && !(valueTypeId == GeodeClassIds.CacheableBoolean))
          {
            continue;
          }
          if (valueTypeId == GeodeClassIds.CacheableNullString)
          {
            continue;
          }

          keyWrapper = CacheableWrapperFactory.CreateKeyInstance(keyTypeId);
          Assert.IsNotNull(keyWrapper, "CacheableHashTableWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", keyTypeId);
          if (keyWrapper.MaxKeys <= index)
          {
            break;
          }
          keyWrapper.InitKey((int)(keyTypeId << 8) + index, keySize);

          if (!CacheableHelper.IsContainerTypeId(valueTypeId) &&
              !CacheableHelper.IsUnhandledType(valueTypeId))
          {
            valueWrapper = CacheableWrapperFactory.CreateInstance(valueTypeId);
            Assert.IsNotNull(valueWrapper, "CacheableHashTableWrapper.InitRandomValue:" +
              " Could not create an instance of typeId [{0}].", valueTypeId);
            valueWrapper.InitRandomValue(maxSize);
            if (valueWrapper.Cacheable == null)
            {
              Util.Log(" adding null value " + valueWrapper.GetType() + " : " + valueTypeId);
            }
            else
              Util.Log(" adding value " + valueWrapper.GetType() + " : " + valueTypeId);
            table.Add(keyWrapper.CacheableKey, valueWrapper.Cacheable);
          }
          index++;
        }
      }
      m_cacheableObject = table;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      //Dictionary<object, object> value = new Dictionary<object, object>();
      System.Collections.Hashtable value = cacheableObject as System.Collections.Hashtable;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableKeyWrapper keyWrapper;
      CacheableWrapper valueWrapper;
      foreach (System.Collections.DictionaryEntry pair in value)
      {
        keyWrapper = CacheableWrapperFactory.CreateKeyInstance(
          pair.Key);
        Assert.IsNotNull(keyWrapper, "CacheableHashTable.GetChecksum:" +
          " Could not create an instance of typeId [{0}].",
          keyWrapper.TypeId);
        valueWrapper = CacheableWrapperFactory.CreateInstance(
          pair.Value);
        Assert.IsNotNull(valueWrapper, "CacheableHashTable.GetChecksum:" +
          " Could not create an instance of typeId [{0}].",
          valueWrapper.TypeId);

        ckSum ^= (keyWrapper.GetChecksum(pair.Key) ^
          valueWrapper.GetChecksum(pair.Value));
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableIdentityHashMapWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableIdentityHashMapWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //CacheableIdentityHashMap map = new CacheableIdentityHashMap();
      Dictionary<object, object> map = new Dictionary<object, object>();
      ICollection<UInt32> keyTypeIds =
        CacheableWrapperFactory.GetRegisteredKeyTypeIds();
      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      int keySize = 16;
      maxSize = maxSize / (keyTypeIds.Count * valueTypeIds.Count) + 1;
      CacheableKeyWrapper keyWrapper;
      CacheableWrapper valueWrapper;
      foreach (UInt32 keyTypeId in keyTypeIds)
      {
        int index = 0;
        foreach (UInt32 valueTypeId in valueTypeIds)
        {
          if ((valueTypeId == GeodeClassIds.CacheableASCIIStringHuge ||
            valueTypeId == GeodeClassIds.CacheableStringHuge)
            && !(keyTypeId == GeodeClassIds.CacheableBoolean))
          {
            continue;
          }
          if ((keyTypeId == GeodeClassIds.CacheableASCIIStringHuge ||
            keyTypeId == GeodeClassIds.CacheableStringHuge)
            && !(valueTypeId == GeodeClassIds.CacheableBoolean))
          {
            continue;
          }
          // null object does not work on server side during deserialization
          if (valueTypeId == GeodeClassIds.CacheableNullString)
          {
            continue;
          }

          keyWrapper = CacheableWrapperFactory.CreateKeyInstance(keyTypeId);
          Assert.IsNotNull(keyWrapper, "CacheableIdentityHashMapWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", keyTypeId);
          if (keyWrapper.MaxKeys <= index)
          {
            break;
          }
          keyWrapper.InitKey((int)(keyTypeId << 8) + index, keySize);

          if (!CacheableHelper.IsContainerTypeId(valueTypeId) &&
              !CacheableHelper.IsUnhandledType(valueTypeId))
          {
            valueWrapper = CacheableWrapperFactory.CreateInstance(valueTypeId);
            Assert.IsNotNull(valueWrapper, "CacheableIdentityHashMapWrapper.InitRandomValue:" +
              " Could not create an instance of typeId [{0}].", valueTypeId);
            valueWrapper.InitRandomValue(maxSize);
            map.Add(keyWrapper.CacheableKey, valueWrapper.Cacheable);
          }
          index++;
        }
      }
      m_cacheableObject = map;
    }

    public override uint GetChecksum(object cacheableObject)
    {

      //CacheableHashMap value = cacheableObject as CacheableHashMap;
      Dictionary<object, object> value = new Dictionary<object, object>();
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableKeyWrapper keyWrapper;
      CacheableWrapper valueWrapper;
      foreach (KeyValuePair<object, object> pair in value)
      {
        keyWrapper = CacheableWrapperFactory.CreateKeyInstance(
          pair.Key);
        Assert.IsNotNull(keyWrapper, "CacheableIdentityHashMap.GetChecksum:" +
          " Could not create an instance of typeId [{0}].",
          keyWrapper.TypeId);
        valueWrapper = CacheableWrapperFactory.CreateInstance(
          pair.Value);
        Assert.IsNotNull(valueWrapper, "CacheableIdentityHashMap.GetChecksum:" +
          " Could not create an instance of typeId [{0}].",
          valueWrapper.TypeId);

        ckSum ^= (keyWrapper.GetChecksum(pair.Key) ^
          valueWrapper.GetChecksum(pair.Value));
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableHashSetWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableHashSetWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      CacheableHashSet set = new CacheableHashSet();
      //List<object> set = new List<object>();

      //Dictionary set = new Dictionary();
      ICollection<UInt32> keyTypeIds =
        CacheableWrapperFactory.GetRegisteredKeyTypeIds();
      maxSize = maxSize / keyTypeIds.Count + 1;
      CacheableKeyWrapper wrapper;
      int keyIndex = 0;
      foreach (UInt32 typeId in keyTypeIds)
      {
        if (!CacheableHelper.IsContainerTypeId(typeId) &&
          !CacheableHelper.IsUnhandledType(typeId))
        {
          wrapper = CacheableWrapperFactory.CreateKeyInstance(typeId);
          Assert.IsNotNull(wrapper, "CacheableHashSetWrapper.InitRandomValue:" +
              " Could not create an instance of typeId [{0}].", typeId);
          wrapper.InitKey(keyIndex++, maxSize);


          set.Add(wrapper.CacheableKey);
        }
      }
      m_cacheableObject = set;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      CacheableHashSet value = cacheableObject as CacheableHashSet;
      //List<object> value = cacheableObject as List<object>;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableKeyWrapper wrapper;
      foreach (object key in value)
      {
        wrapper = CacheableWrapperFactory.CreateKeyInstance(key);
        Assert.IsNotNull(wrapper, "CacheableHashSet.GetChecksum:" +
          " Could not create an instance of typeId [{0}].", wrapper.TypeId);
        ckSum ^= wrapper.GetChecksum(key);
      }
      return ckSum;
    }

    public override int GetHashCodeN(object cacheableObject)
    {
      CacheableHashSet value = cacheableObject as CacheableHashSet;

      return value.GetHashCode();
    }
    #endregion
  }

  public class CacheableLinkedHashSetWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableLinkedHashSetWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      CacheableLinkedHashSet set = new CacheableLinkedHashSet();
      //Dictionary<object, object> set = new Dictionary<object, object>();
      //List<object> set = new List<object>();
      ICollection<UInt32> keyTypeIds =
        CacheableWrapperFactory.GetRegisteredKeyTypeIds();
      maxSize = maxSize / keyTypeIds.Count + 1;
      CacheableKeyWrapper wrapper;
      int keyIndex = 0;
      foreach (UInt32 typeId in keyTypeIds)
      {
        if (!CacheableHelper.IsContainerTypeId(typeId) &&
          !CacheableHelper.IsUnhandledType(typeId))
        {
          wrapper = CacheableWrapperFactory.CreateKeyInstance(typeId);
          Assert.IsNotNull(wrapper, "CacheableLinkedHashSetWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", typeId);
          wrapper.InitKey(keyIndex++, maxSize);
          set.Add(wrapper.CacheableKey);
        }
      }
      m_cacheableObject = set;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      //List<object> value = new List<object>();
      CacheableLinkedHashSet value = cacheableObject as CacheableLinkedHashSet;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableKeyWrapper wrapper;
      foreach (object key in value)
      {
        wrapper = CacheableWrapperFactory.CreateKeyInstance(key);
        Assert.IsNotNull(wrapper, "CacheableLinkedHashSet.GetChecksum:" +
          " Could not create an instance of typeId [{0}].", wrapper.TypeId);
        ckSum ^= wrapper.GetChecksum(key);
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableInt16ArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableInt16ArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      int arraySize = maxSize / sizeof(short);
      arraySize = arraySize > 1 ? arraySize : 2;
      short[] value = new short[arraySize];
      for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
      {
        value[arrayIndex] = (short)Util.Rand(short.MaxValue);
      }
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Int16[] obj = cacheableObject as Int16[];
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      short[] value = obj;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      foreach (short v in value)
      {
        short conv = v;
        int numBytes = sizeof(short);
        for (int i = 0; i < numBytes; i++)
        {
          ms.WriteByte((byte)(conv & 0xff));
          conv = (short)(conv >> 8);
        }
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    #endregion
  }

  public class CacheableInt32ArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableInt32ArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      int arraySize = maxSize / sizeof(int);
      arraySize = arraySize > 1 ? arraySize : 2;
      int[] value = new int[arraySize];
      for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
      {
        value[arrayIndex] = Util.Rand(int.MaxValue);
      }
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Int32[] obj = cacheableObject as Int32[];
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      int[] value = obj;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      foreach (int v in value)
      {
        int conv = v;
        int numBytes = sizeof(int);
        for (int i = 0; i < numBytes; i++)
        {
          ms.WriteByte((byte)(conv & 0xff));
          conv = conv >> 8;
        }
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    #endregion
  }

  public class CacheableInt64ArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableInt64ArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      int arraySize = maxSize / sizeof(long);
      arraySize = arraySize > 1 ? arraySize : 2;
      long[] value = new long[arraySize];
      long rnd;
      for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
      {
        rnd = (long)Util.Rand(int.MaxValue);
        rnd = (rnd << 32) + (long)Util.Rand(int.MaxValue);
        value[arrayIndex] = rnd;
      }
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Int64[] obj = cacheableObject as Int64[];
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      long[] value = obj;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      foreach (long v in value)
      {
        long conv = v;
        int numBytes = sizeof(long);
        for (int i = 0; i < numBytes; i++)
        {
          ms.WriteByte((byte)(conv & 0xff));
          conv = conv >> 8;
        }
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    #endregion
  }

  public class CacheableNullStringWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableNullStringWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //m_cacheableObject = CacheableString.Create((string)null);
      m_cacheableObject = null;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      //CacheableString value = cacheableObject as CacheableString;
      Assert.IsNull(cacheableObject, "GetChecksum: expected null object.");
      return (uint)0;
    }

    #endregion
  }

  public class CacheableEmptyStringWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableEmptyStringWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //m_cacheableObject = CacheableString.Create(string.Empty);
      m_cacheableObject = string.Empty;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      string value = cacheableObject as string;
      Assert.IsNotNull(value, "GetChecksum: expected non null object.");
      Assert.IsTrue(value == string.Empty || value.Length == 0, "Expected IsNullOrEmpty " + value.Length);
      return (uint)0;
    }

    #endregion
  }

  public class CacheableEmptyUnicodeStringWrapper : CacheableWrapper
  {
    // TODO : VJR : Is this a real UNICODE empty string?
    // See bugs #324 and #356 to add this wrapper when tracking them.

    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableEmptyUnicodeStringWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //m_cacheableObject = CacheableString.Create(string.Empty);
      m_cacheableObject = string.Empty;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      string value = cacheableObject as string;
      Assert.IsNotNull(value, "GetChecksum: expected non null object.");
      Assert.IsTrue(value == string.Empty || value.Length == 0, "Expected IsNullOrEmpty");
      return (uint)0;
    }

    #endregion
  }

  public class CacheableStringArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableStringArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      int arraySize = 16;
      maxSize = maxSize / arraySize;
      if (maxSize < 2)
      {
        maxSize = 2;
      }
      String[] value = new String[arraySize];
      for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
      {
        if (arrayIndex % 2 == 0)
        {
          byte[] buffer = Util.RandBytes(maxSize / 2);
          value[arrayIndex] = BitConverter.ToString(buffer).Replace("-", string.Empty);
        }
        else
        {
          byte[] buffer = Util.RandBytes(maxSize / 2);
          char[] charArray = new char[maxSize / 2];
          for (int i = 0; i < maxSize / 2; i++)
          {
            charArray[i] = (char)((int)buffer[i] + 0x0901);
          }
          value[arrayIndex] = new String(charArray);
        }
      }
      //m_cacheableObject = CacheableStringArray.Create(value);
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      String[] value = cacheableObject as String[];
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      foreach (String str in value)
      {
        foreach (char c in str)
        {
          ms.WriteByte((byte)(c & 0xff));
          byte uByte = (byte)((c >> 8) & 0xff);
          if (uByte != 0x00)
            ms.WriteByte(uByte);
        }
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    #endregion
  }

  public class CacheableUndefinedWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableUndefinedWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      m_cacheableObject = new CacheableUndefined();
    }

    public override uint GetChecksum(object cacheableObject)
    {
      CacheableUndefined value = cacheableObject as CacheableUndefined;
      // TODO: [sumedh] server sends back null; check this
      //Assert.IsNotNull(value, "GetChecksum: Null object.");

      return 0;
    }

    #endregion
  }

  public class CacheableVectorWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableVectorWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //CacheableVector vec = new CacheableVector();
      System.Collections.ArrayList vec = new System.Collections.ArrayList();

      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      maxSize = maxSize / valueTypeIds.Count + 1;
      CacheableWrapper wrapper;
      foreach (UInt32 typeId in valueTypeIds)
      {
        if (!CacheableHelper.IsContainerTypeId(typeId) &&
          !CacheableHelper.IsUnhandledType(typeId))
        {
          wrapper = CacheableWrapperFactory.CreateInstance(typeId);
          Assert.IsNotNull(wrapper, "CacheableVectorWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", typeId);
          wrapper.InitRandomValue(maxSize);
          vec.Add(wrapper.Cacheable);
        }
      }
      m_cacheableObject = vec;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      System.Collections.ArrayList value = cacheableObject as System.Collections.ArrayList;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableWrapper wrapper;
      foreach (object obj in value)
      {
        if (obj == null)
        {
          continue;
        }
        wrapper = CacheableWrapperFactory.CreateInstance(obj);
        Assert.IsNotNull(wrapper, "CacheableVectorWrapper.GetChecksum:" +
          " Could not create an instance of typeId [{0}].", wrapper.TypeId);
        ckSum ^= wrapper.GetChecksum(obj);
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableObjectArrayWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableObjectArrayWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      CacheableObjectArray arr = new CacheableObjectArray();
      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      maxSize = maxSize / valueTypeIds.Count + 1;
      CacheableWrapper wrapper;
      foreach (UInt32 typeId in valueTypeIds)
      {
        if (!CacheableHelper.IsContainerTypeId(typeId) &&
          !CacheableHelper.IsUnhandledType(typeId))
        {
          wrapper = CacheableWrapperFactory.CreateInstance(typeId);
          Assert.IsNotNull(wrapper, "CacheableObjectArrayWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", typeId);
          wrapper.InitRandomValue(maxSize);

          arr.Add(wrapper.Cacheable);
        }
      }
      m_cacheableObject = arr;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      CacheableObjectArray value = cacheableObject as CacheableObjectArray;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableWrapper wrapper;
      foreach (object obj in value)
      {
        if (obj == null)
        {
          continue;
        }
        wrapper = CacheableWrapperFactory.CreateInstance(obj);
        Assert.IsNotNull(wrapper, "CacheableObjectArrayWrapper.GetChecksum:" +
          " Could not create an instance of typeId [{0}].", wrapper.TypeId);
        ckSum ^= wrapper.GetChecksum(obj);
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableArrayListWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableArrayListWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //CacheableArrayList arrayList = new CacheableArrayList();
      List<object> arrayList = new List<object>();

      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      maxSize = maxSize / valueTypeIds.Count + 1;
      CacheableWrapper wrapper;
      Util.Log(" arrayList size InitRandomValue ");
      foreach (UInt32 typeId in valueTypeIds)
      {
        if (!CacheableHelper.IsContainerTypeId(typeId) &&
          !CacheableHelper.IsUnhandledType(typeId))
        {
          wrapper = CacheableWrapperFactory.CreateInstance(typeId);
          Assert.IsNotNull(wrapper, "CacheableArrayListWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", typeId);
          wrapper.InitRandomValue(maxSize);
          arrayList.Add(wrapper.Cacheable);
        }
      }
      m_cacheableObject = arrayList;
      Util.Log(" arrayList size InitRandomValue " + arrayList.Count);
    }

    public override uint GetChecksum(object cacheableObject)
    {
      List<object> value = cacheableObject as List<object>;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableWrapper wrapper;
      foreach (object obj in value)
      {
        if (obj == null)
        {
          continue;
        }
        wrapper = CacheableWrapperFactory.CreateInstance(obj);
        Assert.IsNotNull(wrapper, "CacheableArrayListWrapper.GetChecksum:" +
          " Could not create an instance of typeId [{0}].", wrapper.TypeId);
        ckSum ^= wrapper.GetChecksum(obj);
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableStackWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableStackWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      //CacheableStack vec = new CacheableStack();
      Stack<object> vec = new Stack<object>();

      ICollection<UInt32> valueTypeIds =
        CacheableWrapperFactory.GetRegisteredValueTypeIds();
      maxSize = maxSize / valueTypeIds.Count + 1;
      CacheableWrapper wrapper;
      foreach (UInt32 typeId in valueTypeIds)
      {
        if (!CacheableHelper.IsContainerTypeId(typeId) &&
            !CacheableHelper.IsUnhandledType(typeId))
        {
          wrapper = CacheableWrapperFactory.CreateInstance(typeId);
          Assert.IsNotNull(wrapper, "CacheableStackWrapper.InitRandomValue:" +
            " Could not create an instance of typeId [{0}].", typeId);
          wrapper.InitRandomValue(maxSize);
          vec.Push(wrapper.Cacheable);
        }
      }
      m_cacheableObject = vec;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      Stack<object> value = cacheableObject as Stack<object>;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      uint ckSum = 0;
      CacheableWrapper wrapper;
      foreach (Object obj in value)
      {
        if (obj == null)
        {
          continue;
        }
        wrapper = CacheableWrapperFactory.CreateInstance(obj);
        Assert.IsNotNull(wrapper, "CacheableStackWrapper.GetChecksum:" +
          " Could not create an instance of typeId [{0}].", wrapper.TypeId);
        ckSum ^= wrapper.GetChecksum(obj);
      }
      return ckSum;
    }

    #endregion
  }

  public class CacheableObjectWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableObjectWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      CData value = CacheableHelper.RandCData();
      m_cacheableObject = CacheableObject.Create(value);
    }

    public override uint GetChecksum(object cacheableObject)
    {
      CacheableObject obj = cacheableObject as CacheableObject;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      CData value = (CData)obj.Value;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      int first = value.First;
      int numBytes = sizeof(int);
      for (int i = 0; i < numBytes; i++)
      {
        ms.WriteByte((byte)(first & 0xff));
        first = first >> 8;
      }
      long second = value.Second;
      numBytes = sizeof(long);
      for (int i = 0; i < numBytes; i++)
      {
        ms.WriteByte((byte)(second & 0xff));
        second = second >> 8;
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }


    #endregion
  }

  public class CacheableObjectXmlWrapper : CacheableWrapper
  {
    #region Static factory creation function

    public static CacheableWrapper Create()
    {
      return new CacheableObjectXmlWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      CData value = CacheableHelper.RandCData();
      m_cacheableObject = CacheableObjectXml.Create(value);
    }

    public override uint GetChecksum(object cacheableObject)
    {
      CacheableObjectXml obj = cacheableObject as CacheableObjectXml;
      Assert.IsNotNull(obj, "GetChecksum: Null object.");

      CData value = (CData)obj.Value;
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      int first = value.First;
      int numBytes = sizeof(int);
      for (int i = 0; i < numBytes; i++)
      {
        ms.WriteByte((byte)(first & 0xff));
        first = first >> 8;
      }
      long second = value.Second;
      numBytes = sizeof(long);
      for (int i = 0; i < numBytes; i++)
      {
        ms.WriteByte((byte)(second & 0xff));
        second = second >> 8;
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    #endregion
  }

  public class PdxCDataWrapper : CacheableKeyWrapper
  {
    #region Static factory creation function

    public static CacheableKeyWrapper Create()
    {
      return new PdxCDataWrapper();
    }

    #endregion

    #region CacheableWrapper Members

    public override void InitRandomValue(int maxSize)
    {
      PdxCData value = CacheableHelper.RandPdxCData();
      m_cacheableObject = value;
    }

    public override uint GetChecksum(object cacheableObject)
    {
      PdxCData value = cacheableObject as PdxCData;
      Assert.IsNotNull(value, "GetChecksum: Null object.");

      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      int first = value.First;
      int numBytes = sizeof(int);
      for (int i = 0; i < numBytes; i++)
      {
        ms.WriteByte((byte)(first & 0xff));
        first = first >> 8;
      }
      long second = value.Second;
      numBytes = sizeof(long);
      for (int i = 0; i < numBytes; i++)
      {
        ms.WriteByte((byte)(second & 0xff));
        second = second >> 8;
      }
      return CacheableHelper.CRC32(ms.ToArray());
    }

    #endregion

    public override int MaxKeys
    {
      get { return 10; }
    }

    public override void InitKey(int keyIndex, int maxSize)
    {
      //PdxCData value = CacheableHelper.RandPdxCData();
      PdxCData value = new PdxCData(keyIndex, keyIndex * 2999);
      m_cacheableObject = value;
    }
  }

  public class TypesClass
  {
    private Object[,] typesArray;
    private Object NullItem = null;
    public TypesClass()
    {
      typesArray = new Object[,] {
      { /*TypeIds.BoolId ,*/ false, false, false, false, false, false, false, false },
      { /*TypeIds.ByteId , */(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7 },
      { /*TypeIds.CharId ,*/ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' },
      { /*TypeIds.DecimalId , */(decimal)0.0m, (decimal)1.0m, (decimal)2.0m, (decimal)3.0m , (decimal)4.0m, (decimal)5.0m, (decimal)6.0m, (decimal)7.0m },
      { /*TypeIds.DoubleId , */(double)0.0, (double)1.0, (double)2.0, (double)3.0 , (double)4.0, (double)5.0, (double)6.0, (double)7.0 },
      { /*TypeIds.FloatId , */(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f , (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f },
      { /*TypeIds.IntId , */0, 1, 2, 3 ,4 , 5, 6, 7},
      { /*TypeIds.LongId , */(long)0L, (long)1L, (long)2L, (long)3L ,(long)4L , (long)5L, (long)6L, (long)7L},
      { /*TypeIds.SbyteId , */(sbyte)0, (sbyte)1, (sbyte)2, (sbyte)3 ,(sbyte)4 , (sbyte)5, (sbyte)6, (sbyte)7 },
      { /*TypeIds.ShortId , */(short)0, (short)1, (short)2, (short)3 ,(short)4 , (short)5, (short)6, (short)7},
      { /*TypeIds.StructId ,*/ 0, 1, 2, 3 ,4 , 5, 6, 7},
      { /*TypeIds.UintId ,*/ (uint)0u, (uint)1u, (uint)2u, (uint)3u ,(uint)4u , (uint)5u, (uint)6u, (uint)7u},
      { /*TypeIds.UlongId ,*/ (ulong)0UL, (ulong)1UL, (ulong)2UL, (ulong)3UL ,(ulong)4UL , (ulong)5UL, (ulong)6UL, (ulong)7UL},
      { /*TypeIds.UshortId ,*/ (ushort)0, (ushort)1, (ushort)2, (ushort)3 ,(ushort)4 , (ushort)5, (ushort)6, (ushort)7 },
      { /*TypeIds.StringId ,*/ "Zero", "One", "Two", "Three" , "Four", "Five", "Six", "Seven" },
      { /*TypeIds.ObjectId ,*/ (object)"Zero", (object)"One", (object)"Two", (object)"Three" , (object)"Four", (object)"Five", (object)"Six", (object)"Seven" },
      { /*TypeIds.BoolArrayId ,*/ new bool[]{false, false, false, false, false, false, false, false}, new bool[]{false, false, false, false, false, false, false, false}, 
        new bool[]{false, false, false, false, false, false, false, false}, new bool[]{false, false, false, false, false, false, false, false}, 
        new bool[]{false, false, false, false, false, false, false, false}, new bool[]{false, false, false, false, false, false, false, false}, 
        new bool[]{false, false, false, false, false, false, false, false}, new bool[]{false, false, false, false, false, false, false, false} },
      { /*TypeIds.ByteArrayId ,*/ new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7}, new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7}, new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7}, 
        new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7}, new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7}, new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7}, new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7},
        new byte[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7} },
      { /*TypeIds.CharArrayId ,*/ new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, 
        new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'},
        new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'} },
      { /*TypeIds.DecimalArrayId ,*/ new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7}, new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7}, new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7}, 
        new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7}, new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7}, new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7}, new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7},
        new decimal[]{(decimal)0, (decimal)1, (decimal)2, (decimal)3, (decimal)4, (decimal)5, (decimal)6, (decimal)7} },      
      { /*TypeIds.doubleArrayId ,*/ new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D}, new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D}, new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D}, 
        new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D}, new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D}, new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D}, new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D},
        new Double[]{(Double)1.7E+0D, (Double)1.7E+1D, (Double)1.7E+2D, (Double)1.7E+3D, (Double)1.7E+4D, (Double)1.7E+5D, (Double)1.7E+6D, (Double)1.7E+7D} },
      { /*TypeIds.floatArrayId ,*/ new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f}, new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f}, new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f}, 
        new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f}, new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f}, new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f}, new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f},
        new float[]{(float)0.0f, (float)1.0f, (float)2.0f, (float)3.0f, (float)4.0f, (float)5.0f, (float)6.0f, (float)7.0f} },
      { /*TypeIds.intArrayId ,*/ new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7}, new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7}, new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7}, 
        new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7}, new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7}, new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7}, new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7},
        new int[]{(int)0, (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)7} },
      { /*TypeIds.longArrayId ,*/ new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L}, new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L}, new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L}, 
        new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L}, new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L}, new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L}, new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L},
        new long[]{(long)0L, (long)1L, (long)2L, (long)3L, (long)4L, (long)5L, (long)6L, (long)7L} },
      { /*TypeIds.sbyteArrayId ,*/ new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 }, new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 }, new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 }, 
        new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 }, new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 }, new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 }, new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 },
        new sbyte[]{(sbyte)0 , (sbyte)1 , (sbyte)2 , (sbyte)3 , (sbyte)4 , (sbyte)5 , (sbyte)6 , (sbyte)7 } },
      { /*TypeIds.shortArrayId ,*/ new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 }, new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 }, new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 }, 
        new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 }, new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 }, new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 }, new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 },
        new short[]{(short)0 , (short)1 , (short)2 , (short)3 , (short)4 , (short)5 , (short)6 , (short)7 } },
      { /*TypeIds.StructArrayId ,*/ new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7},new int[]{0, 1, 2, 3 ,4 , 5, 6, 7}},
      { /*TypeIds.uintArrayId ,*/ new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 }, new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 }, new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 }, 
        new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 }, new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 }, new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 }, new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 },
        new uint[]{(uint)0 , (uint)1 , (uint)2 , (uint)3 , (uint)4 , (uint)5 , (uint)6 , (uint)7 } },
      { /*TypeIds.ulongArrayId ,*/ new ulong[]{(uint)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 }, new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 }, new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 }, 
        new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 }, new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 }, new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 }, new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 },
        new ulong[]{(ulong)0 , (ulong)1 , (ulong)2 , (ulong)3 , (ulong)4 , (ulong)5 , (ulong)6 , (ulong)7 } },
      { /*TypeIds.ushortArrayId ,*/ new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 }, new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 }, new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 }, 
        new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 }, new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 }, new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 }, new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 },
        new ushort[]{(ushort)0 , (ushort)1 , (ushort)2 , (ushort)3 , (ushort)4 , (ushort)5 , (ushort)6 , (ushort)7 } },      
      { /*TypeIds.stringArrayId ,*/ new string[]{"0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" }, new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" }, new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" }, 
        new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" }, new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" }, new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" }, new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4" ,  "5" ,  "6" ,  "7" },
        new string[]{ "0" ,  "1" ,  "2" ,  "3" ,  "4",  "5" ,  "6" ,  "7" } },
      { /*TypeIds.ObjectArrayId ,*/ new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 }, new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 }, new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 }, 
        new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 }, new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 }, new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 }, new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 },
        new object[]{(object)0 , (object)1 , (object)2 , (object)3 , (object)4 , (object)5 , (object)6 , (object)7 } }      
      };
    }

    public enum TypeIds
    {
      BoolId = 0,
      ByteId,
      CharId,
      DecimalId,
      DoubleId,
      FloatId,
      IntId,
      LongId,
      SbyteId,
      ShortId,
      StructId,
      UintId,
      UlongId,
      UshortId,
      StringId,
      ObjectId,
      //These all array types will be values only.
      BoolArrayId,
      ByteArrayId,
      CharArrayId,
      DecimalArrayId,
      DoubleArrayId,
      FloatArrayId,
      IntArrayId,
      LongArrayId,
      SbyteArrayId,
      ShortArrayId,
      StructArrayId,
      UintArrayId,
      UlongArrayId,
      UshortArrayId,
      StringArrayId,
      ObjectArrayId
    };

    public TItem GetTypeItem<TItem>(int KeyId, int index)
    {
      //Util.Log("TItem type is {0} ", typeof(TItem));
      return (TItem)typesArray[KeyId, index];
    }

    public TItem GetArrayTypeItem<TItem>(int KeyId, int index)
    {
      //Util.Log("TItem type is {0} keyid = {1} index = {2}", typeof(TItem), KeyId, index);
      TItem temp = (TItem)typesArray[KeyId, index];
      return temp;
    }

    public Object[,] GetTypesArray()
    {
      return typesArray;
    }

    public Object GetNullItem()
    {
      return NullItem;
    }

  };
  #endregion
}
