/*
name			: Class Behaviour
update			: 20070705
author			: Maurice van Creij
dependencies	: lib_classbehaviour.js
info			: http://www.woollymittens.nl/
*/
	// MAIN
	// main class-behaviour object
	function ClassBehaviour(){
		// properties
		this.handlers			=	new Array();
		// methods
		this.parseDocument		=	function(node){
										target = (node) ? node : document;
										// get all document nodes
										var allNodes = (target.all) ? target.all : target.getElementsByTagName("*");
										// for all tags
										for(var a=0; a<allNodes.length; a++){ // for(var a=allNodes.length-1; a>=0; a--){
											// if the item has a className
											if(allNodes[a].className){
												// get the classname
												nodeClass = allNodes[a].className;
												// for all behaviours
												for(var b=0; b<this.handlers.length; b++){
													// if the behaviour's name exists in the class name, apply it's events
													if(nodeClass.indexOf(this.handlers[b].name)>-1) this.handlers[b].start(allNodes[a]);
												}
											}
										}
									}
		this.utilities			=	new Utilities;
	}
	// create the main class-behaviour object
	var classBehaviour = new ClassBehaviour;
	
	// UTILITIES
		// General purpose functions
		function Utilities(){
			// returns a string of parameters found in the classname which can be [eval]uated
			this.getClassParameter	=	function(targetNode, paramName, defaultValue){
											// get the class parameter from the classname
											var classParameter = targetNode.className;
											// split the classname between the parameter name
											classParameter = classParameter.split(paramName + '_');
											// split the second piece between spaces and take the first part,  if there are two pieces
											classParameter = (classParameter.length>1) ? classParameter[1].split(' ')[0] : null ;
											// return the value
											return (classParameter!=null) ? classParameter : defaultValue ;
										}
			// get the next node without worrying about text nodes
			this.nextNode			=	function(node, count){
											testNode = node;
											if(count==null) count = 1;
											// look for the next html node
											for(var a=0; a<count; a++){
												do {
													testNode = testNode.nextSibling;
													if(testNode==null) testNode = node;
												}while(testNode.nodeName.indexOf('#text')>-1);
											}
											// return it
											return testNode;
										}
			// get the previous node without worrying about text nodes
			this.previousNode		=	function(node, count){
											testNode = node;
											if(count==null) count = 1;
											// look for the previous html node
											for(var a=0; a<count; a++){
												do {
													testNode = testNode.previousSibling;
													if(testNode==null) testNode = node;
												}while(testNode.nodeName.indexOf('#text')>-1);
											}
											// return it
											return testNode;
										}
			// get the first real child node without worrying about text nodes
			this.firstNode			=	function(node, count){
											return this.nextNode(node.firstChild, count);
										}
			// returns the visible display state needed for this element
			this.getVisibleState	=	function(node){
											// what kind of node is this
											switch(node.nodeName.toLowerCase()){
												case 'table' : visibleState='table' ; break;
												case 'thead' : visibleState='table-header-group' ; break;
												case 'tfoot' : visibleState='table-footer-group' ; break;
												case 'tbody' : visibleState='table-row-group' ; break;
												case 'tr' : visibleState='table-row' ; break;
												case 'td' : visibleState='table-cell' ; break;
												case 'th' : visibleState='table-cell' ; break;
												default : visibleState='block';
											}
											// apply the state
											return (document.all && navigator.userAgent.indexOf('Opera')<0) ? 'block' : visibleState;
										}
		}
		
	// BEHAVIOURs
	
	// hides nodes
		// hide the "hideThisNode" class behaviour by default 
		document.writeln("<style>.hideThisNode{overflow:hidden; visibility:hidden; height:1px;}</style>");
		// define this class behaviour
		function HideThisNode(){
			// properties
			this.name 		= 	'hideThisNode';
			// methods
			this.start		=	function(node){
									node.style.overflow = 'hidden';
									node.style.visibility = 'hidden';
									node.style.height = '1px';
									node.className = node.className.replace('showThisNode', 'hideThisNode');
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.hideThisNode = new HideThisNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.hideThisNode;
		
	// explicit opposite of a hidden node
		// define this class behaviour
		document.writeln("<style>.ShowThisNode{overflow:visible; visibility:visible; height:auto;}</style>");
		function ShowThisNode(){
			// properties
			this.name 		= 	'showThisNode';
			// methods
			this.start		=	function(node){
									node.style.overflow = 'visible';
									node.style.visibility = 'visible';
									node.style.height = 'auto';
									node.className = node.className.replace('hideThisNode', 'showThisNode');
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.showThisNode = new ShowThisNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.showThisNode;
		
	// show or hide a node
		// define this class behaviour
		document.writeln("<style>.toggleNextNode{cursor:pointer;}</style>");
		function ToggleNextNode(){
			/* properties */
			this.name 			= 	'toggleNextNode';
			this.nodes			=	new Array();
			this.step			=	20;
			this.delay			=	10;
			this.index			=	0;
			/* methods */
			this.start			=	function(node){
										// set the event handlers for the source node
										node.onclick = this.toggle;
										// add this node to the node list
										this.nodes[this.nodes.length] = node;
										// give this node an id if it doesn't have one yet
										node.id = (node.id) ? node.id : this.name + this.nodes.length ;
										// is this node marked as "auto", order it to open on a timeout
										autoDelay = classBehaviour.utilities.getClassParameter(node, 'auto', null);
										if(autoDelay){
											this.index++
											node.id = (node.id) ? node.id : this.name + this.index ;
											setTimeout('classBehaviour.toggleNextNode.toggle(document.getElementById("'+node.id+'"))', autoDelay);
										}
									}
			this.shrink			=	function(label, container, finished){
										var t2n = classBehaviour.toggleNextNode;
										// deactivate the label
										label.className = label.className.replace('active','link');
										label.parentNode.className = label.parentNode.className.replace('active','link');
										// if the container isn't shrunk completely
										if(container.offsetHeight>t2n.step){
											// height before
											heightBefore = container.style.height;
											// reduce its height by an amount
											container.style.overflow = 'hidden';
											container.style.visibility = 'visible';
											container.style.height = (container.offsetHeight - t2n.step) + 'px';
											// height after
											heightAfter = container.style.height;
											// the resizing isnt' working, skip straight to the end situation
											finished = (heightBefore==heightAfter) ? classBehaviour.hideThisNode.start(container) : false ;
										}else{
											// close the container
											classBehaviour.hideThisNode.start(container);
										}
										// return the state
										return finished;
									}
			this.grow			=	function(label, container, finished){
										var t2n = classBehaviour.toggleNextNode;
										// activate the label
										label.className = label.className.replace('link','active').replace('hover','active');
										label.parentNode.className = label.parentNode.className.replace('link','active').replace('hover','active');
										// measure the height of all the childnodes of the container
										totalHeight = 0;
										contents = container.childNodes;
										for(var a=0; a<contents.length; a++){
											totalHeight += (contents[a].offsetHeight) ? contents[a].offsetHeight : 0 ;
										}
										// if the container isn't grown completely
										if(container.offsetHeight<totalHeight-t2n.step){
											// height before
											heightBefore = container.style.height;
											// increase its height by an amount
											container.style.overflow = 'hidden';
											container.style.visibility = 'visible';
											container.style.height = (container.offsetHeight + t2n.step) + 'px';
											// height after
											heightAfter = container.style.height;
											// the resizing isnt' working, skip straight to the end situation
											finished = (heightBefore==heightAfter) ? classBehaviour.showThisNode.start(container) : finished = false;
										}else{
											// open the container
											classBehaviour.showThisNode.start(container);
										}
										// return the state
										return finished;
									}
			this.findContainer	=	function(targetLabel, targetRecursion){
										// if there was a target recursion, recurse parent nodes
										if(targetRecursion) for(var a=0; a<parseInt(targetRecursion); a++) targetLabel = targetLabel.parentNode;
										// get the next sibling of the label, which should be the container
										targetObject = classBehaviour.utilities.nextNode(targetLabel);
										// pass it back
										return targetObject;
									}
			/* events */
			this.toggle 		= 	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var t2n = classBehaviour.toggleNextNode;
										// get all information on this node
										targetLabel = objNode;
										targetContainerId = classBehaviour.utilities.getClassParameter(targetLabel, 'id', null);
										targetRecursion = classBehaviour.utilities.getClassParameter(targetLabel, 'parent', null);
										targetContainer = (targetContainerId) ? document.getElementById(targetContainerId) : t2n.findContainer(targetLabel, targetRecursion) ;
										// if the target container is not marked for hiding or showing, mark it now
										if(targetContainer.className.indexOf('hideThisNode')<0 && targetContainer.className.indexOf('showThisNode')<0) targetContainer.className += ' showThisNode' ;
										// call for the node to grow or shrink
										targetGrows = (targetContainer.className.indexOf('hideThisNode')>-1);
										t2n.update(targetLabel.id, targetGrows);
										// cancel the click
										return false;
									}
			this.update			=	function(id, grows){
										var t2n = classBehaviour.toggleNextNode;
										// finished marker
										finished = true;
										// get all information on this node
										targetLabel = document.getElementById(id);
										targetContainerId = classBehaviour.utilities.getClassParameter(targetLabel, 'id', null);
										targetFamily = classBehaviour.utilities.getClassParameter(targetLabel, 'family', null);
										targetRecursion = classBehaviour.utilities.getClassParameter(targetLabel, 'parent', null);
										targetContainer = (targetContainerId) ? document.getElementById(targetContainerId) : t2n.findContainer(targetLabel, targetRecursion) ;
										// for every node in the node-list
										for(var a=0; a<t2n.nodes.length; a++){
											// get its family
											peerLabel = t2n.nodes[a];
											peerContainerId = classBehaviour.utilities.getClassParameter(peerLabel, 'id', null);
											peerFamily = classBehaviour.utilities.getClassParameter(peerLabel, 'family', null);
											peerRecursion = classBehaviour.utilities.getClassParameter(peerLabel, 'parent', null);
											peerContainer = (peerContainerId) ? document.getElementById(peerContainerId) : t2n.findContainer(peerLabel, peerRecursion) ;
											// if this node belongs to the same family and is open but has a different id
											if(peerFamily==targetFamily && peerFamily!=null && peerContainer.className.indexOf('hideThisNode')<0 && peerContainer!=targetContainer){
												// close the container one step
												finished = this.shrink(peerLabel, peerContainer, finished);
											// else if this node has the same id and is open
											}else if(peerLabel.id==targetLabel.id && !grows){
												// close the container one step
												finished = this.shrink(targetLabel, targetContainer, finished);
											// else 
											}else if(peerLabel.id==targetLabel.id && grows){
												// open the container one step
												finished = this.grow(targetLabel, targetContainer, finished);
											}
										}
										// if any step marked the function as unfinished
										if(!finished){
											// repeat it
											setTimeout("classBehaviour.toggleNextNode.update('"+id+"',"+grows+")", t2n.delay);
										}else{
											// notify the iframe resizer to update its size if needed
											if(document.body.className.indexOf('resizeIframe')>-1) classBehaviour.resizeIframe.delay();
										}
									}
		}
		// add this function to the classbehaviour object
		classBehaviour.toggleNextNode = new ToggleNextNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.toggleNextNode;
		
	// Triggers all validateInput class behaviours within a node after the onsubmit event.',
		// define this class behaviour
		function ValidateAllInput(){
			// properties
			this.name 		= 	'validateAllInput';
			// methods
			this.start		=	function(node){
									// set the form validation eventhandler
								//	node.addEventListener('submit', classBehaviour.validateInput.all, false);
								 	node.onsubmit = classBehaviour.validateInput.all;
									// if there's a place for a summary store the id
									classBehaviour.validateInput.summaryId = classBehaviour.utilities.getClassParameter(node, 'summaryId', null);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.validateAllInput = new ValidateAllInput;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.validateAllInput;

	// Validate the value of a for element to a predefined regular expression
		// define this class behaviour
		function ValidateInput(){
			// properties
			this.name 		= 	'validateInput';
			this.summaryId	=	null;
			// methods
			this.start	=	function(node){
								// was a summary requested?
								this.summaryId = classBehaviour.utilities.getClassParameter(node, 'summaryId', this.summaryId);
								// apply the event to all form-element childnodes
								var nodes = (this.isFormElement(node)) ? new Array(node) : node.getElementsByTagName('*');
								for(var a=0; a<nodes.length; a++){
									if(this.isFormElement(nodes[a])){
										// give it the event handler
										nodes[a].onfocus = this.clear;
										//nodes[a].onblur = this.input;
										//nodes[a].onchange = this.input;
										// if the form is small enough one could revalidate the whole thing at every change
											//nodes[a].onblur = this.all;
											//nodes[a].onchange = this.all;
										// and the parent's classname
										nodes[a].className = node.className;
									}
								}
								// if there's a greyed axplanation
								hasExplanation = classBehaviour.utilities.getClassParameter(node, 'explanation', 'no');
								if(hasExplanation=='yes'){
									// remove it if a value is restored by a form manager
									setTimeout("classBehaviour.validateInput.restore('"+node.id+"','"+node.value+"')", 1000);
								}
							}
			this.all 	= 	function(that){
								var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
								var vi = classBehaviour.validateInput;
								var booPassed = true;
								// get all subnodes in the form
									var objSubNodes = objNode.getElementsByTagName("*") ;
									// var objSubNodes = document.getElementsByTagName("*") ;
								// for all nodes
								for(var intA=0; intA<objSubNodes.length; intA++){
									// Does this node have the validateInput put class? Invoke the validator function upon it.
									if(objSubNodes[intA].className.toLowerCase().indexOf('validateinput')>-1 && vi.isFormElement(objSubNodes[intA])) booPassed = (vi.input(objSubNodes[intA], false) && booPassed);
								}
								vi.summaryId = classBehaviour.utilities.getClassParameter(objNode,'summaryId', null);
								// is a summary required
								if(vi.summaryId){
									summaryObj = document.getElementById(vi.summaryId);
									summaryTxt = '';
									// for all nodes
									for(var a=0; a<objSubNodes.length; a++){
										// if this node a visible warning
										if(objSubNodes[a].className.indexOf('validationWarning')>-1 && objSubNodes[a].style.display!='none'){
											// copy it's contents to the summary text
											summaryTxt += '<li>' + objSubNodes[a].innerHTML + '</li>';
										}
									}
									// add the summary text to the summary
									summaryObj.innerHTML = (summaryTxt.length>0) ? '<ul>' + summaryTxt + '</ul>' : '' ;
								}
// NOTE: Special hack-sauce to override jquery.
								if(booPassed){
									referId = classBehaviour.utilities.getClassParameter(objNode,'referId','infoContent');
									setDivID(referId); 
									return AIM.submit(this, {onStart: startCallback, onComplete: completeCallback});
								}else{
									return false;
								}
// /NOTE
								// is the form valid enough?
							//	return booPassed;
							}
			this.input = 	function(that, override){
								var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
								var vi = classBehaviour.validateInput;
								// default validator values
								var booEmptyValidator, booValueValidator;
								// get the type of validation required			
								strValidatorName	= classBehaviour.utilities.getClassParameter(objNode, 'type', '');
								allowEmpty			= classBehaviour.utilities.getClassParameter(objNode, 'allowEmpty', 'no');
								ifCheckedId			= classBehaviour.utilities.getClassParameter(objNode, 'ifCheckedId', null);
								hasExplanation 		= classBehaviour.utilities.getClassParameter(objNode, 'explanation', 'no');
								// check a special dependency on a parent checkbox
								if(ifCheckedId){
									if(!document.getElementById(ifCheckedId).checked) allowEmpty = 'yes';
								}
								// validation tests
									// empty test	objNode.value!=''
									booEmptyValidator = (allowEmpty=='yes' && (objNode.value=='' || hasExplanation=='yes'));
									// bizarre exception for MSIE 5.0
									if(navigator.appVersion.indexOf('MSIE 5.0')>-1 && strValidatorName=='money') strValidatorName = null;
									// test expressions
									switch(strValidatorName){
										// regular expression tests
										case 'email' : 
											booValueValidator = (objNode.value.match(/^[\w\.\-\,\+]+@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/)!=null);
											break;
										case 'phone' : 
											booValueValidator = (objNode.value.match(/(^\+[0-9]{2}|^\+[0-9]{2}\(0\)|^\(\+[0-9]{2}\)\(0\)|^00[0-9]{2}|^0)([0-9]{9}$|[0-9\-\s]{10}$)/)!=null); 
											break;
										case 'dutchzipcode' : 
											booValueValidator = (objNode.value.match(/^[0-9]{4}\s{0,1}[a-zA-Z]{2}$/)!=null); 
											break;
										case 'date' : 
											booValueValidator = (objNode.value.match(/^\d{4}\-\d{1,2}\-\d{1,2}$/)!=null);
											// booRegExpValidator = (objNode.value.match(/^\d{1,2}\-\d{1,2}\-(\d{2}|\d{4})$/)!=null); 
											break;
										case 'number' : 
											booValueValidator = (objNode.value.match(/^[0-9]+$/)!=null); 
											break;
										case 'money' :
											booValueValidator = (objNode.value.match(/^[0-9]+(\.[0-9]{1,2})?$/)!=null); 
											break;
										case 'alphanumeric' :
											booValueValidator = (objNode.value.match(/^[a-zA-Z0-9]/)!=null);
											break;
										// custom tests
										case 'bankaccount' :
											booValueValidator = vi.bankAccount(objNode);
											break;
										case 'isradiochecked' :
											booValueValidator = vi.isRadioChecked(objNode);
											break;
										case 'anyofthesechecked' : 
											booValueValidator = vi.anyOfTheseChecked(objNode);
											break;
										case 'text' :
											booValueValidator = (objNode.value!="");
											break;
										default :
											booValueValidator = true;
									}
								// does the input validate when the field is not empty or not allowed to be empty
								validates = (!booEmptyValidator) ? (booValueValidator && hasExplanation=='no') : true ;
								// show or hide the warning message based on the validator's match
								vi.warning(objNode, validates);
								// return a pass of fail boolean to whoever may want to know the results of the test
								return (override!=null) ? validates : override;
							}
			this.warning =	function(objNode, status){
								var vi = classBehaviour.validateInput;
								// for all inputs with the same name
								allWithSameName = document.getElementsByName(objNode.name);
								for(var b=0; b<allWithSameName.length; b++){
									objNode = allWithSameName[b];
								// Show the foldout warning
									// is the warning node named?
									idWarningNode		= classBehaviour.utilities.getClassParameter(objNode, 'warningId', null);
									// check if the next node is for summaries
									nextNode 			= classBehaviour.utilities.nextNode(objNode);
									// if there's an id given for thewarning message use it. Otherwise use the next node
									objWarningNode		= (idWarningNode) ? document.getElementById(idWarningNode) : nextNode ;
									// show or hide the warning, if the warning node was found
									if(objWarningNode) if(objWarningNode.className.indexOf('validationWarning')>-1) objWarningNode.style.display = (status) ? 'none' : 'block' ;
								// Highlight the label
									// get all labels
									allLabels = document.getElementsByTagName('label');
									// for all labels
									for(var a=0; a<allLabels.length; a++){
										// if the label matches this input
										if(allLabels[a].getAttributeNode('for')){
											if(allLabels[a].getAttributeNode('for').nodeValue == objNode.id){
												// add or remove the warning colour
										//		if(allLabels[a].parentNode.className.indexOf('noWarning')<0 && allLabels[a].className.indexOf('noWarning')<0) allLabels[a].className = (status) ? '' : 'warning' ;
											}
										}
									}
								}
							}
			this.clear	=	function(objNode){
								var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
								// if there was an explanation provides as a value
								hasExplanation = classBehaviour.utilities.getClassParameter(objNode, 'explanation', 'no');
								if(hasExplanation=='yes'){
									// clear the value
									objNode.value = '';
									// che change the class back to normal
									objNode.className = objNode.className.replace('explanation_yes', 'explanation_no');
								}
							}
			this.restore =	function(id, value){
								var objNode = document.getElementById(id);
								// if this input has a value which doesn't match the current value, a form manager has restored a value
								if(objNode.value!=value){
									objNode.className = objNode.className.replace('explanation_yes','explanation_no');
								}
							}
			/* utility functions */
			this.isFormElement		=	function(objNode){
											return (objNode.nodeName=='INPUT' || objNode.nodeName=='SELECT' || objNode.nodeName=='TEXTAREA');
										}
			/* custom validation functions */
			this.bankAccount 		= 	function(objNode){
											var intDeel, intRest;
											var strInput = objNode.value;
											var intTot=0;
											if (strInput.length!=9){
												return false;
											}else{
												for (i=0; i<strInput.length; i++) intTot += strInput.substr(i,1) * (9 - i);
												intDeel = intTot/11;
												intRest = intTot%11;
												return (intRest==0);
											}
										}
			this.isRadioChecked	=	function(objNode){
											// get all inputs with this name
											allInputs = document.getElementsByTagName('input');
											// for all inputs
											for(var a=0; a<allInputs.length; a++){
												// If the input has the same name. 
												if(allInputs[a].name == objNode.name){
													// If the input is checked set the validator to true
													if(allInputs[a].checked) return true;
												}
											}
											return false;
										}
			this.anyOfTheseChecked	=	function(objNode){
												// default validatie
												anyChecked = false;
												// get all inputs from the parentnode
												allChecks = objNode.parentNode.parentNode.getElementsByTagName('input');
												// for all inputs
												for(var a=0; a<allChecks.length; a++){
													// if this checkbox is checked remember is
													if(allChecks[a].checked) anyChecked = true;
												}
												return anyChecked;
											}
		}
		// add this function to the classbehaviour object
		classBehaviour.validateInput = new ValidateInput;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.validateInput;
		
	// Disable form elements during a submit, to avoid multiple submits on slow servers
		// define this class behaviour
		function DisableAfterSubmit(){
			// properties
			this.name 		= 	'disableAfterSubmit';
			// methods
			this.start		=	function(node){
									node.onsubmit = this.disable;
									// get all elements in this form
									allNodes = node.getElementsByTagName("*");
									// is this a form using microsoft's postbacks
									if(typeof(__doPostBack)!='undefined'){
										// for all nodes in this form
										for(var a=0; a<allNodes.length; a++){
											// if this form element has a _dopostback
											if(allNodes[a].onchange!=null){
												if(allNodes[a].onchange.toString().indexOf('__doPostBack')>-1){
													// overrule microsoft's postback event
													allNodes[a].onchange = this.disable;
												}
											}
											if(allNodes[a].onclick!=null){
												if(allNodes[a].onclick.toString().indexOf('__doPostBack')>-1){
													// overrule microsoft's postback event
													allNodes[a].onclick = this.disable;
												}
											}
										}
									}
									// if there's also a validation behaviour defined, trigger it
									if(node.className.indexOf('validateAllInput')>-1) classBehaviour.validateAllInput.start(node);
								}
			// events
			this.disable	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// trigger microsoft's postback
									if(typeof(__doPostBack)!='undefined') __doPostBack(objNode.id, objNode.value);
									// get all elements in this form
									allNodes = document.getElementsByTagName("*");
									// for all nodes in this form
									for(var a=0; a<allNodes.length; a++){
										// if this is a form element
										if(
											allNodes[a].nodeName.indexOf('INPUT')>-1 ||
											allNodes[a].nodeName.indexOf('SELECT')>-1 ||
											allNodes[a].nodeName.indexOf('TEXTAREA')>-1
										){
											// disable the form element
											allNodes[a].disabled = true;
											// deny focus
											allNodes[a].onfocus = blur;
										}
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.disableAfterSubmit = new DisableAfterSubmit;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.disableAfterSubmit;

	// STARTUP-SEQUENCE
	// start the parsing of classes
	classBehaviour.parseDocument();
