@Override
    public boolean hashCodesEqual(@NotNull ASTNode n1, @NotNull LighterASTNode n2) {
      if (n1 instanceof LeafElement && n2 instanceof Token) {
        boolean isForeign1 = n1 instanceof ForeignLeafPsiElement;
        boolean isForeign2 = n2.getTokenType() instanceof ForeignLeafType;
        if (isForeign1 != isForeign2) return false;

        if (isForeign1) {
          return n1.getText().equals(((ForeignLeafType)n2.getTokenType()).getValue());
        }

        return ((LeafElement)n1).textMatches(((Token)n2).getText());
      }

      if (n1 instanceof PsiErrorElement && n2.getTokenType() == TokenType.ERROR_ELEMENT) {
        PsiErrorElement e1 = (PsiErrorElement)n1;
        if (!Objects.equals(e1.getErrorDescription(), getErrorMessage(n2))) return false;
      }

      return ((Node)n2).tokenTextMatches(n1.getChars());
    }
@Override
    public boolean hashCodesEqual(@NotNull ASTNode n1, @NotNull LighterASTNode n2)