public Entity Materialize(int entityIndex, int typeIdIndex, TypeInfo type, Pair <int>[] entityColumns, Tuple tuple)
        {
            var result = entities[entityIndex];

            if (result != null)
            {
                return(result);
            }

            TypeReferenceAccuracy accuracy;
            int typeId = EntityDataReader.ExtractTypeId(type, typeIdRegistry, tuple, typeIdIndex, out accuracy);

            if (typeId == TypeInfo.NoTypeId)
            {
                return(null);
            }

            bool canCache            = accuracy == TypeReferenceAccuracy.ExactType;
            var  materializationInfo = MaterializationContext.GetTypeMapping(entityIndex, type, typeId, entityColumns);
            Key  key;
            var  keyIndexes = materializationInfo.KeyIndexes;

            if (!KeyFactory.IsValidKeyTuple(tuple, keyIndexes))
            {
                return(null);
            }
            if (keyIndexes.Length <= WellKnown.MaxGenericKeyLength)
            {
                key = KeyFactory.Materialize(Session.Domain, Session.StorageNodeId, materializationInfo.Type, tuple, accuracy, canCache, keyIndexes);
            }
            else
            {
                var keyTuple = materializationInfo.KeyTransform.Apply(TupleTransformType.TransformedTuple, tuple);
                key = KeyFactory.Materialize(Session.Domain, Session.StorageNodeId, materializationInfo.Type, keyTuple, accuracy, canCache, null);
            }
            if (accuracy == TypeReferenceAccuracy.ExactType)
            {
                var entityTuple = materializationInfo.Transform.Apply(TupleTransformType.Tuple, tuple);
                var entityState = Session.Handler.UpdateState(key, entityTuple);
                result = entityState.Entity;
            }
            else
            {
                result = Session.Query.SingleOrDefault(key);
            }
            entities[entityIndex] = result;
            return(result);
        }