Index: trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/feature/impl/DefaultFeatureReference.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/feature/impl/DefaultFeatureReference.java	(revision 44487)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/feature/impl/DefaultFeatureReference.java	(revision 44488)
@@ -27,6 +27,7 @@
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.List;
+import java.util.Objects;
 import org.apache.commons.lang3.ArrayUtils;
 
 import org.gvsig.fmap.dal.exception.DataException;
@@ -259,7 +260,7 @@
 			StringBuilder buff = new StringBuilder();
 
 			for (int i = 0; i < this.pk.length; i++) {
-				buff.append(this.pk[i].hashCode());
+				buff.append(Objects.hashCode(this.pk[i]));
 				buff.append("##");
 			}
 			myHashCode = buff.toString().hashCode();
Index: trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/feature/paging/impl/FeaturePagingHelperImpl.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/feature/paging/impl/FeaturePagingHelperImpl.java	(revision 44487)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/feature/paging/impl/FeaturePagingHelperImpl.java	(revision 44488)
@@ -612,6 +612,28 @@
 
         reloadCurrentPage();
     }
+    
+    public boolean isEmpty() {
+        try {
+            return getFeatureSet(false).isEmpty();
+        } catch (ConcurrentDataModificationException ex) {
+            LOG.warn("ConcurrentDataModification error asking about the emptiness of the list. Retrying reloading data.");
+            try {
+                reload();
+            } catch (BaseException e) {
+                LOG.warn("Error reloading data.", e);
+                throw new RuntimeException(e);
+            }
+            try {
+                return getFeatureSet(false).isEmpty();
+            } catch (DataException e) {
+                LOG.warn("Error asking about the emptiness of the list after reloading data.",e);
+                throw new RuntimeException(e);
+            }
+        } catch (DataException ex) {
+            throw  new RuntimeException(ex);
+        }
+    }
 
     public void update(EditableFeature feature) throws BaseException {
     	featureStore.update(feature);
Index: trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.swing/org.gvsig.fmap.dal.swing.impl/src/main/java/org/gvsig/featureform/swing/impl/DefaultJFeaturesForm.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.swing/org.gvsig.fmap.dal.swing.impl/src/main/java/org/gvsig/featureform/swing/impl/DefaultJFeaturesForm.java	(revision 44487)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.swing/org.gvsig.fmap.dal.swing.impl/src/main/java/org/gvsig/featureform/swing/impl/DefaultJFeaturesForm.java	(revision 44488)
@@ -76,6 +76,11 @@
 import org.gvsig.tools.dynform.DynFormManager;
 import org.gvsig.tools.dynform.JDynForm;
 import org.gvsig.tools.dynform.JDynFormSet;
+import static org.gvsig.tools.dynform.JDynFormSet.ACTION_CANCEL_NEW;
+import static org.gvsig.tools.dynform.JDynFormSet.ACTION_DELETE;
+import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NEW;
+import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
+import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SEARCH;
 import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
 import org.gvsig.tools.dynobject.DynClass;
 import org.gvsig.tools.dynobject.DynObject;
@@ -102,6 +107,10 @@
 @SuppressWarnings("UseSpecificCatch")
 public class DefaultJFeaturesForm implements JFeaturesForm {
 
+    private final String STARTEDITING_ACTION = "startEditing";
+    private final String FINISHEDITING_ACTION = "finishEditing";
+
+
     public class DefaultFeaturesFormContext implements FeaturesFormContext {
 
         private DefaultFeaturesFormContext() {
@@ -196,7 +205,7 @@
     private JPanel panel;
     private JDynFormSet formset;
     private FeatureStore store;
-    private FeaturePagingHelper ph;
+    private FeaturePagingHelper features;
     private DynFormDefinition definition = null;
     private FeatureQuery currentQuery;
     private List<Action> otherActions;
@@ -225,16 +234,17 @@
             if( this.currentQuery!=null ) {
                 this.currentQuery.retrievesAllAttributes();
             }
-            this.ph = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
-            this.formset.setValues(ph.asListOfDynObjects());
+            this.features = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
+            this.formset.setValues(features.asListOfDynObjects());
         } catch (Exception ex) {
             throw new RuntimeException("Can't update form", ex);
         }
+        updateButtonEnabledStatus();
     }
 
     @Override
     public JComponent asJComponent() {
-        if (this.ph == null) {
+        if (this.features == null) {
             try {
                 updateForm();
             } catch (Exception ex) {
@@ -270,7 +280,7 @@
         }
         this.store = store;
         DisposeUtils.bind(store);
-        this.ph = null;
+        this.features = null;
     }
 
     private void doDispose() {
@@ -278,7 +288,7 @@
         this.store = null;
         this.panel = null;
         this.formset = null;
-        this.ph = null;
+        this.features = null;
         this.definition = null;
         this.currentQuery = null;
         this.otherActions = null;
@@ -324,19 +334,7 @@
 
             this.formset.addListener(new FormSetListener());
         }
-        if( this.store.isEditing() ) {
-//            this.formset.setReadOnly(false);
-            formset.setActionVisible("startEditing", false);
-            formset.setActionEnabled("startEditing", false);
-            formset.setActionVisible("finishEditing", true);
-            formset.setActionEnabled("finishEditing", true);
-        } else {
-//            this.formset.setReadOnly(true);
-            formset.setActionVisible("startEditing", true);
-            formset.setActionEnabled("startEditing", true);
-            formset.setActionVisible("finishEditing", false);
-            formset.setActionEnabled("finishEditing", false);
-        }
+        updateButtonEnabledStatus();
         return this.formset;
     }
 
@@ -358,11 +356,11 @@
 
     @Override
     public Feature get(long index) {
-        if( this.formset==null || this.ph==null ) {
+        if( this.formset==null || this.features==null ) {
             return null;
         }
         try {
-            return this.ph.getFeatureAt(index);
+            return this.features.getFeatureAt(index);
         } catch (BaseException ex) {
             return null;
         }
@@ -378,7 +376,7 @@
             this.putValue(NAME,null);
             this.putValue(SHORT_DESCRIPTION,i18nManager.getTranslation("_Stop_editing"));
             this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
-            this.putValue(ACTION_COMMAND_KEY, "finishEditing");
+            this.putValue(ACTION_COMMAND_KEY, FINISHEDITING_ACTION);
 
             this.setEnabled(store.isEditing());
             store.addObserver(this);
@@ -410,6 +408,7 @@
                     LOGGER.warn("Can't finish editing in FeatureForm ("+store.getName()+").",ex);
                 }
             }
+            updateButtonEnabledStatus();
         }
 
         @Override
@@ -423,22 +422,14 @@
                     case FeatureStoreNotification.AFTER_STARTEDITING:
                     case FeatureStoreNotification.AFTER_FINISHEDITING:
                     case FeatureStoreNotification.AFTER_CANCELEDITING:
-                        if( store.isEditing() ) {
-                            formset.setReadOnly(false);
-                            formset.setActionVisible("finishEditing", true);
-                            formset.setActionEnabled("finishEditing", true);
-                        } else {
-                            formset.setReadOnly(true);
-                            formset.setActionVisible("finishEditing", false);
-                            formset.setActionEnabled("finishEditing", false);
-                        }
+                        updateButtonEnabledStatus();
                         break;
                 }
             }
         }
 
     }
