docs: public void generate() {
          if (!this.upToDate) {
  
  // Phase One: Sort the symbols by weight into a linked list.
  
              Symbol head = this.symbols[0];
              Symbol next;
              Symbol previous = head;
              Symbol symbol;
  
              this.table = null;
              head.next = null;
              for (int i = 1; i < this.domain; i += 1) {
                  symbol = symbols[i];
  
  // If this symbol weights less than the head, then it becomes the new head.
  
                  if (symbol.weight < head.weight) {
                      symbol.next = head;
                      head = symbol;
                  } else {
  
  // We will start the search from the previous symbol instead of the head unless
  // the current symbol weights less than the previous symbol.
  
                      if (symbol.weight < previous.weight) {
                          previous = head;
                      }
  
  // Find a connected pair (previous and next) where the symbol weighs the same
  // or more than previous but less than the next. Link the symbol between them.
  
                      while (true) {
                          next = previous.next;
                          if (next == null || symbol.weight < next.weight) {
                              break;
                          }
                          previous = next;
                      }
                      symbol.next = next;
                      previous.next = symbol;
                      previous = symbol;
                  }
              }
  
  // Phase Two: Make new symbols from the two lightest symbols until only one
  // symbol remains. The final symbol becomes the root of the table binary tree.
  
              int avail = this.domain;
              Symbol first;
              Symbol second;
              previous = head;
              while (true) {
                  first = head;
                  second = first.next;
                  head = second.next;
                  symbol = this.symbols[avail];
                  avail += 1;
                  symbol.weight = first.weight + second.weight;
                  symbol.zero = first;
                  symbol.one = second;
                  symbol.back = null;
                  first.back = symbol;
                  second.back = symbol;
                  if (head == null) {
                      break;
                  }
  
  // Insert the new symbol back into the sorted list.
  
                  if (symbol.weight < head.weight) {
                      symbol.next = head;
                      head = symbol;
                      previous = head;
                  } else {
                      while (true) {
                          next = previous.next;
                          if (next == null || symbol.weight < next.weight) {
                              break;
                          }
                          previous = next;
                      }
                      symbol.next = next;
                      previous.next = symbol;
                      previous = symbol;
                  }
  
              }
  
  // The last remaining symbol is the root of the table.
  
              this.table = symbol;
              this.upToDate = true;
          }
      }