// static
VFSNode VFSNode::_platform_getKnownDirectoryNode(KnownDirectoryIdentifier id, const VString& companyName, const VString& appName) {
    if (id == CURRENT_WORKING_DIRECTORY) {
        return VFSNode(VPlatformAPI::getcwd());
    }

    if (id == EXECUTABLE_DIRECTORY) {
        /*
        This depends on the structure of the application or tool.
        If it's an iOS application, it's a bundle where we have:
            /...../wanted-dir/AppName.app/executable
            (2 levels up, wanted-dir is a randomized serial number at some path)
        If it's built as a Mac OS X application bundle we have:
            /...../wanted-dir/AppName.app/Contents/MacOS/executable
            (4 levels up, typically wanted-dir is /Applications if installed, but doesn't have to be)
        If it's built as a simple Unix-y tool we have:
            /...../wanted-dir/executable
            (1 level up, wanted-dir is wherever the tool has been placed)
        */
#ifdef VPLATFORM_MAC_IOS
        const int NUM_LEVELS_UP = 2;
#else
#ifdef VAULT_MACOSX_APP_IS_BUNDLE
        const int NUM_LEVELS_UP = 4;
#else
        const int NUM_LEVELS_UP = 1;
#endif
#endif
        VFSNode node = VFSNode::getExecutable();
        for (int i = 0; i < NUM_LEVELS_UP; ++i) {
            VFSNode parentNode;
            node.getParentNode(parentNode);
            node = parentNode;
        }

        return node;
    }

    VFSNode currentUserFolder(_V_NSHomeDirectory());

    if (id == USER_HOME_DIRECTORY) {
        return currentUserFolder;
    }

    VFSNode libraryFolder;
    currentUserFolder.getChildNode("Library", libraryFolder);
    libraryFolder.mkdir();

    VFSNode subFolder;

    switch (id) {
        case USER_HOME_DIRECTORY:
            // handled earlier; we returned above
            break;

        case LOG_FILES_DIRECTORY:
            libraryFolder.getChildNode("Logs", subFolder);
            break;

        case USER_PREFERENCES_DIRECTORY:
            libraryFolder.getChildNode("Preferences", subFolder);
            break;

        case CACHED_DATA_DIRECTORY:
            libraryFolder.getChildNode("Caches", subFolder);
            break;

        case APPLICATION_DATA_DIRECTORY:
            subFolder = libraryFolder;
            break;

        case CURRENT_WORKING_DIRECTORY:
            // handled earlier; we returned above
            break;

        case EXECUTABLE_DIRECTORY:
            // handled earlier; we returned above
            break;

        default:
            throw VStackTraceException(VSTRING_FORMAT("VFSNode::_platform_getKnownDirectoryNode: Requested invalid directory ID %d.", (int) id));
            break;
    }

    subFolder.mkdir();

    VFSNode companyFolder;
    if (companyName.isEmpty()) {
        companyFolder = subFolder;
    } else {
        subFolder.getChildNode(companyName, companyFolder);
        companyFolder.mkdir();
    }

    VFSNode resultNode;
    if (appName.isEmpty()) {
        resultNode = companyFolder;
    } else {
        companyFolder.getChildNode(appName, resultNode);
        resultNode.mkdir();
    }

    return resultNode;
}
// static
VFSNode VFSNode::_platform_getKnownDirectoryNode(KnownDirectoryIdentifier id, const VString& companyName, const VString& appName) {
    if (id == CURRENT_WORKING_DIRECTORY) {
        return VFSNode(VSystemAPI::getcwd());
    }

    if (id == EXECUTABLE_DIRECTORY) {
        VFSNode executable = VFSNode::getExecutable();
        VFSNode executableDirectory;
        executable.getParentNode(executableDirectory);
        return executableDirectory;
    }

    struct passwd* pwInfo = ::getpwuid(::getuid()); // Get info about the current user.
    if (pwInfo == NULL) {
        throw VStackTraceException(
            // Oddity: errno 0 can occur and means "no such user".
            (errno == 0 ? VSystemError(0, "No such user") : VSystemError()),
            "VFSNode::_platform_getKnownDirectoryNode failed to get current user info from getpwuid()."
        );
    }

    const VString homePath(pwInfo->pw_dir);

    if (id == USER_HOME_DIRECTORY) {
        return VFSNode(homePath);
    }

    VString basePath;
    VString companyFolderName(companyName);

    switch (id) {
        case USER_HOME_DIRECTORY:
            // handled earlier; we returned above
            break;

        case LOG_FILES_DIRECTORY:
            basePath = homePath + "/log";
            break;

        case USER_PREFERENCES_DIRECTORY:
            basePath = homePath;
            if (companyName.isNotEmpty()) {
                companyFolderName.format(".%s", companyName.chars());
            }
            break;

        case CACHED_DATA_DIRECTORY:
            basePath = homePath + "/cache";
            break;

        case APPLICATION_DATA_DIRECTORY:
            basePath = homePath + "/data";
            break;

        case CURRENT_WORKING_DIRECTORY:
            // handled earlier; we returned above
            break;

        case EXECUTABLE_DIRECTORY:
            // handled earlier; we returned above
            break;

        default:
            throw VStackTraceException(VSTRING_FORMAT("VFSNode::_platform_getKnownDirectoryNode: Requested invalid directory ID %d.", (int) id));
            break;
    }

    VFSNode baseDir(basePath);
    baseDir.mkdir();

    VFSNode companyFolder;
    if (companyFolderName.isEmpty()) {
        companyFolder = baseDir;
    } else {
        baseDir.getChildNode(companyFolderName, companyFolder);
        companyFolder.mkdir();
    }

    VFSNode resultNode;
    if (appName.isEmpty()) {
        resultNode = companyFolder;
    } else {
        companyFolder.getChildNode(appName, resultNode);
        resultNode.mkdir();
    }

    return resultNode;
}