/// <summary>
        /// Parses the given string.  The given string can either be " quoted, ' quoted, $_GET, $_POST, $_COOKIE, $_REQUEST
        /// </summary>
        /// <param name="toParse"></param>
        /// <param name="webConnection"></param>
        /// <returns></returns>
        private string Parse(string toParse, IWebConnection webConnection)
        {
            if (toParse.StartsWith("\""))
            {
                if (!toParse.EndsWith("\""))
                    throw new CanNotParse();

                return HandleEscapes(toParse, '"');
            }
            else if (toParse.StartsWith("'"))
            {
                if (!toParse.EndsWith("'"))
                    throw new CanNotParse();

                return HandleEscapes(toParse, '\'');
            }
            else if (toParse.StartsWith("$_GET["))
            {
                string argumentName = GetArgument(toParse, "$_GET");

                return webConnection.GetArgumentOrException(argumentName);
            }
            else if (toParse.StartsWith("$_GETENCODE["))
            {
                string argumentName = GetArgument(toParse, "$_GETENCODE");

                return HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.GetArgumentOrException(argumentName));
            }
            else if (toParse.StartsWith("$_POST["))
            {
                string argumentName = GetArgument(toParse, "$_POST");

                return webConnection.PostArgumentOrException(argumentName);
            }
            else if (toParse.StartsWith("$_POSTENCODE["))
            {
                string argumentName = GetArgument(toParse, "$_POSTENCODE");

                return HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.PostArgumentOrException(argumentName));
            }
            else if (toParse.StartsWith("$_COOKIE["))
            {
                string argumentName = GetArgument(toParse, "$_COOKIE");

                return webConnection.CookieOrException(argumentName);
            }
            else if (toParse.StartsWith("$_COOKIEENCODE["))
            {
                string argumentName = GetArgument(toParse, "$_COOKIEENCODE");

                return HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.CookieOrException(argumentName));
            }
            else if (toParse.StartsWith("$_REQUEST["))
            {
                string argumentName = GetArgument(toParse, "$_REQUEST");

                return webConnection.EitherArgumentOrException(argumentName);
            }
            else if (toParse.StartsWith("$_REQUESTENCODE["))
            {
                string argumentName = GetArgument(toParse, "$_REQUESTENCODE");

                return HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.EitherArgumentOrException(argumentName));
            }

            throw new CanNotParse();
        }
        /// <summary>
        /// Parses all of the web components
        /// </summary>
        /// <param name="toResolve"></param>
        /// <param name="webConnection"></param>
        /// <returns></returns>
        private string ParseWebComponents(string toResolve, IWebConnection webConnection)
        {
            string[] splitAtOpenTag = toResolve.Split(new string[] { "<?" }, StringSplitOptions.None);

            // If nothing was found, just return toResolve unparsed
            if (splitAtOpenTag.Length <= 1)
                return toResolve;

            for (int ctr = 1; ctr < splitAtOpenTag.Length; ctr++)
            {
                string tagContentsAndTrailer = splitAtOpenTag[ctr];
                int? closeLoc = FindClose(tagContentsAndTrailer);

                if (null == closeLoc)
                    // no ?>
                    splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;
                else
                {
                    string webComponentTag = tagContentsAndTrailer.Substring(0, closeLoc.Value - 2).Trim();
                    string afterWebComponentTag = tagContentsAndTrailer.Substring(closeLoc.Value);

                    if (webComponentTag.StartsWith("WebComponent(", true, CultureInfo.InvariantCulture))
                    {
                        // <? WebComponent(...
                        try
                        {
                            string arguments = webComponentTag.Substring("WebComponent(".Length);

                            StringBuilder parsedArguments = new StringBuilder();

                            foreach (string subString in SplitAtPeriods(arguments))
                            {
                                string parsed = Parse(subString, webConnection);
                                parsedArguments.Append(parsed);
                            }

                            try
                            {
                                try
                                {
                                    string webComponentResults = webConnection.DoWebComponent(parsedArguments.ToString());
                                    splitAtOpenTag[ctr] = webComponentResults + afterWebComponentTag;
                                }
                                catch (Exception e)
                                {
                                    log.Error("Exception when handling a web component", e);
                                    throw;
                                }
                            }
                            catch (Exception e)
                            {
                                if (e is WebResultsOverrideException)
                                {
                                    WebResultsOverrideException wroe = (WebResultsOverrideException)e;

                                    log.Error("Exception when handling a web component", wroe);
                                    splitAtOpenTag[ctr] = wroe.WebResults.ResultsAsString + afterWebComponentTag;
                                }
                                else
                                {
                                    log.Error("Exception when handling a web component", e);
                                    splitAtOpenTag[ctr] = " Unknown error, see logs " + afterWebComponentTag;
                                }
                            }
                        }
                        catch (CanNotParse cnp)
                        {
                            log.Error(cnp);
                            splitAtOpenTag[ctr] = "<? PARSE ERROR + " + webComponentTag + " PARSE ERROR ?>" + afterWebComponentTag;
                        }
                    }
                    else if (webComponentTag.StartsWith("$_"))
                    {
                        // $_GET...  $_POST...  $_COOKIE...  $_REQUEST...

                        string[] varSourceAndName = webComponentTag.Substring(2).Split('[');

                        if (2 != varSourceAndName.Length)
                            splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;
                        else
                        {
                            string varSource = varSourceAndName[0];

                            string[] variableAndJunk = varSourceAndName[1].Split('"');

                            if (3 != variableAndJunk.Length)
                                splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;
                            else
                            {
                                string name = variableAndJunk[1];

                                string result = null;

                                try
                                {
                                    switch (varSource)
                                    {
                                        case ("GET"):
                                            result = webConnection.GetArgumentOrException(name);
                                            break;
                                        case ("GETENCODE"):
                                            result = HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.GetArgumentOrException(name));
                                            break;
                                        case ("POST"):
                                            result = webConnection.PostArgumentOrException(name);
                                            break;
                                        case ("POSTENCODE"):
                                            result = HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.PostArgumentOrException(name));
                                            break;
                                        case ("COOKIE"):
                                            result = webConnection.CookieOrException(name);
                                            break;
                                        case ("COOKIEENCODE"):
                                            result = HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.CookieOrException(name));
                                            break;
                                        case ("REQUEST"):
                                            result = webConnection.EitherArgumentOrException(name);
                                            break;
                                        case ("REQUESTENCODE"):
                                            result = HTTPStringFunctions.EncodeRequestParametersForBrowser(webConnection.EitherArgumentOrException(name));
                                            break;
                                    }

                                    if (null != result)
                                        splitAtOpenTag[ctr] = result + afterWebComponentTag;
                                    else
                                        splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;

                                }
                                catch (Exception e)
                                {
                                    log.Error("Error when handing a $_ ", e);
                                    splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;
                                }
                            }
                        }
                    }
                    else if (webComponentTag.StartsWith("Cache("))
                    {
                        // <? Cache(...

                        string[] splitAtCloseTag = splitAtOpenTag[ctr].Split(new string[] { "?>" }, 2, StringSplitOptions.None);

                        if (2 != splitAtCloseTag.Length)
                            splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;
                        else
                        {
                            string requestedUrl = splitAtCloseTag[0].Split(new char[] { '(' }, 2)[1].Split(')')[0];
                            splitAtOpenTag[ctr] = webConnection.GetBrowserCacheUrl(requestedUrl) + splitAtCloseTag[1];
                        }
                    }
                    else
                        splitAtOpenTag[ctr] = "<?" + tagContentsAndTrailer;
                }
            }

            StringBuilder toReturn = new StringBuilder();

            foreach (string toAdd in splitAtOpenTag)
                toReturn.Append(toAdd);

            return toReturn.ToString();
        }
 public virtual WebDelegate GetMethod(IWebConnection webConnection)
 {
     string method = webConnection.GetArgumentOrException("Method");
     return FileHandlerFactoryLocator.WebMethodCache[MethodNameAndFileContainer.New(method, FileContainer, this)];
 }