/// <summary>
        /// Export the error rows (if present).
        /// </summary>
        /// <param name="filepath">The output file (csv)</param>
        /// <param name="output">The specified transformed output</param>
        public void ExportErrorRows(string filepath, AppliedTransform output)
        {
            if (String.IsNullOrEmpty(filepath))
            {
                throw new ArgumentException("Filepath must be specified.", "filepath");
            }

            if (output == null)
            {
                throw new ArgumentException("Applied Transform required.", "output");
            }

            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
            {
                throw new InvalidOperationException("Write operations require an authenticated client.");
            }

            var endpoint     = output.GetErrorRowEndpoint().Replace("{input_schema_id}", output.GetInputSchemaId()).Replace("{output_schema_id}", output.GetOutputSchemaId());
            var errorRowsUri = SodaUri.ForErrorRows(Host, endpoint);

            Debug.WriteLine(errorRowsUri.ToString());
            var downloadRowsRequest = new SodaRequest(errorRowsUri, "GET", null, username, password, SodaDataFormat.CSV, "");
            var result = downloadRowsRequest.ParseResponse <String>();

            System.IO.File.WriteAllText(filepath, result);
        }
        /// <summary>
        /// Apply the source, transforms, and update to the specified dataset.
        /// </summary>
        /// <param name="outputSchema">A string of serialized data.</param>
        /// <param name="revision">A string of serialized data.</param>
        /// <returns>A <see cref="PipelineJob"/> for determining success or failure.</returns>
        public PipelineJob Apply(AppliedTransform outputSchema, Revision revision)
        {
            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
            {
                throw new InvalidOperationException("Write operations require an authenticated client.");
            }

            if (outputSchema == null || revision == null)
            {
                throw new InvalidOperationException("Both the output schema and revision are required.");
            }

            Newtonsoft.Json.Linq.JObject payload = new Newtonsoft.Json.Linq.JObject();
            payload["output_schema_id"] = outputSchema.GetOutputSchemaId();

            var uri = SodaUri.ForSource(Host, revision.GetApplyEndpoint());

            Debug.WriteLine(uri.ToString());
            var    applyRequest = new SodaRequest(uri, "PUT", null, username, password, SodaDataFormat.JSON, payload.ToString());
            Result result       = null;

            try
            {
                result = applyRequest.ParseResponse <Result>();
            }
            catch (WebException webException)
            {
                string message = webException.UnwrapExceptionMessage();
                result = new Result()
                {
                    Message = webException.Message, IsError = true, ErrorCode = message, Data = payload
                };
            }
            catch (Exception ex)
            {
                result = new Result()
                {
                    Message = ex.Message, IsError = true, ErrorCode = ex.Message, Data = payload
                };
            }

            return(new PipelineJob(SodaUri.ForJob(Host, revision.getRevisionLink()), username, password));
        }