/// <summary>Adds a parameter value.</summary>
        /// <param name="type">Type of the parameter (must be 'Path' or 'Query').</param>
        /// <param name="name">Parameter name.</param>
        /// <param name="value">Parameter value.</param>
        public void AddParameter(RequestParameterType type, string name, string value)
        {
            name.ThrowIfNull("name");
            if (value == null)
            {
                Logger.Warning("Add parameter should not get null values. type={0}, name={1}", type, name);
                return;
            }
            switch (type)
            {
            case RequestParameterType.Path:
                if (!PathParameters.ContainsKey(name))
                {
                    PathParameters[name] = new List <string> {
                        value
                    };
                }
                else
                {
                    PathParameters[name].Add(value);
                }
                break;

            case RequestParameterType.Query:
                QueryParameters.Add(new KeyValuePair <string, string>(name, value));
                break;

            default:
                throw new ArgumentOutOfRangeException("type");
            }
        }
        /// <summary>
        /// Builds the REST path string builder based on <see cref="PathParameters"/> and the URI template spec
        /// http://tools.ietf.org/html/rfc6570.
        /// </summary>
        /// <returns></returns>
        private StringBuilder BuildRestPath()
        {
            if (string.IsNullOrEmpty(Path))
            {
                return(new StringBuilder(string.Empty));
            }

            var restPath = new StringBuilder(Path);
            var matches  = PathParametersPattern.Matches(restPath.ToString());

            foreach (var match in matches)
            {
                var matchStr = match.ToString();
                // Strip the first and last characters: '{' and '}'.
                var content = matchStr.Substring(1, matchStr.Length - 2);

                var op = string.Empty;
                // If the content's first character is an operator, save and remove it from the content string.
                if (OPERATORS.Contains(content[0].ToString()))
                {
                    op      = content[0].ToString();
                    content = content.Substring(1);
                }

                var newContent = new StringBuilder();

                // Iterate over all possible parameters.
                var parameters = content.Split(',');
                for (var index = 0; index < parameters.Length; ++index)
                {
                    var parameter = parameters[index];

                    var parameterName = parameter;
                    var containStar   = false;
                    var numOfChars    = 0;

                    // Check if it ends with '*'.
                    if (parameterName[parameterName.Length - 1] == '*')
                    {
                        containStar   = true;
                        parameterName = parameterName.Substring(0, parameterName.Length - 1);
                    }
                    // Check if it contains :n which means we should only use the first n characters of this parameter.
                    if (parameterName.Contains(":"))
                    {
                        if (!int.TryParse(parameterName.Substring(parameterName.IndexOf(":") + 1), out numOfChars))
                        {
                            throw new ArgumentException(
                                      string.Format("Can't parse number after ':' in Path \"{0}\". Parameter is \"{1}\"",
                                                    Path, parameterName), Path);
                        }
                        parameterName = parameterName.Substring(0, parameterName.IndexOf(":"));
                    }

                    // We can improve the following if statement, but for readability we will leave it like that.
                    var joiner = op;
                    var start  = op;
                    switch (op)
                    {
                    case "+":
                        start  = index == 0 ? "" : ",";
                        joiner = ",";
                        break;

                    case ".":
                        if (!containStar)
                        {
                            joiner = ",";
                        }
                        break;

                    case "/":
                        if (!containStar)
                        {
                            joiner = ",";
                        }
                        break;

                    case "#":
                        start  = index == 0 ? "#" : ",";
                        joiner = ",";
                        break;

                    case "?":
                        start  = (index == 0 ? "?" : "&") + parameterName + "=";
                        joiner = ",";
                        if (containStar)
                        {
                            joiner = "&" + parameterName + "=";
                        }
                        break;

                    case "&":
                    case ";":
                        start  = op + parameterName + "=";
                        joiner = ",";
                        if (containStar)
                        {
                            joiner = op + parameterName + "=";
                        }
                        break;

                    // No operator, in that case just ','.
                    default:
                        if (index > 0)
                        {
                            start = ",";
                        }
                        joiner = ",";
                        break;
                    }

                    // Check if a path parameter equals the name which appears in the REST path.
                    if (PathParameters.ContainsKey(parameterName))
                    {
                        var value = string.Join(joiner, PathParameters[parameterName]);

                        // Check if we need to use a substring of the value.
                        if (numOfChars != 0 && numOfChars < value.Length)
                        {
                            value = value.Substring(0, numOfChars);
                        }

                        if (op != "+" && op != "#" && PathParameters[parameterName].Count == 1)
                        {
                            value = Uri.EscapeDataString(value);
                        }

                        value = start + value;
                        newContent.Append(value);
                    }
                    else
                    {
                        throw new ArgumentException(
                                  string.Format("Path \"{0}\" misses a \"{1}\" parameter", Path, parameterName), Path);
                    }
                }

                if (op == ";")
                {
                    if (newContent[newContent.Length - 1] == '=')
                    {
                        newContent = newContent.Remove(newContent.Length - 1, 1);
                    }
                    newContent = newContent.Replace("=;", ";");
                }
                restPath = restPath.Replace(matchStr, newContent.ToString());
            }
            return(restPath);
        }