public async Task <IHttpActionResult> PostStop(string uuid)
        {
            //-- Stop recording.
            var path   = String.Format("webapi/uuid_record?{0} stop all", uuid);
            var helper = new FreeSwitchHelper();
            await helper.SendRpc(path, "+OK Success");

            //-- Inform the sides.
            path = String.Format("txtapi/uuid_broadcast?{0}%20ivr/ivr-recording_stopped.wav", uuid);
            await helper.SendRpc(path, "+OK Message sent");

            await Task.Delay(2000); // 1 sec + 1 sec extra

            //-- Hang up the call from the Freeswitch side.
            path = String.Format("webapi/uuid_kill?{0}", uuid);
            await helper.SendRpc(path, "+OK");

            return(StatusCode(HttpStatusCode.NoContent));
        }
        public async Task <IHttpActionResult> PutStart([FromBody] JObject values)
        {
            var learnerSkype = (string)values["learnerSkype"];

            // Make sure the teacher's Skype Name is known. We use it to filter the ongoing calls.
            var sqlTeacher = @"
select SkypeName from dbo.appGetUser(@UserId);
";
            var skypeName  = (await DapperHelper.QueryResilientlyAsync <string>(sqlTeacher, new { UserId = this.GetUserId(), }))
                             .SingleOrDefault();

            if (String.IsNullOrEmpty(skypeName))
            {
                throw new Exception("Please enter your Skype name on the Profile page.");
            }

            // Make sure the learner's Skype Name is known
            var sqlLearner   = @"
select cast(coalesce(dbo.appGetUserIdBySkypeName(@SkypeName), 0) as bit);
";
            var learnerFound = (await DapperHelper.QueryResilientlyAsync <bool>(sqlLearner, new { SkypeName = learnerSkype, }))
                               .SingleOrDefault();

            if (!learnerFound)
            {
                throw new Exception("The Skype name was not found. Ask the learner to enter their Skype name on the Profile page.");
            }

            var helper = new FreeSwitchHelper();

            //-- Find the Skype call. Get the Uuid of the Skype call assigned by Freeswitch.
            var path     = "txtapi/show?calls";
            var response = await helper.SendRpc(path);

            string uuid = null;
            //DateTime? created = null;
            var lines = response.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

            if (lines.Count() > 1)
            {
                var callValues = lines.ElementAt(1).Split(new[] { ',' });
                uuid = callValues[0];
                //var createdValue = DateTime.ParseExact(values[2], "yyyy-MM-dd HH:mm:ss", null);
                // Freeswitch reports the server's local time and it does not report the timezone. We expect the VM's time is UTC (This is the case on Azure.)
                //DateTime.SpecifyKind(createdValue, DateTimeKind.Utc);
                //created = createdValue;
            }
            Guid guid; // uuid is a string which represents a Guid.

            if (!Guid.TryParse(uuid, out guid))
            {
                throw new HttpException("Skype call not found.");
            }

            //-- Play announce
            //path = String.Format("txtapi/uuid_broadcast?{0}%20misc/call_monitoring_blurb.wav", uuid);
            //await helper.SendRpc(path, "+OK Message sent");
            path = String.Format("txtapi/uuid_broadcast?{0}%20ivr/ivr-recording_started.wav", uuid);
            await helper.SendRpc(path, "+OK Message sent");

            // Freeswitch returns 200 OK immidiately, even if the sound will then play longer. Without a delay the announcement will be heard on the recording.
            await Task.Delay(2000); // 3 sec + 1 sec + 1 sec extra

            //-- Start recording
            var sourceDir = ConfigurationManager.AppSettings["Freeswitch.MyRecordingsDir"];

            //  Freeswitch expects a path with forward slash separators. Windows tolerates them as well. We escape the '\' as '\\'.
            sourceDir = sourceDir.Replace('\\', '/');
            var limit = 900; // 15 minutes * 60 = 900 seconds. Limit the maximum recording time.

            path = String.Format("webapi/uuid_record?{0} start '{1}/{0}.wav' {2}", uuid, sourceDir, limit);
            await helper.SendRpc(path, "+OK Success");

            //-- Inject the tone mark at the beginning of the recording. We might use it to correlate the remark spots relativaly to the start.
            // tone_stream://L=1;v=0;%(200,0,1000)
            path = String.Format("txtapi/uuid_broadcast?{0} tone_stream%3A%2F%2FL=1;v=0;%25(200,0,1000)", uuid);
            await helper.SendRpc(path, "+OK Message sent");

            return(Created(uuid, uuid));
        }