/// <inheritdoc/>
        public async Task <StorageObject> CopyStorageObject(StorageObject obj, string destinationContainerName, string destinationObjectName = null)
        {
            obj.AssertIsNotNull("obj", "Cannot create a null storage object.");
            obj.ContainerName.AssertIsNotNullOrEmpty("obj.ContainerName", "Cannot copy a storage object with a null or empty container name.");
            obj.Name.AssertIsNotNullOrEmpty("obj.Name", "Cannot copy a storage object without a name.");
            destinationContainerName.AssertIsNotNullOrEmpty("destinationContainerName", "Cannot copy a storage object to a null or empty destination container name.");

            string localDestinationObjectName = null;

            if (!string.IsNullOrEmpty(destinationObjectName))
            {
                localDestinationObjectName = destinationObjectName;
            }
            else
            {
                localDestinationObjectName = obj.FullName;
            }

            var client = this.GetRestClient();
            var resp   = await client.CopyObject(obj.ContainerName, obj.FullName, destinationContainerName, localDestinationObjectName);

            if (resp.StatusCode != HttpStatusCode.Created)
            {
                throw new InvalidOperationException(string.Format("Failed to copy storage object '{0}'. The remote server returned the following status code: '{1}'.", obj.Name, resp.StatusCode));
            }

            var converter = this.ServiceLocator.Locate <IStorageObjectPayloadConverter>();
            var respObj   = converter.Convert(obj.ContainerName, obj.FullName, resp.Headers);

            return(respObj);
        }
        /// <inheritdoc/>
        public async Task<StorageObject> CopyStorageObject(StorageObject obj, string destinationContainerName, string destinationObjectName = null)
        {
            obj.AssertIsNotNull("obj", "Cannot create a null storage object.");
            obj.ContainerName.AssertIsNotNullOrEmpty("obj.ContainerName", "Cannot copy a storage object with a null or empty container name.");
            obj.Name.AssertIsNotNullOrEmpty("obj.Name", "Cannot copy a storage object without a name.");
            destinationContainerName.AssertIsNotNullOrEmpty("destinationContainerName", "Cannot copy a storage object to a null or empty destination container name.");

            string localDestinationObjectName = null;

            if(!string.IsNullOrEmpty(destinationObjectName))
            {
                localDestinationObjectName = destinationObjectName;
            }
            else
            {
                localDestinationObjectName = obj.FullName;
            }
            
            var client = this.GetRestClient();
            var resp = await client.CopyObject(obj.ContainerName, obj.FullName, destinationContainerName, localDestinationObjectName);

            if (resp.StatusCode != HttpStatusCode.Created)
            {
                throw new InvalidOperationException(string.Format("Failed to copy storage object '{0}'. The remote server returned the following status code: '{1}'.", obj.Name, resp.StatusCode));
            }

            var converter = this.ServiceLocator.Locate<IStorageObjectPayloadConverter>();
            var respObj = converter.Convert(obj.ContainerName, obj.FullName, resp.Headers);

            return respObj;
        }
        /// <inheritdoc/>
        public async Task UpdateStorageObject(StorageObject obj)
        {
            obj.AssertIsNotNull("container", "Cannot update a storage object with a null object.");

            var client = this.GetPocoClient();
            await client.UpdateStorageObject(obj);
        }
        /// <inheritdoc/>
        public async Task <StorageObject> CreateStorageObject(StorageObject obj, Stream content)
        {
            obj.AssertIsNotNull("obj", "Cannot create a null storage object.");
            obj.ContainerName.AssertIsNotNullOrEmpty("obj.ContainerName", "Cannot create a storage object with a null or empty container name.");
            obj.Name.AssertIsNotNullOrEmpty("obj.Name", "Cannot create a storage object without a name.");

            var contentLength = content.Length;
            var client        = this.GetRestClient();
            var resp          = await client.CreateObject(obj.ContainerName, obj.FullName, obj.Metadata, content);

            if (resp.StatusCode != HttpStatusCode.Created)
            {
                throw new InvalidOperationException(string.Format("Failed to create storage object '{0}'. The remote server returned the following status code: '{1}'.", obj.Name, resp.StatusCode));
            }

            var converter = this.ServiceLocator.Locate <IStorageObjectPayloadConverter>();
            var respObj   = converter.Convert(obj.ContainerName, obj.FullName, resp.Headers, contentLength);

            return(respObj);
        }
        /// <inheritdoc/>
        public async Task<StorageObject> CreateStorageObject(StorageObject obj, Stream content)
        {
            obj.AssertIsNotNull("obj", "Cannot create a null storage object.");
            obj.ContainerName.AssertIsNotNullOrEmpty("obj.ContainerName", "Cannot create a storage object with a null or empty container name.");
            obj.Name.AssertIsNotNullOrEmpty("obj.Name","Cannot create a storage object without a name.");
            
            var contentLength = content.Length;
            var client = this.GetRestClient();
            var resp = await client.CreateObject(obj.ContainerName, obj.FullName, obj.Metadata, content);

            if (resp.StatusCode != HttpStatusCode.Created)
            {
                throw new InvalidOperationException(string.Format("Failed to create storage object '{0}'. The remote server returned the following status code: '{1}'.", obj.Name, resp.StatusCode));
            }

            var converter = this.ServiceLocator.Locate<IStorageObjectPayloadConverter>();
            var respObj = converter.Convert(obj.ContainerName, obj.FullName, resp.Headers, contentLength);

            return respObj;
        }
        /// <inheritdoc/>
        public async Task UpdateStorageObject(StorageObject obj)
        {
            obj.AssertIsNotNull("container", "Cannot update a storage object with a null object.");

            var client = this.GetPocoClient();
            await client.UpdateStorageObject(obj);
        }