//Creates a file on Google Drive and uses the specified stream to fill it with data.
            //This should be used for data that is 5MB or less.
            public async Task <GFile> UploadFile(GFile fileMetadata, Stream fileData, IProgress <int> progress)
            {
                //Create the message to send.
                HttpRequestMessage message = new HttpRequestMessage();

                message.Method = HttpMethod.Post;
                //Use the content upload url.
                message.RequestUri = new Uri("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
                                             + "&fields=" + GFile.FileMetadataFields());

                //Create JSON that represents the Google Drive file metadata.
                var jsonText = GFile.ToJObject(fileMetadata).ToString();

                //JSON file metadata content part.
                var metadataContent = new StringContent(jsonText, Encoding.UTF8);

                metadataContent.Headers.ContentLength = Encoding.UTF8.GetByteCount(jsonText);
                metadataContent.Headers.ContentType   = MediaTypeHeaderValue.Parse("application/json; charset=UTF-8");

                //Streaming file bytes content.
                var fileContent = new StreamContent(fileData);

                fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/zip");

                //Create the content for the HTTP request. This content must be multipart content, where the first
                //part is the file metadata JSON, split it using the boundary string "content_separator", and then
                //the next part is the data in the stream. Note I have no idea what the subtype parameter is supposed
                //to do. generic_subtype is just a random value, and it works, so I'll leave it like that.
                var mainContent = new MultipartContent("generic_subtype", "content_separator");

                //Add the metadata.
                mainContent.Add(metadataContent);
                //Add the file data.
                mainContent.Add(fileContent);
                //Specify the content type. Notice the boundary specified in the constructor should also be specified
                //here as well.
                mainContent.Headers.ContentType =
                    MediaTypeHeaderValue.Parse("multipart/related; boundary=content_separator");

                //Add the multipart content to the actual message.
                message.Content = mainContent;

                //Attempt to upload the file.
                var result = await _client.SendAuthorizedRequestMessage(message, progress);

                if (_client.LastError != OAuthClientResult.Success)
                {
                    return(null);
                }

                try
                {
                    return(GFile.FromJObject(JObject.Parse(result)));
                }
                catch (Exception)
                {
                    //An exception means parsing failed for some reason. Return null.
                    return(null);
                }
            }
            public static List <GFile> FromJArray(JArray arrObj)
            {
                //Loop through each object in this array. Each object is a file.
                var files = new List <GFile>();

                foreach (var fileObj in arrObj)
                {
                    files.Add(GFile.FromJObject((JObject)fileObj));
                }

                return(files);
            }
            //Creates a folder on Google Drive, and returns a GFile representing the folder.
            //Set parentFolderId to "root" to specify the root folder as the parent.
            public async Task <GFile> CreateFolder(string name, string description, string parentFolderId)
            {
                //Construct a request message to send.
                HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post,
                                                                    "https://www.googleapis.com/drive/v3/files?fields=" + GFile.FileMetadataFields());
                //The parameters for the folder must be provided in the message body as JSON.
                JObject folderData = new JObject();

                folderData["name"]        = name;
                folderData["description"] = description;
                folderData["mimeType"]    = "application/vnd.google-apps.folder";
                //The following makes JSON that looks like this. [{"id": "parentFolderId"}]
                JArray parentArr = new JArray();

                parentArr.Add(new JObject()
                {
                    ["id"] = parentFolderId
                });
                folderData["parents"] = parentArr;
                //Convert the JSON to a string.
                string json = folderData.ToString();

                //Create the content.
                StringContent content = new StringContent(json, Encoding.UTF8);

                content.Headers.ContentLength = Encoding.UTF8.GetByteCount(json);
                content.Headers.ContentType   = MediaTypeHeaderValue.Parse("application/json; charset=UTF-8");
                message.Content = content;

                //Send the create folder command.
                var result = await _client.SendAuthorizedRequestMessage(message);

                if (_client.LastError != OAuthClientResult.Success)
                {
                    return(null);
                }

                //Try to parse the returned data.
                try
                {
                    return(GFile.FromJObject(JObject.Parse(result)));
                }
                catch (Exception)
                {
                    //Just return null. The error at this point is a parsing issue.
                    return(null);
                }
            }
            //Create an empty file on Google Drive, and returns a GFile representing the file.
            //Note that this does not upload any data, only creates an empty file.
            public async Task <GFile> CreateFile(GFile fileMetadata)
            {
                //Create the message to send.
                HttpRequestMessage message = new HttpRequestMessage();

                //Use the metadata only url.
                message.RequestUri = new Uri("https://www.googleapis.com/drive/v3/files?fields="
                                             + GFile.FileMetadataFields());
                message.Method = HttpMethod.Post;

                //Create JSON that represents the Google Drive file metadata.
                var jsonText = GFile.ToJObject(fileMetadata).ToString();

                //Create the content using the file metadata, converted to a JSON object.
                StringContent content = new StringContent(jsonText, Encoding.UTF8);

                content.Headers.ContentLength = Encoding.UTF8.GetByteCount(jsonText);
                content.Headers.ContentType   = MediaTypeHeaderValue.Parse("application/json; charset=UTF-8");

                //Send the create file command.
                var result = await _client.SendAuthorizedRequestMessage(message);

                if (_client.LastError != OAuthClientResult.Success)
                {
                    return(null);
                }

                try
                {
                    return(GFile.FromJObject(JObject.Parse(result)));
                }
                catch (Exception)
                {
                    //Parsing issue.
                    return(null);
                }
            }