private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntropectAtomicNativeArray
            (object array, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type)
        {
            int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array);

            NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo anoi = null;
            object[] arrayCopy = new object[length];
            int      typeId    = 0;

            for (int i = 0; i < length; i++)
            {
                object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i);
                if (o != null)
                {
                    // If object is not null, try to get the exact type
                    typeId = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.GetFromClass(o.GetType()).GetId
                                 ();
                    anoi         = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, typeId);
                    arrayCopy[i] = anoi;
                }
                else
                {
                    // Else take the declared type
                    arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type
                                                                                                 .GetId());
                }
            }
            NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo
                                                                           (arrayCopy, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.Array, type.GetId());
            return(aoi);
        }
 protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetNativeObjectInfoInternal
     (NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, object o, bool recursive
     , System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                               > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback
     callback)
 {
     NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null;
     if (type.IsAtomicNative())
     {
         if (o == null)
         {
             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetId());
         }
         else
         {
             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, type
                                                                                   .GetId());
         }
     }
     else
     {
         if (type.IsCollection())
         {
             aoi = IntrospectCollection((System.Collections.ICollection)o, recursive, alreadyReadObjects
                                        , type, callback);
         }
         else
         {
             if (type.IsArray())
             {
                 if (o == null)
                 {
                     aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo(null);
                 }
                 else
                 {
                     // Gets the type of the elements of the array
                     string realArrayClassName = OdbClassUtil.GetFullName(o.GetType().GetElementType());
                     NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aroi = null;
                     if (recursive)
                     {
                         aroi = IntrospectArray(o, recursive, alreadyReadObjects, type, callback);
                     }
                     else
                     {
                         aroi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])o
                                                                                         );
                     }
                     aroi.SetRealArrayComponentClassName(realArrayClassName);
                     aoi = aroi;
                 }
             }
             else
             {
                 if (type.IsMap())
                 {
                     if (o == null)
                     {
                         aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.MapObjectInfo(null, type, type.GetDefaultInstanciationClass
                                                                                          ().FullName);
                     }
                     else
                     {
                         MapObjectInfo moi = null;
                         string        realMapClassName = OdbClassUtil.GetFullName(o.GetType());
                         bool          isGeneric        = o.GetType().IsGenericType;
                         if (isGeneric)
                         {
                             moi = new MapObjectInfo(IntrospectGenericMap((System.Collections.Generic.IDictionary <object, object>)o, recursive, alreadyReadObjects, callback), type, realMapClassName);
                         }
                         else
                         {
                             moi = new MapObjectInfo(IntrospectNonGenericMap((System.Collections.IDictionary)o, recursive, alreadyReadObjects, callback), type, realMapClassName);
                         }
                         if (realMapClassName.IndexOf("$") != -1)
                         {
                             moi.SetRealMapClassName(OdbClassUtil.GetFullName(type.GetDefaultInstanciationClass()));
                         }
                         aoi = moi;
                     }
                 }
                 else
                 {
                     if (type.IsEnum())
                     {
                         System.Enum enumObject = (System.Enum)o;
                         if (enumObject == null)
                         {
                             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetSize(
                                                                                                     ));
                         }
                         else
                         {
                             Type   t             = enumObject.GetType();
                             string enumClassName = enumObject == null ? null : OdbClassUtil.GetFullName(enumObject.GetType());
                             // Here we must check if the enum is already in the meta model. Enum must be stored in the meta
                             // model to optimize its storing as we need to keep track of the enum class
                             // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long
                             // instead of the full enum class name string
                             NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = GetClassInfo(enumClassName);
                             string enumValue = enumObject == null ? null : enumObject.ToString();
                             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.EnumNativeObjectInfo(ci, enumValue
                                                                                                 );
                         }
                     }
                 }
             }
         }
     }
     return(aoi);
 }
		private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntropectAtomicNativeArray
			(object array, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type)
		{
			int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array);
			NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo anoi = null;
			object[] arrayCopy = new object[length];
			int typeId = 0;
			for (int i = 0; i < length; i++)
			{
				object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i);
				if (o != null)
				{
					// If object is not null, try to get the exact type
					typeId = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.GetFromClass(o.GetType()).GetId
						();
					anoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, typeId);
					arrayCopy[i] = anoi;
				}
				else
				{
					// Else take the declared type
					arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type
						.GetId());
				}
			}
			NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo
				(arrayCopy, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.Array, type.GetId());
			return aoi;
		}
		public virtual object BuildOneInstance(AtomicNativeObjectInfo objectInfo)
		{
			int odbTypeId = objectInfo.GetOdbTypeId();
			long l = -1;
			switch (odbTypeId)
			{
				case ODBType.NullId:
				{
					return null;
				}

				case ODBType.StringId:
				{
					return objectInfo.GetObject();
				}

				case ODBType.DateId:
				{
					return objectInfo.GetObject();
				}

				case ODBType.LongId:
				case ODBType.NativeLongId:
				{
					if (objectInfo.GetObject().GetType() == typeof(System.Int64))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToInt64(objectInfo.GetObject().ToString());
				}

				case ODBType.IntegerId:
				case ODBType.NativeIntId:
				{
					if (objectInfo.GetObject().GetType() == typeof(int))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToInt32(objectInfo.GetObject().ToString());
				}

				case ODBType.BooleanId:
				case ODBType.NativeBooleanId:
				{
					if (objectInfo.GetObject().GetType() == typeof(bool))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToBoolean(objectInfo.GetObject().ToString());
				}

				case ODBType.ByteId:
				case ODBType.NativeByteId:
				{
					if (objectInfo.GetObject().GetType() == typeof(byte))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToByte(objectInfo.GetObject().ToString());
				}

				case ODBType.ShortId:
				case ODBType.NativeShortId:
				{
					if (objectInfo.GetObject().GetType() == typeof(short))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToInt16(objectInfo.GetObject().ToString());
				}

				case ODBType.FloatId:
				case ODBType.NativeFloatId:
				{
					if (objectInfo.GetObject().GetType() == typeof(float))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToSingle(objectInfo.GetObject().ToString());
				}

				case ODBType.DoubleId:
				case ODBType.NativeDoubleId:
				{
					if (objectInfo.GetObject().GetType() == typeof(double))
					{
						return objectInfo.GetObject();
					}
					return System.Convert.ToDouble(objectInfo.GetObject().ToString());
				}

				case NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.BigDecimalId:
				{
					return System.Decimal.Parse(objectInfo.GetObject().ToString(), System.Globalization.NumberStyles.Any);
				}

				case NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.BigIntegerId:
				{
					return System.Decimal.Parse(objectInfo.GetObject().ToString(), System.Globalization.NumberStyles.Any);
				}

				case ODBType.CharacterId:
				case ODBType.NativeCharId:
				{
					if (objectInfo.GetObject().GetType() == typeof(char))
					{
						return objectInfo.GetObject();
					}
					return objectInfo.GetObject().ToString()[0];
				}

				case ODBType.ObjectOidId:
				{
					if (objectInfo.GetObject().GetType() == typeof(long))
					{
						l = (long)objectInfo.GetObject();
					}
					else
					{
						OID oid = (OID)objectInfo.GetObject();
						l = oid.GetObjectId();
					}
					return OIDFactory.BuildObjectOID(l);
				}

				case ODBType.ClassOidId:
				{
					if (objectInfo.GetObject().GetType() == typeof(long))
					{
						l = (long)objectInfo.GetObject();
					}
					else
					{
						l = System.Convert.ToInt64(objectInfo.GetObject().ToString());
					}
					return OIDFactory.BuildClassOID(l);
				}

				default:
				{
					throw new ODBRuntimeException(NeoDatisError.InstanceBuilderNativeTypeInCollectionNotSupported
							.AddParameter(ODBType.GetNameFromId(odbTypeId)));
					break;
				}
			}
		}
		protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetNativeObjectInfoInternal
			(NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, object o, bool recursive
			, System.Collections.Generic.IDictionary<object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
			> alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback
			 callback)
		{
			NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null;
			if (type.IsAtomicNative())
			{
				if (o == null)
				{
					aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetId());
				}
				else
				{
					aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, type
						.GetId());
				}
			}
			else
			{
				if (type.IsCollection())
				{
					aoi = IntrospectCollection((System.Collections.ICollection)o, recursive, alreadyReadObjects
						, type, callback);
				}
				else
				{
					if (type.IsArray())
					{
						if (o == null)
						{
							aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo(null);
						}
						else
						{
							// Gets the type of the elements of the array
							string realArrayClassName = OdbClassUtil.GetFullName(o.GetType().GetElementType());
							NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aroi = null;
							if (recursive)
							{
								aroi = IntrospectArray(o, recursive, alreadyReadObjects, type, callback);
							}
							else
							{
								aroi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])o
									);
							}
							aroi.SetRealArrayComponentClassName(realArrayClassName);
							aoi = aroi;
						}
					}
					else
					{
						if (type.IsMap())
						{
							if (o == null)
							{
								aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.MapObjectInfo(null, type, type.GetDefaultInstanciationClass
									().FullName);
							}
							else
							{
								MapObjectInfo moi = null;
								string realMapClassName = OdbClassUtil.GetFullName(o.GetType());
                                bool isGeneric = o.GetType().IsGenericType;
                                if (isGeneric)
                                {
                                    moi = new MapObjectInfo(IntrospectGenericMap((System.Collections.Generic.IDictionary<object,object>)o, recursive, alreadyReadObjects, callback), type, realMapClassName);
                                }
                                else
                                {
                                    moi = new MapObjectInfo(IntrospectNonGenericMap((System.Collections.IDictionary)o, recursive, alreadyReadObjects, callback), type, realMapClassName);
                                }
								if (realMapClassName.IndexOf("$") != -1)
								{
									moi.SetRealMapClassName(OdbClassUtil.GetFullName(type.GetDefaultInstanciationClass()));
								}
								aoi = moi;
							}
						}
						else
						{
							if (type.IsEnum())
							{
								System.Enum enumObject = (System.Enum)o;
								if (enumObject == null)
								{
									aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetSize(
										));
								}
								else
								{
                                    Type t = enumObject.GetType();
                                    string enumClassName = enumObject == null ? null : OdbClassUtil.GetFullName(enumObject.GetType());
									// Here we must check if the enum is already in the meta model. Enum must be stored in the meta
									// model to optimize its storing as we need to keep track of the enum class
									// for each enum stored. So instead of storing the enum class name, we can store enum class id, a long
									// instead of the full enum class name string
									NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = GetClassInfo(enumClassName);
									string enumValue = enumObject == null ? null : enumObject.ToString();
									aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.EnumNativeObjectInfo(ci, enumValue
										);
								}
							}
						}
					}
				}
			}
			return aoi;
		}