morpheus.CollapseDataset = function(dataset, collapseToFields,
		summarizeFunction, shallowCopy) {
	var vectors = [];
	for (var i = 0; i < collapseToFields.length; i++) {
		var v = dataset.getRowMetadata().getByName(collapseToFields[i]);
		if (!v) {
			throw collapseToFields[i]
					+ ' not found. Available fields are '
					+ morpheus.MetadataUtil.getMetadataNames(dataset
							.getRowMetadata());
		}
		vectors.push(v);
	}
	var idToIndices = morpheus.VectorUtil.createValuesToIndicesMap(vectors);
	var collapsedDataset = new morpheus.Dataset({
		name : dataset.getName(),
		rows : idToIndices.size(),
		columns : dataset.getColumnCount(),
		dataType : 'Float32'
	});
	var nseries = dataset.getSeriesCount();
	for (var series = 1; series < nseries; series++) {
		collapsedDataset.addSeries({
			name : dataset.getName(i),
			dataType : 'Float32'
		});
	}
	if (shallowCopy) {
		collapsedDataset.setColumnMetadata(dataset.getColumnMetadata());
	} else {
		morpheus.MetadataUtil.copy(dataset.getColumnMetadata(),
				collapsedDataset.getColumnMetadata());
	}
	var nfields = collapseToFields.length;
	var collapseToVectors = [];
	for (var i = 0; i < nfields; i++) {
		collapseToVectors.push(collapsedDataset.getRowMetadata().add(
				collapseToFields[i]));
	}
	var counter = 0;
	idToIndices
			.forEach(function(rowIndices, key) {
				// collapse each column separately
				var slice = morpheus.DatasetUtil.slicedView(dataset,
						rowIndices, null);
				var view = new morpheus.DatasetColumnView(slice);
				for (var series = 0; series < nseries; series++) {
					view.setSeriesIndex(series);
					for (var j = 0, ncols = dataset.getColumnCount(); j < ncols; j++) {
						view.setIndex(j);
						collapsedDataset.setValue(counter, j,
								summarizeFunction(view), series);
					}
				}
				for (var i = 0; i < nfields; i++) {
					var collapsedToVector = collapseToVectors[i];
					var vector = vectors[i];
					collapsedToVector.setValue(counter, vector
							.getValue(rowIndices[0]));
				}
				counter++;
			});
	return collapsedDataset;
};
