docs: public Bits encodePPM(String text, int context) {
      final String original = text;
      //if(verbose) System.p.println(String.format("Encoding %s run %s chars of context", text, context));
      if (!text.endsWith("\u0000")) text += END_OF_STRING;
      ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      BitOutputStream out = new BitOutputStream(buffer);
      String contextStr = "";
      try {
        while (!text.isEmpty()) {
          String right = getRight(contextStr, context);
          TrieNode fromNode = inner.matchPredictor(right); // inner.matchEnd(right).getString()
          String prefix = fromNode.getString();
          // fromNode.getChildrenMap()
          TrieNode toNode = fromNode.traverse(text);
          int segmentChars = toNode.getDepth() - fromNode.getDepth();
          if (toNode.hasChildren()) {
            if (prefix.isEmpty() && 0 == segmentChars) {
              Optional<? extends TrieNode> child = toNode.getChild(ESCAPE);
              assert child.isPresent();
              toNode = child.get();
            }
            else {
              toNode = toNode.getChild(FALLBACK).get();
            }
          }
          
          Interval interval = fromNode.intervalTo(toNode);
          Bits segmentData = interval.toBits();
          if (verbose) {
            System.out.println(String.format(
              "Using context \"%s\", encoded \"%s\" (%s chars) as %s -> %s",
              fromNode.getDebugString(), toNode.getDebugString(fromNode), segmentChars, interval, segmentData));
          }
          out.write(segmentData);
          
          if (0 == segmentChars) {
            if (prefix.isEmpty()) {
              //throw new RuntimeException(String.format("Cannot encode %s in model", text.substring(0,1)));
              char exotic = text.charAt(0);
              out.write(exotic);
              if (verbose) {
                System.out.println(String.format(
                  "Writing exotic character %s -> %s", exotic, new Bits(exotic, 16)));
              }
              text = text.substring(1);
            }
            else if (toNode.getChar() == FALLBACK) {
              contextStr = prefix.substring(1);
            }
            else {
              throw new RuntimeException("Cannot encode " + text.substring(0, 1));
            }
          }
          else {
            contextStr += text.substring(0, segmentChars);
            text = text.substring(segmentChars);
          }
        }
        out.flush();
        Bits bits = new Bits(buffer.toByteArray(), out.getTotalBitsWritten());
        //if(verbose) System.p.println(String.format("Encoded %s to %s", original, bits));
        return bits;
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }