@Override
  protected void runExpensiveCommand() throws Exception {
    var matchesFile = new File(data.getMatchesDBPath());

    try (MatchesDatabase matchesDB = new MatchesDatabase(matchesFile)) {
      FunctionDiffMetadata metaData = matchesDB.loadFunctionDiffMetadata(true);

      var primaryExportFile = new File(data.getBinExportPath(ESide.PRIMARY));
      var secondaryExportFile = new File(data.getBinExportPath(ESide.SECONDARY));

      Diff diff = data.getDiff();
      if (diff == null) {
        diff = new Diff(metaData, matchesFile, primaryExportFile, secondaryExportFile, true);
      }

      var diffLoader = new DiffLoader();
      diffLoader.loadDiff(diff, data);

      if (diff.getCallGraph(ESide.PRIMARY).getNodes().size() != 1) {
        throw new IllegalStateException(
            "Primary call graph of a single function diff has more than one vertex.");
      }
      if (diff.getCallGraph(ESide.SECONDARY).getNodes().size() != 1) {
        throw new IllegalStateException(
            "Secondary call graph of a single function diff has more than one vertex.");
      }

      RawFunction priFunction = diff.getCallGraph(ESide.PRIMARY).getNodes().get(0);
      RawFunction secFunction = diff.getCallGraph(ESide.SECONDARY).getNodes().get(0);

      priFunction.setSizeOfBasicBlocks(metaData.getSizeOfBasicBlocks(ESide.PRIMARY));
      secFunction.setSizeOfBasicBlocks(metaData.getSizeOfBasicBlocks(ESide.SECONDARY));
      priFunction.setSizeOfJumps(metaData.getSizeOfJumps(ESide.PRIMARY));
      secFunction.setSizeOfJumps(metaData.getSizeOfJumps(ESide.SECONDARY));
      priFunction.setSizeOfInstructions(metaData.getSizeOfInstructions(ESide.PRIMARY));
      secFunction.setSizeOfInstructions(metaData.getSizeOfInstructions(ESide.SECONDARY));

      IAddress priFunctionAddr = priFunction.getAddress();
      IAddress secFunctionAddr = secFunction.getAddress();

      metaData.setFunctionAddr(priFunctionAddr, ESide.PRIMARY);
      metaData.setFunctionAddr(secFunctionAddr, ESide.SECONDARY);
      metaData.setFunctionName(priFunction.getName(), ESide.PRIMARY);
      metaData.setFunctionName(secFunction.getName(), ESide.SECONDARY);
      metaData.setFunctionType(priFunction.getFunctionType(), ESide.PRIMARY);
      metaData.setFunctionType(secFunction.getFunctionType(), ESide.SECONDARY);

      FunctionMatchData functionMatch =
          diff.getMatches().getFunctionMatch(priFunctionAddr, ESide.PRIMARY);
      matchesDB.loadBasicBlockMatches(functionMatch);

      CommentsDatabase commentsDatabase = null;
      if (workspace.isLoaded()) {
        commentsDatabase = new CommentsDatabase(workspace, true);
      }

      RawFlowGraph priFlowGraph =
          DiffLoader.loadRawFlowGraph(commentsDatabase, diff, priFunctionAddr, ESide.PRIMARY);
      RawFlowGraph secFlowGraph =
          DiffLoader.loadRawFlowGraph(commentsDatabase, diff, secFunctionAddr, ESide.SECONDARY);
      RawCombinedFlowGraph<RawCombinedBasicBlock, RawCombinedJump<RawCombinedBasicBlock>>
          combinedFlowGraph;
      combinedFlowGraph =
          RawCombinedFlowGraphBuilder.buildRawCombinedFlowGraph(
              functionMatch, priFlowGraph, secFlowGraph);

      createSingleFunctionDiffFlowGraphView(
          diff, functionMatch, priFlowGraph, secFlowGraph, combinedFlowGraph);
    }
  }
Loads flow graphs into a new view.
java/ui/src/main/java/com/google/security/zynamics/bindiff/project/diff/FunctionDiffViewLoader.java