#
# Traversing and printing the simple graph
# to show the interactions between visitors.
#

#!>>
#! The dependency graph is:
#!
#! package
#!     <-> p2
#!     class
#!         <-> c2
#!         feature
#!             <-> f2
#!
#!<<

client:Client[r] "client"
filter:SelectiveVisitor
strategy:TraversalStrategy
text:TextPrinter
traversal:BasicTraversal
package:PackageNode
class:ClassNode
feature:FeatureNode
p2:PackageNode
c2:ClassNode
f2:FeatureNode

client:filter.traverseNodes(packageNodes)
filter:orderedPackageNodes=strategy.order(packageNodes)
filter:text.traverseNodes(orderedPackageNodes)
text:traversal.traverseNodes(orderedPackageNodes)
[c:loop for each ordered package node]
  traversal:package.accept(filter)
  package:filter.visitPackageNode(package)
  filter:t/f=strategy.isInScope(package)
  [c:alt package is in scope]
    filter:package.accept(text)
    package:text.visitPackageNode(package)
    text:package.getName()
    text:package.accept(traversal)
    package:traversal.visitPackageNode(package)
    traversal:traversal.traverseNodeDependencies(package)

    # Traverse inbound dependencies of "package": p2
    traversal:inbounds=package.getInboundDependencies()
    traversal:filter.traverseInbounds(inbounds)
    filter:orderedInbounds=strategy.order(inbounds)
    filter:text.traverseInbounds(orderedInbounds)
    text:traversal.traverseInbounds(orderedInbounds)
    [c:loop for each ordered inbound]
      traversal:p2.acceptInbound(filter)
      p2:filter.visitInboundPackageNode(p2)
      filter:t/f=strategy.isInFilter(p2)
      [c:alt p2 is in filter]
        filter:p2.acceptInbound(text)
        p2:text.visitInboundPackageNode(p2)
        text:name=p2.getName()
        text:p2.acceptInbound(traversal)
        p2:traversal.visitInboundPackageNode(p2)
        traversal:noop
      [/c]
    [/c]

    # Traverse outbound dependencies of "package": p2
    traversal[2]:outbounds=package.getOutboundDependencies()
    traversal:filter.traverseOutbounds(outbounds)
    filter:orderedOutbounds=strategy.order(outbounds)
    filter:text.traverseOutbounds(orderedOutbounds)
    text:traversal.traverseOutbounds(orderedOutbounds)
    [c:loop for each ordered outbound]
      traversal:p2.acceptOutbound(filter)
      p2:filter.visitOutboundPackageNode(p2)
      filter:t/f=strategy.isInFilter(p2)
      [c:alt p2 is in filter]
        filter:p2.acceptOutbound(text)
        p2:text.visitOutboundPackageNode(p2)
        text:name=p2.getName()
        text:p2.acceptOutbound(traversal)
        p2:traversal.visitOutboundPackageNode(p2)
        traversal:noop
      [/c]
    [/c]

    # Traverse classes in "package"
    traversal[3]:classNodes=package.getClasses()
    traversal:filter.traverseNodes(classNodes)
    filter:orderedClassNodes=strategy.order(classNodes)
    filter:text.traverseNodes(orderedClassNodes)
    text:traversal.traverseNodes(orderedClassNodes)
    [c:loop for each ordered class node]
      traversal:class.accept(filter)
      class:filter.visitClassNode(class)
      filter:t/f=strategy.isInScope(class)
      [c:alt class is in scope]
        filter:class.accept(text)
        class:text.visitClassNode(class)
        text:class.getName()
        text:class.accept(traversal)
        class:traversal.visitClassNode(class)
        traversal:traversal.traverseNodeDependencies(class)

        # Traverse inbound dependencies of "class": c2
        traversal:inbounds=class.getInboundDependencies()
        traversal:filter.traverseInbounds(inbounds)
        filter:orderedInbounds=strategy.order(inbounds)
        filter:text.traverseInbounds(orderedInbounds)
        text:traversal.traverseInbounds(orderedInbounds)
        [c:loop for each ordered inbound]
          traversal:c2.acceptInbound(filter)
          c2:filter.visitInboundClassNode(c2)
          filter:t/f=strategy.isInFilter(c2)
          [c:alt c2 is in filter]
            filter:c2.acceptInbound(text)
            c2:text.visitInboundClassNode(c2)
            text:name=c2.getName()
            text:c2.acceptInbound(traversal)
            c2:traversal.visitInboundClassNode(c2)
            traversal:noop
         [/c]
        [/c]

        # Traverse outbound dependencies of "class": c2
        traversal[2]:outbounds=class.getOutboundDependencies()
        traversal:filter.traverseOutbounds(outbounds)
        filter:orderedOutbounds=strategy.order(outbounds)
        filter:text.traverseOutbounds(orderedOutbounds)
        text:traversal.traverseOutbounds(orderedOutbounds)
        [c:loop for each ordered outbound]
          traversal:c2.acceptOutbound(filter)
          c2:filter.visitOutboundClassNode(c2)
          filter:t/f=strategy.isInFilter(c2)
          [c:alt c2 is in filter]
            filter:c2.acceptOutbound(text)
            c2:text.visitOutboundClassNode(c2)
            text:name=c2.getName()
            text:c2.acceptOutbound(traversal)
            c2:traversal.visitOutboundClassNode(c2)
            traversal:noop
          [/c]
        [/c]

        # Traverse features of "class"
        traversal[3]:featureNodes=class.getFeatures()
        traversal:filter.traverseNodes(featureNodes)
        filter:orderedFeatureNodes=strategy.order(featureNodes)
        filter:text.traverseNodes(orderedFeatureNodes)
        text:traversal.traverseNodes(orderedFeatureNodes)
        [c:loop for each ordered feature node]
          traversal:feature.accept(filter)
          feature:filter.visitFeatureNode(feature)
          filter:t/f=strategy.isInScope(feature)
          [c:alt feature is in scope]
            filter:feature.accept(text)
            feature:text.visitFeatureNode(feature)
            text:feature.getName()
            text:feature.accept(traversal)
            feature:traversal.visitFeatureNode(feature)
            traversal:traversal.traverseNodeDependencies(feature)

            # Traverse inbound dependencies of "feature": f2
            traversal:inbounds=feature.getInboundDependencies()
            traversal:filter.traverseInbounds(inbounds)
            filter:orderedInbounds=strategy.order(inbounds)
            filter:text.traverseInbounds(orderedInbounds)
            text:traversal.traverseInbounds(orderedInbounds)
            [c:loop for each ordered inbound]
              traversal:f2.acceptInbound(filter)
              f2:filter.visitInboundFeatureNode(f2)
              filter:t/f=strategy.isInFilter(f2)
              [c:alt f2 is in filter]
                filter:f2.acceptInbound(text)
                f2:text.visitInboundFeatureNode(f2)
                text:name=f2.getName()
                text:f2.acceptInbound(traversal)
                f2:traversal.visitInboundFeatureNode(f2)
                traversal:noop
             [/c]
            [/c]

            # Traverse outbound dependencies of "feature": f2
            traversal[2]:outbounds=feature.getOutboundDependencies()
            traversal:filter.traverseOutbounds(outbounds)
            filter:orderedOutbounds=strategy.order(outbounds)
            filter:text.traverseOutbounds(orderedOutbounds)
            text:traversal.traverseOutbounds(orderedOutbounds)
            [c:loop for each ordered outbound]
              traversal:f2.acceptOutbound(filter)
              f2:filter.visitOutboundFeatureNode(f2)
              filter:t/f=strategy.isInFilter(f2)
              [c:alt f2 is in filter]
                filter:f2.acceptOutbound(text)
                f2:text.visitOutboundFeatureNode(f2)
                text:name=f2.getName()
                text:f2.acceptOutbound(traversal)
                f2:traversal.visitOutboundFeatureNode(f2)
                traversal:noop
              [/c]
            [/c]

          [/c]
        [/c]
      [/c]
    [/c]
  [/c]
[/c]