private void writeToIndex(
      final int linkageID,
      IASTTranslationUnit ast,
      FileContent codeReader,
      FileContext ctx,
      IProgressMonitor pm)
      throws CoreException, InterruptedException {
    HashSet<FileContentKey> enteredFiles = new HashSet<FileContentKey>();
    ArrayList<FileInAST> orderedFileKeys = new ArrayList<FileInAST>();

    final IIndexFileLocation topIfl = fResolver.resolveASTPath(ast.getFilePath());
    FileContentKey topKey = new FileContentKey(linkageID, topIfl, ast.getSignificantMacros());
    enteredFiles.add(topKey);
    IDependencyTree tree = ast.getDependencyTree();
    IASTInclusionNode[] inclusions = tree.getInclusions();
    for (IASTInclusionNode inclusion : inclusions) {
      collectOrderedFileKeys(linkageID, inclusion, enteredFiles, orderedFileKeys);
    }

    IIndexFragmentFile newFile = selectIndexFile(linkageID, topIfl, ast.getSignificantMacros());
    if (ctx != null) {
      orderedFileKeys.add(new FileInAST(topKey, codeReader));
      // File can be reused
      ctx.fNewFile = newFile;
    } else if (newFile == null) {
      orderedFileKeys.add(new FileInAST(topKey, codeReader));
    }

    FileInAST[] fileKeys = orderedFileKeys.toArray(new FileInAST[orderedFileKeys.size()]);
    try {
      addSymbols(ast, fileKeys, fIndex, false, ctx, fTodoTaskUpdater, pm);
    } catch (CoreException e) {
      // Avoid parsing files again, that caused an exception to be thrown.
      withdrawRequests(linkageID, fileKeys);
      throw e;
    } catch (RuntimeException e) {
      withdrawRequests(linkageID, fileKeys);
      throw e;
    } catch (Error e) {
      withdrawRequests(linkageID, fileKeys);
      throw e;
    }
  }