/// <summary>
        /// Reads a binary file from the mount service and writes it into a memory stream
        /// </summary>
        /// <param name="filename">Relative path to the file on the mount service</param>
        /// <param name="readReaderPort">Response port</param>
        /// <returns></returns>
        private IEnumerator <ITask> ReadFileFromMountService(string filename, FileReaderPort readReaderPort)
        {
            if (string.IsNullOrEmpty(filename))
            {
                Exception exception = new ArgumentException(
                    "Cannot read file from mount service. No filename specified"
                    );
                LogWarning(exception);
                readReaderPort.Post(exception);
                yield break;
            }

            // Construct URI to file
            string fileUri = "http://localhost" + ServicePaths.MountPoint;

            if (!filename.StartsWith("/"))
            {
                fileUri += "/";
            }
            fileUri += filename;

            // Establish channel with mount service
            mnt.MountServiceOperations mountPort = ServiceForwarder <mnt.MountServiceOperations>(fileUri);

            // Set up byte query
            mnt.QueryBytesRequest queryBytesRequest = new mnt.QueryBytesRequest();
            mnt.QueryBytes        queryBytes        = new mnt.QueryBytes(queryBytesRequest);
            queryBytesRequest.Offset = 0;
            queryBytesRequest.Length = MountServiceReadBlockSize;

            // Read file in blocks from mount service
            MemoryStream memoryStream = new MemoryStream();
            int          bytesRead    = (int)queryBytesRequest.Length;

            while (bytesRead == queryBytesRequest.Length)
            {
                mountPort.Post(queryBytes);
                yield return((Choice)queryBytes.ResponsePort);

                Fault fault = (Fault)queryBytes.ResponsePort;
                if (fault != null)
                {
                    LogWarning(fault.ToException());
                    readReaderPort.Post(fault.ToException());
                    yield break;
                }

                mnt.QueryBytesResponse byteQueryResponse = (mnt.QueryBytesResponse)queryBytes.ResponsePort;

                bytesRead = byteQueryResponse.Data.Length;
                memoryStream.Write(byteQueryResponse.Data, 0, bytesRead);
                queryBytesRequest.Offset += bytesRead;
            }
            memoryStream.Position = 0;

            readReaderPort.Post(memoryStream);
        }
        /// <summary>
        /// Loads a grammar into the speech recognition engine; MUST run exclusive
        /// </summary>
        /// <param name="request">Request that contains the new grammar to load</param>
        /// <param name="response">Response port</param>
        /// <returns></returns>
        private IEnumerator <ITask> LoadGrammar(LoadGrammarRequest request, SuccessFailurePort response)
        {
            #region Build grammar
            // Build grammar
            if (request.GrammarType == GrammarType.Srgs)
            {
                // Load SRGS grammar file
                FileReaderPort fileReaderPort = new FileReaderPort();
                yield return(new IterativeTask(delegate
                {
                    return ReadFileFromMountService(request.SrgsFileLocation, fileReaderPort);
                }));

                Exception fileReaderException = (Exception)fileReaderPort;
                if (fileReaderException != null)
                {
                    LogWarning(fileReaderException);
                    response.Post(fileReaderException);
                    yield break;
                }

                try
                {
                    grammarToLoad = GrammarUtilities.BuildSrgsGrammar((MemoryStream)fileReaderPort);
                }
                catch (Exception ex)
                {
                    LogWarning(ex);
                    response.Post(ex);
                    yield break;
                }
            }
            else
            {
                // Build dictionary-style grammar
                try
                {
                    grammarToLoad = GrammarUtilities.BuildDictionaryGrammar(request.DictionaryGrammar);
                }
                catch (Exception ex)
                {
                    LogWarning(ex);
                    response.Post(ex);
                    yield break;
                }
            }
            #endregion

            #region Load grammar and start engine if necessary
            // Request chance to update recognition engine and cancel current recognition
            // operation
            state.Recognizer.RequestRecognizerUpdate();
            state.Recognizer.RecognizeAsyncCancel();
            yield return((Choice)loadGrammarResponsePort);

            Exception loadGrammarException = (Exception)loadGrammarResponsePort;
            if (loadGrammarException != null)
            {
                LogWarning(loadGrammarException);
                response.Post(loadGrammarException);
                yield break;
            }

            // Empty response port
            SuccessResult loadGrammarSuccess = (SuccessResult)loadGrammarResponsePort;

            // Start engine again
            if (state.Recognizer.Grammars.Count > 0 && !state.IgnoreAudioInput)
            {
                state.Recognizer.RecognizeAsync(RecognizeMode.Multiple);
            }
            #endregion

            // Store information about the new grammar in the service's state
            this.state.Grammar     = grammarToLoad;
            this.state.GrammarType = request.GrammarType;

            if (request.GrammarType == GrammarType.Srgs)
            {
                this.state.SrgsFileLocation  = request.SrgsFileLocation;
                this.state.DictionaryGrammar = null;
            }
            else
            {
                this.state.DictionaryGrammar = request.DictionaryGrammar;
                this.state.SrgsFileLocation  = null;
            }

            response.Post(SuccessResult.Instance);
        }