/**
   * Writes the C++ header for the package to the specified output stream.
   *
   * @param out The output stream.
   * @return The output stream.
   */
  public Printer translateHeader(Printer out) {
    // Get any imports
    Set<JavaPackage> using = new HashSet<JavaPackage>();
    for (JavaFile file : files) {
      Set<JavaPackage> imports = file.getImports();
      for (JavaPackage i : imports) {
        if (!i.getPath().equals(getPath())) using.add(i);
      }
    }

    // Include any imported headers
    out.pln("#pragma once").pln();
    out.pln("#include <iostream>");
    out.pln("#include <sstream>").pln();
    out.pln("#include \"include/java_lang.h\"");
    for (JavaPackage i : using) {
      out.p("#include \"").p(i.getFilename()).pln(".h\"");
    }

    // Declare namespaces being used
    out.pln().pln("using namespace java::lang;");
    for (JavaPackage i : using) {
      out.p("using namespace ").p(i.getNamespace()).pln(";");
    }
    out.pln();

    // Add the namespace
    for (String part : pkg) {
      out.indent().p("namespace ").p(part).pln(" {").incr();
    }

    // Declare the class structs
    for (JavaFile file : files) {
      file.orderClasses();
      for (JavaClass cls : file.getClasses()) {
        String className = cls.getName();
        out.indent().p("struct __").p(className).pln(";");
        out.indent().p("struct __").p(className).pln("_VT;");
        out.pln()
            .indent()
            .p("typedef __rt::Ptr<__")
            .p(className)
            .p("> ")
            .p(className)
            .pln(";")
            .pln();
      }
    }

    // Print header structs
    for (JavaFile file : files) {
      for (JavaClass cls : file.getClasses()) {
        cls.translateHeader(out).pln();
      }
    }

    // Close the namespace
    for (int i = 0; i < pkg.size(); i++) {
      out.decr().indent().pln("}");
    }

    return out;
  }