package org.paxml.util;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class TraversalUtils {
	/**
	 * Make a list of maps out of a map of lists. The given map is treated as a
	 * grid, where the row index is the map key. The combination algorithm is to
	 * grab an item from each row of the grid to make a map, where each result
	 * map is contains that chosen item associated with the key. For instance,
	 * map: {a:[1,2],b:[3,4]} becomes list
	 * [{a:1,b:3},{a:1,b:4},{a:2,b:3},{a:2,b:4}].
	 * 
	 * @param map
	 *            the map of lists
	 * @return the list of maps
	 */
	public static <K, V> List<Map<K, V>> combination(Map<K, List<V>> map) {
		List<K> keys = new ArrayList<K>(map.size());
		List<List<V>> grid = new ArrayList<List<V>>(map.size());
		for (Map.Entry entry : map.entrySet()) {
			keys.add((K) entry.getKey());
			List<V> row = (List<V>) entry.getValue();
			if (row == null) {
				row = new ArrayList<V>();
				row.add(null);
			}
			grid.add(row);
		}
		return combine(keys.size() - 1, keys, grid);
	}

	private static <K, V> List<Map<K, V>> combine(int rowIndex, List<K> keys, List<List<V>> grid) {

		List<V> row = grid.get(rowIndex);
		K key = keys.get(rowIndex);

		List<Map<K, V>> result = new ArrayList();
		if (rowIndex <= 0) {
			// reached the 1st row, create new maps
			for (V val : row) {
				Map<K, V> map = new LinkedHashMap();
				map.put(key, val);
				result.add(map);
			}

		} else {
			// not to the 1st row yet
			for (V val : row) {
				List<Map<K, V>> created = combine(rowIndex - 1, keys, grid);
				for (Map<K, V> map : created) {
					map.put(key, val);
				}
				result.addAll(created);
			}

		}
		return result;
	}
}

@@ -1,8 +1,712 @@
+/**%0A * This file is part of PaxmlCore.%0A *%0A * PaxmlCore is free software: you can redistribute it and/or modify%0A * it under the terms of the GNU Affero General Public License as published by%0A * the Free Software Foundation, either version 3 of the License, or%0A * (at your option) any later version.%0A *%0A * PaxmlCore is distributed in the hope that it will be useful,%0A * but WITHOUT ANY WARRANTY; without even the implied warranty of%0A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the%0A * GNU Affero General Public License for more details.%0A *%0A * You should have received a copy of the GNU Affero General Public License%0A * along with PaxmlCore.  If not, see %3Chttp://www.gnu.org/licenses/%3E.%0A */%0A
 package 
@@ -828,16 +828,95 @@
 l.Map;%0A%0A
+/**%0A * The utils for traversing collections.%0A * %0A * @author Xuetao Niu%0A * %0A */%0A
 public c

add more doc