Bug 547415: Fix escaping of unicode C1 Control characters in
RValueFormatter

Change-Id: I4905040227cd271df3d71be1b0918afaaea85874
diff --git a/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/data/RValueFormatter05chrTest.java b/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/data/RValueFormatter05chrTest.java
index e285aa5..a4fb65c 100644
--- a/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/data/RValueFormatter05chrTest.java
+++ b/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/data/RValueFormatter05chrTest.java
@@ -102,10 +102,10 @@
 	}
 	
 	@Test
-	public void printPrintableBasic() {
-		final char[] chars= new char[0xFF];
+	public void printPrintableU0000() {
+		final char[] chars= new char[0x7F];
 		int idx= 0;
-		for (char c= 0x20; c <= 0xFF; c++) {
+		for (char c= 0x20; c <= 0x7F; c++) {
 			switch (c) {
 			case '\u007F':
 			case '\\':
@@ -122,6 +122,25 @@
 	}
 	
 	@Test
+	public void printPrintableU0080() {
+		final StringBuilder rawBuilder= new StringBuilder();
+		final StringBuilder expectedBuilder= new StringBuilder();
+		for (char c= 0x80; c <= 0xFF; c++) {
+			if ((c >= 0x80 && c <= 0x9F) || c == 0xAD) {
+				rawBuilder.append(c);
+				expectedBuilder.append("\\u{").append(Integer.toHexString(c).toUpperCase()).append("}");
+			}
+			else {
+				rawBuilder.append(c);
+				expectedBuilder.append(c);
+			}
+		}
+		this.formatter.clear();
+		this.formatter.appendStringD(rawBuilder.toString());
+		assertStringD(expectedBuilder.toString());
+	}
+	
+	@Test
 	public void printNonPrintableExt() {
 		this.formatter.clear();
 		this.formatter.appendStringD("\uFFF0");
diff --git a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/data/RValueFormatter.java b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/data/RValueFormatter.java
index e446a67..a8d5906 100644
--- a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/data/RValueFormatter.java
+++ b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/data/RValueFormatter.java
@@ -179,107 +179,117 @@
 		int start= idx;
 		while (idx < value.length()) {
 			final char c= value.charAt(idx);
-			if (c <= 255) {
-				switch (c) {
-				case 0x00:
-				case 0x01:
-				case 0x02:
-				case 0x03:
-				case 0x04:
-				case 0x05:
-				case 0x0E:
-				case 0x0F:
-				case 0x10:
-				case 0x11:
-				case 0x12:
-				case 0x13:
-				case 0x14:
-				case 0x15:
-				case 0x16:
-				case 0x17:
-				case 0x18:
-				case 0x19:
-				case 0x1A:
-				case 0x1B:
-				case 0x1C:
-				case 0x1D:
-				case 0x1E:
-				case 0x1F:
-				case 0x7F:
-					append(value, start, idx);
-					appendEscapedCodepoint(c);
-					start= ++idx;
-					continue;
-				case 0x07:
-					append(value, start, idx);
-					this.sb.append("\\a"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x08:
-					append(value, start, idx);
-					this.sb.append("\\b"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x09:
-					append(value, start, idx);
-					this.sb.append("\\t"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0A:
-					append(value, start, idx);
-					this.sb.append("\\n"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0B:
-					append(value, start, idx);
-					this.sb.append("\\v"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0C:
-					append(value, start, idx);
-					this.sb.append("\\f"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0D:
-					append(value, start, idx);
-					this.sb.append("\\r"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case '\\':
-					append(value, start, idx);
-					this.sb.append('\\');
-					start= idx++;
-					continue;
-				case '\"':
-					append(value, start, idx);
-					this.sb.append('\\');
-					start= idx++;
-					continue;
-				default:
-					idx++;
-					continue;
-				}
-			}
-			{	final int cp= value.codePointAt(idx);
-				if (isPrintableChar(cp)) {
-					if (cp != c) {
-						idx+= 2;
+			switch (c) {
+			case 0x00:
+			case 0x01:
+			case 0x02:
+			case 0x03:
+			case 0x04:
+			case 0x05:
+			case 0x0E:
+			case 0x0F:
+			case 0x10:
+			case 0x11:
+			case 0x12:
+			case 0x13:
+			case 0x14:
+			case 0x15:
+			case 0x16:
+			case 0x17:
+			case 0x18:
+			case 0x19:
+			case 0x1A:
+			case 0x1B:
+			case 0x1C:
+			case 0x1D:
+			case 0x1E:
+			case 0x1F:
+			case 0x7F:
+				append(value, start, idx);
+				appendEscapedCodepoint(c);
+				start= ++idx;
+				continue;
+			case 0x07:
+				append(value, start, idx);
+				this.sb.append("\\a"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x08:
+				append(value, start, idx);
+				this.sb.append("\\b"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x09:
+				append(value, start, idx);
+				this.sb.append("\\t"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0A:
+				append(value, start, idx);
+				this.sb.append("\\n"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0B:
+				append(value, start, idx);
+				this.sb.append("\\v"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0C:
+				append(value, start, idx);
+				this.sb.append("\\f"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0D:
+				append(value, start, idx);
+				this.sb.append("\\r"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case '\\':
+				append(value, start, idx);
+				this.sb.append('\\');
+				start= idx++;
+				continue;
+			case '\"':
+				append(value, start, idx);
+				this.sb.append('\\');
+				start= idx++;
+				continue;
+			case 0x20: case 0x21: /* "    */ case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+			case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
+			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+			case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F:
+			case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+			case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+			case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+			case 0x58: case 0x59: case 0x5A: case 0x5B: /* \\   */ case 0x5D: case 0x5E: case 0x5F:
+			case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+			case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
+			case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+			case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: /* DEL  */
+				idx++;
+				continue;
+			default:
+				{	final int cp= value.codePointAt(idx);
+					if (isPrintableChar(cp)) {
+						if (cp != c) {
+							idx+= 2;
+						}
+						else {
+							idx++;
+						}
+						continue;
 					}
 					else {
-						idx++;
+						append(value, start, idx);
+						appendEscapedCodepoint(cp);
+						if (cp != c) {
+							start= (idx+= 2);
+						}
+						else {
+							start= ++idx;
+						}
+						continue;
 					}
-					continue;
-				}
-				else {
-					append(value, start, idx);
-					appendEscapedCodepoint(cp);
-					if (cp != c) {
-						start= (idx+= 2);
-					}
-					else {
-						start= ++idx;
-					}
-					continue;
 				}
 			}
 		}
@@ -298,103 +308,113 @@
 		int start= idx;
 		while (idx < value.length()) {
 			final char c= value.charAt(idx);
-			if (c <= 255) {
-				switch (c) {
-				case 0x00:
-				case 0x01:
-				case 0x02:
-				case 0x03:
-				case 0x04:
-				case 0x05:
-				case 0x06:
-				case 0x0E:
-				case 0x0F:
-				case 0x10:
-				case 0x11:
-				case 0x12:
-				case 0x13:
-				case 0x14:
-				case 0x15:
-				case 0x16:
-				case 0x17:
-				case 0x18:
-				case 0x19:
-				case 0x1A:
-				case 0x1B:
-				case 0x1C:
-				case 0x1D:
-				case 0x1E:
-				case 0x1F:
-				case 0x7F:
-					append(value, start, idx);
-					appendEscapedCodepoint(c);
-					start= ++idx;
-					continue;
-				case 0x07:
-					append(value, start, idx);
-					this.sb.append("\\a"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x08:
-					append(value, start, idx);
-					this.sb.append("\\b"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x09:
-					append(value, start, idx);
-					this.sb.append("\\t"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0A:
-					append(value, start, idx);
-					this.sb.append("\\n"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0B:
-					append(value, start, idx);
-					this.sb.append("\\v"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0C:
-					append(value, start, idx);
-					this.sb.append("\\f"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0D:
-					append(value, start, idx);
-					this.sb.append("\\r"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case '\\':
-					append(value, start, idx);
-					this.sb.append('\\');
-					start= idx++;
-					continue;
-				default:
-					idx++;
-					continue;
-				}
-			}
-			{	final int cp= value.codePointAt(idx);
-				if (isPrintableChar(cp)) {
-					if (cp != c) {
-						idx+= 2;
+			switch (c) {
+			case 0x00:
+			case 0x01:
+			case 0x02:
+			case 0x03:
+			case 0x04:
+			case 0x05:
+			case 0x06:
+			case 0x0E:
+			case 0x0F:
+			case 0x10:
+			case 0x11:
+			case 0x12:
+			case 0x13:
+			case 0x14:
+			case 0x15:
+			case 0x16:
+			case 0x17:
+			case 0x18:
+			case 0x19:
+			case 0x1A:
+			case 0x1B:
+			case 0x1C:
+			case 0x1D:
+			case 0x1E:
+			case 0x1F:
+			case 0x7F:
+				append(value, start, idx);
+				appendEscapedCodepoint(c);
+				start= ++idx;
+				continue;
+			case 0x07:
+				append(value, start, idx);
+				this.sb.append("\\a"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x08:
+				append(value, start, idx);
+				this.sb.append("\\b"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x09:
+				append(value, start, idx);
+				this.sb.append("\\t"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0A:
+				append(value, start, idx);
+				this.sb.append("\\n"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0B:
+				append(value, start, idx);
+				this.sb.append("\\v"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0C:
+				append(value, start, idx);
+				this.sb.append("\\f"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0D:
+				append(value, start, idx);
+				this.sb.append("\\r"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case '\\':
+				append(value, start, idx);
+				this.sb.append('\\');
+				start= idx++;
+				continue;
+			case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+			case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
+			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+			case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F:
+			case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+			case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+			case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+			case 0x58: case 0x59: case 0x5A: case 0x5B: /* \\   */ case 0x5D: case 0x5E: case 0x5F:
+			case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+			case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
+			case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+			case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: /* DEL  */
+				idx++;
+				continue;
+			default:
+				{	final int cp= value.codePointAt(idx);
+					if (isPrintableChar(cp)) {
+						if (cp != c) {
+							idx+= 2;
+						}
+						else {
+							idx++;
+						}
+						continue;
 					}
 					else {
-						idx++;
+						append(value, start, idx);
+						appendEscapedCodepoint(cp);
+						if (cp != c) {
+							start= (idx+= 2);
+						}
+						else {
+							start= ++idx;
+						}
+						continue;
 					}
-					continue;
-				}
-				else {
-					append(value, start, idx);
-					appendEscapedCodepoint(cp);
-					if (cp != c) {
-						start= (idx+= 2);
-					}
-					else {
-						start= ++idx;
-					}
-					continue;
 				}
 			}
 		}
@@ -406,109 +426,119 @@
 		int start= idx;
 		while (idx < value.length()) {
 			final char c= value.charAt(idx);
-			if (c <= 255) {
-				switch (c) {
-				case 0x00:
-				case 0x01:
-				case 0x02:
-				case 0x03:
-				case 0x04:
-				case 0x05:
-				case 0x06:
-				case 0x0E:
-				case 0x0F:
-				case 0x10:
-				case 0x11:
-				case 0x12:
-				case 0x13:
-				case 0x14:
-				case 0x15:
-				case 0x16:
-				case 0x17:
-				case 0x18:
-				case 0x19:
-				case 0x1A:
-				case 0x1B:
-				case 0x1C:
-				case 0x1D:
-				case 0x1E:
-				case 0x1F:
-				case 0x7F:
-					append(value, start, idx);
-					appendEscapedCodepoint(c);
-					start= ++idx;
-					continue;
-				case 0x07:
-					append(value, start, idx);
-					this.sb.append("\\a"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x08:
-					append(value, start, idx);
-					this.sb.append("\\b"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x09:
-					append(value, start, idx);
-					this.sb.append("\\t"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0A:
-					append(value, start, idx);
-					this.sb.append("\\n"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0B:
-					append(value, start, idx);
-					this.sb.append("\\v"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0C:
-					append(value, start, idx);
-					this.sb.append("\\f"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0D:
-					append(value, start, idx);
-					this.sb.append("\\r"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case '`':
-					append(value, start, idx);
-					this.sb.append("\\`"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case '\\':
-					append(value, start, idx);
-					this.sb.append('\\');
-					start= idx++;
-					continue;
-				default:
-					idx++;
-					continue;
-				}
-			}
-			{	final int cp= value.codePointAt(idx);
-			if (isPrintableChar(cp)) {
-				if (cp != c) {
-					idx+= 2;
-				}
-				else {
-					idx++;
-				}
-				continue;
-			}
-			else {
+			switch (c) {
+			case 0x00:
+			case 0x01:
+			case 0x02:
+			case 0x03:
+			case 0x04:
+			case 0x05:
+			case 0x06:
+			case 0x0E:
+			case 0x0F:
+			case 0x10:
+			case 0x11:
+			case 0x12:
+			case 0x13:
+			case 0x14:
+			case 0x15:
+			case 0x16:
+			case 0x17:
+			case 0x18:
+			case 0x19:
+			case 0x1A:
+			case 0x1B:
+			case 0x1C:
+			case 0x1D:
+			case 0x1E:
+			case 0x1F:
+			case 0x7F:
 				append(value, start, idx);
-				appendEscapedCodepoint(cp);
-				if (cp != c) {
-					start= (idx+= 2);
-				}
-				else {
-					start= ++idx;
-				}
+				appendEscapedCodepoint(c);
+				start= ++idx;
 				continue;
-			}
+			case 0x07:
+				append(value, start, idx);
+				this.sb.append("\\a"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x08:
+				append(value, start, idx);
+				this.sb.append("\\b"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x09:
+				append(value, start, idx);
+				this.sb.append("\\t"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0A:
+				append(value, start, idx);
+				this.sb.append("\\n"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0B:
+				append(value, start, idx);
+				this.sb.append("\\v"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0C:
+				append(value, start, idx);
+				this.sb.append("\\f"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0D:
+				append(value, start, idx);
+				this.sb.append("\\r"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case '`':
+				append(value, start, idx);
+				this.sb.append("\\`"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case '\\':
+				append(value, start, idx);
+				this.sb.append('\\');
+				start= idx++;
+				continue;
+			case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+			case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
+			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+			case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F:
+			case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+			case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+			case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+			case 0x58: case 0x59: case 0x5A: case 0x5B: /* \\   */ case 0x5D: case 0x5E: case 0x5F:
+			/* `    */ case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+			case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
+			case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+			case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: /* DEL  */
+				idx++;
+				continue;
+			default:
+				{	final int cp= value.codePointAt(idx);
+					if (isPrintableChar(cp)) {
+						if (cp != c) {
+							idx+= 2;
+						}
+						else {
+							idx++;
+						}
+						continue;
+					}
+					else {
+						append(value, start, idx);
+						appendEscapedCodepoint(cp);
+						if (cp != c) {
+							start= (idx+= 2);
+						}
+						else {
+							start= ++idx;
+						}
+						continue;
+					}
+				}
 			}
 		}
 		append(value, start, idx);
@@ -520,114 +550,124 @@
 		int end= 0;
 		while (idx < value.length() && this.sb.length() + (idx - start) < max) {
 			final char c= value.charAt(idx);
-			if (c <= 255) {
-				switch (c) {
-				case 0x00:
-				case 0x01:
-				case 0x02:
-				case 0x03:
-				case 0x04:
-				case 0x05:
-				case 0x06:
-				case 0x0E:
-				case 0x0F:
-				case 0x10:
-				case 0x11:
-				case 0x12:
-				case 0x13:
-				case 0x14:
-				case 0x15:
-				case 0x16:
-				case 0x17:
-				case 0x18:
-				case 0x19:
-				case 0x1A:
-				case 0x1B:
-				case 0x1C:
-				case 0x1D:
-				case 0x1E:
-				case 0x1F:
-				case 0x7F:
-					append(value, start, idx);
-					end= this.sb.length();
-					appendEscapedCodepoint(c);
-					start= ++idx;
-					continue;
-				case 0x07:
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append("\\a"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x08:
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append("\\b"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x09:
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append("\\t"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0A:
-					append(value, start, idx);
-					this.sb.append("\\n"); //$NON-NLS-1$
-					end= this.sb.length();
-					start= ++idx;
-					continue;
-				case 0x0B:
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append("\\v"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0C:
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append("\\f"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0D:
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append("\\r"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case '\\':
-					append(value, start, idx);
-					end= this.sb.length();
-					this.sb.append('\\');
-					start= (isEscaped) ? ++idx : idx++;
-					continue;
-				default:
-					idx++;
-					continue;
-				}
-			}
-			{	final int cp= value.codePointAt(idx);
-				if (isPrintableChar(cp)) {
-					if (cp != c) {
-						idx+= 2;
-						max++;
+			switch (c) {
+			case 0x00:
+			case 0x01:
+			case 0x02:
+			case 0x03:
+			case 0x04:
+			case 0x05:
+			case 0x06:
+			case 0x0E:
+			case 0x0F:
+			case 0x10:
+			case 0x11:
+			case 0x12:
+			case 0x13:
+			case 0x14:
+			case 0x15:
+			case 0x16:
+			case 0x17:
+			case 0x18:
+			case 0x19:
+			case 0x1A:
+			case 0x1B:
+			case 0x1C:
+			case 0x1D:
+			case 0x1E:
+			case 0x1F:
+			case 0x7F:
+				append(value, start, idx);
+				end= this.sb.length();
+				appendEscapedCodepoint(c);
+				start= ++idx;
+				continue;
+			case 0x07:
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append("\\a"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x08:
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append("\\b"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x09:
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append("\\t"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0A:
+				append(value, start, idx);
+				this.sb.append("\\n"); //$NON-NLS-1$
+				end= this.sb.length();
+				start= ++idx;
+				continue;
+			case 0x0B:
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append("\\v"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0C:
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append("\\f"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0D:
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append("\\r"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case '\\':
+				append(value, start, idx);
+				end= this.sb.length();
+				this.sb.append('\\');
+				start= (isEscaped) ? ++idx : idx++;
+				continue;
+			case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+			case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
+			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+			case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F:
+			case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+			case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+			case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+			case 0x58: case 0x59: case 0x5A: case 0x5B: /* \\   */ case 0x5D: case 0x5E: case 0x5F:
+			case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+			case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
+			case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+			case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: /* DEL  */
+				idx++;
+				continue;
+			default:
+				{	final int cp= value.codePointAt(idx);
+					if (isPrintableChar(cp)) {
+						if (cp != c) {
+							idx+= 2;
+							max++;
+						}
+						else {
+							idx++;
+						}
+						continue;
 					}
 					else {
-						idx++;
+						append(value, start, idx);
+						end= this.sb.length();
+						appendEscapedCodepoint(cp);
+						if (cp != c) {
+							start= (idx+= 2);
+						}
+						else {
+							start= ++idx;
+						}
+						continue;
 					}
-					continue;
-				}
-				else {
-					append(value, start, idx);
-					end= this.sb.length();
-					appendEscapedCodepoint(cp);
-					if (cp != c) {
-						start= (idx+= 2);
-					}
-					else {
-						start= ++idx;
-					}
-					continue;
 				}
 			}
 		}
@@ -648,103 +688,113 @@
 		int start= idx;
 		while (idx < s.length()) {
 			final char c= s.charAt(idx);
-			if (c <= 255) {
-				switch (c) {
-				case 0x00:
-				case 0x01:
-				case 0x02:
-				case 0x03:
-				case 0x04:
-				case 0x05:
-				case 0x06:
-				case 0x0E:
-				case 0x0F:
-				case 0x10:
-				case 0x11:
-				case 0x12:
-				case 0x13:
-				case 0x14:
-				case 0x15:
-				case 0x16:
-				case 0x17:
-				case 0x18:
-				case 0x19:
-				case 0x1A:
-				case 0x1B:
-				case 0x1C:
-				case 0x1D:
-				case 0x1E:
-				case 0x1F:
-				case 0x7F:
-					append(s, start, idx);
-					appendEscapedCodepoint(c);
-					start= ++idx;
-					continue;
-				case 0x07:
-					append(s, start, idx);
-					this.sb.append("\\a"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x08:
-					append(s, start, idx);
-					this.sb.append("\\b"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x09:
-					append(s, start, idx);
-					this.sb.append("\\t"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0A:
-					append(s, start, idx);
-					this.sb.append("\\n"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0B:
-					append(s, start, idx);
-					this.sb.append("\\v"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0C:
-					append(s, start, idx);
-					this.sb.append("\\f"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case 0x0D:
-					append(s, start, idx);
-					this.sb.append("\\r"); //$NON-NLS-1$
-					start= ++idx;
-					continue;
-				case '\\':
-					append(s, start, idx);
-					this.sb.append("\\"); //$NON-NLS-1$
-					start= idx++;
-					continue;
-				default:
-					idx++;
-					continue;
-				}
-			}
-			{	final int cp= s.codePointAt(idx);
-				if (isPrintableChar(cp)) {
-					if (cp != c) {
-						idx+= 2;
+			switch (c) {
+			case 0x00:
+			case 0x01:
+			case 0x02:
+			case 0x03:
+			case 0x04:
+			case 0x05:
+			case 0x06:
+			case 0x0E:
+			case 0x0F:
+			case 0x10:
+			case 0x11:
+			case 0x12:
+			case 0x13:
+			case 0x14:
+			case 0x15:
+			case 0x16:
+			case 0x17:
+			case 0x18:
+			case 0x19:
+			case 0x1A:
+			case 0x1B:
+			case 0x1C:
+			case 0x1D:
+			case 0x1E:
+			case 0x1F:
+			case 0x7F:
+				append(s, start, idx);
+				appendEscapedCodepoint(c);
+				start= ++idx;
+				continue;
+			case 0x07:
+				append(s, start, idx);
+				this.sb.append("\\a"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x08:
+				append(s, start, idx);
+				this.sb.append("\\b"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x09:
+				append(s, start, idx);
+				this.sb.append("\\t"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0A:
+				append(s, start, idx);
+				this.sb.append("\\n"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0B:
+				append(s, start, idx);
+				this.sb.append("\\v"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0C:
+				append(s, start, idx);
+				this.sb.append("\\f"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case 0x0D:
+				append(s, start, idx);
+				this.sb.append("\\r"); //$NON-NLS-1$
+				start= ++idx;
+				continue;
+			case '\\':
+				append(s, start, idx);
+				this.sb.append("\\"); //$NON-NLS-1$
+				start= idx++;
+				continue;
+			case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+			case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
+			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+			case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F:
+			case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+			case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+			case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
+			case 0x58: case 0x59: case 0x5A: case 0x5B: /* \\   */ case 0x5D: case 0x5E: case 0x5F:
+			case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+			case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
+			case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+			case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: /* DEL  */
+				idx++;
+				continue;
+			default:
+				{	final int cp= s.codePointAt(idx);
+					if (isPrintableChar(cp)) {
+						if (cp != c) {
+							idx+= 2;
+						}
+						else {
+							idx++;
+						}
+						continue;
 					}
 					else {
-						idx++;
+						append(s, start, idx);
+						appendEscapedCodepoint(cp);
+						if (cp != c) {
+							start= (idx+= 2);
+						}
+						else {
+							start= ++idx;
+						}
+						continue;
 					}
-					continue;
-				}
-				else {
-					append(s, start, idx);
-					appendEscapedCodepoint(cp);
-					if (cp != c) {
-						start= (idx+= 2);
-					}
-					else {
-						start= ++idx;
-					}
-					continue;
 				}
 			}
 		}
diff --git a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/RLexer.java b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/RLexer.java
index 1a7f77b..75dc45b 100644
--- a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/RLexer.java
+++ b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/RLexer.java
@@ -26,6 +26,7 @@
 import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS12_SYNTAX_TOKEN_NOT_CLOSED;
 import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS_MASK_12;
 
+import org.eclipse.statet.jcommons.lang.Nullable;
 import org.eclipse.statet.jcommons.string.StringFactory;
 import org.eclipse.statet.jcommons.text.core.input.TextParserInput;
 
@@ -72,7 +73,7 @@
 /*=============================================================================*/
 	
 	private static StatusDetail createDetail(final TextParserInput in,
-			final int startOffset, final int endOffset, final String text) {
+			final int startOffset, final int endOffset, final @Nullable String text) {
 		final int beginIndex= in.getIndex(startOffset);
 		return new StatusDetail(beginIndex, in.getIndex() + in.getLengthInSource(endOffset) - beginIndex,
 				text );