public static @NotNull TokenSet orSet(TokenSet @NotNull ... sets) {
    if (sets.length == 0) return EMPTY;

    List<IElementType.Predicate> orConditions = new ArrayList<>();
    ContainerUtil.addIfNotNull(orConditions, sets[0].myOrCondition);

    short shift = sets[0].myShift;
    short max = sets[0].myMax;
    for (int i = 1; i < sets.length; i++) {
      if (shift > sets[i].myShift) shift = sets[i].myShift;
      if (max < sets[i].myMax) max = sets[i].myMax;
      ContainerUtil.addIfNotNull(orConditions, sets[i].myOrCondition);
    }

    IElementType.Predicate disjunction =
      orConditions.isEmpty() ? null :
      orConditions.size() == 1 ? orConditions.get(0) :
      new OrPredicate(orConditions);
    TokenSet newSet = new TokenSet(shift, max, disjunction);
    for (TokenSet set : sets) {
      final int shiftDiff = set.myShift - newSet.myShift;
      for (int i = 0; i < set.myWords.length; i++) {
        newSet.myWords[i + shiftDiff] |= set.myWords[i];
      }
    }
    return newSet;
  }
public static @NotNull TokenSet orSet(TokenSet @NotNull ... sets)