/**
   * Test method for traverseFileSystem
   *
   * @throws Exception
   */
  @Test
  public void testTraverseFileSystem() throws Exception {

    /*
     * Create an object of type FileSystemTraverseCallback that'll be called for each
     * file system path that's reported. Calling getNames() returns an array of Strings
     * containing the file names.
     */
    TestCallback callbackCollector = new TestCallback();

    /* Test a non-existent directory */
    SystemUtils.traverseFileSystem(
        "/non-existent",
        SystemUtils.REPORT_DIRECTORIES | SystemUtils.REPORT_FILES,
        callbackCollector);
    String names[] = callbackCollector.getNames();
    assertEquals(0, names.length);

    /* report all directories in our test hierarchy */
    SystemUtils.traverseFileSystem(
        ourTempDir.toString(), SystemUtils.REPORT_DIRECTORIES, callbackCollector);
    names = callbackCollector.getNames();
    assertEquals(5, names.length);
    assertSortedPathArraysEqual(
        ourTempDir.toString(),
        names,
        new String[] {"", "/dirA", "/dirA/nested", "/dirA/nested/dirB", "/dirC"});

    /* report all files in our test hierarchy */
    SystemUtils.traverseFileSystem(
        ourTempDir.toString(), SystemUtils.REPORT_FILES, callbackCollector);
    names = callbackCollector.getNames();
    assertSortedPathArraysEqual(
        ourTempDir.toString(),
        names,
        new String[] {
          "/dirA/fileInDirA",
          "/dirA/nested/dirB/aThirdFileInDirB",
          "/dirA/nested/dirB/anotherFileInDirB",
          "/dirA/nested/dirB/fileInDirB",
          "/dirA/nested/dirB/onelastFileInDirB",
          "/topLevelFile"
        });

    /* report all files and directories in our test hierarchy */
    SystemUtils.traverseFileSystem(
        ourTempDir.toString(),
        SystemUtils.REPORT_FILES | SystemUtils.REPORT_DIRECTORIES,
        callbackCollector);
    names = callbackCollector.getNames();
    assertSortedPathArraysEqual(
        ourTempDir.toString(),
        names,
        new String[] {
          "",
          "/dirA",
          "/dirA/fileInDirA",
          "/dirA/nested",
          "/dirA/nested/dirB",
          "/dirA/nested/dirB/aThirdFileInDirB",
          "/dirA/nested/dirB/anotherFileInDirB",
          "/dirA/nested/dirB/fileInDirB",
          "/dirA/nested/dirB/onelastFileInDirB",
          "/dirC",
          "/topLevelFile"
        });

    /* filter out the "nested" directory */
    SystemUtils.traverseFileSystem(
        ourTempDir.toString(),
        null,
        "nested",
        SystemUtils.REPORT_FILES | SystemUtils.REPORT_DIRECTORIES,
        callbackCollector);
    names = callbackCollector.getNames();
    assertSortedPathArraysEqual(
        ourTempDir.toString(),
        names,
        new String[] {"", "/dirA", "/dirA/fileInDirA", "/dirC", "/topLevelFile"});

    /* filter out the "nested" and "dirC" directories */
    SystemUtils.traverseFileSystem(
        ourTempDir.toString(),
        null,
        "nested|dirC",
        SystemUtils.REPORT_FILES | SystemUtils.REPORT_DIRECTORIES,
        callbackCollector);
    names = callbackCollector.getNames();
    assertSortedPathArraysEqual(
        ourTempDir.toString(),
        names,
        new String[] {"", "/dirA", "/dirA/fileInDirA", "/topLevelFile"});

    /* only return the files that have "In" in their name */
    SystemUtils.traverseFileSystem(
        ourTempDir.toString(), ".*In.*", null, SystemUtils.REPORT_FILES, callbackCollector);
    names = callbackCollector.getNames();
    assertSortedPathArraysEqual(
        ourTempDir.toString(),
        names,
        new String[] {
          "/dirA/fileInDirA",
          "/dirA/nested/dirB/aThirdFileInDirB",
          "/dirA/nested/dirB/anotherFileInDirB",
          "/dirA/nested/dirB/fileInDirB",
          "/dirA/nested/dirB/onelastFileInDirB"
        });
  }