function globUnescape(s) {
        return s.replace(/\\(.)/g, '$1')
      }
/c)
            //     - b matches b
            //     - doublestar
            //       - matchOne(x/y/z/c, c) -> no
            //       - matchOne(y/z/c, c) -> no
            //       - matchOne(z/c, c) -> no
            //       - matchOne(c, c) yes, hit
            var fr = fi
            var pr = pi + 1
            if (pr === pl) {
              this.debug('** at the end')
              // a ** at the end will just swallow the rest.
              // We have found a match.
              // however, it will not swallow /.x, unless
              // options.dot is set.
              // . and .. are *never* matched by **, for explosively
              // exponential reasons.
              for (; fi < fl; fi++) {
                if (
                  file[fi] === '.' ||
                  file[fi] === '..' ||
                  (!options.dot && file[fi].charAt(0) === '.')
                )
                  return false
              }
              return true
            }

            // ok, let's see if we can swallow whatever we can.
            while (fr < fl) {
              var swallowee = file[fr]

              this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)

              // XXX remove this slice.  Just pass the start index.
              if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
                this.debug('globstar found match!', fr, fl, swallowee)
                // found a match.
                return true
              } else {
                // can't swallow "." or ".." ever.
                // can only swallow ".foo" when explicitly asked.
                if (
                  swallowee === '.' ||
                  swallowee === '..' ||
                  (!options.dot && swallowee.charAt(0) === '.')
                ) {
                  this.debug('dot detected!', file, fr, pattern, pr)
                  break
                }

                // ** swallows a segment, and continue.
                this.debug('globstar swallow a segment, and continue')
                fr++
              }
            }

            // no match was found.
            // However, in partial mode, we can't say this is necessarily over.
            // If there's more *pattern* left, then
            if (partial) {
              // ran out of file
              this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
              if (fr === fl) return true
            }
            return false
          }

          // something other than **
          // non-magic patterns just have to match exactly
          // patterns with magic have been turned into regexps.
          var hit
          if (typeof p === 'string') {
            if (options.nocase) {
              hit = f.toLowerCase() === p.toLowerCase()
            } else {
              hit = f === p
            }
            this.debug('string match', p, f, hit)
          } else {
            hit = f.match(p)
            this.debug('pattern match', p, f, hit)
          }

          if (!hit) return false
        }

        // Note: ending in / means that we'll get a final ""
        // at the end of the pattern.  This can only match a
        // corresponding "" at the end of the file.
        // If the file ends in /, then it can only match a
        // a pattern that ends in /, unless the pattern just
        // doesn't have any more for it. But, a/b/ should *not*
        // match "a/b/*", even though "" matches against the
        // [^/]*? pattern, except in partial mode, where it might
        // simply not be reached yet.
        // However, a/b/ should still satisfy a/*

        // now either we fell off the end of the pattern, or we're done.
        if (fi === fl && pi === pl) {
          // ran out of pattern and filename at the same time.
          // an exact hit!
          return true
        } else if (fi === fl) {
          // ran out of file, but still had pattern left.
          // this is ok if we're doing the match as part of
          // a glob fs traversal.
          return partial
        } else if (pi === pl) {
          // ran out of pattern, still have file left.
          // this is only acceptable if we're on the very last
          // empty segment of a file with a trailing slash.
          // a/* should match a/b/
          var emptyFileEnd = fi === fl - 1 && file[fi] === ''
          return emptyFileEnd
        }

        // should be unreachable.
        throw new Error('wtf?')
      }

      // replace stuff like \* with *
      function globUnescape(s) {
        return s.replace(/\\(.)/g, '$1')
      }

      function regExpEscape(s) {
        return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
      }

      /**