class IndexComparator implements DatabaseObjectComparator {
    @Override
    public int getPriority(Class<? extends DatabaseObject> objectType, Database database) {
        if (Index.class.isAssignableFrom(objectType)) {
            return PRIORITY_TYPE;
        }
        return PRIORITY_NONE;
    }

    @Override
    public String[] hash(DatabaseObject databaseObject, Database accordingTo, DatabaseObjectComparatorChain chain) {<FILL_FUNCTION_BODY>}


    @Override
    public boolean isSameObject(DatabaseObject databaseObject1, DatabaseObject databaseObject2, Database accordingTo, DatabaseObjectComparatorChain chain) {
        if (!((databaseObject1 instanceof Index) && (databaseObject2 instanceof Index))) {
            return false;
        }

        Index thisIndex = (Index) databaseObject1;
        Index otherIndex = (Index) databaseObject2;

        int thisIndexSize = thisIndex.getColumns().size();
        int otherIndexSize = otherIndex.getColumns().size();

        if ((thisIndex.getRelation() != null) && (otherIndex.getRelation() != null)) {
            if (!DatabaseObjectComparatorFactory.getInstance().isSameObject(thisIndex.getRelation(), otherIndex.getRelation(), chain.getSchemaComparisons(), accordingTo)) {
                return false;
            }
            if ((databaseObject1.getSchema() != null) && (databaseObject2.getSchema() != null) &&
                !DatabaseObjectComparatorFactory.getInstance().isSameObject(databaseObject1.getSchema(),
                    databaseObject2.getSchema(), chain.getSchemaComparisons(), accordingTo)) {
                return false;
            }

            if ((databaseObject1.getName() != null) && (databaseObject2.getName() != null) &&
                DefaultDatabaseObjectComparator.nameMatches(databaseObject1, databaseObject2, accordingTo)) {
                return true;
            } else {
                if ((thisIndexSize == 0) || (otherIndexSize == 0)) {
                    return DefaultDatabaseObjectComparator.nameMatches(databaseObject1, databaseObject2, accordingTo);
                }


                if (thisIndexSize != otherIndexSize) {
                    return false;
                }


                for (int i = 0; i < otherIndexSize; i++) {
                    if (!DatabaseObjectComparatorFactory.getInstance().isSameObject(thisIndex.getColumns().get(i), otherIndex.getColumns().get(i), chain.getSchemaComparisons(), accordingTo)) {
                        return false;
                    }
                }
                return true;
            }
        } else {
            if ((thisIndexSize > 0) && (otherIndexSize > 0) && (thisIndexSize != otherIndexSize)) {
                return false;
            }

            if (!DefaultDatabaseObjectComparator.nameMatches(databaseObject1, databaseObject2, accordingTo)) {
                return false;
            }

            if ((databaseObject1.getSchema() != null) && (databaseObject2.getSchema() != null)) {
                return DatabaseObjectComparatorFactory.getInstance().isSameObject(databaseObject1.getSchema(), databaseObject2.getSchema(), chain.getSchemaComparisons(), accordingTo);
            } else {
                return true;
            }
        }

    }


    @Override
    public ObjectDifferences findDifferences(DatabaseObject databaseObject1, DatabaseObject databaseObject2, Database accordingTo, CompareControl compareControl, DatabaseObjectComparatorChain chain, Set<String> exclude) {
        exclude.add("name");
        exclude.add("columns");
        ObjectDifferences differences = chain.findDifferences(databaseObject1, databaseObject2, accordingTo, compareControl, exclude);

        differences.compare("columns", databaseObject1, databaseObject2, (referenceValue, compareToValue) -> {
            List<Column> referenceList = (List) referenceValue;
            List<Column> compareList = (List) compareToValue;

            if (referenceList.size() != compareList.size()) {
                return false;
            }
            for (int i=0; i<referenceList.size(); i++) {
                //
                // Check for nulls
                // If both reference and comparison objects are null then return true
                // else if only one is null then return false
                //
                if (referenceList.get(i) == null || compareList.get(i) == null) {
                    return referenceList.get(i) == compareList.get(i);
                }
                if (!StringUtil.trimToEmpty((referenceList.get(i)).getName()).equalsIgnoreCase(StringUtil.trimToEmpty(compareList.get(i).getName()))) {
                    return false;
                }
            }
            return true;
        });

        return differences;
    }
}

        List<String> hashes = new ArrayList<>();
        if (databaseObject.getName() != null) {
            hashes.add(databaseObject.getName().toLowerCase());
        }

        Relation table = ((Index) databaseObject).getRelation();
        if (table != null) {
            hashes.addAll(Arrays.asList(DatabaseObjectComparatorFactory.getInstance().hash(table, chain.getSchemaComparisons(), accordingTo)));
        }

        return hashes.toArray(new String[0]);
    
<no_super_class>