private static function composeMailMessage($loggable, $level, array &$context) {
        if (!key_exists('cliMessage', $context))
            self::composeCliMessage($loggable, $level, $context);

        $msg = $context['cliMessage'];
        if (key_exists('cliExtra', $context))
            $msg .= $context['cliExtra'];
        $location = null;

        // compose message
        if (CLI) {
            $msg     .= NL.NL.'Shell:'.NL.'------'.NL.print_r(ksort_r($_SERVER), true).NL;
            $location = realpath($_SERVER['PHP_SELF']);
        }
        else {
            $request  = Request::me();
            $location = strLeftTo($request->getUrl(), '?');
            $session  = null;

            if (isset($_SESSION)) {
                $session = $_SESSION;
            }
            else if ($request->hasSessionId()) {
                $request->getSession($suppressHeadersAlreadySentError = true);
                if (session_id() == $request->getSessionId())       // if both differ the id was regenerated and
                    $session = $_SESSION;                           // the session is empty
            }
            $session  = is_null($session) ? null : print_r(ksort_r($session), true);
            $ip       = $_SERVER['REMOTE_ADDR'];
            $host     = NetTools::getHostByAddress($ip);
            if ($host != $ip)
                $ip .= ' ('.$host.')';
            $msg .= NL.NL.'Request:'.NL.'--------'.NL.$request.NL.NL
              . 'Session: '.($session ? NL.'--------'.NL.$session : '(none)'.NL.'--------'.NL).NL.NL
              . 'Server:'.NL.'-------'.NL.print_r(ksort_r($_SERVER), true).NL.NL
              . 'IP:   '.$ip.NL
              . 'Time: '.date('Y-m-d H:i:s').NL;
        }
        $type = ($loggable instanceof \Exception && key_exists('unhandled', $context)) ? 'Unhandled Exception ':'';

        // store subject and message
        $context['mailSubject'] = 'PHP ['.self::$logLevels[$level].'] '.$type.(CLI ? 'in ':'at ').$location;
        $context['mailMessage'] = $msg;
    }