context: using System;
  using System.IO;
  using System.Windows.Forms;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using Sdl.LanguagePlatform.Core;
  using Sdl.Core.Globalization;
  using Sdl.LanguagePlatform.TranslationMemory;
  using Sdl.LanguagePlatform.TranslationMemoryApi;
  
  namespace Sdl.Community.TermInjector
  {
      public class TermInjectorTranslationProviderLanguageDirection : ITranslationProviderLanguageDirection
      {
          private static LanguagePair _languageDirection;
          
          #region "PrivateMembers"
          private TermInjectorTranslationProvider _provider;
          private static TermInjectorTranslationOptions _options;
          
          private Boolean _matchCase;
          private SearchResults[] _resultarray;
  
          #endregion
  
          #region "ITranslationProviderLanguageDirection Members"
  
          #region "TermInjectorTranslationProviderLanguageDirection"
          public TermInjectorTranslationProviderLanguageDirection(TermInjectorTranslationProvider provider, LanguagePair languages)
          {
              #region "Instantiate"
              _provider = provider;
              _languageDirection = languages;
              _options = _provider.Options;
              _matchCase = _options.MatchCase == "true" ? true : false;
              #endregion
  
          }
  
          #endregion
  
          public System.Globalization.CultureInfo SourceLanguage
          {
              get { return _languageDirection.SourceCulture; }
          }
  
          public System.Globalization.CultureInfo TargetLanguage
          {
              get { return _languageDirection.TargetCulture; }
          }
  
          public bool CanReverseLanguageDirection
          {
              get { return false; }
          }
  
          public ITranslationProvider TranslationProvider
          {
              get { return _provider; }
          }
  
          private Boolean InjectTermsNoMatch(Segment segment, Segment blankSegment)
          {
              //Reset the nomatch visitor and have it visit the segment elements
              _provider.NoMatchVisitor.Reset();
              //Pass the blank segment to no match visitor
              _provider.NoMatchVisitor.Segment = blankSegment;
  
  
              foreach (var element in segment.Elements)
              {
  
                  element.AcceptSegmentElementVisitor(_provider.NoMatchVisitor);
              }
  
  
              if (_provider.NoMatchVisitor.OriginalSegmentChanged)
              {
                  return true;
              }
              else
              {
                  return false;
              }
          }
  
          private Segment InjectTermsFuzzyMatch(Segment segment, SearchResult result)
          {
              
              //Reset the fuzzy current visitor
              _provider.FuzzyCurrentVisitor.Reset();
  
              //Have the fuzzy visitor go through the current source segment and pick up found
              //terms and their possible replacements
              foreach (var element in segment.Elements)
              {
                  element.AcceptSegmentElementVisitor(_provider.FuzzyCurrentVisitor);
              }
  
              //Generate a new replacement trie from the fuzzy current visitor term list
              Trie replacementTrie = _provider.ExactMatchTrieReplaces.Clone();
              
              //Create a new regex trie which will be used as the secondary regex trie in the visitor
              RegexTrie<TranslationAndReplacement> replacementRegexTrie = new RegexTrie<TranslationAndReplacement>();
              Boolean regexesAdded = false;
              
              //This will be the new term list of the visitor, with replacement terms removed
              List<PositionAndTranslation> newTermList = new List<PositionAndTranslation>();
  
              //Go through the terms adding the terms to either the normal or regex trie or to the new term list
              foreach (var term in _provider.FuzzyCurrentVisitor.TermList)
              {
                  //If the term has a replaces value, add it to trie
                  if (term.Replaces != "")
                  {
                      //Use replaces field as source. If the term is from a regex trie, add
                      //it to a regex trie
                      if (term.Regex)
                      {
                          _provider.RegexTrieFactory.AddToRegexTrie(
                              replacementRegexTrie,
                              term.Replaces,
                              new TranslationAndReplacement(
                                  term.Translation,
                                  ""));
                          regexesAdded = true;
                          
                      }
                      else
                      {
                          replacementTrie.AddToTrie(term.Replaces, term.Translation, "");
                      }
                  }
                  //If there's no replaces field, handle this in the comparison phase
                  else
                  {
                      newTermList.Add(term);
                  }
              }
              //Determinise the regex trie
              if (regexesAdded)
              {
                  replacementRegexTrie = _provider.Determiniser.determiniseNFA(replacementRegexTrie);
              }
              //Update the fuzzy term list with the list that does not contain the replacement terms
              _provider.FuzzyCurrentVisitor.TermList = newTermList;
  
              //Reset fuzzy replace visitor and update the tries to it
              _provider.FuzzyReplaceVisitor.Reset();
              _provider.FuzzyReplaceVisitor.SndTrie = replacementTrie;
              _provider.FuzzyReplaceVisitor.SndRegexTrie = replacementRegexTrie;
              
              //Go through the translation proposal target segment with the visitor
              foreach (var element in result.TranslationProposal.TargetSegment.Elements)
              {
                  //Why would there be null elements? 
                  if (element != null)
                  {
                      element.AcceptSegmentElementVisitor(_provider.FuzzyReplaceVisitor);
                  }
              }
  
              Segment segmentWithTerms = _provider.FuzzyReplaceVisitor.Segment;
  
              //Visit the elements of the results, compare the resulting visitor with the _fuzzyVisitor and
              //and add the terms only found in _fuzzyVisitor to the translation proposal
              if (_options.InjectNewTermsIntoFuzzies == "true")
              {
                  _provider.FuzzyMatchVisitor.Reset();
                  foreach (var element in result.MemoryTranslationUnit.SourceSegment.Elements)
                  {
                      element.AcceptSegmentElementVisitor(_provider.FuzzyMatchVisitor);
                  }
  
                  Text newTerms = _provider.FuzzyCurrentVisitor.TermDifference(_provider.FuzzyMatchVisitor);
  
                  if (newTerms.Value.Length > 0)
                  {
                      segmentWithTerms.Elements.Insert(0, newTerms);
                  }
              }
  
              //Return a deep copy of the segment (if reference is used, all results will display
              //the last segment constructed.)
              return segmentWithTerms.Duplicate();
          }
  
          public SearchResults[] SearchTranslationUnitsMasked(SearchSettings settings, TranslationUnit[] translationUnits, bool[] mask)
          {
              //This is the function that is called when a TM lookup is done, so the injection code is called here
              #region "SegmentLookup"
              if (settings.Mode == SearchMode.NormalSearch || settings.Mode == SearchMode.FullSearch)
              {
                  _resultarray = _provider.FileTM.GetLanguageDirection(_languageDirection).SearchTranslationUnitsMasked(settings,translationUnits,mask);
                  
                  foreach (var results in _resultarray)
                  {
                      //First search the TM for results. If there are no results, give as a result the source segment
                      //with terms translations inserted
                      if (results == null)
                      {
                          continue;
                      }
                      if (results.Count == 0)
                      {
                          
                          //This segment is passed onto the injection method and possible modified
  
gt:                         Segment blankSegment = new Segment();