@Contract("true -> !null")
  public static String getHomePath(boolean insideIde) {
    String result = ourHomePath;
    if (result != null) return result;

    //noinspection SynchronizeOnThis
    synchronized (PathManager.class) {
      result = ourHomePath;
      if (result != null) return result;

      String explicit = getExplicitPath(PROPERTY_HOME_PATH);
      if (explicit == null) explicit = getExplicitPath(PROPERTY_HOME);
      if (explicit != null) {
        result = explicit;
        if (!Files.isDirectory(Paths.get(result))) {
          ourHomePath = result;
          throw new RuntimeException("Invalid home path '" + result + "'");
        }
      }
      else if (insideIde) {
        result = getHomePathFor(PathManager.class);
        if (result == null) {
          String advice = SystemInfoRt.isMac ? "reinstall the software." : "make sure bin/idea.properties is present in the installation directory.";
          throw new RuntimeException("Could not find installation home path. Please " + advice);
        }
      }

      if (result != null && SystemInfoRt.isWindows) {
        try {
          result = Paths.get(result).toRealPath(LinkOption.NOFOLLOW_LINKS).toString();
        }
        catch (IOException ignored) { }
      }

      // set before ourHomePath because getBinDirectories() rely on the fact that if `getHomePath(true)`
      // returns something, then `ourBinDirectories` is already computed
      if (result == null) {
        ourBinDirectories = Collections.emptyList();
      }
      else {
        Path root = Paths.get(result);
        if (Boolean.getBoolean("idea.use.dev.build.server")) {
          root = root.resolve("../../../..").normalize();
        }
        ourBinDirectories = getBinDirectories(root);
      }

      ourHomePath = result;
    }

    return result;
  }
@Contract("true -> !null")
  public static String getHomePath(boolean insideIde)