Perl_re_intuit_start(pTHX_
                    REGEXP * const rx,
                    SV *sv,
                    const char * const strbeg,
                    char *strpos,
                    char *strend,
                    const U32 flags,
                    re_scream_pos_data *data)
{
    struct regexp *const prog = ReANY(rx);
    SSize_t start_shift = prog->check_offset_min;
    /* Should be nonnegative! */
    SSize_t end_shift   = 0;
    /* current lowest pos in string where the regex can start matching */
    char *rx_origin = strpos;
    SV *check;
    const bool utf8_target = (sv && SvUTF8(sv)) ? 1 : 0; /* if no sv we have to assume bytes */
    U8   other_ix = 1 - prog->substrs->check_ix;
    bool ml_anch = 0;
    char *other_last = strpos;/* latest pos 'other' substr already checked to */
    char *check_at = NULL;		/* check substr found at this pos */
    const I32 multiline = prog->extflags & RXf_PMf_MULTILINE;
    RXi_GET_DECL(prog,progi);
    regmatch_info reginfo_buf;  /* create some info to pass to find_byclass */
    regmatch_info *const reginfo = &reginfo_buf;
    GET_RE_DEBUG_FLAGS_DECL;

    PERL_ARGS_ASSERT_RE_INTUIT_START;
    PERL_UNUSED_ARG(flags);
    PERL_UNUSED_ARG(data);

    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                "Intuit: trying to determine minimum start position...\n"));

    /* for now, assume that all substr offsets are positive. If at some point
     * in the future someone wants to do clever things with look-behind and
     * -ve offsets, they'll need to fix up any code in this function
     * which uses these offsets. See the thread beginning
     * <20140113145929.GF27210@iabyn.com>
     */
    assert(prog->substrs->data[0].min_offset >= 0);
    assert(prog->substrs->data[0].max_offset >= 0);
    assert(prog->substrs->data[1].min_offset >= 0);
    assert(prog->substrs->data[1].max_offset >= 0);
    assert(prog->substrs->data[2].min_offset >= 0);
    assert(prog->substrs->data[2].max_offset >= 0);

    /* for now, assume that if both present, that the floating substring
     * doesn't start before the anchored substring.
     * If you break this assumption (e.g. doing better optimisations
     * with lookahead/behind), then you'll need to audit the code in this
     * function carefully first
     */
    assert(
            ! (  (prog->anchored_utf8 || prog->anchored_substr)
              && (prog->float_utf8    || prog->float_substr))
           || (prog->float_min_offset >= prog->anchored_offset));

    /* byte rather than char calculation for efficiency. It fails
     * to quickly reject some cases that can't match, but will reject
     * them later after doing full char arithmetic */
    if (prog->minlen > strend - strpos) {
	DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
			      "  String too short...\n"));
	goto fail;
    }

    RX_MATCH_UTF8_set(rx,utf8_target);
    reginfo->is_utf8_target = cBOOL(utf8_target);
    reginfo->info_aux = NULL;
    reginfo->strbeg = strbeg;
    reginfo->strend = strend;
    reginfo->is_utf8_pat = cBOOL(RX_UTF8(rx));
    reginfo->intuit = 1;
    /* not actually used within intuit, but zero for safety anyway */
    reginfo->poscache_maxiter = 0;

    if (utf8_target) {
	if (!prog->check_utf8 && prog->check_substr)
	    to_utf8_substr(prog);
	check = prog->check_utf8;
    } else {
	if (!prog->check_substr && prog->check_utf8) {
	    if (! to_byte_substr(prog)) {
                NON_UTF8_TARGET_BUT_UTF8_REQUIRED(fail);
            }
        }
	check = prog->check_substr;
    }

    /* dump the various substring data */
    DEBUG_OPTIMISE_MORE_r({
        int i;
        for (i=0; i<=2; i++) {
            SV *sv = (utf8_target ? prog->substrs->data[i].utf8_substr
                                  : prog->substrs->data[i].substr);
            if (!sv)
                continue;

            PerlIO_printf(Perl_debug_log,
                "  substrs[%d]: min=%"IVdf" max=%"IVdf" end shift=%"IVdf
                " useful=%"IVdf" utf8=%d [%s]\n",
                i,
                (IV)prog->substrs->data[i].min_offset,
                (IV)prog->substrs->data[i].max_offset,
                (IV)prog->substrs->data[i].end_shift,
                BmUSEFUL(sv),
                utf8_target ? 1 : 0,
                SvPEEK(sv));
        }
    });

    if (prog->intflags & PREGf_ANCH) { /* Match at \G, beg-of-str or after \n */

        /* ml_anch: check after \n?
         *
         * A note about PREGf_IMPLICIT: on an un-anchored pattern beginning
         * with /.*.../, these flags will have been added by the
         * compiler:
         *   /.*abc/, /.*abc/m:  PREGf_IMPLICIT | PREGf_ANCH_MBOL
         *   /.*abc/s:           PREGf_IMPLICIT | PREGf_ANCH_SBOL
         */
	ml_anch =      (prog->intflags & PREGf_ANCH_MBOL)
                   && !(prog->intflags & PREGf_IMPLICIT);

	if (!ml_anch && !(prog->intflags & PREGf_IMPLICIT)) {
            /* we are only allowed to match at BOS or \G */

            /* trivially reject if there's a BOS anchor and we're not at BOS.
             *
             * Note that we don't try to do a similar quick reject for
             * \G, since generally the caller will have calculated strpos
             * based on pos() and gofs, so the string is already correctly
             * anchored by definition; and handling the exceptions would
             * be too fiddly (e.g. REXEC_IGNOREPOS).
             */
            if (   strpos != strbeg
                && (prog->intflags & PREGf_ANCH_SBOL))
            {
	        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                                "  Not at start...\n"));
	        goto fail;
	    }

            /* in the presence of an anchor, the anchored (relative to the
             * start of the regex) substr must also be anchored relative
             * to strpos. So quickly reject if substr isn't found there.
             * This works for \G too, because the caller will already have
             * subtracted gofs from pos, and gofs is the offset from the
             * \G to the start of the regex. For example, in /.abc\Gdef/,
             * where substr="abcdef", pos()=3, gofs=4, offset_min=1:
             * caller will have set strpos=pos()-4; we look for the substr
             * at position pos()-4+1, which lines up with the "a" */

	    if (prog->check_offset_min == prog->check_offset_max) {
	        /* Substring at constant offset from beg-of-str... */
	        SSize_t slen = SvCUR(check);
                char *s = HOP3c(strpos, prog->check_offset_min, strend);
	    
                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                    "  Looking for check substr at fixed offset %"IVdf"...\n",
                    (IV)prog->check_offset_min));

	        if (SvTAIL(check)) {
                    /* In this case, the regex is anchored at the end too.
                     * Unless it's a multiline match, the lengths must match
                     * exactly, give or take a \n.  NB: slen >= 1 since
                     * the last char of check is \n */
		    if (!multiline
                        && (   strend - s > slen
                            || strend - s < slen - 1
                            || (strend - s == slen && strend[-1] != '\n')))
                    {
                        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                                            "  String too long...\n"));
                        goto fail_finish;
                    }
                    /* Now should match s[0..slen-2] */
                    slen--;
                }
                if (slen && (*SvPVX_const(check) != *s
                    || (slen > 1 && memNE(SvPVX_const(check), s, slen))))
                {
                    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                                    "  String not equal...\n"));
                    goto fail_finish;
                }

                check_at = s;
                goto success_at_start;
	    }
	}
    }

    end_shift = prog->check_end_shift;

