public function run(DebuggerClient $client = null, $asDaemon = true)
    {
        $client = $client ?: $this->defaultClient();
        $extSourceContexts = $this->extSourceContext ? [$this->extSourceContext] : [];
        $uniquifier = $this->uniquifier ?: $this->defaultUniquifier();

        do {
            $debuggee = $client->debuggee(null, [
                'uniquifier' => $uniquifier,
                'description' => $this->description,
                'extSourceContexts' => $extSourceContexts,
                'labels' => $this->labels
            ]);

            // If registration with backoff fails, then propagate the exception.
            $backoff = new ExponentialBackoff();
            $backoff->execute(function () use ($debuggee) {
                $debuggee->register();
            });

            try {
                $options = [];
                do {
                    try {
                        $resp = $debuggee->breakpointsWithWaitToken($options);
                        $this->setBreakpoints($debuggee, $resp['breakpoints']);
                        $options['waitToken'] = $resp['nextWaitToken'];
                    } catch (ConflictException $e) {
                        // The hanging GET call returns a 409 (Conflict) response
                        // when the request times out with a status of 'ABORTED'.
                        // In this case, we'll fetch again with the same waitToken.
                    }
                    gc_collect_cycles();
                } while ($asDaemon);
            } catch (ServiceException $e) {
                // For any other ServiceExceptions, re-register and start over.
            }
            gc_collect_cycles();
        } while ($asDaemon);
    }