public function save($name, $content, $cacheRule = null, $cacheTagsAppend = [])
    {
        // initialize log
        $log = new DebugLog();
        $log->addMessage('State', 'Save');

        // check if get
        if (!isset($_SERVER['REQUEST_METHOD']) || strtolower($_SERVER['REQUEST_METHOD']) != 'get') {
            $log->addMessage('CacheRule-Match', 'Only GET requests can be cached.');

            return false;
        }

        // get rule
        if (!($rule = $this->getMatchedRule($cacheRule)) || $rule->getCacheRule()->getTtl() <= 0) {
            $log->addMessage('CacheRule-Match', 'No rule matched the request.');

            return false;
        }
        $log->addMessage('CacheRule-Match', sprintf('%s rule matched the request.', $rule->getCacheRule()->getName()));

        // append tags
        $rule->getCacheRule()->appendTags($cacheTagsAppend);

        // create key
        $key = $this->createJointKey($name, $rule->getCacheKey());

        // create save payload instance
        $savePayload = new SavePayload($key, $content, $rule);

        // callback: beforeSave
        foreach ($this->callbacks as $cb) {
            call_user_func_array([$cb, 'beforeSave'], [$savePayload]);
        }

        // check if a callback set the save flag to false
        if(!$savePayload->getSaveFlag()){
            return false;
        }

        $log->addMessage('CacheRule-CacheKey', $savePayload->getKey());
        $saved = $this->cacheStorage->save($savePayload->getKey(), $savePayload->getContent(),
            $savePayload->getRule()->getCacheRule()->getTtl());

        // update the index
        if ($saved) {
            $this->indexStorage->save($savePayload->getKey(), $savePayload->getRule()->getCacheRule()->getTags(),
                ($savePayload->getRule()->getCacheRule()->getTtl()));
            $log->addMessage('CacheStorage-Save', 'Cache saved.');
        } else {
            throw new HrcException('There has been an error while trying to save the cache.');
        }

        $this->log = $log;

        // when saved, return cache key
        // callback: afterSave
        foreach ($this->callbacks as $cb) {
            call_user_func_array([$cb, 'afterSave'], [$savePayload]);
        }

        return $savePayload->getKey();
    }