public static LinkedList<Pair<Integer, Set<CharacterClass>>> getOverlaps(Set<CharacterClass> ccs) {
		LinkedList<Pair<Integer, Set<CharacterClass>>> overlaps = new LinkedList<Pair<Integer,Set<CharacterClass>>>(new Pair<Integer, Set<CharacterClass>>(0, new ShareableHashSet<CharacterClass>()));
		
		// insert all ranges of all characterclasses into the list
		for (CharacterClass cc : ccs) {
			LinkedList<Pair<Integer, Set<CharacterClass>>> l = overlaps;
			for (int i = 0; i < cc.size; ) {
				int c1 = cc.ranges[i++];
				int c2 = cc.ranges[i++];
				
				// from
				while (l.next != null && l.next.elem.a <= c1) {
					l = l.next;
				}
				
				if (l.elem.a == c1) {
					// do nothing
				} else {
					Pair<Integer, Set<CharacterClass>> p = new Pair<Integer, Set<CharacterClass>>(c1, new ShareableHashSet<CharacterClass>());
					p.b.addAll(l.elem.b);
					l = l.insert(p);
				}
				
				// to
				while (l.next != null && l.next.elem.a <= c2) {
					l.elem.b.add(cc);
					l = l.next;
				}
				
				if (l.next == null) {
					l.insert(new Pair<Integer, Set<CharacterClass>>(c2 + 1, new ShareableHashSet<CharacterClass>()));
				} else if (l.next.elem.a == c2 + 1) {
					// do nothing
				} else {
					Pair<Integer, Set<CharacterClass>> p = new Pair<Integer, Set<CharacterClass>>(c2 + 1, new ShareableHashSet<CharacterClass>());
					p.b.addAll(l.elem.b);
					l.insert(p);
				}
				l.elem.b.add(cc);
			}
		}
		return overlaps;
	}