private @NotNull String createRegex(@NotNull String glob, boolean acceptChildren) {
    glob = glob.trim();
    String cached = GLOBS_CACHE.get(glob);
    if (cached != null) {
      return cached;
    }

    StringBuilder sb = new StringBuilder("^");
    boolean escape = false, star = false, doubleStar = false, bracket = false;
    int beginIndex = 0;

    if (StringUtil.startsWith(glob, IgnoreFileConstants.DOUBLESTAR)) {
      sb.append("(?:[^/]*?/)*");
      beginIndex = 2;
      doubleStar = true;
    }
    else if (StringUtil.startsWith(glob, "*/")) {
      sb.append("[^/]*");
      beginIndex = 1;
      star = true;
    }
    else if (StringUtil.equals(IgnoreFileConstants.STAR, glob)) {
      sb.append(".*");
    }
    else if (StringUtil.startsWithChar(glob, '*')) {
      sb.append(".*?");
    }
    else if (StringUtil.startsWithChar(glob, '/')) {
      beginIndex = 1;
    }
    else {
      int slashes = StringUtil.countChars(glob, '/');
      if (slashes == 0 || (slashes == 1 && StringUtil.endsWithChar(glob, '/'))) {
        sb.append("(?:[^/]*?/)*");
      }
    }

    char[] chars = glob.substring(beginIndex).toCharArray();
    for (char ch : chars) {
      if (bracket && ch != ']') {
        sb.append(ch);
        continue;
      }
      else if (doubleStar) {
        doubleStar = false;
        if (ch == '/') {
          sb.append("(?:[^/]*/)*?");
          continue;
        }
        else {
          sb.append("[^/]*?");
        }
      }

      if (ch == '*') {
        if (escape) {
          sb.append("\\*");
          escape = false;
          star = false;
        }
        else if (star) {
          char prev = sb.length() > 0 ? sb.charAt(sb.length() - 1) : '\0';
          if (prev == '\0' || prev == '^' || prev == '/') {
            doubleStar = true;
          }
          else {
            sb.append("[^/]*?");
          }
          star = false;
        }
        else {
          star = true;
        }
        continue;
      }
      else if (star) {
        sb.append("[^/]*?");
        star = false;
      }

      switch (ch) {
        case '\\' -> {
          if (escape) {
            sb.append("\\\\");
            escape = false;
          }
          else {
            escape = true;
          }
        }
        case '?' -> {
          if (escape) {
            sb.append("\\?");
            escape = false;
          }
          else {
            sb.append('.');
          }
        }
        case '[' -> {
          if (escape) {
            sb.append('\\');
            escape = false;
          }
          else {
            bracket = true;
          }
          sb.append(ch);
        }
        case ']' -> {
          if (!bracket) {
            sb.append('\\');
          }
          sb.append(ch);
          bracket = false;
          escape = false;
        }
        case '.', '(', ')', '+', '|', '^', '$', '@', '%' -> {
          sb.append('\\');
          sb.append(ch);
          escape = false;
        }
        default -> {
          escape = false;
          sb.append(ch);
        }
      }
    }

    if (star || doubleStar) {
      if (StringUtil.endsWithChar(sb, '/')) {
        sb.append(acceptChildren ? ".+" : "[^/]+/?");
      }
      else {
        sb.append("[^/]*/?");
      }
    }
    else {
      if (StringUtil.endsWithChar(sb, '/')) {
        if (acceptChildren) {
          sb.append("[^/]*");
        }
      }
      else {
        sb.append(acceptChildren ? "(?:/.*)?" : "/?");
      }
    }

    sb.append('$');
    GLOBS_CACHE.put(glob, sb.toString());

    return sb.toString();
  }
private @NotNull String createRegex(@NotNull String glob, boolean acceptChildren)