@Override
  public ResourceId resolve(String other, ResolveOptions resolveOptions) {
    checkState(isDirectory(), "Expected this resource to be a directory, but was [%s]", toString());

    if (resolveOptions == ResolveOptions.StandardResolveOptions.RESOLVE_DIRECTORY) {
      if ("..".equals(other)) {
        if ("/".equals(key)) {
          return this;
        }
        int parentStopsAt = key.substring(0, key.length() - 1).lastIndexOf('/');
        return fromComponents(scheme, bucket, key.substring(0, parentStopsAt + 1));
      }

      if ("".equals(other)) {
        return this;
      }

      if (!other.endsWith("/")) {
        other += "/";
      }
      if (S3_URI.matcher(other).matches()) {
        return resolveFromUri(other);
      }
      return fromComponents(scheme, bucket, key + other);
    }

    if (resolveOptions == ResolveOptions.StandardResolveOptions.RESOLVE_FILE) {
      checkArgument(
          !other.endsWith("/"), "Cannot resolve a file with a directory path: [%s]", other);
      checkArgument(!"..".equals(other), "Cannot resolve parent as file: [%s]", other);
      if (S3_URI.matcher(other).matches()) {
        return resolveFromUri(other);
      }
      return fromComponents(scheme, bucket, key + other);
    }

    throw new UnsupportedOperationException(
        String.format("Unexpected StandardResolveOptions [%s]", resolveOptions));
  }
@Test
  public void testResolve() {
    for (TestCase testCase : PATH_TEST_CASES) {
      ResourceId resourceId = S3ResourceId.fromUri(testCase.baseUri);
      ResourceId resolved = resourceId.resolve(testCase.relativePath, testCase.resolveOptions);
      assertEquals(testCase.expectedResult, resolved.toString());
    }

    // Tests for common s3 paths.
    assertEquals(
        S3ResourceId.fromUri("s3://bucket/tmp/aa"),
        S3ResourceId.fromUri("s3://bucket/tmp/").resolve("aa", RESOLVE_FILE));
    assertEquals(
        S3ResourceId.fromUri("s3://bucket/tmp/aa/bb/cc/"),
        S3ResourceId.fromUri("s3://bucket/tmp/")
            .resolve("aa", RESOLVE_DIRECTORY)
            .resolve("bb", RESOLVE_DIRECTORY)
            .resolve("cc", RESOLVE_DIRECTORY));

    // Tests absolute path.
    assertEquals(
        S3ResourceId.fromUri("s3://bucket/tmp/aa"),
        S3ResourceId.fromUri("s3://bucket/tmp/bb/").resolve("s3://bucket/tmp/aa", RESOLVE_FILE));

    // Tests bucket with no ending '/'.
    assertEquals(
        S3ResourceId.fromUri("s3://my-bucket/tmp"),
        S3ResourceId.fromUri("s3://my-bucket").resolve("tmp", RESOLVE_FILE));

    // Tests path with unicode
    assertEquals(
        S3ResourceId.fromUri("s3://bucket/输出 目录/输出 文件01.txt"),
        S3ResourceId.fromUri("s3://bucket/输出 目录/").resolve("输出 文件01.txt", RESOLVE_FILE));
  }