public static HierarchicalMixtureModel build(MixtureModel f, Clustering.CLUSTERING_TYPE type, LINKAGE_CRITERION linkage){
		
		// Variables
		int i, j, n = f.size;
		MixtureModel               fT        = mixtureL2T(f);
		HierarchicalMixtureModel[] hmm_array = new HierarchicalMixtureModel[n];
		
		// Build the array, each case containing a hierarchical mixture model with one parameter
		for (i=0; i<n; i++){
			MixtureModel  mm  = new MixtureModel(1);
			mm.EF             = fT.EF;
			mm.param[0]       = fT.param[i];
			mm.weight[0]      = 1.0;
			HierarchicalMixtureModel hmm = new HierarchicalMixtureModel();
			hmm.EF            = fT.EF;
			hmm.weight        = fT.weight[i];
			hmm.node          = mm;
			hmm.type          = type;
			hmm.resolutionMax  = 1;
			hmm_array[i]      = hmm;
		}
		
		// General loop
		for (i=0; i<n-1; i++){
			
			// Temporary array containing new hierarchical mixture models
			HierarchicalMixtureModel[] hmm_array_new = new HierarchicalMixtureModel[n-i-1];
			
			// Find two closest hierarchical mixture models in the array
			int[] index = find2ClosestMixtureModels(hmm_array, type, linkage);
			
			// Fusion the two closest hierarchical mixture models in a new one
			HierarchicalMixtureModel hmm, hmm_1, hmm_2;
			MixtureModel  mm , mm_1 , mm_2 ;
			hmm_1 = hmm_array[index[0]];
			hmm_2 = hmm_array[index[1]];
			mm_1  = hmm_1.node;
			mm_2  = hmm_2.node;
			mm    = new MixtureModel( mm_1.size + mm_2.size );
			mm.EF = mm_1.EF;
			for (j=0; j<mm_1.size; j++){
				mm.param[j]  = mm_1.param[j];
				mm.weight[j] = mm_1.weight[j] * hmm_1.weight;
			}
			for (j=0; j<mm_2.size; j++){
				mm.param[mm_1.size+j]  = mm_2.param[j];
				mm.weight[mm_1.size+j] = mm_2.weight[j] * hmm_2.weight;
			}
			mm.normalizeWeights();
			hmm                = new HierarchicalMixtureModel();
			hmm.EF             = mm_1.EF;
			hmm.weight         = hmm_1.weight + hmm_2.weight;
			hmm.node           = mm;
			hmm.leftChild      = hmm_1;
			hmm.rightChild     = hmm_2;
			hmm.type           = hmm_1.type;
			hmm.resolutionMax  = hmm_1.resolutionMax+1;
			hmm_1.parent       = hmm;
			hmm_2.parent       = hmm;
			hmm_array_new[0]   = hmm;
			
			// Copy other hierarchical mixture models in the temporary array
			int cpt = 1;
			for (j=0; j<n-i; j++){
				if (j!=index[0] && j!=index[1]){
					HierarchicalMixtureModel hmm_current = hmm_array[j];
					HierarchicalMixtureModel hmm_new     = new HierarchicalMixtureModel();
					hmm_new.EF            = hmm_current.EF;
					hmm_new.node          = hmm_current.node;
					hmm_new.weight        = hmm_current.weight;
					hmm_new.leftChild     = hmm_current;
					hmm_new.type          = hmm_current.type;
					hmm_new.resolutionMax = hmm_current.resolutionMax+1;
					hmm_current.parent    = hmm_new;
					hmm_array_new[cpt]    = hmm_new;
					cpt++;
				}
			}
			
			// Remplace the array by the temporary array
			hmm_array = hmm_array_new;
		}
		
		// Return the root of the hierarchical mixture model
		return hmm_array[0];
	}