You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2020/05/04 20:00:32 UTC

[directory-studio] branch master updated: DIRSTUDIO-1251: Show LDAP result code in modification log, LDIF log, and error dialog

This is an automated email from the ASF dual-hosted git repository.

seelmann pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/directory-studio.git


The following commit(s) were added to refs/heads/master by this push:
     new 16753e1  DIRSTUDIO-1251: Show LDAP result code in modification log, LDIF log, and error dialog
16753e1 is described below

commit 16753e1c51f04018e15e1b66a59a99e378884666
Author: Stefan Seelmann <ma...@stefan-seelmann.de>
AuthorDate: Mon May 4 22:00:17 2020 +0200

    DIRSTUDIO-1251: Show LDAP result code in modification log, LDIF log, and error dialog
---
 .../common/core/jobs/StudioProgressMonitor.java    |   2 +-
 .../studio/connection/core/ILdapLogger.java        |  42 ++--
 .../connection/core/io/StudioLdapException.java    |  74 +++++++
 .../core/io/api/DirectoryApiConnectionWrapper.java |  52 ++---
 .../core/io/api/LdifModificationLogger.java        |  47 +----
 .../connection/core/io/api/LdifSearchLogger.java   |  52 +----
 .../ldapbrowser/core/jobs/CopyEntriesRunnable.java |   4 +-
 .../core/jobs/DeleteEntriesRunnable.java           |   4 +-
 .../ldapbrowser/core/jobs/ImportLdifRunnable.java  |   4 +-
 .../ldapbrowser/core/jobs/MoveEntriesRunnable.java |   4 +-
 .../ldapbrowser/core/jobs/RenameEntryRunnable.java |   4 +-
 .../PasswordModifyExtendedOperationAction.java     |   1 +
 .../core/DirectoryApiConnectionWrapperTest.java    |  48 +++--
 .../studio/test/integration/ui/CopyEntryTest.java  |   4 +-
 .../test/integration/ui/ErrorHandlingTest.java     | 216 +++++++++++++++++++++
 .../integration/ui/ExtendedOperationsTest.java     |   3 +
 .../test/integration/ui/ImportExportTest.java      | 133 ++++++++++---
 .../integration/ui/NewConnectionWizardTest.java    |   2 +-
 .../studio/test/integration/ui/bots/BotUtils.java  |   1 -
 .../ui/bots/CertificateTrustDialogBot.java         |  15 --
 .../studio/test/integration/ui/bots/DialogBot.java |   7 +
 .../test/integration/ui/bots/EntryEditorBot.java   |  12 ++
 .../integration/ui/bots/EntryEditorWidgetBot.java  |  17 ++
 .../test/integration/ui/bots/ErrorDialogBot.java   |   6 +
 .../test/integration/ui/bots/ImportWizardBot.java  |  27 ++-
 .../PasswordModifyExtendedOperationDialogBot.java  |  18 --
 26 files changed, 575 insertions(+), 224 deletions(-)

diff --git a/plugins/common.core/src/main/java/org/apache/directory/studio/common/core/jobs/StudioProgressMonitor.java b/plugins/common.core/src/main/java/org/apache/directory/studio/common/core/jobs/StudioProgressMonitor.java
index 3214067..6dcbb40 100644
--- a/plugins/common.core/src/main/java/org/apache/directory/studio/common/core/jobs/StudioProgressMonitor.java
+++ b/plugins/common.core/src/main/java/org/apache/directory/studio/common/core/jobs/StudioProgressMonitor.java
@@ -285,7 +285,7 @@ public class StudioProgressMonitor extends ProgressMonitorWrapper
                     
                     if ( indexOfAny > -1 )
                     {
-                        exceptionMessage = exceptionMessage.substring( 0, indexOfAny - 1 );
+                        exceptionMessage = exceptionMessage.substring( 0, indexOfAny );
                     }
                     
                     buffer.append( "\n - " ).append( exceptionMessage ); //$NON-NLS-1$
diff --git a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ILdapLogger.java b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ILdapLogger.java
index fd00f59..259245d 100644
--- a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ILdapLogger.java
+++ b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/ILdapLogger.java
@@ -26,11 +26,11 @@ import javax.naming.directory.SearchControls;
 
 import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.ldap.model.entry.Modification;
-import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.message.Referral;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 
 
 /**
@@ -49,7 +49,10 @@ public interface ILdapLogger
      * @param controls the controls
      * @param ex the LDAP exception if an error occurred, null otherwise
      */
-    void logChangetypeAdd( Connection connection, final Entry entry, final Control[] controls, LdapException ex );
+    default void logChangetypeAdd( Connection connection, final Entry entry, final Control[] controls,
+        StudioLdapException ex )
+    {
+    }
 
 
     /**
@@ -61,8 +64,11 @@ public interface ILdapLogger
      * @param ex the LDAP exception if an error occurred, null otherwise
      * 
      */
-    void logChangetypeDelete( Connection connection, final Dn dn, final Control[] controls,
-        LdapException ex );
+    default void logChangetypeDelete( Connection connection, final Dn dn, final Control[] controls,
+        StudioLdapException ex )
+    {
+
+    }
 
 
     /**
@@ -74,8 +80,10 @@ public interface ILdapLogger
      * @param ex the LDAP exception if an error occurred, null otherwise
      * @param controls the controls
      */
-    void logChangetypeModify( Connection connection, final Dn dn,
-        final Collection<Modification> modifications, final Control[] controls, LdapException ex );
+    default void logChangetypeModify( Connection connection, final Dn dn,
+        final Collection<Modification> modifications, final Control[] controls, StudioLdapException ex )
+    {
+    }
 
 
     /**
@@ -88,8 +96,10 @@ public interface ILdapLogger
      * @param controls the controls
      * @param ex the LDAP exception if an error occurred, null otherwise
      */
-    void logChangetypeModDn( Connection connection, final Dn oldDn, final Dn newDn,
-        final boolean deleteOldRdn, final Control[] controls, LdapException ex );
+    default void logChangetypeModDn( Connection connection, final Dn oldDn, final Dn newDn,
+        final boolean deleteOldRdn, final Control[] controls, StudioLdapException ex )
+    {
+    }
 
 
     /**
@@ -152,9 +162,11 @@ public interface ILdapLogger
      * @param requestNum the request number
      * @param ex the LDAP exception if an error occurred, null otherwise
      */
-    void logSearchRequest( Connection connection, String searchBase, String filter,
+    default void logSearchRequest( Connection connection, String searchBase, String filter,
         SearchControls searchControls, AliasDereferencingMethod aliasesDereferencingMethod,
-        Control[] controls, long requestNum, LdapException ex );
+        Control[] controls, long requestNum, StudioLdapException ex )
+    {
+    }
 
 
     /**
@@ -166,8 +178,10 @@ public interface ILdapLogger
      * @param requestNum the request number
      * @param ex the LDAP exception if an error occurred, null otherwise
      */
-    void logSearchResultReference( Connection connection, Referral referral,
-        ReferralsInfo referralsInfo, long requestNum, LdapException ex );
+    default void logSearchResultReference( Connection connection, Referral referral,
+        ReferralsInfo referralsInfo, long requestNum, StudioLdapException ex )
+    {
+    }
 
 
     /**
@@ -178,6 +192,8 @@ public interface ILdapLogger
      * @param requestNum the request number
      * @param ex the LDAP exception if an error occurred, null otherwise
      */
-    void logSearchResultDone( Connection connection, long count, long requestNum, LdapException ex );
+    default void logSearchResultDone( Connection connection, long count, long requestNum, StudioLdapException ex )
+    {
+    }
 
 }
