def doCreateOrientationHelpers(self):
    """ 
    """
    log.debug(">>> addOrientationHelpers")
    assert self.cls == 'TemplateFactory.go',"Not a TemlateFactory.go instance!"
    assert mc.objExists(self.m.mNode),"module no longer exists"
    #Gather limb specific data and check
    #===================================
    #'orientHelpers':'messageSimple',#Orientation helper controls
    #'orientRootHelper':'messageSimple',#Root orienation helper

    helperObjects = []
    helperObjectGroups = []
    returnBuffer = []
    root = self.i_templateNull.getMessage('root')[0]
    objects =  self.i_templateNull.getMessage('controlObjects')
    log.debug(root)
    log.debug(objects)
    log.debug(self.foundDirections)
    
    #>> Create orient root control
    #=============================     
    orientRootSize = (distance.returnBoundingBoxSizeToAverage(root,True)*2.5)    
    i_orientRootControl = cgmMeta.cgmObject( curves.createControlCurve('circleArrow1',orientRootSize) )
    i_orientRootControl.addAttr('mClass','cgmObject',lock=True)
    
    curves.setCurveColorByName(i_orientRootControl.mNode,self.moduleColors[0])
    i_orientRootControl.addAttr('cgmName',value = str(self.m.getShortName()), attrType = 'string', lock=True)#<<<<<<<<<<<FIX THIS str(call) when Mark fixes bug    
    i_orientRootControl.addAttr('cgmType',value = 'templateOrientRoot', attrType = 'string', lock=True)
    i_orientRootControl.doName()
    
    #>>> Store it
    i_orientRootControl.connectParent(self.templateNull,'orientRootHelper','owner')#Connect it to it's object      
    
    #>>> Position and set up follow groups
    position.moveParentSnap(i_orientRootControl.mNode,root)    
    i_orientRootControl.parent = root #parent it to the root
    i_orientRootControl.doGroup(maintain = True)#group while maintainting position
    
    mc.pointConstraint(objects[0],i_orientRootControl.parent,maintainOffset = False)#Point contraint orient control to the first helper object
    mc.aimConstraint(objects[-1],i_orientRootControl.parent,maintainOffset = True, weight = 1, aimVector = [1,0,0], upVector = [0,1,0], worldUpObject = root, worldUpType = 'objectRotation' )
    attributes.doSetLockHideKeyableAttr(i_orientRootControl.mNode,True,False,False,['tx','ty','tz','rx','ry','sx','sy','sz','v'])
    
    self.i_orientHelpers = []#we're gonna store the instances so we can get them all after parenting and what not
    #>> Sub controls
    #============================= 
    if len(objects) == 1:#If a single handle module
        i_obj = cgmMeta.cgmObject(objects[0])
        position.moveOrientSnap(objects[0],root)
    else:
        for i,obj in enumerate(objects):
            log.debug("on %s"%(mc.ls(obj,shortNames=True)[0]))
            #>>> Create and color      
            size = (distance.returnBoundingBoxSizeToAverage(obj,True)*2) # Get size
            i_obj = cgmMeta.cgmObject(curves.createControlCurve('circleArrow2Axis',size))#make the curve
            i_obj.addAttr('mClass','cgmObject',lock=True)
            curves.setCurveColorByName(i_obj.mNode,self.moduleColors[1])
            #>>> Tag and name
            i_obj.doCopyNameTagsFromObject(obj)
            i_obj.doStore('cgmType','templateOrientHelper',True)        
            i_obj.doName()
            
            #>>> Link it to it's object and append list for full store
            i_obj.connectParent(obj,'helper','owner')#Connect it to it's object      
            self.i_orientHelpers.append(i_obj)
            log.debug(i_obj.owner)
            #>>> initial snapping """
            position.movePointSnap(i_obj.mNode,obj)
            
            if i < len(objects)-1:#If we have a pair for it, aim at that pairs aim, otherwise, aim at the second to last object
                constBuffer = mc.aimConstraint(objects[i+1],i_obj.mNode,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,1,0], worldUpVector = self.foundDirections[1], worldUpType = 'vector' )
            else:
                constBuffer = mc.aimConstraint(objects[-2],i_obj.mNode,maintainOffset = False, weight = 1, aimVector = [0,0,-1], upVector = [0,1,0], worldUpVector = self.foundDirections[1], worldUpType = 'vector' )
    
            if constBuffer:mc.delete(constBuffer)
        
            #>>> follow groups
            i_obj.parent = obj
            i_obj.doGroup(maintain = True)
            
            if i < len(objects)-1:#If we have a pair for it, aim at that pairs aim, otherwise, aim at the second to last object
                mc.aimConstraint(objects[i+1],i_obj.parent,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,1,0], worldUpVector = [0,1,0], worldUpObject = i_orientRootControl.mNode, worldUpType = 'objectrotation' )
            else:
                constBuffer = mc.aimConstraint(objects[-2],i_obj.parent,maintainOffset = False, weight = 1, aimVector = [0,0,-1], upVector = [0,1,0], worldUpObject = i_orientRootControl.mNode, worldUpType = 'objectrotation' )
    
            #>>> ConnectVis, lock and hide
            #mc.connectAttr((visAttr),(helperObj+'.v'))
            if obj == objects[-1]:
                attributes.doSetLockHideKeyableAttr(i_obj.mNode,True,False,False,['tx','ty','tz','ry','sx','sy','sz','v'])            
            else:
                attributes.doSetLockHideKeyableAttr(i_obj.mNode,True,False,False,['tx','ty','tz','rx','ry','sx','sy','sz','v'])
    #>>> Get data ready to go forward
    bufferList = []
    for o in self.i_orientHelpers:
        bufferList.append(o.mNode)
    self.i_templateNull.orientHelpers = bufferList
    self.i_orientRootHelper = i_orientRootControl
    log.debug("orientRootHelper: [%s]"%self.i_templateNull.orientRootHelper.getShortName())   
    log.debug("orientHelpers: %s"%self.i_templateNull.getMessage('orientHelpers'))

    return True
