public static List<TextMateSelectorToken> tokenize(@NotNull CharSequence selector) {
    ArrayList<TextMateSelectorToken> result = new ArrayList<>();
    StringBuilder currentSelector = new StringBuilder();
    for (int i = 0; i < selector.length(); i++) {
      char c = selector.charAt(i);
      if (c == '(') {
        currentSelector = addPendingToken(result, currentSelector);
        result.add(TextMateSelectorToken.LPAREN);
      }
      else if (c == ')') {
        currentSelector = addPendingToken(result, currentSelector);
        result.add(TextMateSelectorToken.RPAREN);
      }
      else if (c == ',') {
        currentSelector = addPendingToken(result, currentSelector);
        result.add(TextMateSelectorToken.COMMA);
      }
      else if (c == '|') {
        currentSelector = addPendingToken(result, currentSelector);
        result.add(TextMateSelectorToken.PIPE);
      }
      else if (c == '^') {
        currentSelector = addPendingToken(result, currentSelector);
        result.add(TextMateSelectorToken.HAT);
      }
      else if (c == '-' && currentSelector.isEmpty()) {
        currentSelector = addPendingToken(result, currentSelector);
        result.add(TextMateSelectorToken.MINUS);
      }
      else if (c == ' ') {
        currentSelector = addPendingToken(result, currentSelector);
      }
      else if ((c == 'R' || c == 'L' || c == 'B') && i + 1 < selector.length() && selector.charAt(i+1) == ':') {
        currentSelector = addPendingToken(result, currentSelector);
        //noinspection AssignmentToForLoopParameter
        i++;
        if (c == 'R') {
          result.add(new PriorityToken(TextMateWeigh.Priority.LOW));
        }
        else if (c == 'L') {
          result.add(new PriorityToken(TextMateWeigh.Priority.HIGH));
        }
      }
      else {
        currentSelector.append(c);
      }
    }
    addPendingToken(result, currentSelector);
    return result;
  }
public static List<TextMateSelectorToken> tokenize(@NotNull CharSequence selector)