diff --git a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/StudioLdapException.java b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/StudioLdapException.java
new file mode 100644
index 0000000..4057a4d
--- /dev/null
+++ b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/StudioLdapException.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.studio.connection.core.io;
+
+
+import java.util.Locale;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
+import org.apache.directory.api.ldap.model.exception.LdapOperationException;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+
+
+public class StudioLdapException extends Exception
+{
+    private static final long serialVersionUID = -1L;
+
+    public StudioLdapException( Exception exception )
+    {
+        super( exception );
+    }
+
+
+    @Override
+    public String getMessage()
+    {
+        String message = "";
+        Throwable cause = getCause();
+        if ( cause instanceof LdapOperationException )
+        {
+            LdapOperationException loe = ( LdapOperationException ) cause;
+            ResultCodeEnum rc = loe.getResultCode();
+            String template = " [LDAP result code %d - %s]"; //$NON-NLS-1$
+            message += String.format( Locale.ROOT, template, rc.getResultCode(), rc.getMessage() );
+        }
+        if ( StringUtils.isNotBlank( cause.getMessage() ) )
+        {
+            message += " " + cause.getMessage(); //$NON-NLS-1$
+        }
+        return message;
+    }
+
+
+    public static boolean isEntryAlreadyExistsException( Exception exception )
+    {
+        return ExceptionUtils.indexOfThrowable( exception, LdapEntryAlreadyExistsException.class ) > -1;
+    }
+
+
+    public static boolean isContextNotEmptyException( Exception exception )
+    {
+        return ExceptionUtils.indexOfThrowable( exception, LdapContextNotEmptyException.class ) > -1;
+    }
+
+}
diff --git a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/DirectoryApiConnectionWrapper.java b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/DirectoryApiConnectionWrapper.java
index b7ebdb3..0450fd2 100644
--- a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/DirectoryApiConnectionWrapper.java
+++ b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/DirectoryApiConnectionWrapper.java
@@ -91,6 +91,7 @@ import org.apache.directory.studio.connection.core.Messages;
 import org.apache.directory.studio.connection.core.ReferralsInfo;
 import org.apache.directory.studio.connection.core.io.ConnectionWrapper;
 import org.apache.directory.studio.connection.core.io.ConnectionWrapperUtils;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.io.StudioTrustManager;
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.osgi.util.NLS;
@@ -243,7 +244,7 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
 
                     try
                     {
@@ -493,7 +494,7 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                     }
                     catch ( Exception e )
                     {
-                        exception = e;
+                        exception = toStudioLdapException( e );
                     }
                 }
             };
@@ -593,23 +594,21 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
                 }
 
-                LdapException le = toLdapException( exception );
-
                 for ( ILdapLogger logger : getLdapLoggers() )
                 {
                     if ( searchResultEnumeration != null )
                     {
                         logger.logSearchRequest( connection, searchBase, filter, searchControls,
-                            aliasesDereferencingMethod, controls, requestNum, le );
+                            aliasesDereferencingMethod, controls, requestNum, exception );
                     }
                     else
                     {
                         logger.logSearchRequest( connection, searchBase, filter, searchControls,
-                            aliasesDereferencingMethod, controls, requestNum, le );
-                        logger.logSearchResultDone( connection, 0, requestNum, le );
+                            aliasesDereferencingMethod, controls, requestNum, exception );
+                        logger.logSearchResultDone( connection, 0, requestNum, exception );
                     }
                 }
             }
@@ -750,14 +749,12 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
                 }
 
-                LdapException le = toLdapException( exception );
-
                 for ( ILdapLogger logger : getLdapLoggers() )
                 {
-                    logger.logChangetypeModify( connection, dn, modifications, controls, le );
+                    logger.logChangetypeModify( connection, dn, modifications, controls, exception );
                 }
             }
         };
@@ -831,14 +828,12 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
                 }
 
-                LdapException le = toLdapException( exception );
-
                 for ( ILdapLogger logger : getLdapLoggers() )
                 {
-                    logger.logChangetypeModDn( connection, oldDn, newDn, deleteOldRdn, controls, le );
+                    logger.logChangetypeModDn( connection, oldDn, newDn, deleteOldRdn, controls, exception );
                 }
             }
         };
@@ -912,14 +907,12 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
                 }
 
-                LdapException le = toLdapException( exception );
-
                 for ( ILdapLogger logger : getLdapLoggers() )
                 {
-                    logger.logChangetypeAdd( connection, entry, controls, le );
+                    logger.logChangetypeAdd( connection, entry, controls, exception );
                 }
             }
         };
@@ -990,14 +983,12 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
                 }
 
-                LdapException le = toLdapException( exception );
-
                 for ( ILdapLogger logger : getLdapLoggers() )
                 {
-                    logger.logChangetypeDelete( connection, dn, controls, le );
+                    logger.logChangetypeDelete( connection, dn, controls, exception );
                 }
             }
         };
@@ -1049,12 +1040,9 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
                 }
                 catch ( Exception e )
                 {
-                    exception = e;
+                    exception = toStudioLdapException( e );
                 }
 
-                // TODO: logging?
-                LdapException le = toLdapException( exception );
-
                 for ( ILdapLogger logger : getLdapLoggers() )
                 {
                 }
@@ -1090,7 +1078,7 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
     abstract class InnerRunnable implements Runnable
     {
         protected StudioSearchResultEnumeration searchResultEnumeration = null;
-        protected Exception exception = null;
+        protected StudioLdapException exception = null;
         protected boolean canceled = false;
 
 
@@ -1357,7 +1345,7 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
     }
 
 
-    private LdapException toLdapException( Exception exception )
+    private StudioLdapException toStudioLdapException( Exception exception )
     {
         if ( exception == null )
         {
@@ -1365,11 +1353,11 @@ public class DirectoryApiConnectionWrapper implements ConnectionWrapper
         }
         else if ( exception instanceof LdapException )
         {
-            return ( LdapException ) exception;
+            return new StudioLdapException( ( LdapException ) exception );
         }
         else
         {
-            return new LdapException( exception.getMessage(), exception );
+            return new StudioLdapException( exception );
         }
     }
 
diff --git a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifModificationLogger.java b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifModificationLogger.java
index ee73cd0..c3076b6 100644
--- a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifModificationLogger.java
+++ b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifModificationLogger.java
@@ -39,26 +39,21 @@ import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 
-import javax.naming.directory.SearchControls;
-
 import org.apache.directory.api.ldap.model.entry.Attribute;
 import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.ldap.model.entry.Modification;
 import org.apache.directory.api.ldap.model.entry.Value;
-import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.Control;
-import org.apache.directory.api.ldap.model.message.Referral;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.ldap.model.name.Rdn;
 import org.apache.directory.api.util.Strings;
 import org.apache.directory.studio.connection.core.Connection;
-import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
 import org.apache.directory.studio.connection.core.ConnectionCoreConstants;
 import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
 import org.apache.directory.studio.connection.core.ConnectionManager;
 import org.apache.directory.studio.connection.core.Controls;
 import org.apache.directory.studio.connection.core.ILdapLogger;
-import org.apache.directory.studio.connection.core.ReferralsInfo;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.ldifparser.LdifFormatParameters;
 import org.apache.directory.studio.ldifparser.model.container.LdifChangeAddRecord;
 import org.apache.directory.studio.ldifparser.model.container.LdifChangeDeleteRecord;
@@ -207,7 +202,7 @@ public class LdifModificationLogger implements ILdapLogger
     }
 
 
