public static NodeModel createAddNodeAndRelCommand(
      DiagramEditPart diagramController,
      Artifact art,
      NodeModel mostRecentNavigation,
      int mostRecentLineNumber,
      Object selElement,
      CompoundCommand command) {
    DiagramModel diagram = (DiagramModel) diagramController.getModel();
    Resource resToAdd = art.elementRes;
    IJavaElement selectedElt = null;
    if (selElement instanceof IJavaElement) selectedElt = (IJavaElement) selElement;

    ReloRdfRepository repo = StoreUtil.getDefaultStoreRepository();
    IJavaElement elmtToAdd =
        selectedElt != null ? selectedElt : RJCore.resourceToJDTElement(repo, resToAdd);
    NodeModel addedNode = null;

    if (IJavaElement.TYPE == elmtToAdd.getElementType()) {
      addedNode =
          InstanceUtil.findOrCreateContainerInstanceModel(
              null, InstanceUtil.getClassName(resToAdd, repo), resToAdd, diagram, -1, command);
    } else if (elmtToAdd instanceof IMethod && elmtToAdd.getParent() instanceof IType) {
      if (mostRecentNavigation instanceof MethodBoxModel) {
        addMethodModelsAndConns(
            addedNode, resToAdd, mostRecentNavigation, mostRecentLineNumber, diagram, command);
      }
      if (addedNode == null) {
        IType containerClass = (IType) elmtToAdd.getParent();
        Resource classRes = RJCore.jdtElementToResource(repo, containerClass);
        InstanceModel instance =
            InstanceUtil.findOrCreateContainerInstanceModel(
                null, InstanceUtil.getClassName(classRes, repo), classRes, diagram, -1, command);

        IMethod method = (IMethod) elmtToAdd;
        addedNode = MethodUtil.findOrCreateMethodModel(method, resToAdd, instance, -1, command);
      }
    } else if (elmtToAdd instanceof IField && elmtToAdd.getParent() instanceof IType) {
      if (mostRecentNavigation instanceof MethodBoxModel) {
        addFieldModelsAndConns(
            addedNode, resToAdd, mostRecentNavigation, mostRecentLineNumber, diagram, command);
      }
      if (addedNode == null) {
        IType containerClass = (IType) elmtToAdd.getParent();
        Resource classRes = RJCore.jdtElementToResource(repo, containerClass);
        InstanceModel instance =
            InstanceUtil.findOrCreateContainerInstanceModel(
                null, InstanceUtil.getClassName(classRes, repo), classRes, diagram, -1, command);

        IField field = (IField) elmtToAdd;
        addedNode = FieldUtil.findOrCreateFieldModel(field, resToAdd, instance, -1, command);
      }
    }
    return addedNode;
  }
  private static void addFieldModelsAndConns(
      NodeModel addedNode,
      Resource resToAdd,
      NodeModel mostRecentNavigation,
      int mostRecentLineNumber,
      DiagramModel diagram,
      CompoundCommand command) {

    MethodBoxModel methodAccessingField = (MethodBoxModel) mostRecentNavigation;
    for (FieldRead fieldRead : methodAccessingField.getFieldReadsMade()) {

      Resource fieldReadRes =
          RJCore.jdtElementToResource(
              StoreUtil.getDefaultStoreRepository(),
              fieldRead.resolveFieldBinding().getJavaElement());
      int fieldReadLineNum =
          InstanceUtil.getLineNumber(
              methodAccessingField.getInstanceModel(), fieldRead.getStartPosition());
      if (resToAdd.equals(fieldReadRes) && fieldReadLineNum == mostRecentLineNumber) {

        // test whether field read doesn't need to
        // be added because already in diagram
        for (FieldModel child : methodAccessingField.getFieldChildren()) {
          if (fieldRead.getFieldRead().equals(child.getASTNode())) {
            addedNode = child.getPartner();
            return;
          }
        }
        FieldModel fieldAccessModel =
            FieldUtil.createModelsForField(
                methodAccessingField,
                fieldRead,
                -1,
                FieldUtil.getFieldAccessType(fieldRead),
                diagram,
                command,
                null);
        addedNode = fieldAccessModel.getPartner();
        return;
      }
    }
  }
  private static void addMethodModelsAndConns(
      NodeModel addedNode,
      Resource resToAdd,
      NodeModel mostRecentNavigation,
      int mostRecentLineNumber,
      DiagramModel diagram,
      CompoundCommand command) {

    MethodBoxModel srcMethod = (MethodBoxModel) mostRecentNavigation;
    for (Invocation invocation : srcMethod.getCallsMade(null)) {

      Resource invocationRes =
          RJCore.jdtElementToResource(
              StoreUtil.getDefaultStoreRepository(), invocation.getMethodElement());
      int invocationLineNum =
          InstanceUtil.getLineNumber(srcMethod.getInstanceModel(), invocation.getStartPosition());
      if (resToAdd.equals(invocationRes) && invocationLineNum == mostRecentLineNumber) {

        // test whether call doesn't need to
        // be added because already in diagram
        for (MethodBoxModel child : srcMethod.getMethodChildren()) {
          if (invocation.getInvocation().equals(child.getASTNode())) {
            addedNode = child.getPartner();
            return;
          }
        }
        Resource classOfInstance =
            MethodUtil.getClassOfInstanceCalledOn(invocation, srcMethod.getInstanceModel());
        MethodBoxModel invocationModel =
            MethodUtil.createModelsForMethodRes(
                invocation, srcMethod, diagram, classOfInstance, null, false, command, null, false);
        addedNode = invocationModel.getPartner();
        return;
      }
    }
  }
  private static void generate(IRSEDiagramEngine diagramEngine) {
    if (diagramEngine == null) return;

    LinkedHashMap<IType, List<Invocation>> history =
        SeqUtil.getNavigationHistory(numNavigationsToInclude);
    List<CodeUnit> classUnits = new ArrayList<CodeUnit>();
    List<CodeUnit> methodUnits = new ArrayList<CodeUnit>();
    List<ArtifactFragment> toAddToDiagram = new ArrayList<ArtifactFragment>();

    for (IType type : history.keySet()) {
      if (!openTabs.contains(type)) continue;

      Resource classOfNavigationRes =
          RJCore.jdtElementToResource(StoreUtil.getDefaultStoreRepository(), type);
      CodeUnit classOfNavigationCU =
          GenerateUtil.getCodeUnitForRes(classOfNavigationRes, null, classUnits, null);

      // Add method calls
      for (Invocation invocation : history.get(type)) {

        IType container = null;
        if (invocation.getMethodElement() != null) {
          IMethod method = invocation.getMethodElement();
          container = method.getDeclaringType();
        }
        if (container == null) continue;

        boolean containerIsAnOpenTab = false;
        for (IType navigatedType : openTabs) {
          if (navigatedType.equals(container)) {
            containerIsAnOpenTab = true;
            break;
          }
        }
        if (!containerIsAnOpenTab) continue;

        // Find the method declaration in which the invocation is made
        CompilationUnit cu = ASTUtil.getAst(IJEUtils.ije_getTypeRoot(type));
        MethodDeclarationFinder finder = new MethodDeclarationFinder(cu);
        MethodDeclaration declaration = finder.findDeclaration(invocation.getStartPosition());
        if (declaration == null
            || declaration.resolveBinding() == null
            || declaration.resolveBinding().getJavaElement() == null) continue;

        Resource declarationRes =
            RJCore.jdtElementToResource(
                StoreUtil.getDefaultStoreRepository(),
                declaration.resolveBinding().getJavaElement());
        CodeUnit declarationThatMakesInvocation =
            GenerateUtil.getCodeUnitForRes(declarationRes, null, methodUnits, classOfNavigationCU);

        String instanceName =
            (invocation.getInvocation() instanceof SuperMethodInvocation)
                ? null
                : MethodUtil.getInstanceCalledOn(invocation);
        CodeUnit containerOfDeclOfInvokedMethod =
            GenerateUtil.getCodeUnitForRes(
                RJCore.jdtElementToResource(StoreUtil.getDefaultStoreRepository(), container),
                instanceName,
                classUnits,
                null);
        Resource declOfInvokedMethodRes =
            RJCore.jdtElementToResource(
                StoreUtil.getDefaultStoreRepository(), invocation.getMethodElement());
        CodeUnit declOfInvokedMethodCU =
            GenerateUtil.getCodeUnitForRes(
                declOfInvokedMethodRes, null, methodUnits, containerOfDeclOfInvokedMethod);

        ArtifactRel rel =
            new ArtifactRel(declarationThatMakesInvocation, declOfInvokedMethodCU, RJCore.calls);

        declarationThatMakesInvocation.addSourceConnection(rel);
        declOfInvokedMethodCU.addTargetConnection(rel);
      }

      // Add inheritance relationships among classes
      for (Resource superClassRes : InstanceUtil.getSuperClasses(classOfNavigationRes)) {
        CodeUnit superClassCU =
            GenerateUtil.getCodeUnitForRes(superClassRes, null, classUnits, null);

        IJavaElement superClassElt =
            RJCore.resourceToJDTElement(StoreUtil.getDefaultStoreRepository(), superClassRes);
        if (!history.keySet().contains(superClassElt))
          continue; // superclass has not been recently navigated
        if (!openTabs.contains(superClassElt)) continue; // superclass is not an open tab

        ArtifactRel inheritanceRel =
            new ArtifactRel(classOfNavigationCU, superClassCU, RJCore.inherits);
        classOfNavigationCU.addSourceConnection(inheritanceRel);
        superClassCU.addTargetConnection(inheritanceRel);
      }
    }

    for (CodeUnit classUnit : classUnits) {
      if (classUnit.getShownChildren().size() > 0) toAddToDiagram.add(classUnit);
    }

    int numBeingAdded = toAddToDiagram.size();
    if (numBeingAdded < numNavigationsToInclude) {
      // Diagram going to be small, so add a reasonable number
      // of the open tabs that were most recently activated
      // (openTabs list is ordered with most recently activated first)
      for (int i = 0; i < openTabs.size() && numBeingAdded < numNavigationsToInclude; i++) {
        IType type = openTabs.get(i);

        // only adding top level tabs here, not any nested classes
        if (!(type instanceof SourceType)
            || ((SourceType) type).getParent().getElementType() == IJavaElement.TYPE) continue;

        Resource classOfNavigationRes =
            RJCore.jdtElementToResource(StoreUtil.getDefaultStoreRepository(), type);
        CodeUnit classOfNavigationCU =
            GenerateUtil.getCodeUnitForRes(classOfNavigationRes, null, classUnits, null);
        if (!toAddToDiagram.contains(classOfNavigationCU)) {
          toAddToDiagram.add(classOfNavigationCU);
          numBeingAdded++;
        }
      }
    }
    diagramEngine.openDiagramFromNavigatedTabs(
        toAddToDiagram, new ArrayList<ArtifactFragment>(classUnits));
  }