public function dispatch(Request $request)
    {
        // determine resource
        $resourceParts = explode('/', $request->getResource());
        $resourceName = $resourceParts[0];
        $subResourceName = false;
        if (count($resourceParts) > 1) {
            $subResourceName = $resourceParts[1];
        }

        try {
            $resourceMetadata = $this->resourceMetadataFactory->getMetadataByResourceName($resourceName);
        } catch (ResourceMappingException $e) {
            throw Exception::resourceNotFound($resourceName, 404, $e);
        }

        // determine service
        if ($subResourceName) {
            if (!$resourceMetadata->hasSubResource($subResourceName)) {
                throw Exception::resourceNotFound($request->getResource());
            }

            $subResourceMapping = $resourceMetadata->getSubResource($subResourceName);
            $service = $this->serviceLocator->get($subResourceMapping['service']);
        } else {
            $service = $this->serviceLocator->get($resourceMetadata->getService());
        }

        $this->registerListeners($service);

        $event = new RequestEvent();
        $event->setRequest($request);

        $this->eventManager->dispatch($request->getMethod(), $event);

        return $event->getData();
    }