dist/multilabel/Homer.js
function(dataset, treeNode) {
		var superlabelsDataset = [];
		var mapSuperlabelToRestDataset = {};
		dataset.forEach(function(datum) { 
			var splitLabels = datum.output;	// [ [ 'Offer', 'Leased Car', 'Without leased car' ], [ 'Offer', 'Working Hours', '9 hours' ] ]
			var superlabels = {};           // the first parts of each of the splitLabels
			var mapSuperlabelToRest = {};   // each value is a list of continuations of the key. 
			for (var i in splitLabels) { 
				var splitLabel = splitLabels[i];//[ 'Offer', 'Leased Car', 'Without leased car' ]
				var superlabel = splitLabel[0];
				superlabels[superlabel] = true; //superlabels['Offer'] = true
				if (splitLabel.length>1) { 		// if it have more than one label (superlabel)
					if (!mapSuperlabelToRest[superlabel]) 
						mapSuperlabelToRest[superlabel] = [];
					mapSuperlabelToRest[superlabel].push(splitLabel.slice(1));//['Leased Car', 'Without leased car']
				}
			}

/*			Sample of mapSuperlabelToRest
			{ Offer: 
			[ [ 'Leased Car', 'Without leased car' ],
   			  [ 'Working Hours', '9 hours' ] ] }

			Sample of superlabelsDataset, initial dataset with superlabel instead of entire output
			'. [end]': 0.965080896043587 },
			output: [ 'Offer' ] } ]
*/
			superlabelsDataset.push({
				input: datum.input,
				output: Object.keys(superlabels)
			});		

			for (var superlabel in mapSuperlabelToRest) {
				if (!(superlabel in mapSuperlabelToRestDataset)) 
					mapSuperlabelToRestDataset[superlabel] = [];
				mapSuperlabelToRestDataset[superlabel].push({
					input: datum.input,
					output: mapSuperlabelToRest[superlabel]
				});
			}
		}, this);
		
/*		Sample of mapSuperlabelToRestDataset
		{ Offer: [ { input: [Object], output: [["Leased Car","Without leased car"],["Working Hours","9 hours"]] } ] }
*/

		// train the classifier only on superlabels
		treeNode.superlabelClassifier.trainBatch(superlabelsDataset);

		for (var superlabel in mapSuperlabelToRestDataset) {
			if (!(superlabel in treeNode.mapSuperlabelToBranch)) {
				treeNode.mapSuperlabelToBranch[superlabel] = {
					superlabelClassifier: this.newMultilabelClassifier(),
					mapSuperlabelToBranch: {}
				}
			}
/*			train the next level classifier for a give superlabel classifier superlabel (from loop)
			with the dataset from new structure mapSuperlabelToRestDataset (see above)
*/			this.trainBatchRecursive(mapSuperlabelToRestDataset[superlabel], treeNode.mapSuperlabelToBranch[superlabel]);
		}
	}
function(dataset, treeNode) {
		var superlabelsDataset = [];
		var mapSuperlabelToRestDataset = {};
		dataset.forEach(function(datum) { 
			var splitLabels = datum.output;	// [ [ 'Offer', 'Leased Car', 'Without leased car' ], [ 'Offer', 'Working Hours', '9 hours' ] ]
			var superlabels = {};           // the first parts of each of the splitLabels
			var mapSuperlabelToRest = {};   // each value is a list of continuations of the key. 
			for (var i in splitLabels) { 
				var splitLabel = splitLabels[i];//[ 'Offer', 'Leased Car', 'Without leased car' ]
				var superlabel = splitLabel[0];
				superlabels[superlabel] = true; //superlabels['Offer'] = true
				if (splitLabel.length>1) { 		// if it have more than one label (superlabel)
					if (!mapSuperlabelToRest[superlabel]) 
						mapSuperlabelToRest[superlabel] = [];
					mapSuperlabelToRest[superlabel].push(splitLabel.slice(1));//['Leased Car', 'Without leased car']
				}
			}

/*			Sample of mapSuperlabelToRest
			{ Offer: 
			[ [ 'Leased Car', 'Without leased car' ],
   			  [ 'Working Hours', '9 hours' ] ] }

			Sample of superlabelsDataset, initial dataset with superlabel instead of entire output
			'. [end]': 0.965080896043587 },
			output: [ 'Offer' ] } ]
*/
			superlabelsDataset.push({
				input: datum.input,
				output: Object.keys(superlabels)
			});		

			for (var superlabel in mapSuperlabelToRest) {
				if (!(superlabel in mapSuperlabelToRestDataset)) 
					mapSuperlabelToRestDataset[superlabel] = [];
				mapSuperlabelToRestDataset[superlabel].push({
					input: datum.input,
					output: mapSuperlabelToRest[superlabel]
				});
			}
		}, this);
		
/*		Sample of mapSuperlabelToRestDataset
		{ Offer: [ { input: [Object], output: [["Leased Car","Without leased car"],["Working Hours","9 hours"]] } ] }
*/

		// train the classifier only on superlabels
		treeNode.superlabelClassifier.trainBatch(superlabelsDataset);

		for (var superlabel in mapSuperlabelToRestDataset) {
			if (!(superlabel in treeNode.mapSuperlabelToBranch)) {
				treeNode.mapSuperlabelToBranch[superlabel] = {
					superlabelClassifier: this.newMultilabelClassifier(),
					mapSuperlabelToBranch: {}
				}
			}
/*			train the next level classifier for a give superlabel classifier superlabel (from loop)
			with the dataset from new structure mapSuperlabelToRestDataset (see above)
*/			this.trainBatchRecursive(mapSuperlabelToRestDataset[superlabel], treeNode.mapSuperlabelToBranch[superlabel]);
		}
	}
Recursive internal subroutine of trainBatch.