protected function resolveValue(Config $config, $key)
    {
        $value = $config->getRequired($key);
        if (is_array($value)) {
            throw new KeyException(sprintf('Referenced configuration key "%s" must not be an array.', $key));
        }

        if (in_array($key, $this->referenceStack)) {
            throw new KeyException(sprintf('Circular reference detected resolving configuration key "%s"', $key));
        }
        $this->referenceStack[] = $key;

        preg_match_all('/%([^%]+)%/', $value, $matches);
        if (!$matches) {
            return;
        }

        foreach ($matches[1] as $referenceKey) {
            $replacement = $this->resolveValue($config, $referenceKey);
            $value = str_replace('%'.$referenceKey.'%', $replacement, $value);
        }
        array_pop($this->referenceStack);

        return $value;
    }