public TelepathyObjectSchema FilterSchema(TelepathyFilterConfig config)
        {
            var typeConfig = config.GetObjectTypeConfig(Name);

            int includedFields = 0;

            for (int i = 0; i < NumFields; i++)
            {
                if (typeConfig.includesField(GetFieldName(i)))
                {
                    includedFields++;
                }
            }

            var filteredSchema = new TelepathyObjectSchema(Name, includedFields, PrimaryKey);

            for (var i = 0; i < NumFields; i++)
            {
                if (typeConfig.includesField(GetFieldName(i)))
                {
                    filteredSchema.AddField(GetFieldName(i), GetFieldType(i), GetReferencedType(i));
                }
            }

            return(filteredSchema);
        }
        public TelepathyObjectSchema FindCommonSchema(TelepathyObjectSchema otherSchema)
        {
            if (!Name.Equals(otherSchema.Name))
            {
                throw new ArgumentException("Cannot find common schema of two schemas with different names!");
            }

            var commonFields = _fieldNames.Count(fieldName => otherSchema.GetPosition(fieldName) != -1);

            var primaryKey = PrimaryKey.Equals(otherSchema.PrimaryKey) ? PrimaryKey : null;

            TelepathyObjectSchema commonSchema = new TelepathyObjectSchema(Name, commonFields, primaryKey);

            for (int i = 0; i < _fieldNames.Length; i++)
            {
                int otherFieldIndex = otherSchema.GetPosition(_fieldNames[i]);
                if (otherFieldIndex != -1)
                {
                    if (_fieldTypes[i] != otherSchema.GetFieldType(otherFieldIndex) ||
                        !ReferenceEquals(ReferencedTypes[i], otherSchema.GetReferencedType(otherFieldIndex)))
                    {
                        throw new ArgumentException("No common schema exists for " + Name + ": field " + _fieldNames[i] + " has unmatched types");
                    }
                    commonSchema.AddField(_fieldNames[i], _fieldTypes[i], ReferencedTypes[i]);
                }
            }

            return(commonSchema);
        }
        public TelepathyObjectSchema FindUnionSchema(TelepathyObjectSchema otherSchema)
        {
            if (!Name.Equals(otherSchema.Name))
            {
                throw new ArgumentException("Cannot find common schema of two schemas with different names!");
            }

            int totalFields = otherSchema.NumFields;

            foreach (var fieldName in _fieldNames)
            {
                if (otherSchema.GetPosition(fieldName) == -1)
                {
                    totalFields++;
                }
            }


            var primaryKey  = PrimaryKey.Equals(otherSchema.PrimaryKey) ? PrimaryKey : null;
            var unionSchema = new TelepathyObjectSchema(Name, totalFields, primaryKey);

            for (int i = 0; i < _fieldNames.Length; i++)
            {
                unionSchema.AddField(_fieldNames[i], _fieldTypes[i], ReferencedTypes[i]);
            }

            for (int i = 0; i < otherSchema.NumFields; i++)
            {
                if (GetPosition(otherSchema.GetFieldName(i)) == -1)
                {
                    unionSchema.AddField(otherSchema.GetFieldName(i), otherSchema.GetFieldType(i),
                                         otherSchema.GetReferencedType(i));
                }
            }

            return(unionSchema);
        }