private TreeHashResult computeHash(PsiElement element,
                                     PsiFragment parent,
                                     EquivalenceDescriptor descriptor,
                                     NodeSpecificHasher hasher) {
    final NodeSpecificHasherBase ssrHasher = (NodeSpecificHasherBase)hasher;
    final PsiElement element2 = DuplocatorUtil.skipNodeIfNecessary(element, descriptor, ssrHasher.getNodeFilter());
    final boolean canSkip = element2 != element;

    final PsiFragment fragment = buildFragment(hasher, element, 0);

    if (parent != null) {
      fragment.setParent(parent);
    }

    int hash = canSkip ? 0 : hasher.getNodeHash(element);
    int cost = hasher.getNodeCost(element);

    for (SingleChildDescriptor childDescriptor : descriptor.getSingleChildDescriptors()) {
      final Couple<Integer> childHashResult = computeHash(childDescriptor, fragment, hasher);
      hash = hash * 31 + childHashResult.first;
      cost += childHashResult.second;
    }

    for (MultiChildDescriptor childDescriptor : descriptor.getMultiChildDescriptors()) {
      final Couple<Integer> childHashResult = computeHash(childDescriptor, fragment, hasher);
      hash = hash * 31 + childHashResult.first;
      cost += childHashResult.second;
    }

    for (Object constant : descriptor.getConstants()) {
      final int constantHash = constant != null ? constant.hashCode() : 0;
      hash = hash * 31 + constantHash;
    }

    for (PsiElement[] codeBlock : descriptor.getCodeBlocks()) {
      final List<PsiElement> filteredBlock = filter(codeBlock, ssrHasher);
      final TreeHashResult childHashResult = hashCodeBlock(filteredBlock, fragment, hasher);
      hash = hash * 31 + childHashResult.getHash();
      cost += childHashResult.getCost();
    }

    if (myCallback != null) {
      myCallback.add(hash, cost, fragment);
    }
    return new TreeHashResult(hash, cost, fragment);
  }
private TreeHashResult computeHash(PsiElement element,
                                     PsiFragment parent,
                                     EquivalenceDescriptor descriptor,
                                     NodeSpecificHasher hasher)