# File lib/diff/lcs.rb, line 395
395:     def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks, &block) #:yields change events:
396:       matches = Diff::LCS.__lcs(seq1, seq2)
397: 
398:       run_finished_a = run_finished_b = false
399:       string = seq1.kind_of?(String)
400: 
401:       a_size = seq1.size
402:       b_size = seq2.size
403:       ai = bj = 0
404: 
405:       (0 .. matches.size).each do |ii|
406:         b_line = matches[ii]
407: 
408:         ax = string ? seq1[ii, 1] : seq1[ii]
409:         bx = string ? seq2[bj, 1] : seq2[bj]
410: 
411:         if b_line.nil?
412:           unless ax.nil?
413:             event = Diff::LCS::ContextChange.new('-', ii, ax, bj, bx)
414:             event = yield event if block_given?
415:             callbacks.discard_a(event)
416:           end
417:         else
418:           loop do
419:             break unless bj < b_line
420:             bx = string ? seq2[bj, 1] : seq2[bj]
421:             event = Diff::LCS::ContextChange.new('+', ii, ax, bj, bx)
422:             event = yield event if block_given?
423:             callbacks.discard_b(event)
424:             bj += 1
425:           end
426:           bx = string ? seq2[bj, 1] : seq2[bj]
427:           event = Diff::LCS::ContextChange.new('=', ii, ax, bj, bx)
428:           event = yield event if block_given?
429:           callbacks.match(event)
430:           bj += 1
431:         end
432:         ai = ii
433:       end
434:       ai += 1
435: 
436:         # The last entry (if any) processed was a match. +ai+ and +bj+ point
437:         # just past the last matching lines in their sequences.
438:       while (ai < a_size) or (bj < b_size)
439:           # last A?
440:         if ai == a_size and bj < b_size
441:           if callbacks.respond_to?(:finished_a) and not run_finished_a
442:             ax = string ? seq1[-1, 1] : seq1[-1]
443:             bx = string ? seq2[bj, 1] : seq2[bj]
444:             event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
445:             event = yield event if block_given?
446:             callbacks.finished_a(event)
447:             run_finished_a = true
448:           else
449:             ax = string ? seq1[ai, 1] : seq1[ai]
450:             loop do
451:               bx = string ? seq2[bj, 1] : seq2[bj]
452:               event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
453:               event = yield event if block_given?
454:               callbacks.discard_b(event)
455:               bj += 1
456:               break unless bj < b_size
457:             end
458:           end
459:         end
460: 
461:           # last B?
462:         if bj == b_size and ai < a_size
463:           if callbacks.respond_to?(:finished_b) and not run_finished_b
464:             ax = string ? seq1[ai, 1] : seq1[ai]
465:             bx = string ? seq2[-1, 1] : seq2[-1]
466:             event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
467:             event = yield event if block_given?
468:             callbacks.finished_b(event)
469:             run_finished_b = true
470:           else
471:             bx = string ? seq2[bj, 1] : seq2[bj]
472:             loop do
473:               ax = string ? seq1[ai, 1] : seq1[ai]
474:               event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
475:               event = yield event if block_given?
476:               callbacks.discard_a(event)
477:               ai += 1
478:               break unless bj < b_size
479:             end
480:           end
481:         end
482: 
483:         if ai < a_size
484:           ax = string ? seq1[ai, 1] : seq1[ai]
485:           bx = string ? seq2[bj, 1] : seq2[bj]
486:           event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
487:           event = yield event if block_given?
488:           callbacks.discard_a(event)
489:           ai += 1
490:         end
491: 
492:         if bj < b_size
493:           ax = string ? seq1[ai, 1] : seq1[ai]
494:           bx = string ? seq2[bj, 1] : seq2[bj]
495:           event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
496:           event = yield event if block_given?
497:           callbacks.discard_b(event)
498:           bj += 1
499:         end
500:       end
501:     end