protected function getTunnelInfo($open = true)
    {
        if (!isset($this->tunnelInfo)) {
            $this->tunnelInfo = [];
            // @todo move this to State service (in a new major version)
            $filename = $this->config()->getWritableUserDir() . '/tunnel-info.json';
            if (file_exists($filename)) {
                $this->debug(sprintf('Loading tunnel info from %s', $filename));
                $this->tunnelInfo = (array) json_decode(file_get_contents($filename), true);
            }
        }

        if ($open) {
            $needsSave = false;
            foreach ($this->tunnelInfo as $key => $tunnel) {
                /** @noinspection PhpComposerExtensionStubsInspection */
                if (isset($tunnel['pid']) && function_exists('posix_kill') && !posix_kill($tunnel['pid'], 0)) {
                    $this->debug(sprintf(
                        'The tunnel at port %d is no longer open, removing from list',
                        $tunnel['localPort']
                    ));
                    unset($this->tunnelInfo[$key]);
                    $needsSave = true;
                }
            }
            if ($needsSave) {
                $this->saveTunnelInfo();
            }
        }

        return $this->tunnelInfo;
    }