void doWriteFiles(TreeSet allFiles, Vector allConfigNames, NameFilter filter) {
    startTag(
        "Filter",
        new String[] {
          "Name", filter.name(),
          "Filter", filter.filterString()
        });

    if (filter instanceof ContainerFilter) {

      Iterator i = ((ContainerFilter) filter).babies();
      while (i.hasNext()) {
        doWriteFiles(allFiles, allConfigNames, (NameFilter) i.next());
      }

    } else {

      Iterator i = allFiles.iterator();
      while (i.hasNext()) {
        FileInfo fi = (FileInfo) i.next();

        if (!filter.match(fi)) {
          continue;
        }

        startTag("File", new String[] {"RelativePath", fi.full.replace('/', '\\')});

        FileAttribute a = fi.attr;
        if (a.pchRoot) {
          writeCustomToolConfig(
              allConfigNames,
              new String[] {
                "Name", "VCCLCompilerTool",
                "UsePrecompiledHeader", "1"
              });
        }

        if (a.noPch) {
          writeCustomToolConfig(
              allConfigNames,
              new String[] {
                "Name", "VCCLCompilerTool",
                "UsePrecompiledHeader", "0"
              });
        }

        if (a.configs != null) {
          for (Iterator j = allConfigNames.iterator(); j.hasNext(); ) {
            String cfg = (String) j.next();
            if (!a.configs.contains(cfg)) {
              startTag(
                  "FileConfiguration", new String[] {"Name", cfg, "ExcludedFromBuild", "TRUE"});
              tag("Tool", new String[] {"Name", "VCCLCompilerTool"});
              endTag("FileConfiguration");
            }
          }
        }

        endTag("File");

        // we not gonna look at this file anymore
        i.remove();
      }
    }

    endTag("Filter");
  }