public ConceptSubstitution(string originalText, int startIndex, int stopIndex, ConceptGroupWithTheSameSynonym replacementConceptGroup, string replacementText)
 {
     OriginalText            = originalText;
     StartIndex              = startIndex;
     StopIndex               = stopIndex;
     ReplacementConceptGroup = replacementConceptGroup;
     ReplacementText         = replacementText;
 }
        internal void AddConcept(Concept concept)
        {
            // Check for duplicate synonyms in a single concept
            ISet <string> thisConceptSynonyms = new HashSet <string>();
            int           i = 1;

            foreach (var synonym in concept.Synonyms)
            {
                i++;
                if (thisConceptSynonyms.Contains(synonym))
                {
                    LogMessage(concept.LineNumber + i, MessageType.DuplicateSynonym, "Duplicate synonym : \"" + synonym + "\" inside the same concept \"" + concept.Key + "\"");
                }
                else
                {
                    thisConceptSynonyms.Add(synonym);
                }
            }

            // Add concept in dictionary of concepts
            Concept conceptInDictionary = null;

            if (!String.IsNullOrEmpty(concept.Id))
            {
                if (Concepts.ContainsKey(concept.Id))
                {
                    conceptInDictionary = Concepts[concept.Id];
                    // Mark second concept as duplicate
                    concept.IsDuplicate = true;
                    // Merge second concept synonyms
                    foreach (var synonym in concept.Synonyms)
                    {
                        if (!conceptInDictionary.Synonyms.Contains(synonym))
                        {
                            conceptInDictionary.Synonyms.Add(synonym);
                        }
                    }
                    // Log error message
                    LogMessage(concept.LineNumber, MessageType.DuplicateConcept, "Duplicate concept nodes found for id \"" + concept.Id + "\" : line " + concept.LineNumber + " and line " + conceptInDictionary.LineNumber);
                }
                else if (Concepts.ContainsKey(concept.CanonicalValue))
                {
                    conceptInDictionary = Concepts[concept.CanonicalValue];
                    // Mark second concept as duplicate
                    concept.IsDuplicate = true;
                    // Merge second concept synonyms
                    foreach (var synonym in concept.Synonyms)
                    {
                        if (!conceptInDictionary.Synonyms.Contains(synonym))
                        {
                            conceptInDictionary.Synonyms.Add(synonym);
                        }
                    }
                    // Merge second concept Id
                    if (String.IsNullOrEmpty(conceptInDictionary.Id))
                    {
                        conceptInDictionary.Id  = concept.Id;
                        conceptInDictionary.Key = concept.Id;
                        Concepts.Add(conceptInDictionary.Id, conceptInDictionary);
                    }
                    // Log error message
                    LogMessage(concept.LineNumber, MessageType.DuplicateConcept, "Duplicate concept nodes found for canonical value \"" + concept.CanonicalValue + "\" : line " + concept.LineNumber + " and line " + conceptInDictionary.LineNumber + " => you should probably merge them");
                }
                else
                {
                    conceptInDictionary = concept;
                    Concepts.Add(concept.Id, concept);
                    Concepts.Add(concept.CanonicalValue, concept);
                }
            }
            else
            {
                if (Concepts.ContainsKey(concept.CanonicalValue))
                {
                    conceptInDictionary = Concepts[concept.CanonicalValue];
                    // Mark second concept as duplicate
                    concept.IsDuplicate = true;
                    // Merge second concept synonyms
                    foreach (var synonym in concept.Synonyms)
                    {
                        if (!conceptInDictionary.Synonyms.Contains(synonym))
                        {
                            conceptInDictionary.Synonyms.Add(synonym);
                        }
                    }
                    // Log error message
                    LogMessage(concept.LineNumber, MessageType.DuplicateConcept, "Duplicate concept nodes found for canonical value \"" + concept.CanonicalValue + "\" : line " + concept.LineNumber + " and line " + conceptInDictionary.LineNumber + " => you should probably merge them");
                }
                else
                {
                    conceptInDictionary = concept;
                    Concepts.Add(concept.CanonicalValue, concept);
                }
            }

            // Add concept synonyms in dictionary of synonyms
            foreach (var synonym in thisConceptSynonyms)
            {
                if (ConceptsSynonyms.ContainsKey(synonym))
                {
                    var conceptGroupWithTheSameSynonym = ConceptsSynonyms[synonym];
                    conceptGroupWithTheSameSynonym.AddConcept(conceptInDictionary);
                }
                else
                {
                    ConceptsSynonyms[synonym] = new ConceptGroupWithTheSameSynonym(synonym, conceptInDictionary);
                }
            }
        }