ParseRequest(HttpRequest request, string tempLoc, Func <MultipartSection, MultipartFileInfo, Task> fileHandler = null)
        {
            var files = new List <LocalMultipartFileInfo>();

            if (fileHandler == null)
            {
                fileHandler = HandleFileSection;
            }

            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new InvalidDataException("Request is not a multipart request");
            }

            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                BONDARY_LENGTH_LIMIT);

            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition,
                        out ContentDispositionHeaderValue contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        var formFile = new LocalMultipartFileInfo()
                        {
                            Name     = section.AsFileSection().Name,
                            FileName = section.AsFileSection().FileName,
                            Length   = section.Body.Length,
                        };
                        await fileHandler(section, formFile);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        formAccumulator = await AccumulateForm(formAccumulator, section, contentDisposition);
                    }
                }

                section = await reader.ReadNextSectionAsync();
            }

            return(formAccumulator.GetResults(), files);

            async Task HandleFileSection(MultipartSection fileSection, MultipartFileInfo formFile)
            {
                string targetFilePath;
                var    guid = Guid.NewGuid();

                targetFilePath = Path.Combine(tempLoc, guid.ToString());

                using (var targetStream = File.Create(targetFilePath))
                {
                    await fileSection.Body.CopyToAsync(targetStream);
                }

                var tFormFile = new LocalMultipartFileInfo()
                {
                    Name              = formFile.Name,
                    Length            = formFile.Length,
                    FileName          = formFile.FileName,
                    TemporaryLocation = targetFilePath,
                };

                files.Add(tFormFile);
            }
        }