[527258] Preserve 'en space' and 'em space' in XML formatter
diff --git a/xml/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java b/xml/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java
index 61cbf0e..d42b011 100644
--- a/xml/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java
+++ b/xml/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
+ * Copyright (c) 2007, 2020 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
@@ -68,6 +68,18 @@
 	static private final String EMPTY = ""; //$NON-NLS-1$
 	static private final String PROPERTY_WHITESPACE_FACET = "org.eclipse.wst.xsd.cm.properties/whitespace"; //$NON-NLS-1$
 
+	/**
+	 * @param c
+	 * @return whether the character falls within the XML Recommendation
+	 *         syntactic construct for whitespace. The standard Java Character
+	 *         class considers "em space" and "en space" to be whitespace,
+	 *         even though ICU4J does not.
+	 */
+	static boolean isWhitespace(char c) {
+		// https://bugs.eclipse.org/527258 : to preserve en space and em space
+		return c == 0x20 || c == '\t' || c == '\n' || c == '\r';
+	}
+
 	private XMLFormattingPreferences fPreferences = null;
 	private IProgressMonitor fProgressMonitor;
 
@@ -1061,7 +1073,7 @@
 		for (int i = 0; i < length; i++) {
 			c = text.charAt(i);
 			// Compress whitespace unless its a line delimiter and formatting does not permit joining lines
-			if (Character.isWhitespace(c)) {
+			if (isWhitespace(c)) {
 				if ((c != '\r' && c!= '\n') || joinLines) {
 					// Just came off of a word
 					if (start == end) {
@@ -1163,7 +1175,7 @@
 		boolean nonCharacterFound = false;
 		while (textOffset < fullTextArray.length && !nonCharacterFound) {
 			char c = fullTextArray[textOffset];
-			boolean isWhitespace = Character.isWhitespace(c);
+			boolean isWhitespace = isWhitespace(c);
 			if ((forWhitespace && isWhitespace) || (!forWhitespace && !isWhitespace))
 				characterRun.append(c);
 			else
@@ -1178,7 +1190,7 @@
 		int index = text.length() - 1;
 		while(index >= 0) {
 			char c = text.charAt(index--);
-			if (Character.isWhitespace(c))
+			if (isWhitespace(c))
 				whitespaceRun.insert(0, c);
 			else
 				break;
@@ -1311,7 +1323,7 @@
 				previousRegionFullText = previousDocumentRegion.getFullText();
 				int length = previousRegionFullText.length();
 				if (length > 1)
-					canIndent = Character.isWhitespace(previousRegionFullText.charAt(length - 1));
+					canIndent = isWhitespace(previousRegionFullText.charAt(length - 1));
 			}
 		}
 		if (canIndent) {
@@ -1712,4 +1724,4 @@
 	void setProgressMonitor(IProgressMonitor monitor) {
 		fProgressMonitor = monitor;
 	}
-}
\ No newline at end of file
+}
diff --git a/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/TestPartitionFormatterXML.java b/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/TestPartitionFormatterXML.java
index 2295e9f..0b55bc0 100644
--- a/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/TestPartitionFormatterXML.java
+++ b/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/TestPartitionFormatterXML.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
+ * Copyright (c) 2007, 2020 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
@@ -199,6 +199,13 @@
 		formatAndAssertEquals("testfiles/xml/xml-space-preserve-standalone.xml", "testfiles/xml/xml-space-preserve-standalone-newfmt.xml", prefs);
 	}
 
+	public void testPreserveESpace() throws UnsupportedEncodingException, IOException, CoreException {
+		// [527258] - XML formatter replaces 'en space' with space
+		XMLFormattingPreferences prefs = new XMLFormattingPreferences();
+		prefs.setClearAllBlankLines(true);
+		formatAndAssertEquals("testfiles/xml/nbsp-before.xml", "testfiles/xml/nbsp-after.xml", prefs);
+	}
+
 	public void testPreserveFormatDTD() throws UnsupportedEncodingException, IOException, CoreException {
 		// results are different than old formatter
 		// Bug [228495] - Result should have blank lines cleared
diff --git a/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/testfiles/xml/nbsp-after.xml b/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/testfiles/xml/nbsp-after.xml
new file mode 100644
index 0000000..099fc2c
--- /dev/null
+++ b/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/testfiles/xml/nbsp-after.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<cell> 40° C.</cell>
\ No newline at end of file
diff --git a/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/testfiles/xml/nbsp-before.xml b/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/testfiles/xml/nbsp-before.xml
new file mode 100644
index 0000000..099fc2c
--- /dev/null
+++ b/xml/tests/org.eclipse.wst.xml.core.tests/src/org/eclipse/wst/xml/core/tests/format/testfiles/xml/nbsp-before.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<cell> 40° C.</cell>
\ No newline at end of file