From a374d387a2c57bc22b34d91a841283c905fce902 Mon Sep 17 00:00:00 2001
From: Raphael Girardot <raphael.girardot@synchrotron-soleil.fr>
Date: Thu, 6 Aug 2020 08:04:02 +0000
Subject: [PATCH] - Prefer using constants to new strings - Prefer using
 String.isEmpty() to String comparison with "" - Prefer using
 DeviceProxyFactory.get(device_name) to new DeviceProxy(device_name)- Respect
 SOLEIL convention - Prefer using "for each" to "for int in list size" - Avoid
 return inside if - Don't select context if loading failed - TANGOARCH-629:
 Ensure "register" button is deactivated when context is loaded + register a
 new context if attribute list changed

---
 .../actions/context/AbsRefreshAction.java     |  30 +--
 .../actions/context/LoadContextAction.java    |   6 +-
 .../context/RegisterContextAction.java        |  12 +-
 .../context/SaveSelectedContextAction.java    |  19 +-
 .../actions/context/SearchContextsAction.java |  10 +-
 .../ValidateAlternateSelectionAction.java     |   3 +-
 .../listeners/ContextTableListener.java       |  92 +++++----
 .../listeners/ContextTextListener.java        |  86 +++-----
 .../listeners/SelectedContextListener.java    |  20 +-
 .../snapshot/AddSnapshotToCompareAction.java  |   7 +-
 .../snapshot/detail/SnapshotCompareTable.java |  11 +-
 .../containers/context/ContextDataPanel.java  | 193 +++++++++---------
 .../SnapshotDetailTabbedPaneContent.java      |  10 +-
 .../dialogs/options/OptionsSnapshotTab.java   | 100 +++------
 .../soleil/bensikin/data/context/Context.java | 158 ++++++--------
 .../bensikin/data/context/ContextData.java    |  23 ++-
 .../data/snapshot/SnapshotAttributeValue.java |  18 +-
 .../bensikin/impl/TangoManagerImpl.java       |   5 +-
 .../bensikin/models/AttributesTreeModel.java  | 139 ++++++-------
 .../models/ContextAttributesTreeModel.java    |  69 ++++---
 ...ssibleAttributesTreeSelectionListener.java |  38 +---
 .../bensikin/options/sub/SnapshotOptions.java |  30 +--
 .../soleil/bensikin/xml/BensikinXMLLine.java  |   2 +-
 23 files changed, 498 insertions(+), 583 deletions(-)

diff --git a/src/main/java/fr/soleil/bensikin/actions/context/AbsRefreshAction.java b/src/main/java/fr/soleil/bensikin/actions/context/AbsRefreshAction.java
index be4f323..b08a143 100644
--- a/src/main/java/fr/soleil/bensikin/actions/context/AbsRefreshAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/context/AbsRefreshAction.java
@@ -55,7 +55,7 @@ import fr.soleil.bensikin.tools.Messages;
 
 public abstract class AbsRefreshAction extends BensikinAction {
 
-    private static final long serialVersionUID = -2191681757850094634L;
+    private static final long serialVersionUID = 7230693529506010508L;
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AbsRefreshAction.class);
 
