protected TestUnitResult Upload(ITransferRequest transferRequest)
        {
            if (transferRequest == null)
            {
                return(null);
            }

            List <IMetric> metrics = new List <IMetric>();

            metrics.Add(new StringMetric(MetricName.url, transferRequest.RequestUri.ToString(), ""));

            int taskId = Task.CurrentId.Value;

            DateTimeOffset timeStart = DateTimeOffset.UtcNow;

            metrics.Add(new DateTimeMetric(MetricName.startTime, timeStart, "dateTime"));

            List <ItemAccessMethod> methods = new List <ItemAccessMethod>()
            {
                transferRequest.Method
            };

            if (methods.Count() == 0)
            {
                log.WarnFormat("No upload methods found. Skipping upload.");
                var tcr1 = new TestUnitResult(metrics, TestUnitResultStatus.NotStarted);
                tcr1.State = transferRequest;
                metrics.Add(new DateTimeMetric(MetricName.endTime, DateTimeOffset.UtcNow, "dateTime"));
                return(tcr1);
            }

            var method = methods.First();

            long   respTime  = 0;
            Random rng       = new Random();
            long   totalSize = Convert.ToInt64(transferRequest.ContentLength);

            log.DebugFormat("Upload {1} to {0} ({2}) ...", transferRequest.RequestUri, BytesToString(Convert.ToInt64(totalSize)), transferRequest.Method);

            Stopwatch stopWatchUploadElaspedTime = new Stopwatch();

            metrics.Add(new LongMetric(MetricName.beginGetResponseTime, DateTimeOffset.UtcNow.Ticks, "ticks"));
            Stopwatch sw = new Stopwatch();

            sw.Start();

            var uploadStreamTask = transferRequest.GetRequestStreamAsync();

            uploadStreamTask.ContinueWith(streamTask =>
            {
                respTime                 = sw.ElapsedMilliseconds;
                Stream stream            = streamTask.Result;
                byte[] buf               = new byte[4096];
                double progessPct        = 0;
                long totalByteCounter    = 0;
                long intermediateCounter = 0;
                stopWatchUploadElaspedTime.Start();
                while (totalByteCounter < totalSize)
                {
                    rng.NextBytes(buf);
                    int length = buf.Length;
                    if (totalSize < totalByteCounter + length)
                    {
                        length = Convert.ToInt32(totalSize - totalByteCounter);
                    }
                    stream.Write(buf, 0, buf.Length);
                    totalByteCounter    += buf.Length;
                    intermediateCounter += buf.Length;
                    double totalPct      = ((double)totalByteCounter / totalSize) * 100;
                    if ((Math.Abs(progessPct - totalPct) >= 1) || intermediateCounter >= 10485760)
                    {
                        progessPct         = totalPct;
                        double bytespersec = (double)totalByteCounter / ((double)stopWatchUploadElaspedTime.ElapsedMilliseconds / 1000);
                        log.DebugFormat("[{2}] Uploaded {0}% [{1}/s]", totalPct.ToString("F1"), BytesToString((long)bytespersec), taskId);

                        intermediateCounter = 0;
                    }

                    if (Configuration.Current.Global.TestMode && totalByteCounter >= 10485760 * 2)
                    {
                        // Test Breaker at 20MB )
                        log.Warn("!!!!!TEST DOWNLOAD BREAKER!!!!");
                        break;
                    }
                }
                stream.Close();
                stopWatchUploadElaspedTime.Stop();
            });

            try
            {
                uploadStreamTask.Wait();
            }
            catch (Exception e)
            {
                Exception ie = e;
                while (ie.InnerException != null)
                {
                    ie = ie.InnerException;
                }
                if (ie is WebException)
                {
                    WebException we = ie as WebException;
                    log.DebugFormat("[{0}] Error uploading {2}. {4} Error: {1}[{3}]", Task.CurrentId, we.Message, transferRequest.RequestUri, we.Status.ToString(), method);
                    if (we.Response is HttpWebResponse)
                    {
                        metrics.Add(new StringMetric(MetricName.httpStatusCode, string.Format("{0}:{1}", (int)((HttpWebResponse)we.Response).StatusCode, ((HttpWebResponse)we.Response).StatusDescription), ""));
                    }

                    metrics.Add(new ExceptionMetric(we));
                }
                else
                {
                    log.DebugFormat("[{0}] Error during upload {2}. Exception: {1}", Task.CurrentId, ie.Message, transferRequest.RequestUri);
                    log.Debug(ie.StackTrace);
                    metrics.Add(new ExceptionMetric(ie));
                }
            }

            var uploadTask = transferRequest.GetResponseAsync().ContinueWith(resp =>
            {
                sw.Stop();

                using (ITransferResponse response = resp.Result)
                {
                    log.InfoFormat("[{1}] > {3} Status Code {0} ({2}ms)", response.StatusCode, taskId, respTime, method);
                    metrics.Add(new StringMetric(MetricName.httpStatusCode, string.Format("{0}:{1}", (int)response.StatusCode, response.StatusDescription), ""));
                    if (!(response.StatusCode == TransferStatusCode.OK || response.StatusCode == TransferStatusCode.Accepted || response.StatusCode == TransferStatusCode.Created))
                    {
                        log.DebugFormat("[{0}] < Not OK. Exception: {1}", taskId, response.StatusDescription);
                        metrics.Add(new ExceptionMetric(new Exception(
                                                            string.Format("[{0}] < Not OK. Exception: {1}", taskId, response.StatusDescription))));
                    }
                    else
                    {
                        log.InfoFormat("[{0}] < OK. Content Type {1}", taskId, response.ContentType);
                    }
                }
            });

            try
            {
                uploadTask.Wait();
            }
            catch (Exception e)
            {
                Exception ie = e;
                while (ie.InnerException != null)
                {
                    ie = ie.InnerException;
                }
                if (ie is WebException)
                {
                    WebException we = ie as WebException;
                    log.DebugFormat("[{0}] Error uploading {2}. {4} Error: {1}[{3}]", Task.CurrentId, we.Message, transferRequest.RequestUri, we.Status.ToString(), method);
                    if (we.Response is HttpWebResponse)
                    {
                        metrics.Add(new StringMetric(MetricName.httpStatusCode, string.Format("{0}:{1}", (int)((HttpWebResponse)we.Response).StatusCode, ((HttpWebResponse)we.Response).StatusDescription), ""));
                    }

                    metrics.Add(new ExceptionMetric(we));
                }
                else
                {
                    log.DebugFormat("[{0}] Error during upload {2}. Exception: {1}", Task.CurrentId, ie.Message, transferRequest.RequestUri);
                    log.Debug(ie.StackTrace);
                    metrics.Add(new ExceptionMetric(ie));
                }
            }

            DateTimeOffset timeStop = DateTimeOffset.UtcNow;

            metrics.Add(new DateTimeMetric(MetricName.endTime, timeStop, "dateTime"));
            metrics.Add(new LongMetric(MetricName.endGetResponseTime, DateTime.UtcNow.Ticks, "ticks"));
            metrics.Add(new LongMetric(MetricName.responseTime, respTime, "ms"));
            metrics.Add(new LongMetric(MetricName.size, totalSize, "bytes"));
            metrics.Add(new LongMetric(MetricName.downloadElapsedTime, stopWatchUploadElaspedTime.ElapsedMilliseconds, "ms"));
            metrics.Add(new LongMetric(MetricName.maxTotalResults, 1, "#"));
            metrics.Add(new LongMetric(MetricName.totalReadResults, 1, "#"));
            metrics.Add(new LongMetric(MetricName.wrongResultsCount, 0, "#"));
            var tcr = new TestUnitResult(metrics);

            tcr.State = transferRequest;
            return(tcr);
        }