function goInto(element, after, char) {
              switch (element.type) {
                case "Assertion": {
                  if (element.kind === "lookahead" || element.kind === "lookbehind") {
                    for (const alt of element.alternatives) {
                      if (alt.elements.length > 0) {
                        tryReachUntil(alt.elements[0], char, after);
                      }
                    }
                  }
                  return EMPTY;
                }
                case "Group":
                case "CapturingGroup": {
                  let total = EMPTY;
                  for (const alt of element.alternatives) {
                    if (alt.elements.length > 0) {
                      total = total.union(tryReachUntil(alt.elements[0], char, after));
                    } else {
                      total = char;
                    }
                  }
                  return total;
                }
                case "Character":
                case "CharacterClass":
                case "CharacterSet": {
                  return char.intersect(toCharSet(element));
                }
                case "Quantifier": {
                  if (element.min === 0) {
                    goInto(element.element, after, char);
                    return char;
                  } else {
                    return goInto(element.element, after, char);
                  }
                }
                default:
                  return EMPTY;
              }
            }
@param {Element} element
@param {Element} after
@param {CharSet} char
@returns {CharSet}