Merge pull request #36 from tied/Changes-for-Apple-Silicon-M1-build

DIRSTUDIO-1293 | Changes for native Apple Silicon M1 build
diff --git a/.gitignore b/.gitignore
index ef2d377..e875c86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,4 @@
 plugins/ldapservers.apacheds/resources/libs/
 tests/test.integration.ui/screenshots
 .DS_Store
-
+workspace
diff --git a/eclipse-trgt-platform/pom-first.xml b/eclipse-trgt-platform/pom-first.xml
index 22ed568..2ae081e 100644
--- a/eclipse-trgt-platform/pom-first.xml
+++ b/eclipse-trgt-platform/pom-first.xml
@@ -74,6 +74,12 @@
       <version>${org.apache.commons.pool.version}</version>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-text</artifactId>
+      <version>${org.apache.commons.text.version}</version>
+    </dependency>
+
     <!-- Bouncycastle modules -->
     <dependency>
       <groupId>org.bouncycastle</groupId>
diff --git a/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template b/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template
index 498a76e..842990d 100644
--- a/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template
+++ b/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template
@@ -19,7 +19,7 @@
   @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 -->
 <?pde version="3.8"?>
-<target name="Apache Directory Studio Platform" sequenceNumber="485">
+<target name="Apache Directory Studio Platform" sequenceNumber="486">
   <locations>
 
     <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
@@ -39,6 +39,7 @@
       <unit id="org.apache.commons.io" version="${org.apache.commons.io.bundleversion}"/>
       <unit id="org.apache.commons.lang3" version="${org.apache.commons.lang3.bundleversion}"/>
       <unit id="org.apache.commons.commons-pool2" version="${org.apache.commons.pool.bundleversion}"/>
+      <unit id="org.apache.commons.commons-text" version="${org.apache.commons.text.bundleversion}"/>
 
       <!-- LDAP API modules -->
       <unit id="org.apache.directory.api.asn1.api" version="${org.apache.directory.api.bundleversion}"/>
diff --git a/features/rcp.feature/feature.xml b/features/rcp.feature/feature.xml
index def333d..65e3678 100644
--- a/features/rcp.feature/feature.xml
+++ b/features/rcp.feature/feature.xml
@@ -267,6 +267,13 @@
          unpack="false"/>
 
    <plugin
+         id="org.apache.commons.commons-text"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
          id="com.github.ben-manes.caffeine"
          download-size="0"
          install-size="0"
diff --git a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ListContentProposalProvider.java b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ListContentProposalProvider.java
index 8533d41..bf386e6 100644
--- a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ListContentProposalProvider.java
+++ b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ListContentProposalProvider.java
@@ -124,7 +124,7 @@
         }
         else
         {
-            this.proposals = newProposals;
+            this.proposals = new ArrayList<String>( newProposals );
         }
     }
 
diff --git a/plugins/ldapbrowser.core/pom-first.xml b/plugins/ldapbrowser.core/pom-first.xml
index bb34e8d..b279dad 100644
--- a/plugins/ldapbrowser.core/pom-first.xml
+++ b/plugins/ldapbrowser.core/pom-first.xml
@@ -118,6 +118,7 @@
  org.apache.directory.studio.ldapbrowser.core.utils</Export-Package>
  
             <Import-Package>
+ org.apache.commons.text,
  org.apache.commons.lang3,
  org.apache.commons.collections4,
  org.apache.commons.codec.digest,
@@ -127,6 +128,7 @@
             </Import-Package>
             
             <Require-Bundle>
