docs: int[] impliedElements(int anc, int desc) {
      // <style> and <script> are allowed anywhere.
      if (desc == SCRIPT_TAG || desc == STYLE_TAG) {
        return ZERO_INTS;
      }
  
      // It's dangerous to allow free <li> tags because of the way an <li>
      // implies a </li> if there is an <li> on the parse stack without a
      // LIST_SCOPE element in the middle.
  
      // Since we don't control the context in which sanitized HTML is embedded,
      // we can't assume that there isn't a containing <li> tag before parsing
      // starts, so we make sure we never produce an <li> or <td> without a
      // corresponding LIST or TABLE scope element on the stack.
      // <select> is not a scope for <option> elements, but we do that too for
      // symmetry and as an extra degree of safety against future spec changes.
      FreeWrapper wrapper = desc != TEXT_NODE && desc < FREE_WRAPPERS.length
          ? FREE_WRAPPERS[desc] : null;
      if (wrapper != null) {
        if (anc < wrapper.allowedContainers.length
            && !wrapper.allowedContainers[anc]) {
          return wrapper.implied;
        }
      }
  
      if (desc != TEXT_NODE) {
        int[] implied = impliedElements.getElementIndexList(anc, desc);
        // This handles the table case at least
        if (implied.length != 0) { return implied; }
      }
  
      // If we require above that all <li>s appear in a <ul> or <ol> then
      // for symmetry, we require here that all content of a <ul> or <ol> appear
      // nested in a <li>.
      // This does not have the same security implications as the above, but is
      // symmetric.
      int[] oneImplied = null;
      if (anc == OL_TAG || anc == UL_TAG) {
        oneImplied = LI_TAG_ARR;
      } else if (anc == SELECT_TAG) {
        oneImplied = OPTION_TAG_ARR;
      }
      if (oneImplied != null) {
        if (desc != oneImplied[0]) {
          return LI_TAG_ARR;
        }
      }
      // TODO: why are we dropping OPTION_AG_ARR?
      return ZERO_INTS;
    }