protected internal void HandleTranslationComplete(object sender, TranslateArrayCompletedEventArgs e)
        {
            // look up the id from e
            if (e.UserState == null)
            {
                string message = string.Format("UserState from async translation is null, expected it to be an istance of BingTranslatorUserState.");
                throw new UnexpectedStateException(message);
            }

            // BingTranslatorUserState userState = new BingTranslatorUserState(e.UserState as object[]);
            BingTranslatorUserState userState = e.UserState as BingTranslatorUserState;
            // see if there are any registered handlers
            List <IAsyncTranslationComplete> handlers = null;

            this.AsyncTranslationHandlers.TryGetValue(userState.Id, out handlers);

            // remove the id from the dictionary then call the events, they may take time to execute
            //      that is why they are removed first
            if (handlers != null)
            {
                lock (lockAsyncTranslationHandlers) {
                    this.AsyncTranslationHandlers[userState.Id] = null;
                }

                // create the object that will be passed to the handlers
                List <ITranslation> translationResult = new List <ITranslation>();

                foreach (IAsyncTranslationComplete handler in handlers)
                {
                    List <string> stringsToTranslate = handler.TranslationAsync.StringsToTranslate;
                    if (stringsToTranslate.Count != e.Result.Length)
                    {
                        string message = string.Format(
                            "There was a mis-match between the count of strings to translate [{0}] and the translated strings [{1}].",
                            stringsToTranslate.Count,
                            e.Result.Length);
                        throw new UnexpectedStateException(message);
                    }

                    List <ITranslation> translations = new List <ITranslation>(stringsToTranslate.Count);

                    for (int i = 0; i < stringsToTranslate.Count; i++)
                    {
                        translations.Add(
                            new Translation(
                                handler.TranslationAsync.SourceLanguage,
                                handler.TranslationAsync.DestLanguage,
                                stringsToTranslate[i],
                                e.Result[i].TranslatedText));
                    }

                    handler.OnTranslationComplete(handler.TranslationAsync, translations);
                }
            }
        }
        public IAsyncContinuation Translate2(IEnumerable <string> stringsToTranslate, ILanguage destLanguage, ILanguage sourceLanguage = null)
        {
            if (stringsToTranslate == null)
            {
                throw new ArgumentNullException("stringsToTranslate");
            }

            // Convert stringsToTranslate to a list because I need to send them all at once
            //      to the translation engine. We can only get benefit of IEnumberable in one direction
            List <string> stringList = stringsToTranslate.ToList();

            if (sourceLanguage == null)
            {
                // detect language from the first string in the list to translate
                sourceLanguage = this.DetectLanguage(stringsToTranslate.First());
            }

            Guid translationGuid = Guid.NewGuid();

            IAsyncTranslationPayload asyncObj  = new AsyncTranslationPayload(Guid.NewGuid(), stringList, sourceLanguage, destLanguage, this);
            BingTranslatorUserState  userState = new BingTranslatorUserState {
                Id             = asyncObj.Id,
                SourceLanguage = sourceLanguage as BaseLanguage,
                DestLanguage   = destLanguage as BaseLanguage
            };

            // TODO: Do we want this to be done async? if so update this code
            using (BingTranslatorService.SoapService client = new BingTranslatorService.SoapService()) {
                client.TranslateArrayAsync(
                    this.ApiKey,
                    stringList.ToArray(),
                    sourceLanguage.Language,
                    destLanguage.Language,
                    this.TranslateOptions,
                    userState);
                client.TranslateArrayCompleted += HandleTranslationComplete;
            }

            return(asyncObj);
        }
        public IAsyncContinuation Translate2(IEnumerable<string> stringsToTranslate, ILanguage destLanguage, ILanguage sourceLanguage = null)
        {
            if (stringsToTranslate == null) { throw new ArgumentNullException("stringsToTranslate"); }

            // Convert stringsToTranslate to a list because I need to send them all at once
            //      to the translation engine. We can only get benefit of IEnumberable in one direction
            List<string> stringList = stringsToTranslate.ToList();

            if (sourceLanguage == null) {
                // detect language from the first string in the list to translate
                sourceLanguage = this.DetectLanguage(stringsToTranslate.First());
            }

            Guid translationGuid = Guid.NewGuid();

            IAsyncTranslationPayload asyncObj = new AsyncTranslationPayload(Guid.NewGuid(), stringList, sourceLanguage, destLanguage, this);
            BingTranslatorUserState userState = new BingTranslatorUserState {
                Id = asyncObj.Id,
                SourceLanguage = sourceLanguage as BaseLanguage,
                DestLanguage = destLanguage as BaseLanguage
            };

            // TODO: Do we want this to be done async? if so update this code
            using (BingTranslatorService.SoapService client = new BingTranslatorService.SoapService()) {
                client.TranslateArrayAsync(
                    this.ApiKey,
                    stringList.ToArray(),
                    sourceLanguage.Language,
                    destLanguage.Language,
                    this.TranslateOptions,
                    userState);
                client.TranslateArrayCompleted += HandleTranslationComplete;
            }

            return asyncObj;
        }