+ org.apache.commons.commons-text,
  org.apache.directory.api.asn1.api;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.model;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.codec.core;bundle-version="${org.apache.directory.api.bundleversion}",
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java
index e6195ba..e5b9d56 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java
@@ -30,6 +30,7 @@
 import java.util.Map;
 
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.text.translate.CharSequenceTranslator;
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
@@ -267,6 +268,7 @@
         String[] attributes, String attributeDelimiter, String valueDelimiter, String quoteCharacter,
         String lineSeparator, String encoding, int binaryEncoding, boolean exportDn )
     {
+        CharSequenceTranslator decoder = Utils.createPostalAddressDecoder( lineSeparator );
 
         // group multi-valued attributes
         Map<String, String> attributeMap = getAttributeMap( browserConnection, record, valueDelimiter, encoding,
@@ -294,7 +296,7 @@
                 AttributeType type = browserConnection.getSchema().getAttributeTypeDescription( attributeName );
                 if ( SchemaConstants.POSTAL_ADDRESS_SYNTAX.equals( type.getSyntaxOid() ) )
                 {
-                    value = Utils.decodePostalAddress( value, lineSeparator );
+                    value = decoder.translate( value );
                 }
                 appendValue( quoteCharacter, sb, value );
             }
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java
index abbed1d..b9c40e8 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java
@@ -26,6 +26,7 @@
 import java.util.Map;
 
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.text.translate.CharSequenceTranslator;
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
@@ -60,6 +61,9 @@
     /** The maximum count limit */
     public static final int MAX_COUNT_LIMIT = 65000;
 
+    /** The postal address decoder. */
+    private static CharSequenceTranslator DECODER = Utils.createPostalAddressDecoder( "\n" ); //$NON-NLS-1$;
+
     /** The filename of the ODF file. */
     private String exportOdfFilename;
 
@@ -297,7 +301,7 @@
                 if ( SchemaConstants.POSTAL_ADDRESS_SYNTAX.equals( type.getSyntaxOid() ) )
                 {
                     // https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#__RefHeading__1017970_715980110
-                    value = Utils.decodePostalAddress( value, "\n" ); //$NON-NLS-1$
+                    value = DECODER.translate( value );
                     cell.setTextWrapped( true );
                 }
                 cell.setStringValue( value );
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java
index 2030022..3bfaafc 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java
@@ -27,6 +27,7 @@
 import java.util.Map;
 
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.text.translate.CharSequenceTranslator;
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
@@ -62,6 +63,9 @@
     /** The maximum count limit */
     public static final int MAX_COUNT_LIMIT = 65000;
 
+    /** The postal address decoder. */
+    private static CharSequenceTranslator DECODER = Utils.createPostalAddressDecoder( "\n" ); //$NON-NLS-1$;
+
     /** The filename of the XLS file. */
     private String exportXlsFilename;
 
@@ -314,7 +318,7 @@
                 if ( SchemaConstants.POSTAL_ADDRESS_SYNTAX.equals( type.getSyntaxOid() ) )
                 {
                     // https://poi.apache.org/components/spreadsheet/quick-guide.html#NewLinesInCells
-                    value = Utils.decodePostalAddress( value, "\n" ); //$NON-NLS-1$
+                    value = DECODER.translate( value );
                     cell.setCellStyle( wrapStyle );
                 }
                 cell.setCellValue( value );
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
index 604c8af..1247dd0 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
@@ -35,6 +35,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.text.translate.CharSequenceTranslator;
+import org.apache.commons.text.translate.LookupTranslator;
 import org.apache.directory.api.ldap.model.name.Ava;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.ldap.model.name.Rdn;
@@ -673,30 +675,30 @@
      *                 / UTFMB
      * </pre>
      *
-     * @param input the encoded string
      * @param separator the separator to output between address lines
-     * @return the decoded string
+     * @return a translator object for decoding
      */
-    public static String decodePostalAddress( String input, String separator )
+    public static CharSequenceTranslator createPostalAddressDecoder( String separator )
     {
-        return input.replace( "$", separator ) //$NON-NLS-1$
-            .replace( "\\24", "$" ) //$NON-NLS-1$ //$NON-NLS-2$
-            .replace( "\\5C", "\\" ) //$NON-NLS-1$ //$NON-NLS-2$
-            .replace( "\\5c", "\\" ); //$NON-NLS-1$ //$NON-NLS-2$
+        return new LookupTranslator( Map.of(
+            "$", separator, //$NON-NLS-1$
+            "\\24", "$", //$NON-NLS-1$ //$NON-NLS-2$
+            "\\5C", "\\", //$NON-NLS-1$ //$NON-NLS-2$
+            "\\5c", "\\" ) ); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
 
     /**
      * Encodes the RFC 4517 Postal Address syntax.
      *
-     * @param input the string to encode
      * @param separator the separator used between address lines
-     * @return the encoded string
+     * @return a translator object for encoding
      */
-    public static String encodePostalAddress( String input, String separator )
+    public static CharSequenceTranslator createPostalAddressEncoder( String separator )
     {
-        return input.replace( "\\", "\\5C" ) //$NON-NLS-1$ //$NON-NLS-2$
-            .replace( "$", "\\24" ) //$NON-NLS-1$ //$NON-NLS-2$
-            .replace( separator, "$" ); //$NON-NLS-1$
+        return new LookupTranslator( Map.of(
+            "\\", "\\5C", //$NON-NLS-1$ //$NON-NLS-2$
+            "$", "\\24", //$NON-NLS-1$ //$NON-NLS-2$
+            separator, "$" ) ); //$NON-NLS-1$
     }
 }
diff --git a/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java b/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java
index b99651f..0f88cbc 100644
--- a/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java
+++ b/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java
@@ -21,6 +21,7 @@
 
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.apache.commons.text.translate.CharSequenceTranslator;
 import org.junit.jupiter.api.Test;
 
 
@@ -29,36 +30,42 @@
     @Test
     public void testPostalAddressTrivial()
     {
-        assertEquals( "abc", Utils.decodePostalAddress( "abc", "!" ) );
-        assertEquals( "abc", Utils.encodePostalAddress( "abc", "!" ) );
+        assertEquals( "abc", Utils.createPostalAddressDecoder( "!" ).translate( "abc" ) );
+        assertEquals( "abc", Utils.createPostalAddressEncoder( "!" ).translate( "abc" ) );
     }
 
 
     @Test
     public void testPostalAddressEscaped()
     {
-        assertEquals( "!", Utils.decodePostalAddress( "$", "!" ) );
-        assertEquals( "$", Utils.decodePostalAddress( "\\24", "!" ) );
-        assertEquals( "\\", Utils.decodePostalAddress( "\\5C", "!" ) );
-        assertEquals( "\\", Utils.decodePostalAddress( "\\5c", "!" ) );
+        CharSequenceTranslator decoder = Utils.createPostalAddressDecoder( "!" );
+        assertEquals( "!", decoder.translate( "$" ) );
+        assertEquals( "$", decoder.translate( "\\24" ) );
+        assertEquals( "\\", decoder.translate( "\\5C" ) );
+        assertEquals( "\\", decoder.translate( "\\5c" ) );
+        assertEquals( "\\5C", decoder.translate( "\\5c5C" ) );
+        assertEquals( "\\5c", decoder.translate( "\\5C5c" ) );
 
-        assertEquals( "$", Utils.encodePostalAddress( "!", "!" ) );
-        assertEquals( "\\24", Utils.encodePostalAddress( "$", "!" ) );
-        assertEquals( "\\5C", Utils.encodePostalAddress( "\\", "!" ) );
+        CharSequenceTranslator encoder = Utils.createPostalAddressEncoder( "!" );
+        assertEquals( "$", encoder.translate( "!" ) );
+        assertEquals( "\\24", encoder.translate( "$" ) );
+        assertEquals( "\\5C", encoder.translate( "\\" ) );
     }
 
 
     @Test
     public void testPostalAddressRfcExamples()
     {
+        CharSequenceTranslator decoder = Utils.createPostalAddressDecoder( "\n" );
         assertEquals( "1234 Main St.\nAnytown, CA 12345\nUSA",
-            Utils.decodePostalAddress( "1234 Main St.$Anytown, CA 12345$USA", "\n" ) );
+            decoder.translate( "1234 Main St.$Anytown, CA 12345$USA" ) );
         assertEquals( "$1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA",
-            Utils.decodePostalAddress( "\\241,000,000 Sweepstakes$PO Box 1000000$Anytown, CA 12345$USA", "\n" ) );
+            decoder.translate( "\\241,000,000 Sweepstakes$PO Box 1000000$Anytown, CA 12345$USA" ) );
 
