/// <summary>
 /// Sets the word using autoconversion method, if enabled
 /// </summary>
 /// <param name="key">The key.</param>
 /// <returns></returns>
 public translationTextTableEntryEnum SetWord(string key)
 {
     lock (SetWordLock)
     {
         if (!isAutoConversionEnabled)
         {
             throw new dataException("Can't set word with SetWord(" + key + ") method because the conversion method was not specified");
         }
         translationTextTableEntryEnum entry = checkForEntry(key);
         if (entry == translationTextTableEntryEnum.unknownEntry || entry == translationTextTableEntryEnum.valueEntry)
         {
             if (isAutoConversionEnabled)
             {
                 string k = key;
                 string v = conversionMethod(key);
                 if (k != v)
                 {
                     Add(key, conversionMethod(key));
                     return translationTextTableEntryEnum.newEntry;
                 }
                 else
                 {
                     return translationTextTableEntryEnum.none;
                 }
             }
         }
     }
     return translationTextTableEntryEnum.none;
 }
        /// <summary>
        /// Gets the word pair either the specified <c>key</c> was found as Key or Value, otherwise returns the <c>key</c> or makes auto conversion if <see cref="isAutoConversionEnabled" /> i.e. <see cref="conversionMethod" /> provided with <see cref="translationTextTable" /> constructor
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="oentry">Provides insight how word was found/converted</param>
        /// <returns></returns>
        public string GetWord(string key, out translationTextTableEntryEnum oentry)
        {
            translationTextTableEntryEnum entry = checkForEntry(key);
            oentry = entry;

            if (entry == translationTextTableEntryEnum.keyEntry)
            {
                return byKeys[key];
            }
            else if (entry == translationTextTableEntryEnum.valueEntry)
            {
                return byValues[key];
            }
            else if (entry == translationTextTableEntryEnum.unknownEntry)
            {
                if (isAutoConversionEnabled)
                {
                    /*
                    String v = conversionMethod(key);
                    String k = key;
                    Add(k, v);
                    */
                    SetWord(key);
                    return byKeys[key];
                }
            }
            return key;
        }
        /// <summary>
        /// Sets the entry from string pair like: <c>štetočina|stetocina</c> if <c>štetočina</c> not already defined. It will recognize automatically if its not single line but multiple lines
        /// </summary>
        /// <param name="entryLine">The entry line.</param>
        /// <returns><see cref="translationTextTableEntryEnum.newEntry"/> if new entry was created, <see cref="translationTextTableEntryEnum.none"/> if there was problem in the format, other if the entry was found</returns>
        public translationTextTableEntryEnum SetEntryFromString(string entryLine)
        {
            if (imbSciStringExtensions.isNullOrEmptyString(entryLine)) return translationTextTableEntryEnum.none;

            if (entryLine.Contains(Environment.NewLine))
            {
                int c = SetEntriesFromString(entryLine);
                if (c > 0) return translationTextTableEntryEnum.newEntry;
            }

            string[] stp = entryLine.Split(new char[] { ENTRYSEPARATOR }, StringSplitOptions.RemoveEmptyEntries);

            if (stp.Count() < 2) return translationTextTableEntryEnum.none;

            string k = stp[0].Trim();
            string v = stp[1].Trim();

            translationTextTableEntryEnum entry = checkForEntry(k);
            if ((entry == translationTextTableEntryEnum.unknownEntry || entry == translationTextTableEntryEnum.valueEntry))
            {
                Add(k, v);
                entry = translationTextTableEntryEnum.newEntry;
            }
            else
            {
            }
            return entry;
        }
        /// <summary>
        /// Sets the item into cache
        /// </summary>
        /// <param name="item">The item.</param>
        public void Add(ILexiconItem item)
        {
            int retryIndex = 0;

            while (retryIndex < retryLimit)
            {
                try
                {
                    translationTextTableEntryEnum entry = translationTextTableEntryEnum.none;
                    if (item is ITermLemma)
                    {
                        ITermLemma lemma = (ITermLemma)item;
                        lemmas.AddUnique(item.name, lemma);
                        if (item.name.isNonDosChars())
                        {
                            lemmas.AddUnique(twins.GetWord(item.name, out entry), lemma);
                        }

                        foreach (TermInstance instance in lemma.instances)
                        {
                            instances.AddUnique(item.name, instance);
                            if (item.name.isNonDosChars())
                            {
                                instances.AddUnique(twins.GetWord(item.name, out entry), instance);
                            }
                        }
                    }
                    else if (item is ITermInstance)
                    {
                        instances.AddUnique(item.name, item as ITermInstance);
                        if (item.name.isNonDosChars())
                        {
                            instances.AddUnique(twins.GetWord(item.name, out entry), item as ITermInstance);
                        }
                    }
                    retryIndex = retryLimit + 1;
                }
                catch (Exception ex)
                {
                    aceLog.log("SemanticLexiconCache->Add(" + item.name + ") failed: " + ex.Message + "  Retries left[" + (retryLimit - retryIndex) + "]", null, true);
                    aceTerminalInput.askPressAnyKeyInTime("-- cooldown delay -- press any key to skip --", true, 3, false, 1);
                    retryIndex++;
                }
            }
        }
 /// <summary>
 /// Gets the entry as string pair like: <c>rečnik|dictionary</c> either the <c>key</c> found as Key or Value in the table. Returns empty string if not found and autoconversion wasn't enabled
 /// </summary>
 /// <param name="key">The key or value to get pair for</param>
 /// <returns>Gets the entry as string pair like: <c>rečnik|dictionary</c> either the <c>key</c> found as Key or Value in the table. Returns empty string if not found and autoconversion wasn't enabled</returns>
 public string GetEntryAsStringPair(string key)
 {
     translationTextTableEntryEnum entry = checkForEntry(key);
     if (entry == translationTextTableEntryEnum.keyEntry)
     {
         return key + ENTRYSEPARATOR + byKeys[key];
     }
     else if (entry == translationTextTableEntryEnum.valueEntry)
     {
         return byKeys[key] + ENTRYSEPARATOR + key;
     }
     else if (entry == translationTextTableEntryEnum.unknownEntry)
     {
         if (isAutoConversionEnabled)
         {
             return key + ENTRYSEPARATOR + conversionMethod(key);
         }
     }
     return "";
 }
        /// <summary>
        /// Gets the lexicon items from cached terms or failed queris
        /// </summary>
        /// <param name="termForm">The term form.</param>
        /// <returns></returns>
        public lexiconResponse getLexiconItems(string termForm, ILogBuilder loger = null)
        {
            lexiconResponse output      = new lexiconResponse();
            string          termFormLat = termForm;

            if (semanticLexiconManager.manager.settings.doQueryPreprocess)
            {
                termForm = termForm.ToLower().Trim();
                //  termFormLat = termForm.transliterate(transliterateFlag.cyrilicToLatin);
            }

            termForm = termFormLat;

            output.setType(lexiconResponse.responseType.none);

            if (failed.ContainsKey(termForm))
            {
                output = failed[termForm];
                output.setType(lexiconResponse.responseType.failedQueries);
            }
            else if (lemmas.ContainsKey(termForm))
            {
                output.AddRange(lemmas[termForm]);
                output.setType(lexiconResponse.responseType.cachedLexicon);
            }
            else if (instances.ContainsKey(termForm))
            {
                output.AddRange(instances[termForm]);
                output.setType(lexiconResponse.responseType.cachedLexicon);
            }
            else
            {
                List <string> termForms = new List <string>();
                termForms.Add(termForm);
                translationTextTableEntryEnum entry = twins.checkForEntry(termForm);

                switch (entry)
                {
                case translationTextTableEntryEnum.keyEntry:
                case translationTextTableEntryEnum.valueEntry:
                    termForms.Add(twins.GetWord(termForm, out entry));
                    break;

                case translationTextTableEntryEnum.unknownEntry:
                    if (termForm.isNonDosChars())
                    {
                        termForms.Add(twins.GetWord(termForm, out entry));
                    }
                    break;
                }

                if (doAllowLexiconQuery && !isLexiconPreloaded)
                {
                    output.setType(lexiconResponse.responseType.askingLexiconContext);
                    output = _getLexiconItems(termForms, loger);
                }

                if (output.Any())
                {
                    output.setType(lexiconResponse.responseType.lexicon);
                    Add(output);
                }
                else
                {
                    output = AddTemp(termForms, loger);
                    output.setType(lexiconResponse.responseType.failedQueries);
                }
            }
            //} catch (Exception ex)
            //{
            //    aceGeneralException axe = new aceGeneralException("semanticLexiconCache.getLexiconItems error", ex, this, "lexCache.getLexiconItems() current state: " + output.type);

            //    throw axe;
            //}
            return(output);
        }