package liquibase.structure.core;

import liquibase.CatalogAndSchema;
import liquibase.structure.AbstractDatabaseObject;
import liquibase.structure.DatabaseObject;
import liquibase.util.StringUtils;

import java.util.*;

public class Schema extends AbstractDatabaseObject {

    public Schema() {
        setAttribute("objects",  new HashMap<Class<? extends DatabaseObject>, Set<DatabaseObject>>());
    }

    public Schema(String catalog, String schemaName) {
        this(new Catalog(catalog), schemaName);
    }

    public Schema(Catalog catalog, String schemaName) {
        schemaName = StringUtils.trimToNull(schemaName);

        setAttribute("name", schemaName);
        setAttribute("catalog", catalog);
        setAttribute("objects", new HashMap<Class<? extends DatabaseObject>, Set<DatabaseObject>>());
    }

    @Override
    public DatabaseObject[] getContainingObjects() {
        return null;
    }

    @Override
    public String getName() {
        return getAttribute("name", String.class);
    }


    @Override
    public Schema setName(String name) {
        setAttribute("name", name);
        return this;
    }

    public boolean isDefault() {
        return getAttribute("default", false) || (getName() == null);
    }

    public Schema setDefault(Boolean isDefault) {
        setAttribute("default", isDefault);
        return this;
    }


    @Override
    public Schema getSchema() {
        return this;
    }

    public Catalog getCatalog() {
        return getAttribute("catalog", Catalog.class);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if ((o == null) || (getClass() != o.getClass())) return false;

        Schema schema = (Schema) o;

        if ((getCatalog() != null) ? !getCatalog().equals(schema.getCatalog()) : (schema.getCatalog() != null)) return false;
        return (getName() != null) ? getName().equalsIgnoreCase(schema.getName()) : (schema.getName() == null);
    }

    @Override
    public int hashCode() {
        int result = (getCatalog() != null) ? getCatalog().hashCode() : 0;
        result = (31 * result) + ((getName() != null) ? getName().hashCode() : 0);
        return result;
    }

    public String getCatalogName() {
        if (getCatalog() == null) {
            return null;
        }
        return getCatalog().getName();
    }
    
    @Override
    public String toString() {
        String catalogName = getCatalogName();

        String schemaName = getName();
        if (schemaName == null) {
            schemaName = "DEFAULT";
        }

        if ((catalogName == null) || catalogName.equals(schemaName)) {
            return schemaName;
        } else {
            return catalogName +"."+ schemaName;
        }
    }

    public CatalogAndSchema toCatalogAndSchema() {
        String catalogName;
        if ((getCatalog() != null) && getCatalog().isDefault()) {
            catalogName = null;
        } else {
            catalogName = getCatalogName();
        }

        String schemaName;
        if (isDefault()) {
            schemaName = null;
        } else {
            schemaName = getName();
        }
        return new CatalogAndSchema(catalogName, schemaName);
    }

    protected Map<Class<? extends DatabaseObject>, Set<DatabaseObject>> getObjects() {
        return getAttribute("objects", Map.class);
    }

    public <DatabaseObjectType extends DatabaseObject> List<DatabaseObjectType> getDatabaseObjects(Class<DatabaseObjectType> type) {
        Set<DatabaseObjectType> databaseObjects = (Set<DatabaseObjectType>) getObjects().get(type);
        if (databaseObjects == null) {
            return new ArrayList<>();
        }
        return new ArrayList<>(databaseObjects);
    }

    public void addDatabaseObject(DatabaseObject databaseObject) {
        if (databaseObject == null) {
            return;
        }
        Set<DatabaseObject> objects = this.getObjects().get(databaseObject.getClass());
        if (objects == null) {
            objects = new HashSet<>();
            this.getObjects().put(databaseObject.getClass(), objects);
        }
        objects.add(databaseObject);

    }

    @Override
    public Set<String> getSerializableFields() {
        Set<String> fields = super.getSerializableFields();
        fields.remove("objects");
        return fields;
    }
}

@@ -1006,33 +1006,32 @@
 .class);%0A    %7D%0A%0A
-%0A
     @Override%0A  
@@ -3387,34 +3387,17 @@
 public %3C
-DatabaseObjectType
+T
  extends
@@ -3418,34 +3418,17 @@
 t%3E List%3C
-DatabaseObjectType
+T
 %3E getDat
@@ -3446,34 +3446,17 @@
 s(Class%3C
-DatabaseObjectType
+T
 %3E type) 
@@ -3469,34 +3469,17 @@
     Set%3C
-DatabaseObjectType
+T
 %3E databa
@@ -3493,32 +3493,27 @@
 ts =
- (Set%3CDatabaseObjectType
+%0A            (Set%3CT
 %3E) g

Use standard convention for the type name