+        CharSequenceTranslator encoder = Utils.createPostalAddressEncoder( "\n" );
         assertEquals( "1234 Main St.$Anytown, CA 12345$USA",
-            Utils.encodePostalAddress( "1234 Main St.\nAnytown, CA 12345\nUSA", "\n" ) );
+            encoder.translate( "1234 Main St.\nAnytown, CA 12345\nUSA" ) );
         assertEquals( "\\241,000,000 Sweepstakes$PO Box 1000000$Anytown, CA 12345$USA",
-            Utils.encodePostalAddress( "$1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA", "\n" ) );
+            encoder.translate( "$1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA" ) );
     }
 }
diff --git a/plugins/valueeditors/pom-first.xml b/plugins/valueeditors/pom-first.xml
index 95338de..f4e60c4 100644
--- a/plugins/valueeditors/pom-first.xml
+++ b/plugins/valueeditors/pom-first.xml
@@ -64,10 +64,12 @@
  org.apache.directory.studio.valueeditors.uuid</Export-Package>
  
             <Import-Package>org.apache.commons.codec,
- org.apache.commons.codec.binary
+ org.apache.commons.codec.binary,
+ org.apache.commons.text
             </Import-Package>
             
             <Require-Bundle>
+ org.apache.commons.commons-text,
  org.apache.directory.api.ldap.model;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.util;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.studio.common.ui,
