public function intersect($requestedScopes, $availableScopes = [])
    {
        if ($availableScopes instanceof \Traversable) {
            $availableScopes = iterator_to_array($availableScopes);
        } else if (!is_array($availableScopes)) {
            throw new \InvalidArgumentException(
                'Available scopes has to be array or traversable. But ' . gettype($availableScopes) . ' was given.'
            );
        }

        $intersection = [];

        if (empty($availableScopes)) {
            throw new InvalidArgumentException('Available scopes has to be array of OAuth2\Storage\IScope instances. Empty was given.');
        }

        // validate available scopes
        foreach ($availableScopes as $scope) {
            if (!$scope instanceof IScope) {
                throw new \InvalidArgumentException('Available scopes has to be array of OAuth2\Storage\IScope instances.');
            }
        }

        if (empty($requestedScopes)) {
            return $availableScopes;
        } else if (is_string($requestedScopes)) {
            $requestedScopes = explode(' ', $requestedScopes);
        } else if ($requestedScopes instanceof IScope) {
            $requestedScopes = [$requestedScopes->getId()];
        } else if ($requestedScopes instanceof \Traversable) {
            $requestedScopes = $this->parseScopeArray(iterator_to_array($requestedScopes));
        } else if (is_array($requestedScopes)) {
            $requestedScopes = $this->parseScopeArray($requestedScopes);
        }

        // find intersection
        foreach ($requestedScopes as $requestedScope) {
            foreach ($availableScopes as $index => $availableScope) {
                if ($availableScope->getId() === $requestedScope) {
                    // unset scope from available scopes
                    unset($availableScopes[$index]);
                    $intersection[] = $availableScope;
                    continue 2;
                }
            }

            throw new InvalidScopeException("Scope '$requestedScope' is invalid.");
        }

        return $intersection;
    }