public function can($action, $resource, $resourceValue = null)
    {
        if (is_object($resource)) {
            $resourceValue = $resource;
            $resource = get_classname($resourceValue);
        } elseif (is_array($resource)) {
            // Nested resources can be passed through an associative array, this way conditions which are
            // dependent upon the association will work when using a class.
            $resourceValue = head(array_values($resource));
            $resource = head(array_keys($resource));
        }

        // The conditional callback (Closure) is only evaluated when an actual instance object is present.
        // It is not evaluated when checking permissions on the class name (such as in the 'index' action).
        $skipConditions = false;
        if (is_string($resource) && ! is_object($resourceValue) && $this->hasCondition($action, $resource)) {
            $skipConditions = true;
        }

        $self = $this;
        $rules = $this->getRulesFor($action, $resource);

        if (! $rules->isEmpty()) {
            $allowed = array_reduce($rules->all(), function ($result, $rule) use ($self, $resourceValue, $skipConditions) {
                if ($skipConditions) {
                    return $rule->getBehavior(); // Short circuit
                } else {
                    if ($rule->isRestriction()) {
                        // 'deny' rules override prior rules.
                        $result = $result && $rule->isAllowed($self, $resourceValue);
                    } else {
                        // 'allow' rules do not override prior rules but instead are logically or'ed.
                        // Unlike Authority default behavior.
                        $result =  $result || $rule->isAllowed($self, $resourceValue);
                    }
                }

                return $result;
            }, false);
        } else {
            $allowed = false;
        }

        return $allowed;
    }