void RemoveEntryAssetType(TableEntryReference tableEntry, string entryCode)
        {
            long keyId = tableEntry.ReferenceType == TableEntryReference.Type.Name ? SharedData.GetId(tableEntry.Key) : tableEntry.KeyId;

            if (keyId == SharedTableData.EmptyId)
            {
                return;
            }

            // Update type metadata
            // We cant use a foreach here as we are sometimes inside of a loop and exceptions will be thrown (Collection was modified).
            for (int i = 0; i < SharedData.Metadata.MetadataEntries.Count; ++i)
            {
                var md = SharedData.Metadata.MetadataEntries[i];
                if (md is AssetTypeMetadata at)
                {
                    if (at.Contains(keyId))
                    {
                        at.RemoveEntry(keyId, entryCode);
                        if (at.IsEmpty)
                        {
                            SharedData.Metadata.RemoveMetadata(at);
                        }
                        return;
                    }
                }
            }
        }
        void SetEntryAssetType(TableEntryReference tableEntry, Type assetType, string entryCode)
        {
            long keyId = tableEntry.ReferenceType == TableEntryReference.Type.Name ? SharedData.GetId(tableEntry.Key, true) : tableEntry.KeyId;

            // Update type metadata
            AssetTypeMetadata entryMetadata = null;
            AssetTypeMetadata typeMetadata  = null;

            // We cant use a foreach here as we are sometimes inside of a loop and exceptions will be thrown (Collection was modified).
            for (int i = 0; i < SharedData.Metadata.MetadataEntries.Count; ++i)
            {
                var md = SharedData.Metadata.MetadataEntries[i];
                if (md is AssetTypeMetadata at)
                {
                    if (at.Contains(keyId))
                    {
                        if (!at.Type.IsAssignableFrom(assetType))
                        {
                            at.RemoveEntry(keyId, entryCode);
                            if (at.IsEmpty)
                            {
                                SharedData.Metadata.RemoveMetadata(at);
                            }

                            // Are other tables still using the type for the same id?
                            if (at.Contains(tableEntry.KeyId))
                            {
                                var name = SharedData.GetEntry(tableEntry.KeyId);
                                Debug.LogWarning($"Table entry {name}({tableEntry.KeyId}) contains mixed types. Both {at.Type} and {assetType} are used.");
                            }
                        }
                        else
                        {
                            entryMetadata = at;
                            break;
                        }
                    }

                    if (at.Type == assetType)
                    {
                        typeMetadata = at;
                        break;
                    }
                }
            }
            var foundMetadata = entryMetadata ?? typeMetadata;

            if (foundMetadata == null)
            {
                foundMetadata = new AssetTypeMetadata()
                {
                    Type = assetType
                };
                SharedData.Metadata.AddMetadata(foundMetadata);
            }

            foundMetadata.AddEntry(keyId, entryCode);
        }
        /// <summary>
        /// Returns the expected type for the entry.
        /// When an asset is first added to an entry, the type is recorded so that the Editor can ensure all subsequent assets that are added are compatible.
        /// </summary>
        /// <param name="tableEntry">The entry to return the asset type for.</param>
        /// <returns>The expected asset type or typeof(Object) if unknown.</returns>
        public Type GetEntryAssetType(TableEntryReference tableEntry)
        {
            long keyId = tableEntry.ReferenceType == TableEntryReference.Type.Name ? SharedData.GetId(tableEntry.Key) : tableEntry.KeyId;

            foreach (AssetTypeMetadata assetType in SharedData.Metadata.MetadataEntries)
            {
                if (assetType == null)
                {
                    continue;
                }

                if (assetType.Contains(keyId))
                {
                    return(assetType.Type);
                }
            }
            return(typeof(Object));
        }