-
+    
     private class StartEditingAction extends AbstractAction implements Observer {
 
         @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
@@ -449,7 +440,7 @@
             this.putValue(NAME,null);
             this.putValue(SHORT_DESCRIPTION,i18nManager.getTranslation("_Start_editing"));
             this.putValue(SMALL_ICON, iconTheme.get("table-start-editing"));
-            this.putValue(ACTION_COMMAND_KEY, "startEditing");
+            this.putValue(ACTION_COMMAND_KEY, STARTEDITING_ACTION);
 
             this.setEnabled(!store.isEditing());
             store.addObserver(this);
@@ -464,6 +455,7 @@
                     LOGGER.warn("Can't finish editing in FeatureForm ("+store.getName()+").",ex);
                 }
             }
+            updateButtonEnabledStatus();
         }
 
         @Override
@@ -477,15 +469,7 @@
                     case FeatureStoreNotification.AFTER_STARTEDITING:
                     case FeatureStoreNotification.AFTER_FINISHEDITING:
                     case FeatureStoreNotification.AFTER_CANCELEDITING:
-                        if( store.isEditing() ) {
-                            formset.setReadOnly(false);
-                            formset.setActionVisible("startEditing", false);
-                            formset.setActionEnabled("startEditing", false);
-                        } else {
-                            formset.setReadOnly(true);
-                            formset.setActionVisible("startEditing", true);
-                            formset.setActionEnabled("startEditing", true);
-                        }
+                        updateButtonEnabledStatus();
                         break;
                 }
             }
