docs: public String decodePPM(byte[] data, int context) {
      try {
        BitInputStream in = new BitInputStream(new ByteArrayInputStream(data));
        StringBuilder out = new StringBuilder();
        String contextStr = "";
        while (true) {
          TrieNode fromNode = inner.matchPredictor(getRight(contextStr, context));
          if (0 == fromNode.getNumberOfChildren()) return "";
          long seek = in.peekLongCoord(fromNode.getCursorCount());
          TrieNode toNode = fromNode.traverse(seek + fromNode.getCursorIndex());
          String newSegment = toNode.getString(fromNode);
          Interval interval = fromNode.intervalTo(toNode);
          Bits bits = interval.toBits();
          if (verbose) {
            System.out.println(String.format(
              "Using prefix \"%s\", seek to %s pos, path \"%s\" run %s -> %s, input buffer = %s",
              fromNode.getDebugString(), seek, toNode.getDebugString(fromNode), interval, bits, in.peek(24)));
          }
          in.expect(bits);
          if (toNode.isStringTerminal()) {
            if (verbose) System.out.println("Inserting null char to terminate string");
            newSegment += END_OF_STRING;
          }
          if (!newSegment.isEmpty()) {
            if (newSegment.endsWith("\u0000")) {
              out.append(newSegment.substring(0, newSegment.length() - 1));
              if (verbose) System.out.println(String.format("Null char reached"));
              break;
            }
            else {
              contextStr += newSegment;
              out.append(newSegment);
            }
          }
          else if (in.availible() == 0) {
            if (verbose) System.out.println(String.format("No More Data"));
            break;
          }
          else if (toNode.getChar() == END_OF_STRING) {
            if (verbose) System.out.println(String.format("End code"));
            break;
            //throw new RuntimeException("Cannot decode text");
          }
          else if (toNode.getChar() == FALLBACK) {
            contextStr = fromNode.getString().substring(1);
          }
          else if (toNode.getChar() == ESCAPE) {
            Bits charBits = in.read(16);
            char exotic = (char) charBits.toLong();
            out.append(new String(new char[]{exotic}));
            if (verbose) {
              System.out.println(String.format(
                "Read exotic byte %s -> %s, input buffer = %s", exotic, charBits, in.peek(24)));
            }
          }
          else {
            if (verbose) System.out.println(String.format("Cannot decode text"));
            break;
            //throw new RuntimeException("Cannot decode text");
          }
        }
        return out.toString();
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }