class ValueObjectUtils {

    public static boolean equalGroupElements(List<? extends SchemaElement> groupElements1, List<? extends SchemaElement> groupElements2) {
        if(groupElements1 == null && groupElements2 == null) return true;
        if(groupElements1 == null || groupElements2 == null) return false;
        if (groupElements1.size() != groupElements2.size())  return false;

        if (!(groupElements1.get(0) instanceof AbstractResourceGroupElement)) {
            return groupElements1.containsAll(groupElements2);
        }
        List<? extends SchemaElement> groupElements1Copy = new ArrayList<SchemaElement>(groupElements1);
        List<? extends SchemaElement> groupElements2Copy = new ArrayList<SchemaElement>(groupElements2);
        Comparator<SchemaElement> comparator = new Comparator<SchemaElement>() {
            public int compare(SchemaElement elem1, SchemaElement elem2) {
                if (elem1 != null && elem2 != null)
                    return ObjectUtils.compare(elem1.getName(), elem2.getName());
                else if (elem1 == null) return  1;
                else if(elem2 == null) return -1;
                else return 0;
            }
        };
        Collections.sort(groupElements1Copy, comparator);
        Collections.sort(groupElements2Copy, comparator);
        boolean result = true;
        for (int i = 0; i < groupElements1Copy.size(); i++) {
            final SchemaElement resourceElement1 = groupElements1Copy.get(i);
            final SchemaElement resourceElement2 = groupElements2Copy.get(i);
            if (resourceElement1 == null && resourceElement2 == null){
                result &= true;
            } else if(resourceElement1 != null && resourceElement2 != null &&resourceElement1.getName().equals(resourceElement2.getName())
                    && resourceElement1.getClass() == resourceElement2.getClass()) {
                if(resourceElement1 instanceof AbstractResourceGroupElement) {
                    result &= equalGroupElements(((AbstractResourceGroupElement) resourceElement1).getElements(),
                            ((AbstractResourceGroupElement) resourceElement2).getElements());
                } else if (resourceElement1 instanceof ConstantsResourceGroupElement) {
                    result &=  equalGroupElements(((ConstantsResourceGroupElement) resourceElement1).getElements(),
                            ((ConstantsResourceGroupElement) resourceElement2).getElements());
                }
            }  else {
                result &= false;
            }
        }
        return result;
    }

}