/**
  * Allows to construct element types for some temporary purposes without registering them. This is
  * not default behavior and not recommended. A lot of other functionality (e.g. {@link TokenSet})
  * won't work with such element types. Please use {@link #IElementType(String, Language)} unless
  * you know what you're doing.
  */
 protected IElementType(
     @NotNull @NonNls String debugName, @Nullable Language language, boolean register) {
   myDebugName = debugName;
   myLanguage = language == null ? Language.ANY : language;
   if (register) {
     synchronized (lock) {
       myIndex = size++;
       LOG.assertTrue(
           myIndex < MAX_INDEXED_TYPES,
           "Too many element types registered. Out of (short) range.");
       IElementType[] newRegistry =
           myIndex >= ourRegistry.length
               ? ArrayUtil.realloc(ourRegistry, ourRegistry.length * 3 / 2 + 1, FACTORY)
               : ourRegistry;
       newRegistry[myIndex] = this;
       ourRegistry = newRegistry;
     }
   } else {
     myIndex = -1;
   }
 }
 // entries must be sorted BY_OWNER_MODULE
 @NotNull
 private OrderEntry[] mergeWith(@NotNull OrderEntry[] entries) {
   OrderEntry[] orderEntries = this.orderEntries;
   OrderEntry[] result = new OrderEntry[orderEntries.length + entries.length];
   int i = 0;
   int j = 0;
   // remove equals entries in the process
   int o = 0;
   while (i != orderEntries.length || j != entries.length) {
     OrderEntry m =
         i != orderEntries.length
                 && (j == entries.length
                     || BY_OWNER_MODULE.compare(orderEntries[i], entries[j]) < 0)
             ? orderEntries[i++]
             : entries[j++];
     if (o == 0 || !m.equals(result[o - 1])) {
       result[o++] = m;
     }
   }
   if (o != result.length) {
     result = ArrayUtil.realloc(result, o, ORDER_ENTRY_ARRAY_FACTORY);
   }
   return result;
 }