public void setCheckedState(Object element, boolean checked) {
    File file = (File) element;

    if (checked) {
      backupSpec.addFile(file);
    } else {
      backupSpec.removeFile(file);
    }
  }
 public boolean isChecked(Object element) {
   return backupSpec.containsFile((File) element, false);
 }
  // This method formats an easily readable string describing the
  // backup specification.  An example message would be:
  //
  // "Backup c:/foo.txt, c:/bar.xls, and all files under c:/tom.  Also backup
  // c:/garrick except for c:/garrick/bigfiles."
  public void updateText() {
    ArrayList includedFiles = backupSpec.includedFiles();
    ArrayList excludedFiles = backupSpec.excludedFiles();

    if (includedFiles.isEmpty()) {
      text.setText(
          "No files are selected for backup.  Select the check box to the left of a file to mark it for backup.");
      return;
    }

    Color red = text.getDisplay().getSystemColor(SWT.COLOR_RED);
    Color blue = text.getDisplay().getSystemColor(SWT.COLOR_BLUE);

    ArrayList styles = new ArrayList();
    StringBuffer buffer = new StringBuffer();

    buffer.append("Backup ");

    // The first sentence includes all included files (not directories).  This is
    // the "Backup c:/foo.txt. c:/bar.xls..." portion of the example message.
    int numFiles = 0;
    for (int i = 0, count = includedFiles.size(); i < count; i++) {

      File file = (File) includedFiles.get(i);

      if (file.isFile()) {
        numFiles++;

        if (numFiles > 1) {
          if (numFiles == includedFiles.size()) {
            buffer.append(", and ");
          } else {
            buffer.append(", ");
          }
        }

        appendFile(file, buffer, styles, blue);
      }
    }

    if (numFiles == includedFiles.size()) {
      // We only had individual files, so put a period on it, we are done!
      // Otherwise we leave the sentence hanging so that directories can
      // be added on.
      buffer.append(".");
    } else {

      // We've got directories.
      if (numFiles > 0) {
        // If we had some files, then we need to append the
        // directories to an already existing sentence.
        buffer.append(", and ");
      }

      // Find all top level directories that have no exclusions under
      // them.  A "top level" directory is one which was not included
      // in response to an exclusion.  For instance if
      //		includedFiles = [c:/tom, c:/garrick, c:/garrick/Documents/Work]
      //  and excludedFiles = [c:/garrick/Documents]
      //
      // Then c:/tom and c:/garrick are "top level" directories, although
      // since c:/garrick has exclusions then only c:/tom will end up in
      // the list.

      ArrayList topLevelDirectoriesWithoutExclusions = new ArrayList();
      for (int i = 0, count = includedFiles.size(); i < count; i++) {
        File file = (File) includedFiles.get(i);

        if (file.isFile()) {
          continue;
        }

        backupSpec.findFilesExplicitlyExcludedFrom(file, excluded);
        File parent = file.getParentFile();
        if (excluded.isEmpty()
            && (parent == null
                || BackupSpecification.nearestAncestor(parent, includedFiles) == null)) {
          topLevelDirectoriesWithoutExclusions.add(file);
        }
      }

      // If we have any topLevelDirectoriesWithoutExclusions, then pack
      // them into one sentence (potentially along with the lone files).
      boolean appendedDirectory = false;
      if (topLevelDirectoriesWithoutExclusions.size() > 0) {
        buffer.append("all files under ");

        for (int i = 0, count = topLevelDirectoriesWithoutExclusions.size(); i < count; i++) {
          File file = (File) topLevelDirectoriesWithoutExclusions.get(i);

          if (i > 0 && i == topLevelDirectoriesWithoutExclusions.size() - 1) {
            buffer.append(", and ");
          } else if (i > 0) {
            buffer.append(", ");
          }

          appendFile(file, buffer, styles, blue);
        }

        appendedDirectory = true;
        buffer.append(".");
      }

      // Now do all other directories, one sentence each.
      for (int i = 0, count = includedFiles.size(); i < count; i++) {
        File file = (File) includedFiles.get(i);

        if (file.isFile() || topLevelDirectoriesWithoutExclusions.contains(file)) {
          continue;
        }

        if (appendedDirectory == true) {
          // We are starting a new sentence, rather than joining
          // the initial sentence containing files.
          buffer.append("  Also backup ");
        }
        appendedDirectory = true;

        buffer.append("all files under ");

        appendFile(file, buffer, styles, blue);

        backupSpec.findFilesExplicitlyExcludedFrom(file, excluded);

        if (excluded.size() > 0) {
          buffer.append(" except for ");

          for (int j = 0, jcount = excluded.size(); j < jcount; j++) {
            File excludedFile = (File) excluded.get(j);

            if (j > 0 && j == excluded.size() - 1) {
              buffer.append(", and ");
            } else if (j > 0) {
              buffer.append(", ");
            }

            appendFile(excludedFile, buffer, styles, red);
          }
        }
        buffer.append(".");
      }
    }

    text.setText(buffer.toString());
    text.setStyleRanges((StyleRange[]) styles.toArray(new StyleRange[styles.size()]));
  }