public function buildCache()
    {
        if ($this->cache === null)
            throw new \LogicException("Cannot build cache without a cache instance");
        
        $this->cache->set('cache_built', false);
        $this->cache->set('classpaths', array());
        
        $stack = array($this->root_namespace);
        
        while (!empty($stack))
        {
            $ref = array_pop($stack);
            foreach ($ref['loaders'] as $loader)
            {
                if ($loader['std'] !== Autoloader::PSR4)
                    throw new \LogicException("Cache builder only works with pure PSR4-based namespaces");

                $class_count = 0;
                $root = $loader['path'] . DIRECTORY_SEPARATOR;
                $ns = $loader['ns'];
                $php_files = self::findSourceFiles($loader['path']);
                foreach ($php_files as $file)
                {
                    $rel_file = substr($file, strlen($root));

                    // Store absolute resolved paths when not using stream wrappers
                    if (strpos($file, '://') === false) $file = realpath($file);
                    $parts = explode(DIRECTORY_SEPARATOR, $rel_file);
                    $class_name = substr($ns . implode('\\', $parts), 0, -4);
                    if ($this->cache->has('classpaths', $class_name))
                    {
                        $conflict = $this->cache->get('classpaths', $class_name);
                        throw new \LogicException(sprintf(
                            "Duplicate class definition in file %s and %s (conflicting namespace: %s)", 
                            $file,
                            $conflict,
                            $ns
                        ));
                    }

                    $this->cache->set('classpaths', $class_name, $file);
                    ++$class_count;
                }
                self::getLogger()->info('Found {0} classes in namespace {1}', [$class_count, $ns]);
            }

            foreach ($ref['sub_ns'] as $sub_ns)
                array_push($stack, $sub_ns);
        }

        $this->cache->set('cache_built', true);
        self::getLogger()->info('Class cache built');
    }