/// <summary>
        ///
        /// Material definitions
        ///
        /// Parse material definitions data
        /// Starts material definition node parsing.
        /// If a new material has been created this function will go through stored meshes
        /// and check if it can create new mesh with this material available.
        /// </summary>
        public static void ParseMaterialDefinitionData(System.IntPtr materialDefinitionDataPtr)
        {
            try
            {
                var materialDefinitionData = (MaterialDefinitionData)System.Runtime.InteropServices.Marshal.PtrToStructure(materialDefinitionDataPtr, typeof(MaterialDefinitionData));

                // If all dependants are here, parse object data
                bool dependencySuccess = MaterialDefinitionHandler.DependencyCheck(materialDefinitionData);
                if (dependencySuccess)
                {
                    ParseMaterialDefinitionData(materialDefinitionData);

                    // Delete object data
                    ImportMenu.stpUnityDeleteMaterialDefinitionData(materialDefinitionDataPtr);
                }
                // If we are missing dependants store the object data
                else
                {
                    materialDefinitionDataStore.Add(materialDefinitionDataPtr);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);

                // Delete object data
                ImportMenu.stpUnityDeleteMaterialDefinitionData(materialDefinitionDataPtr);
            }
        }
        public static void ParseMaterialDefinitionData(MaterialDefinitionData materialDefinitionData)
        {
            // Check if the object already exists in the package mapper
            if (PackageMapper.TokenExistsInCache(materialDefinitionData.entityToken))
            {
                // If object exists skip update
                // TODO: At some point decide how we handle material updates.
                // Important note to consider is that we will be adding already existing
                // materials in Unity that STP didn't create to the material map and how to handle those updates.
                Debug.LogWarning("Material Definition Update not supported yet! Discarding material data!!");
                return;
            }
            else
            {
                // Create a new GameObject in the hierarchy
                Object newMaterial = MaterialDefinitionHandler.CreateMaterial(materialDefinitionData);

                if (newMaterial)
                {
                    PackageMapper.MapTokenToObject(materialDefinitionData.entityToken, newMaterial);

                    // If a new material has been created go through the stored list of meshes
                    // to see if we can create a new one with this material available
                    IterateMeshStore();
                }
            }
        }
        // Iterate through material store that were missing dependants and check if we can create new material objects
        // or update existing material objects
        public static void IterateMaterialDefinitionStore()
        {
            for (int i = materialDefinitionDataStore.Count - 1; i >= 0; i--)
            {
                MaterialDefinitionData materialDefinitionData = (MaterialDefinitionData)System.Runtime.InteropServices.Marshal.PtrToStructure(materialDefinitionDataStore[i], typeof(MaterialDefinitionData));

                // If all dependants are here, create the material
                bool dependencySuccess = MaterialDefinitionHandler.DependencyCheck(materialDefinitionData);
                if (dependencySuccess)
                {
                    ParseMaterialDefinitionData(materialDefinitionData);

                    // Delete object data
                    ImportMenu.stpUnityDeleteMaterialDefinitionData(materialDefinitionDataStore[i]);

                    // Remove from the store
                    materialDefinitionDataStore.RemoveAt(i);
                }
            }
        }
        private static bool PushMaterial(Material material)
        {
            var materialPrefab = PackageMapper.GetPrefabFromMaterial(material);

            // If material prefab doesn't exist it means this material is new to STP and we need
            // to add it to the database and generate a prefab for it
            if (!materialPrefab)
            {
                materialPrefab = MaterialDefinitionHandler.CreateNonSTPMaterialPrefab(material);
            }

            var tokenStore = materialPrefab.GetComponent <FoundryUniqueToken>();

            // If the token store is non existant bail out
            if (!tokenStore || System.String.IsNullOrEmpty(tokenStore.uniqueToken))
            {
                Debug.LogWarningFormat("Material '{0}' push failed! No available unique token!", material.name);
                return(false);
            }

            MaterialDefinitionHandler.CreateAndSendMaterialDefinitionRequest(material, tokenStore.uniqueToken);
            return(true);
        }