private ShareableHashMap<GSSNode, Set<GSSNode>> getShifts(Collection<GSSNode> gss) {
		// collect all shift transitions in the gss
		ShareableHashMap<GSSNode, Set<GSSNode>> shifts = new ShareableHashMap<GSSNode, Set<GSSNode>>();
		ShareableHashSet<GSSNode> todo = new ShareableHashSet<GSSNode>();
		Set<GSSNode> done = new ShareableHashSet<GSSNode>();
		todo.addAll(gss);
		while (todo.size() > 0) {
			GSSNode n = todo.removeOne();
			done.add(n);
			
			Set<GSSNode> from = shifts.get(n);
			if (from == null) {
				from = new ShareableHashSet<GSSNode>();
				from.add(n);
				shifts.put(n, from);
			}
			
			for (GSSEdge e : n.edges) {
				if (!(e.symbol instanceof Derive)) {
					from.add(e.from);
				}
				if (!done.contains(e.from)) {
					todo.add(e.from);
				}
				if (e.reducedFrom != null && !done.contains(e.reducedFrom)) {
					todo.add(e.reducedFrom);
				}
			}
		}
		
		return shifts;
	}