Index: src/test/display/SrtDisplay.java
===================================================================
--- src/test/display/SrtDisplay.java	(revision 580)
+++ src/test/display/SrtDisplay.java	(working copy)
@@ -57,6 +57,11 @@
 
 	private final Map<Integer, Integer> offsetToBlock = new HashMap<>();
 
+	private String srtDescription;
+	private int codepage;
+	private int id1;
+	private int id2;
+
 	protected void print() {
 		readCommonHeader();
 		readFileHeader();
@@ -119,9 +124,9 @@
 
 		d.setTitle("Description");
 
-		String s = d.zstringValue("Description: %s");
+		srtDescription = d.zstringValue("Description: %s");
 
-		long remain = description.getLen() - s.length() - 1;
+		long remain = description.getLen() - srtDescription.length() - 1;
 		d.rawValue((int) remain);
 
 		d.print(outStream);
@@ -138,10 +143,10 @@
 		d.setSectStart(start);
 		reader.position(start);
 		int len = d.charValue("sub header len %d");
-		d.charValue("id1 %d");
-		d.charValue("id2 %d");
+		id1 = d.charValue("id1 %d");
+		id2 = d.charValue("id2 %d");
 
-		int codepage = d.charValue("codepage %d");
+		codepage = d.charValue("codepage %d");
 		if (codepage == 65001)
 			isUnicode = true;
 		Charset charset = Sort.charsetFromCodepage(codepage);
@@ -206,38 +211,82 @@
 		d.setTitle("------- Summary of ordering --------");
 
 		Formatter chars = new Formatter();
-		Formatter comment = new Formatter();
+		//Formatter comment = new Formatter();
+		
+		// reproduce header like mkgmap resource/sort/cp*.txt entries
+		chars.format("\n\n\n");
+		chars.format("# Compare this with resource/sort/cp%d.txt.\n\n", codepage);
+		chars.format("codepage %d\n", codepage);
+		chars.format("id1 %d\n", id1);
+		chars.format("id2 %d\n", id2);
+		chars.format("description \"%s\"\n\n", srtDescription);
+		chars.format("characters\n\n");
+
 		CharPosition last = new CharPosition(0);
-		last.first = -1;
+		//last.first = -1;
+		last.first = 0; // start first line with zero/ignore sortOrder
 		for (CharPosition cp : charmap) {
-			if (cp.expands)
+			if (cp.expands > 0)
 				continue;
+			int unicodeChar = toUnicode(cp.val);
+			if (unicodeChar < 0) // no character defined for this position
+				continue;
 
 			if (cp.first != last.first) {
 				//chars.format("    # %s\n[%d] < ", comment, cp.first);
-				chars.format("\n< ");
-				comment = new Formatter();
+				chars.format("\n < ");
+				//comment = new Formatter();
 			} else if (cp.second != last.second) {
 				chars.format(" ; ");
-				comment.format(" ; ");
+				//comment.format(" ; ");
 			} else if (cp.third != last.third) {
 				chars.format(",");
-				comment.format(",");
+				//comment.format(",");
 			} else {
 				chars.format("=");
-				comment.format("=");
+				//comment.format("=");
 			}
 			last = cp;
-			chars.format("%s", fmtChar(toUnicode(cp.val)));
-			comment.format("U+%04x", cp.val);
+			chars.format("%s", fmtChar(unicodeChar));
+			//comment.format("U+%04x", cp.val);
 		}
 
 		chars.format("\n");
 		for (CharPosition cp : charmap) {
-			if (cp.expands)
-				continue;
-			chars.format("%4s %s\n", fmtChar(toUnicode(cp.val)), cp);
+			if (cp.expands > 0) {
+				chars.format("expand %s to ", fmtChar(toUnicode(cp.val)));
+				for (int i = 0; i <= cp.expands; ++i) {
+					CharPosition ch = expansions.get(cp.first + i - 1);
+					// need to search for best char with this first/primary. Doesn't actually matter
+					// apart from the cosmetics of the sort/cp*.txt expand list because the secondary
+					// and tertiary binary sortOrders are chosen to avoid matching existing real chars.
+					// see mkgmap/srt/SrtTextReader.java for more info
+					if (ch.second > 7)
+						ch.second -= 7;
+					ch.third = ch.third >= 5 ? 2 : 1;
+					int charValue = -1;
+					for (CharPosition scanCp : charmap) {
+						if (scanCp.expands > 0)
+							continue;
+						if (scanCp.first == ch.first) {
+							if (scanCp.second == ch.second &&
+								scanCp.third == ch.third) {
+								charValue = scanCp.val;
+								break;
+							} else if (charValue < 0) {
+								charValue = scanCp.val;
+							}
+						}
+					}
+					if (charValue >= 0)
+						charValue = toUnicode(charValue);
+					if (charValue >= 0)
+						chars.format(" %c", charValue);
+				}
+				chars.format("\n");
+			}
 		}
+		chars.format("\n# ends\n", codepage);
 
 		d.item().addText(chars.toString());
 		d.print(outStream);
@@ -286,7 +335,11 @@
 		StringBuilder sb = new StringBuilder();
 		Formatter fmt = new Formatter(sb);
 		fmt.format("0x%02x ", charValue);
-		fmt.format("(%c) ", toUnicode(charValue));
+		int unicodeChar = toUnicode(charValue);
+		if (unicodeChar < 0) // no character defined for this position
+			fmt.format("NaC ");
+		else
+			fmt.format("(%c) ", unicodeChar);
 		if ((flags & 0x1) != 0)
 			sb.append("Letter ");
 		if ((flags & 0x2) != 0)
@@ -297,8 +350,8 @@
 		} else {
 			// This is an expansion, it sorts as two or more characters (eg ß sorts near ss).
 			// The pos is an index into srt5.
-			c.expands = true;
-			expansion(sb, c.first, (flags >> 4) & 0xf);
+			c.expands = (flags >> 4) & 0xf;
+			expansion(sb, c.first, c.expands);
 		}
 
 		item.addText(sb.toString());
@@ -373,7 +426,7 @@
 			CharBuffer chars = decoder.decode(b);
 			return chars.charAt(0);
 		} catch (CharacterCodingException e) {
-			return '?';
+			return -1;
 		}
 	}
 
@@ -472,7 +525,7 @@
 		private int first;
 		private int second;
 		private int third;
-		private boolean expands;
+		private int expands;
 
 		public CharPosition(int charValue) {
 			this.val = charValue;
