boolean (PsiElement element1, PsiElement element2) { if (element1 == null || element2 == null) { return element1 == element2; } if (myDiscardCost > 0) { final int cost1 = myTreeHasher.hash(element1, null, myNodeSpecificHasher).getCost(); final int cost2 = myTreeHasher.hash(element2, null, myNodeSpecificHasher).getCost(); if (cost1 < myDiscardCost || cost2 < myDiscardCost) { return true; } } final DuplicatesProfileBase duplicatesProfile = myNodeSpecificHasher.getDuplicatesProfile(); final PsiElementRole role1 = duplicatesProfile.getRole(element1); final PsiElementRole role2 = duplicatesProfile.getRole(element2); final Set<PsiElementRole> skippedRoles = EnumSet.noneOf(PsiElementRole.class); final ExternalizableDuplocatorState duplocatorState = duplicatesProfile.getDuplocatorState(duplicatesProfile.getLanguage(element1)); for (PsiElementRole role : PsiElementRole.values()) { if (!duplocatorState.distinguishRole(role)) { skippedRoles.add(role); } } if (role1 == role2 && skippedRoles.contains(role1)) { return true; } final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element1); EquivalenceDescriptor descriptor1 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element1) : null; EquivalenceDescriptor descriptor2 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element2) : null; PsiElement newElement1 = DuplocatorUtil.skipNodeIfNecessary(element1, descriptor1, myNodeFilter); PsiElement newElement2 = DuplocatorUtil.skipNodeIfNecessary(element2, descriptor2, myNodeFilter); if (newElement1 != element1 || newElement2 != element2) { return match(newElement1, newElement2); } if (!element1.getClass().equals(element2.getClass())) { return false; } if (descriptor1 != null && descriptor2 != null) { return DuplocatorUtil.match(descriptor1, descriptor2, this, skippedRoles, duplicatesProfile); } if (element1 instanceof LeafElement) { IElementType elementType1 = ((LeafElement)element1).getElementType(); IElementType elementType2 = ((LeafElement)element2).getElementType(); if (!duplocatorState.distinguishLiterals() && duplicatesProfile.getLiterals().contains(elementType1) && duplicatesProfile.getLiterals().contains(elementType2)) { return true; } return element1.getText().equals(element2.getText()); } if (element1.getFirstChild() == null && element1.getTextLength() == 0) { return element2.getFirstChild() == null && element2.getTextLength() == 0; } return matchSequentially(new FilteringNodeIterator(SiblingNodeIterator.create(element1.getFirstChild()), getNodeFilter()), new FilteringNodeIterator(SiblingNodeIterator.create(element2.getFirstChild()), getNodeFilter())); }