public virtual object BuildGenericCollectionInstance(CollectionObjectInfo coi, Type t)
		{
            Type genericType = t.GetGenericTypeDefinition();
            object newCollection = null;
            try
            {
                newCollection = System.Activator.CreateInstance(t);
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e);
                throw new ODBRuntimeException(NeoDatisError.CollectionInstanciationError.AddParameter(coi.GetRealCollectionClassName()));
            }
            System.Collections.IEnumerator iterator = coi.GetCollection().GetEnumerator();
            AbstractObjectInfo aoi = null;
            MethodInfo method = t.GetMethod("Add");
            while (iterator.MoveNext())
            {
                aoi = (AbstractObjectInfo)iterator.Current;
                if (!aoi.IsDeletedObject())
                {
                    method.Invoke(newCollection, new object[] { BuildOneInstance(aoi) });
                }
            }
            return newCollection;
           
		}
        private NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo IntrospectCollection
            (System.Collections.ICollection collection, bool introspect, System.Collections.Generic.IDictionary
            <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects
            , NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback
            callback)
        {
            if (collection == null)
            {
                return(new NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo());
            }
            // A collection that contain all meta representations of the collection
            // objects
            System.Collections.Generic.ICollection <NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo
                                                    > collectionCopy = new System.Collections.Generic.List <NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo
                                                                                                            >(collection.Count);
            // A collection to keep references all all non native objects of the
            // collection
            // This will be used later to get all non native objects contained in an
            // object
            System.Collections.Generic.ICollection <NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                    > nonNativesObjects = new System.Collections.Generic.List <NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                                                                               >(collection.Count);
            NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null;
            System.Collections.IEnumerator iterator = collection.GetEnumerator();
            while (iterator.MoveNext())
            {
                object o = iterator.Current;
                NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null;
                // Null objects are not inserted in list
                if (o != null)
                {
                    ci  = GetClassInfo(OdbClassUtil.GetFullName(o.GetType()));
                    aoi = GetObjectInfo(o, ci, introspect, alreadyReadObjects, callback);
                    collectionCopy.Add(aoi);
                    if (aoi.IsNonNativeObject())
                    {
                        // o is not null, call the callback with it
                        //callback.objectFound(o);
                        // This is a non native object
                        nonNativesObjects.Add((NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo)aoi
                                              );
                    }
                }
            }
            NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo coi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo
                                                                                (collectionCopy, nonNativesObjects);
            string realCollectionClassName = OdbClassUtil.GetFullName(collection.GetType());

            if (realCollectionClassName.IndexOf("$") != -1)
            {
                coi.SetRealCollectionClassName(type.GetDefaultInstanciationClass().FullName);
            }
            else
            {
                coi.SetRealCollectionClassName(realCollectionClassName);
            }
            return(coi);
        }
        public virtual object BuildCollectionInstance(CollectionObjectInfo coi)
		{
            Type t = classPool.GetClass(coi.GetRealCollectionClassName());

            if(t.IsGenericType){
                return BuildGenericCollectionInstance(coi,t);
            }else{
                return BuildNonGenericCollectionInstance(coi,t);
            }
           
		}
		/// <summary>
		/// Checks if something in the Collection has changed, if yes, stores the
		/// change
		/// </summary>
		/// <param name="nnoi1">
		/// The first Object meta representation (nnoi =
		/// NonNativeObjectInfo)
		/// </param>
		/// <param name="nnoi2">The second object meta representation</param>
		/// <param name="fieldIndex">The field index that this collection represents</param>
		/// <param name="coi1">
		/// The Meta representation of the collection 1 (coi =
		/// CollectionObjectInfo)
		/// </param>
		/// <param name="coi2">The Meta representation of the collection 2</param>
		/// <param name="objectRecursionLevel"></param>
		/// <returns>true if 2 collection representation are different</returns>
		private bool ManageCollectionChanges(NonNativeObjectInfo
			 nnoi1, NonNativeObjectInfo nnoi2, int fieldId
			, CollectionObjectInfo coi1, CollectionObjectInfo
			 coi2, int objectRecursionLevel)
		{
			ICollection<AbstractObjectInfo
				> collection1 = coi1.GetCollection();
			ICollection<AbstractObjectInfo
				> collection2 = coi2.GetCollection();
			if (collection1.Count != collection2.Count)
			{
				System.Text.StringBuilder buffer = new System.Text.StringBuilder();
				buffer.Append("Collection size has changed oldsize=").Append(collection1.Count).Append
					("/newsize=").Append(collection2.Count);
				StoreChangedObject(nnoi1, nnoi2, fieldId, coi1, coi2, buffer.ToString(), objectRecursionLevel
					);
				return true;
			}
			System.Collections.IEnumerator iterator1 = collection1.GetEnumerator();
			System.Collections.IEnumerator iterator2 = collection2.GetEnumerator();
			AbstractObjectInfo value1 = null;
			AbstractObjectInfo value2 = null;
			int index = 0;
			while (iterator1.MoveNext())
			{
                iterator2.MoveNext();
                value1 = (AbstractObjectInfo)iterator1.Current;
				value2 = (AbstractObjectInfo)iterator2.Current;
				bool hasChanged = this.HasChanged(value1, value2, objectRecursionLevel);
				if (hasChanged)
				{
					// We consider collection has changed only if object are
					// different, If objects are the same instance, but something in
					// the object has changed, then the collection has not
					// changed,only the object
					if (value1.IsNonNativeObject() && value2.IsNonNativeObject())
					{
						NonNativeObjectInfo nnoia = (NonNativeObjectInfo
							)value1;
						NonNativeObjectInfo nnoib = (NonNativeObjectInfo
							)value2;
						if (nnoia.GetOid() != null && !nnoia.GetOid().Equals(nnoi2.GetOid()))
						{
							// Objects are not the same instance -> the collection
							// has changed
							StoreChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "List element index " +
								 index + " has changed", objectRecursionLevel);
						}
					}
					else
					{
						supportInPlaceUpdate = false;
						nbChanges++;
					}
					//storeChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "List element index " + index + " has changed", objectRecursionLevel);
					return true;
				}
				index++;
			}
			return false;
		}
        public virtual object BuildNonGenericCollectionInstance(CollectionObjectInfo coi, Type t)
		{
            System.Collections.IList newCollection = (System.Collections.IList)System.Activator.CreateInstance(classPool.GetClass(coi.GetRealCollectionClassName()));
            System.Collections.IEnumerator iterator = coi.GetCollection().GetEnumerator();
            AbstractObjectInfo aoi = null;
            
            while (iterator.MoveNext())
            {
                aoi = (AbstractObjectInfo)iterator.Current;
                if (!aoi.IsDeletedObject())
                {
                    newCollection.Add(BuildOneInstance(aoi));
                }
            }
            return newCollection;
		}
		private NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo IntrospectCollection
			(System.Collections.ICollection collection, bool introspect, System.Collections.Generic.IDictionary
			<object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects
			, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback
			 callback)
		{
			if (collection == null)
			{
				return new NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo();
			}
			// A collection that contain all meta representations of the collection
			// objects
			System.Collections.Generic.ICollection<NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo
				> collectionCopy = new System.Collections.Generic.List<NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo
				>(collection.Count);
			// A collection to keep references all all non native objects of the
			// collection
			// This will be used later to get all non native objects contained in an
			// object
			System.Collections.Generic.ICollection<NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
				> nonNativesObjects = new System.Collections.Generic.List<NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
				>(collection.Count);
			NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null;
			System.Collections.IEnumerator iterator = collection.GetEnumerator();
			while (iterator.MoveNext())
			{
				object o = iterator.Current;
				NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null;
				// Null objects are not inserted in list
				if (o != null)
				{
					ci = GetClassInfo(OdbClassUtil.GetFullName(o.GetType()));
					aoi = GetObjectInfo(o, ci, introspect, alreadyReadObjects, callback);
					collectionCopy.Add(aoi);
					if (aoi.IsNonNativeObject())
					{
						// o is not null, call the callback with it
						//callback.objectFound(o);
						// This is a non native object
						nonNativesObjects.Add((NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo)aoi
							);
					}
				}
			}
			NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo coi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo
				(collectionCopy, nonNativesObjects);
			string realCollectionClassName = OdbClassUtil.GetFullName(collection.GetType());
			if (realCollectionClassName.IndexOf("$") != -1)
			{
				coi.SetRealCollectionClassName(type.GetDefaultInstanciationClass().FullName);
			}
			else
			{
				coi.SetRealCollectionClassName(realCollectionClassName);
			}
			return coi;
		}