public int Execute(Execution execution)
        {
            using (var client = new RetryableWebClient())
            {
                var sourcePackage = _packageUrlParser.Parse(execution.PackageUrl);

                RedirectableConsole.WriteLine("Retrieving source package...");
                var metadata = _packageLookup.Lookup(execution.WorkingDirectory, new PackageRequestRef(
                                                         sourcePackage.Uri,
                                                         sourcePackage.GitRef,
                                                         execution.PackagePushPlatform,
                                                         true,
                                                         sourcePackage.IsStaticReference));

                if (metadata.GetProtobuildPackageBinary == null)
                {
                    RedirectableConsole.ErrorWriteLine(
                        "ERROR: URL resolved to a package metadata type '" + metadata.GetType().Name + "', " +
                        "but this type doesn't provide a mechanism to convert to a Protobuild package.");
                }

                string archiveType;
                byte[] archiveData;
                metadata.GetProtobuildPackageBinary(metadata, out archiveType, out archiveData);

                var protobuildPackageMetadata = metadata as ProtobuildPackageMetadata;
                if (protobuildPackageMetadata == null)
                {
                    RedirectableConsole.ErrorWriteLine("--repush requires that the source URL resolve to a Protobuild package");
                    return(1);
                }

                RedirectableConsole.WriteLine("Detected package type as " + archiveType + ".");

                if (execution.PackagePushVersion.StartsWith("hash:", StringComparison.InvariantCulture))
                {
                    var sha1   = new SHA1Managed();
                    var hashed = sha1.ComputeHash(Encoding.ASCII.GetBytes(execution.PackagePushVersion.Substring("hash:".Length)));
                    execution.PackagePushVersion = BitConverter.ToString(hashed).ToLowerInvariant().Replace("-", "");
                }

                RedirectableConsole.WriteLine("Creating new package version...");

                var uploadParameters = new System.Collections.Specialized.NameValueCollection
                {
                    { "__apikey__", execution.PackagePushApiKey },
                    { "version", execution.PackagePushVersion },
                    { "platform", execution.PackagePushPlatform },
                };

                var json = fastJSON.JSON.ToDynamic(
                    System.Text.Encoding.ASCII.GetString(
                        client.UploadValues(execution.PackagePushUrl + "/version/new/api", uploadParameters)));

                if (json.has_error)
                {
                    RedirectableConsole.WriteLine(json.error);
                    return(1);
                }

                var uploadTarget   = (string)json.result.uploadUrl;
                var finalizeTarget = (string)json.result.finalizeUrl;

                RedirectableConsole.WriteLine("Uploading package...");
                this.PushBinary(uploadTarget, archiveData);

                RedirectableConsole.WriteLine("Finalizing package version...");

                var finalizeParameters = new System.Collections.Specialized.NameValueCollection
                {
                    { "__apikey__", execution.PackagePushApiKey },
                    { "archiveType", archiveType },
                };

                json = fastJSON.JSON.ToDynamic(
                    System.Text.Encoding.ASCII.GetString(
                        client.UploadValues(finalizeTarget, finalizeParameters)));

                if (json.has_error)
                {
                    RedirectableConsole.WriteLine(json.error);
                    return(1);
                }

                if (execution.PackagePushBranchToUpdate != null)
                {
                    RedirectableConsole.WriteLine("Updating branch " + execution.PackagePushBranchToUpdate + " to point at new version...");

                    var branchUpdateParameters = new System.Collections.Specialized.NameValueCollection
                    {
                        { "__apikey__", execution.PackagePushApiKey },
                        { "name", execution.PackagePushBranchToUpdate },
                        { "git", execution.PackagePushVersion },
                    };

                    json = fastJSON.JSON.ToDynamic(
                        System.Text.Encoding.ASCII.GetString(
                            client.UploadValues(
                                execution.PackagePushUrl + "/branch/edit/" + execution.PackagePushBranchToUpdate + "/api",
                                branchUpdateParameters)));

                    if (json.has_error)
                    {
                        RedirectableConsole.WriteLine(json.error);
                        return(1);
                    }
                }

                RedirectableConsole.WriteLine("Package version repushed successfully.");
            }
            return(0);
        }
        public int Execute(Execution execution)
        {
            using (var client = new RetryableWebClient())
            {
                var archiveType = this.DetectPackageType(execution.PackagePushFile);

                Console.WriteLine("Detected package type as " + archiveType + ".");

                Console.WriteLine("Creating new package version...");

                if (execution.PackagePushVersion.StartsWith("hash:", StringComparison.InvariantCulture))
                {
                    var sha1   = new SHA1Managed();
                    var hashed = sha1.ComputeHash(Encoding.ASCII.GetBytes(execution.PackagePushVersion.Substring("hash:".Length)));
                    execution.PackagePushVersion = BitConverter.ToString(hashed).ToLowerInvariant().Replace("-", "");
                }

                var uploadParameters = new System.Collections.Specialized.NameValueCollection
                {
                    { "__apikey__", execution.PackagePushApiKey },
                    { "version", execution.PackagePushVersion },
                    { "platform", execution.PackagePushPlatform },
                };

                byte[] versionData;
                try
                {
                    versionData = client.UploadValues(execution.PackagePushUrl + "/version/new/api", uploadParameters);
                }
                catch (WebException ex)
                {
                    var responseData = string.Empty;

                    // Try and get the full response from the server to display in the exception message.
                    try
                    {
                        var stream = ex.Response.GetResponseStream();
                        if (stream != null)
                        {
                            using (var reader = new StreamReader(stream, Encoding.Default, true, 4096, true))
                            {
                                responseData = reader.ReadToEnd();
                            }
                        }
                    }
                    catch (Exception)
                    {
                    }

                    throw new WebException(ex.Message + "  Content of response was: " + responseData);
                }

                var json = fastJSON.JSON.ToDynamic(
                    System.Text.Encoding.ASCII.GetString(
                        versionData));

                if (json.has_error)
                {
                    Console.WriteLine(json.error);

                    if (execution.PackagePushIgnoreOnExisting &&
                        ((string)json.error.ToString()).Contains("Another version already exists with this Git hash and platform"))
                    {
                        return(0);
                    }

                    return(1);
                }

                var uploadTarget   = (string)json.result.uploadUrl;
                var finalizeTarget = (string)json.result.finalizeUrl;

                Console.WriteLine("Uploading package...");
                this.PushBinary(uploadTarget, execution.PackagePushFile);

                Console.WriteLine("Finalizing package version...");

                var finalizeParameters = new System.Collections.Specialized.NameValueCollection
                {
                    { "__apikey__", execution.PackagePushApiKey },
                    { "archiveType", archiveType },
                };

                json = fastJSON.JSON.ToDynamic(
                    System.Text.Encoding.ASCII.GetString(
                        client.UploadValues(finalizeTarget, finalizeParameters)));

                if (json.has_error)
                {
                    Console.WriteLine(json.error);
                    return(1);
                }

                if (execution.PackagePushBranchToUpdate != null)
                {
                    Console.WriteLine("Updating branch " + execution.PackagePushBranchToUpdate + " to point at new version...");

                    var branchUpdateParameters = new System.Collections.Specialized.NameValueCollection
                    {
                        { "__apikey__", execution.PackagePushApiKey },
                        { "name", execution.PackagePushBranchToUpdate },
                        { "git", execution.PackagePushVersion },
                    };

                    json = fastJSON.JSON.ToDynamic(
                        System.Text.Encoding.ASCII.GetString(
                            client.UploadValues(
                                execution.PackagePushUrl + "/branch/edit/" + execution.PackagePushBranchToUpdate + "/api",
                                branchUpdateParameters)));

                    if (json.has_error)
                    {
                        Console.WriteLine(json.error);
                        return(1);
                    }
                }

                Console.WriteLine("Package version pushed successfully.");
            }
            return(0);
        }