static int
match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
     wchar_t *wstring;
     char **indices;
     size_t wstrlen;
     wchar_t *wpat;
     int mtype;
     char **sp, **ep;
{
  wchar_t wc, *wp, *nwpat, *wp1;
  size_t len;
  int mlen;
  int n, n1, n2, simple;

  simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
#if defined (EXTENDED_GLOB)
  if (extended_glob)
    simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
#endif

  /* If the pattern doesn't match anywhere in the string, go ahead and
     short-circuit right away.  A minor optimization, saves a bunch of
     unnecessary calls to strmatch (up to N calls for a string of N
     characters) if the match is unsuccessful.  To preserve the semantics
     of the substring matches below, we make sure that the pattern has
     `*' as first and last character, making a new pattern if necessary. */
  len = wcslen (wpat);
  if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
    {
      int unescaped_backslash;
      wchar_t *wpp;

      wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
      wp1 = wpat;
      if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
	*wp++ = L'*';
      while (*wp1 != L'\0')
	*wp++ = *wp1++;
#if 1
      /* See comments above in match_upattern. */
      if (wp1[-1] == L'*' && (unescaped_backslash = wp1[-2] == L'\\'))
        {
          wpp = wp1 - 3;
          while (wpp >= wpat && *wpp-- == L'\\')
            unescaped_backslash = 1 - unescaped_backslash;
          if (unescaped_backslash)
            *wp++ = L'*';
        }
      else if (wp1[-1] != L'*')
        *wp++ = L'*';
#else      
      if (wp1[-1] != L'*' || wp1[-2] == L'\\')
        *wp++ = L'*';
#endif
      *wp = '\0';
    }
  else
    nwpat = wpat;
  len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG | FNMATCH_IGNCASE);
  if (nwpat != wpat)
    free (nwpat);
  if (len == FNM_NOMATCH)
    return (0);

  mlen = wmatchlen (wpat, wstrlen);

/* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
  switch (mtype)
    {
    case MATCH_ANY:
      for (n = 0; n <= wstrlen; n++)
	{
	  n2 = simple ? (WFOLD(*wpat) == WFOLD(wstring[n])) : match_pattern_wchar (wpat, wstring + n, FNMATCH_IGNCASE);
	  if (n2)
	    {
	      n1 = (mlen == -1) ? wstrlen : n + mlen;
	      if (n1 > wstrlen)
	        break;

	      for ( ; n1 >= n; n1--)
		{
		  wc = wstring[n1]; wstring[n1] = L'\0';
		  if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
		    {
		      wstring[n1] = wc;
		      *sp = indices[n];
		      *ep = indices[n1];
		      return 1;
		    }
		  wstring[n1] = wc;
		  /* If MLEN != -1, we have a fixed length pattern. */
		  if (mlen != -1)
		    break;
		}
	    }
	}

      return (0);

    case MATCH_BEG:
      if (match_pattern_wchar (wpat, wstring, FNMATCH_IGNCASE) == 0)
	return (0);

      for (n = (mlen == -1) ? wstrlen : mlen; n >= 0; n--)
	{
	  wc = wstring[n]; wstring[n] = L'\0';
	  if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
	    {
	      wstring[n] = wc;
	      *sp = indices[0];
	      *ep = indices[n];
	      return 1;
	    }
	  wstring[n] = wc;
	  /* If MLEN != -1, we have a fixed length pattern. */
	  if (mlen != -1)
	    break;
	}

      return (0);

    case MATCH_END:
      for (n = wstrlen - ((mlen == -1) ? wstrlen : mlen); n <= wstrlen; n++)
	{
	  if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0)
	    {
	      *sp = indices[n];
	      *ep = indices[wstrlen];
	      return 1;
	    }
	  /* If MLEN != -1, we have a fixed length pattern. */
	  if (mlen != -1)
	    break;
	}

      return (0);
    }

  return (0);