boolean (@Nullable Element o1, @Nullable Element o2) { if (o1 == o2) { return true; } if (o1 == null || o2 == null || !Comparing.strEqual(o1.getName(), o2.getName()) || !attributesEqual(o1, o2)) { return false; } List<Content> content1 = o1.getContent(); List<Content> content2 = o2.getContent(); if (content1.size() != content2.size()) return false; for (int i = 0; i < content1.size(); i++) { Content c1 = content1.get(i); Content c2 = content2.get(i); if (c1 instanceof Text) { if (!(c2 instanceof Text) || !Comparing.strEqual(c1.getValue(), c2.getValue())) { return false; } } else if (c1 instanceof Element) { if (!(c2 instanceof Element) || !equals((Element)c1, (Element)c2)) { return false; } } else { throw new RuntimeException(c1.toString()); } } return true; }