#ifdef DEBUGGING	/* 7/99: reports of failure (with the older version) */
    if (end_shift < 0)
	Perl_croak(aTHX_ "panic: end_shift: %"IVdf" pattern:\n%s\n ",
		   (IV)end_shift, RX_PRECOMP(prog));
#endif

  restart:
    
    /* This is the (re)entry point of the main loop in this function.
     * The goal of this loop is to:
     * 1) find the "check" substring in the region rx_origin..strend
     *    (adjusted by start_shift / end_shift). If not found, reject
     *    immediately.
     * 2) If it exists, look for the "other" substr too if defined; for
     *    example, if the check substr maps to the anchored substr, then
     *    check the floating substr, and vice-versa. If not found, go
     *    back to (1) with rx_origin suitably incremented.
     * 3) If we find an rx_origin position that doesn't contradict
     *    either of the substrings, then check the possible additional
     *    constraints on rx_origin of /^.../m or a known start class.
     *    If these fail, then depending on which constraints fail, jump
     *    back to here, or to various other re-entry points further along
     *    that skip some of the first steps.
     * 4) If we pass all those tests, update the BmUSEFUL() count on the
     *    substring. If the start position was determined to be at the
     *    beginning of the string  - so, not rejected, but not optimised,
     *    since we have to run regmatch from position 0 - decrement the
     *    BmUSEFUL() count. Otherwise increment it.
     */


    /* first, look for the 'check' substring */

    {
        U8* start_point;
        U8* end_point;

        DEBUG_OPTIMISE_MORE_r({
            PerlIO_printf(Perl_debug_log,
                "  At restart: rx_origin=%"IVdf" Check offset min: %"IVdf
                " Start shift: %"IVdf" End shift %"IVdf
                " Real end Shift: %"IVdf"\n",
                (IV)(rx_origin - strbeg),
                (IV)prog->check_offset_min,
                (IV)start_shift,
                (IV)end_shift,
                (IV)prog->check_end_shift);
        });
        
        end_point = HOP3(strend, -end_shift, strbeg);
        start_point = HOPMAYBE3(rx_origin, start_shift, end_point);
        if (!start_point)
            goto fail_finish;


        /* If the regex is absolutely anchored to either the start of the
         * string (SBOL) or to pos() (ANCH_GPOS), then
         * check_offset_max represents an upper bound on the string where
         * the substr could start. For the ANCH_GPOS case, we assume that
         * the caller of intuit will have already set strpos to
         * pos()-gofs, so in this case strpos + offset_max will still be
         * an upper bound on the substr.
         */
        if (!ml_anch
            && prog->intflags & PREGf_ANCH
            && prog->check_offset_max != SSize_t_MAX)
        {
            SSize_t len = SvCUR(check) - !!SvTAIL(check);
            const char * const anchor =
                        (prog->intflags & PREGf_ANCH_GPOS ? strpos : strbeg);

            /* do a bytes rather than chars comparison. It's conservative;
             * so it skips doing the HOP if the result can't possibly end
             * up earlier than the old value of end_point.
             */
            if ((char*)end_point - anchor > prog->check_offset_max) {
                end_point = HOP3lim((U8*)anchor,
                                prog->check_offset_max,
                                end_point -len)
                            + len;
            }
        }

	check_at = fbm_instr( start_point, end_point,
		      check, multiline ? FBMrf_MULTILINE : 0);

	DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
            "  doing 'check' fbm scan, [%"IVdf"..%"IVdf"] gave %"IVdf"\n",
            (IV)((char*)start_point - strbeg),
            (IV)((char*)end_point   - strbeg),
            (IV)(check_at ? check_at - strbeg : -1)
        ));

        /* Update the count-of-usability, remove useless subpatterns,
            unshift s.  */

        DEBUG_EXECUTE_r({
            RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
                SvPVX_const(check), RE_SV_DUMPLEN(check), 30);
            PerlIO_printf(Perl_debug_log, "  %s %s substr %s%s%s",
                              (check_at ? "Found" : "Did not find"),
                (check == (utf8_target ? prog->anchored_utf8 : prog->anchored_substr)
                    ? "anchored" : "floating"),
                quoted,
                RE_SV_TAIL(check),
                (check_at ? " at offset " : "...\n") );
        });

        if (!check_at)
            goto fail_finish;
        /* set rx_origin to the minimum position where the regex could start
         * matching, given the constraint of the just-matched check substring.
         * But don't set it lower than previously.
         */

        if (check_at - rx_origin > prog->check_offset_max)
            rx_origin = HOP3c(check_at, -prog->check_offset_max, rx_origin);
        /* Finish the diagnostic message */
        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
            "%ld (rx_origin now %"IVdf")...\n",
            (long)(check_at - strbeg),
            (IV)(rx_origin - strbeg)
        ));
    }


    /* now look for the 'other' substring if defined */

    if (utf8_target ? prog->substrs->data[other_ix].utf8_substr
                    : prog->substrs->data[other_ix].substr)
    {
	/* Take into account the "other" substring. */
        char *last, *last1;
        char *s;
        SV* must;
        struct reg_substr_datum *other;

      do_other_substr:
        other = &prog->substrs->data[other_ix];

        /* if "other" is anchored:
         * we've previously found a floating substr starting at check_at.
         * This means that the regex origin must lie somewhere
         * between min (rx_origin): HOP3(check_at, -check_offset_max)
         * and max:                 HOP3(check_at, -check_offset_min)
         * (except that min will be >= strpos)
         * So the fixed  substr must lie somewhere between
         *  HOP3(min, anchored_offset)
         *  HOP3(max, anchored_offset) + SvCUR(substr)
         */

        /* if "other" is floating
         * Calculate last1, the absolute latest point where the
         * floating substr could start in the string, ignoring any
         * constraints from the earlier fixed match. It is calculated
         * as follows:
         *
         * strend - prog->minlen (in chars) is the absolute latest
         * position within the string where the origin of the regex
         * could appear. The latest start point for the floating
         * substr is float_min_offset(*) on from the start of the
         * regex.  last1 simply combines thee two offsets.
         *
         * (*) You might think the latest start point should be
         * float_max_offset from the regex origin, and technically
         * you'd be correct. However, consider
         *    /a\d{2,4}bcd\w/
         * Here, float min, max are 3,5 and minlen is 7.
         * This can match either
         *    /a\d\dbcd\w/
         *    /a\d\d\dbcd\w/
         *    /a\d\d\d\dbcd\w/
         * In the first case, the regex matches minlen chars; in the
         * second, minlen+1, in the third, minlen+2.
         * In the first case, the floating offset is 3 (which equals
         * float_min), in the second, 4, and in the third, 5 (which
         * equals float_max). In all cases, the floating string bcd
         * can never start more than 4 chars from the end of the
         * string, which equals minlen - float_min. As the substring
         * starts to match more than float_min from the start of the
         * regex, it makes the regex match more than minlen chars,
         * and the two cancel each other out. So we can always use
         * float_min - minlen, rather than float_max - minlen for the
         * latest position in the string.
         *
         * Note that -minlen + float_min_offset is equivalent (AFAIKT)
         * to CHR_SVLEN(must) - !!SvTAIL(must) + prog->float_end_shift
         */

        assert(prog->minlen >= other->min_offset);
        last1 = HOP3c(strend,
                        other->min_offset - prog->minlen, strbeg);

        if (other_ix) {/* i.e. if (other-is-float) */
            /* last is the latest point where the floating substr could
             * start, *given* any constraints from the earlier fixed
             * match. This constraint is that the floating string starts
             * <= float_max_offset chars from the regex origin (rx_origin).
             * If this value is less than last1, use it instead.
             */
            assert(rx_origin <= last1);
            last =
                /* this condition handles the offset==infinity case, and
                 * is a short-cut otherwise. Although it's comparing a
                 * byte offset to a char length, it does so in a safe way,
                 * since 1 char always occupies 1 or more bytes,
                 * so if a string range is  (last1 - rx_origin) bytes,
                 * it will be less than or equal to  (last1 - rx_origin)
                 * chars; meaning it errs towards doing the accurate HOP3
                 * rather than just using last1 as a short-cut */
                (last1 - rx_origin) < other->max_offset
                    ? last1
                    : (char*)HOP3lim(rx_origin, other->max_offset, last1);
        }
        else {
            assert(strpos + start_shift <= check_at);
            last = HOP4c(check_at, other->min_offset - start_shift,
                        strbeg, strend);
        }

        s = HOP3c(rx_origin, other->min_offset, strend);
        if (s < other_last)	/* These positions already checked */
            s = other_last;

        must = utf8_target ? other->utf8_substr : other->substr;
        assert(SvPOK(must));
        {
            char *from = s;
            char *to   = last + SvCUR(must) - (SvTAIL(must)!=0);

            if (from > to) {
                s = NULL;
                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                    "  skipping 'other' fbm scan: %"IVdf" > %"IVdf"\n",
                    (IV)(from - strbeg),
                    (IV)(to   - strbeg)
                ));
            }
            else {
                s = fbm_instr(
                    (unsigned char*)from,
                    (unsigned char*)to,
                    must,
                    multiline ? FBMrf_MULTILINE : 0
                );
                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                    "  doing 'other' fbm scan, [%"IVdf"..%"IVdf"] gave %"IVdf"\n",
                    (IV)(from - strbeg),
                    (IV)(to   - strbeg),
                    (IV)(s ? s - strbeg : -1)
                ));
            }
        }

        DEBUG_EXECUTE_r({
            RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
                SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
            PerlIO_printf(Perl_debug_log, "  %s %s substr %s%s",
                s ? "Found" : "Contradicts",
                other_ix ? "floating" : "anchored",
                quoted, RE_SV_TAIL(must));
        });


        if (!s) {
            /* last1 is latest possible substr location. If we didn't
             * find it before there, we never will */
            if (last >= last1) {
                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                                        "; giving up...\n"));
                goto fail_finish;
            }

            /* try to find the check substr again at a later
             * position. Maybe next time we'll find the "other" substr
             * in range too */
            other_last = HOP3c(last, 1, strend) /* highest failure */;
            rx_origin =
                other_ix /* i.e. if other-is-float */
                    ? HOP3c(rx_origin, 1, strend)
                    : HOP4c(last, 1 - other->min_offset, strbeg, strend);
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                "; about to retry %s at offset %ld (rx_origin now %"IVdf")...\n",
                (other_ix ? "floating" : "anchored"),
                (long)(HOP3c(check_at, 1, strend) - strbeg),
                (IV)(rx_origin - strbeg)
            ));
            goto restart;
        }
        else {
            if (other_ix) { /* if (other-is-float) */
                /* other_last is set to s, not s+1, since its possible for
                 * a floating substr to fail first time, then succeed
                 * second time at the same floating position; e.g.:
                 *     "-AB--AABZ" =~ /\wAB\d*Z/
                 * The first time round, anchored and float match at
                 * "-(AB)--AAB(Z)" then fail on the initial \w character
                 * class. Second time round, they match at "-AB--A(AB)(Z)".
                 */
                other_last = s;
            }
            else {
                rx_origin = HOP3c(s, -other->min_offset, strbeg);
                other_last = HOP3c(s, 1, strend);
            }
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                " at offset %ld (rx_origin now %"IVdf")...\n",
                  (long)(s - strbeg),
                (IV)(rx_origin - strbeg)
              ));

        }
    }
    else {
        DEBUG_OPTIMISE_MORE_r(
            PerlIO_printf(Perl_debug_log,
                "  Check-only match: offset min:%"IVdf" max:%"IVdf
                " check_at:%"IVdf" rx_origin:%"IVdf" rx_origin-check_at:%"IVdf
                " strend:%"IVdf"\n",
                (IV)prog->check_offset_min,
                (IV)prog->check_offset_max,
                (IV)(check_at-strbeg),
                (IV)(rx_origin-strbeg),
                (IV)(rx_origin-check_at),
                (IV)(strend-strbeg)
            )
        );
    }

  postprocess_substr_matches:

    /* handle the extra constraint of /^.../m if present */

    if (ml_anch && rx_origin != strbeg && rx_origin[-1] != '\n') {
        char *s;

        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                        "  looking for /^/m anchor"));

        /* we have failed the constraint of a \n before rx_origin.
         * Find the next \n, if any, even if it's beyond the current
         * anchored and/or floating substrings. Whether we should be
         * scanning ahead for the next \n or the next substr is debatable.
         * On the one hand you'd expect rare substrings to appear less
         * often than \n's. On the other hand, searching for \n means
         * we're effectively flipping between check_substr and "\n" on each
         * iteration as the current "rarest" string candidate, which
         * means for example that we'll quickly reject the whole string if
         * hasn't got a \n, rather than trying every substr position
         * first
         */

        s = HOP3c(strend, - prog->minlen, strpos);
        if (s <= rx_origin ||
            ! ( rx_origin = (char *)memchr(rx_origin, '\n', s - rx_origin)))
        {
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                            "  Did not find /%s^%s/m...\n",
                            PL_colors[0], PL_colors[1]));
            goto fail_finish;
        }

        /* earliest possible origin is 1 char after the \n.
         * (since *rx_origin == '\n', it's safe to ++ here rather than
         * HOP(rx_origin, 1)) */
        rx_origin++;

        if (prog->substrs->check_ix == 0  /* check is anchored */
            || rx_origin >= HOP3c(check_at,  - prog->check_offset_min, strpos))
        {
            /* Position contradicts check-string; either because
             * check was anchored (and thus has no wiggle room),
             * or check was float and rx_origin is above the float range */
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                "  Found /%s^%s/m, about to restart lookup for check-string with rx_origin %ld...\n",
                PL_colors[0], PL_colors[1], (long)(rx_origin - strbeg)));
            goto restart;
        }

        /* if we get here, the check substr must have been float,
         * is in range, and we may or may not have had an anchored
         * "other" substr which still contradicts */
        assert(prog->substrs->check_ix); /* check is float */

        if (utf8_target ? prog->anchored_utf8 : prog->anchored_substr) {
            /* whoops, the anchored "other" substr exists, so we still
             * contradict. On the other hand, the float "check" substr
             * didn't contradict, so just retry the anchored "other"
             * substr */
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                "  Found /%s^%s/m, rescanning for anchored from offset %ld (rx_origin now %"IVdf")...\n",
                PL_colors[0], PL_colors[1],
                (long)(rx_origin - strbeg + prog->anchored_offset),
                (long)(rx_origin - strbeg)
            ));
            goto do_other_substr;
        }

        /* success: we don't contradict the found floating substring
         * (and there's no anchored substr). */
        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
            "  Found /%s^%s/m with rx_origin %ld...\n",
            PL_colors[0], PL_colors[1], (long)(rx_origin - strbeg)));
    }
    else {
        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
            "  (multiline anchor test skipped)\n"));
    }

  success_at_start:


    /* if we have a starting character class, then test that extra constraint.
     * (trie stclasses are too expensive to use here, we are better off to
     * leave it to regmatch itself) */

    if (progi->regstclass && PL_regkind[OP(progi->regstclass)]!=TRIE) {
        const U8* const str = (U8*)STRING(progi->regstclass);

        /* XXX this value could be pre-computed */
        const int cl_l = (PL_regkind[OP(progi->regstclass)] == EXACT
		    ?  (reginfo->is_utf8_pat
                        ? utf8_distance(str + STR_LEN(progi->regstclass), str)
                        : STR_LEN(progi->regstclass))
		    : 1);
	char * endpos;
        char *s;
        /* latest pos that a matching float substr constrains rx start to */
        char *rx_max_float = NULL;

        /* if the current rx_origin is anchored, either by satisfying an
         * anchored substring constraint, or a /^.../m constraint, then we
         * can reject the current origin if the start class isn't found
         * at the current position. If we have a float-only match, then
         * rx_origin is constrained to a range; so look for the start class
         * in that range. if neither, then look for the start class in the
         * whole rest of the string */

        /* XXX DAPM it's not clear what the minlen test is for, and why
         * it's not used in the floating case. Nothing in the test suite
         * causes minlen == 0 here. See <20140313134639.GS12844@iabyn.com>.
         * Here are some old comments, which may or may not be correct:
         *
	 *   minlen == 0 is possible if regstclass is \b or \B,
	 *   and the fixed substr is ''$.
         *   Since minlen is already taken into account, rx_origin+1 is
         *   before strend; accidentally, minlen >= 1 guaranties no false
         *   positives at rx_origin + 1 even for \b or \B.  But (minlen? 1 :
         *   0) below assumes that regstclass does not come from lookahead...
	 *   If regstclass takes bytelength more than 1: If charlength==1, OK.
         *   This leaves EXACTF-ish only, which are dealt with in
         *   find_byclass().
         */

	if (prog->anchored_substr || prog->anchored_utf8 || ml_anch)
            endpos= HOP3c(rx_origin, (prog->minlen ? cl_l : 0), strend);
        else if (prog->float_substr || prog->float_utf8) {
	    rx_max_float = HOP3c(check_at, -start_shift, strbeg);
	    endpos= HOP3c(rx_max_float, cl_l, strend);
        }
        else 
            endpos= strend;
		    
        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
            "  looking for class: start_shift: %"IVdf" check_at: %"IVdf
            " rx_origin: %"IVdf" endpos: %"IVdf"\n",
              (IV)start_shift, (IV)(check_at - strbeg),
              (IV)(rx_origin - strbeg), (IV)(endpos - strbeg)));

        s = find_byclass(prog, progi->regstclass, rx_origin, endpos,
                            reginfo);
	if (!s) {
	    if (endpos == strend) {
		DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
				"  Could not match STCLASS...\n") );
		goto fail;
	    }
	    DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
                               "  This position contradicts STCLASS...\n") );
            if ((prog->intflags & PREGf_ANCH) && !ml_anch
                        && !(prog->intflags & PREGf_IMPLICIT))
		goto fail;

	    /* Contradict one of substrings */
	    if (prog->anchored_substr || prog->anchored_utf8) {
                if (prog->substrs->check_ix == 1) { /* check is float */
                    /* Have both, check_string is floating */
                    assert(rx_origin + start_shift <= check_at);
                    if (rx_origin + start_shift != check_at) {
                        /* not at latest position float substr could match:
                         * Recheck anchored substring, but not floating.
                         * The condition above is in bytes rather than
                         * chars for efficiency. It's conservative, in
                         * that it errs on the side of doing 'goto
                         * do_other_substr'. In this case, at worst,
                         * an extra anchored search may get done, but in
                         * practice the extra fbm_instr() is likely to
                         * get skipped anyway. */
                        DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
                            "  about to retry anchored at offset %ld (rx_origin now %"IVdf")...\n",
                            (long)(other_last - strbeg),
                            (IV)(rx_origin - strbeg)
                        ));
                        goto do_other_substr;
                    }
                }
            }
	    else {
                /* float-only */

                if (ml_anch) {
                    /* In the presence of ml_anch, we might be able to
                     * find another \n without breaking the current float
                     * constraint. */

                    /* strictly speaking this should be HOP3c(..., 1, ...),
                     * but since we goto a block of code that's going to
                     * search for the next \n if any, its safe here */
                    rx_origin++;
                    DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
                              "  about to look for /%s^%s/m starting at rx_origin %ld...\n",
                              PL_colors[0], PL_colors[1],
                              (long)(rx_origin - strbeg)) );
                    goto postprocess_substr_matches;
                }

                /* strictly speaking this can never be true; but might
                 * be if we ever allow intuit without substrings */
                if (!(utf8_target ? prog->float_utf8 : prog->float_substr))
                    goto fail;

                rx_origin = rx_max_float;
            }

            /* at this point, any matching substrings have been
             * contradicted. Start again... */

            rx_origin = HOP3c(rx_origin, 1, strend);

            /* uses bytes rather than char calculations for efficiency.
             * It's conservative: it errs on the side of doing 'goto restart',
             * where there is code that does a proper char-based test */
            if (rx_origin + start_shift + end_shift > strend) {
                DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
                                       "  Could not match STCLASS...\n") );
                goto fail;
            }
            DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
                "  about to look for %s substr starting at offset %ld (rx_origin now %"IVdf")...\n",
                (prog->substrs->check_ix ? "floating" : "anchored"),
                (long)(rx_origin + start_shift - strbeg),
                (IV)(rx_origin - strbeg)
            ));
            goto restart;
	}

        /* Success !!! */

	if (rx_origin != s) {
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
			"  By STCLASS: moving %ld --> %ld\n",
                                  (long)(rx_origin - strbeg), (long)(s - strbeg))
                   );
        }
        else {
            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
                                  "  Does not contradict STCLASS...\n");
                   );
        }
    }

    /* Decide whether using the substrings helped */

    if (rx_origin != strpos) {
	/* Fixed substring is found far enough so that the match
	   cannot start at strpos. */

        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "  try at offset...\n"));
	++BmUSEFUL(utf8_target ? prog->check_utf8 : prog->check_substr);	/* hooray/5 */
    }
    else {
        /* The found rx_origin position does not prohibit matching at
         * strpos, so calling intuit didn't gain us anything. Decrement
         * the BmUSEFUL() count on the check substring, and if we reach
         * zero, free it.  */
	if (!(prog->intflags & PREGf_NAUGHTY)
	    && (utf8_target ? (
		prog->check_utf8		/* Could be deleted already */
		&& --BmUSEFUL(prog->check_utf8) < 0
		&& (prog->check_utf8 == prog->float_utf8)
	    ) : (
		prog->check_substr		/* Could be deleted already */
		&& --BmUSEFUL(prog->check_substr) < 0
		&& (prog->check_substr == prog->float_substr)
	    )))
	{
	    /* If flags & SOMETHING - do not do it many times on the same match */
	    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "  ... Disabling check substring...\n"));
	    /* XXX Does the destruction order has to change with utf8_target? */
	    SvREFCNT_dec(utf8_target ? prog->check_utf8 : prog->check_substr);
	    SvREFCNT_dec(utf8_target ? prog->check_substr : prog->check_utf8);
	    prog->check_substr = prog->check_utf8 = NULL;	/* disable */
	    prog->float_substr = prog->float_utf8 = NULL;	/* clear */
	    check = NULL;			/* abort */
	    /* XXXX This is a remnant of the old implementation.  It
	            looks wasteful, since now INTUIT can use many
	            other heuristics. */
	    prog->extflags &= ~RXf_USE_INTUIT;
	}
    }

    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
            "Intuit: %sSuccessfully guessed:%s match at offset %ld\n",
             PL_colors[4], PL_colors[5], (long)(rx_origin - strbeg)) );

    return rx_origin;

  fail_finish:				/* Substring not found */
    if (prog->check_substr || prog->check_utf8)		/* could be removed already */
	BmUSEFUL(utf8_target ? prog->check_utf8 : prog->check_substr) += 5; /* hooray */
  fail:
    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch rejected by optimizer%s\n",
			  PL_colors[4], PL_colors[5]));
    return NULL;
}