/// <summary>
 /// Removes the given descriptor from this set so that it can no longer be looked up from the lookup methods.
 /// This operation is idempotent.
 /// </summary>
 /// <param name="schemaDescriptor"> the descriptor to remove. </param>
 public virtual void Remove(T schemaDescriptor)
 {
     foreach (int entityTokenId in schemaDescriptor.schema().EntityTokenIds)
     {
         PropertyMultiSet any = _byEntityToken.get(entityTokenId);
         if (any != null && any.Remove(schemaDescriptor))
         {
             _byEntityToken.remove(entityTokenId);
         }
     }
 }
 /// <summary>
 /// Collects descriptors matching the given complete list of entity tokens.
 /// </summary>
 /// <param name="into"> <seealso cref="System.Collections.ICollection"/> to add matching descriptors into. </param>
 /// <param name="entityTokenIds"> complete and sorted array of entity token ids for the entity. </param>
 internal virtual void MatchingDescriptors(ICollection <T> into, long[] entityTokenIds)
 {
     Debug.Assert(isSortedSet(entityTokenIds));
     foreach (long entityTokenId in entityTokenIds)
     {
         PropertyMultiSet set = _byEntityToken.get(toIntExact(entityTokenId));
         if (set != null)
         {
             set.CollectAll(into);
         }
     }
 }
 /// <summary>
 /// Collects descriptors matching the given complete list of entity tokens, but only partial list of property key tokens.
 /// I.e. all entity tokens of the matching descriptors can be found in the given lists of tokens,
 /// but some matching descriptors may have other property key tokens in addition to those found in the given properties of the entity.
 /// This is for a scenario where the complete list of property key tokens isn't known when calling this method and may
 /// collect additional descriptors that in the end isn't relevant for the specific entity.
 /// </summary>
 /// <param name="into"> <seealso cref="System.Collections.ICollection"/> to add matching descriptors into. </param>
 /// <param name="entityTokenIds"> complete and sorted array of entity token ids for the entity. </param>
 /// <param name="sortedProperties"> complete and sorted array of property key token ids for the entity. </param>
 internal virtual void MatchingDescriptorsForPartialListOfProperties(ICollection <T> into, long[] entityTokenIds, int[] sortedProperties)
 {
     Debug.Assert(isSortedSet(sortedProperties));
     foreach (long entityTokenId in entityTokenIds)
     {
         PropertyMultiSet first = _byEntityToken.get(toIntExact(entityTokenId));
         if (first != null)
         {
             first.CollectForPartialListOfProperties(into, sortedProperties);
         }
     }
 }
        /// <summary>
        /// Cheap way of finding out whether or not there are any descriptors matching the set of entity token ids and the property key id.
        /// </summary>
        /// <param name="entityTokenIds"> complete list of entity token ids for the entity to check. </param>
        /// <param name="propertyKey"> a property key id to check. </param>
        /// <returns> {@code true} if there are one or more descriptors matching the given tokens. </returns>
        internal virtual bool Has(long[] entityTokenIds, int propertyKey)
        {
            // Abort right away if there are no descriptors at all
            if (Empty)
            {
                return(false);
            }

            // Check if there are any descriptors that matches any of the first (or only) entity token
            foreach (long entityTokenId in entityTokenIds)
            {
                PropertyMultiSet set = _byEntityToken.get(toIntExact(entityTokenId));
                if (set != null && set.Has(propertyKey))
                {
                    return(true);
                }
            }
            return(false);
        }