	
def createNodeOnCurve( side, name, number_of_nodes, main_curve, up_curve=None, create_joints=False, parent_joints_to_nodes=True, u_values_override=None, u_as_percentage=False, aim_axis='x', up_axis='y' ):
	'''
	=> This proc will create group(s) on a single curve or more.
	
	How to run:
	=> test_data = CreateNodeOnCurve( '', 'test', 10, 'path_crv' )   
	  
	Options:
	=> If you specify an up curve those groups will use it as up_vector.
	==> If you want to create joint(s) it will add joint(s) driven by the group(s).
	===> If you specify parent_joints_to_nodes = 1 the joint will be parented under the node(s), if 0 joint(s) will be parented under 'jointHierarchy'.
	====> If you specify u_values_override = [0.1,0.2,0.3] the node(s) will use those value(s) as motion path u value(s) otherwise they are uniformly spreaded.
	=====> If you set u_as_percentage = 1 the u values will be used as a pourcentage of the lenth of the curve, otherwise it will be used as the "raw" u value of the curve.
	======> If you specify aim_axis or up_axis you can get different orientation for your objects.
	
	How to get infor back after creation ?
	=> the object created in this proc get attributes added to all of them
	'''
	
	########
	# TEST
	########
	
	if not cmds.objExists(main_curve): 
		cmds.error('the main curve: "'+main_curve+ '" do not exists in your scene (createNodeOnCurve)' )	
	if up_curve: 
		if not cmds.objExists(up_curve): 
			cmds.error('the main curve: "'+up_curve+ '" do not exists in your scene (createNodeOnCurve)' )	
	
	########
	# GET FULL NAME
	########
	
	fullname = name
	if side:
		fullname = side+'_'+name

	########
	# FEW HELPERS
	########
	
	# create a group on a curve using a motion path
	def _createSingleNodeOnSingleCurve( fullname, main_curve, aim_int, inverse_front, up_int, inverse_up, u_as_percentage):
		grp = cmds.group( em=True, n=fullname+'_null' )
		main_curve_shape = cmds.listRelatives( main_curve, shapes=True )[0]
		motion_path = cmds.createNode( 'motionPath', n=fullname+'_MP' )
		cmds.connectAttr( main_curve_shape+'.worldSpace', motion_path+'.geometryPath' )
		cmds.connectAttr( motion_path+'.rotateOrder', grp+'.rotateOrder' )
		cmds.connectAttr( motion_path+'.rotate', grp+'.r' )
		cmds.connectAttr( motion_path+'.allCoordinates', grp+'.translate' )

		cmds.setAttr( motion_path+'.worldUpType', 1 )
		cmds.setAttr( motion_path+'.frontAxis', aim_int )
		cmds.setAttr( motion_path+'.upAxis', up_int )
		cmds.setAttr( motion_path+'.inverseUp', inverse_up )
		cmds.setAttr( motion_path+'.inverseFront', inverse_front )
		cmds.setAttr( motion_path+'.fractionMode', int(u_as_percentage) )

		return motion_path, grp

	# get the info necessary to populate the motion path option from a string axis.
	def _getAxeInfos( stringAxe ):
		vecAxe = [1,0,0]
		reverse = 0
		intAxe = 0
		if '-' in stringAxe:
			reverse = 1
		if stringAxe == '-x':
			vecAxe = [-1,0,0] 