public async Task Execute()
        {
            // hack for testing from a project file
            //var videoFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(this.filePath));
            var videoFile = await StorageFile.GetFileFromPathAsync(this.filePath);
            var videoFileProperties = await videoFile.GetBasicPropertiesAsync();

            // determine number of chunks
            var fileSize = videoFileProperties.Size;
            var totalChunks = (long)((fileSize + CHUNK_SIZE) / CHUNK_SIZE);

            // send chunked upload request
            var chunkedUploadRequest = new ApiRequest("video/uploadchunked/request");
            chunkedUploadRequest.Authenticated = true;
            chunkedUploadRequest.AddJsonContent(new { VideoId = this.videoId, TotalChunks = totalChunks });
            var chunkedUploadRequestResponse = await chunkedUploadRequest.ExecuteAsync();

            // check response
            if (!chunkedUploadRequestResponse)
            {
                if (this.UploadFailed != null)
                    this.UploadFailed.Invoke(this, new EventArgs());

                return;
            }

            // open file for reading
            var newFileStream = await videoFile.OpenReadAsync();
            var videoFileStream = newFileStream.AsStream();
            byte[] buffer = new byte[CHUNK_SIZE];

            // iterate
            if (this.MissingChunks != null)
            {
                foreach (var chunk in this.MissingChunks)
                {
                    videoFileStream.Seek(chunk * CHUNK_SIZE, SeekOrigin.Begin);
                    int readCount = await videoFileStream.ReadAsync(buffer, 0, CHUNK_SIZE);

                    if (readCount > 0)
                    {
                        var uploadChunkRequest = new ApiRequest("video/uploadchunked/upload");
                        uploadChunkRequest.Authenticated = true;
                        uploadChunkRequest.Parameters.Add("VideoId", videoId.ToString());
                        uploadChunkRequest.Parameters.Add("ChunkId", chunk.ToString());
                        uploadChunkRequest.AddByteContent(buffer, 0, readCount);
                        var uploadChunkRequestResponse = await uploadChunkRequest.ExecuteAsync();

                        if (this.Progess != null)
                            this.Progess.Invoke(this, new ApiChunkedVideoUploadProgressEventArgs(chunk + 1, (int)totalChunks));
                    }
                }
            }
            else
            {
                //Parallel.For(0, totalChunks, async i =>
                //{
                //	int readCount = await videoFileStream.ReadAsync(buffer, 0, CHUNK_SIZE);

                //	if (readCount > 0)
                //	{
                //		var uploadChunkRequest = new ApiRequest("video/uploadchunked/upload");
                //		uploadChunkRequest.Authenticated = true;
                //		uploadChunkRequest.Parameters.Add("VideoId", videoId.ToString());
                //		uploadChunkRequest.Parameters.Add("ChunkId", i.ToString());
                //		uploadChunkRequest.AddByteContent(buffer, 0, readCount);
                //		var uploadChunkRequestResponse = await uploadChunkRequest.ExecuteAsync();

                //		if (this.Progess != null)
                //			this.Progess.Invoke(this, new ApiChunkedVideoUploadProgressEventArgs((int)i + 1, (int)totalChunks));
                //	}
                //});

                for (int i = 0; i < totalChunks; i++)
                {
                    int readCount = await videoFileStream.ReadAsync(buffer, 0, CHUNK_SIZE);

                    if (readCount > 0)
                    {
                        var uploadChunkRequest = new ApiRequest("video/uploadchunked/upload");
                        uploadChunkRequest.Authenticated = true;
                        uploadChunkRequest.Parameters.Add("VideoId", videoId.ToString());
                        uploadChunkRequest.Parameters.Add("ChunkId", i.ToString());
                        uploadChunkRequest.AddByteContent(buffer, 0, readCount);
                        var uploadChunkRequestResponse = await uploadChunkRequest.ExecuteAsync();

                        if (this.Progess != null)
                            this.Progess.Invoke(this, new ApiChunkedVideoUploadProgressEventArgs(i + 1, (int)totalChunks));
                    }
                }
            }

            // fire upload complete event
            if (this.UploadComplete != null)
                this.UploadComplete.Invoke(this, new EventArgs());
        }