public function resolve($path, $absolute = true)
    {
        $path = $this->normalizeName($path);

        if (isset($this->paths[$path])) {
            $path = $this->paths[$path];
        }

        $path = preg_replace_callback('#%(.+)%#', function ($match) use ($path) {
            $alias = $match[1];

            if (!isset($this->paths[$this->normalizeName($alias)])) {
                throw new PathResolutionException("Failed to resolve path. Alias %$alias% is not defined.");
            }

            // absolute if alias is at start of path
            $absolute = strpos($path, "%$alias%") === 0;

            if (isset($this->resolving[$alias])) {
                throw new PathResolutionException('Failed to resolve path. Infinite recursion detected.');
            }

            $this->resolving[$alias] = true;
            try {
                return $this->resolve($alias, $absolute);
            } finally {
                unset($this->resolving[$alias]);
            }
        }, $path);

        if ($absolute && Path::isRelative($path)) {
            $path = Path::makeAbsolute($path, $this->paths['root']);
        }

        // Not necessary, could remove.
        $path = Path::canonicalize($path);

        return $path;
    }