docs: public int updateMixture( float[] pixelValue , float[] dataRow , int modelIndex ) {
  
  		// see which gaussian is the best fit based on Mahalanobis distance
  		int index = modelIndex;
  		float bestDistance = maxDistance*numBands;
  		int bestIndex=-1;
  
  		int ng; // number of gaussians in use
  		for (ng = 0; ng < maxGaussians; ng++, index += gaussianStride) {
  			float variance = dataRow[index+1];
  			if( variance <= 0 ) {
  				break;
  			}
  
  			float mahalanobis = 0;
  			for (int i = 0; i < numBands; i++) {
  				float mean = dataRow[index+2+i];
  				float delta = pixelValue[i]-mean;
  				mahalanobis += delta*delta/variance;
  			}
  
  			if( mahalanobis < bestDistance ) {
  				bestDistance = mahalanobis;
  				bestIndex = index;
  			}
  		}
  
  		// Update the model for the best gaussian
  		if( bestIndex != -1 ) {
  			// If there is a good fit update the model
  			float weight = dataRow[bestIndex];
  			float variance = dataRow[bestIndex+1];
  
  			weight += learningRate*(1f-weight);
  			dataRow[bestIndex]   = 1; // set to one so that it can't possible go negative
  
  			float sumDeltaSq = 0;
  			for (int i = 0; i < numBands; i++) {
  				float mean = dataRow[bestIndex+2+i];
  				float delta = pixelValue[i]-mean;
  				dataRow[bestIndex+2+i] = mean + delta*learningRate/weight;
  				sumDeltaSq += delta*delta;
  			}
  			sumDeltaSq /= numBands;
  			dataRow[bestIndex+1] = variance + (learningRate /weight)*(sumDeltaSq*1.2F - variance);
  			// 1.2f is a fudge factor. Empirical testing shows that the above equation is biased. Can't be bothered
  			// to verify the derivation and see if there's a mistake
  
  			// Update Gaussian weights and prune models
  			updateWeightAndPrune(dataRow, modelIndex, ng, bestIndex, weight);
  
  			return weight >= significantWeight ? 0 : 1;
  		} else if( ng < maxGaussians ) {
  			// if there is no good fit then create a new model, if there is room
  
  			bestIndex = modelIndex + ng*gaussianStride;
  			dataRow[bestIndex]   = 1; // weight is changed later or it's the only model
  			dataRow[bestIndex+1] = initialVariance;
  			for (int i = 0; i < numBands; i++) {
  				dataRow[bestIndex+2+i] = pixelValue[i];
  			}
  			// There are no models. Return unknown
  			if( ng == 0 )
  				return unknownValue;
  
  			updateWeightAndPrune(dataRow, modelIndex, ng+1, bestIndex, learningRate);
  			return 1;
  		} else {
  			// didn't match any models and can't create a new model
  			return 1;
  		}
  	}