/// <summary>
        /// Spawn a new instance of the given CESharp entity.
        /// </summary>
        /// <param name="name">Name.</param>
        public static T Spawn <T> (string name = null) where T : BaseEntity
        {
            EntityClass cls = s_entityClassRegistry.GetEntityClass <T> ();

            if (cls == null)
            {
                Log.Warning("[EntityFramework] Could not find managed CESharp entity class for {0}", typeof(T).Name);
                return(null);
            }

            if (typeof(T).IsAbstract)
            {
                Log.Warning("[EntityFramework] Cannot instantiate {0} as it is an abstract class.", typeof(T).Name);
                return(null);
            }

            int i = 1;

            while (String.IsNullOrEmpty(name))
            {
                string test = cls.Description.sName + i.ToString();
                if (Global.gEnv.pEntitySystem.FindEntityByName(test) == null)
                {
                    name = test;
                }
                i++;
            }

            SEntitySpawnParams sParams = new SEntitySpawnParams();

            sParams.sName  = name;
            sParams.pClass = cls.NativeClass;
            IEntity pEnt = Global.gEnv.pEntitySystem.SpawnEntity(sParams);

            if (s_managedEntities.ContainsKey(pEnt.GetId()))
            {
                if (s_managedEntities [pEnt.GetId()].GetType() == typeof(T))
                {
                    return(s_managedEntities [pEnt.GetId()] as T);
                }
                else
                {
                    Log.Error("[EntityFramework] Entity {0} already registered, but with a different type ({1} instead of {2})", pEnt.GetId(), pEnt.GetType().FullName, typeof(T).FullName);
                    return(null);
                }
            }
            else
            {
                Log.Info("[EntityFramework] Spawn entity: {0} ({1})", name, cls.ProtoType.Name);
                T instance = (T)cls.CreateInstance(pEnt);
                cls.NativeClass.LoadScript(true);
                s_managedEntities.Add(pEnt.GetId(), instance);
                return(instance);
            }
        }
        /// <summary>
        /// Called when CRYENGINE's entity system is spawning an entity. Will check if the entity class is registered with the managed entity class registry and if yes, it will create a managed CESharp entity instance.
        /// </summary>
        private static void OnSpawn(IEntity pEntity, SEntitySpawnParams arg1)
        {
            if (s_managedEntities.ContainsKey(pEntity.GetId()))
            {
                return;
            }

            EntityClass managedClass = s_entityClassRegistry.GetEntityClass(arg1);

            if (managedClass == null)
            {
                return;
            }

            Log.Info("[EntityFramework] Spawn entity: {0} ({1})", arg1.sName, managedClass.ProtoType.Name);
            s_managedEntities.Add(pEntity.GetId(), managedClass.CreateInstance(pEntity, arg1.HasEntityNode() ? arg1.entityNode : null));
        }
        /// <summary>
        /// Setup the CESharp EntityFramework, including registering of discovered CESharp entity classes and assumption of already spawned CESharp entites.
        /// </summary>
        public static void Instantiate(InterDomainHandler handler)
        {
            EntityProperty.RegisterConverters();
            s_managedEntities     = new Dictionary <uint, BaseEntity> ();
            s_entityClassRegistry = new EntityClassRegistry();
            s_entityClassRegistry.RegisterAll();
            s_entitySystemSink             = new EntitySystemSink();
            s_entitySystemSink.Spawn      += OnSpawn;
            s_entitySystemSink.Event      += OnEvent;
            s_entitySystemSink.Remove     += OnRemove;
            s_entityUpdateListener         = new EntityUpdateListener();
            s_entityUpdateListener.Update += OnUpdate;

            // Assume already spawned entities
            IEntityIt it = Global.gEnv.pEntitySystem.GetEntityIterator();

            if (it != null)
            {
                it.MoveFirst();

                IEntity pEntity = null;
                while (!it.IsEnd())
                {
                    pEntity = it.Next();

                    EntityClass managedClass = s_entityClassRegistry.GetEntityClass(pEntity);
                    if (managedClass == null)
                    {
                        continue;
                    }

                    Log.Info("[EntityFramework] Assume entity: {0} ({1})", pEntity.GetName(), managedClass.ProtoType.Name);
                    BaseEntity instance = managedClass.CreateInstance(pEntity);
                    handler.RetrieveEntity(instance);
                    s_managedEntities.Add(pEntity.GetId(), instance);
                }
            }
        }