Index: trunk/src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 5620)
+++ trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 5621)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.actions.upload.ApiPreconditionCheckerHook;
 import org.openstreetmap.josm.actions.upload.DiscardTagsHook;
+import org.openstreetmap.josm.actions.upload.FixDataHook;
 import org.openstreetmap.josm.actions.upload.RelationUploadOrderHook;
 import org.openstreetmap.josm.actions.upload.UploadHook;
@@ -53,5 +54,14 @@
     private static final LinkedList<UploadHook> lateUploadHooks = new LinkedList<UploadHook>();
     static {
+        /**
+         * Calls validator before upload.
+         */
         uploadHooks.add(new ValidateUploadHook());
+
+        /**
+         * Fixes database errors
+         */
+        uploadHooks.add(new FixDataHook());
+
         /**
          * Checks server capabilities before upload.
Index: trunk/src/org/openstreetmap/josm/actions/upload/FixDataHook.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/upload/FixDataHook.java	(revision 5621)
+++ trunk/src/org/openstreetmap/josm/actions/upload/FixDataHook.java	(revision 5621)
@@ -0,0 +1,200 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.upload;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.APIDataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+
+/**
+ * Fixes defective data entries for all modified objects before upload
+ */
+public class FixDataHook implements UploadHook {
+
+    /**
+     * List of checks to run on data
+     */
+    private List<FixData> deprecated = new LinkedList<FixData>();
+
+    /**
+     * Constructor for data initialization
+     */
+    public FixDataHook () {
+        deprecated.add(new FixDataSpace());
+        deprecated.add(new FixDataKey("color",            "colour"));
+        deprecated.add(new FixDataTag("highway", "ford",  "ford",    "yes"));
+        deprecated.add(new FixDataTag("oneway",  "false", "oneway",  "no"));
+        deprecated.add(new FixDataTag("oneway",  "0",     "oneway",  "no"));
+        deprecated.add(new FixDataTag("oneway",  "true",  "oneway",  "yes"));
+        deprecated.add(new FixDataTag("oneway",  "1",     "oneway",  "yes"));
+        deprecated.add(new FixDataTag("highway", "stile", "barrier", "stile"));
+        deprecated.add(new FixData() {
+            public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
+                if(osm instanceof Relation && keys.get("type").equals("multipolygon") && keys.get("boundary").equals("administrative")) {
+                    keys.put("type", "boundary");
+                    return true;
+                }
+                return false;
+            }
+        });
+    }
+
+    /**
+     * Common set of commands for data fixing
+     */
+    public interface FixData {
+        /**
+         * Checks if data needs to be fixed and change keys
+         *
+         * @param keys list of keys to be modified
+         * @param osm the object for type validation, don't use keys of it!
+         * @return <code>true</code> if keys have been modified
+         */
+        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm);
+    }
+
+    /**
+     * Data fix to remove spaces at begin or end of tags
+     */
+    public class FixDataSpace implements FixData {
+        @Override
+        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
+            boolean changed = false;
+            for(Entry<String, String> e : keys.entrySet()) {
+                String v = e.getValue().trim();
+                String k = e.getKey().trim();
+                if(!e.getKey().equals(k)) {
+                    changed = true;
+                    boolean drop = k.isEmpty() || v.isEmpty();
+                    if(drop || !keys.containsKey(k)) {
+                        keys.remove(e.getKey());
+                        if(!drop)
+                            keys.put(k, v);
+                    }
+                } else if(!e.getValue().equals(v)) {
+                    if(v.isEmpty())
+                        keys.remove(k);
+                    else
+                        keys.put(k, v);
+                    changed = true;
+                }
+            }
+            return changed;
+        }
+    }
+    
+    /**
+     * Data fix to cleanup wrong spelled keys
+     */
+    public class FixDataKey implements FixData {
+        /** key of wrong data */
+        String oldKey;
+        /** key of correct data */
+        String newKey;
+
+        /**
+         * Setup key check for wrong spelled keys
+         *
+         * @param oldKey wrong spelled key
+         * @param newKey correct replacement
+         */
+        public FixDataKey(String oldKey, String newKey) {
+            this.oldKey = oldKey;
+            this.newKey = newKey;
+        }
+
+        @Override
+        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
+            if(keys.containsKey(oldKey) && !keys.containsKey(newKey)) {
+                keys.put(newKey, keys.get(oldKey));
+                keys.remove(oldKey);
+                return true;
+            }
+            return false;
+        }
+    }
+    
+    /**
+     * Data fix to cleanup wrong spelled tags
+     */
+    public class FixDataTag implements FixData {
+        /** key of wrong data */
+        String oldKey;
+        /** value of wrong data */
+        String oldValue;
+        /** key of correct data */
+        String newKey;
+        /** value of correct data */
+        String newValue;
+
+        /**
+         * Setup key check for wrong spelled keys
+         *
+         * @param oldKey wrong or old key
+         * @param oldValue wrong or old value
+         * @param newKey correct key replacement
+         * @param newValue correct value replacement
+         */
+        public FixDataTag(String oldKey, String oldValue, String newKey, String newValue) {
+            this.oldKey = oldKey;
+            this.oldValue = oldValue;
+            this.newKey = newKey;
+            this.newValue = newValue;
+        }
+
+        @Override
+        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
+            if(oldValue.equals(keys.get(oldKey)) && (newKey.equals(oldKey) || !keys.containsKey(newKey))) {
+                keys.put(newKey, newValue);
+                if(!newKey.equals(oldKey))
+                    keys.remove(oldKey);
+                return true;
+            }
+            return false;
+        }
+    }
+    
+    /**
+     * Checks the upload for deprecated or wrong tags.
+     * @param apiDataSet the data to upload
+     */
+    @Override
+    public boolean checkUpload(APIDataSet apiDataSet) {
+        if(!Main.pref.getBoolean("fix.data.on.upload", true))
+            return true;
+
+        List<OsmPrimitive> objectsToUpload = apiDataSet.getPrimitives();
+        Collection<Command> cmds = new LinkedList<Command>();
+
+        boolean needsChange = false;
+        for (OsmPrimitive osm : objectsToUpload) {
+            Map<String, String> keys = osm.getKeys();
+            if(!keys.isEmpty()) {
+                boolean modified = false;
+                for (FixData fix : deprecated) {
+                    if(fix.fixKeys(keys, osm))
+                        modified = true;
+                }
+                if(modified)
+                    cmds.add(new ChangePropertyCommand(Collections.singleton(osm), new HashMap<String, String>(keys)));
+            }
+        }
+
+        if(!cmds.isEmpty())
+            Main.main.undoRedo.add(new SequenceCommand(tr("Fix deprecated tags"), cmds));
+        return true;
+    }
+}
