private function initialize($request = null)
    {
        // Store a reference to the database object
        // so the database connection can be reused during tests
        $this->oldDb = null;
        if (isset($this->app['db']) && $this->app['db']->connection()) {
            $this->oldDb = $this->app['db'];
        }

        if (class_exists(Facade::class)) {
            // If the container has been instantiated ever,
            // we need to clear its static fields before create new container.
            Facade::clearResolvedInstances();
        }

        $this->app = $this->kernel = require $this->module->config['bootstrap_file'];
        
        // in version 5.6.*, lumen introduced the same design pattern like Laravel
        // to load all service provider we need to call on Laravel\Lumen\Application::boot()
        if (method_exists($this->app, 'boot')) {
            $this->app->boot();
        }
        // Lumen registers necessary bindings on demand when calling $app->make(),
        // so here we force the request binding before registering our own request object,
        // otherwise Lumen will overwrite our request object.
        $this->app->make('request');

        $request = $request ?: SymfonyRequest::create($this->module->config['url']);
        $this->app->instance('Illuminate\Http\Request', Request::createFromBase($request));

        // Reset the old database if there is one
        if ($this->oldDb) {
            $this->app->singleton('db', function () {
                return $this->oldDb;
            });
            Model::setConnectionResolver($this->oldDb);
        }

        $this->module->setApplication($this->app);
    }