public function outboxRequest(IOutbox $outboxNode, RequestInterface $request, ResponseInterface $response)
    {
        $outboxPath = $request->getPath();

        // Parsing the request body
        try {
            $vObject = VObject\Reader::read($request->getBody());
        } catch (VObject\ParseException $e) {
            throw new BadRequest('The request body must be a valid iCalendar object. Parse error: '.$e->getMessage());
        }

        // The incoming iCalendar object must have a METHOD property, and a
        // component. The combination of both determines what type of request
        // this is.
        $componentType = null;
        foreach ($vObject->getComponents() as $component) {
            if ('VTIMEZONE' !== $component->name) {
                $componentType = $component->name;
                break;
            }
        }
        if (is_null($componentType)) {
            throw new BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
        }

        // Validating the METHOD
        $method = strtoupper((string) $vObject->METHOD);
        if (!$method) {
            throw new BadRequest('A METHOD property must be specified in iTIP messages');
        }

        // So we support one type of request:
        //
        // REQUEST with a VFREEBUSY component

        $acl = $this->server->getPlugin('acl');

        if ('VFREEBUSY' === $componentType && 'REQUEST' === $method) {
            $acl && $acl->checkPrivileges($outboxPath, '{'.self::NS_CALDAV.'}schedule-send-freebusy');
            $this->handleFreeBusyRequest($outboxNode, $vObject, $request, $response);

            // Destroy circular references so PHP can GC the object.
            $vObject->destroy();
            unset($vObject);
        } else {
            throw new NotImplemented('We only support VFREEBUSY (REQUEST) on this endpoint');
        }
    }