diff --git a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressDialog.java b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressDialog.java
index d025204..f02539b 100644
--- a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressDialog.java
+++ b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressDialog.java
@@ -21,6 +21,10 @@
 package org.apache.directory.studio.valueeditors.address;
 
 
+import java.util.regex.Pattern;
+
+import org.apache.commons.text.translate.CharSequenceTranslator;
+import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils;
 import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants;
 import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.valueeditors.ValueEditorsActivator;
@@ -29,6 +33,8 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
@@ -52,6 +58,14 @@
     /** The text widget. */
     private Text text;
 
+    /** The postal address decoder. */
+    private CharSequenceTranslator decoder;
+
+    /** The postal address encoder. */
+    private CharSequenceTranslator encoder;
+
+    /** The checkbox to strip trailing whitespace. */
+    private Button stripWhitespaceCheckbox;
 
     /**
      * Creates a new instance of AddressDialog.
@@ -65,6 +79,8 @@
         super.setShellStyle( super.getShellStyle() | SWT.RESIZE );
         this.initialAddress = initialAddress;
         this.returnAddress = null;
+        this.decoder = Utils.createPostalAddressDecoder( BrowserCoreConstants.LINE_SEPARATOR );
+        this.encoder = Utils.createPostalAddressEncoder( BrowserCoreConstants.LINE_SEPARATOR );
     }
 
 
@@ -84,17 +100,27 @@
      */
     protected void createButtonsForButtonBar( Composite parent )
     {
+        ((GridLayout) parent.getLayout()).numColumns = 2;
+        stripWhitespaceCheckbox = BaseWidgetUtils.createCheckbox( parent, Messages.getString( "AddressDialog.StripWhitespace" ), 2 ); //$NON-NLS-1$
+        stripWhitespaceCheckbox.setSelection( true );
         createButton( parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, false );
         createButton( parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false );
     }
 
 
+    private static final Pattern TRAILING_WHITESPACE = Pattern.compile( "\\s+$", Pattern.MULTILINE ); //$NON-NLS-1$
+
+
     /**
      * @see org.eclipse.jface.dialogs.Dialog#okPressed()
      */
     protected void okPressed()
     {
-        returnAddress = Utils.encodePostalAddress( text.getText(), BrowserCoreConstants.LINE_SEPARATOR );
+        String lines = text.getText();
+        if ( stripWhitespaceCheckbox.getSelection() ) {
+            lines = TRAILING_WHITESPACE.matcher(lines).replaceAll( "" ); //$NON-NLS-1$
+        }
+        returnAddress = encoder.translate( lines );
         super.okPressed();
     }
 
@@ -111,7 +137,7 @@
 
         // text widget
         text = new Text( composite, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL );
-        text.setText( Utils.decodePostalAddress( initialAddress, BrowserCoreConstants.LINE_SEPARATOR ) );
+        text.setText( decoder.translate( initialAddress ) );
         // GridData gd = new GridData(GridData.GRAB_HORIZONTAL |
         // GridData.HORIZONTAL_ALIGN_FILL);
         gd = new GridData( GridData.FILL_BOTH );
diff --git a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressValueEditor.java b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressValueEditor.java
index 2eac89b..2b54d57 100644
--- a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressValueEditor.java
+++ b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/AddressValueEditor.java
@@ -21,6 +21,7 @@
 package org.apache.directory.studio.valueeditors.address;
 
 
+import org.apache.commons.text.translate.CharSequenceTranslator;
 import org.apache.directory.studio.ldapbrowser.core.model.IValue;
 import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.valueeditors.AbstractDialogStringValueEditor;
