public function start()
    {
        try {
            /* raw input handler */
            $raw = file_get_contents(php_sapi_name() === 'cli' ? 'php://stdin' : 'php://input');
            if ($this->rawInputHandler !== null) {
                call_user_func($this->rawInputHandler, $raw);
            }
            /* parse the incoming request */
            $request = new Request($raw);
            /* find the CallFlow */
            if (array_key_exists($request->app, $this->cf)) {
                $cf = $this->cf[$request->app];
            } elseif (array_key_exists('*', $this->cf)) {
                $cf = $this->cf['*'];
            } else {
                throw new \Exception("CallFlow for '{$request->app}' Not Found", 404);
            }
            /* call the previous callback. if response is null, we just received a HANGUP */
            if (($label = $cf->callback($request)) !== null) {
                /* call the next label */
                $response = $cf->execute($label);
                /* output response */
                echo $response->getJSON();
            }
        } catch (\Exception $e) {
            /* if an exception is thrown, we reply with an HTTP error */
            echo $this->httpError($e->getMessage(), $e->getCode());
        }
        $output = ob_get_contents();
        /* raw output handler */
        if ($this->rawOutputHandler !== null) {
            call_user_func($this->rawOutputHandler, $output);
        }
        /* Content-Type */
        header('Content-Type: '.self::CONTENT_TYPE);
        /* flush output buffer */
        ob_end_flush();
    }