/// <summary>
        /// Creates a post request based on the provided parameters
        /// </summary>
        /// <param name="requestParameters">List of IRequestParameters thtat will be used for request creation </param>
        /// <param name="request">An instance of PostRequest can be provided to be populated with data. Returned result will be the same instance but updated with params data.</param>
        /// <returns>An instance of PostRequest</returns>
        public static PostRequest CreateRequest(List<IRequestParameter> requestParameters, PostRequest request = null)
        {
            if (requestParameters == null || requestParameters.Count == 0)
            {
                throw new ArgumentException("You need to specify at least one parameter, otherwise it is not possible to create a post request.");
            }

            if (requestParameters.Exists(p => p.ParameterType == RequestParameterType.Basic)
               && requestParameters.Exists(p => p.ParameterType != RequestParameterType.Basic))
            {
                throw new ApplicationException("You cannot have, for the same request, a mix from basic parameters and other types. Basic parameters should not be used in combination with other types of parameters.");
            }

            if (request == null)
            {
                request = new PostRequest();
            }

            InitContentTypeHeader(request, requestParameters[0]);

            foreach (var param in requestParameters)
            {
                if (param == null)
                {
                    continue;
                }

                switch (param.ParameterType)
                {
                    case RequestParameterType.Basic:
                        AddBasicParameterToBodyContent(request, (BasicRequestParameter) param);
                        break;

                    case RequestParameterType.Text:
                        AddTextParameterToBodyContent(request, (TextRequestParameter)param);
                        break;

                    case RequestParameterType.Binary:
                        AddBinaryParameterToBodyContent(request, (BinaryRequestParameter)param);
                        break;

                    default:
                        throw new ApplicationException(string.Format("{0} is an unknown type of RequestParameter.", param.GetType().Name));
                }
            }

            //Add end boundary delimiter to the end of the request for the multipart request
            if (requestParameters[0].ParameterType != RequestParameterType.Basic)
            {
                request.BodyBuilder.Append(string.Format(EndBoundaryTemplate, request.BoundaryValue));
            }

            return request;
        }
        public void PostRequestConstructorTest()
        {
            var target = new PostRequest();

            Assert.IsNotNull(target.BodyBuilder, "BodyBuilder should be initialized in the constructor.");
            Assert.IsNotNull(target.BinaryParamsContent, "BodyBuilder should be initialized in the constructor.");
            Assert.IsTrue(target.BoundaryValue.StartsWith("---------------------------"));
        }
        /// <summary>
        /// Create Content-Type header value based on the provided parameters
        /// </summary>
        /// <param name="request">Request for which Content-Type header is generated</param>
        /// <param name="firstRequestParameter">First parameter which was used in generating post request body</param>
        private static void InitContentTypeHeader(PostRequest request, IRequestParameter firstRequestParameter)
        {
            request.ContentTypeHeader =
                string.Format(TypeHeaderTemplate, firstRequestParameter.ParameterType == RequestParameterType.Basic ? "application/x-www-form-urlencoded" : "multipart/form-data");

            if (firstRequestParameter.ParameterType != RequestParameterType.Basic)
            {
                request.ContentTypeHeader += string.Format(BoundaryDefinitionTemplate, request.BoundaryValue);
            }

            request.ContentTypeHeader += NewLine;
        }
        private static void AddTextParameterToBodyContent(PostRequest request, TextRequestParameter parameter)
        {
            request.BodyBuilder.Append(string.Format(BeginBoundaryTemplate, request.BoundaryValue));

            request.BodyBuilder.Append(string.Format(DispositionHeaderTemplate, parameter.Name)).Append(NewLine);

            if (parameter.IncludeContentTypeHeaderInTheBodySection)
            {
                request.BodyBuilder.Append(string.Format(BodyTypeHeaderTemplate, parameter.ContentType));
            }

            if (parameter.TransportAsBase64)
            {
                request.BodyBuilder.Append(string.Format(TransportEncodingHeaderTemplate, "base64"));
            }
            else
            {
                request.BodyBuilder.Append(NewLine);
            }

            request.BodyBuilder.Append(parameter.Content).Append(NewLine);
        }
        private static void AddBinaryParameterToBodyContent(PostRequest request, BinaryRequestParameter parameter)
        {
            request.BodyBuilder.Append(string.Format(BeginBoundaryTemplate, request.BoundaryValue));

            request.BodyBuilder.Append(string.Format(DispositionHeaderTemplate, parameter.Name));

            request.BodyBuilder.Append(string.Format(FileNameParamTemplate, parameter.FileName)).Append(NewLine);

            request.BodyBuilder.Append(string.Format(BodyTypeHeaderTemplate, parameter.ContentType));

            request.BodyBuilder.Append(string.Format(TransportEncodingHeaderTemplate, parameter.TransportAsBase64 ? "base64" : "binary"));

            if (parameter.TransportAsBase64)
            {
                request.BodyBuilder.Append(parameter.ContentAsBase64);
            }
            else
            {
                request.AllowBodyContentOnlyAsBytes = true;

                request.BinaryParamsContent.Add(parameter.ContentAsBytes);

                request.BodyBuilder.Append(PostRequest.BinaryDataPlaceHolder);
            }

            request.BodyBuilder.Append(NewLine);
        }
        private static void AddBasicParameterToBodyContent(PostRequest request, BasicRequestParameter parameter)
        {
            if (!string.IsNullOrEmpty(request.Body))
            {
                request.BodyBuilder.Append("&");
            }

            request.BodyBuilder.Append(string.Format("{0}={1}", parameter.Name, parameter.Content));
        }