@@ -37,6 +38,10 @@
  */
 public class AddressValueEditor extends AbstractDialogStringValueEditor
 {
+    /** The postal address decoder. */
+    private CharSequenceTranslator decoder = Utils.createPostalAddressDecoder( ", " ); //$NON-NLS-1$
+
+
     /**
      * {@inheritDoc}
      * 
@@ -73,7 +78,7 @@
 
         if ( !showRawValues() )
         {
-            displayValue = Utils.decodePostalAddress( displayValue, ", " ); //$NON-NLS-1$
+            displayValue = decoder.translate( displayValue );
         }
 
         return displayValue;
diff --git a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages.properties b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages.properties
index a70151f..f27e8f9 100644
--- a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages.properties
+++ b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages.properties
@@ -16,3 +16,4 @@
 # under the License.
 
 AddressDialog.AddressEditor=Address Editor
+AddressDialog.StripWhitespace=Strip trailing whitespace
diff --git a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_de.properties b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_de.properties
index 96fafb3..a4f8e2a 100644
--- a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_de.properties
+++ b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_de.properties
@@ -16,3 +16,4 @@
 # under the License.
 
 AddressDialog.AddressEditor=Adressen Editor
+AddressDialog.StripWhitespace=Nachgestellte Leerzeichen entfernen
diff --git a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_fr.properties b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_fr.properties
index e1263a5..8d814e3 100644
--- a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_fr.properties
+++ b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/address/messages_fr.properties
@@ -16,3 +16,4 @@
 # under the License.
 
 AddressDialog.AddressEditor=Editeur d''addresse
+AddressDialog.StripWhitespace=Supprimer les espaces de fin
diff --git a/pom.xml b/pom.xml
index cf3d610..e8e5612 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,8 @@
     <org.apache.commons.lang3.bundleversion>3.12.0</org.apache.commons.lang3.bundleversion>
     <org.apache.commons.pool.version>2.9.0</org.apache.commons.pool.version>
     <org.apache.commons.pool.bundleversion>2.9.0</org.apache.commons.pool.bundleversion>
+    <org.apache.commons.text.version>1.9</org.apache.commons.text.version>
+    <org.apache.commons.text.bundleversion>1.9</org.apache.commons.text.bundleversion>
     <org.apache.directory.api.version>2.1.0</org.apache.directory.api.version>
     <org.apache.directory.api.bundleversion>2.1.0</org.apache.directory.api.bundleversion>
     <org.apache.directory.server.version>2.0.0.AM26</org.apache.directory.server.version>
@@ -137,8 +139,8 @@
         <groupId>org.eclipse.tycho</groupId>
         <artifactId>tycho-compiler-plugin</artifactId>
         <configuration>
-          <source>1.8</source>
-          <target>1.8</target>
+          <source>11</source>
+          <target>11</target>
         </configuration>
       </plugin>
 
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/EntryEditorTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/EntryEditorTest.java
index 7c2b53c..001e3ab 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/EntryEditorTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/EntryEditorTest.java
@@ -569,7 +569,7 @@
 
 
     /**
-     * DIRSTUDIO-1298: The RFC 4517 Postal Address value editor en-/decoding is incomplete
+     * Test for the postal address value editor, with an example from DIRSTUDIO-1298 to verify encoding/decoding of special characters.
      */
     @ParameterizedTest
     @LdapServersSource
@@ -611,30 +611,48 @@
             "1234 Main St., Anytown, CA 12345, USA" );
         assertTrue( addressEditorDialogBot.isVisible() );
         assertEquals( "1234 Main St.\nAnytown, CA 12345\nUSA", addressEditorDialogBot.getText() );
