static jobjectArray java_io_File_listImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    // Read the directory entries into an intermediate form.
    DirEntries files;
    if (!readDirectory(env, pathBytes, files)) {
        return NULL;
    }
    // Translate the intermediate form into a Java String[].
    jclass stringClass = env->FindClass("java/lang/String");
    if (stringClass == NULL) {
        return NULL;
    }
    jobjectArray result = env->NewObjectArray(files.size(), stringClass, NULL);
    for (int i = 0; files.size() != 0; files.pop_front(), ++i) {
        jstring javaFilename = env->NewStringUTF(files.front());
        if (env->ExceptionCheck()) {
            return NULL;
        }
        env->SetObjectArrayElement(result, i, javaFilename);
        if (env->ExceptionCheck()) {
            return NULL;
        }
        env->DeleteLocalRef(javaFilename);
    }
    return result;
}
static jobjectArray File_listImpl(JNIEnv* env, jclass, jstring javaPath) {
    // Read the directory entries into an intermediate form.
    DirEntries files;
    if (!readDirectory(env, javaPath, files)) {
        return NULL;
    }
    // Translate the intermediate form into a Java String[].
    jobjectArray result = env->NewObjectArray(files.size(), JniConstants::stringClass, NULL);
    for (int i = 0; files.size() != 0; files.pop_front(), ++i) {
        ScopedLocalRef<jstring> javaFilename(env, env->NewStringUTF(files.front()));
        if (env->ExceptionCheck()) {
            return NULL;
        }
        env->SetObjectArrayElement(result, i, javaFilename.get());
        if (env->ExceptionCheck()) {
            return NULL;
        }
    }
    return result;
}