public static EntityData Instantiate(EntityData prototype, CellData cell, Direction orientation, int uniqueID)
    {
        if (prototype != null)
        {
            EntityData instance = new EntityData();

            instance.uniqueID = uniqueID;

            instance.instructionSetID = prototype.instructionSetID;
            instance.prefab           = prototype.prefab;
            instance.orientation      = orientation;
            instance.cellData         = cell;
            instance.cellData.entity  = instance;

            instance.lightMode = prototype.lightMode;
            instance.useVFX    = prototype.useVFX;

            instance.gameObject      = GameObject.Instantiate(instance.prefab);
            instance.gameObject.name = instance.instructionSetID;
            instance.gameObject.transform.SetParent(Metrics.entityContainer.transform, true);
            instance.gameObject.transform.eulerAngles = new Vector3(0, Metrics.OrientationFromDirection[(int)instance.orientation], 0);
            instance.gameObject.transform.position    = Coordinates.ToWorldSpace(instance.cellData.coordinates);

            GridData.DamageableInstantiated(instance.gameObject, instance);

            instance.extensions = new Dictionary <string, ExtensionData>();

            if (instance.instructionSetID == PStrings.playerSpawn)
            {
                instance.extensions.Add(PStrings.entityController, new PlayerController());
            }
            else if (instance.instructionSetID == PStrings.zombie)
            {
                instance.extensions.Add(PStrings.entityController, new ZombieController());
            }
            else if (instance.instructionSetID == PStrings.imp)
            {
                instance.extensions.Add(PStrings.entityController, new ImpController());
            }

            instance.controller = (EntityController)instance.GetExtension(PStrings.entityController);
            instance.extensions.Add(PStrings.waypointManager, new WaypointManagerData());
            instance.extensions.Add(PStrings.pathfindManager, new PathfindManagerData());

            if (instance.lightMode != LightMode.Null)
            {
                instance.extensions.Add(PStrings.light, new LightData());
            }
            if (instance.useVFX == true)
            {
                instance.extensions.Add(PStrings.visualEffects, new VisualEffectData());
            }

            GridData.EntityInstanciated(instance);

            foreach (ExtensionData extension in instance.extensions.Values)
            {
                extension.Initialize(uniqueID);
            }

            return(instance);
        }

        if (cell.entity != null)
        {
            EntityData instance = cell.entity;

            cell.entity = null;
            GridData.DamageableDestroyed(instance.gameObject, instance);

            WaypointManagerData waypointManager = (WaypointManagerData)instance.GetExtension(PStrings.waypointManager);
            waypointManager.Purge();

            GameObject.Destroy(instance.gameObject);

            GridData.EntityDestroyed(instance);

            return(instance);
        }

        return(null);
    }