private function createProjectContext($rootDir, $env)
    {
        Assert::fileExists($rootDir, 'Could not load Puli context: The root %s does not exist.');
        Assert::directory($rootDir, 'Could not load Puli context: The root %s is a file. Expected a directory.');

        $baseConfig = new DefaultConfig();
        $homeDir = self::parseHomeDirectory();

        if (null !== $configFile = $this->loadConfigFile($homeDir, $baseConfig)) {
            $baseConfig = $configFile->getConfig();
        }

        // Create a storage without the factory manager
        $jsonStorage = new JsonStorage(
            $this->getStorage(),
            new JsonConverterProvider($this),
            $this->getJsonEncoder(),
            $this->getJsonDecoder()
        );

        $rootDir = Path::canonicalize($rootDir);
        $rootFilePath = $this->rootDir.'/puli.json';

        try {
            $rootModuleFile = $jsonStorage->loadRootModuleFile($rootFilePath, $baseConfig);
        } catch (FileNotFoundException $e) {
            $rootModuleFile = new RootModuleFile(null, $rootFilePath, $baseConfig);
        }

        $config = new EnvConfig($rootModuleFile->getConfig());

        return new ProjectContext($homeDir, $rootDir, $config, $rootModuleFile, $configFile, $this->dispatcher, $env);
    }