# File lib/diff/lcs.rb, line 585
585:     def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
586:       matches = Diff::LCS.__lcs(seq1, seq2)
587:       a_size = seq1.size
588:       b_size = seq2.size
589:       ai = bj = mb = 0
590:       ma = -1
591:       string = seq1.kind_of?(String)
592: 
593:         # Process all the lines in the match vector.
594:       loop do
595:           # Find next match indices +ma+ and +mb+
596:         loop do
597:           ma += 1
598:           break unless ma < matches.size and matches[ma].nil?
599:         end
600: 
601:         break if ma >= matches.size # end of matches?
602:         mb = matches[ma]
603: 
604:           # Change(seq2)
605:         while (ai < ma) or (bj < mb)
606:           ax = string ? seq1[ai, 1] : seq1[ai]
607:           bx = string ? seq2[bj, 1] : seq2[bj]
608: 
609:           case [(ai < ma), (bj < mb)]
610:           when [true, true]
611:             if callbacks.respond_to?(:change)
612:               event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
613:               event = yield event if block_given?
614:               callbacks.change(event)
615:               ai += 1
616:               bj += 1
617:             else
618:               event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
619:               event = yield event if block_given?
620:               callbacks.discard_a(event)
621:               ai += 1
622:               ax = string ? seq1[ai, 1] : seq1[ai]
623:               event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
624:               event = yield event if block_given?
625:               callbacks.discard_b(event)
626:               bj += 1
627:             end
628:           when [true, false]
629:             event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
630:             event = yield event if block_given?
631:             callbacks.discard_a(event)
632:             ai += 1
633:           when [false, true]
634:             event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
635:             event = yield event if block_given?
636:             callbacks.discard_b(event)
637:             bj += 1
638:           end
639:         end
640: 
641:           # Match
642:         ax = string ? seq1[ai, 1] : seq1[ai]
643:         bx = string ? seq2[bj, 1] : seq2[bj]
644:         event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
645:         event = yield event if block_given?
646:         callbacks.match(event)
647:         ai += 1
648:         bj += 1
649:       end
650: 
651:       while (ai < a_size) or (bj < b_size)
652:         ax = string ? seq1[ai, 1] : seq1[ai]
653:         bx = string ? seq2[bj, 1] : seq2[bj]
654: 
655:         case [(ai < a_size), (bj < b_size)]
656:         when [true, true]
657:           if callbacks.respond_to?(:change)
658:             event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
659:             event = yield event if block_given?
660:             callbacks.change(event)
661:             ai += 1
662:             bj += 1
663:           else
664:             event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
665:             event = yield event if block_given?
666:             callbacks.discard_a(event)
667:             ai += 1
668:             ax = string ? seq1[ai, 1] : seq1[ai]
669:             event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
670:             event = yield event if block_given?
671:             callbacks.discard_b(event)
672:             bj += 1
673:           end
674:         when [true, false]
675:           event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
676:           event = yield event if block_given?
677:           callbacks.discard_a(event)
678:           ai += 1
679:         when [false, true]
680:           event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
681:           event = yield event if block_given?
682:           callbacks.discard_b(event)
683:           bj += 1
684:         end
685:       end
686:     end