public static string ValueForKeyedIdentifier(this HttpResponse response, string key)
        {
            var keyType = BasicRequestDefinition.LocationForKey(key);

            switch (keyType)
            {
            case PlaceholderLocation.Body:
                return(response.Body);

            case PlaceholderLocation.HttpHeader:
                string headerTrueName = key.Substring(0, key.Length - 1);
                if (response.Headers.AllKeys.Contains(headerTrueName))
                {
                    return(response.Headers[headerTrueName]);
                }
                return(null);

            case PlaceholderLocation.Json:
                if (!response.ContentType.MatchesContentTypeIdentifier(MethodDefinition.MimeTypeJson))
                {
                    throw new NotSupportedException(string.Format("Cannot read JPath property from response with content-type: {0}", response.ContentType));
                }

                return(JsonPath.ValueFromJsonPath(response.Body, key).ToString());

            default:
                throw new NotSupportedException(string.Format("Unsupported location for keyed identifier {0}: {1}", key, keyType));
            }
        }
        /// <summary>
        /// Locate the Http.HttpRequest instance for this request definition either by
        /// parsing the RawHttpRequest or resolving MethodName into a request.
        /// </summary>
        /// <param name="definition"></param>
        /// <param name="documents"></param>
        /// <returns></returns>
        public static HttpRequest GetHttpRequest(this BasicRequestDefinition definition, DocSet documents, IServiceAccount account, IssueLogger issues)
        {
            HttpRequest foundRequest = null;

            if (!string.IsNullOrEmpty(definition.RawHttpRequest))
            {
                foundRequest = ParseHttpRequest(definition.RawHttpRequest, issues);
            }
            else if (!string.IsNullOrEmpty(definition.MethodName))
            {
                foundRequest = LookupHttpRequestForMethod(definition.MethodName, documents, account, issues);
            }
            else if (!string.IsNullOrEmpty(definition.CannedRequestName))
            {
                foundRequest = HttpRequestForCannedRequest(definition.CannedRequestName, documents, account, issues);
            }

            return(foundRequest);
        }
        /// <summary>
        /// Convert the input into a PlaceholderValue and realize any reference to a stored value into
        /// the actual value at the given time.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="storedValues"></param>
        /// <returns></returns>
        public static PlaceholderValue ConvertToPlaceholderValue(string key, string value, Dictionary <string, string> storedValues)
        {
            string replacementValue = value;

            switch (BasicRequestDefinition.LocationForKey(value))
            {
            case PlaceholderLocation.StoredValue:
                if (!storedValues.TryGetValue(value, out replacementValue))
                {
                    throw new PlaceholderValueNotFoundException($"Unable to locate the placeholder value {value} in available values: {storedValues.Keys.ComponentsJoinedByString(",")}");
                }
                break;

            case PlaceholderLocation.CSharpCode:
                replacementValue = CSharpEval.Evaluate(value.Substring(1), storedValues);
                break;
            }

            PlaceholderValue v = new PlaceholderValue
            {
                PlaceholderKey = key,
                DefinedValue   = value,
                Location       = BasicRequestDefinition.LocationForKey(key),
                Value          = replacementValue
            };

            // Allow the random-filename generator to swap the value with a randomly generated filename.
            int index = value == null ? -1 : value.IndexOf(RandomFilenameValuePrefix);

            if (index >= 0)
            {
                int    endIndex    = value.IndexOf("!", index + 1);
                string placeholder = null;
                if (endIndex > -1)
                {
                    placeholder = value.Substring(index, endIndex - index + 1);
                }
                else
                {
                    // Be backwards comaptible with previous behavior.
                    placeholder = value.Substring(index);
                    if (!placeholder.EndsWith("!"))
                    {
                        if (placeholder != RandomFilenameValuePrefix)
                        {
                            value = "/" + value.Replace(placeholder, placeholder + "!");
                        }
                        else
                        {
                            value = value.Replace(placeholder, placeholder + "!");
                        }
                        placeholder = placeholder + "!";
                    }
                }
                string randomFilename = GenerateRandomFilename(placeholder);
                v.Value = value.Replace(placeholder, randomFilename);
            }

            Debug.WriteLine("Converting \"{0}: {1}\" into loc={2},value={3}", key, value, v.Location, v.Value);

            return(v);
        }