def doMakeLimbTemplate(self):  
    """
    Self should be a TemplateFactory.go
    """
    """
    returnList = []
    templObjNameList = []
    templHandleList = []
    """
    log.debug(">>> doMakeLimbTemplate")
    assert self.cls == 'TemplateFactory.go',"Not a TemlateFactory.go instance!"
    
    #Gather limb specific data and check
    #==============
    doCurveDegree = getGoodCurveDegree(self)
    if not doCurveDegree:raise ValueError,"Curve degree didn't query"
    
    #>>>Scale stuff
    size = returnModuleBaseSize(self.m)
    
    lastCountSizeMatch = len(self.corePosList) -1
    
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    # Making the template objects
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    templHandleList = []
    self.i_controlObjects = []
    self.i_locs = []
    for i,pos in enumerate(self.corePosList):# Don't like this sizing method but it is what it is for now
        #>> Make each of our base handles
        #=============================        
        if i == 0:
            sizeMultiplier = 1
        elif i == lastCountSizeMatch:
            sizeMultiplier = .8
        else:
            sizeMultiplier = .75
        
        #>>> Create and set attributes on the object
        i_obj = cgmMeta.cgmObject( curves.createControlCurve('sphere',(size * sizeMultiplier)) )
        i_obj.addAttr('mClass','cgmObject',lock=True)#tag it so it can initialize later
        
        curves.setCurveColorByName(i_obj.mNode,self.moduleColors[0])
        
        i_obj.addAttr('cgmName',value = str(self.l_coreNames[i]), attrType = 'string', lock=True)#<<<<<<<<<<<FIX THIS str(call) when Mark fixes bug
        if self.direction != None:
            i_obj.addAttr('cgmDirection',value = self.direction,attrType = 'string',lock=True)  
        i_obj.addAttr('cgmType',value = 'templateObject', attrType = 'string',lock=True) 
        i_obj.doName()#Name it
        
        mc.move (pos[0], pos[1], pos[2], [i_obj.mNode], a=True)
        i_obj.parent = self.templateNull
        
        #>>> Loc it and store the loc
        #i_loc = cgmMeta.cgmObject( i_obj.doLoc() )
        i_loc =  i_obj.doLoc()
        i_loc.addAttr('mClass','cgmObject',lock=True)#tag it so it can initialize later
        i_loc.addAttr('cgmName',value = self.m.getShortName(), attrType = 'string', lock=True) #Add name tag
        i_loc.addAttr('cgmType',value = 'templateCurveLoc', attrType = 'string', lock=True) #Add Type
        i_loc.v = False # Turn off visibility
        i_loc.doName()
        
        self.i_locs.append(i_loc)
        i_obj.connectChildNode(i_loc.mNode,'curveLoc','owner')
        i_loc.parent = self.templateNull#parent to the templateNull
        
        mc.pointConstraint(i_obj.mNode,i_loc.mNode,maintainOffset = False)#Point contraint loc to the object
                    
        templHandleList.append (i_obj.mNode)
        self.i_controlObjects.append(i_obj)
        
    #>> Make the curve
    #=============================     
    i_crv = cgmMeta.cgmObject( mc.curve (d=doCurveDegree, p = self.corePosList , os=True) )
    i_crv.addAttr('mClass','cgmObject',lock=True)#tag it so it can initialize later
    
    i_crv.addAttr('cgmName',value = str(self.m.getShortName()), attrType = 'string', lock=True)#<<<<<<<<<<<FIX THIS str(call) when Mark fixes bug
    if self.direction != None:
        i_crv.addAttr('cgmDirection',value = self.direction, attrType = 'string', lock=True)#<<<<<<<<<<<FIX THIS str(call) when Mark fixes bug

    i_crv.addAttr('cgmType',value = 'templateCurve', attrType = 'string', lock=True)
    curves.setCurveColorByName(i_crv.mNode,self.moduleColors[0])
    i_crv.parent = self.templateNull    
    i_crv.doName()
    i_crv.setDrawingOverrideSettings({'overrideEnabled':1,'overrideDisplayType':2},True)
        
    for i,i_obj in enumerate(self.i_controlObjects):#Connect each of our handles ot the cv's of the curve we just made
        mc.connectAttr ( (i_obj.curveLoc.mNode+'.translate') , ('%s%s%i%s' % (i_crv.mNode, '.controlPoints[', i, ']')), f=True )
        
    
    self.foundDirections = returnGeneralDirections(self,templHandleList)
    log.debug("directions: %s"%self.foundDirections )
    
    #>> Create root control
    #=============================  
    rootSize = (distance.returnBoundingBoxSizeToAverage(templHandleList[0],True)*1.25)    
    i_rootControl = cgmMeta.cgmObject( curves.createControlCurve('cube',rootSize) )
    i_rootControl.addAttr('mClass','cgmObject',lock=True)
    
    curves.setCurveColorByName(i_rootControl.mNode,self.moduleColors[0])
    i_rootControl.addAttr('cgmName',value = str(self.m.getShortName()), attrType = 'string', lock=True)#<<<<<<<<<<<FIX THIS str(call) when Mark fixes bug    
    i_rootControl.addAttr('cgmType',value = 'templateRoot', attrType = 'string', lock=True)
    if self.direction != None:
        i_rootControl.addAttr('cgmDirection',value = self.direction, attrType = 'string', lock=True)#<<<<<<<<<<<FIX THIS str(call) when Mark fixes bug
    i_rootControl.doName()

    #>>> Position it
    if self.m.moduleType in ['clavicle']:
        position.movePointSnap(i_rootControl.mNode,templHandleList[0])
    else:
        position.movePointSnap(i_rootControl.mNode,templHandleList[0])
    
    #See if there's a better way to do this
    log.debug("templHandleList: %s"%templHandleList)
    if self.m.moduleType not in ['foot']:
        if len(templHandleList)>1:
            log.info("setting up constraints...")        
            constBuffer = mc.aimConstraint(templHandleList[-1],i_rootControl.mNode,maintainOffset = False, weight = 1, aimVector = [0,0,1], upVector = [0,1,0], worldUpVector = self.worldUpVector, worldUpType = 'vector' )
            mc.delete (constBuffer[0])    
        elif self.m.getMessage('moduleParent'):
            #parentTemplateObjects =  self.m.moduleParent.templateNull.getMessage('controlObjects')
            helper = self.m.moduleParent.templateNull.controlObjects[-1].helper.mNode
            if helper:
                log.info("helper: %s"%helper)
                constBuffer = mc.orientConstraint( helper,i_rootControl.mNode,maintainOffset = False)
                mc.delete (constBuffer[0])    
    
    i_rootControl.parent = self.templateNull
    i_rootControl.doGroup(maintain=True)
    
    
    #>> Store objects
    #=============================      
    self.i_templateNull.curve = i_crv.mNode
    self.i_templateNull.root = i_rootControl.mNode
    self.i_templateNull.controlObjects = templHandleList
    
    self.i_rootControl = i_rootControl#link to carry

    #>> Orientation helpers
    #=============================      
    """ Make our Orientation Helpers """
    doCreateOrientationHelpers(self)
    doParentControlObjects(self.m)

    #if self.m.getMessage('moduleParent'):#If we have a moduleParent, constrain it
        #constrainToParentModule(self.m)
    return True