protected static function parseServerVariables() {
        $env = static::defaultEnvironment();

        // REQUEST_METHOD.
        $env['REQUEST_METHOD'] = val('REQUEST_METHOD', $_SERVER) ?: 'CONSOLE';

        // SCRIPT_NAME: This is the root directory of the application.
        $script_name = rtrim_substr($_SERVER['SCRIPT_NAME'], 'index.php');
        $env['SCRIPT_NAME'] = rtrim($script_name, '/');

        // PATH_INFO.
        $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';

        // Strip the extension from the path.
        list($path, $ext) = static::splitPathExt($path);
        $env['PATH_INFO'] = '/' . ltrim($path, '/');
        $env['EXT'] = $ext;

        // QUERY.
        $get = $_GET;
        $env['QUERY'] = $get;

        // SERVER_NAME.
        $host = array_select(
            ['HTTP_X_FORWARDED_HOST', 'HTTP_HOST', 'SERVER_NAME'],
            $_SERVER
        );
        list($host) = explode(':', $host, 2);
        $env['SERVER_NAME'] = $host;

        // HTTP_* headers.
        $env = array_replace($env, static::extractHeaders($_SERVER));

        // URL_SCHEME.
        $url_scheme = 'http';
        // Web server-originated SSL.
        if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
            $url_scheme = 'https';
        }
        $url_scheme = array_select([
            'HTTP_X_ORIGINALLY_FORWARDED_PROTO', // varnish modifies the scheme
            'HTTP_X_FORWARDED_PROTO' // load balancer-originated (and terminated) ssl
        ], $_SERVER, $url_scheme);
        $env['URL_SCHEME'] = $url_scheme;

        // SERVER_PORT.
        $server_port = (int)val('SERVER_PORT', $_SERVER, $url_scheme === 'https' ? 443 :80);
        $env['SERVER_PORT'] = $server_port;

        // INPUT: The entire input.
        // Input stream (readable one time only; not available for multipart/form-data requests)
        switch (val('CONTENT_TYPE', $env)) {
            case 'application/json':
                $input_raw = @file_get_contents('php://input');
                $input = @json_decode($input_raw, true);
                break;
            default:
                $input = $_POST;
                $input_raw = null;
                break;
        }
        $env['INPUT'] = $input;
        $env['INPUT_RAW'] = $input_raw;

        // IP Address.
        // Load balancers set a different ip address.
        $ip = array_select(
            ['HTTP_X_ORIGINALLY_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'],
            $_SERVER,
            '127.0.0.1'
        );
        $env['REMOTE_ADDR'] = force_ipv4($ip);
        return $env;
    }