package org.checkerframework.framework.ajava;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.body.AnnotationDeclaration;
import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
import com.github.javaparser.ast.body.BodyDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.EnumConstantDeclaration;
import com.github.javaparser.ast.body.EnumDeclaration;
import com.github.javaparser.ast.body.InitializerDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.body.ReceiverParameter;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.ArrayAccessExpr;
import com.github.javaparser.ast.expr.AssignExpr;
import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.CastExpr;
import com.github.javaparser.ast.expr.ClassExpr;
import com.github.javaparser.ast.expr.ConditionalExpr;
import com.github.javaparser.ast.expr.EnclosedExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.InstanceOfExpr;
import com.github.javaparser.ast.expr.LambdaExpr;
import com.github.javaparser.ast.expr.LiteralExpr;
import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
import com.github.javaparser.ast.expr.MemberValuePair;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.MethodReferenceExpr;
import com.github.javaparser.ast.expr.Name;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
import com.github.javaparser.ast.expr.SimpleName;
import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
import com.github.javaparser.ast.expr.SuperExpr;
import com.github.javaparser.ast.expr.ThisExpr;
import com.github.javaparser.ast.expr.TypeExpr;
import com.github.javaparser.ast.expr.UnaryExpr;
import com.github.javaparser.ast.modules.ModuleDeclaration;
import com.github.javaparser.ast.modules.ModuleExportsDirective;
import com.github.javaparser.ast.modules.ModuleOpensDirective;
import com.github.javaparser.ast.modules.ModuleProvidesDirective;
import com.github.javaparser.ast.modules.ModuleRequiresDirective;
import com.github.javaparser.ast.modules.ModuleUsesDirective;
import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
import com.github.javaparser.ast.stmt.AssertStmt;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.BreakStmt;
import com.github.javaparser.ast.stmt.CatchClause;
import com.github.javaparser.ast.stmt.ContinueStmt;
import com.github.javaparser.ast.stmt.DoStmt;
import com.github.javaparser.ast.stmt.EmptyStmt;
import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ForEachStmt;
import com.github.javaparser.ast.stmt.ForStmt;
import com.github.javaparser.ast.stmt.IfStmt;
import com.github.javaparser.ast.stmt.LabeledStmt;
import com.github.javaparser.ast.stmt.LocalClassDeclarationStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.stmt.SwitchEntry;
import com.github.javaparser.ast.stmt.SwitchStmt;
import com.github.javaparser.ast.stmt.SynchronizedStmt;
import com.github.javaparser.ast.stmt.ThrowStmt;
import com.github.javaparser.ast.stmt.TryStmt;
import com.github.javaparser.ast.stmt.WhileStmt;
import com.github.javaparser.ast.type.ArrayType;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.IntersectionType;
import com.github.javaparser.ast.type.PrimitiveType;
import com.github.javaparser.ast.type.TypeParameter;
import com.github.javaparser.ast.type.UnionType;
import com.github.javaparser.ast.type.VoidType;
import com.github.javaparser.ast.type.WildcardType;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.sun.source.tree.AnnotatedTypeTree;
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.ArrayAccessTree;
import com.sun.source.tree.ArrayTypeTree;
import com.sun.source.tree.AssertTree;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.BlockTree;
import com.sun.source.tree.BreakTree;
import com.sun.source.tree.CaseTree;
import com.sun.source.tree.CatchTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.ConditionalExpressionTree;
import com.sun.source.tree.ContinueTree;
import com.sun.source.tree.DoWhileLoopTree;
import com.sun.source.tree.EmptyStatementTree;
import com.sun.source.tree.EnhancedForLoopTree;
import com.sun.source.tree.ErroneousTree;
import com.sun.source.tree.ExportsTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.ForLoopTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.IfTree;
import com.sun.source.tree.ImportTree;
import com.sun.source.tree.InstanceOfTree;
import com.sun.source.tree.IntersectionTypeTree;
import com.sun.source.tree.LabeledStatementTree;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MemberReferenceTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ModifiersTree;
import com.sun.source.tree.ModuleTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.OpensTree;
import com.sun.source.tree.PackageTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.PrimitiveTypeTree;
import com.sun.source.tree.ProvidesTree;
import com.sun.source.tree.RequiresTree;
import com.sun.source.tree.ReturnTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.SwitchTree;
import com.sun.source.tree.SynchronizedTree;
import com.sun.source.tree.ThrowTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.tree.TreeVisitor;
import com.sun.source.tree.TryTree;
import com.sun.source.tree.TypeCastTree;
import com.sun.source.tree.TypeParameterTree;
import com.sun.source.tree.UnaryTree;
import com.sun.source.tree.UnionTypeTree;
import com.sun.source.tree.UsesTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.tree.WhileLoopTree;
import com.sun.source.tree.WildcardTree;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.checkerframework.javacutil.BugInCF;

/**
 * A visitor that processes javac trees and JavaParser nodes simultaneously, matching corresponding
 * nodes.
 *
 * <p>By default, visits all children of a javac tree along with corresponding JavaParser nodes. The
 * JavaParser node corresponding to a javac tree is always passed as the secondary parameter to the
 * {@code visit} methods.
 *
 * <p>To perform an action on a particular tree type, override one of the methods starting with
 * "process". For each javac tree type JavacType, and for each possible JavaParser node type
 * JavaParserNode that it may be matched to, this class contains a method {@code
 * processJavacType(JavacTypeTree javacTree, JavaParserNode javaParserNode)}. These are named after
 * the visit methods in {@code com.sun.source.tree.TreeVisitor}, but for each javac tree type there
 * may be multiple process methods for each possible node type it could be matched to.
 *
 * <p>The {@code process} methods are called in pre-order. That is, process methods for a parent are
 * called before its children.
 */