-    private void log( String text, LdapException ex, Connection connection )
+    private void log( String text, StudioLdapException ex, Connection connection )
     {
         String id = connection.getId();
         if ( !loggers.containsKey( id ) )
@@ -261,7 +256,7 @@ public class LdifModificationLogger implements ILdapLogger
     /**
      * {@inheritDoc}
      */
-    public void logChangetypeAdd( Connection connection, final Entry entry, final Control[] controls, LdapException ex )
+    public void logChangetypeAdd( Connection connection, final Entry entry, final Control[] controls, StudioLdapException ex )
     {
         if ( !isModificationLogEnabled() )
         {
@@ -305,7 +300,7 @@ public class LdifModificationLogger implements ILdapLogger
      * {@inheritDoc}
      */
     public void logChangetypeDelete( Connection connection, final Dn dn, final Control[] controls,
-        LdapException ex )
+        StudioLdapException ex )
     {
         if ( !isModificationLogEnabled() )
         {
@@ -326,7 +321,7 @@ public class LdifModificationLogger implements ILdapLogger
      * {@inheritDoc}
      */
     public void logChangetypeModify( Connection connection, final Dn dn,
-        final Collection<Modification> modifications, final Control[] controls, LdapException ex )
+        final Collection<Modification> modifications, final Control[] controls, StudioLdapException ex )
     {
         if ( !isModificationLogEnabled() )
         {
@@ -388,7 +383,7 @@ public class LdifModificationLogger implements ILdapLogger
      * {@inheritDoc}
      */
     public void logChangetypeModDn( Connection connection, final Dn oldDn, final Dn newDn,
-        final boolean deleteOldRdn, final Control[] controls, LdapException ex )
+        final boolean deleteOldRdn, final Control[] controls, StudioLdapException ex )
     {
         if ( !isModificationLogEnabled() )
         {
@@ -412,36 +407,6 @@ public class LdifModificationLogger implements ILdapLogger
 
 
     /**
-     * {@inheritDoc}
-     */
-    public void logSearchRequest( Connection connection, String searchBase, String filter,
-        SearchControls searchControls, AliasDereferencingMethod aliasesDereferencingMethod,
-        Control[] controls, long requestNum, LdapException ex )
-    {
-        // don't log searches
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void logSearchResultReference( Connection connection, Referral referral,
-        ReferralsInfo referralsInfo, long requestNum, LdapException ex )
-    {
-        // don't log searches 
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void logSearchResultDone( Connection connection, long count, long requestNum, LdapException ex )
-    {
-        // don't log searches 
-    }
-
-
-    /**
      * Adds control lines to the record
      *
      * @param record the recored
diff --git a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifSearchLogger.java b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifSearchLogger.java
index d2772af..f49a201 100644
--- a/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifSearchLogger.java
+++ b/plugins/connection.core/src/main/java/org/apache/directory/studio/connection/core/io/api/LdifSearchLogger.java
@@ -41,12 +41,8 @@ import java.util.logging.Logger;
 import javax.naming.directory.SearchControls;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.entry.Modification;
-import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.message.Referral;
-import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.ldap.model.url.LdapUrl;
 import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
@@ -56,6 +52,7 @@ import org.apache.directory.studio.connection.core.ConnectionManager;
 import org.apache.directory.studio.connection.core.ILdapLogger;
 import org.apache.directory.studio.connection.core.ReferralsInfo;
 import org.apache.directory.studio.connection.core.Utils;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.ldifparser.LdifFormatParameters;
 import org.apache.directory.studio.ldifparser.model.lines.LdifCommentLine;
 import org.apache.directory.studio.ldifparser.model.lines.LdifLineBase;
@@ -191,7 +188,7 @@ public class LdifSearchLogger implements ILdapLogger
     }
 
 
-    private void log( String text, String type, LdapException ex, Connection connection )
+    private void log( String text, String type, StudioLdapException ex, Connection connection )
     {
         String id = connection.getId();
         if ( !loggers.containsKey( id ) )
@@ -245,48 +242,9 @@ public class LdifSearchLogger implements ILdapLogger
     /**
      * {@inheritDoc}
      */
-    public void logChangetypeAdd( Connection connection, final Entry entry, final Control[] controls, LdapException ex )
-    {
-        // don't log changetypes
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void logChangetypeDelete( Connection connection, final Dn dn, final Control[] controls,
-        LdapException ex )
-    {
-        // don't log changetypes
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void logChangetypeModify( Connection connection, final Dn dn,
-        final Collection<Modification> modifications, final Control[] controls, LdapException ex )
-    {
-        // don't log changetypes
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void logChangetypeModDn( Connection connection, final Dn oldDn, final Dn newDn,
-        final boolean deleteOldRdn, final Control[] controls, LdapException ex )
-    {
-        // don't log changetypes
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
     public void logSearchRequest( Connection connection, String searchBase, String filter,
         SearchControls searchControls, AliasDereferencingMethod aliasesDereferencingMethod,
-        Control[] controls, long requestNum, LdapException ex )
+        Control[] controls, long requestNum, StudioLdapException ex )
     {
         if ( !isSearchRequestLogEnabled() )
         {
@@ -349,7 +307,7 @@ public class LdifSearchLogger implements ILdapLogger
      * {@inheritDoc}
      */
     public void logSearchResultReference( Connection connection, Referral referral,
-        ReferralsInfo referralsInfo, long requestNum, LdapException ex )
+        ReferralsInfo referralsInfo, long requestNum, StudioLdapException ex )
     {
         if ( !isSearchResultEntryLogEnabled() )
         {
@@ -373,7 +331,7 @@ public class LdifSearchLogger implements ILdapLogger
     /**
      * {@inheritDoc}
      */
-    public void logSearchResultDone( Connection connection, long count, long requestNum, LdapException ex )
+    public void logSearchResultDone( Connection connection, long count, long requestNum, StudioLdapException ex )
     {
         if ( !isSearchRequestLogEnabled() )
         {
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesRunnable.java
index 50e9c06..ea87931 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/CopyEntriesRunnable.java
@@ -43,6 +43,7 @@ import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
 import org.apache.directory.studio.connection.core.Connection.ReferralHandlingMethod;
 import org.apache.directory.studio.connection.core.Controls;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.io.api.StudioSearchResultEnumeration;
 import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
 import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
@@ -317,7 +318,8 @@ public class CopyEntriesRunnable implements StudioConnectionBulkRunnableWithProg
 
                 while ( dummyMonitor.errorsReported() )
                 {
-                    if ( dialog != null && dummyMonitor.getException() instanceof LdapEntryAlreadyExistsException )
+                    if ( dialog != null
+                        && StudioLdapException.isEntryAlreadyExistsException( dummyMonitor.getException() ) )
                     {
                         // open dialog
                         dialog.setExistingEntry( targetBrowserConnection, newLdapDn );
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesRunnable.java
index b7bd125..a9b2935 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/DeleteEntriesRunnable.java
@@ -31,7 +31,6 @@ import java.util.Set;
 
 import javax.naming.directory.SearchControls;
 
-import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
@@ -40,6 +39,7 @@ import org.apache.directory.studio.connection.core.Controls;
 import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
 import org.apache.directory.studio.connection.core.Connection.ReferralHandlingMethod;
 import org.apache.directory.studio.connection.core.StudioControl;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.io.api.StudioSearchResultEnumeration;
 import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
 import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
@@ -276,7 +276,7 @@ public class DeleteEntriesRunnable implements StudioConnectionBulkRunnableWithPr
                 new String[]
                     { "" + numberOfDeletedEntries } ) ); //$NON-NLS-1$
         }
-        else if ( dummyMonitor.getException() instanceof LdapContextNotEmptyException )
+        else if ( StudioLdapException.isContextNotEmptyException( dummyMonitor.getException() ) )
         {
             // do not follow referrals or dereference aliases when deleting entries
             AliasDereferencingMethod aliasDereferencingMethod = AliasDereferencingMethod.NEVER;
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ImportLdifRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ImportLdifRunnable.java
index cf7b569..d0c301d 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ImportLdifRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ImportLdifRunnable.java
@@ -42,7 +42,6 @@ import org.apache.directory.api.ldap.model.entry.DefaultModification;
 import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.ldap.model.entry.Modification;
 import org.apache.directory.api.ldap.model.entry.ModificationOperation;
-import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
 import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
@@ -52,6 +51,7 @@ import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
 import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.ConnectionCoreConstants;
 import org.apache.directory.studio.connection.core.Controls;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
 import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
 import org.apache.directory.studio.ldapbrowser.core.events.BulkModificationEvent;
@@ -445,7 +445,7 @@ public class ImportLdifRunnable implements StudioConnectionBulkRunnableWithProgr
                 .createEntry( entry, getControls( record ), monitor, null );
 
             if ( monitor.errorsReported() && updateIfEntryExists
-                && monitor.getException() instanceof LdapEntryAlreadyExistsException )
+                && StudioLdapException.isEntryAlreadyExistsException( monitor.getException() ) )
             {
                 // creation failed with Error 68, now try to update the existing entry
                 monitor.reset();
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/MoveEntriesRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/MoveEntriesRunnable.java
index 3b18a26..f0a50e5 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/MoveEntriesRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/MoveEntriesRunnable.java
@@ -29,13 +29,13 @@ import java.util.Set;
 
 import javax.naming.directory.SearchControls;
 
-import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
 import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.Controls;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
 import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
 import org.apache.directory.studio.ldapbrowser.core.events.BulkModificationEvent;
@@ -181,7 +181,7 @@ public class MoveEntriesRunnable implements StudioConnectionBulkRunnableWithProg
             // do a simulated rename, if renaming of a non-leaf entry is not supported.
             if ( dummyMonitor.errorsReported() )
             {
-                if ( dialog != null && dummyMonitor.getException() instanceof LdapContextNotEmptyException )
+                if ( dialog != null && StudioLdapException.isContextNotEmptyException( dummyMonitor.getException() ) )
                 {
                     // open dialog
                     if ( numAdd == 0 )
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/RenameEntryRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/RenameEntryRunnable.java
index 7b718e5..f6c3bc6 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/RenameEntryRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/RenameEntryRunnable.java
@@ -28,7 +28,6 @@ import java.util.Set;
 
 import javax.naming.directory.SearchControls;
 
-import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.name.Dn;
@@ -36,6 +35,7 @@ import org.apache.directory.api.ldap.model.name.Rdn;
 import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
 import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.Controls;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
 import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
 import org.apache.directory.studio.ldapbrowser.core.events.EntryRenamedEvent;
@@ -166,7 +166,7 @@ public class RenameEntryRunnable implements StudioConnectionBulkRunnableWithProg
         // do a simulated rename, if renaming of a non-leaf entry is not supported.
         if ( dummyMonitor.errorsReported() && !monitor.isCanceled() )
         {
-            if ( dialog != null && dummyMonitor.getException() instanceof LdapContextNotEmptyException )
+            if ( dialog != null && StudioLdapException.isContextNotEmptyException( dummyMonitor.getException() ) )
             {
                 // open dialog
                 dialog.setEntryInfo( browserConnection, oldDn, newDn );
diff --git a/plugins/ldapbrowser.ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/actions/PasswordModifyExtendedOperationAction.java b/plugins/ldapbrowser.ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/actions/PasswordModifyExtendedOperationAction.java
index 4a9bc0b..1d31660 100644
--- a/plugins/ldapbrowser.ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/actions/PasswordModifyExtendedOperationAction.java
+++ b/plugins/ldapbrowser.ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/actions/PasswordModifyExtendedOperationAction.java
@@ -123,6 +123,7 @@ public class PasswordModifyExtendedOperationAction extends BrowserAction
     public boolean isEnabled()
     {
         return getConnectionAndEntry() != null
+            && getConnectionAndEntry().connection != null
             && getConnectionAndEntry().connection.getRootDSE()
                 .isExtensionSupported( PasswordModifyRequest.EXTENSION_OID );
     }
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java
index b17eb59..25209d9 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java
@@ -89,6 +89,7 @@ import org.apache.directory.studio.connection.core.ConnectionParameter.Authentic
 import org.apache.directory.studio.connection.core.ConnectionParameter.EncryptionMethod;
 import org.apache.directory.studio.connection.core.event.ConnectionEventRegistry;
 import org.apache.directory.studio.connection.core.io.ConnectionWrapper;
+import org.apache.directory.studio.connection.core.io.StudioLdapException;
 import org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper;
 import org.apache.directory.studio.connection.core.io.api.StudioSearchResult;
 import org.apache.directory.studio.connection.core.io.api.StudioSearchResultEnumeration;
@@ -119,7 +120,6 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
 
     protected ConnectionWrapper connectionWrapper;
 
-
     @Before
     public void setUp() throws Exception
     {
@@ -225,9 +225,11 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         connectionWrapper.connect( monitor );
         assertFalse( connectionWrapper.isConnected() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof InvalidConnectionException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
         assertNotNull( monitor.getException().getCause() );
-        assertTrue( monitor.getException().getCause() instanceof ConnectException );
+        assertTrue( monitor.getException().getCause() instanceof InvalidConnectionException );
+        assertNotNull( monitor.getException().getCause().getCause() );
+        assertTrue( monitor.getException().getCause().getCause() instanceof ConnectException );
 
         // unknown host
         monitor = getProgressMonitor();
@@ -238,9 +240,11 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         connectionWrapper.connect( monitor );
         assertFalse( connectionWrapper.isConnected() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof InvalidConnectionException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
         assertNotNull( monitor.getException().getCause() );
-        assertTrue( monitor.getException().getCause() instanceof UnresolvedAddressException );
+        assertTrue( monitor.getException().getCause() instanceof InvalidConnectionException );
+        assertNotNull( monitor.getException().getCause().getCause() );
+        assertTrue( monitor.getException().getCause().getCause() instanceof UnresolvedAddressException );
 
         // TODO: SSL, StartTLS
     }
@@ -293,8 +297,11 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         connectionWrapper.bind( monitor );
         assertFalse( connectionWrapper.isConnected() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof LdapAuthenticationException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
+        assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 49 - invalidCredentials]" ) );
         assertTrue( monitor.getException().getMessage().contains( "INVALID_CREDENTIALS" ) );
+        assertTrue( monitor.getException().getCause() instanceof LdapAuthenticationException );
+        assertTrue( monitor.getException().getCause().getMessage().contains( "INVALID_CREDENTIALS" ) );
 
         // simple auth with invalid principal and credential
         monitor = getProgressMonitor();
@@ -306,8 +313,11 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         connectionWrapper.bind( monitor );
         assertFalse( connectionWrapper.isConnected() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof LdapAuthenticationException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
+        assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 49 - invalidCredentials]" ) );
         assertTrue( monitor.getException().getMessage().contains( "INVALID_CREDENTIALS" ) );
+        assertTrue( monitor.getException().getCause() instanceof LdapAuthenticationException );
+        assertTrue( monitor.getException().getCause().getMessage().contains( "INVALID_CREDENTIALS" ) );
     }
 
 
@@ -555,7 +565,10 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertFalse( monitor.isCanceled() );
         assertTrue( monitor.errorsReported() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof LdapLoopDetectedException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
+        assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 54 - loopDetect]" ) );
+        assertTrue( monitor.getException().getMessage().contains( "already processed" ) );
+        assertTrue( monitor.getException().getCause() instanceof LdapLoopDetectedException );
     }
 
 
@@ -654,7 +667,10 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertFalse( monitor.isCanceled() );
         assertTrue( monitor.errorsReported() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof LdapLoopDetectedException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
+        assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 54 - loopDetect]" ) );
+        assertTrue( monitor.getException().getMessage().contains( "already processed" ) );
+        assertTrue( monitor.getException().getCause() instanceof LdapLoopDetectedException );
     }
 
 
@@ -738,7 +754,10 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertFalse( monitor.isCanceled() );
         assertTrue( monitor.errorsReported() );
         assertNotNull( monitor.getException() );
-        assertTrue( monitor.getException() instanceof LdapLoopDetectedException );
+        assertTrue( monitor.getException() instanceof StudioLdapException );
+        assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 54 - loopDetect]" ) );
+        assertTrue( monitor.getException().getMessage().contains( "already processed" ) );
+        assertTrue( monitor.getException().getCause() instanceof LdapLoopDetectedException );
         assertTrue( service.getAdminSession().exists( targetDn ) );
     }
 
@@ -945,24 +964,23 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertEquals( "uid=admin,ou=system", response.getDn().toString() );
     }
 
-
     /*
     @Ignore
     @Test
     public void testStartEndTransactionExtendedOperation() throws Exception
     {
         LdapApiService ldapApiService = LdapApiServiceFactory.getSingleton();
-
+    
         StartTransactionRequest request1 = ( StartTransactionRequest ) ldapApiService.getExtendedRequestFactories()
             .get( StartTransactionRequest.EXTENSION_OID ).newRequest();
         StudioProgressMonitor monitor1 = getProgressMonitor();
         StartTransactionResponse response1 = ( StartTransactionResponse ) getConnectionWrapper( monitor1 )
             .extended( request1, monitor1 );
-
+    
         assertEquals( ResultCodeEnum.SUCCESS, response1.getLdapResult().getResultCode() );
         assertFalse( monitor1.isCanceled() );
         assertFalse( monitor1.errorsReported() );
-
+    
         EndTransactionRequest request2 = ( EndTransactionRequest ) ldapApiService.getExtendedRequestFactories()
             .get( EndTransactionRequest.EXTENSION_OID ).newRequest();
         request2.setTransactionId( response1.getTransactionId() );
@@ -970,7 +988,7 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         StudioProgressMonitor monitor2 = getProgressMonitor();
         EndTransactionResponse response2 = ( EndTransactionResponse ) getConnectionWrapper( monitor2 )
             .extended( request2, monitor2 );
-
+    
         assertEquals( ResultCodeEnum.SUCCESS, response2.getLdapResult().getResultCode() );
         assertFalse( monitor2.isCanceled() );
         assertFalse( monitor2.errorsReported() );
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CopyEntryTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CopyEntryTest.java
index 1d4902f..a83bed1 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CopyEntryTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CopyEntryTest.java
@@ -230,7 +230,7 @@ public class CopyEntryTest extends AbstractLdapTestUnit
         dialog.clickOkButton();
 
         // verify in modification logs
-        modificationLogsViewBot.assertContainsError( "ENTRY_ALREADY_EXISTS", "dn: uid=user.1,ou=users,ou=system",
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 68 - entryAlreadyExists]", "dn: uid=user.1,ou=users,ou=system",
             "changetype: add", "uid: user.1" );
         modificationLogsViewBot.assertContainsOk( "dn: uid=user.1,ou=users,ou=system", "changetype: modify",
             "replace: uid" + LdifParserConstants.LINE_SEPARATOR + "uid: user.1" + LdifParserConstants.LINE_SEPARATOR
@@ -263,7 +263,7 @@ public class CopyEntryTest extends AbstractLdapTestUnit
         browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.renamed" );
 
         // verify in modification logs
-        modificationLogsViewBot.assertContainsError( "ENTRY_ALREADY_EXISTS", "dn: uid=user.1,ou=users,ou=system",
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 68 - entryAlreadyExists]", "dn: uid=user.1,ou=users,ou=system",
             "changetype: add", "uid: user.1" );
         modificationLogsViewBot.assertContainsOk( "dn: uid=user.renamed,ou=users,ou=system", "changetype: add",
             "uid: user.renamed" );
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ErrorHandlingTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ErrorHandlingTest.java
new file mode 100644
index 0000000..0f3dd30
--- /dev/null
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ErrorHandlingTest.java
@@ -0,0 +1,216 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+
+package org.apache.directory.studio.test.integration.ui;
+
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.ldap.handlers.extended.PwdModifyHandler;
+import org.apache.directory.studio.test.integration.ui.bots.BrowserViewBot;
+import org.apache.directory.studio.test.integration.ui.bots.ConnectionsViewBot;
+import org.apache.directory.studio.test.integration.ui.bots.DeleteDialogBot;
+import org.apache.directory.studio.test.integration.ui.bots.EntryEditorBot;
+import org.apache.directory.studio.test.integration.ui.bots.ErrorDialogBot;
+import org.apache.directory.studio.test.integration.ui.bots.ModificationLogsViewBot;
+import org.apache.directory.studio.test.integration.ui.bots.StudioBot;
+import org.apache.directory.studio.test.integration.ui.bots.utils.Assertions;
+import org.apache.directory.studio.test.integration.ui.bots.utils.FrameworkRunnerWithScreenshotCaptureListener;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests error handling
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+@RunWith(FrameworkRunnerWithScreenshotCaptureListener.class)
+@CreateLdapServer(transports =
+    { @CreateTransport(protocol = "LDAP") }, extendedOpHandlers =
+    { PwdModifyHandler.class })
+@ApplyLdifFiles(clazz = ErrorHandlingTest.class, value = "org/apache/directory/studio/test/integration/ui/BrowserTest.ldif")
+public class ErrorHandlingTest extends AbstractLdapTestUnit
+{
+    private StudioBot studioBot;
+    private ConnectionsViewBot connectionsViewBot;
+    private BrowserViewBot browserViewBot;
+    private ModificationLogsViewBot modificationLogsViewBot;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        studioBot = new StudioBot();
+        studioBot.resetLdapPerspective();
+        connectionsViewBot = studioBot.getConnectionView();
+        connectionsViewBot.createTestConnection( "BrowserTest", ldapServer.getPort() );
+        browserViewBot = studioBot.getBrowserView();
+        modificationLogsViewBot = studioBot.getModificationLogsViewBot();
+    }
+
+
+    @After
+    public void tearDown() throws Exception
+    {
+        connectionsViewBot.deleteTestConnections();
+        Assertions.genericTearDownAssertions();
+    }
+
+
+    @Test
+    public void testDeleteObjectClassTopSchemaEntryShouldFail() throws Exception
+    {
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=schema", "cn=system", "ou=objectClasses", "m-oid=2.5.6.0" );
+        browserViewBot.expandEntry( "DIT", "Root DSE", "ou=schema", "cn=system", "ou=objectClasses", "m-oid=2.5.6.0" );
+        DeleteDialogBot deleteDialog = browserViewBot.openDeleteDialog();
+        ErrorDialogBot errorDialog = deleteDialog.clickOkButtonExpectingErrorDialog();
+
+        // verify message in error dialog
+        assertThat( errorDialog.getErrorDetails(), containsString( "[LDAP result code 53 - unwillingToPerform]" ) );
+        errorDialog.clickOkButton();
+
+        // verify in modification logs
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 53 - unwillingToPerform]",
+            "dn: m-oid=2.5.6.0,ou=objectClasses,cn=system,ou=schema", "changetype: delete" );
+    }
+
+
+    @Test
+    public void testDeleteObjectClassAttributeShouldFail() throws Exception
+    {
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( "uid=user.1,ou=users,ou=system" );
+        entryEditorBot.activate();
+        ErrorDialogBot errorDialog = entryEditorBot.deleteValueExpectingErrorDialog( "objectclass",
+            "inetOrgPerson (structural)" );
+
+        // verify message in error dialog
+        assertThat( errorDialog.getErrorMessage(), containsString( "[LDAP result code 65 - objectClassViolation]" ) );
+        errorDialog.clickOkButton();
+
+        // verify in modification logs
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 65 - objectClassViolation]",
+            "dn: uid=user.1,ou=users,ou=system", "changetype: modify" );
+    }
+
+
+    @Test
+    public void testDeleteRdnAttributeShouldFail() throws Exception
+    {
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( "uid=user.1,ou=users,ou=system" );
+        entryEditorBot.activate();
+        ErrorDialogBot errorDialog = entryEditorBot.deleteValueExpectingErrorDialog( "uid", "user.1" );
+
+        // verify message in error dialog
+        assertThat( errorDialog.getErrorMessage(), containsString( "[LDAP result code 67 - notAllowedOnRDN]" ) );
+        errorDialog.clickOkButton();
+
+        // verify in modification logs
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 67 - notAllowedOnRDN]",
+            "dn: uid=user.1,ou=users,ou=system", "changetype: modify", "delete: uid" );
+    }
+
+
+    @Test
+    public void testDeleteMustAttributeShouldFail() throws Exception
+    {
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( "uid=user.1,ou=users,ou=system" );
+        entryEditorBot.activate();
+        ErrorDialogBot errorDialog = entryEditorBot.deleteValueExpectingErrorDialog( "sn", "Amar" );
+
+        // verify message in error dialog
+        assertThat( errorDialog.getErrorMessage(), containsString( "[LDAP result code 65 - objectClassViolation]" ) );
+        errorDialog.clickOkButton();
+
+        // verify in modification logs
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 65 - objectClassViolation]",
+            "dn: uid=user.1,ou=users,ou=system", "changetype: modify", "delete: sn" );
+    }
+
+
+    @Test
+    public void testDeleteOperationalAttributeShouldFail() throws Exception
+    {
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( "uid=user.1,ou=users,ou=system" );
+        entryEditorBot.activate();
+        entryEditorBot.fetchOperationalAttributes();
+        SWTUtils.sleep( 1000 );
+        entryEditorBot.activate();
+        ErrorDialogBot errorDialog = entryEditorBot.deleteValueExpectingErrorDialog( "nbChildren", "0" );
+
+        // verify message in error dialog
+        assertThat( errorDialog.getErrorMessage(),
+            containsString( "[LDAP result code 50 - insufficientAccessRights]" ) );
+        errorDialog.clickOkButton();
+
+        // verify in modification logs
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 50 - insufficientAccessRights]",
+            "dn: uid=user.1,ou=users,ou=system", "changetype: modify", "delete: nbChildren" );
+    }
+
+
+    @Test
+    public void testModifyInvalidSyntaxShouldFail() throws Exception
+    {
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( "uid=user.1,ou=users,ou=system" );
+        entryEditorBot.activate();
+        entryEditorBot.editValue( "telephonenumber", "976-893-3312" );
+        ErrorDialogBot errorDialog = entryEditorBot.typeValueAndFinishAndExpectErrorDialog( "Invalid phone number" );
+
+        // verify message in error dialog
+        assertThat( errorDialog.getErrorMessage(),
+            containsString( "[LDAP result code 21 - invalidAttributeSyntax]" ) );
+        errorDialog.clickOkButton();
+
+        // verify in modification logs
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 21 - invalidAttributeSyntax]",
+            "dn: uid=user.1,ou=users,ou=system", "changetype: modify", "replace: telephonenumber",
+            "telephonenumber: Invalid phone number" );
+    }
+
+
+    @Ignore("Until DIRSERVER-2308 is fixed")
+    @Test
+    public void testRenameAlreadyExistingEntry() throws Exception
+    {
+    }
+
+
+    @Ignore("Until DIRSERVER-2308 is fixed")
+    @Test
+    public void testMoveAlreadyExistingEntry() throws Exception
+    {
+    }
+
+}
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ExtendedOperationsTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ExtendedOperationsTest.java
index ea9e09b..0bc2f68 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ExtendedOperationsTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ExtendedOperationsTest.java
@@ -37,6 +37,7 @@ import org.apache.directory.studio.test.integration.ui.bots.BrowserViewBot;
 import org.apache.directory.studio.test.integration.ui.bots.ConnectionsViewBot;
 import org.apache.directory.studio.test.integration.ui.bots.EntryEditorBot;
 import org.apache.directory.studio.test.integration.ui.bots.ErrorDialogBot;
+import org.apache.directory.studio.test.integration.ui.bots.ModificationLogsViewBot;
 import org.apache.directory.studio.test.integration.ui.bots.PasswordEditorDialogBot;
 import org.apache.directory.studio.test.integration.ui.bots.PasswordModifyExtendedOperationDialogBot;
 import org.apache.directory.studio.test.integration.ui.bots.StudioBot;
@@ -64,6 +65,7 @@ public class ExtendedOperationsTest extends AbstractLdapTestUnit
     private StudioBot studioBot;
     private ConnectionsViewBot connectionsViewBot;
     private BrowserViewBot browserViewBot;
+    private ModificationLogsViewBot modificationLogsViewBot;
 
 
     @Before
@@ -74,6 +76,7 @@ public class ExtendedOperationsTest extends AbstractLdapTestUnit
         connectionsViewBot = studioBot.getConnectionView();
         connectionsViewBot.createTestConnection( "BrowserTest", ldapServer.getPort() );
         browserViewBot = studioBot.getBrowserView();
+        modificationLogsViewBot = studioBot.getModificationLogsViewBot();
     }
 
 
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java
index a395207..4cb5ee8 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java
@@ -21,17 +21,23 @@
 package org.apache.directory.studio.test.integration.ui;
 
 
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.UUID;
 import java.util.function.Supplier;
 
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
 import org.apache.directory.api.ldap.model.message.SearchScope;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.util.FileUtils;
@@ -55,6 +61,7 @@ import org.apache.directory.studio.test.integration.ui.bots.DeleteDialogBot;
 import org.apache.directory.studio.test.integration.ui.bots.EntryEditorBot;
 import org.apache.directory.studio.test.integration.ui.bots.ExportWizardBot;
 import org.apache.directory.studio.test.integration.ui.bots.ImportWizardBot;
+import org.apache.directory.studio.test.integration.ui.bots.ModificationLogsViewBot;
 import org.apache.directory.studio.test.integration.ui.bots.SearchLogsViewBot;
 import org.apache.directory.studio.test.integration.ui.bots.StudioBot;
 import org.apache.directory.studio.test.integration.ui.bots.utils.Assertions;
@@ -85,7 +92,7 @@ public class ImportExportTest extends AbstractLdapTestUnit
     private BrowserViewBot browserViewBot;
     private Connection connection;
     private SearchLogsViewBot searchLogsViewBot;
-
+    private ModificationLogsViewBot modificationLogsViewBot;
 
     @Before
     public void setUp() throws Exception
@@ -96,6 +103,7 @@ public class ImportExportTest extends AbstractLdapTestUnit
         connection = connectionsViewBot.createTestConnection( "ImportExportTest", ldapServer.getPort() );
         browserViewBot = studioBot.getBrowserView();
         searchLogsViewBot = studioBot.getSearchLogsViewBot();
+        modificationLogsViewBot = studioBot.getModificationLogsViewBot();
     }
 
 
@@ -276,9 +284,12 @@ public class ImportExportTest extends AbstractLdapTestUnit
         DeleteDialogBot dialogBot = browserViewBot.openDeleteDialog();
         assertTrue( dialogBot.isVisible() );
         dialogBot.clickOkButton();
-        waitAndAssert(false, () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=alias" ));
-        waitAndAssert(false, () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=referral" ));
-        waitAndAssert(false, () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=subentry" ));
+        waitAndAssert( false,
+            () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=alias" ) );
+        waitAndAssert( false,
+            () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=referral" ) );
+        waitAndAssert( false,
+            () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=subentry" ) );
 
         // import LDIFs
         ImportWizardBot importWizardBot = browserViewBot.openImportLdifWizard();
@@ -364,9 +375,12 @@ public class ImportExportTest extends AbstractLdapTestUnit
         DeleteDialogBot dialogBot = browserViewBot.openDeleteDialog();
         assertTrue( dialogBot.isVisible() );
         dialogBot.clickOkButton();
-        waitAndAssert(false, () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=alias" ));
-        waitAndAssert(false, () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=referral" ));
-        waitAndAssert(false, () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=subentry" ));
+        waitAndAssert( false,
+            () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=alias" ) );
+        waitAndAssert( false,
+            () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=referral" ) );
+        waitAndAssert( false,
+            () -> browserViewBot.existsEntry( "DIT", "Root DSE", "ou=system", "ou=special", "cn=subentry" ) );
 
         // import DSML
         ImportWizardBot importWizardBot = browserViewBot.openImportDsmlWizard();
@@ -485,20 +499,15 @@ public class ImportExportTest extends AbstractLdapTestUnit
     @Test
     public void testImportDoesNotUpdateUI() throws Exception
     {
-        URL url = Platform.getInstanceLocation().getURL();
-        String destFile = url.getFile() + "ImportDontUpdateUiTest.ldif";
-        InputStream is = getClass().getResourceAsStream( "ImportExportTest_ImportDontUpdateUI.ldif" );
-        String ldifContent = IOUtils.toString( is, StandardCharsets.UTF_8 );
-        FileUtils.writeStringToFile( new File( destFile ), ldifContent, StandardCharsets.UTF_8, false );
-
         browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users" );
         browserViewBot.expandEntry( "DIT", "Root DSE", "ou=system", "ou=users" );
 
         long fireCount0 = EventRegistry.getFireCount();
 
         // import the LDIF
+        String file = prepareInputFile( "ImportExportTest_ImportDontUpdateUI.ldif" );
         ImportWizardBot importWizardBot = browserViewBot.openImportLdifWizard();
-        importWizardBot.typeFile( destFile );
+        importWizardBot.typeFile( file );
         importWizardBot.clickFinishButton();
         browserViewBot.waitForEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=User.1" );
         browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=User.1" );
@@ -554,15 +563,10 @@ public class ImportExportTest extends AbstractLdapTestUnit
     @Test
     public void testDIRSTUDIO_1160() throws Exception
     {
-        URL url = Platform.getInstanceLocation().getURL();
-        String destFile = url.getFile() + "DIRSTUDIO-1160.ldif";
-        InputStream is = getClass().getResourceAsStream( "DIRSTUDIO-1160.ldif" );
-        String ldifContent = IOUtils.toString( is, StandardCharsets.UTF_8 );
-        FileUtils.writeStringToFile( new File( destFile ), ldifContent, StandardCharsets.UTF_8, false );
-
         // import the LDIF
+        String file = prepareInputFile( "DIRSTUDIO-1160.ldif" );
         ImportWizardBot importWizardBot = browserViewBot.openImportLdifWizard();
-        importWizardBot.typeFile( destFile );
+        importWizardBot.typeFile( file );
         importWizardBot.clickFinishButton();
 
         browserViewBot.waitForEntry( "DIT", "Root DSE", "ou=system", "ou=users", "cn=U0034692" );
@@ -585,15 +589,10 @@ public class ImportExportTest extends AbstractLdapTestUnit
     @Test
     public void testLdifModification() throws Exception
     {
-        URL url = Platform.getInstanceLocation().getURL();
-        String destFile = url.getFile() + "ImportExportTest_Modifications.ldif";
-        InputStream is = getClass().getResourceAsStream( "ImportExportTest_Modifications.ldif" );
-        String ldifContent = IOUtils.toString( is, StandardCharsets.UTF_8 );
-        FileUtils.writeStringToFile( new File( destFile ), ldifContent, StandardCharsets.UTF_8, false );
-
         // import the LDIF
+        String file = prepareInputFile( "ImportExportTest_Modifications.ldif" );
         ImportWizardBot importWizardBot = browserViewBot.openImportLdifWizard();
-        importWizardBot.typeFile( destFile );
+        importWizardBot.typeFile( file );
         importWizardBot.clickFinishButton();
 
         browserViewBot.waitForEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=user.1" );
@@ -615,4 +614,82 @@ public class ImportExportTest extends AbstractLdapTestUnit
         assertFalse( entryEditorBot.getAttributeValues().contains( "uid: user.3" ) );
     }
 
+
+    @Test
+    public void testImportUpdateExistingEntriesFalse() throws Exception
+    {
+        String dn = "uid=User.1,ou=users,ou=system";
+        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), dn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: User.1" ) );
+
+        // import the LDIF
+        String file = prepareInputFile( "ImportExportTest_ImportDontUpdateUI.ldif" );
+        ImportWizardBot importWizardBot = browserViewBot.openImportLdifWizard();
+        importWizardBot.typeFile( file );
+        importWizardBot.setUpdateExistingEntries( false );
+        importWizardBot.setContinueOnError( false );
+        importWizardBot.clickFinishButton();
+
+        // check entry was not updated
+        browserViewBot.waitForEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=User.1" );
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=User.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( dn );
+        entryEditorBot.activate();
+        assertTrue( entryEditorBot.getAttributeValues().contains( "sn: X" ) );
+        assertFalse( entryEditorBot.getAttributeValues().contains( "sn: Amar" ) );
+        assertFalse( entryEditorBot.getAttributeValues().contains( "roomNumber: 1388" ) );
+
+        // check error in modifications logs view
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 68 - entryAlreadyExists]",
+            "dn: uid=User.1,ou=users,ou=system", "changetype: add" );
+        // check error in LDIF log file
+        String logContent = FileUtils.readFileToString( new File( file + ".log" ), StandardCharsets.UTF_8 );
+        assertThat( logContent, containsString( "[LDAP result code 68 - entryAlreadyExists]" ) );
+    }
+
+
+    @Test
+    public void testImportUpdateExistingEntriesTrue() throws Exception
+    {
+        String dn = "uid=User.1,ou=users,ou=system";
+        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), dn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: User.1" ) );
+
+        // import the LDIF
+        String file = prepareInputFile( "ImportExportTest_ImportDontUpdateUI.ldif" );
+        ImportWizardBot importWizardBot = browserViewBot.openImportLdifWizard();
+        importWizardBot.typeFile( file );
+        importWizardBot.setUpdateExistingEntries( true );
+        importWizardBot.setContinueOnError( false );
+        importWizardBot.clickFinishButton();
+
+        // check entry was updated
+        browserViewBot.waitForEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=User.1" );
+        browserViewBot.selectEntry( "DIT", "Root DSE", "ou=system", "ou=users", "uid=User.1" );
+        EntryEditorBot entryEditorBot = studioBot.getEntryEditorBot( dn );
+        entryEditorBot.activate();
+        assertFalse( entryEditorBot.getAttributeValues().contains( "sn: X" ) );
+        assertTrue( entryEditorBot.getAttributeValues().contains( "sn: Amar" ) );
+        assertTrue( entryEditorBot.getAttributeValues().contains( "roomNumber: 1388" ) );
+
+        // check error and update in modifications logs view
+        modificationLogsViewBot.assertContainsError( "[LDAP result code 68 - entryAlreadyExists]",
+            "dn: uid=User.1,ou=users,ou=system", "changetype: add" );
+        modificationLogsViewBot.assertContainsOk( "dn: uid=User.1,ou=users,ou=system", "changetype: modify" );
+        // check no error but update in LDIF log file
+        String logContent = FileUtils.readFileToString( new File( file + ".log" ), StandardCharsets.UTF_8 );
+        assertThat( logContent, not( containsString( "[LDAP result code 68 - entryAlreadyExists]" ) ) );
+    }
+
+
+    private String prepareInputFile( String inputFileName ) throws IOException
+    {
+        URL url = Platform.getInstanceLocation().getURL();
+        String destFile = url.getFile() + UUID.randomUUID().toString();
+        InputStream is = getClass().getResourceAsStream( inputFileName );
+        String ldifContent = IOUtils.toString( is, StandardCharsets.UTF_8 );
+        FileUtils.writeStringToFile( new File( destFile ), ldifContent, StandardCharsets.UTF_8, false );
+        return destFile;
+    }
+
 }
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java
index 4cc19a9..cb31bee 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java
@@ -498,7 +498,7 @@ public class NewConnectionWizardTest extends AbstractLdapTestUnit
         // click "Check Network Parameter" button
         String result = wizardBot.clickCheckAuthenticationButton();
         assertNotNull( "Expected Error", result );
-        assertTrue( "'INVALID_CREDENTIALS' message must occur in error message", result.contains( "INVALID_CREDENTIALS" ) );
+        assertThat( result, containsString( "[LDAP result code 49 - invalidCredentials]" ) );
 
         wizardBot.clickCancelButton();
     }
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/BotUtils.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/BotUtils.java
index b4cf48f..600b3e0 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/BotUtils.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/BotUtils.java
@@ -24,7 +24,6 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.swtbot.swt.finder.SWTBot;
 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/CertificateTrustDialogBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/CertificateTrustDialogBot.java
index 866297f..d472e8c 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/CertificateTrustDialogBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/CertificateTrustDialogBot.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel;
-import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
 
 
 public class CertificateTrustDialogBot extends DialogBot
@@ -123,18 +122,4 @@ public class CertificateTrustDialogBot extends DialogBot
         bot.radio( "Always trust this certificate." ).click();
     }
 
-
-    public ErrorDialogBot clickOkButtonExpectingErrorDialog()
-    {
-        SWTBotShell shell = BotUtils.shell( new Runnable()
-        {
-            public void run()
-            {
-                clickOkButton();
-            }
-        }, "Error", "Problem Occurred" );
-        String shellText = shell.getText();
-
-        return new ErrorDialogBot(shellText);
-    }
 }
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/DialogBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/DialogBot.java
index 029b5aa..ef80d66 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/DialogBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/DialogBot.java
@@ -72,6 +72,13 @@ public abstract class DialogBot
     }
 
 
+    public ErrorDialogBot clickOkButtonExpectingErrorDialog()
+    {
+        String shellText = BotUtils.shell( () -> clickButton( "OK" ), "Error", "Problem Occurred" ).getText();
+        return new ErrorDialogBot( shellText );
+    }
+
+
     public void clickCancelButton()
     {
         clickButton( "Cancel" );
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorBot.java
index 1ba2852..64ca0d3 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorBot.java
@@ -83,6 +83,12 @@ public class EntryEditorBot
     }
 
 
+    public ErrorDialogBot typeValueAndFinishAndExpectErrorDialog( String value )
+    {
+        return editorBot.typeValueAndFinishAndExpectErrorDialog( value );
+    }
+
+
     public void addValue( String attributeType )
     {
         editorBot.addValue( attributeType );
@@ -131,6 +137,12 @@ public class EntryEditorBot
     }
 
 
+    public ErrorDialogBot deleteValueExpectingErrorDialog( String attributeType, String value )
+    {
+        return editorBot.deleteValueExpectingErrorDialog( attributeType, value );
+    }
+
+
     public void copyValue( String attributeType, String value )
     {
         editorBot.copyValue( attributeType, value );
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorWidgetBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorWidgetBot.java
index ad08d6d..29c7da0 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorWidgetBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/EntryEditorWidgetBot.java
@@ -94,6 +94,13 @@ class EntryEditorWidgetBot
     }
 
 
+    public ErrorDialogBot typeValueAndFinishAndExpectErrorDialog( String value )
+    {
+        String shellText = BotUtils.shell( () -> typeValueAndFinish( value, false ), "Error" ).getText();
+        return new ErrorDialogBot( shellText );
+    }
+
+
     void cancelEditValue()
     {
         SWTBotTree tree = bot.tree( 0 );
@@ -213,6 +220,16 @@ class EntryEditorWidgetBot
     }
 
 
+    public ErrorDialogBot deleteValueExpectingErrorDialog( String attributeType, String value )
+    {
+        SWTBotTreeItem treeItem = getTreeItem( attributeType, value );
+        treeItem.select();
+        ContextMenuHelper.clickContextMenu( bot.tree(), "Delete Value" );
+        DeleteDialogBot deleteDialogBot = new DeleteDialogBot( DeleteDialogBot.DELETE_VALUE_TITLE );
+        return deleteDialogBot.clickOkButtonExpectingErrorDialog();
+    }
+
+
     public void copyValue( String attributeType, String value )
     {
 
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ErrorDialogBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ErrorDialogBot.java
index 6661424..3933ac9 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ErrorDialogBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ErrorDialogBot.java
@@ -40,4 +40,10 @@ public class ErrorDialogBot extends DialogBot
         return bot.label( 1 ).getText();
     }
 
+
+    public String getErrorDetails()
+    {
+        return bot.label( 2 ).getText();
+    }
+
 }
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ImportWizardBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ImportWizardBot.java
index f985963..6f4bc61 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ImportWizardBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ImportWizardBot.java
@@ -30,7 +30,6 @@ public class ImportWizardBot extends WizardBot
     public static final String IMPORT_DSML_TITLE = "DSML Import";
     private String title;
 
-
     public ImportWizardBot()
     {
         this( "Import" );
@@ -71,4 +70,30 @@ public class ImportWizardBot extends WizardBot
         }
     }
 
+
+    public void setContinueOnError( boolean enabled )
+    {
+        if ( enabled )
+        {
+            bot.checkBox( "Continue on error" ).select();
+        }
+        else
+        {
+            bot.checkBox( "Continue on error" ).deselect();
+        }
+    }
+
+
+    public void setUpdateExistingEntries( boolean enabled )
+    {
+        if ( enabled )
+        {
+            bot.checkBox( "Update existing entries" ).select();
+        }
+        else
+        {
+            bot.checkBox( "Update existing entries" ).deselect();
+        }
+    }
+
 }
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/PasswordModifyExtendedOperationDialogBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/PasswordModifyExtendedOperationDialogBot.java
index b57e621..7590a3d 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/PasswordModifyExtendedOperationDialogBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/PasswordModifyExtendedOperationDialogBot.java
@@ -20,9 +20,6 @@
 package org.apache.directory.studio.test.integration.ui.bots;
 
 
-import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
-
-
 public class PasswordModifyExtendedOperationDialogBot extends DialogBot
 {
     public PasswordModifyExtendedOperationDialogBot()
@@ -123,19 +120,4 @@ public class PasswordModifyExtendedOperationDialogBot extends DialogBot
         }
     }
 
-
-    public ErrorDialogBot clickOkButtonExpectingErrorDialog()
-    {
-        SWTBotShell shell = BotUtils.shell( new Runnable()
-        {
-            public void run()
-            {
-                clickOkButton();
-            }
-        }, "Error" );
-        String shellText = shell.getText();
-
-        return new ErrorDialogBot( shellText );
-    }
-
 }