TokenSet (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; }