private Path findEmbulkHome() {
        // 1) If a system config "embulk_home" is set from the command line, it is the most prioritized.
        final Optional<Path> ofCommandLine = normalizePathInCommandLineProperties("embulk_home");
        if (ofCommandLine.isPresent()) {
            logger.info("embulk_home is set from command-line: {}", ofCommandLine.get().toString());
            return ofCommandLine.get();
        }

        // 2) If an environment variable "EMBULK_HOME" is set, it is the second prioritized.
        final Optional<Path> ofEnv = normalizePathInEnv("EMBULK_HOME");
        if (ofEnv.isPresent()) {
            logger.info("embulk_home is set from environment variable: {}", ofEnv.get().toString());
            return ofEnv.get();
        }

        // (3) and (4) depend on "user.home" and "user.dir". Exception if they are unavailable.
        final Path userHome = userHomeOrEx.orRethrow();
        final Path userDir = userDirOrEx.orRethrow();

        final Path iterateUpTill;
        if (isUnderHome()) {
            // 3-1) If "user.dir" (almost equal to the working directory) is under "user.home", it iterates up till "user.home".
            iterateUpTill = userHome;
        } else {
            // 3-2) If "user.dir" is not under "user.home", it iterates up till the root directory.
            iterateUpTill = userDir.getRoot();
        }

        // 3) If neither (1) nor (2) is set, it iterates up over parent directories from "user.dir" for a directory that:
        //   * is named ".embulk",
        //   * has a readable file "embulk.properties" just under itself.
        if (iterateUpTill != null) {
            for (Path pwd = userDir; pwd != null && pwd.startsWith(iterateUpTill); pwd = pwd.getParent()) {
                // When checking the actual file/directory, symbolic links are resolved.

                final Path dotEmbulk;
                try {
                    dotEmbulk = pwd.resolve(".embulk");
                    if (Files.notExists(dotEmbulk) || (!Files.isDirectory(dotEmbulk))) {
                        continue;
                    }
                } catch (final RuntimeException ex) {
                    logger.debug("Failed to check for \".embulk\" at: " + pwd.toString(), ex);
                    continue;
                }

                try {
                    final Path properties = dotEmbulk.resolve("embulk.properties");
                    if (Files.notExists(properties) || (!Files.isRegularFile(properties)) || (!Files.isReadable(properties))) {
                        continue;
                    }
                } catch (final RuntimeException ex) {
                    logger.debug("Failed to check for \"embulk.properties\" at: " + dotEmbulk.toString(), ex);
                    continue;
                }

                logger.info("embulk_home is set by the location of embulk.properties found in: {}", dotEmbulk.toString());
                return dotEmbulk;
            }
        }

        // 4) If none of the above does not work, use the traditional predefined directory "~/.embulk".
        return userHome.resolve(".embulk");
    }
Finds an appropriate "embulk_home" directory based on a rule defined.

<ul>
<li>1) If a system config {@code "embulk_home"} is set from the command line, it is the most prioritized.
<li>2) If an environment variable {@code "EMBULK_HOME"} is set, it is the second prioritized.
<li>3) If neither (1) nor (2) is set, it iterates up over parent directories from "user.dir" for a directory that:
  <ul>
  <li>is named ".embulk",
  <li>has "embulk.properties" just under itself.
  </ul>
  <ul>
  <li>3-1) If "user.dir" (almost equal to the working directory) is under "user.home", it iterates up till "user.home".
  <li>3-2) If "user.dir" is not under "user.home", Embulk iterates until the root directory.
  </ul>
</li>
<li>4) If none of the above does not work, use the traditional predefined directory "~/.embulk".
</ul>
embulk-core/src/main/java/org/embulk/cli/EmbulkSystemPropertiesBuilder.java