def __call__(self, morph=None):
     self.morph = ExactlyOneNotNone(morph, self.morph)
     if not self.alreadycalled:
         self.pretraversefunctor()
         self.VisitSectionInternal(self.morph.getDummySection())
         self.posttraversefunctor()
         self.alreadycalled = True
         
     return self.returnfunctor() 
class SectionVisitorDF(object):
    
    
    @classmethod
    def build(cls, functor, morph ):
        v = SectionVisitorDF(functor=functor)
        return v(morph)
    
    
    def __init__(self, functor, morph=None, dummysectionfunctor=None, rootsectionfunctor=None, returnfunctor=lambda:None, pretraversefunctor=lambda:None, posttraversefunctor=lambda:None):
        self.functor = functor
        self.dummysectionfunctor = dummysectionfunctor
        self.rootsectionfunctor = rootsectionfunctor if rootsectionfunctor else functor
        self.returnfunctor = returnfunctor
        self.pretraversefunctor = pretraversefunctor
        self.posttraversefunctor = posttraversefunctor
        
        self.alreadycalled = False
        self.morph = morph
        
        if self.morph != None:
            self.__call__()
    
    def __call__(self, morph=None):
        self.morph = ExactlyOneNotNone(morph, self.morph)
        if not self.alreadycalled:
            self.pretraversefunctor()
            self.VisitSectionInternal(self.morph.getDummySection())
            self.posttraversefunctor()
            self.alreadycalled = True
            
        return self.returnfunctor() 
        
    def isVisitRoot(self):
        return self.rootsectionfunctor != None

    def isVisitDummy(self):
        return self.dummysectionfunctor != None

        
    def VisitSectionInternal(self, section):
        """ Implements:  1. Visit the node. 2. Traverse the subtrees. """
        if section.isDummySection():
            if self.isVisitDummy(): 
                assert False
                self.dummysectionfunctor(section)
        elif section.isARootSection():
            if self.isVisitRoot():
                self.rootsectionfunctor(section)
        else: 
            self.functor(section)
        
        for c in section.children:
            self.VisitSectionInternal(c)