-        // TODO: $1,000,000 Sweepstakes
-        addressEditorDialogBot.setText( "1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA" );
+        addressEditorDialogBot.setText( "$1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA" );
         addressEditorDialogBot.clickOkButton();
         assertEquals( 9, entryEditorBot.getAttributeValues().size() );
         assertFalse( entryEditorBot.getAttributeValues()
             .contains( "postalAddress: 1234 Main St., Anytown, CA 12345, USA" ) );
         assertTrue( entryEditorBot.getAttributeValues()
-            // TODO: $1,000,000 Sweepstakes
-            .contains( "postalAddress: 1,000,000 Sweepstakes, PO Box 1000000, Anytown, CA 12345, USA" ) );
+            .contains( "postalAddress: $1,000,000 Sweepstakes, PO Box 1000000, Anytown, CA 12345, USA" ) );
         modificationLogsViewBot
             .waitForText( "delete: postalAddress\npostalAddress: 1234 Main St.$Anytown, CA 12345$USA" );
         modificationLogsViewBot.waitForText(
-            // TODO: $1,000,000 Sweepstakes
-            "add: postalAddress\npostalAddress: 1,000,000 Sweepstakes$PO Box 1000000$Anytown, CA 12345$USA" );
+            "add: postalAddress\npostalAddress: \\241,000,000 Sweepstakes$PO Box 1000000$Anytown, CA 12345$USA" );
 
         // verify value is correctly decoded
-        // TODO: $1,000,000 Sweepstakes
         addressEditorDialogBot = entryEditorBot.editValueExpectingAddressEditor( "postalAddress",
-            "1,000,000 Sweepstakes, PO Box 1000000, Anytown, CA 12345, USA" );
+            "$1,000,000 Sweepstakes, PO Box 1000000, Anytown, CA 12345, USA" );
         assertTrue( addressEditorDialogBot.isVisible() );
-        // TODO: $1,000,000 Sweepstakes
-        assertEquals( "1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA",
+        assertEquals( "$1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA",
             addressEditorDialogBot.getText() );
         addressEditorDialogBot.clickCancelButton();
+
+        // verify that the default is to strip trailing whitespace
+        addressEditorDialogBot = entryEditorBot.editValueExpectingAddressEditor( "postalAddress",
+            "$1,000,000 Sweepstakes, PO Box 1000000, Anytown, CA 12345, USA" );
+        assertTrue( addressEditorDialogBot.isVisible() );
+        addressEditorDialogBot.setText( "line 1 \nline 2  \nline 3   \n" );
+        addressEditorDialogBot.clickOkButton();
+        assertEquals( 9, entryEditorBot.getAttributeValues().size() );
+        assertTrue( entryEditorBot.getAttributeValues()
+            .contains( "postalAddress: line 1, line 2, line 3" ) );
+        modificationLogsViewBot.waitForText(
+            "add: postalAddress\npostalAddress: line 1$line 2$line 3" );
+
+        // verify that stripping of trailing whitespace can be disabled
+        addressEditorDialogBot = entryEditorBot.editValueExpectingAddressEditor( "postalAddress",
+            "line 1, line 2, line 3" );
+        assertTrue( addressEditorDialogBot.isVisible() );
+        addressEditorDialogBot.setText( "line 1 \nline 2  \nline 3" );
+        addressEditorDialogBot.deselectStripWhitespaceCheckbox();
+        addressEditorDialogBot.clickOkButton();
+        assertEquals( 9, entryEditorBot.getAttributeValues().size() );
+        modificationLogsViewBot.waitForText(
+            "add: postalAddress\npostalAddress: line 1 $line 2  $line 3" );
     }
 
 
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/AddressEditorDialogBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/AddressEditorDialogBot.java
index 83a7719..3108a02 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/AddressEditorDialogBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/AddressEditorDialogBot.java
@@ -44,4 +44,9 @@
         bot.text( 0 ).setText( text );
     }
 
+    public void deselectStripWhitespaceCheckbox()
+    {
+        bot.checkBox( "Strip trailing whitespace" ).deselect();
+    }
+
 }
diff --git a/tools/Debian Package/package/usr/share/applications/apachedirectorystudio.desktop b/tools/Debian Package/package/usr/share/applications/apachedirectorystudio.desktop
index cc7d709..0255d87 100644
--- a/tools/Debian Package/package/usr/share/applications/apachedirectorystudio.desktop
+++ b/tools/Debian Package/package/usr/share/applications/apachedirectorystudio.desktop
@@ -1,9 +1,8 @@
 [Desktop Entry]
 Version=1.0
-Encoding=UTF-8
 Name=Apache Directory Studio
 GenericName=Apache Directory Studio
 Comment=LDAP Browser and Directory Client
 Type=Application
 Exec=apachedirectorystudio
-Categories=Accessories;
+Categories=Development;Database;