public function run($api_key, $metadata, $upload_data)
    {
        $parts = $this->createParts($api_key, $metadata, $upload_data);

        // upload parts
        $result = $this->processParts($parts);

        // parts uploaded, register complete and wait for acceptance
        $wait_attempts = FilestackConfig::UPLOAD_WAIT_ATTEMPTS;
        $wait_time = FilestackConfig::UPLOAD_WAIT_SECONDS;
        $accepted_code = HttpStatusCodes::HTTP_ACCEPTED;

        $completed_status_code = $accepted_code;
        $completed_result = ['status_code' => 0, 'filelink' => []];

        while ($completed_status_code == $accepted_code &&
          $wait_attempts > 0) {

            $completed_result = $this->registerComplete($api_key, $result,
                          $upload_data, $metadata);

            $completed_status_code = $completed_result['status_code'];
            if ($completed_status_code == $accepted_code) {
              sleep($wait_time);
            }
            $wait_attempts--;
        }

        return $completed_result;
    }