internal GameObject DoInstantiate(Hashtable evData, PhotonPlayer photonPlayer, GameObject resourceGameObject)
    {
        string prefabName = (string)evData[(byte)0];

        Vector3 position;
        if (evData.ContainsKey((byte)1))
        {
            position = (Vector3)evData[(byte)1];
        }
        else
        {
            position = Vector3.zero;
        }

        Quaternion rotation = (Quaternion)evData[(byte)2];

        int group = 0;
        if (evData.ContainsKey((byte)3))
        {
            group = (int)evData[(byte)3];
        }

        PhotonViewID[] viewsIDs;
        if (evData.ContainsKey((byte)4))
        {
            viewsIDs = (PhotonViewID[])evData[(byte)4];
        }
        else
        {
            viewsIDs = new PhotonViewID[0];
        }

        object[] data;
        if (evData.ContainsKey((byte)5))
        {
            data = (object[])evData[(byte)5];
        }
        else
        {
            data = new object[0];
        }

        int serverTime = (int)evData[(byte)6];
        int instantiationId = (int)evData[(byte)7];

        // SetReceiving filtering
        if (this.blockReceivingGroups.Contains(group))
        {
            return null; // Ignore group
        }

        // Check prefab
        if (resourceGameObject == null)
        {
            resourceGameObject = (GameObject)Resources.Load(prefabName, typeof(GameObject));
            if (resourceGameObject == null)
            {
                Debug.LogError("PhotonNetwork error: Could not Instantiate the prefab [" + prefabName + "]. Please verify you have this gameobject in a Resources folder.");
                return null;
            }
        }

        //Add this PhotonView setup info to a list, so that the PhotonView can use this to setup if it's accessed DURING the Instantiation call (in awake)
        InstantiatedPhotonViewSetup newPVS = new InstantiatedPhotonViewSetup();
        newPVS.viewIDs = viewsIDs;
        newPVS.group = group;
        newPVS.instantiationData = data;
        instantiatedPhotonViewSetupList.Add(newPVS);

        // Instantiate the object
        GameObject go = (GameObject)GameObject.Instantiate(resourceGameObject, position, rotation);
        this.instantiatedObjects.Add(instantiationId, go);

        SetupInstantiatedGO(go, newPVS);

        // Send mono event
        object[] messageInfoParam = new object[1];
        messageInfoParam[0] = new PhotonMessageInfo(photonPlayer, serverTime, null);

        MonoBehaviour[] monos = go.GetComponentsInChildren<MonoBehaviour>();
        for (int index = 0; index < monos.Length; index++)
        {
            MonoBehaviour mono = monos[index];
            MethodInfo methodI = this.GetCachedMethod(mono, PhotonNetworkingMessage.OnPhotonInstantiate);
            if (methodI != null)
            {
                object result = methodI.Invoke((object)mono, messageInfoParam);
                if (methodI.ReturnType == typeof(System.Collections.IEnumerator))
                {
                    PhotonHandler.SP.StartCoroutine((IEnumerator)result);
                }
            }
        }

        return go;
    }
    //TODO: can we get rid of this?!
    void SetupInstantiatedGO(GameObject goRoot, InstantiatedPhotonViewSetup setupInfo)
    {
        if (!this.instantiatedPhotonViewSetupList.Contains(setupInfo))
        {
            // Setup has already been run for this setupInfo (via a Awake access on the PhotonView)
            return;
        }

        // Assign view IDs
        PhotonView[] views = (PhotonView[])goRoot.GetComponentsInChildren<PhotonView>();
        for (int index = 0; index < views.Length; index++)
        {
            PhotonView view = views[index];
            view.viewID = setupInfo.viewIDs[index];
            view.group = setupInfo.group;
            view.instantiationData = setupInfo.instantiationData;
        }

        instantiatedPhotonViewSetupList.Remove(setupInfo);
    }
    void SetupInstantiatedGO(GameObject goRoot, InstantiatedPhotonViewSetup setupInfo)
    {
        if (!instantiatedPhotonViewSetupList.Contains(setupInfo))
        {   //Setup has already been run for this setupInfo (via a Awake access on the PhotonView)
            return;
        }
        // Assign view IDs
        PhotonView[] views = (PhotonView[])goRoot.GetComponentsInChildren<PhotonView>();
        int i = 0;
        foreach (PhotonView view in views)
        {
            view.viewID = setupInfo.viewIDs[i];
            view.group = setupInfo.group;
            view.instantiationData = setupInfo.instantiationData;
            i++;
        }

        instantiatedPhotonViewSetupList.Remove(setupInfo);
    }