private ReplaceStatus TryAndReplace(Token nextToken, ReplaceOperation replaceOperation)
        {
            ReplaceStatus status = new ReplaceStatus();
            IList<Token> originalMatchingTokens;

            #if EUROINFO_LEGACY_REPLACING_SYNTAX

            // Support for legacy replacing syntax semantics :
            // Insert SuffixChar before the first '-' in all user defined words found in the COPY text
            // before copying it into the main program
            if (CopyReplacingDirective != null && CopyReplacingDirective.InsertSuffixChar && nextToken.TokenType == TokenType.UserDefinedWord)
            {
                string originalText = nextToken.Text;
                int indexOFirstDash = originalText.IndexOf('-');
                if (indexOFirstDash > 0)
                {
                    string replacedText = originalText.Substring(0, indexOFirstDash) + CopyReplacingDirective.SuffixChar + originalText.Substring(indexOFirstDash);
                    TokensLine virtualTokensLine = TokensLine.CreateVirtualLineForInsertedToken(0, replacedText);
                    Token replacementToken = new Token(TokenType.UserDefinedWord, 0, replacedText.Length - 1, virtualTokensLine);

                    status.replacedToken = new ReplacedToken(replacementToken, nextToken);
                    currentPosition.CurrentToken = status.replacedToken;
                }
            }
            #endif

            if (replaceOperation != null && TryMatchReplaceOperation(nextToken, replaceOperation, out originalMatchingTokens))
            {
                status.replacedToken = CreateReplacedTokens(nextToken, replaceOperation, originalMatchingTokens);
                if (status.replacedToken != null)
                {
                    // REPLACE pattern matched => return the first replaced token
                    currentPosition.CurrentToken = status.replacedToken;
                }
                else
                {
                    // If the replacement token set is empty (REPLACE == ... = BY == ==), get next token and try again
                    status.tryAgain = true;
                }
            }
            return status;
        }
 /// <summary>
 /// Check if the current tokens match with the comparison tokens of the current replace operation
 /// </summary>
 private bool TryMatchReplaceOperation(Token originalToken, ReplaceOperation replaceOperation, out IList<Token> originalMatchingTokens)
 {
     // Check if the first token matches the replace pattern
     if (originalToken.CompareForReplace(replaceOperation.ComparisonToken))
     {
         // Multiple tokens pattern => check if the following tokens returned by the underlying iterator all match the pattern
         if (replaceOperation.Type == ReplaceOperationType.MultipleTokens)
         {
             MultipleTokensReplaceOperation multipleTokensReplaceOperation = (MultipleTokensReplaceOperation)replaceOperation;
             originalMatchingTokens = new List<Token>();
             originalMatchingTokens.Add(originalToken);
             sourceIterator.SaveCurrentPositionSnapshot();
             bool comparisonInterrupted = false;
             foreach (Token comparisonToken in multipleTokensReplaceOperation.FollowingComparisonTokens)
             {
                 Token nextCandidateToken = sourceIterator.NextToken();
                 if (!comparisonToken.CompareForReplace(nextCandidateToken))
                 {
                     comparisonInterrupted = true;
                     break;
                 }
                 else
                 {
                     originalMatchingTokens.Add(nextCandidateToken);
                 }
             }
             // The following tokens did not match
             if (comparisonInterrupted)
             {
                 // Restore the uderlying iterator position
                 sourceIterator.ReturnToLastPositionSnapshot();
                 // Match failed
                 originalMatchingTokens = null;
                 return false;
             }
             // Multiple tokens match OK
             else
             {
                 return true;
             }
         }
         // Single token comparison => match OK
         else
         {
             originalMatchingTokens = null;
             return true;
         }
     }
     // First token does not match
     else
     {
         originalMatchingTokens = null;
         return false;
     }
 }
        /// <summary>
        /// Create replaced tokens for all matched tokens
        /// (a ReplacedToken references both the original token and the replacement token)
        /// </summary>
        private Token CreateReplacedTokens(Token originalToken, ReplaceOperation replaceOperation, IList<Token> originalMatchingTokens)
        {
            switch (replaceOperation.Type)
            {
                // One comparison token => zero or one replacement token
                case ReplaceOperationType.SingleToken:
                    SingleTokenReplaceOperation singleTokenReplaceOperation = (SingleTokenReplaceOperation)replaceOperation;
                    if (singleTokenReplaceOperation.ReplacementToken != null)
                    {
                        ReplacedToken replacedToken = new ReplacedToken(singleTokenReplaceOperation.ReplacementToken, originalToken);
                        return replacedToken;
                    }
                    else
                    {
                        return null;
                    }

                // One pure partial word => one replacement token
                case ReplaceOperationType.PartialWord:
                    PartialWordReplaceOperation partialWordReplaceOperation = (PartialWordReplaceOperation)replaceOperation;
                    string originalTokenText = originalToken.Text;
                    string partToReplace = partialWordReplaceOperation.ComparisonToken.Text;
                    //#258 - PartialReplacementToken can be null. In this case, we consider that it's an empty replacement
                    var replacementPart = partialWordReplaceOperation.PartialReplacementToken != null ? partialWordReplaceOperation.PartialReplacementToken.Text : "";
                    // The index below is always >= 0 because CompareForReplace() above was true
                    int indexOfPartToReplace = originalTokenText.IndexOf(partToReplace, StringComparison.OrdinalIgnoreCase);
                    string replacedTokenText =
                        (indexOfPartToReplace > 0 ? originalTokenText.Substring(0, indexOfPartToReplace) : String.Empty) +
                        replacementPart +
                        ((indexOfPartToReplace + partToReplace.Length) < (originalTokenText.Length - 1) ? originalTokenText.Substring(indexOfPartToReplace + partToReplace.Length) : String.Empty);
                    // TO DO : find a way to transfer the scanner context the of original token to the call below
                    Diagnostic error = null;
                    Token generatedToken = Scanner.Scanner.ScanIsolatedTokenInDefaultContext(replacedTokenText, out error);
                    // TO DO : find a way to report the error above ...
                    ReplacedPartialCobolWord replacedPartialCobolWord = new ReplacedPartialCobolWord(generatedToken, partialWordReplaceOperation.PartialReplacementToken, originalToken);
                    return replacedPartialCobolWord;

                // One comparison token => more than one replacement tokens
                case ReplaceOperationType.SingleToMultipleTokens:
                    SingleToMultipleTokensReplaceOperation singleToMultipleTokensReplaceOperation = (SingleToMultipleTokensReplaceOperation)replaceOperation;
                    currentPosition.ReplacementTokensBeingReturned = new Token[singleToMultipleTokensReplaceOperation.ReplacementTokens.Length];
                    int i = 0;
                    foreach (Token replacementToken in singleToMultipleTokensReplaceOperation.ReplacementTokens)
                    {
                        currentPosition.ReplacementTokensBeingReturned[i] = new ReplacedToken(replacementToken, originalToken);
                        i++;
                    }
                    currentPosition.ReplacementTokenIndexLastReturned = 0;
                    return currentPosition.ReplacementTokensBeingReturned[currentPosition.ReplacementTokenIndexLastReturned];

                // One first + several following comparison tokens => zero to many replacement tokens
                //case ReplaceOperationType.MultipleTokens:
                default:
                    MultipleTokensReplaceOperation multipleTokensReplaceOperation = (MultipleTokensReplaceOperation)replaceOperation;
                    if (multipleTokensReplaceOperation.ReplacementTokens != null)
                    {
                        if (multipleTokensReplaceOperation.ReplacementTokens.Length == 1)
                        {
                            ReplacedTokenGroup replacedTokenGroup = new ReplacedTokenGroup(multipleTokensReplaceOperation.ReplacementTokens[0], originalMatchingTokens);
                            return replacedTokenGroup;
                        }
                        else
                        {
                            currentPosition.ReplacementTokensBeingReturned = new Token[multipleTokensReplaceOperation.ReplacementTokens.Length];
                            i = 0;
                            foreach (Token replacementToken in multipleTokensReplaceOperation.ReplacementTokens)
                            {
                                currentPosition.ReplacementTokensBeingReturned[i] = new ReplacedTokenGroup(replacementToken, originalMatchingTokens);
                                i++;
                            }
                            currentPosition.ReplacementTokenIndexLastReturned = 0;
                            return currentPosition.ReplacementTokensBeingReturned[currentPosition.ReplacementTokenIndexLastReturned];
                        }
                    }
                    else
                    {
                        return null;
                    }
            }
        }