@Override
  protected List<MatchResult> match(List<String> specs) {
    ImmutableList.Builder<MatchResult> resultsBuilder = ImmutableList.builder();
    for (String spec : specs) {
      try {
        final Set<Metadata> metadata = new HashSet<>();
        if (spec.contains("**")) {
          // recursive glob
          int index = spec.indexOf("**");
          metadata.addAll(
              matchRecursiveGlob(spec.substring(0, index + 1), spec.substring(index + 1)));
        } else {
          // normal glob
          final Path path = new Path(spec);
          final FileStatus[] fileStatuses = path.getFileSystem(configuration).globStatus(path);
          if (fileStatuses != null) {
            for (FileStatus fileStatus : fileStatuses) {
              metadata.add(toMetadata(fileStatus));
            }
          }
        }
        if (metadata.isEmpty()) {
          resultsBuilder.add(MatchResult.create(Status.NOT_FOUND, Collections.emptyList()));
        } else {
          resultsBuilder.add(MatchResult.create(Status.OK, new ArrayList<>(metadata)));
        }
      } catch (IOException e) {
        resultsBuilder.add(MatchResult.create(Status.ERROR, e));
      }
    }
    return resultsBuilder.build();
  }
@Test
  public void testMatch() throws Exception {
    create("testFileAA", "testDataAA".getBytes(StandardCharsets.UTF_8));
    create("testFileA", "testDataA".getBytes(StandardCharsets.UTF_8));
    create("testFileB", "testDataB".getBytes(StandardCharsets.UTF_8));

    // ensure files exist
    assertArrayEquals("testDataAA".getBytes(StandardCharsets.UTF_8), read("testFileAA", 0));
    assertArrayEquals("testDataA".getBytes(StandardCharsets.UTF_8), read("testFileA", 0));
    assertArrayEquals("testDataB".getBytes(StandardCharsets.UTF_8), read("testFileB", 0));

    List<MatchResult> results =
        fileSystem.match(ImmutableList.of(testPath("testFileA*").toString()));
    assertEquals(Status.OK, Iterables.getOnlyElement(results).status());
    assertThat(
        Iterables.getOnlyElement(results).metadata(),
        containsInAnyOrder(
            Metadata.builder()
                .setResourceId(testPath("testFileAA"))
                .setIsReadSeekEfficient(true)
                .setSizeBytes("testDataAA".getBytes(StandardCharsets.UTF_8).length)
                .setLastModifiedMillis(lastModified("testFileAA"))
                .build(),
            Metadata.builder()
                .setResourceId(testPath("testFileA"))
                .setIsReadSeekEfficient(true)
                .setSizeBytes("testDataA".getBytes(StandardCharsets.UTF_8).length)
                .setLastModifiedMillis(lastModified("testFileA"))
                .build()));
  }