@@ -67,7 +67,7 @@ public abstract class AbsRefreshAction extends BensikinAction {
      */
     private void verifyFields(final SnapshotFilterPanel source) throws FieldFormatException {
         final String id = source.getTextId().getText();
-        if (id != null && !id.trim().equals("")) {
+        if (id != null && !id.trim().isEmpty()) {
             try {
                 // int i =
                 Integer.parseInt(id);
@@ -77,12 +77,12 @@ public abstract class AbsRefreshAction extends BensikinAction {
         }
 
         final String startTime = source.getTextStartTime().getText();
-        if (startTime != null && !startTime.trim().equals("")) {
+        if (startTime != null && !startTime.trim().isEmpty()) {
             DateUtils.stringToTimestamp(startTime, true, FieldFormatException.FILTER_SNAPSHOTS_START_TIME);
         }
 
         final String endTime = source.getTextEndTime().getText();
-        if (endTime != null && !endTime.trim().equals("")) {
+        if (endTime != null && !endTime.trim().isEmpty()) {
             DateUtils.stringToTimestamp(endTime, true, FieldFormatException.FILTER_SNAPSHOTS_START_TIME);
         }
 
@@ -105,7 +105,7 @@ public abstract class AbsRefreshAction extends BensikinAction {
         String _text = text;
         // Date Formating
         if (SnapConst.TAB_SNAP[2].equals(id_field_key2)) {
-            if (!"".equals(_text)) {
+            if (!_text.isEmpty()) {
                 try {
                     final long milli = DateUtil.stringToMilli(_text);
                     final String date = Tools.formatDate(milli);
@@ -121,7 +121,7 @@ public abstract class AbsRefreshAction extends BensikinAction {
             isACriterion = false;
         }
 
-        if (_text == null || _text.trim().equals("")) {
+        if (_text == null || _text.trim().isEmpty()) {
             isACriterion = false;
         }
 
@@ -149,17 +149,17 @@ public abstract class AbsRefreshAction extends BensikinAction {
             final String title = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR");
 
             switch (e.getCode()) {
-            case FieldFormatException.FILTER_SNAPSHOTS_ID:
-                msg = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR_ID");
-                break;
+                case FieldFormatException.FILTER_SNAPSHOTS_ID:
+                    msg = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR_ID");
+                    break;
 
-            case FieldFormatException.FILTER_SNAPSHOTS_START_TIME:
-                msg = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR_START_TIME");
-                break;
+                case FieldFormatException.FILTER_SNAPSHOTS_START_TIME:
+                    msg = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR_START_TIME");
+                    break;
 
-            case FieldFormatException.FILTER_SNAPSHOTS_END_TIME:
-                msg = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR_END_TIME");
-                break;
+                case FieldFormatException.FILTER_SNAPSHOTS_END_TIME:
+                    msg = Messages.getLogMessage("FILTER_SNAPSHOTS_FIELD_ERROR_END_TIME");
+                    break;
             }
 
             JOptionPane.showMessageDialog(BensikinFrame.getInstance(), msg, title, JOptionPane.ERROR_MESSAGE);
diff --git a/src/main/java/fr/soleil/bensikin/actions/context/LoadContextAction.java b/src/main/java/fr/soleil/bensikin/actions/context/LoadContextAction.java
index 911ccba..4a93df1 100644
--- a/src/main/java/fr/soleil/bensikin/actions/context/LoadContextAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/context/LoadContextAction.java
@@ -108,7 +108,9 @@ public class LoadContextAction extends BensikinAction {
     public void actionPerformed(final ActionEvent actionEvent) {
         final IContextManager manager = ContextManagerFactory.getCurrentImpl();
         boolean load = true;
-        if (!isDefault) {
+        if (isDefault) {
+            manager.setNonDefaultSaveLocation(null);
+        } else {
             // open file chooser
             final JFileChooser chooser = new JFileChooser();
             final String location = manager.getSaveLocation();
@@ -142,8 +144,6 @@ public class LoadContextAction extends BensikinAction {
             } else {
                 load = false;
             }
-        } else {
-            manager.setNonDefaultSaveLocation(null);
         }
         if (load) {
             try {
diff --git a/src/main/java/fr/soleil/bensikin/actions/context/RegisterContextAction.java b/src/main/java/fr/soleil/bensikin/actions/context/RegisterContextAction.java
index 108567d..9039a96 100644
--- a/src/main/java/fr/soleil/bensikin/actions/context/RegisterContextAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/context/RegisterContextAction.java
@@ -68,6 +68,7 @@ import fr.soleil.bensikin.data.context.Context;
 import fr.soleil.bensikin.data.snapshot.Snapshot;
 import fr.soleil.bensikin.models.ContextAttributesTreeModel;
 import fr.soleil.bensikin.tools.Messages;
+import fr.soleil.lib.project.ObjectUtils;
 
 /**
  * Registers a new context; a singleton class.
@@ -124,15 +125,22 @@ public class RegisterContextAction extends BensikinAction {
     public void actionPerformed(final ActionEvent arg0) {
         WaitingDialog.changeFirstMessage(Messages.getMessage("DIALOGS_WAITING_SAVING_TITLE"));
         WaitingDialog.openInstance();
+
         final ContextDataPanel contextDataPanel = ContextDataPanel.getInstance();
+        final ContextAttributesTreeModel model = ContextAttributesTreeModel.getInstance(false);
 
         final String name = contextDataPanel.getNameField().getText();
         final String author = contextDataPanel.getAuthorNameField().getText();
         final String reason = contextDataPanel.getReasonField().getText();
         final String description = contextDataPanel.getDescriptionField().getText();
-        final String id = contextDataPanel.getIDField().getText();
+        final String id;
+        if ((model != null) && (model.isAttributeListChanged())) {
+            // TANGOARCH-629: if attribute list changed, a new context should be created.
+            id = ObjectUtils.EMPTY_STRING;
+        } else {
+            id = contextDataPanel.getIDField().getText();
+        }
 
-        final ContextAttributesTreeModel model = ContextAttributesTreeModel.getInstance(false);
         Context savedContext = null;
         try {
             final SnapContext toSave = Context.fillSnapContext(id, name, author, reason, description, model);
diff --git a/src/main/java/fr/soleil/bensikin/actions/context/SaveSelectedContextAction.java b/src/main/java/fr/soleil/bensikin/actions/context/SaveSelectedContextAction.java
index ae929f2..3505fed 100644
--- a/src/main/java/fr/soleil/bensikin/actions/context/SaveSelectedContextAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/context/SaveSelectedContextAction.java
@@ -51,11 +51,11 @@ import fr.soleil.bensikin.data.context.manager.IContextManager;
 /**
  * Saves the current context in a file. This action can be of 2 type: default
  * (quick save to the default directory and file), or non-default (save to the
- * user-defined directory and file, with prepositionning on the default
+ * user-defined directory and file, with pre-positioning on the default
  * directory).
  * <UL>
  * <LI>Builds the current context from the display area
- * <LI>Opens a file chooser dialog specialised in context saving, gets the path
+ * <LI>Opens a file chooser dialog specialized in context saving, gets the path
  * to save to from it (if non-default)
  * <LI>Uses the application's IContextManager to save the context
  * <LI>Logs the action's success or failure
@@ -70,20 +70,17 @@ public class SaveSelectedContextAction extends BensikinAction {
     private boolean isSaveAs;
 
     /**
-     * Standard action constructor that sets the action's name, plus sets the
-     * isDefault attribute.
+     * Standard action constructor that sets the action's name, plus sets the isDefault attribute.
      * 
-     * @param name
-     *            The action name
-     * @param _isDefault
-     *            True if the save action is a quick save to the working
-     *            directory and default file, false otherwise
+     * @param name The action name
+     * @param isSaveAs False if the save action is a quick save to the working directory and default file, true
+     *            otherwise
      */
-    public SaveSelectedContextAction(String name, boolean _isSaveAs) {
+    public SaveSelectedContextAction(String name, boolean isSaveAs) {
         super.putValue(Action.NAME, name);
         super.putValue(Action.SHORT_DESCRIPTION, name);
 
-        this.isSaveAs = _isSaveAs;
+        this.isSaveAs = isSaveAs;
     }
 
     @Override
diff --git a/src/main/java/fr/soleil/bensikin/actions/context/SearchContextsAction.java b/src/main/java/fr/soleil/bensikin/actions/context/SearchContextsAction.java
index bca1911..6031d47 100644
--- a/src/main/java/fr/soleil/bensikin/actions/context/SearchContextsAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/context/SearchContextsAction.java
@@ -80,7 +80,7 @@ import fr.soleil.bensikin.tools.Messages;
  */
 public class SearchContextsAction extends BensikinAction {
 
-    private static final long serialVersionUID = 8173399365040494502L;
+    private static final long serialVersionUID = -6484800349299896833L;
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SearchContextsAction.class);
 
@@ -203,7 +203,7 @@ public class SearchContextsAction extends BensikinAction {
      */
     private void verifyFields(final SearchContextsInDBDialog source) throws FieldFormatException {
         final String id = source.textId.getText();
-        if (id != null && !id.trim().equals("")) {
+        if (id != null && !id.trim().isEmpty()) {
             try {
                 // int i =
                 Integer.parseInt(id);
@@ -213,12 +213,12 @@ public class SearchContextsAction extends BensikinAction {
         }
 
         final String startTime = source.textStartTime.getText();
-        if (startTime != null && !startTime.trim().equals("")) {
+        if (startTime != null && !startTime.trim().isEmpty()) {
             DateUtils.stringToTimestamp(startTime, false, FieldFormatException.SEARCH_CONTEXTS_START_TIME);
         }
 
         final String endTime = source.textEndTime.getText();
-        if (endTime != null && !endTime.trim().equals("")) {
+        if (endTime != null && !endTime.trim().isEmpty()) {
             DateUtils.stringToTimestamp(startTime, false, FieldFormatException.SEARCH_CONTEXTS_END_TIME);
         }
     }
@@ -245,7 +245,7 @@ public class SearchContextsAction extends BensikinAction {
             isACriterion = false;
         }
 
-        if (_text == null || _text.trim().equals("")) {
+        if (_text == null || _text.trim().isEmpty()) {
             isACriterion = false;
         }
 
diff --git a/src/main/java/fr/soleil/bensikin/actions/context/ValidateAlternateSelectionAction.java b/src/main/java/fr/soleil/bensikin/actions/context/ValidateAlternateSelectionAction.java
index cd5774e..dc5db25 100644
--- a/src/main/java/fr/soleil/bensikin/actions/context/ValidateAlternateSelectionAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/context/ValidateAlternateSelectionAction.java
@@ -95,8 +95,7 @@ public class ValidateAlternateSelectionAction extends BensikinAction {
                     }
                 }
             }
-            // Forces the table to have ContextAttribute[] instead of
-            // Attribute[]
+            // Forces the table to have ContextAttribute[] instead of Attribute[]
             treeModel.addSelectedAttributes(validatedCA, true);
             TreeMap<String, ContextAttribute> attrs = treeModel.getAttributes();
             Context currentContext = Context.getSelectedContext();
diff --git a/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTableListener.java b/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTableListener.java
index beabf3d..878797d 100644
--- a/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTableListener.java
+++ b/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTableListener.java
@@ -128,18 +128,12 @@ public class ContextTableListener extends MouseAdapter implements ActionListener
         final ContextData selectedContextData = sourceModel.getContextAtRow(source.convertRowIndexToModel(row));
 
         final Context selectedContext = new Context(selectedContextData.getId());
-        Context.setSelectedContext(selectedContext);
+
+        // Don't select context if loading failed
+        boolean loadError = false;
 
         try {
             selectedContext.loadAttributes(null);
-
-            Snapshot.reset(false, true);
-
-            // preparing snapshot filter
-            transferFilter();
-
-            final String msg = Messages.getLogMessage("LOAD_CONTEXT_ATTRIBUTES_OK");
-            LOGGER.debug(msg);
         } catch (final SnapshotingException e) {
             String msg;
             if (e.computeIsDueToATimeOut()) {
@@ -148,16 +142,26 @@ public class ContextTableListener extends MouseAdapter implements ActionListener
                 msg = Messages.getLogMessage("LOAD_CONTEXT_ATTRIBUTES_KO");
             }
             LOGGER.error(msg, e);
-            return;
+            loadError = true;
         } catch (final Exception e) {
             final String msg = Messages.getLogMessage("LOAD_CONTEXT_ATTRIBUTES_KO");
             LOGGER.error(msg, e);
-            return;
+            loadError = true;
+        }
+        if (!loadError) {
+            Context.setSelectedContext(selectedContext);
+            Snapshot.reset(false, true);
+
+            // preparing snapshot filter
+            transferFilter();
+
+            final String msg = Messages.getLogMessage("LOAD_CONTEXT_ATTRIBUTES_OK");
+            LOGGER.debug(msg);
+            selectedContext.push();
+            ContextAttributesTree.getInstance().expandAll(true);
+            ContextActionPanel.getInstance().allowPrint(true);
         }
 
-        selectedContext.push();
-        ContextAttributesTree.getInstance().expandAll(true);
-        ContextActionPanel.getInstance().allowPrint(true);
     }
 
     public static void transferFilter() {
@@ -168,42 +172,42 @@ public class ContextTableListener extends MouseAdapter implements ActionListener
         today.set(Calendar.MILLISECOND, 0);
         int day;
         switch (Options.getInstance().getSnapshotOptions().getTimeFilter()) {
-        case SnapshotOptions.FILTER_DAY7:
-            day = today.get(Calendar.DAY_OF_YEAR);
-            day -= 7;
-            if (day < 1) {
-                today.set(Calendar.YEAR, today.get(Calendar.YEAR) - 1);
-                today.set(Calendar.MONTH, Calendar.DECEMBER);
-                today.set(Calendar.DAY_OF_MONTH, 31);
-                day = today.get(Calendar.DAY_OF_YEAR) + day;
-            }
-            today.set(Calendar.DAY_OF_YEAR, day);
-            break;
-        case SnapshotOptions.FILTER_DAY30:
-            day = today.get(Calendar.DAY_OF_YEAR);
-            day -= 30;
-            if (day < 1) {
-                today.set(Calendar.YEAR, today.get(Calendar.YEAR) - 1);
-                today.set(Calendar.MONTH, Calendar.DECEMBER);
-                today.set(Calendar.DAY_OF_MONTH, 31);
-                day = today.get(Calendar.DAY_OF_YEAR) + day;
-            }
-            today.set(Calendar.DAY_OF_YEAR, day);
-            break;
-        case SnapshotOptions.FILTER_WEEK:
-            today.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-            break;
-        case SnapshotOptions.FILTER_MONTH:
-            today.set(Calendar.DAY_OF_MONTH, 1);
-            break;
+            case SnapshotOptions.FILTER_DAY7:
+                day = today.get(Calendar.DAY_OF_YEAR);
+                day -= 7;
+                if (day < 1) {
+                    today.set(Calendar.YEAR, today.get(Calendar.YEAR) - 1);
+                    today.set(Calendar.MONTH, Calendar.DECEMBER);
+                    today.set(Calendar.DAY_OF_MONTH, 31);
+                    day = today.get(Calendar.DAY_OF_YEAR) + day;
+                }
+                today.set(Calendar.DAY_OF_YEAR, day);
+                break;
+            case SnapshotOptions.FILTER_DAY30:
+                day = today.get(Calendar.DAY_OF_YEAR);
+                day -= 30;
+                if (day < 1) {
+                    today.set(Calendar.YEAR, today.get(Calendar.YEAR) - 1);
+                    today.set(Calendar.MONTH, Calendar.DECEMBER);
+                    today.set(Calendar.DAY_OF_MONTH, 31);
+                    day = today.get(Calendar.DAY_OF_YEAR) + day;
+                }
+                today.set(Calendar.DAY_OF_YEAR, day);
+                break;
+            case SnapshotOptions.FILTER_WEEK:
+                today.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+                break;
+            case SnapshotOptions.FILTER_MONTH:
+                today.set(Calendar.DAY_OF_MONTH, 1);
+                break;
         }
         final String dayStartString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(today.getTime());
         // starting filter
         SnapshotFilterPanel.getInstance().resetFields();
         SnapshotFilterPanel.getInstance().getSelectStartTime().setSelectedIndex(1);
         SnapshotFilterPanel.getInstance().getTextStartTime().setText(dayStartString);
-        FilterSnapshotsAction.getInstance().actionPerformed(
-                new ActionEvent(new JButton(), ActionEvent.ACTION_PERFORMED, ""));
+        FilterSnapshotsAction.getInstance()
+                .actionPerformed(new ActionEvent(new JButton(), ActionEvent.ACTION_PERFORMED, ""));
         // end filtering
     }
 }
diff --git a/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTextListener.java b/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTextListener.java
index 25eeccc..145b8d6 100644
--- a/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTextListener.java
+++ b/src/main/java/fr/soleil/bensikin/actions/listeners/ContextTextListener.java
@@ -36,61 +36,43 @@ import fr.soleil.bensikin.containers.context.ContextActionPanel;
 
 public class ContextTextListener implements DocumentListener {
 
-	public ContextTextListener() {
-		// nothing, this is just here to have a constructor
-	}
+    public ContextTextListener() {
+        // nothing, this is just here to have a constructor
+    }
 
-	private void textChanged(DocumentEvent arg0) {
-		if (arg0 == null) {
-			return;
-		}
-		Document doc = arg0.getDocument();
-		if (doc != null && doc.getLength() > 0) {
-			try {
-				if (!"".equals(doc.getText(0, doc.getLength()).trim())) {
-					RegisterContextAction register = RegisterContextAction
-							.getInstance();
-					if (register != null) {
-						register.setEnabled(true);
-					}
-					ContextActionPanel.getInstance().allowPrint(false);
-				}
-			} catch (BadLocationException e) {
-				// trace here but should never happen.
-				e.printStackTrace();
-				return;
-			}
-		}
-	}
+    private void textChanged(DocumentEvent evt) {
+        if (evt != null) {
+            Document doc = evt.getDocument();
+            if (doc != null && doc.getLength() > 0) {
+                try {
+                    if (!doc.getText(0, doc.getLength()).trim().isEmpty()) {
+                        RegisterContextAction register = RegisterContextAction.getInstance();
+                        if (register != null) {
+                            register.setEnabled(true);
+                        }
+                        ContextActionPanel.getInstance().allowPrint(false);
+                    }
+                } catch (BadLocationException e) {
+                    // trace here but should never happen.
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @seejavax.swing.event.DocumentListener#changedUpdate(javax.swing.event.
-	 * DocumentEvent)
-	 */
-	public void changedUpdate(DocumentEvent arg0) {
-		// textChanged(arg0);
-	}
+    @Override
+    public void changedUpdate(DocumentEvent evt) {
+        // textChanged(evt);
+    }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @seejavax.swing.event.DocumentListener#insertUpdate(javax.swing.event.
-	 * DocumentEvent)
-	 */
-	public void insertUpdate(DocumentEvent arg0) {
-		textChanged(arg0);
-	}
+    @Override
+    public void insertUpdate(DocumentEvent evt) {
+        textChanged(evt);
+    }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @seejavax.swing.event.DocumentListener#removeUpdate(javax.swing.event.
-	 * DocumentEvent)
-	 */
-	public void removeUpdate(DocumentEvent arg0) {
-		textChanged(arg0);
-	}
+    @Override
+    public void removeUpdate(DocumentEvent evt) {
+        textChanged(evt);
+    }
 
 }
diff --git a/src/main/java/fr/soleil/bensikin/actions/listeners/SelectedContextListener.java b/src/main/java/fr/soleil/bensikin/actions/listeners/SelectedContextListener.java
index 2278158..d2403fd 100644
--- a/src/main/java/fr/soleil/bensikin/actions/listeners/SelectedContextListener.java
+++ b/src/main/java/fr/soleil/bensikin/actions/listeners/SelectedContextListener.java
@@ -54,25 +54,19 @@ public class SelectedContextListener implements PropertyChangeListener {
     public static final String ID_TEXT_PROPERTY = "idText";
     public final static String INFO_TEXT_PROPERTY = "info";
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @seejava.beans.PropertyChangeListener#propertyChange(java.beans.
-     * PropertyChangeEvent)
-     */
+    @Override
     public void propertyChange(PropertyChangeEvent event) {
         String prop = event.getPropertyName();
         if (ID_TEXT_PROPERTY.equals(prop)) {
             LaunchSnapshotAction launchSnapshotAction = LaunchSnapshotAction.getInstance();
             FilterSnapshotsAction filterSnapshotsAction = FilterSnapshotsAction.getInstance();
             RegisterContextAction registerContextAction = RegisterContextAction.getInstance();
-            MatchContextAttributesAction matchContextAttributesAction = MatchContextAttributesAction
-                    .getInstance();
+            MatchContextAttributesAction matchContextAttributesAction = MatchContextAttributesAction.getInstance();
 
             JTextField idField = (JTextField) event.getSource();
             String id = idField.getText();
 
-            if (id == null || id.trim().equals("")) {
+            if (id == null || id.trim().isEmpty()) {
                 launchSnapshotAction.setEnabled(false);
                 filterSnapshotsAction.setEnabled(false);
 
@@ -86,8 +80,7 @@ public class SelectedContextListener implements PropertyChangeListener {
                 if (matchContextAttributesAction != null) {
                     matchContextAttributesAction.setEnabled(false);
                 }
-            }
-            else {
+            } else {
                 boolean isContextFileSelected = false;
                 if (Context.getSelectedContext() != null) {
                     isContextFileSelected = Context.getSelectedContext().isContextFile();
@@ -109,10 +102,9 @@ public class SelectedContextListener implements PropertyChangeListener {
             JTextField idField = (JTextField) event.getSource();
             String id = idField.getText();
 
-            if (id == null || id.trim().equals("")) {
+            if (id == null || id.trim().isEmpty()) {
                 registerContextAction.setEnabled(false);
-            }
-            else {
+            } else {
                 registerContextAction.setEnabled(true);
             }
         }
diff --git a/src/main/java/fr/soleil/bensikin/actions/snapshot/AddSnapshotToCompareAction.java b/src/main/java/fr/soleil/bensikin/actions/snapshot/AddSnapshotToCompareAction.java
index 1c2f4a1..ec7bbd6 100644
--- a/src/main/java/fr/soleil/bensikin/actions/snapshot/AddSnapshotToCompareAction.java
+++ b/src/main/java/fr/soleil/bensikin/actions/snapshot/AddSnapshotToCompareAction.java
@@ -63,8 +63,7 @@ public class AddSnapshotToCompareAction extends BensikinAction {
     /**
      * Standard action constructor that sets the action's name.
      * 
-     * @param name
-     *            The action name
+     * @param name The action name
      */
     public AddSnapshotToCompareAction(String name) {
         this.putValue(Action.NAME, name);
@@ -82,9 +81,9 @@ public class AddSnapshotToCompareAction extends BensikinAction {
         SnapshotDetailComparePanel comparePanel = SnapshotDetailComparePanel.getInstance();
         JTextField field1 = comparePanel.getSn1TextField();
         JTextField field2 = comparePanel.getSn2TextField();
-        boolean isField1Empty = field1.getText() == null || field1.getText().trim().equals("");
+        boolean isField1Empty = field1.getText() == null || field1.getText().trim().isEmpty();
         // boolean isField2Empty = field2.getText() == null ||
-        // field2.getText().trim().equals("");
+        // field2.getText().trim().isEmpty();
         JTextField fieldToFill = field1;
         boolean isFirst = true;
         if (!isField1Empty) {
diff --git a/src/main/java/fr/soleil/bensikin/components/snapshot/detail/SnapshotCompareTable.java b/src/main/java/fr/soleil/bensikin/components/snapshot/detail/SnapshotCompareTable.java
index 4741b0f..5b4746d 100644
--- a/src/main/java/fr/soleil/bensikin/components/snapshot/detail/SnapshotCompareTable.java
+++ b/src/main/java/fr/soleil/bensikin/components/snapshot/detail/SnapshotCompareTable.java
@@ -71,8 +71,7 @@ import fr.soleil.bensikin.data.snapshot.Snapshot;
 import fr.soleil.bensikin.models.SnapshotCompareTablePrintModel;
 
 /**
- * A JTable used to compare 2 Snapshots, that can take a variable set of
- * columns.
+ * A JTable used to compare 2 Snapshots, that can take a variable set of columns.
  * 
  * @author CLAISSE
  */
@@ -139,10 +138,8 @@ public class SnapshotCompareTable extends JTable {
     /**
      * Builds its model from <code>snapshot1</code> and <code>snapshot2</code>
      * 
-     * @param snapshot1
-     *            The 1st snapshot of the comparison
-     * @param snapshot2
-     *            The 2nd snapshot of the comparison
+     * @param snapshot1 The 1st snapshot of the comparison
+     * @param snapshot2 The 2nd snapshot of the comparison
      */
     public void build(Snapshot snapshot1, Snapshot snapshot2) {
         SnapshotCompareTablePrintModel model = new SnapshotCompareTablePrintModel(snapshot1,
@@ -177,7 +174,7 @@ public class SnapshotCompareTable extends JTable {
             this.setColumnId(nextCol, i);
             // public Object getIdentifier()
             int size = 120;
-            if (id.trim().equals("")) {
+            if (id.trim().isEmpty()) {
                 size = 200;
             }
             nextCol.setPreferredWidth(size);
diff --git a/src/main/java/fr/soleil/bensikin/containers/context/ContextDataPanel.java b/src/main/java/fr/soleil/bensikin/containers/context/ContextDataPanel.java
index 7f3b31b..3f5a722 100644
--- a/src/main/java/fr/soleil/bensikin/containers/context/ContextDataPanel.java
+++ b/src/main/java/fr/soleil/bensikin/containers/context/ContextDataPanel.java
@@ -58,29 +58,34 @@ import fr.soleil.bensikin.actions.listeners.ContextTextListener;
 import fr.soleil.bensikin.actions.listeners.SelectedContextListener;
 import fr.soleil.bensikin.components.context.detail.IDTextField;
 import fr.soleil.bensikin.tools.Messages;
+import fr.soleil.lib.project.ObjectUtils;
 
 /**
- * Contains the attributes-independant information about the current text: id, date (never
+ * Contains the attributes-independent information about the current text: id, date (never
  * user-modifiable fields) and name, author, reason, description (user-modifiable fields).
  * 
  * @author CLAISSE
  */
 public class ContextDataPanel extends JPanel {
 
-    private static final long serialVersionUID = 4693572269520139244L;
-    private IDTextField idField = null;
-    private JTextField creationDateField = null;
-    private JTextField nameField = null;
-    private JTextField authorNameField = null;
-    private JTextField reasonField = null;
-    private JTextField descriptionField = null;
-    private JTextField attributeCountField = null;
+    private static final long serialVersionUID = 5752827912756103034L;
 
-    // private Color disabledColor;
+    private static final String BULLET = "(*) ";
+    private static final Color DARK_RED = new Color(150, 0, 0);
 
     private static ContextDataPanel instance = null;
     private static boolean isInputEnabled = true;
 
+    private IDTextField idField;
+    private JTextField creationDateField;
+    private JTextField nameField;
+    private JTextField authorNameField;
+    private JTextField reasonField;
+    private JTextField descriptionField;
+    private JTextField attributeCountField;
+
+    // private Color disabledColor;
+
     /**
      * Instantiates itself if necessary, returns the instance.
      * 
@@ -91,88 +96,19 @@ public class ContextDataPanel extends JPanel {
             instance = new ContextDataPanel();
             instance.applyEnabled();
         }
-
         return instance;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see java.awt.Component#isEnabled()
-     */
-    @Override
-    public boolean isEnabled() {
-        return nameField.isEnabled();
-        // we use the name field in this test, but it could as well have been
-        // any other field
-        // (except never editable field id and date)
-    }
-
-    public void applyEnabled() {
-        if (!ContextDataPanel.isInputEnabled) {
-            nameField.setEnabled(false);
-            authorNameField.setEnabled(false);
-            reasonField.setEnabled(false);
-            descriptionField.setEnabled(false);
-        }
-    }
-
-    public static void disableInput() {
-        ContextDataPanel.isInputEnabled = false;
-        if (instance != null) {
-            instance.applyEnabled();
-        }
-    }
-
-    /**
-     * Enables modification of the text fields
-     * 
-     * @param forNewContext If true
-     */
-    public void enableInput(boolean forNewContext) {
-        Color enabledColor = Color.WHITE;
-
-        nameField.setEnabled(true);
-        // disabledColor = NameField.getBackground();
-        nameField.setBackground(enabledColor);
-
-        authorNameField.setEnabled(true);
-        authorNameField.setBackground(enabledColor);
-
-        reasonField.setEnabled(true);
-        reasonField.setBackground(enabledColor);
-
-        descriptionField.setEnabled(true);
-        descriptionField.setBackground(enabledColor);
-
-        if (forNewContext) {
-            this.resetFields();
-        }
-    }
-
-    /**
-     * 29 juin 2005
-     */
-    public void resetFields() {
-        idField.setText("");
-        creationDateField.setText("");
-        nameField.setText("");
-        authorNameField.setText("");
-        reasonField.setText("");
-        descriptionField.setText("");
-        attributeCountField.setText("");
-    }
-
     /**
      * Builds the panel
      */
     private ContextDataPanel() {
-        Color disabledColor = Color.lightGray;
+        Color disabledColor = Color.LIGHT_GRAY;
 
         idField = new IDTextField(5);
         idField.setMinimumSize(idField.getPreferredSize());
         idField.setEnabled(false);
-        idField.setDisabledTextColor(Color.black);
+        idField.setDisabledTextColor(Color.BLACK);
         idField.setBackground(disabledColor);
         idField.addPropertyChangeListener(new SelectedContextListener());
 
@@ -208,27 +144,28 @@ public class ContextDataPanel extends JPanel {
         attributeCountField = new JTextField(10);
         attributeCountField.setEnabled(false);
         attributeCountField.setEditable(false);
-        attributeCountField.setDisabledTextColor(Color.black);
+        attributeCountField.setDisabledTextColor(Color.BLACK);
         attributeCountField.setBackground(disabledColor);
-        attributeCountField.setText("");
+        attributeCountField.setText(ObjectUtils.EMPTY_STRING);
         attributeCountField.setMinimumSize(attributeCountField.getPreferredSize());
 
-        nameField.getDocument().addDocumentListener(new ContextTextListener());
-        authorNameField.getDocument().addDocumentListener(new ContextTextListener());
-        reasonField.getDocument().addDocumentListener(new ContextTextListener());
-        descriptionField.getDocument().addDocumentListener(new ContextTextListener());
+        ContextTextListener listener = new ContextTextListener();
+        nameField.getDocument().addDocumentListener(listener);
+        authorNameField.getDocument().addDocumentListener(listener);
+        reasonField.getDocument().addDocumentListener(listener);
+        descriptionField.getDocument().addDocumentListener(listener);
 
         String msgId = Messages.getMessage("CONTEXT_DETAIL_LABELS_ID");
         String msgTime = Messages.getMessage("CONTEXT_DETAIL_LABELS_TIME");
-        String msgName = "(*) " + Messages.getMessage("CONTEXT_DETAIL_LABELS_NAME");
-        String msgAuthor = "(*) " + Messages.getMessage("CONTEXT_DETAIL_LABELS_AUTHOR");
-        String msgReason = "(*) " + Messages.getMessage("CONTEXT_DETAIL_LABELS_REASON");
-        String msgDescription = "(*) " + Messages.getMessage("CONTEXT_DETAIL_LABELS_DESRIPTION");
-        String oblig = "(*) " + Messages.getMessage("CONTEXT_DETAIL_LABELS_MANDATORY");
+        String msgName = BULLET + Messages.getMessage("CONTEXT_DETAIL_LABELS_NAME");
+        String msgAuthor = BULLET + Messages.getMessage("CONTEXT_DETAIL_LABELS_AUTHOR");
+        String msgReason = BULLET + Messages.getMessage("CONTEXT_DETAIL_LABELS_REASON");
+        String msgDescription = BULLET + Messages.getMessage("CONTEXT_DETAIL_LABELS_DESRIPTION");
+        String oblig = BULLET + Messages.getMessage("CONTEXT_DETAIL_LABELS_MANDATORY");
         String attrCount = Messages.getMessage("CONTEXT_DETAIL_LABELS_ATTRIBUTE_COUNT");
 
         JLabel mandatoryLabel = new JLabel(oblig, JLabel.RIGHT);
-        mandatoryLabel.setForeground(new Color(150, 0, 0));
+        mandatoryLabel.setForeground(DARK_RED);
         mandatoryLabel.setFont(smallFont);
         JLabel idLabel = new JLabel(msgId);
         idLabel.setFont(font);
@@ -236,16 +173,16 @@ public class ContextDataPanel extends JPanel {
         timeLabel.setFont(font);
         JLabel nameLabel = new JLabel(msgName);
         nameLabel.setFont(font);
-        nameLabel.setForeground(new Color(150, 0, 0));
+        nameLabel.setForeground(DARK_RED);
         JLabel authorLabel = new JLabel(msgAuthor);
         authorLabel.setFont(font);
-        authorLabel.setForeground(new Color(150, 0, 0));
+        authorLabel.setForeground(DARK_RED);
         JLabel reasonLabel = new JLabel(msgReason);
         reasonLabel.setFont(font);
-        reasonLabel.setForeground(new Color(150, 0, 0));
+        reasonLabel.setForeground(DARK_RED);
         JLabel descrLabel = new JLabel(msgDescription);
         descrLabel.setFont(font);
-        descrLabel.setForeground(new Color(150, 0, 0));
+        descrLabel.setForeground(DARK_RED);
         JLabel attrCountLabel = new JLabel(attrCount, JLabel.RIGHT);
         attrCountLabel.setFont(font);
 
@@ -406,6 +343,68 @@ public class ContextDataPanel extends JPanel {
         GUIUtilities.setObjectBackground(this, GUIUtilities.CONTEXT_COLOR);
     }
 
+    @Override
+    public boolean isEnabled() {
+        return nameField.isEnabled();
+        // we use the name field in this test, but it could as well have been
+        // any other field (except never editable field id and date)
+    }
+
+    public void applyEnabled() {
+        if (!ContextDataPanel.isInputEnabled) {
+            nameField.setEnabled(false);
+            authorNameField.setEnabled(false);
+            reasonField.setEnabled(false);
+            descriptionField.setEnabled(false);
+        }
+    }
+
+    public static void disableInput() {
+        ContextDataPanel.isInputEnabled = false;
+        if (instance != null) {
+            instance.applyEnabled();
+        }
+    }
+
+    /**
+     * Enables modification of the text fields
+     * 
+     * @param forNewContext If true
+     */
+    public void enableInput(boolean forNewContext) {
+        Color enabledColor = Color.WHITE;
+
+        nameField.setEnabled(true);
+        // disabledColor = NameField.getBackground();
+        nameField.setBackground(enabledColor);
+
+        authorNameField.setEnabled(true);
+        authorNameField.setBackground(enabledColor);
+
+        reasonField.setEnabled(true);
+        reasonField.setBackground(enabledColor);
+
+        descriptionField.setEnabled(true);
+        descriptionField.setBackground(enabledColor);
+
+        if (forNewContext) {
+            this.resetFields();
+        }
+    }
+
+    /**
+     * 29 juin 2005
+     */
+    public void resetFields() {
+        creationDateField.setText(ObjectUtils.EMPTY_STRING);
+        nameField.setText(ObjectUtils.EMPTY_STRING);
+        authorNameField.setText(ObjectUtils.EMPTY_STRING);
+        reasonField.setText(ObjectUtils.EMPTY_STRING);
+        descriptionField.setText(ObjectUtils.EMPTY_STRING);
+        attributeCountField.setText(ObjectUtils.EMPTY_STRING);
+        idField.setText(ObjectUtils.EMPTY_STRING);
+    }
+
     /**
      * @return Returns the authorNameField.
      */
diff --git a/src/main/java/fr/soleil/bensikin/containers/snapshot/SnapshotDetailTabbedPaneContent.java b/src/main/java/fr/soleil/bensikin/containers/snapshot/SnapshotDetailTabbedPaneContent.java
index 3d9b337..5665fc5 100644
--- a/src/main/java/fr/soleil/bensikin/containers/snapshot/SnapshotDetailTabbedPaneContent.java
+++ b/src/main/java/fr/soleil/bensikin/containers/snapshot/SnapshotDetailTabbedPaneContent.java
@@ -273,8 +273,8 @@ public class SnapshotDetailTabbedPaneContent extends JPanel {
         GUIUtilities.setObjectBackground(toTextAndEditButton, GUIUtilities.SNAPSHOT_CLIPBOARD_COLOR);
 
         msg = Messages.getMessage("CONTEXT_DETAIL_ATTRIBUTES_ALTERNATE_SELECT_NONE_BUTTON");
-        selectNoneButton = new JButton(new SelectAllOrNoneAction(msg, SelectAllOrNoneAction.SELECT_NONE_TYPE,
-                this.snapshotDetailTable));
+        selectNoneButton = new JButton(
+                new SelectAllOrNoneAction(msg, SelectAllOrNoneAction.SELECT_NONE_TYPE, this.snapshotDetailTable));
         selectNoneButton.setMargin(new Insets(0, 0, 0, 0));
         selectNoneButton.setFocusPainted(false);
         selectNoneButton.setFocusable(false);
@@ -290,8 +290,8 @@ public class SnapshotDetailTabbedPaneContent extends JPanel {
         GUIUtilities.setObjectBackground(transferRWButton, GUIUtilities.SELECT_COLOR);
 
         msg = Messages.getMessage("SNAPSHOT_DETAIL_SELECT_ALL_BUTTON");
-        selectAllButton = new JButton(new SelectAllOrNoneAction(msg, SelectAllOrNoneAction.SELECT_ALL_TYPE,
-                this.snapshotDetailTable));
+        selectAllButton = new JButton(
+                new SelectAllOrNoneAction(msg, SelectAllOrNoneAction.SELECT_ALL_TYPE, this.snapshotDetailTable));
         selectAllButton.setMargin(new Insets(0, 0, 0, 0));
         selectAllButton.setFocusPainted(false);
         selectAllButton.setFocusable(false);
@@ -339,7 +339,7 @@ public class SnapshotDetailTabbedPaneContent extends JPanel {
                 timeText = Messages.getMessage("SNAPSHOT_DETAIL_NO_TIMESTAMP");
             } else {
                 timeText = timeText.trim();
-                if ("".equals(timeText)) {
+                if (timeText.isEmpty()) {
                     timeText = Messages.getMessage("SNAPSHOT_DETAIL_NO_TIMESTAMP");
                 }
             }
diff --git a/src/main/java/fr/soleil/bensikin/containers/sub/dialogs/options/OptionsSnapshotTab.java b/src/main/java/fr/soleil/bensikin/containers/sub/dialogs/options/OptionsSnapshotTab.java
index 9a0d8a9..4fb7440 100644
--- a/src/main/java/fr/soleil/bensikin/containers/sub/dialogs/options/OptionsSnapshotTab.java
+++ b/src/main/java/fr/soleil/bensikin/containers/sub/dialogs/options/OptionsSnapshotTab.java
@@ -238,7 +238,7 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Inits the tab's components.
+     * Initializes the tab's components.
      */
     private void initComponents() {
 
@@ -933,21 +933,17 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * @return The buttonGroup attribute, containing the autoSnapshotCommentYes
-     *         and autoSnapshotCommentNo JRadioButtons
+     * @return The buttonGroup attribute, containing the autoSnapshotCommentYes and autoSnapshotCommentNo JRadioButtons
      */
     public ButtonGroup getButtonGroup() {
         return buttonGroup;
     }
 
     /**
-     * Selects a auto comment JRadioButton, depending on the autoComment
-     * parameter value
+     * Selects a auto comment JRadioButton, depending on the autoComment parameter value
      * 
-     * @param autoComment
-     *            Has to be either SNAPSHOT_AUTO_COMMENT_YES or
-     *            SNAPSHOT_AUTO_COMMENT_NO, otherwise a IllegalArgumentException
-     *            is thrown
+     * @param autoComment Has to be either SNAPSHOT_AUTO_COMMENT_YES or SNAPSHOT_AUTO_COMMENT_NO, otherwise a
+     *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
     public void selectAutoCommentButton(int autoComment) throws IllegalArgumentException {
@@ -966,12 +962,9 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a show read JRadioButton, depending on the showRead parameter
-     * value
+     * Selects a show read JRadioButton, depending on the showRead parameter value
      * 
-     * @param showRead
-     *            Has to be either SNAPSHOT_COMPARE_SHOW_READ_YES or
-     *            SNAPSHOT_COMPARE_SHOW_READ_NO, otherwise a
+     * @param showRead Has to be either SNAPSHOT_COMPARE_SHOW_READ_YES or SNAPSHOT_COMPARE_SHOW_READ_NO, otherwise a
      *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
@@ -993,12 +986,9 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a show write JRadioButton, depending on the showWrite parameter
-     * value
+     * Selects a show write JRadioButton, depending on the showWrite parameter value
      * 
-     * @param showWrite
-     *            Has to be either SNAPSHOT_COMPARE_SHOW_WRITE_YES or
-     *            SNAPSHOT_COMPARE_SHOW_WRITE_NO, otherwise a
+     * @param showWrite Has to be either SNAPSHOT_COMPARE_SHOW_WRITE_YES or SNAPSHOT_COMPARE_SHOW_WRITE_NO, otherwise a
      *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
@@ -1020,12 +1010,9 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a show delta JRadioButton, depending on the showDelta parameter
-     * value
+     * Selects a show delta JRadioButton, depending on the showDelta parameter value
      * 
-     * @param showDelta
-     *            Has to be either SNAPSHOT_COMPARE_SHOW_DELTA_YES or
-     *            SNAPSHOT_COMPARE_SHOW_DELTA_NO, otherwise a
+     * @param showDelta Has to be either SNAPSHOT_COMPARE_SHOW_DELTA_YES or SNAPSHOT_COMPARE_SHOW_DELTA_NO, otherwise a
      *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
@@ -1047,12 +1034,9 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a show diff JRadioButton, depending on the showDiff parameter
-     * value
+     * Selects a show diff JRadioButton, depending on the showDiff parameter value
      * 
-     * @param showDiff
-     *            Has to be either SNAPSHOT_COMPARE_SHOW_DIFF_YES or
-     *            SNAPSHOT_COMPARE_SHOW_DIFF_NO, otherwise a
+     * @param showDiff Has to be either SNAPSHOT_COMPARE_SHOW_DIFF_YES or SNAPSHOT_COMPARE_SHOW_DIFF_NO, otherwise a
      *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
@@ -1074,12 +1058,9 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a show diff abs JRadioButton, depending on the showDiff parameter
-     * value
+     * Selects a show diff abs JRadioButton, depending on the showDiff parameter value
      * 
-     * @param showDiff
-     *            Has to be either SNAPSHOT_COMPARE_SHOW_DIFF_YES or
-     *            SNAPSHOT_COMPARE_SHOW_DIFF_NO, otherwise a
+     * @param showDiff Has to be either SNAPSHOT_COMPARE_SHOW_DIFF_YES or SNAPSHOT_COMPARE_SHOW_DIFF_NO, otherwise a
      *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
@@ -1103,9 +1084,8 @@ public class OptionsSnapshotTab extends JPanel {
     /**
      * Selects a csv id JRadioButton, depending on the csvID parameter value
      * 
-     * @param csvID
-     *            Has to be either SNAPSHOT_CSV_ID_YES or SNAPSHOT_CSV_ID_NO,
-     *            otherwise a IllegalArgumentException is thrown
+     * @param csvID Has to be either SNAPSHOT_CSV_ID_YES or SNAPSHOT_CSV_ID_NO, otherwise a IllegalArgumentException is
+     *            thrown
      * @throws IllegalArgumentException
      */
     public void selectCSVIDButton(int csvID) throws IllegalArgumentException {
@@ -1126,10 +1106,8 @@ public class OptionsSnapshotTab extends JPanel {
     /**
      * Selects a csv time JRadioButton, depending on the csvTime parameter value
      * 
-     * @param csvTime
-     *            Has to be either SNAPSHOT_CSV_TIME_YES or
-     *            SNAPSHOT_CSV_TIME_NO, otherwise a IllegalArgumentException is
-     *            thrown
+     * @param csvTime Has to be either SNAPSHOT_CSV_TIME_YES or SNAPSHOT_CSV_TIME_NO, otherwise a
+     *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
     public void selectCSVTimeButton(int csvTime) throws IllegalArgumentException {
@@ -1148,12 +1126,9 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a csv contextID JRadioButton, depending on the csvContextID
-     * parameter value
+     * Selects a csv contextID JRadioButton, depending on the csvContextID parameter value
      * 
-     * @param csvContextID
-     *            Has to be either SNAPSHOT_CSV_CONTEXT_ID_YES or
-     *            SNAPSHOT_CSV_CONTEXT_ID_NO, otherwise a
+     * @param csvContextID Has to be either SNAPSHOT_CSV_CONTEXT_ID_YES or SNAPSHOT_CSV_CONTEXT_ID_NO, otherwise a
      *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
@@ -1175,10 +1150,8 @@ public class OptionsSnapshotTab extends JPanel {
     /**
      * Selects a csv read JRadioButton, depending on the csvRead parameter value
      * 
-     * @param csvRead
-     *            Has to be either SNAPSHOT_CSV_READ_YES or
-     *            SNAPSHOT_CSV_READ_NO, otherwise a IllegalArgumentException is
-     *            thrown
+     * @param csvRead Has to be either SNAPSHOT_CSV_READ_YES or SNAPSHOT_CSV_READ_NO, otherwise a
+     *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
     public void selectCSVReadButton(int csvRead) throws IllegalArgumentException {
@@ -1197,13 +1170,10 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a csv write JRadioButton, depending on the csvWrite parameter
-     * value
+     * Selects a csv write JRadioButton, depending on the csvWrite parameter value
      * 
-     * @param csvWrite
-     *            Has to be either SNAPSHOT_CSV_WRITE_YES or
-     *            SNAPSHOT_CSV_WRITE_NO, otherwise a IllegalArgumentException is
-     *            thrown
+     * @param csvWrite Has to be either SNAPSHOT_CSV_WRITE_YES or SNAPSHOT_CSV_WRITE_NO, otherwise a
+     *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
     public void selectCSVWriteButton(int csvWrite) throws IllegalArgumentException {
@@ -1222,13 +1192,10 @@ public class OptionsSnapshotTab extends JPanel {
     }
 
     /**
-     * Selects a csv delta JRadioButton, depending on the csvDelta parameter
-     * value
+     * Selects a csv delta JRadioButton, depending on the csvDelta parameter value
      * 
-     * @param csvDelta
-     *            Has to be either SNAPSHOT_CSV_DELTA_YES or
-     *            SNAPSHOT_CSV_DELTA_NO, otherwise a IllegalArgumentException is
-     *            thrown
+     * @param csvDelta Has to be either SNAPSHOT_CSV_DELTA_YES or NAPSHOT_CSV_DELTA_NO, otherwise a
+     *            IllegalArgumentException is thrown
      * @throws IllegalArgumentException
      */
     public void selectCSVDeltaButton(int csvDelta) throws IllegalArgumentException {
@@ -1258,11 +1225,10 @@ public class OptionsSnapshotTab extends JPanel {
     /**
      * Sets the default comment.
      * 
-     * @param _comment
-     *            The default comment
+     * @param comment The default comment
      */
-    public void setSnapshotDefaultComment(String _comment) {
-        this.defaultSnapshotComment.setText(_comment);
+    public void setSnapshotDefaultComment(String comment) {
+        this.defaultSnapshotComment.setText(comment);
     }
 
     /**
@@ -1433,7 +1399,7 @@ public class OptionsSnapshotTab extends JPanel {
             idx = 1;
         } else if (val_s.equals(SnapshotOptions.SNAPSHOT_CSV_SEPARATOR_PIPE)) {
             idx = 2;
-        } else if (val_s.trim().equals("")) {
+        } else if (val_s.trim().isEmpty()) {
             idx = 1;
         } else {
             idx = 0;
diff --git a/src/main/java/fr/soleil/bensikin/data/context/Context.java b/src/main/java/fr/soleil/bensikin/data/context/Context.java
index 7cd16fd..a3a3bfc 100644
--- a/src/main/java/fr/soleil/bensikin/data/context/Context.java
+++ b/src/main/java/fr/soleil/bensikin/data/context/Context.java
@@ -105,6 +105,7 @@ import fr.soleil.bensikin.options.Options;
 import fr.soleil.bensikin.options.sub.SnapshotOptions;
 import fr.soleil.bensikin.tools.Messages;
 import fr.soleil.bensikin.xml.BensikinXMLLine;
+import fr.soleil.lib.project.ObjectUtils;
 
 /**
  * A pivotal class of Bensikin, this class is the upper level modelisation of a
@@ -152,37 +153,36 @@ public class Context implements Comparable<Context> {
      * Sets the contextData and contextAttributes attributes
      * 
      * @param _contextData
-     * @param _contextAttributes
+     * @param contextAttributes
      */
-    public Context(final int _contextId, final ContextAttributes _contextAttributes) {
-        contextId = _contextId;
-        contextAttributes = _contextAttributes;
+    public Context(final int contextId, final ContextAttributes contextAttributes) {
+        this.contextId = contextId;
+        this.contextAttributes = contextAttributes;
     }
 
     /**
-     * Only sets the contextData attribute
+     * Only sets the context id
      * 
-     * @param _contextData
+     * @param contextId
      */
-    public Context(final int _contextId) {
-        contextId = _contextId;
+    public Context(final int contextId) {
+        this.contextId = contextId;
     }
 
     /**
-     * Looks up in database the referenced attributes for this context, provided
-     * they match the search criterions. The join condition on context id is
-     * automatically added to searchCriterions. Once the attributes are found
-     * ,they are converted to the ContextAttributes attribute.
+     * Looks up in database the referenced attributes for this context, provided they match the search criterions. The
+     * join condition on context id is automatically added to searchCriterions. Once the attributes are found,they are
+     * converted to the ContextAttributes attribute.
      * 
-     * @param searchCriterions
-     *            The object containing the search criterions
+     * @param searchCriterions The object containing the search criterions
      * @throws SnapshotingException
      */
     public void loadAttributes(Criterions searchCriterions) throws SnapshotingException {
         if (searchCriterions == null) {
             searchCriterions = new Criterions();
         }
-        searchCriterions.addCondition(new Condition(SnapConst.TAB_CONTEXT[0], SnapConst.OP_EQUALS, "" + contextId));
+        searchCriterions.addCondition(
+                new Condition(SnapConst.TAB_CONTEXT[0], SnapConst.OP_EQUALS, ObjectUtils.EMPTY_STRING + contextId));
         final ISnapManager source = SnapManagerFactory.getCurrentImpl();
         final SnapContext cont = getAsSnapContext();
         if (cont.getId() == 0) {
@@ -194,17 +194,16 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Looks up in database the referenced snapshots for this context, provided
-     * they match the search criterions. The join condition on context id is
-     * automatically added to searchCriterions. Once the contexts are found
-     * ,they are converted to the Snapshot [] attribute.
+     * Looks up in database the referenced snapshots for this context, provided hey match the search criterions. The
+     * join condition on context id is automatically added to searchCriterions. Once the contexts are found, they are
+     * converted to the Snapshot [] attribute.
      * 
-     * @param searchCriterions
-     *            The object containing the search criterions
+     * @param searchCriterions The object containing the search criterions
      * @throws Exception
      */
     public void loadSnapshots(final Criterions searchCriterions) throws SnapshotingException {
-        searchCriterions.addCondition(new Condition(SnapConst.TAB_SNAP[1], SnapConst.OP_EQUALS, "" + contextId));
+        searchCriterions.addCondition(
+                new Condition(SnapConst.TAB_SNAP[1], SnapConst.OP_EQUALS, ObjectUtils.EMPTY_STRING + contextId));
 
         final ISnapManager source = SnapManagerFactory.getCurrentImpl();
         final SnapshotLight[] newList = source.findSnapshots(searchCriterions);
@@ -219,13 +218,11 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Saves a SnapContext object, and results the resulting Context object
-     * (which unlike the SnapContext has a known id and date)
+     * Saves a SnapContext object, and results the resulting Context object (which unlike the SnapContext has a known id
+     * and date)
      * 
-     * @param context
-     *            The context to save
-     * @return A Context object that has the same properties as the context
-     *         pamareter, except for its id and date
+     * @param context The context to save
+     * @return A Context object that has the same properties as the context parameter, except for its id and date
      * @throws Exception
      */
     public static Context save(final SnapContext context) throws Exception {
@@ -264,11 +261,9 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Converts a SnapAttributeHeavy[] object to set the contextAttributes
-     * attribute.
+     * Converts a SnapAttributeHeavy[] object to set the contextAttributes attribute.
      * 
-     * @param sah
-     *            The attributes to convert
+     * @param sah The attributes to convert
      */
     private void setContextAttributes(final SnapAttributeHeavy[] sah) {
         if (sah == null) {
@@ -321,11 +316,10 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * @param _selectedContext
-     *            The currently selected Context
+     * @param selectedContext The currently selected Context
      */
-    public static void setSelectedContext(final Context _selectedContext) {
-        selectedContext = _selectedContext;
+    public static void setSelectedContext(final Context selectedContext) {
+        Context.selectedContext = selectedContext;
     }
 
     /**
@@ -336,8 +330,7 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Looks up in database the contexts matching the search criterions. Only
-     * loads their ContextData part.
+     * Looks up in database the contexts matching the search criterions. Only loads their ContextData part.
      * 
      * @param searchCriterions
      * @return The list of contexts matching the search criterions.
@@ -363,11 +356,10 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Looks up in database a particular Context, defined by its id. Loads both
-     * its ContextData and ContextAttributes part.
+     * Looks up in database a particular Context, defined by its id. Loads both its ContextData and ContextAttributes
+     * part.
      * 
-     * @param id
-     *            The key of the context
+     * @param id The key of the context
      * @return The required Context
      * @throws Exception
      */
@@ -379,8 +371,7 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * @return The Map which values are the currently opened Contexts, and which
-     *         keys are those contexts' ids.
+     * @return The Map which values are the currently opened Contexts, and which keys are those contexts' ids.
      */
     public static Map<String, Context> getOpenedContexts() {
         return openedContexts;
@@ -389,9 +380,7 @@ public class Context implements Comparable<Context> {
     /**
      * Adds openedContext to the current set of opened Contexts.
      * 
-     * @param openedContext
-     *            The opened context to add to the current set of opened
-     *            Contexts
+     * @param openedContext The opened context to add to the current set of opened Contexts
      */
     public static void addOpenedContext(final Context openedContext) {
         final int id = openedContext.getContextId();
@@ -401,9 +390,7 @@ public class Context implements Comparable<Context> {
     /**
      * Removes from the current set of opened Contexts the one that has that id.
      * 
-     * @param id
-     *            The id of the Context to remove from the current set of opened
-     *            Contexts
+     * @param id The id of the Context to remove from the current set of opened Contexts
      */
     public static void removeOpenedContext(final int id) {
         openedContexts.remove(String.valueOf(id));
@@ -412,16 +399,15 @@ public class Context implements Comparable<Context> {
     /**
      * Completely sets the openedContexts Map.
      * 
-     * @param openedContexts
-     *            The new openedContexts Map
+     * @param openedContexts The new openedContexts Map
      */
     public static void setOpenedContexts(final Map<String, Context> openedContexts) {
         Context.openedContexts = openedContexts;
     }
 
     /**
-     * Empties all references to opened and selected contexts, and resets the
-     * context displays, list and detail, accordingly.
+     * Empties all references to opened and selected contexts, and resets the context displays, list and detail,
+     * accordingly.
      */
     public static void reset() {
         selectedContext = null;
@@ -442,9 +428,8 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Launches a snapshot on this context. If necessary (defined in
-     * SnapshotOptions), automatically updates this snapshot's comment. Also
-     * refreshes the snapshots list.
+     * Launches a snapshot on this context. If necessary (defined in SnapshotOptions), automatically updates this
+     * snapshot's comment. Also refreshes the snapshots list.
      */
     public void launchSnapshot() throws SnapshotingException {
         final ISnapManager source = SnapManagerFactory.getCurrentImpl();
@@ -459,7 +444,7 @@ public class Context implements Comparable<Context> {
         final SnapshotOptions snapshotOptions = options.getSnapshotOptions();
         snapshotOptions.push();
         final String defaultComment = Snapshot.getSnapshotDefaultComment();
-        if (defaultComment != null && !defaultComment.trim().equals("")) {
+        if (defaultComment != null && !defaultComment.trim().isEmpty()) {
             toUpdate.updateComment(defaultComment);
         }
         // auto comment edit if that's in the options
@@ -471,19 +456,14 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * Builds a SnapContext object from parameters. Verifies the parameters and
-     * attributes list are non empty beforehand.
+     * Builds a SnapContext object from parameters. Verifies the parameters and attributes list are non empty
+     * beforehand.
      * 
-     * @param name
-     *            The name field
-     * @param author
-     *            The author field
-     * @param reason
-     *            The reason field
-     * @param description
-     *            The description field
-     * @param model
-     *            The model to get the selected attributes from
+     * @param name The name field
+     * @param author The author field
+     * @param reason The reason field
+     * @param description The description field
+     * @param model The model to get the selected attributes from
      * @return A SnapContext object built from parameters.
      * @throws Exception
      */
@@ -532,25 +512,20 @@ public class Context implements Comparable<Context> {
     /**
      * Builds a Context object from parameters.
      * 
-     * @param name
-     *            The name field
-     * @param author
-     *            The author field
-     * @param reason
-     *            The reason field
-     * @param description
-     *            The description field
-     * @param model
-     *            The model to get the selected attributes from
+     * @param name The name field
+     * @param author The author field
+     * @param reason The reason field
+     * @param description The description field
+     * @param model The model to get the selected attributes from
      * @return The filled Context, with data and attributes
      * @throws Exception
      */
     public static Context fillContext(final String id_s, final String creationDate_s, final String name,
             final String author, final String reason, final String description,
             final ContextAttributesTreeModel model) {
-        final int id = id_s == null || id_s.equals("") ? -1 : Integer.parseInt(id_s);
+        final int id = id_s == null || id_s.isEmpty() ? -1 : Integer.parseInt(id_s);
         Date creationDate = null;
-        if (creationDate_s == null || creationDate_s.equals("")) {
+        if (creationDate_s == null || creationDate_s.isEmpty()) {
             SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
             try {
                 creationDate = formatter.parse(creationDate_s);
@@ -589,8 +564,7 @@ public class Context implements Comparable<Context> {
     /**
      * Verifies an enumeration is non-empty.
      * 
-     * @param enum
-     *            The Enumeration to check
+     * @param enum The Enumeration to check
      * @return True if non-empty, false otherwise
      */
     private static boolean verifyAttributes(final Iterator<String> enumer) {
@@ -635,7 +609,7 @@ public class Context implements Comparable<Context> {
      */
     @Override
     public String toString() {
-        String ret = "";
+        String ret = ObjectUtils.EMPTY_STRING;
 
         final BensikinXMLLine openingLine = new BensikinXMLLine(Context.XML_TAG, BensikinXMLLine.OPENING_TAG_CATEGORY);
         final BensikinXMLLine closingLine = new BensikinXMLLine(Context.XML_TAG, BensikinXMLLine.CLOSING_TAG_CATEGORY);
@@ -650,7 +624,7 @@ public class Context implements Comparable<Context> {
         final String name = contextData.getName();
         final String reason = contextData.getReason();
         final String path = contextData.getPath();
-        final String isModified = this.isModified + "";
+        final String isModified = this.isModified + ObjectUtils.EMPTY_STRING;
 
         openingLine.setAttribute(ContextData.ID_PROPERTY_XML_TAG, String.valueOf(id));
         openingLine.setAttribute(ContextData.IS_MODIFIED_PROPERTY_XML_TAG, isModified);
@@ -717,8 +691,7 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * @param contextAttributes
-     *            The contextAttributes to set.
+     * @param contextAttributes The contextAttributes to set.
      */
     public void setContextAttributes(final ContextAttributes contextAttributes) {
         this.contextAttributes = contextAttributes;
@@ -735,8 +708,7 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * @param contextData
-     *            The contextData to set.
+     * @param contextData The contextData to set.
      */
     public void setContextData(final ContextData contextData) {
         this.contextData = contextData;
@@ -750,8 +722,7 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * @param snapshots
-     *            The snapshots to set.
+     * @param snapshots The snapshots to set.
      */
     public void setSnapshots(final Snapshot[] snapshots) {
         this.snapshots = snapshots;
@@ -948,8 +919,7 @@ public class Context implements Comparable<Context> {
     }
 
     /**
-     * @param isModified
-     *            The isModified to set.
+     * @param isModified The isModified to set.
      */
     public void setModified(final boolean isModified) {
         this.isModified = isModified;
diff --git a/src/main/java/fr/soleil/bensikin/data/context/ContextData.java b/src/main/java/fr/soleil/bensikin/data/context/ContextData.java
index 58366f0..8fb217f 100644
--- a/src/main/java/fr/soleil/bensikin/data/context/ContextData.java
+++ b/src/main/java/fr/soleil/bensikin/data/context/ContextData.java
@@ -38,6 +38,7 @@ import fr.soleil.bensikin.components.BensikinMenuBar;
 import fr.soleil.bensikin.components.context.detail.IDTextField;
 import fr.soleil.bensikin.containers.context.ContextActionPanel;
 import fr.soleil.bensikin.containers.context.ContextDataPanel;
+import fr.soleil.lib.project.ObjectUtils;
 
 /**
  * Represents the non-attribute dependant informations attached to a context
@@ -49,10 +50,10 @@ public class ContextData implements Comparable<ContextData> {
 
     private int id;
     private Date creationDate = null;
-    private String name = "";
-    private String authorName = "";
-    private String reason = "";
-    private String description = "";
+    private String name = ObjectUtils.EMPTY_STRING;
+    private String authorName = ObjectUtils.EMPTY_STRING;
+    private String reason = ObjectUtils.EMPTY_STRING;
+    private String description = ObjectUtils.EMPTY_STRING;
 
     private String path = null;
 
@@ -137,12 +138,9 @@ public class ContextData implements Comparable<ContextData> {
     public void push() {
         ContextDataPanel contextDataPanel = ContextDataPanel.getInstance();
 
-        IDTextField idField = contextDataPanel.getIDField();
-        String id_s = this.getId() == -1 ? "" : String.valueOf(this.getId());
-        idField.setText(id_s);
-
         JTextField timeField = contextDataPanel.getCreationDateField();
-        String creation_date_s = this.getCreationDate() == null ? "" : this.getCreationDate().toString();
+        String creation_date_s = this.getCreationDate() == null ? ObjectUtils.EMPTY_STRING
+                : this.getCreationDate().toString();
         timeField.setText(creation_date_s);
 
         JTextField nameField = contextDataPanel.getNameField();
@@ -164,9 +162,14 @@ public class ContextData implements Comparable<ContextData> {
         if (!descriptionField.getText().equals(this.getName())) {
             descriptionField.setText(this.getDescription());
         }
+
+        // Update ID at end to ensure SelectedContextListener disables "register context" action (TANGOARCH-629)
+        IDTextField idField = contextDataPanel.getIDField();
+        String id_s = this.getId() == -1 ? ObjectUtils.EMPTY_STRING : String.valueOf(this.getId());
+        idField.setText(id_s);
+
         BensikinMenuBar.getInstance().updateRegisterItem();
         ContextActionPanel.getInstance().updateRegisterButton();
-
     }
 
     /**
diff --git a/src/main/java/fr/soleil/bensikin/data/snapshot/SnapshotAttributeValue.java b/src/main/java/fr/soleil/bensikin/data/snapshot/SnapshotAttributeValue.java
index dacbc4b..da8adeb 100644
--- a/src/main/java/fr/soleil/bensikin/data/snapshot/SnapshotAttributeValue.java
+++ b/src/main/java/fr/soleil/bensikin/data/snapshot/SnapshotAttributeValue.java
@@ -93,6 +93,10 @@ import fr.soleil.lib.project.math.MathConst;
  * @author CLAISSE
  */
 public class SnapshotAttributeValue {
+
+    private static final String NULL = "null";
+    private static final String TRUE = "true";
+
     protected int dataFormat;
     protected int dataType;
 
@@ -490,7 +494,7 @@ public class SnapshotAttributeValue {
                                 final String[] strArray = new String[length];
                                 for (int i = 0; i < length; i++) {
                                     String token = tokenizer.nextToken();
-                                    if ("".equals(token) || "null".equals(token)) {
+                                    if (token.isEmpty() || NULL.equals(token)) {
                                         strArray[i] = null;
                                     } else {
                                         strArray[i] = token;
@@ -505,7 +509,7 @@ public class SnapshotAttributeValue {
                                 final double[] dbArray = new double[length];
                                 for (int i = 0; i < length; i++) {
                                     String token = tokenizer.nextToken();
-                                    if ("".equals(token) || "null".equals(token)) {
+                                    if (token.isEmpty() || NULL.equals(token)) {
                                         dbArray[i] = MathConst.NAN_FOR_NULL;
                                         nullElementsArray[i] = true;
                                     } else {
@@ -522,7 +526,7 @@ public class SnapshotAttributeValue {
                                 final float[] flArray = new float[length];
                                 for (int i = 0; i < length; i++) {
                                     String token = tokenizer.nextToken();
-                                    if ("".equals(token) || "null".equals(token)) {
+                                    if (token.isEmpty() || NULL.equals(token)) {
                                         flArray[i] = Float.NaN;
                                         nullElementsArray[i] = true;
                                     } else {
@@ -540,7 +544,7 @@ public class SnapshotAttributeValue {
                                 final short[] shArray = new short[length];
                                 for (int i = 0; i < length; i++) {
                                     String token = tokenizer.nextToken();
-                                    if ("".equals(token) || "null".equals(token)) {
+                                    if (token.isEmpty() || NULL.equals(token)) {
                                         shArray[i] = 0;
                                         nullElementsArray[i] = true;
                                     } else {
@@ -560,7 +564,7 @@ public class SnapshotAttributeValue {
                                 final int[] intArray = new int[length];
                                 for (int i = 0; i < length; i++) {
                                     String token = tokenizer.nextToken();
-                                    if ("".equals(token) || "null".equals(token)) {
+                                    if (token.isEmpty() || NULL.equals(token)) {
                                         intArray[i] = 0;
                                         nullElementsArray[i] = true;
                                     } else {
@@ -577,11 +581,11 @@ public class SnapshotAttributeValue {
                                 final boolean[] boolArray = new boolean[length];
                                 for (int i = 0; i < length; i++) {
                                     String token = tokenizer.nextToken();
-                                    if ("".equals(token) || "null".equals(token)) {
+                                    if (token.isEmpty() || NULL.equals(token)) {
                                         boolArray[i] = false;
                                         nullElementsArray[i] = true;
                                     } else {
-                                        boolArray[i] = "true".equalsIgnoreCase(token);
+                                        boolArray[i] = TRUE.equalsIgnoreCase(token);
                                     }
                                 }
                                 this.spectrumValue = boolArray;
diff --git a/src/main/java/fr/soleil/bensikin/impl/TangoManagerImpl.java b/src/main/java/fr/soleil/bensikin/impl/TangoManagerImpl.java
index 7ad715b..7f256ee 100644
--- a/src/main/java/fr/soleil/bensikin/impl/TangoManagerImpl.java
+++ b/src/main/java/fr/soleil/bensikin/impl/TangoManagerImpl.java
@@ -38,6 +38,7 @@ import java.util.List;
 import fr.esrf.Tango.DevFailed;
 import fr.esrf.TangoApi.DeviceData;
 import fr.esrf.TangoApi.DeviceProxy;
+import fr.esrf.TangoApi.DeviceProxyFactory;
 import fr.soleil.archiving.gui.tools.GUIUtilities;
 import fr.soleil.archiving.tango.TangoLoaderUtil;
 import fr.soleil.archiving.tango.entity.Domain;
@@ -80,9 +81,9 @@ public class TangoManagerImpl implements ITangoManager {
      */
     @Override
     public List<String> dbGetAttributeList(final String device_name) {
-        List<String> liste_att = new ArrayList<String>(32);
+        List<String> liste_att = new ArrayList<>(32);
         try {
-            final DeviceProxy deviceProxy = new DeviceProxy(device_name);
+            final DeviceProxy deviceProxy = DeviceProxyFactory.get(device_name);
             deviceProxy.ping();
             final DeviceData device_data_argin = new DeviceData();
             String[] device_data_argout;
diff --git a/src/main/java/fr/soleil/bensikin/models/AttributesTreeModel.java b/src/main/java/fr/soleil/bensikin/models/AttributesTreeModel.java
index 588d3be..6fc09bc 100644
--- a/src/main/java/fr/soleil/bensikin/models/AttributesTreeModel.java
+++ b/src/main/java/fr/soleil/bensikin/models/AttributesTreeModel.java
@@ -54,9 +54,8 @@ import fr.soleil.archiving.tango.entity.ui.comparator.EntitiesComparator;
 import fr.soleil.bensikin.data.context.ContextAttribute;
 
 /**
- * The mother class of all tree models of the application. It implements methods
- * to add/get atributes, and keeps track of the current attributes in a
- * Map, which keys are the attributes paths. A Map
+ * The mother class of all tree models of the application. It implements methods to add/get attributes, and keeps track
+ * of the current attributes in a Map, which keys are the attributes paths. A Map
  * 
  * @author CLAISSE
  */
@@ -97,7 +96,7 @@ public class AttributesTreeModel extends DefaultTreeModel {
      */
     public AttributesTreeModel() {
         super(findRootInSystemProperties());
-        attributesHT = new TreeMap<String, ContextAttribute>(Collator.getInstance());
+        attributesHT = new TreeMap<>(Collator.getInstance());
     }
 
     /**
@@ -109,74 +108,68 @@ public class AttributesTreeModel extends DefaultTreeModel {
      * <LI>For each Member, adds all of its Attributes nodes (provided the attributes have been loaded yet)
      * </UL>
      * 
-     * @param _domains
-     *            The Domains to display
+     * @param domains The Domains to display
      */
-    public void build(final List<Domain> _domains) {
-        attributesHT = new TreeMap<String, ContextAttribute>(Collator.getInstance());
-        domains = _domains;
-
-        if (_domains == null) {
-            return;
-        }
-        Collections.sort(_domains, new EntitiesComparator());
-
-        for (int domainIndex = 0; domainIndex < _domains.size(); domainIndex++) {
-            // START CURRENT DOMAIN
-            final Domain domain = _domains.get(domainIndex);
-            final DefaultMutableTreeNode domainNode = new DefaultMutableTreeNode(domain.getName());
-
-            ((DefaultMutableTreeNode) getRoot()).add(domainNode);
-
-            final List<Family> familiesToSort = new ArrayList<Family>();
-            familiesToSort.addAll(domain.getFamilies().values());
-            Collections.sort(familiesToSort, new EntitiesComparator());
-
-            for (int familyIndex = 0; familyIndex < familiesToSort.size(); familyIndex++) {
-                // START CURRENT FAMILY
-                final Family family = familiesToSort.get(familyIndex);
-                final DefaultMutableTreeNode familyNode = new DefaultMutableTreeNode(family.getName());
-                domainNode.add(familyNode);
-
-                final List<Member> membersToSort = new ArrayList<Member>();
-                membersToSort.addAll(family.getMembers().values());
-                Collections.sort(membersToSort, new EntitiesComparator());
-
-                for (int memberIndex = 0; memberIndex < membersToSort.size(); memberIndex++) {
-                    // START CURRENT MEMBER
-                    final Member member = membersToSort.get(memberIndex);
-                    final DefaultMutableTreeNode memberNode = new DefaultMutableTreeNode(member.getName());
-                    familyNode.add(memberNode);
-
-                    final Collection<Attribute> coll = member.getAttributes().values();
-                    final List<Attribute> attributesToSort = new ArrayList<Attribute>();
-                    attributesToSort.addAll(coll);
-                    Collections.sort(attributesToSort, new EntitiesComparator());
-
-                    for (int attributeIndex = 0; attributeIndex < attributesToSort.size(); attributeIndex++) {
-                        // START CURRENT ATTRIBUTE
-                        final Attribute attribute = attributesToSort.get(attributeIndex);
-                        attribute.setCompleteName(domain.getName() + "/" + family.getName() + "/" + member.getName()
-                                + "/" + attribute.getName());
-                        attribute.setDomain(domain.getName());
-                        attribute.setFamily(family.getName());
-                        attribute.setMember(member.getName());
-                        attribute.setDevice(member.getName());
-
-                        final DefaultMutableTreeNode attributeNode = new DefaultMutableTreeNode(attribute.getName());
-                        memberNode.add(attributeNode);
-                        if (attribute instanceof ContextAttribute) {
-                            addAttribute(attributeNode.getPath(), (ContextAttribute) attribute);
-                        } else {
-                            addAttribute(attributeNode.getPath(), new ContextAttribute(attribute));
+    public void build(final List<Domain> domains) {
+        this.attributesHT = new TreeMap<>(Collator.getInstance());
+        this.domains = domains;
+        if (domains != null) {
+            Collections.sort(domains, new EntitiesComparator());
+
+            for (Domain domain : domains) {
+                // START CURRENT DOMAIN
+                final DefaultMutableTreeNode domainNode = new DefaultMutableTreeNode(domain.getName());
+
+                ((DefaultMutableTreeNode) getRoot()).add(domainNode);
+
+                final List<Family> familiesToSort = new ArrayList<Family>();
+                familiesToSort.addAll(domain.getFamilies().values());
+                Collections.sort(familiesToSort, new EntitiesComparator());
+
+                for (Family family : familiesToSort) {
+                    // START CURRENT FAMILY
+                    final DefaultMutableTreeNode familyNode = new DefaultMutableTreeNode(family.getName());
+                    domainNode.add(familyNode);
+
+                    final List<Member> membersToSort = new ArrayList<Member>();
+                    membersToSort.addAll(family.getMembers().values());
+                    Collections.sort(membersToSort, new EntitiesComparator());
+
+                    for (Member member : membersToSort) {
+                        // START CURRENT MEMBER
+                        final DefaultMutableTreeNode memberNode = new DefaultMutableTreeNode(member.getName());
+                        familyNode.add(memberNode);
+
+                        final Collection<Attribute> coll = member.getAttributes().values();
+                        final List<Attribute> attributesToSort = new ArrayList<Attribute>();
+                        attributesToSort.addAll(coll);
+                        Collections.sort(attributesToSort, new EntitiesComparator());
+
+                        for (Attribute attribute : attributesToSort) {
+                            // START CURRENT ATTRIBUTE
+                            attribute.setCompleteName(domain.getName() + "/" + family.getName() + "/" + member.getName()
+                                    + "/" + attribute.getName());
+                            attribute.setDomain(domain.getName());
+                            attribute.setFamily(family.getName());
+                            attribute.setMember(member.getName());
+                            attribute.setDevice(member.getName());
+
+                            final DefaultMutableTreeNode attributeNode = new DefaultMutableTreeNode(
+                                    attribute.getName());
+                            memberNode.add(attributeNode);
+                            if (attribute instanceof ContextAttribute) {
+                                addAttribute(attributeNode.getPath(), (ContextAttribute) attribute);
+                            } else {
+                                addAttribute(attributeNode.getPath(), new ContextAttribute(attribute));
+                            }
+                            // END CURRENT ATTRIBUTE
                         }
-                        // END CURRENT ATTRIBUTE
+                        // END CURRENT MEMBER
                     }
-                    // END CURRENT MEMBER
+                    // END CURRENT FAMILY
                 }
-                // END CURRENT FAMILY
+                // END CURRENT DOMAIN
             }
-            // END CURRENT DOMAIN
         }
     }
 
@@ -196,9 +189,7 @@ public class AttributesTreeModel extends DefaultTreeModel {
     /**
      * Returns the attribute located at a given path in the tree.
      * 
-     * @param key
-     *            The String representations of the path of the desired
-     *            attribute
+     * @param key The String representations of the path of the desired attribute
      * @return The attribute at this path in the tree
      */
     public ContextAttribute getAttribute(final String key) {
@@ -224,11 +215,9 @@ public class AttributesTreeModel extends DefaultTreeModel {
     }
 
     /**
-     * Returns the String representation of the given path, usable as key in the
-     * attributes Map.
+     * Returns the String representation of the given path, usable as key in the attributes Map.
      * 
-     * @param path
-     *            The path to convert
+     * @param path The path to convert
      * @return The String representation of the given path
      */
     public static String translatePathIntoKey(final TreeNode[] path) {
@@ -269,7 +258,7 @@ public class AttributesTreeModel extends DefaultTreeModel {
     public void removeAll() {
         final DefaultMutableTreeNode root = (DefaultMutableTreeNode) getRoot();
         final String name = (String) root.getUserObject();
-        attributesHT = new TreeMap<String, ContextAttribute>(Collator.getInstance());
+        attributesHT = new TreeMap<>(Collator.getInstance());
         setRoot(new DefaultMutableTreeNode(name));
     }
 }
diff --git a/src/main/java/fr/soleil/bensikin/models/ContextAttributesTreeModel.java b/src/main/java/fr/soleil/bensikin/models/ContextAttributesTreeModel.java
index 1c04e8d..dbce6c2 100644
--- a/src/main/java/fr/soleil/bensikin/models/ContextAttributesTreeModel.java
+++ b/src/main/java/fr/soleil/bensikin/models/ContextAttributesTreeModel.java
@@ -56,12 +56,14 @@ import javax.swing.tree.TreeNode;
 import javax.swing.tree.TreePath;
 
 import fr.soleil.archiving.gui.tools.GUIUtilities;
+import fr.soleil.archiving.tango.entity.Domain;
 import fr.soleil.archiving.tango.entity.model.AttributesSelectTableModel;
 import fr.soleil.bensikin.comparators.BensikinToStringObjectComparator;
 import fr.soleil.bensikin.components.context.detail.ContextAttributesTree;
 import fr.soleil.bensikin.components.context.detail.PossibleAttributesTree;
 import fr.soleil.bensikin.containers.context.ContextDetailPanel;
 import fr.soleil.bensikin.data.context.ContextAttribute;
+import fr.soleil.lib.project.ObjectUtils;
 
 /**
  * A daughter of AttributesTreeModel representing the attributes of the current
@@ -75,16 +77,22 @@ import fr.soleil.bensikin.data.context.ContextAttribute;
  */
 public class ContextAttributesTreeModel extends AttributesTreeModel {
 
-    private static final long serialVersionUID = -326464997002976108L;
+    private static final long serialVersionUID = 7973888977887098597L;
 
-    private ContextAttributesTree contextAttributesTreeInstance = null;
     private static ContextAttributesTreeModel instance = null;
+    private ContextAttributesTree contextAttributesTreeInstance;
+
+    // boolean useful to know whether attribute list did change, which means a new Context should be created in database
+    // (TANGOARCH-629)
+    private boolean attributeListChanged;
 
     /**
      * Calls mother constructor
      */
     private ContextAttributesTreeModel() {
         super();
+        contextAttributesTreeInstance = null;
+        attributeListChanged = true;
     }
 
     /**
@@ -130,7 +138,7 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
             possibleAttr = null;
         }
 
-        TreeMap<String, ContextAttribute> htAttr = this.getAttributes();
+        TreeMap<String, ContextAttribute> htAttr = getAttributes();
 
         for (TreePath aPath : validSelected) {
             // START CURRENT SELECTED PATH
@@ -165,13 +173,16 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
                     if (depth == CONTEXT_TREE_DEPTH - 1) {
                         TreeNode[] path = newChild.getPath();
 
-                        ContextAttribute attribute = (possibleAttr == null) ? null : (ContextAttribute) possibleAttr
-                                .get(translatePathIntoKey(path));
+                        ContextAttribute attribute = (possibleAttr == null) ? null
+                                : (ContextAttribute) possibleAttr.get(translatePathIntoKey(path));
                         if (attribute == null) {
                             attribute = new ContextAttribute(path);
                         }
 
-                        htAttr.put(translatePathIntoKey(path), attribute);
+                        ContextAttribute old = htAttr.put(translatePathIntoKey(path), attribute);
+                        if (!ObjectUtils.sameObject(old, attribute)) {
+                            attributeListChanged = true;
+                        }
 
                         // ----------------
                         if (contextAttributesTreeInstance != null) {
@@ -186,7 +197,7 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
                 }
             }
         }
-        super.attributesHT = htAttr;
+        attributesHT = htAttr;
         if (updateTableToo) {
             Collection<ContextAttribute> values = getAttributes().values();
             ContextAttribute[] attrArray = values.toArray(new ContextAttribute[values.size()]);
@@ -200,10 +211,9 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
             AttributesSelectTableModel attributesSelectTableModel = ContextDetailPanel.getInstance()
                     .getAttributeTableSelectionBean().getSelectionPanel().getAttributesSelectTable().getModel();
 
-            TreeMap<String, ContextAttribute> htAttr = this.getAttributes();
+            TreeMap<String, ContextAttribute> htAttr = getAttributes();
 
-            for (int attrIndex = 0; attrIndex < attributesToAdd.length; attrIndex++) {
-                ContextAttribute attribute = attributesToAdd[attrIndex];
+            for (ContextAttribute attribute : attributesToAdd) {
                 if (attribute != null) {
                     TreePath aPath = attribute.getTreePath();
 
@@ -218,7 +228,7 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
                         }
 
                         int numOfChildren = this.getChildCount(currentTreeObject);
-                        List<String> vect = new ArrayList<String>();
+                        List<String> vect = new ArrayList<>();
                         for (int childIndex = 0; childIndex < numOfChildren; childIndex++) {
                             Object childAt = this.getChild(currentTreeObject, childIndex);
                             vect.add(childAt.toString());
@@ -237,7 +247,10 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
                             if (depth == CONTEXT_TREE_DEPTH - 1) {
                                 TreeNode[] path = newChild.getPath();
 
-                                htAttr.put(translatePathIntoKey(path), attribute);
+                                ContextAttribute old = htAttr.put(translatePathIntoKey(path), attribute);
+                                if (!ObjectUtils.sameObject(old, attribute)) {
+                                    attributeListChanged = true;
+                                }
 
                                 // ----------------
                                 if (contextAttributesTreeInstance != null) {
@@ -265,9 +278,7 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
     /**
      * Removes a list of attributes from the model.
      * 
-     * @param validSelected
-     *            A list of TreePath references to the attributes that are to be
-     *            removed
+     * @param validSelected A list of TreePath references to the attributes that should be removed
      */
     public void removeSelectedAttributes(Collection<TreePath> validSelected) {
         AttributesSelectTableModel attributesSelectTableModel = ContextDetailPanel.getInstance()
@@ -285,7 +296,9 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
              * attributesSelectTableModel.r
              */
             // to do global remove
-            this.getAttributes().remove(key);
+            if (getAttributes().remove(key) != null) {
+                attributeListChanged = true;
+            }
             try {
                 this.removeNodeFromParent(node);
             } catch (Exception e) {
@@ -299,19 +312,25 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
         attributesSelectTableModel.setRows(attrArray);
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see bensikin.bensikin.models.AttributesTreeModel#getTreeAttributes()
-     */
     @Override
-    public Collection<String> getTreeAttributes() {
-        return super.getTreeAttributes();
+    public void build(List<Domain> domains) {
+        super.build(domains);
+        attributeListChanged = false;
     }
 
     @Override
     public void removeAll() {
         super.removeAll();
+        attributeListChanged = true;
+    }
+
+    /**
+     * Returns whether attribute list did change.
+     * 
+     * @return A <code>boolean</code>.
+     */
+    public boolean isAttributeListChanged() {
+        return attributeListChanged;
     }
 
     /**
@@ -357,7 +376,9 @@ public class ContextAttributesTreeModel extends AttributesTreeModel {
             // System.out.println ( "before/"+this.getAttributes
             // ().size()+"/translatePathIntoKey ( path )|"+translatePathIntoKey
             // ( path )+"|" );
-            this.getAttributes().remove(translatePathIntoKey(path));
+            if (getAttributes().remove(translatePathIntoKey(path)) != null) {
+                attributeListChanged = true;
+            }
             // System.out.println ( "after/"+this.getAttributes ().size() );
         }
     }
diff --git a/src/main/java/fr/soleil/bensikin/models/listeners/PossibleAttributesTreeSelectionListener.java b/src/main/java/fr/soleil/bensikin/models/listeners/PossibleAttributesTreeSelectionListener.java
index bd08167..4a62cb7 100644
--- a/src/main/java/fr/soleil/bensikin/models/listeners/PossibleAttributesTreeSelectionListener.java
+++ b/src/main/java/fr/soleil/bensikin/models/listeners/PossibleAttributesTreeSelectionListener.java
@@ -46,11 +46,10 @@ import fr.soleil.bensikin.models.PossibleAttributesTreeModel;
 /**
  * Listens to selection events on the PossibleAttributesTree instance.
  * <UL>
- * <LI>If the event is on any node other than a Member node, nothing happens
- * <LI>If the event is on a Member node which attributes are already loaded,
- * nothing happens
- * <LI>Otherwise, that is in the case of a yet unloaded Member node, the
- * attributes are loaded, and the tree model refreshed
+ * <LI>If the event is on any node other than a Member node, nothing happens</LI>
+ * <LI>If the event is on a Member node which attributes are already loaded, nothing happens</LI>
+ * <LI>Otherwise, that is in the case of a yet unloaded Member node, the attributes are loaded, and the tree model
+ * refreshed</LI>
  * </UL>
  * 
  * @author CLAISSE
@@ -59,38 +58,23 @@ public class PossibleAttributesTreeSelectionListener implements TreeSelectionLis
     private static DefaultMutableTreeNode currentNode;
     private static PossibleAttributesTreeModel model;
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event
-     * .TreeSelectionEvent)
-     */
     @Override
     public void valueChanged(TreeSelectionEvent event) {
         PossibleAttributesTree tree = (PossibleAttributesTree) event.getSource();
         DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
         model = (PossibleAttributesTreeModel) tree.getModel();
-        if (node == null) {
-            return;
+        if ((node != null) && node.isLeaf()) {
+            currentNode = node;
+            query(node.toString(), node.getLevel());
         }
-        if (!node.isLeaf()) {
-            return;
-        }
-
-        currentNode = node;
-        query(node.toString(), node.getLevel());
     }
 
     /**
-     * Called whenever a Member node's attributes needs to be loaded. Uses the
-     * current implementation of <code>ITangoManager</code> to load them.
+     * Called whenever a Member node's attributes needs to be loaded. Uses the current implementation of
+     * <code>ITangoManager</code> to load them.
      * 
-     * @param node
-     *            The String representation of the member node to load
-     *            attributes for
-     * @param level
-     *            The node level
+     * @param node The String representation of the member node to load attributes for
+     * @param level The node level
      */
     private void query(String node, int level) {
         if (level == 3) {
diff --git a/src/main/java/fr/soleil/bensikin/options/sub/SnapshotOptions.java b/src/main/java/fr/soleil/bensikin/options/sub/SnapshotOptions.java
index fef3cec..45374e5 100644
--- a/src/main/java/fr/soleil/bensikin/options/sub/SnapshotOptions.java
+++ b/src/main/java/fr/soleil/bensikin/options/sub/SnapshotOptions.java
@@ -428,16 +428,16 @@ public class SnapshotOptions extends ReadWriteOptionBook implements PushPullOpti
             // LifeCycleManager lifeCycleManager =
             // LifeCycleManagerFactory.getCurrentImpl();
             switch (val) {
-            case SNAPSHOT_AUTO_COMMENT_YES:
-                String snapshotDefaultComment = this.content.get(SNAPSHOT_DEFAULT_COMMENT);
-                Snapshot.setSnapshotDefaultComment(snapshotDefaultComment);
-                OptionsSnapshotTab snapshotTab = OptionsSnapshotTab.getInstance();
-                snapshotTab.setSnapshotDefaultComment(snapshotDefaultComment);
-                break;
-
-            case SNAPSHOT_AUTO_COMMENT_NO:
-                Snapshot.setSnapshotDefaultComment(null);
-                break;
+                case SNAPSHOT_AUTO_COMMENT_YES:
+                    String snapshotDefaultComment = this.content.get(SNAPSHOT_DEFAULT_COMMENT);
+                    Snapshot.setSnapshotDefaultComment(snapshotDefaultComment);
+                    OptionsSnapshotTab snapshotTab = OptionsSnapshotTab.getInstance();
+                    snapshotTab.setSnapshotDefaultComment(snapshotDefaultComment);
+                    break;
+
+                case SNAPSHOT_AUTO_COMMENT_NO:
+                    Snapshot.setSnapshotDefaultComment(null);
+                    break;
             }
         }
 
@@ -815,12 +815,12 @@ public class SnapshotOptions extends ReadWriteOptionBook implements PushPullOpti
     }
 
     private int[] stringToIntArray(String toArray, int defaultValue, int[] defaultResult) {
-
-        if (toArray == null || "".equals(toArray.trim())) {
-            return defaultResult;
+        int[] result;
+        if (toArray == null || toArray.trim().isEmpty()) {
+            result = defaultResult;
         } else {
             String[] array = toArray.split(";");
-            int[] result = new int[array.length];
+            result = new int[array.length];
             for (int i = 0; i < array.length; i++) {
                 try {
                     result[i] = Integer.parseInt(array[i]);
@@ -829,8 +829,8 @@ public class SnapshotOptions extends ReadWriteOptionBook implements PushPullOpti
                 }
             }
             array = null;
-            return result;
         }
+        return result;
     }
 
 }
diff --git a/src/main/java/fr/soleil/bensikin/xml/BensikinXMLLine.java b/src/main/java/fr/soleil/bensikin/xml/BensikinXMLLine.java
index 4837e2a..ddd186f 100644
--- a/src/main/java/fr/soleil/bensikin/xml/BensikinXMLLine.java
+++ b/src/main/java/fr/soleil/bensikin/xml/BensikinXMLLine.java
@@ -119,7 +119,7 @@ public class BensikinXMLLine extends XMLLine {
         String label = this.getLabel();
 
         String itemName;
-        if (label != null && !label.trim().equals("")) {
+        if (label != null && !label.trim().isEmpty()) {
             itemName = label + " (" + id + ")";
         } else {
             itemName = id;
-- 
GitLab