public abstract class JointJavacJavaParserVisitor implements TreeVisitor<Void, Node> {
  @Override
  public Void visitAnnotation(AnnotationTree javacTree, Node javaParserNode) {
    // javac stores annotation arguments as assignments, so @MyAnno("myArg") is stored the same
    // as @MyAnno(value="myArg") which has a single element argument list with an assignment.
    if (javaParserNode instanceof MarkerAnnotationExpr) {
      processAnnotation(javacTree, (MarkerAnnotationExpr) javaParserNode);
    } else if (javaParserNode instanceof SingleMemberAnnotationExpr) {
      SingleMemberAnnotationExpr node = (SingleMemberAnnotationExpr) javaParserNode;
      processAnnotation(javacTree, node);
      assert javacTree.getArguments().size() == 1;
      ExpressionTree value = javacTree.getArguments().get(0);
      assert value instanceof AssignmentTree;
      AssignmentTree assignment = (AssignmentTree) value;
      assert assignment.getVariable().getKind() == Kind.IDENTIFIER;
      assert ((IdentifierTree) assignment.getVariable()).getName().contentEquals("value");
      assignment.getExpression().accept(this, node.getMemberValue());
    } else if (javaParserNode instanceof NormalAnnotationExpr) {
      NormalAnnotationExpr node = (NormalAnnotationExpr) javaParserNode;
      processAnnotation(javacTree, node);
      assert javacTree.getArguments().size() == node.getPairs().size();
      Iterator<MemberValuePair> argIter = node.getPairs().iterator();
      for (ExpressionTree arg : javacTree.getArguments()) {
        assert arg instanceof AssignmentTree;
        AssignmentTree assignment = (AssignmentTree) arg;
        IdentifierTree memberName = (IdentifierTree) assignment.getVariable();
        MemberValuePair javaParserArg = argIter.next();
        assert memberName.getName().contentEquals(javaParserArg.getNameAsString());
        assignment.getExpression().accept(this, javaParserArg.getValue());
      }
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitAnnotatedType(AnnotatedTypeTree javacTree, Node javaParserNode) {
    castNode(NodeWithAnnotations.class, javaParserNode, javacTree);
    processAnnotatedType(javacTree, javaParserNode);
    javacTree.getUnderlyingType().accept(this, javaParserNode);
    return null;
  }

  @Override
  public Void visitArrayAccess(ArrayAccessTree javacTree, Node javaParserNode) {
    ArrayAccessExpr node = castNode(ArrayAccessExpr.class, javaParserNode, javacTree);
    processArrayAccess(javacTree, node);
    javacTree.getExpression().accept(this, node.getName());
    javacTree.getIndex().accept(this, node.getIndex());
    return null;
  }

  @Override
  public Void visitArrayType(ArrayTypeTree javacTree, Node javaParserNode) {
    ArrayType node = castNode(ArrayType.class, javaParserNode, javacTree);
    processArrayType(javacTree, node);
    javacTree.getType().accept(this, node.getComponentType());
    return null;
  }

  @Override
  public Void visitAssert(AssertTree javacTree, Node javaParserNode) {
    AssertStmt node = castNode(AssertStmt.class, javaParserNode, javacTree);
    processAssert(javacTree, node);
    javacTree.getCondition().accept(this, node.getCheck());
    visitOptional(javacTree.getDetail(), node.getMessage());

    return null;
  }

  @Override
  public Void visitAssignment(AssignmentTree javacTree, Node javaParserNode) {
    AssignExpr node = castNode(AssignExpr.class, javaParserNode, javacTree);
    processAssignment(javacTree, node);
    javacTree.getVariable().accept(this, node.getTarget());
    javacTree.getExpression().accept(this, node.getValue());
    return null;
  }

  @Override
  public Void visitBinary(BinaryTree javacTree, Node javaParserNode) {
    BinaryExpr node = castNode(BinaryExpr.class, javaParserNode, javacTree);
    processBinary(javacTree, node);
    javacTree.getLeftOperand().accept(this, node.getLeft());
    javacTree.getRightOperand().accept(this, node.getRight());
    return null;
  }

  @Override
  public Void visitBlock(BlockTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof InitializerDeclaration) {
      return javacTree.accept(this, ((InitializerDeclaration) javaParserNode).getBody());
    }

    BlockStmt node = castNode(BlockStmt.class, javaParserNode, javacTree);
    processBlock(javacTree, node);
    processStatements(javacTree.getStatements(), node.getStatements());
    return null;
  }

  /**
   * Given a matching sequence of statements for a block, visits each javac statement with its
   * corresponding JavaParser statement, excluding synthetic javac trees like no-argument
   * constructors.
   *
   * @param javacStatements sequence of javac trees for statements
   * @param javaParserStatements sequence of JavaParser statements representing the same block as
   *     {@code javacStatements}
   */
  private void processStatements(
      Iterable<? extends StatementTree> javacStatements, Iterable<Statement> javaParserStatements) {
    PeekingIterator<StatementTree> javacIter =
        Iterators.peekingIterator(javacStatements.iterator());
    PeekingIterator<Statement> javaParserIter =
        Iterators.peekingIterator(javaParserStatements.iterator());

    while (javacIter.hasNext() || javaParserIter.hasNext()) {
      // Skip synthetic javac super() calls by checking if the JavaParser statement matches.
      if (javacIter.hasNext()
          && isDefaultSuperConstructorCall(javacIter.peek())
          && (!javaParserIter.hasNext() || !isDefaultSuperConstructorCall(javaParserIter.peek()))) {
        javacIter.next();
        continue;
      }

      // In javac, a line like "int i = 0, j = 0" is expanded as two sibling VariableTree
      // instances. In javaParser this is one VariableDeclarationExpr with two nested
      // VariableDeclarators. Match the declarators with the VariableTrees.
      if (javaParserIter.hasNext()
          && javaParserIter.peek().isExpressionStmt()
          && javaParserIter.peek().asExpressionStmt().getExpression().isVariableDeclarationExpr()) {
        for (VariableDeclarator decl :
            javaParserIter
                .next()
                .asExpressionStmt()
                .getExpression()
                .asVariableDeclarationExpr()
                .getVariables()) {
          assert javacIter.hasNext();
          assert javacIter.peek().getKind() == Kind.VARIABLE;
          javacIter.next().accept(this, decl);
        }

        continue;
      }

      assert javacIter.hasNext();
      assert javaParserIter.hasNext();
      javacIter.next().accept(this, javaParserIter.next());
    }

    assert !javacIter.hasNext();
    assert !javaParserIter.hasNext();
  }

  /**
   * Returns whether a javac statement represents a method call {@code super()}.
   *
   * @param statement the javac statement to check
   * @return true if statement is a method invocation named "super" with no arguments, false
   *     otherwise
   */
  public static boolean isDefaultSuperConstructorCall(StatementTree statement) {
    if (statement.getKind() != Kind.EXPRESSION_STATEMENT) {
      return false;
    }

    ExpressionStatementTree expressionStatement = (ExpressionStatementTree) statement;
    if (expressionStatement.getExpression().getKind() != Kind.METHOD_INVOCATION) {
      return false;
    }

    MethodInvocationTree invocation = (MethodInvocationTree) expressionStatement.getExpression();
    if (invocation.getMethodSelect().getKind() != Kind.IDENTIFIER) {
      return false;
    }

    if (!((IdentifierTree) invocation.getMethodSelect()).getName().contentEquals("super")) {
      return false;
    }

    return invocation.getArguments().isEmpty();
  }

  /**
   * Returns whether a JavaParser statement represents a method call {@code super()}.
   *
   * @param statement the JavaParser statement to check
   * @return true if statement is an explicit super constructor invocation with no arguments
   */
  private boolean isDefaultSuperConstructorCall(Statement statement) {
    if (!statement.isExplicitConstructorInvocationStmt()) {
      return false;
    }

    ExplicitConstructorInvocationStmt invocation = statement.asExplicitConstructorInvocationStmt();
    boolean isSuper = !invocation.isThis();
    return isSuper && invocation.getArguments().isEmpty();
  }

  @Override
  public Void visitBreak(BreakTree javacTree, Node javaParserNode) {
    BreakStmt node = castNode(BreakStmt.class, javaParserNode, javacTree);
    processBreak(javacTree, node);
    return null;
  }

  @Override
  public Void visitCase(CaseTree javacTree, Node javaParserNode) {
    SwitchEntry node = castNode(SwitchEntry.class, javaParserNode, javacTree);
    processCase(javacTree, node);
    // The expression is null if and only if the case is the default case.
    // Java 12 introduced multiple label cases, but expressions should contain at most one
    // element for Java 11 and below.
    List<Expression> expressions = node.getLabels();
    if (javacTree.getExpression() == null) {
      assert expressions.isEmpty();
    } else {
      assert expressions.size() == 1;
      javacTree.getExpression().accept(this, expressions.get(0));
    }

    processStatements(javacTree.getStatements(), node.getStatements());
    return null;
  }

  @Override
  public Void visitCatch(CatchTree javacTree, Node javaParserNode) {
    CatchClause node = castNode(CatchClause.class, javaParserNode, javacTree);
    processCatch(javacTree, node);
    javacTree.getParameter().accept(this, node.getParameter());
    javacTree.getBlock().accept(this, node.getBody());
    return null;
  }

  @Override
  public Void visitClass(ClassTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof ClassOrInterfaceDeclaration) {
      ClassOrInterfaceDeclaration node = (ClassOrInterfaceDeclaration) javaParserNode;
      processClass(javacTree, node);
      visitLists(javacTree.getTypeParameters(), node.getTypeParameters());

      if (javacTree.getKind() == Kind.CLASS) {
        if (javacTree.getExtendsClause() == null) {
          assert node.getExtendedTypes().isEmpty();
        } else {
          assert node.getExtendedTypes().size() == 1;
          javacTree.getExtendsClause().accept(this, node.getExtendedTypes().get(0));
        }

        visitLists(javacTree.getImplementsClause(), node.getImplementedTypes());
      } else if (javacTree.getKind() == Kind.INTERFACE) {
        visitLists(javacTree.getImplementsClause(), node.getExtendedTypes());
      }

      visitClassMembers(javacTree.getMembers(), node.getMembers());
    } else if (javaParserNode instanceof AnnotationDeclaration) {
      AnnotationDeclaration node = (AnnotationDeclaration) javaParserNode;
      processClass(javacTree, node);
      visitClassMembers(javacTree.getMembers(), node.getMembers());
    } else if (javaParserNode instanceof LocalClassDeclarationStmt) {
      javacTree.accept(this, ((LocalClassDeclarationStmt) javaParserNode).getClassDeclaration());
    } else if (javaParserNode instanceof EnumDeclaration) {
      EnumDeclaration node = (EnumDeclaration) javaParserNode;
      processClass(javacTree, node);
      visitLists(javacTree.getImplementsClause(), node.getImplementedTypes());
      // In an enum declaration, javac stores the enum constants expanded as constant variable
      // members, whereas JavaParser stores them as one object.  Need to match them.
      assert javacTree.getKind() == Kind.ENUM;
      List<Tree> javacMembers = new ArrayList<>(javacTree.getMembers());
      // Discard a synthetic constructor if it exists.  If there are any constants in this
      // enum, then they will show up as the first members of the javac tree, except for
      // possibly a synthetic constructor.
      if (!node.getEntries().isEmpty()) {
        while (!javacMembers.isEmpty() && javacMembers.get(0).getKind() != Kind.VARIABLE) {
          javacMembers.remove(0);
        }
      }

      for (EnumConstantDeclaration entry : node.getEntries()) {
        assert !javacMembers.isEmpty();
        javacMembers.get(0).accept(this, entry);
        javacMembers.remove(0);
      }

      visitClassMembers(javacMembers, node.getMembers());
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  /**
   * Given a list of class members for javac and JavaParser, visits each javac member with its
   * corresponding JavaParser member. Skips synthetic javac members.
   *
   * @param javacMembers a list of trees forming the members of a javac {@code ClassTree}
   * @param javaParserMembers a list of nodes forming the members of a JavaParser {@code
   *     ClassOrInterfaceDeclaration} or an {@code ObjectCreationExpr} with an anonymous class body
   *     that corresponds to {@code javacMembers}
   */
  private void visitClassMembers(
      List<? extends Tree> javacMembers, List<BodyDeclaration<?>> javaParserMembers) {
    PeekingIterator<Tree> javacIter = Iterators.peekingIterator(javacMembers.iterator());
    PeekingIterator<BodyDeclaration<?>> javaParserIter =
        Iterators.peekingIterator(javaParserMembers.iterator());
    while (javacIter.hasNext() || javaParserIter.hasNext()) {
      // Skip javac's synthetic no-argument constructors.
      if (javacIter.hasNext()
          && isNoArgumentConstructor(javacIter.peek())
          && (!javaParserIter.hasNext() || !isNoArgumentConstructor(javaParserIter.peek()))) {
        javacIter.next();
        continue;
      }

      // In javac, a line like int i = 0, j = 0 is expanded as two sibling VariableTree
      // instances. In JavaParser this is one FieldDeclaration with two nested
      // VariableDeclarators. Match the declarators with the VariableTrees.
      if (javaParserIter.hasNext() && javaParserIter.peek().isFieldDeclaration()) {
        for (VariableDeclarator decl : javaParserIter.next().asFieldDeclaration().getVariables()) {
          assert javacIter.hasNext();
          assert javacIter.peek().getKind() == Kind.VARIABLE;
          javacIter.next().accept(this, decl);
        }

        continue;
      }

      assert javacIter.hasNext();
      assert javaParserIter.hasNext();
      javacIter.next().accept(this, javaParserIter.next());
    }

    assert !javacIter.hasNext();
    assert !javaParserIter.hasNext();
  }

  /**
   * Visits the the members of an anonymous class body.
   *
   * <p>In normal classes, javac inserts a synthetic no-argument constructor if no constructor is
   * explicitly defined, which is skipped when visiting members. Anonymous class bodies may
   * introduce constructors that take arguments if the constructor invocation that created them was
   * passed arguments. For example, if {@code MyClass} has a constructor taking a single integer
   * argument, then writing {@code new MyClass(5) { }} expands to the javac tree
   *
   * <pre>{@code
   * new MyClass(5) {
   *     (int arg) {
   *         super(arg);
   *     }
   * }
   * }</pre>
   *
   * <p>This method skips these synthetic constructors.
   *
   * @param javacBody body of an anonymous class body
   * @param javaParserMembers list of members for the anonymous class body of an {@code
   *     ObjectCreationExpr}
   */
  public void visitAnonymousClassBody(
      ClassTree javacBody, List<BodyDeclaration<?>> javaParserMembers) {
    List<Tree> javacMembers = new ArrayList<>(javacBody.getMembers());
    if (!javacMembers.isEmpty()) {
      Tree member = javacMembers.get(0);
      if (member.getKind() == Kind.METHOD) {
        MethodTree methodTree = (MethodTree) member;
        if (methodTree.getName().contentEquals("<init>")) {
          javacMembers.remove(0);
        }
      }
    }

    visitClassMembers(javacMembers, javaParserMembers);
  }

  /**
   * Returns whether {@code member} is a javac constructor declaration that takes no arguments.
   *
   * @param member the javac tree to check
   * @return true if {@code member} is a method declaration with name {@code <init>} that takes no
   *     arguments
   */
  public static boolean isNoArgumentConstructor(Tree member) {
    if (member.getKind() != Kind.METHOD) {
      return false;
    }

    MethodTree methodTree = (MethodTree) member;
    return methodTree.getName().contentEquals("<init>") && methodTree.getParameters().isEmpty();
  }

  /**
   * Returns whether {@code member} is a JavaParser constructor declaration that takes no arguments.
   *
   * @param member the JavaParser body declaration to check
   * @return true if {@code member} is a constructor declaration that takes no arguments
   */
  private boolean isNoArgumentConstructor(BodyDeclaration<?> member) {
    return member.isConstructorDeclaration()
        && member.asConstructorDeclaration().getParameters().isEmpty();
  }

  @Override
  public Void visitCompilationUnit(CompilationUnitTree javacTree, Node javaParserNode) {
    CompilationUnit node = castNode(CompilationUnit.class, javaParserNode, javacTree);
    processCompilationUnit(javacTree, node);
    visitOptional(javacTree.getPackage(), node.getPackageDeclaration());
    visitLists(javacTree.getImports(), node.getImports());
    visitLists(javacTree.getTypeDecls(), node.getTypes());
    return null;
  }

  @Override
  public Void visitCompoundAssignment(CompoundAssignmentTree javacTree, Node javaParserNode) {
    AssignExpr node = castNode(AssignExpr.class, javaParserNode, javacTree);
    processCompoundAssignment(javacTree, node);
    javacTree.getVariable().accept(this, node.getTarget());
    javacTree.getExpression().accept(this, node.getValue());
    return null;
  }

  @Override
  public Void visitConditionalExpression(ConditionalExpressionTree javacTree, Node javaParserNode) {
    ConditionalExpr node = castNode(ConditionalExpr.class, javaParserNode, javacTree);
    processConditionalExpression(javacTree, node);
    javacTree.getCondition().accept(this, node.getCondition());
    javacTree.getTrueExpression().accept(this, node.getThenExpr());
    javacTree.getFalseExpression().accept(this, node.getElseExpr());
    return null;
  }

  @Override
  public Void visitContinue(ContinueTree javacTree, Node javaParserNode) {
    ContinueStmt node = castNode(ContinueStmt.class, javaParserNode, javacTree);
    processContinue(javacTree, node);
    return null;
  }

  @Override
  public Void visitDoWhileLoop(DoWhileLoopTree javacTree, Node javaParserNode) {
    DoStmt node = castNode(DoStmt.class, javaParserNode, javacTree);
    processDoWhileLoop(javacTree, node);
    // In javac the condition is parenthesized but not in JavaParser.
    ExpressionTree condition = ((ParenthesizedTree) javacTree.getCondition()).getExpression();
    condition.accept(this, node.getCondition());
    javacTree.getStatement().accept(this, node.getBody());
    return null;
  }

  @Override
  public Void visitEmptyStatement(EmptyStatementTree javacTree, Node javaParserNode) {
    EmptyStmt node = castNode(EmptyStmt.class, javaParserNode, javacTree);
    processEmptyStatement(javacTree, node);
    return null;
  }

  @Override
  public Void visitEnhancedForLoop(EnhancedForLoopTree javacTree, Node javaParserNode) {
    ForEachStmt node = castNode(ForEachStmt.class, javaParserNode, javacTree);
    processEnhancedForLoop(javacTree, node);
    javacTree.getVariable().accept(this, node.getVariableDeclarator());
    javacTree.getExpression().accept(this, node.getIterable());
    javacTree.getStatement().accept(this, node.getBody());
    return null;
  }

  @Override
  public Void visitErroneous(ErroneousTree javacTree, Node javaParserNode) {
    // An erroneous tree is a malformed expression, so skip.
    return null;
  }

  @Override
  public Void visitExports(ExportsTree javacTree, Node javaParserNode) {
    ModuleExportsDirective node = castNode(ModuleExportsDirective.class, javaParserNode, javacTree);
    processExports(javacTree, node);
    visitLists(javacTree.getModuleNames(), node.getModuleNames());
    javacTree.getPackageName().accept(this, node.getName());
    return null;
  }

  @Override
  public Void visitExpressionStatement(ExpressionStatementTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof ExpressionStmt) {
      ExpressionStmt node = (ExpressionStmt) javaParserNode;
      processExpressionStatemen(javacTree, node);
      javacTree.getExpression().accept(this, node.getExpression());
    } else if (javaParserNode instanceof ExplicitConstructorInvocationStmt) {
      // In this case the javac expression will be a MethodTree. Since JavaParser doesn't
      // surround explicit constructor invocations in an expression statement, we match
      // javaParserNode to the javac expression rather than the javac expression statement.
      javacTree.getExpression().accept(this, javaParserNode);
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitForLoop(ForLoopTree javacTree, Node javaParserNode) {
    ForStmt node = castNode(ForStmt.class, javaParserNode, javacTree);
    processForLoop(javacTree, node);
    Iterator<? extends StatementTree> javacInitializers = javacTree.getInitializer().iterator();
    for (Expression initializer : node.getInitialization()) {
      if (initializer.isVariableDeclarationExpr()) {
        for (VariableDeclarator declarator :
            initializer.asVariableDeclarationExpr().getVariables()) {
          assert javacInitializers.hasNext();
          javacInitializers.next().accept(this, declarator);
        }
      } else if (initializer.isAssignExpr()) {
        ExpressionStatementTree statement = (ExpressionStatementTree) javacInitializers.next();
        statement.getExpression().accept(this, initializer);
      } else {
        assert javacInitializers.hasNext();
        javacInitializers.next().accept(this, initializer);
      }
    }
    assert !javacInitializers.hasNext();

    visitOptional(javacTree.getCondition(), node.getCompare());

    // Javac stores a list of expression statements and JavaParser stores a list of statements,
    // the javac statements must be unwrapped.
    assert javacTree.getUpdate().size() == node.getUpdate().size();
    Iterator<Expression> javaParserUpdates = node.getUpdate().iterator();
    for (ExpressionStatementTree javacUpdate : javacTree.getUpdate()) {
      // Match the inner javac expression with the JavaParser expression.
      javacUpdate.getExpression().accept(this, javaParserUpdates.next());
    }

    javacTree.getStatement().accept(this, node.getBody());
    return null;
  }

  @Override
  public Void visitIdentifier(IdentifierTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof ClassOrInterfaceType) {
      processIdentifier(javacTree, (ClassOrInterfaceType) javaParserNode);
    } else if (javaParserNode instanceof Name) {
      processIdentifier(javacTree, (Name) javaParserNode);
    } else if (javaParserNode instanceof NameExpr) {
      processIdentifier(javacTree, (NameExpr) javaParserNode);
    } else if (javaParserNode instanceof SimpleName) {
      processIdentifier(javacTree, (SimpleName) javaParserNode);
    } else if (javaParserNode instanceof ThisExpr) {
      processIdentifier(javacTree, (ThisExpr) javaParserNode);
    } else if (javaParserNode instanceof SuperExpr) {
      processIdentifier(javacTree, (SuperExpr) javaParserNode);
    } else if (javaParserNode instanceof TypeExpr) {
      // This occurs in a member reference like MyClass::myMember. The MyClass is wrapped in a
      // TypeExpr.
      javacTree.accept(this, ((TypeExpr) javaParserNode).getType());
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitIf(IfTree javacTree, Node javaParserNode) {
    IfStmt node = castNode(IfStmt.class, javaParserNode, javacTree);
    processIf(javacTree, node);
    assert javacTree.getCondition().getKind() == Kind.PARENTHESIZED;
    ExpressionTree condition = ((ParenthesizedTree) javacTree.getCondition()).getExpression();
    condition.accept(this, node.getCondition());
    javacTree.getThenStatement().accept(this, node.getThenStmt());
    visitOptional(javacTree.getElseStatement(), node.getElseStmt());

    return null;
  }

  @Override
  public Void visitImport(ImportTree javacTree, Node javaParserNode) {
    ImportDeclaration node = castNode(ImportDeclaration.class, javaParserNode, javacTree);
    processImport(javacTree, node);
    // In javac trees, a name like "a.*" is stored as a member select, but JavaParser just
    // stores "a" and records that the name ends in an asterisk.
    if (node.isAsterisk()) {
      assert javacTree.getQualifiedIdentifier().getKind() == Kind.MEMBER_SELECT;
      MemberSelectTree identifier = (MemberSelectTree) javacTree.getQualifiedIdentifier();
      identifier.getExpression().accept(this, node.getName());
    } else {
      javacTree.getQualifiedIdentifier().accept(this, node.getName());
    }

    return null;
  }

  @Override
  public Void visitInstanceOf(InstanceOfTree javacTree, Node javaParserNode) {
    InstanceOfExpr node = castNode(InstanceOfExpr.class, javaParserNode, javacTree);
    processInstanceOf(javacTree, node);
    javacTree.getExpression().accept(this, node.getExpression());
    javacTree.getType().accept(this, node.getType());
    return null;
  }

  @Override
  public Void visitIntersectionType(IntersectionTypeTree javacTree, Node javaParserNode) {
    IntersectionType node = castNode(IntersectionType.class, javaParserNode, javacTree);
    processIntersectionType(javacTree, node);
    visitLists(javacTree.getBounds(), node.getElements());
    return null;
  }

  @Override
  public Void visitLabeledStatement(LabeledStatementTree javacTree, Node javaParserNode) {
    LabeledStmt node = castNode(LabeledStmt.class, javaParserNode, javacTree);
    processLabeledStatement(javacTree, node);
    javacTree.getStatement().accept(this, node.getStatement());
    return null;
  }

  @Override
  public Void visitLambdaExpression(LambdaExpressionTree javacTree, Node javaParserNode) {
    LambdaExpr node = castNode(LambdaExpr.class, javaParserNode, javacTree);
    processLambdaExpression(javacTree, node);
    visitLists(javacTree.getParameters(), node.getParameters());
    switch (javacTree.getBodyKind()) {
      case EXPRESSION:
        assert node.getBody() instanceof ExpressionStmt;
        ExpressionStmt body = (ExpressionStmt) node.getBody();
        javacTree.getBody().accept(this, body.getExpression());
        break;
      case STATEMENT:
        javacTree.getBody().accept(this, node.getBody());
        break;
    }

    return null;
  }

  @Override
  public Void visitLiteral(LiteralTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof LiteralExpr) {
      processLiteral(javacTree, (LiteralExpr) javaParserNode);
    } else if (javaParserNode instanceof UnaryExpr) {
      // Occurs for negative literals such as -7.
      processLiteral(javacTree, (UnaryExpr) javaParserNode);
    } else if (javaParserNode instanceof BinaryExpr) {
      // Occurs for expression like "a" + "b" where javac compresses them to "ab" but
      // JavaParser doesn't.
      processLiteral(javacTree, (BinaryExpr) javaParserNode);
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitMemberReference(MemberReferenceTree javacTree, Node javaParserNode) {
    MethodReferenceExpr node = castNode(MethodReferenceExpr.class, javaParserNode, javacTree);
    processMemberReference(javacTree, node);
    if (node.getScope().isTypeExpr()) {
      javacTree.getQualifierExpression().accept(this, node.getScope().asTypeExpr().getType());
    } else {
      javacTree.getQualifierExpression().accept(this, node.getScope());
    }

    assert (javacTree.getTypeArguments() != null) == node.getTypeArguments().isPresent();
    if (javacTree.getTypeArguments() != null) {
      visitLists(javacTree.getTypeArguments(), node.getTypeArguments().get());
    }

    return null;
  }

  @Override
  public Void visitMemberSelect(MemberSelectTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof FieldAccessExpr) {
      FieldAccessExpr node = (FieldAccessExpr) javaParserNode;
      processMemberSelect(javacTree, node);
      javacTree.getExpression().accept(this, node.getScope());
    } else if (javaParserNode instanceof Name) {
      Name node = (Name) javaParserNode;
      processMemberSelect(javacTree, node);
      assert node.getQualifier().isPresent();
      javacTree.getExpression().accept(this, node.getQualifier().get());
    } else if (javaParserNode instanceof ClassOrInterfaceType) {
      ClassOrInterfaceType node = (ClassOrInterfaceType) javaParserNode;
      processMemberSelect(javacTree, node);
      assert node.getScope().isPresent();
      javacTree.getExpression().accept(this, node.getScope().get());
    } else if (javaParserNode instanceof ClassExpr) {
      ClassExpr node = (ClassExpr) javaParserNode;
      processMemberSelect(javacTree, node);
      javacTree.getExpression().accept(this, node.getType());
    } else if (javaParserNode instanceof ThisExpr) {
      ThisExpr node = (ThisExpr) javaParserNode;
      processMemberSelect(javacTree, node);
      assert node.getTypeName().isPresent();
      javacTree.getExpression().accept(this, node.getTypeName().get());
    } else if (javaParserNode instanceof SuperExpr) {
      SuperExpr node = (SuperExpr) javaParserNode;
      processMemberSelect(javacTree, node);
      assert node.getTypeName().isPresent();
      javacTree.getExpression().accept(this, node.getTypeName().get());
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitMethod(MethodTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof MethodDeclaration) {
      visitMethodForMethodDeclaration(javacTree, (MethodDeclaration) javaParserNode);
    } else if (javaParserNode instanceof ConstructorDeclaration) {
      visitMethodForConstructorDeclaration(javacTree, (ConstructorDeclaration) javaParserNode);
    } else if (javaParserNode instanceof AnnotationMemberDeclaration) {
      visitMethodForAnnotationMemberDeclaration(
          javacTree, (AnnotationMemberDeclaration) javaParserNode);
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
      throw new BugInCF("unreachable");
    }
    return null;
  }

  /**
   * Visits a method declaration in the case where the matched JavaParser node was a {@code
   * MethodDeclaration}.
   *
   * @param javacTree method declaration to visit
   * @param javaParserNode corresponding JavaParser method declaration
   */
  private void visitMethodForMethodDeclaration(
      MethodTree javacTree, MethodDeclaration javaParserNode) {
    processMethod(javacTree, javaParserNode);
    // TODO: Handle modifiers. In javac this is a ModifiersTree but in JavaParser it's a list of
    // modifiers. This is a problem because a ModifiersTree has separate accessors to
    // annotations and other modifiers, so the order doesn't match. It might be that for
    // JavaParser, the annotations and other modifiers are also accessed separately.
    javacTree.getReturnType().accept(this, javaParserNode.getType());
    // Unlike other javac constructs, the javac list is non-null even if no type parameters are
    // present.
    visitLists(javacTree.getTypeParameters(), javaParserNode.getTypeParameters());
    // JavaParser sometimes inserts a receiver parameter that is not present in the source code.
    // (Example: on an explicitly-written toString for an enum class.)
    if (javacTree.getReceiverParameter() != null
        && javaParserNode.getReceiverParameter().isPresent()) {
      javacTree.getReceiverParameter().accept(this, javaParserNode.getReceiverParameter().get());
    }

    visitLists(javacTree.getParameters(), javaParserNode.getParameters());

    visitLists(javacTree.getThrows(), javaParserNode.getThrownExceptions());
    visitOptional(javacTree.getBody(), javaParserNode.getBody());
  }

  /**
   * Visits a method declaration in the case where the matched JavaParser node was a {@code
   * ConstructorDeclaration}.
   *
   * @param javacTree method declaration to visit
   * @param javaParserNode corresponding JavaParser constructor declaration
   */
  private void visitMethodForConstructorDeclaration(
      MethodTree javacTree, ConstructorDeclaration javaParserNode) {
    processMethod(javacTree, javaParserNode);
    visitLists(javacTree.getTypeParameters(), javaParserNode.getTypeParameters());
    visitOptional(javacTree.getReceiverParameter(), javaParserNode.getReceiverParameter());
    visitLists(javacTree.getParameters(), javaParserNode.getParameters());
    visitLists(javacTree.getThrows(), javaParserNode.getThrownExceptions());
    javacTree.getBody().accept(this, javaParserNode.getBody());
  }

  /**
   * Visits a method declaration in the case where the matched JavaParser node was a {@code
   * AnnotationMemberDeclaration}.
   *
   * @param javacTree method declaration to visit
   * @param javaParserNode corresponding JavaParser annotation member declaration
   */
  private void visitMethodForAnnotationMemberDeclaration(
      MethodTree javacTree, AnnotationMemberDeclaration javaParserNode) {
    processMethod(javacTree, javaParserNode);
    javacTree.getReturnType().accept(this, javaParserNode.getType());
    visitOptional(javacTree.getDefaultValue(), javaParserNode.getDefaultValue());
  }

  @Override
  public Void visitMethodInvocation(MethodInvocationTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof MethodCallExpr) {
      MethodCallExpr node = (MethodCallExpr) javaParserNode;
      processMethodInvocation(javacTree, node);
      // In javac, the type arguments will be empty if no type arguments are specified, but in
      // JavaParser the type arguments will have the none Optional value.
      assert javacTree.getTypeArguments().isEmpty() != node.getTypeArguments().isPresent();
      if (!javacTree.getTypeArguments().isEmpty()) {
        visitLists(javacTree.getTypeArguments(), node.getTypeArguments().get());
      }

      // In JavaParser, the method name itself and receiver are stored as fields of the
      // invocation itself, but in javac they might be combined into one MemberSelectTree.
      // That member select may also be a single IdentifierTree if no receiver was written.
      // This requires one layer of unnesting.
      ExpressionTree methodSelect = javacTree.getMethodSelect();
      if (methodSelect.getKind() == Kind.IDENTIFIER) {
        methodSelect.accept(this, node.getName());
      } else if (methodSelect.getKind() == Kind.MEMBER_SELECT) {
        MemberSelectTree selection = (MemberSelectTree) methodSelect;
        assert node.getScope().isPresent();
        selection.getExpression().accept(this, node.getScope().get());
      } else {
        throw new BugInCF("Unexpected method selection type: %s", methodSelect);
      }

      visitLists(javacTree.getArguments(), node.getArguments());
    } else if (javaParserNode instanceof ExplicitConstructorInvocationStmt) {
      ExplicitConstructorInvocationStmt node = (ExplicitConstructorInvocationStmt) javaParserNode;
      processMethodInvocation(javacTree, node);
      assert javacTree.getTypeArguments().isEmpty() != node.getTypeArguments().isPresent();
      if (!javacTree.getTypeArguments().isEmpty()) {
        visitLists(javacTree.getTypeArguments(), node.getTypeArguments().get());
      }

      visitLists(javacTree.getArguments(), node.getArguments());
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitModifiers(ModifiersTree arg0, Node arg1) {
    // TODO How to handle this? I don't think there's a corresponding JavaParser class, maybe
    // the NodeWithModifiers interface?
    return null;
  }

  @Override
  public Void visitModule(ModuleTree javacTree, Node javaParserNode) {
    ModuleDeclaration node = castNode(ModuleDeclaration.class, javaParserNode, javacTree);
    processModule(javacTree, node);
    javacTree.getName().accept(this, node.getName());
    return null;
  }

  @Override
  public Void visitNewArray(NewArrayTree javacTree, Node javaParserNode) {
    // TODO: Implement this.
    //
    // Some notes:
    // - javacTree.getAnnotations() seems to always return empty, any annotations on the base
    // type seem to go on the type itself in javacTree.getType(). The JavaParser version doesn't
    // even have a corresponding getAnnotations method.
    // - When there are no initializers, both systems use similar representations. The
    // dimensions line up.
    // - When there is an initializer, they differ greatly for multi-dimensional arrays. Javac
    // turns an expression like new int[][]{{1, 2}, {3, 4}} into a single NewArray tree with
    // type int[] and two initializer elements {1, 2} and {3, 4}. However, for each of the
    // sub-initializers, it creates an implicit NewArray tree with a null component type.
    // JavaParser keeps the whole expression as one ArrayCreationExpr with multiple dimensions
    // and the initializer stored in special ArrayInitializerExpr type.
    return null;
  }

  @Override
  public Void visitNewClass(NewClassTree javacTree, Node javaParserNode) {
    ObjectCreationExpr node = castNode(ObjectCreationExpr.class, javaParserNode, javacTree);
    processNewClass(javacTree, node);
    // When using Java 11 javac, an expression like this.new MyInnerClass() would store "this"
    // as the enclosing expression. In Java 8 javac, this would be stored as new
    // MyInnerClass(this).  So, we only traverse the enclosing expression if present in both.
    if (javacTree.getEnclosingExpression() != null && node.getScope().isPresent()) {
      javacTree.getEnclosingExpression().accept(this, node.getScope().get());
    }

    javacTree.getIdentifier().accept(this, node.getType());
    if (javacTree.getTypeArguments().isEmpty()) {
      assert !node.getTypeArguments().isPresent();
    } else {
      assert node.getTypeArguments().isPresent();
      visitLists(javacTree.getTypeArguments(), node.getTypeArguments().get());
    }

    // Remove synthetic javac argument. When using Java 11, an expression like this.new
    // MyInnerClass() would store "this" as the enclosing expression. In Java 8, this would be
    // stored as new MyInnerClass(this). So, for the argument lists to match, we may have to
    // remove the first argument.
    List<? extends ExpressionTree> javacArgs = new ArrayList<>(javacTree.getArguments());
    if (javacArgs.size() > node.getArguments().size()) {
      javacArgs.remove(0);
    }

    visitLists(javacArgs, node.getArguments());
    assert (javacTree.getClassBody() != null) == node.getAnonymousClassBody().isPresent();
    if (javacTree.getClassBody() != null) {
      visitAnonymousClassBody(javacTree.getClassBody(), node.getAnonymousClassBody().get());
    }

    return null;
  }

  @Override
  public Void visitOpens(OpensTree javacTree, Node javaParserNode) {
    ModuleOpensDirective node = castNode(ModuleOpensDirective.class, javaParserNode, javacTree);
    processOpens(javacTree, node);
    javacTree.getPackageName().accept(this, node.getName());
    visitLists(javacTree.getModuleNames(), node.getModuleNames());
    return null;
  }

  @Override
  public Void visitOther(Tree javacTree, Node javaParserNode) {
    processOther(javacTree, javaParserNode);
    return null;
  }

  @Override
  public Void visitPackage(PackageTree javacTree, Node javaParserNode) {
    PackageDeclaration node = castNode(PackageDeclaration.class, javaParserNode, javacTree);
    processPackage(javacTree, node);
    // visitLists(javacTree.getAnnotations(), node.getAnnotations());
    javacTree.getPackageName().accept(this, node.getName());
    return null;
  }

  @Override
  public Void visitParameterizedType(ParameterizedTypeTree javacTree, Node javaParserNode) {
    ClassOrInterfaceType node = castNode(ClassOrInterfaceType.class, javaParserNode, javacTree);
    processParameterizedType(javacTree, node);
    javacTree.getType().accept(this, node);
    // TODO: In a parameterized type, will the first branch ever run?
    if (javacTree.getTypeArguments().isEmpty()) {
      assert !node.getTypeArguments().isPresent() || node.getTypeArguments().get().isEmpty();
    } else {
      assert node.getTypeArguments().isPresent();
      visitLists(javacTree.getTypeArguments(), node.getTypeArguments().get());
    }
    return null;
  }

  @Override
  public Void visitParenthesized(ParenthesizedTree javacTree, Node javaParserNode) {
    EnclosedExpr node = castNode(EnclosedExpr.class, javaParserNode, javacTree);
    processParenthesized(javacTree, node);
    javacTree.getExpression().accept(this, node.getInner());
    return null;
  }

  @Override
  public Void visitPrimitiveType(PrimitiveTypeTree javacTree, Node javaParserNode) {
    if (javaParserNode instanceof PrimitiveType) {
      processPrimitiveType(javacTree, (PrimitiveType) javaParserNode);
    } else if (javaParserNode instanceof VoidType) {
      processPrimitiveType(javacTree, (VoidType) javaParserNode);
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitProvides(ProvidesTree javacTree, Node javaParserNode) {
    ModuleProvidesDirective node =
        castNode(ModuleProvidesDirective.class, javaParserNode, javacTree);
    processProvides(javacTree, node);
    javacTree.getServiceName().accept(this, node.getName());
    visitLists(javacTree.getImplementationNames(), node.getWith());
    return null;
  }

  @Override
  public Void visitRequires(RequiresTree javacTree, Node javaParserNode) {
    ModuleRequiresDirective node =
        castNode(ModuleRequiresDirective.class, javaParserNode, javacTree);
    processRequires(javacTree, node);
    javacTree.getModuleName().accept(this, node.getName());
    return null;
  }

  @Override
  public Void visitReturn(ReturnTree javacTree, Node javaParserNode) {
    ReturnStmt node = castNode(ReturnStmt.class, javaParserNode, javacTree);
    processReturn(javacTree, node);
    visitOptional(javacTree.getExpression(), node.getExpression());

    return null;
  }

  @Override
  public Void visitSwitch(SwitchTree javacTree, Node javaParserNode) {
    SwitchStmt node = castNode(SwitchStmt.class, javaParserNode, javacTree);
    processSwitch(javacTree, node);
    // Switch expressions are always parenthesized in javac but never in JavaParser.
    ExpressionTree expression = ((ParenthesizedTree) javacTree.getExpression()).getExpression();
    expression.accept(this, node.getSelector());
    visitLists(javacTree.getCases(), node.getEntries());
    return null;
  }

  @Override
  public Void visitSynchronized(SynchronizedTree javacTree, Node javaParserNode) {
    SynchronizedStmt node = castNode(SynchronizedStmt.class, javaParserNode, javacTree);
    processSynchronized(javacTree, node);
    ((ParenthesizedTree) javacTree.getExpression())
        .getExpression()
        .accept(this, node.getExpression());
    javacTree.getBlock().accept(this, node.getBody());
    return null;
  }

  @Override
  public Void visitThrow(ThrowTree javacTree, Node javaParserNode) {
    ThrowStmt node = castNode(ThrowStmt.class, javaParserNode, javacTree);
    processThrow(javacTree, node);
    javacTree.getExpression().accept(this, node.getExpression());
    return null;
  }

  @Override
  public Void visitTry(TryTree javacTree, Node javaParserNode) {
    TryStmt node = castNode(TryStmt.class, javaParserNode, javacTree);
    processTry(javacTree, node);
    Iterator<? extends Tree> javacResources = javacTree.getResources().iterator();
    for (Expression resource : node.getResources()) {
      if (resource.isVariableDeclarationExpr()) {
        for (VariableDeclarator declarator : resource.asVariableDeclarationExpr().getVariables()) {
          assert javacResources.hasNext();
          javacResources.next().accept(this, declarator);
        }
      } else {
        assert javacResources.hasNext();
        javacResources.next().accept(this, resource);
      }
    }

    javacTree.getBlock().accept(this, node.getTryBlock());
    visitLists(javacTree.getCatches(), node.getCatchClauses());
    visitOptional(javacTree.getFinallyBlock(), node.getFinallyBlock());

    return null;
  }

  @Override
  public Void visitTypeCast(TypeCastTree javacTree, Node javaParserNode) {
    CastExpr node = castNode(CastExpr.class, javaParserNode, javacTree);
    processTypeCast(javacTree, node);
    javacTree.getType().accept(this, node.getType());
    javacTree.getExpression().accept(this, node.getExpression());
    return null;
  }

  @Override
  public Void visitTypeParameter(TypeParameterTree javacTree, Node javaParserNode) {
    TypeParameter node = castNode(TypeParameter.class, javaParserNode, javacTree);
    processTypeParameter(javacTree, node);
    visitLists(javacTree.getBounds(), node.getTypeBound());
    return null;
  }

  @Override
  public Void visitUnary(UnaryTree javacTree, Node javaParserNode) {
    UnaryExpr node = castNode(UnaryExpr.class, javaParserNode, javacTree);
    processUnary(javacTree, node);
    javacTree.getExpression().accept(this, node.getExpression());
    return null;
  }

  @Override
  public Void visitUnionType(UnionTypeTree javacTree, Node javaParserNode) {
    UnionType node = castNode(UnionType.class, javaParserNode, javacTree);
    processUnionType(javacTree, node);
    visitLists(javacTree.getTypeAlternatives(), node.getElements());
    return null;
  }

  @Override
  public Void visitUses(UsesTree javacTree, Node javaParserNode) {
    ModuleUsesDirective node = castNode(ModuleUsesDirective.class, javaParserNode, javacTree);
    processUses(javacTree, node);
    javacTree.getServiceName().accept(this, node.getName());
    return null;
  }

  @Override
  public Void visitVariable(VariableTree javacTree, Node javaParserNode) {
    // Javac uses the class VariableTree to represent multiple syntactic concepts such as
    // variable declarations, parameters, and fields.
    if (javaParserNode instanceof VariableDeclarator) {
      // JavaParser uses VariableDeclarator as parts of other declaration types like
      // VariableDeclarationExpr when multiple variables may be declared.
      VariableDeclarator node = (VariableDeclarator) javaParserNode;
      processVariable(javacTree, node);
      // Don't process the variable type when it's the Java keyword "var".
      if (!node.getType().isVarType()
          && (!node.getType().isClassOrInterfaceType()
              || !node.getType().asClassOrInterfaceType().getName().asString().equals("var"))) {
        javacTree.getType().accept(this, node.getType());
      }

      // The name expression can be null, even when a name exists.
      if (javacTree.getNameExpression() != null) {
        javacTree.getNameExpression().accept(this, node.getName());
      }

      visitOptional(javacTree.getInitializer(), node.getInitializer());
    } else if (javaParserNode instanceof Parameter) {
      Parameter node = (Parameter) javaParserNode;
      processVariable(javacTree, node);
      if (node.isVarArgs()) {
        ArrayTypeTree arrayType;
        // A varargs parameter's type will either be an ArrayTypeTree or an
        // AnnotatedType depending on whether it has an annotation.
        if (javacTree.getType().getKind() == Kind.ARRAY_TYPE) {
          arrayType = (ArrayTypeTree) javacTree.getType();
        } else {
          AnnotatedTypeTree annotatedType = (AnnotatedTypeTree) javacTree.getType();
          arrayType = (ArrayTypeTree) annotatedType.getUnderlyingType();
        }

        arrayType.getType().accept(this, node.getType());
      } else {
        // Types for lambda parameters without explicit types don't have JavaParser nodes,
        // don't process them.
        if (!node.getType().isUnknownType()) {
          javacTree.getType().accept(this, node.getType());
        }
      }

      // The name expression can be null, even when a name exists.
      if (javacTree.getNameExpression() != null) {
        javacTree.getNameExpression().accept(this, node.getName());
      }

      assert javacTree.getInitializer() == null;
    } else if (javaParserNode instanceof ReceiverParameter) {
      ReceiverParameter node = (ReceiverParameter) javaParserNode;
      processVariable(javacTree, node);
      javacTree.getType().accept(this, node.getType());
      // The name expression can be null, even when a name exists.
      if (javacTree.getNameExpression() != null) {
        javacTree.getNameExpression().accept(this, node.getName());
      }

      assert javacTree.getInitializer() == null;
    } else if (javaParserNode instanceof EnumConstantDeclaration) {
      // In javac, an enum constant is expanded as a variable declaration initialized to a
      // constuctor call.
      EnumConstantDeclaration node = (EnumConstantDeclaration) javaParserNode;
      processVariable(javacTree, node);
      if (javacTree.getNameExpression() != null) {
        javacTree.getNameExpression().accept(this, node.getName());
      }

      assert javacTree.getInitializer().getKind() == Kind.NEW_CLASS;
      NewClassTree constructor = (NewClassTree) javacTree.getInitializer();
      visitLists(constructor.getArguments(), node.getArguments());
      if (constructor.getClassBody() != null) {
        visitAnonymousClassBody(constructor.getClassBody(), node.getClassBody());
      } else {
        assert node.getClassBody().isEmpty();
      }
    } else {
      throwUnexpectedNodeType(javacTree, javaParserNode);
    }

    return null;
  }

  @Override
  public Void visitWhileLoop(WhileLoopTree javacTree, Node javaParserNode) {
    WhileStmt node = castNode(WhileStmt.class, javaParserNode, javacTree);
    processWhileLoop(javacTree, node);
    // While loop conditions are always parenthesized in javac but never in JavaParser.
    assert javacTree.getCondition().getKind() == Kind.PARENTHESIZED;
    ExpressionTree condition = ((ParenthesizedTree) javacTree.getCondition()).getExpression();
    condition.accept(this, node.getCondition());
    javacTree.getStatement().accept(this, node.getBody());
    return null;
  }

  @Override
  public Void visitWildcard(WildcardTree javacTree, Node javaParserNode) {
    WildcardType node = castNode(WildcardType.class, javaParserNode, javacTree);
    processWildcard(javacTree, node);
    // In javac, whether the bound is an extends or super clause depends on the kind of the tree.
    assert (javacTree.getKind() == Kind.EXTENDS_WILDCARD) == node.getExtendedType().isPresent();
    assert (javacTree.getKind() == Kind.SUPER_WILDCARD) == node.getSuperType().isPresent();
    switch (javacTree.getKind()) {
      case UNBOUNDED_WILDCARD:
        break;
      case EXTENDS_WILDCARD:
        javacTree.getBound().accept(this, node.getExtendedType().get());
        break;
      case SUPER_WILDCARD:
        javacTree.getBound().accept(this, node.getSuperType().get());
        break;
      default:
        throw new BugInCF("Unexpected wildcard kind: %s", javacTree);
    }

    return null;
  }

  /**
   * Process an {@code AnnotationTree} with multiple key-value pairs like {@code @MyAnno(a=5,
   * b=10)}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processAnnotation(
      AnnotationTree javacTree, NormalAnnotationExpr javaParserNode);

  /**
   * Process an {@code AnnotationTree} with no arguments like {@code @MyAnno}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processAnnotation(
      AnnotationTree javacTree, MarkerAnnotationExpr javaParserNode);

  /**
   * Process an {@code AnnotationTree} with a single argument like {@code MyAnno(5)}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processAnnotation(
      AnnotationTree javacTree, SingleMemberAnnotationExpr javaParserNode);

  /**
   * Process an {@code AnnotatedTypeTree}.
   *
   * <p>In javac, a type with an annotation is represented as an {@code AnnotatedTypeTree} with a
   * nested tree for the base type whereas in JavaParser the annotations are store directly on the
   * node for the base type. As a result, the JavaParser base type node will be processed twice,
   * once with the {@code AnnotatedTypeTree} and once with the tree for the base type.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processAnnotatedType(AnnotatedTypeTree javacTree, Node javaParserNode);

  /**
   * Process an {@code ArrayAccessTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processArrayAccess(
      ArrayAccessTree javacTree, ArrayAccessExpr javaParserNode);

  /**
   * Process an {@code ArrayTypeTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processArrayType(ArrayTypeTree javacTree, ArrayType javaParserNode);

  /**
   * Process an {@code AssertTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processAssert(AssertTree javacTree, AssertStmt javaParserNode);

  /**
   * Process an {@code AssignmentTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processAssignment(AssignmentTree javacTree, AssignExpr javaParserNode);

  /**
   * Process a {@code BinaryTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processBinary(BinaryTree javacTree, BinaryExpr javaParserNode);

  /**
   * Process a {@code BlockTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processBlock(BlockTree javacTree, BlockStmt javaParserNode);

  /**
   * Process a {@code BreakTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processBreak(BreakTree javacTree, BreakStmt javaParserNode);

  /**
   * Process a {@code CaseTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processCase(CaseTree javacTree, SwitchEntry javaParserNode);

  /**
   * Process a {@code CatchTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processCatch(CatchTree javacTree, CatchClause javaParserNode);

  /**
   * Process a {@code ClassTree} representing an annotation declaration.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processClass(ClassTree javacTree, AnnotationDeclaration javaParserNode);

  /**
   * Process a {@code ClassTree} representing an annotation declaration.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processClass(
      ClassTree javacTree, ClassOrInterfaceDeclaration javaParserNode);

  /**
   * Process a {@code ClassTree} representing an enum declaration.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processClass(ClassTree javacTree, EnumDeclaration javaParserNode);

  /**
   * Process a {@code CompilationUnitTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processCompilationUnit(
      CompilationUnitTree javacTree, CompilationUnit javaParserNode);

  /**
   * Process a {@code ConditionalExpressionTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processConditionalExpression(
      ConditionalExpressionTree javacTree, ConditionalExpr javaParserNode);

  /**
   * Process a {@code ContinueTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processContinue(ContinueTree javacTree, ContinueStmt javaParserNode);

  /**
   * Process a {@code DoWhileLoopTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processDoWhileLoop(DoWhileLoopTree javacTree, DoStmt javaParserNode);

  /**
   * Process an {@code EmptyStatementTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processEmptyStatement(
      EmptyStatementTree javacTree, EmptyStmt javaParserNode);

  /**
   * Process an {@code EnhancedForLoopTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processEnhancedForLoop(
      EnhancedForLoopTree javacTree, ForEachStmt javaParserNode);

  /**
   * Process an {@code ExportsTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processExports(ExportsTree javacTree, ModuleExportsDirective javaParserNode);

  /**
   * Process an {@code ExpressionStatementTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processExpressionStatemen(
      ExpressionStatementTree javacTree, ExpressionStmt javaParserNode);

  /**
   * Process a {@code ForLoopTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processForLoop(ForLoopTree javacTree, ForStmt javaParserNode);

  /**
   * Process an {@code IdentifierTree} representing a class or interface type.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIdentifier(
      IdentifierTree javacTree, ClassOrInterfaceType javaParserNode);

  /**
   * Process an {@code IdentifierTree} representing a name that may contain dots.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIdentifier(IdentifierTree javacTree, Name javaParserNode);

  /**
   * Process an {@code IdentifierTree} representing an expression that evaluates to the value of a
   * variable.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIdentifier(IdentifierTree javacTree, NameExpr javaParserNode);

  /**
   * Process an {@code IdentifierTree} representing a name without dots.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIdentifier(IdentifierTree javacTree, SimpleName javaParserNode);

  /**
   * Process an {@code IdentifierTree} representing a {@code super} expression like the {@code
   * super} in {@code super.myMethod()} or {@code MyClass.super.myMethod()}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIdentifier(IdentifierTree javacTree, SuperExpr javaParserNode);

  /**
   * Process an {@code IdentifierTree} representing a {@code this} expression like the {@code this}
   * in {@code MyClass = this}, {@code this.myMethod()}, or {@code MyClass.this.myMethod()}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIdentifier(IdentifierTree javacTree, ThisExpr javaParserNode);

  /**
   * Process an {@code IfTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIf(IfTree javacTree, IfStmt javaParserNode);

  /**
   * Process an {@code ImportTree}.
   *
   * <p>Wildcards are stored differently between the two. In a statement like {@code import a.*;},
   * the name is stored as a {@code MemberSelectTree} with {@code a} and {@code *}. In JavaParser
   * this is just stored as {@code a} but with a method that returns whether it has a wildcard.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processImport(ImportTree javacTree, ImportDeclaration javaParserNode);

  /**
   * Process an {@code InstanceOfTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processInstanceOf(InstanceOfTree javacTree, InstanceOfExpr javaParserNode);

  /**
   * Process an {@code IntersectionType}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processIntersectionType(
      IntersectionTypeTree javacTree, IntersectionType javaParserNode);

  /**
   * Process a {@code LabeledStatement}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processLabeledStatement(
      LabeledStatementTree javacTree, LabeledStmt javaParserNode);

  /**
   * Process a {@code LambdaExpressionTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processLambdaExpression(
      LambdaExpressionTree javacTree, LambdaExpr javaParserNode);

  /**
   * Process a {@code LiteralTree} for a String literal defined using concatenation.
   *
   * <p>For an expression like {@code "a" + "b"}, javac stores a single String literal {@code "ab"}
   * but JavaParser stores it as an operation with two operands.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processLiteral(LiteralTree javacTree, BinaryExpr javaParserNode);

  /**
   * Process a {@code LiteralTree} for a literal expression prefixed with {@code +} or {@code -}
   * like {@code +5} or {@code -2}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processLiteral(LiteralTree javacTree, UnaryExpr javaParserNode);

  /**
   * Process a {@code LiteralTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processLiteral(LiteralTree javacTree, LiteralExpr javaParserNode);

  /**
   * Process a {@code MemberReferenceTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberReference(
      MemberReferenceTree javacTree, MethodReferenceExpr javaParserNode);

  /**
   * Process a {@code MemberSelectTree} for a class expression like {@code MyClass.class}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberSelect(MemberSelectTree javacTree, ClassExpr javaParserNode);

  /**
   * Process a {@code MemberSelectTree} for a type with a name containing dots, like {@code
   * mypackage.MyClass}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberSelect(
      MemberSelectTree javacTree, ClassOrInterfaceType javaParserNode);
  /**
   * Process a {@code MemberSelectTree} for a field access expression like {@code myObj.myField}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberSelect(
      MemberSelectTree javacTree, FieldAccessExpr javaParserNode);

  /**
   * Process a {@code MemberSelectTree} for a name that contains dots.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberSelect(MemberSelectTree javacTree, Name javaParserNode);

  /**
   * Process a {@code MemberSelectTree} for a this expression with a class like {@code
   * MyClass.this}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberSelect(MemberSelectTree javacTree, ThisExpr javaParserNode);

  /**
   * Process a {@code MemberSelectTree} for a super expression with a class like {@code
   * super.MyClass}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMemberSelect(MemberSelectTree javacTree, SuperExpr javaParserNode);

  /**
   * Process a {@code MethodTree} representing a regular method declaration.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMethod(MethodTree javacTree, MethodDeclaration javaParserNode);

  /**
   * Process a {@code MethodTree} representing a constructor declaration.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMethod(MethodTree javacTree, ConstructorDeclaration javaParserNode);

  /**
   * Process a {@code MethodTree} representing a value field for an annotation.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMethod(
      MethodTree javacTree, AnnotationMemberDeclaration javaParserNode);

  /**
   * Process a {@code MethodInvocationTree} representing a constructor invocation.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMethodInvocation(
      MethodInvocationTree javacTree, ExplicitConstructorInvocationStmt javaParserNode);

  /**
   * Process a {@code MethodInvocationTree} representing a regular method invocation.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processMethodInvocation(
      MethodInvocationTree javacTree, MethodCallExpr javaParserNode);

  /**
   * Process a {@code ModuleTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processModule(ModuleTree javacTree, ModuleDeclaration javaParserNode);

  /**
   * Process a {@code NewClassTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processNewClass(NewClassTree javacTree, ObjectCreationExpr javaParserNode);

  /**
   * Process an {@code OpensTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processOpens(OpensTree javacTree, ModuleOpensDirective javaParserNode);

  /**
   * Process a {@code Tree} that isn't an instance of any specific tree class.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processOther(Tree javacTree, Node javaParserNode);

  /**
   * Process a {@code PackageTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processPackage(PackageTree javacTree, PackageDeclaration javaParserNode);

  /**
   * Process a {@code ParameterizedTypeTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processParameterizedType(
      ParameterizedTypeTree javacTree, ClassOrInterfaceType javaParserNode);

  /**
   * Process a {@code ParenthesizedTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processParenthesized(
      ParenthesizedTree javacTree, EnclosedExpr javaParserNode);

  /**
   * Process a {@code PrimitiveTypeTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processPrimitiveType(
      PrimitiveTypeTree javacTree, PrimitiveType javaParserNode);

  /**
   * Process a {@code PrimitiveTypeTree} representing a void type.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processPrimitiveType(PrimitiveTypeTree javacTree, VoidType javaParserNode);

  /**
   * Process a {@code ProvidesTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processProvides(
      ProvidesTree javacTree, ModuleProvidesDirective javaParserNode);

  /**
   * Process a {@code RequiresTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processRequires(
      RequiresTree javacTree, ModuleRequiresDirective javaParserNode);

  /**
   * Process a {@code RetrunTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processReturn(ReturnTree javacTree, ReturnStmt javaParserNode);

  /**
   * Process a {@code SwitchTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processSwitch(SwitchTree javacTree, SwitchStmt javaParserNode);

  /**
   * Process a {@code SynchronizedTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processSynchronized(
      SynchronizedTree javacTree, SynchronizedStmt javaParserNode);

  /**
   * Process a {@code ThrowTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processThrow(ThrowTree javacTree, ThrowStmt javaParserNode);

  /**
   * Process a {@code TryTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processTry(TryTree javacTree, TryStmt javaParserNode);

  /**
   * Process a {@code TypeCastTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processTypeCast(TypeCastTree javacTree, CastExpr javaParserNode);

  /**
   * Process a {@code TypeParameterTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processTypeParameter(
      TypeParameterTree javacTree, TypeParameter javaParserNode);

  /**
   * Process a {@code UnaryTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processUnary(UnaryTree javacTree, UnaryExpr javaParserNode);

  /**
   * Process a {@code UnionTypeTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processUnionType(UnionTypeTree javacTree, UnionType javaParserNode);

  /**
   * Process a {@code UsesTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processUses(UsesTree javacTree, ModuleUsesDirective javaParserNode);

  /**
   * Process a {@code VariableTree} representing an enum constant declaration. In an enum like
   * {@code enum MyEnum { MY_CONSTANT }}, javac expands {@code MY_CONSTANT} as a constant variable.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processVariable(
      VariableTree javacTree, EnumConstantDeclaration javaParserNode);

  /**
   * Process a {@code VariableTree} representing a parameter to a method or constructor.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processVariable(VariableTree javacTree, Parameter javaParserNode);

  /**
   * Process a {@code VariableTree} representing the receiver parameter of a method.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processVariable(VariableTree javacTree, ReceiverParameter javaParserNode);

  /**
   * Process a {@code VariableTree} representing a regular variable declaration.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processVariable(VariableTree javacTree, VariableDeclarator javaParserNode);

  /**
   * Process a {@code WhileLoopTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processWhileLoop(WhileLoopTree javacTree, WhileStmt javaParserNode);

  /**
   * Process a {@code WhileLoopTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processWildcard(WildcardTree javacTree, WildcardType javaParserNode);

  /**
   * Process a {@code CompoundAssignmentTree}.
   *
   * @param javacTree tree to process
   * @param javaParserNode corresponding JavaParser node
   */
  public abstract void processCompoundAssignment(
      CompoundAssignmentTree javacTree, AssignExpr javaParserNode);

  /**
   * Given a list of javac trees and a list of JavaParser nodes, where the elements of the lists
   * correspond to each other, visit each javac tree along with its corresponding JavaParser node.
   *
   * <p>The two lists must be of the same length and elements at corresponding positions must match.
   *
   * @param javacTrees list of trees
   * @param javaParserNodes list of corresponding JavaParser nodes
   */
  private void visitLists(List<? extends Tree> javacTrees, List<? extends Node> javaParserNodes) {
    assert javacTrees.size() == javaParserNodes.size();
    Iterator<? extends Node> nodeIter = javaParserNodes.iterator();
    for (Tree tree : javacTrees) {
      tree.accept(this, nodeIter.next());
    }
  }

  /**
   * Visit an optional syntax construct. Whether the javac tree is non-null must match whether the
   * JavaParser optional is present.
   *
   * @param javacTree a javac tree or null
   * @param javaParserNode an optional JavaParser node, which might not be present
   */
  private void visitOptional(Tree javacTree, Optional<? extends Node> javaParserNode) {
    assert javacTree != null == javaParserNode.isPresent()
        : String.format("visitOptional(%s, %s)", javacTree, javaParserNode);
    if (javacTree != null) {
      javacTree.accept(this, javaParserNode.get());
    }
  }

  /**
   * Cast {@code javaParserNode} to type {@code type} and return it.
   *
   * @param <T> the type of {@code type}
   * @param type the type to cast to
   * @param javaParserNode the object to cast
   * @param javacTree the javac tree that corresponds to {@code javaParserNode}; used only for error
   *     reporting
   * @return javaParserNode, casted to {@code type}
   */
  public <T> T castNode(Class<T> type, Node javaParserNode, Tree javacTree) {
    if (type.isInstance(javaParserNode)) {
      return type.cast(javaParserNode);
    }
    throwUnexpectedNodeType(javacTree, javaParserNode, type);
    throw new BugInCF("unreachable");
  }

  /**
   * Given a javac tree and JavaPaser node which were visited but didn't correspond to each other,
   * throws an exception indicating that the visiting process failed for those nodes.
   *
   * @param javacTree a tree that was visited
   * @param javaParserNode a node that was visited at the same time as {@code javacTree}, but which
   *     was not of the correct type for that tree
   * @throws BugInCF that indicates the javac trees and JavaParser nodes were desynced during the
   *     visitng process at {@code javacTree} and {@code javaParserNode}
   */
  private void throwUnexpectedNodeType(Tree javacTree, Node javaParserNode) {
    throw new BugInCF(
        "desynced trees: %s [%s], %s [%s]",
        javacTree, javacTree.getClass(), javaParserNode, javaParserNode.getClass());
  }

  /**
   * Given a javac tree and JavaPaser node which were visited but didn't correspond to each other,
   * throws an exception indicating that the visiting process failed for those nodes because {@code
   * javaParserNode} was expected to be of type {@code expectedType}.
   *
   * @param javacTree a tree that was visited
   * @param javaParserNode a node that was visited at the same time as {@code javacTree}, but which
   *     was not of the correct type for that tree
   * @param expectedType the type {@code javaParserNode} was expected to be based on {@code
   *     javacTree}
   * @throws BugInCF that indicates the javac trees and JavaParser nodes were desynced during the
   *     visitng process at {@code javacTree} and {@code javaParserNode}
   */
  private void throwUnexpectedNodeType(Tree javacTree, Node javaParserNode, Class<?> expectedType) {
    throw new BugInCF(
        "desynced trees: %s [%s], %s [%s (expected %s)]",
        javacTree, javacTree.getClass(), javaParserNode, javaParserNode.getClass(), expectedType);
  }
}
