code: protected function readConfiguration()
      {
          // Return if already loaded
          if (is_array($this->config)) {
              return;
          }
          
          $fileName = $this->dir . static::CONFIG_FILE;
          
          // Abort if the file doesn't exist
          if (!file_exists($fileName)) {
              $this->config = $this->validateConfiguration();
              return;
          }
          
          $modifyTime = filemtime($fileName);
          if (false === $modifyTime) {
              throw new \RuntimeException("Unable to get mtime of the configuration file.");
          }
          
          // Check if the configuration is in cache
          $cacheKey = md5($fileName);
          if ($this->cache->has($cacheKey)) {
              $this->config=$this->cache->get($cacheKey);
              
              // Cached file is up to date
              if ($this->config["_mtime"] === $modifyTime) {
                  return;
              }
          }
  
          if (($yaml = self::readFile($fileName)) !== false) {
              $config = \Symfony\Component\Yaml\Yaml::parse($yaml);
              $this->config = $this->validateConfiguration($config);
          } else {
              throw new \RuntimeException("Unable to read configuration file.");
          }
          
          // Save to cache with updated modify-time
          $storedConfig = $this->config;
          $storedConfig["_mtime"]= $modifyTime;
          $this->cache->set($cacheKey, $storedConfig);
      }
docs: Initializes the configuration array
  
  If the file exists, tries to read from the cache first, if the cache
  has the data, but the file is newer, reads the file and renews the cache.
  
  md5 is used as a cache key, because some cache providers may not accept
  characters present in the file path.
  Collisions or reversibility do not present security concerns.
  
  @throws \RuntimeException On file read error