void writeConfiguration(BuildConfig cfg) {
    startTag(
        "Configuration",
        new String[] {
          "Name",
          cfg.get("Name"),
          "OutputDirectory",
          cfg.get("OutputDir"),
          "IntermediateDirectory",
          cfg.get("OutputDir"),
          "ConfigurationType",
          "2",
          "UseOfMFC",
          "0",
          "ATLMinimizesCRunTimeLibraryUsage",
          "FALSE"
        });

    tagV("Tool", cfg.getV("CompilerFlags"));

    tag("Tool", new String[] {"Name", "VCCustomBuildTool"});

    tagV("Tool", cfg.getV("LinkerFlags"));

    tag("Tool", new String[] {"Name", "VCPostBuildEventTool"});

    tag("Tool", new String[] {"Name", "VCPreBuildEventTool"});

    tag(
        "Tool",
        new String[] {
          "Name", "VCPreLinkEventTool",
          "Description", BuildConfig.getFieldString(null, "PrelinkDescription"),
          // Caution: String.replace(String,String) is available from JDK5 onwards only
          "CommandLine",
              cfg.expandFormat(
                  BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "
"))
        });

    tag(
        "Tool",
        new String[] {
          "Name", "VCResourceCompilerTool",
          // XXX???
          "PreprocessorDefinitions", "NDEBUG",
          "Culture", "1033"
        });
    tag("Tool", new String[] {"Name", "VCWebServiceProxyGeneratorTool"});

    tag("Tool", new String[] {"Name", "VCXMLDataGeneratorTool"});

    tag("Tool", new String[] {"Name", "VCWebDeploymentTool"});
    tag("Tool", new String[] {"Name", "VCManagedWrapperGeneratorTool"});
    tag("Tool", new String[] {"Name", "VCAuxiliaryManagedWrapperGeneratorTool"});

    tag(
        "Tool",
        new String[] {
          "Name", "VCMIDLTool",
          "PreprocessorDefinitions", "NDEBUG",
          "MkTypLibCompatible", "TRUE",
          "SuppressStartupBanner", "TRUE",
          "TargetEnvironment", "1",
          "TypeLibraryName", cfg.get("OutputDir") + Util.sep + "vm.tlb",
          "HeaderFileName", ""
        });

    endTag("Configuration");
  }
  // here we define filters, which define layout of what can be seen in 'Solution View' of MSVC
  // Basically there are two types of entities - container filters and real filters
  //   - container filter just provides a container to group together real filters
  //   - real filter can select elements from the set according to some rule, put it into XML
  //     and remove from the list
  Vector makeFilters(TreeSet files) {
    Vector rv = new Vector();
    String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase") + "/src/");

    ContainerFilter rt = new ContainerFilter("Runtime");
    rt.add(new DirectoryFilter("share/vm/prims", sbase));
    rt.add(new DirectoryFilter("share/vm/runtime", sbase));
    rt.add(new DirectoryFilter("share/vm/oops", sbase));
    rv.add(rt);

    ContainerFilter gc = new ContainerFilter("GC");
    gc.add(new DirectoryFilter("share/vm/memory", sbase));
    gc.add(new DirectoryFilter("share/vm/gc_interface", sbase));

    ContainerFilter gc_impl = new ContainerFilter("Implementations");
    gc_impl.add(
        new DirectoryFilter("CMS", "share/vm/gc_implementation/concurrentMarkSweep", sbase));
    gc_impl.add(
        new DirectoryFilter(
            "Parallel Scavenge", "share/vm/gc_implementation/parallelScavenge", sbase));
    gc_impl.add(new DirectoryFilter("Shared", "share/vm/gc_implementation/shared", sbase));
    // for all leftovers
    gc_impl.add(new DirectoryFilter("Misc", "share/vm/gc_implementation", sbase));

    gc.add(gc_impl);
    rv.add(gc);

    rv.add(new DirectoryFilter("C1", "share/vm/c1", sbase));

    ContainerFilter c2 = new ContainerFilter("C2");
    // c2.add(new DirectoryFilter("share/vm/adlc", sbase));
    c2.add(new DirectoryFilter("share/vm/opto", sbase));
    c2.add(new SpecificNameFilter("Generated", new String[] {"^ad_.+", "^dfa_.+", "^adGlobals.+"}));
    rv.add(c2);

    ContainerFilter comp = new ContainerFilter("Compiler Common");
    comp.add(new DirectoryFilter("share/vm/asm", sbase));
    comp.add(new DirectoryFilter("share/vm/ci", sbase));
    comp.add(new DirectoryFilter("share/vm/code", sbase));
    comp.add(new DirectoryFilter("share/vm/compiler", sbase));
    rv.add(comp);

    rv.add(new DirectoryFilter("Interpreter", "share/vm/interpreter", sbase));

    ContainerFilter misc = new ContainerFilter("Misc");
    // misc.add(new DirectoryFilter("share/vm/launch", sbase));
    misc.add(new DirectoryFilter("share/vm/libadt", sbase));
    misc.add(new DirectoryFilter("share/vm/services", sbase));
    misc.add(new DirectoryFilter("share/vm/utilities", sbase));
    rv.add(misc);

    rv.add(new DirectoryFilter("os_cpu", sbase));

    rv.add(new DirectoryFilter("cpu", sbase));

    rv.add(new DirectoryFilter("os", sbase));

    rv.add(new SpecificNameFilter("JVMTI Generated", new String[] {"^jvmti.+"}));

    rv.add(
        new SpecificNameFilter(
            "C++ Interpreter Generated", new String[] {"^bytecodeInterpreterWithChecks.+"}));

    rv.add(new SpecificNameFilter("Include DBs", new String[] {"^includeDB_.+"}));

    // this one is to catch files not caught by other filters
    // rv.add(new TypeFilter("Header Files", new String[] {"h", "hpp", "hxx", "hm", "inl", "fi",
    // "fd"}));
    rv.add(new TerminatorFilter("Source Files"));

    return rv;
  }