private function startServer()
    {
        if ($this->resource !== null) {
            return;
        }

        $this->writeln(PHP_EOL);
        $this->writeln('Starting PhantomJS Server.');

        $command = $this->getCommand();

        if ($this->config['debug']) {
            $this->writeln(PHP_EOL);

            // Output the generated command.
            $this->writeln('Generated PhantomJS Command:');
            $this->writeln($command);
            $this->writeln(PHP_EOL);
        }

        $descriptorSpec = [
            ['pipe', 'r'],
            ['file', $this->getLogDir() . 'phantomjs.output.txt', 'w'],
            ['file', $this->getLogDir() . 'phantomjs.errors.txt', 'a'],
        ];

        $this->resource = proc_open($command, $descriptorSpec, $this->pipes, null, null, ['bypass_shell' => true]);

        if (!is_resource($this->resource) || !proc_get_status($this->resource)['running']) {
            proc_close($this->resource);
            throw new ExtensionException($this, 'Failed to start PhantomJS server.');
        }

        // Wait till the server is reachable before continuing.
        $max_checks = 10;
        $checks = 0;

        $this->write('Waiting for the PhantomJS server to be reachable.');
        while (true) {
            if ($checks >= $max_checks) {
                throw new ExtensionException($this, 'PhantomJS server never became reachable.');
            }

            $fp = @fsockopen('127.0.0.1', $this->config['port'], $errCode, $errStr, 10);
            if ($fp) {
                $this->writeln('');
                $this->writeln('PhantomJS server now accessible.');
                fclose($fp);
                break;
            }

            $this->write('.');
            $checks++;

            // Wait before checking again.
            sleep(1);
        }

        // Clear progress line writing.
        $this->writeln('');
    }