@@ -495,7 +479,7 @@
 
     @Override
     public void setQuery(FeatureQuery query) {
-        if (this.ph != null) {
+        if (this.features != null) {
             if (this.formset != null && !formset.isReadOnly() && this.formset.isAutosave() && this.formset.countValues() > 0) {
                 if (!store.isEditing()) {
                     try {
@@ -523,47 +507,34 @@
         winmgr.showWindow(this.asJComponent(), title, mode);
     }
 
-    private void saveChanges(JDynFormSet dynformSet) {
+    private void saveChanges(JDynFormSet theFormSet) {
         I18nManager i18n = ToolsLocator.getI18nManager();
-        if( dynformSet.isInNewState() ) {
-            Feature feat = null;
-            try {
-                feat = store.createNewFeature(false);
-            } catch (DataException ex) {
-                LOGGER.warn("Can't create new feature.",ex);
-                I18nManager i18nManager = ToolsLocator.getI18nManager();
-                dynformSet.message(i18nManager.getTranslation("error_saving_data_will_not_save"));
-                throw new RuntimeException("Can't new save values");
+        try {
+            if( theFormSet.isInNewState() ) {
+                Feature newFeature = store.createNewFeature(false);
+                DynObject newElement = newFeature.getAsDynObject();
+                theFormSet.getFormValues(newElement);
+                features.insert(((FacadeOfAFeature)newElement).getEditableFeature());
+                this.formset.message(i18n.getTranslation("_Record_saved"));
+                try {
+                    this.formset.setValues(features.asListOfDynObjects());
+                    this.formset.setCurrentIndex((int)(features.getTotalSize())-1);
+                } catch(Exception ex) {
+                    LOGGER.warn("Can't reload form data after insert.",ex);
+                }
+            } else {
+                int index = theFormSet.getCurrentIndex();
+                DynObject currentElement = theFormSet.get(index);
+                theFormSet.getFormValues(currentElement);
+                features.update(((FacadeOfAFeature)currentElement).getEditableFeature());
+                this.formset.message(i18n.getTranslation("_Record_saved"));
             }
-            DynObject dynObject = feat.getAsDynObject();
-            dynformSet.getFormValues(dynObject);
-            try {
-                ph.insert(((FacadeOfAFeature)dynObject).getEditableFeature());
-            } catch (BaseException e) {
-                throw new RuntimeException("Can't save values", e);
-            }
-            try {
-                this.formset.setValues(ph.asListOfDynObjects());
-                this.formset.setCurrentIndex((int)(ph.getTotalSize())-1);
-            } catch(Exception ex) {
-                LOGGER.warn("Can't reload form data after insert.",ex);
-            }
-            this.formset.message(i18n.getTranslation("_Record_saved"));
-        } else {
-            int index = dynformSet.getCurrentIndex();
-            DynObject dynObject = dynformSet.get(index);
-
-            if ( !(dynObject instanceof FacadeOfAFeature) ) {
-                LOGGER.warn("Can't get the associated feature index " + index);
-                dynformSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
-                throw new RuntimeException("Can't save values");
-            }
-            dynformSet.getFormValues(dynObject);
-            try {
-                ph.update(((FacadeOfAFeature)dynObject).getEditableFeature());
-            } catch (BaseException e) {
-                throw new RuntimeException("Can't save values", e);
-            }
+        } catch(Exception ex) {
+            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
+            throw new RuntimeException("Can't save values",ex);
+            
+        } finally {
+            updateButtonEnabledStatus();
         }
 
     }
@@ -583,10 +554,76 @@
         }
     }
 
+    private void updateButtonEnabledStatus() {
+        if( this.formset == null ) {
+            return;
+        }
+        if( this.store == null || store.isBroken() || store.isAppending() ) {
+            this.formset.setReadOnly(true);
+            formset.setActionVisible(STARTEDITING_ACTION, true);
+            formset.setActionEnabled(STARTEDITING_ACTION, true);
+            formset.setActionVisible(FINISHEDITING_ACTION, false);
+            formset.setActionEnabled(FINISHEDITING_ACTION, false);
+            formset.setActionEnabled(ACTION_DELETE, false);
+            formset.setActionEnabled(ACTION_NEW,false);
+            formset.setActionEnabled(ACTION_CANCEL_NEW,false);
+            formset.setActionEnabled(ACTION_SAVE,false);
+            formset.setActionEnabled(ACTION_SEARCH,false);
+            return;
+        }
+        if( store.isEditing() ) {
+            this.formset.setReadOnly(false);
+            formset.setActionVisible(STARTEDITING_ACTION, false);
+            formset.setActionEnabled(STARTEDITING_ACTION, false);
+            formset.setActionVisible(FINISHEDITING_ACTION, true);
+            formset.setActionEnabled(FINISHEDITING_ACTION, true);
+            if( formset.isInNewState() ) {
+                formset.setActionEnabled(ACTION_DELETE, false);
+                formset.setActionEnabled(ACTION_SEARCH,false);
+                formset.setActionEnabled(ACTION_NEW,false);
+                formset.setActionEnabled(ACTION_CANCEL_NEW,true);
+                formset.setActionEnabled(ACTION_SAVE,true);
+                
+            } else if( this.features.isEmpty() ) {
+                formset.setActionEnabled(ACTION_DELETE, false);
+                formset.setActionEnabled(ACTION_SEARCH,false);
+                formset.setActionEnabled(ACTION_NEW,true);
+                formset.setActionEnabled(ACTION_CANCEL_NEW,true);
+                formset.setActionEnabled(ACTION_SAVE,false);
+
+            } else if( formset.getForm().isModified() ) {
+                formset.setActionEnabled(ACTION_DELETE, true);
+                formset.setActionEnabled(ACTION_SEARCH,true);
+                formset.setActionEnabled(ACTION_NEW,true);
+                formset.setActionEnabled(ACTION_CANCEL_NEW,false);
+                formset.setActionEnabled(ACTION_SAVE,true);
+
+            } else {
+                formset.setActionEnabled(ACTION_DELETE, true);
+                formset.setActionEnabled(ACTION_SEARCH,true);
+                formset.setActionEnabled(ACTION_NEW,true);
+                formset.setActionEnabled(ACTION_CANCEL_NEW,false);
+                formset.setActionEnabled(ACTION_SAVE,true); //false);
+            }
+
+            return;
+        }
+        this.formset.setReadOnly(true);
+        formset.setActionVisible(STARTEDITING_ACTION, true);
+        formset.setActionEnabled(STARTEDITING_ACTION, true);
+        formset.setActionVisible(FINISHEDITING_ACTION, false);
+        formset.setActionEnabled(FINISHEDITING_ACTION, false);
+        formset.setActionEnabled(ACTION_DELETE, false);
+        formset.setActionEnabled(ACTION_NEW,false);
+        formset.setActionEnabled(ACTION_CANCEL_NEW,false);
+        formset.setActionEnabled(ACTION_SAVE,false);
+        formset.setActionEnabled(ACTION_SEARCH,true);
+    }
+        
     @Override
     public long getDataSetSize() {
-        if (this.ph != null) {
-            return ph.getTotalSize();
+        if (this.features != null) {
+            return features.getTotalSize();
         }
         return 0;
     }
@@ -610,44 +647,44 @@
         @Override
         public void formMovedTo(int currentPosition) throws AbortActionException {
             LOGGER.trace("formMovedTo " + currentPosition);
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formBeforeSave");
-            if (!store.isEditing()) {
-                try {
-                    store.edit();
-                } catch (DataException e1) {
-                    throw new StoreEditException(e1, store.getName());
-                }
-            }
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formBeforeNew");
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formBeforeDelete");
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formAfterSave");
             saveChanges(dynformSet);
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formAfterNew");
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formAfterDelete");
+            updateButtonEnabledStatus();
         }
 
 //        @Override
@@ -738,24 +775,26 @@
         @Override
         public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formBeforeCancelNew");
+            updateButtonEnabledStatus();
         }
 
         @Override
         public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
             LOGGER.trace("formAfterCancelNew");
+            updateButtonEnabledStatus();
         }
     }
 
-    private static class StoreEditException extends AbortActionException {
-
-        /**
-         *
-         */
-        private static final long serialVersionUID = -7682017811778577130L;
-
-        public StoreEditException(Throwable cause, String storename) {
-            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
-            setValue("storename", storename);
-        }
-    }
+//    private static class StoreEditException extends AbortActionException {
+//
+//        /**
+//         *
+//         */
+//        private static final long serialVersionUID = -7682017811778577130L;
+//
+//        public StoreEditException(Throwable cause, String storename) {
+//            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
+//            setValue("storename", storename);
+//        }
+//    }
 }
Index: trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.swing/org.gvsig.fmap.dal.swing.impl/src/main/java/org/gvsig/featureform/swing/impl/dynformfield/linkforeingkey/JDynFormFieldForeingKey.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.swing/org.gvsig.fmap.dal.swing.impl/src/main/java/org/gvsig/featureform/swing/impl/dynformfield/linkforeingkey/JDynFormFieldForeingKey.java	(revision 44487)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.swing/org.gvsig.fmap.dal.swing.impl/src/main/java/org/gvsig/featureform/swing/impl/dynformfield/linkforeingkey/JDynFormFieldForeingKey.java	(revision 44488)
@@ -340,6 +340,7 @@
     @Override
     public void setReadOnly(boolean readonly) {
         initComponentIfNeed();
+        this.readOnly = readonly;
         boolean editable = !readonly;
         JComponent jlabel = this.getJLabel();
         if( jlabel !=null ) {
@@ -368,10 +369,6 @@
     }
 
     @Override
-    public void fetch(DynObject container) {
-    }
-
-    @Override
     public boolean hasValidValue() {
         return true;
     }
Index: trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.api/src/main/java/org/gvsig/fmap/dal/feature/paging/FeaturePagingHelper.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.api/src/main/java/org/gvsig/fmap/dal/feature/paging/FeaturePagingHelper.java	(revision 44487)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.api/src/main/java/org/gvsig/fmap/dal/feature/paging/FeaturePagingHelper.java	(revision 44488)
@@ -150,4 +150,5 @@
 
     public void setSelection(FeatureSelection selection);
 
+    public boolean isEmpty();
 }
