public IEnumerator <ITask> DeleteGrammarEntryHandler(DeleteGrammarEntry delete)
        {
            // Make sure current grammar type is dictionary-style
            if (_state.GrammarType != GrammarType.DictionaryStyle)
            {
                Fault fault = Fault.FromCodeSubcodeReason(
                    FaultCodes.Receiver,
                    DsspFaultCodes.OperationFailed,
                    "Cannot delete entries from grammar dictionary because grammar"
                    + "currently in use is not DictionaryStyle."
                    );
                LogInfo(fault.ToException());
                delete.ResponsePort.Post(fault);
                yield break;
            }

            #region Set up load grammar request and load grammar
            // Set up load grammar request
            LoadGrammarRequest loadRequest = new LoadGrammarRequest();
            loadRequest.GrammarType       = GrammarType.DictionaryStyle;
            loadRequest.DictionaryGrammar = new Dictionary <string, string>(_state.DictionaryGrammar);
            GrammarUtilities.DeleteDictionary(loadRequest.DictionaryGrammar, delete.Body.DictionaryGrammar);

            // Load new grammar
            SuccessFailurePort loadGrammarPort = new SuccessFailurePort();
            SpawnIterator <LoadGrammarRequest, SuccessFailurePort>(
                loadRequest,
                loadGrammarPort,
                LoadGrammar
                );

            // Check loading outcome
            yield return((Choice)loadGrammarPort);

            Exception exception = (Exception)loadGrammarPort;
            if (exception != null)
            {
                LogWarning(exception);
                delete.ResponsePort.Post(Fault.FromCodeSubcodeReason(
                                             FaultCodes.Receiver,
                                             DsspFaultCodes.OperationFailed,
                                             exception.Message
                                             ));
                yield break;
            }
            #endregion

            SaveState(_state);

            // Notify subscribers of state change
            Replace replace = new Replace();
            replace.Body = _state;
            SendNotification <Replace>(_subMgrPort, replace);

            delete.ResponsePort.Post(DefaultDeleteResponseType.Instance);
        }
        public IEnumerator <ITask> UpsertGrammarEntryHandler(UpsertGrammarEntry upsert)
        {
            if (_state.GrammarType != GrammarType.DictionaryStyle)
            {
                // Since we are switching grammar mode make sure there exists a valid,
                // empty dictionary
                if (_state.DictionaryGrammar == null)
                {
                    _state.DictionaryGrammar = new Dictionary <string, string>();
                }
                else
                {
                    _state.DictionaryGrammar.Clear();
                }
            }

            #region Set up load grammar request and load grammar
            // Set up load grammar request
            LoadGrammarRequest loadRequest = new LoadGrammarRequest();
            loadRequest.GrammarType       = GrammarType.DictionaryStyle;
            loadRequest.DictionaryGrammar = new Dictionary <string, string>(_state.DictionaryGrammar);
            GrammarUtilities.UpsertDictionary(loadRequest.DictionaryGrammar, upsert.Body.DictionaryGrammar);

            // Load new grammar
            SuccessFailurePort loadGrammarPort = new SuccessFailurePort();
            SpawnIterator <LoadGrammarRequest, SuccessFailurePort>(
                loadRequest,
                loadGrammarPort,
                LoadGrammar
                );

            // Check loading outcome
            yield return((Choice)loadGrammarPort);

            Exception exception = (Exception)loadGrammarPort;
            if (exception != null)
            {
                LogWarning(exception);
                upsert.ResponsePort.Post(Fault.FromCodeSubcodeReason(
                                             FaultCodes.Receiver,
                                             DsspFaultCodes.OperationFailed,
                                             exception.Message
                                             ));
                yield break;
            }
            #endregion

            SaveState(_state);

            // Notify subscribers of state change
            Replace replace = new Replace();
            replace.Body = _state;
            SendNotification <Replace>(_subMgrPort, replace);

            upsert.ResponsePort.Post(DefaultUpsertResponseType.Instance);
        }
        /// <summary>
        /// Loads grammar on service startup
        /// </summary>
        /// <returns></returns>
        private IEnumerator <ITask> LoadGrammarOnStartup()
        {
            // Determine whether we have a valid grammar to load
            bool loadGrammar = false;

            switch (_state.GrammarType)
            {
            case GrammarType.DictionaryStyle:
                loadGrammar = _state.DictionaryGrammar.Count > 0;
                break;

            case GrammarType.Srgs:
                loadGrammar = !string.IsNullOrEmpty(_state.SrgsFileLocation);
                break;
            }

            // Load grammar
            if (loadGrammar)
            {
                SuccessFailurePort loadGrammarPort = new SuccessFailurePort();
                LoadGrammarRequest loadRequest     = new LoadGrammarRequest();
                loadRequest.GrammarType       = _state.GrammarType;
                loadRequest.DictionaryGrammar = _state.DictionaryGrammar;
                loadRequest.SrgsFileLocation  = _state.SrgsFileLocation;
                SpawnIterator <LoadGrammarRequest, SuccessFailurePort>(
                    loadRequest,
                    loadGrammarPort,
                    LoadGrammar
                    );

                yield return((Choice)loadGrammarPort);

                Exception exception = (Exception)loadGrammarPort;
                if (exception != null)
                {
                    LogWarning(exception);
                }
            }

            StartService();
            yield break;
        }
        public IEnumerator <ITask> SetSrgsGrammarFileHandler(SetSrgsGrammarFile setSrgsGrammarFile)
        {
            #region Set up load grammar request and load grammar
            // Set up load grammar request
            LoadGrammarRequest loadRequest = new LoadGrammarRequest();
            loadRequest.GrammarType      = GrammarType.Srgs;
            loadRequest.SrgsFileLocation = setSrgsGrammarFile.Body.FileLocation;

            // Load new grammar
            SuccessFailurePort loadGrammarPort = new SuccessFailurePort();
            SpawnIterator <LoadGrammarRequest, SuccessFailurePort>(
                loadRequest,
                loadGrammarPort,
                LoadGrammar
                );

            // Check loading outcome
            yield return((Choice)loadGrammarPort);

            Exception exception = (Exception)loadGrammarPort;
            if (exception != null)
            {
                LogWarning(exception);
                setSrgsGrammarFile.ResponsePort.Post(Fault.FromCodeSubcodeReason(
                                                         FaultCodes.Receiver,
                                                         DsspFaultCodes.OperationFailed,
                                                         exception.Message
                                                         ));
                yield break;
            }
            #endregion

            SaveState(_state);

            // Notify subscribers of state change
            Replace replace = new Replace();
            replace.Body = _state;
            SendNotification <Replace>(_subMgrPort, replace);

            setSrgsGrammarFile.ResponsePort.Post(DefaultUpdateResponseType.Instance);
        }
        /// <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
            _state.Grammar     = _grammarToLoad;
            _state.GrammarType = request.GrammarType;

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

            response.Post(SuccessResult.Instance);
        }
        public IEnumerator <ITask> ReplaceHandler(Replace replace)
        {
            SpeechRecognizerState newState = replace.Body;

            #region Set up load grammar request, load grammar and on success store new grammar in state
            // Set up load grammar request
            LoadGrammarRequest loadRequest = new LoadGrammarRequest();
            loadRequest.GrammarType       = newState.GrammarType;
            loadRequest.SrgsFileLocation  = newState.SrgsFileLocation;
            loadRequest.DictionaryGrammar = newState.DictionaryGrammar;

            // Load new grammar
            SuccessFailurePort loadGrammarPort = new SuccessFailurePort();
            SpawnIterator <LoadGrammarRequest, SuccessFailurePort>(
                loadRequest,
                loadGrammarPort,
                LoadGrammar
                );

            // Check loading outcome
            yield return((Choice)loadGrammarPort);

            Exception exception = (Exception)loadGrammarPort;
            if (exception != null)
            {
                LogWarning(exception);
                replace.ResponsePort.Post(Fault.FromCodeSubcodeReason(
                                              W3C.Soap.FaultCodes.Receiver,
                                              DsspFaultCodes.OperationFailed,
                                              exception.Message
                                              ));
                yield break;
            }
            #endregion

            #region Check new state's IgnoreAudioInput flag and start recognition engine if necessary
            if (newState.IgnoreAudioInput != _state.IgnoreAudioInput)
            {
                _state.IgnoreAudioInput = newState.IgnoreAudioInput;
                if (_state.IgnoreAudioInput)
                {
                    // Stop engine and switch to ignoring audio input
                    _state.Recognizer.RecognizeAsyncCancel();
                    _state.Recognizer.SetInputToNull();
                }
                else
                {
                    _state.Recognizer.SetInputToDefaultAudioDevice();

                    // Because old state ignored audio input the engine is stopped, now that
                    // we switched to listening to audio input the engine needs to be started
                    if (_state.Recognizer.Grammars.Count > 0)
                    {
                        _state.Recognizer.RecognizeAsync(RecognizeMode.Multiple);
                    }
                }
            }
            #endregion

            SaveState(_state);

            // Notify subscribers of state change
            replace.Body = _state;
            SendNotification <Replace>(_subMgrPort, replace);

            replace.ResponsePort.Post(DefaultReplaceResponseType.Instance);
        }