diff --git a/data/gpx-extensions.xsd b/data/gpx-extensions.xsd
index bc5452e..875be90 100644
--- a/data/gpx-extensions.xsd
+++ b/data/gpx-extensions.xsd
@@ -5,7 +5,11 @@
     <!-- true, if gpx data has been downloaded from the osm server -->
     <!-- it this case, JOSM improves the rendering of clouds of anonymous TrackPoints -->
     <element name="from-server" type="boolean"/>
-    
+
+    <!-- custom colors set to this layer -->
+    <element name="color" type="string"/>
+    <element name="marker-color" type="string"/>
+
     <!-- the following properties are only set for marker layer export -->
     <element name="offset" type="decimal"/>
     <element name="sync-offset" type="decimal"/>
diff --git a/src/org/openstreetmap/josm/data/gpx/GpxData.java b/src/org/openstreetmap/josm/data/gpx/GpxData.java
index 88ac490..63ad205 100644
--- a/src/org/openstreetmap/josm/data/gpx/GpxData.java
+++ b/src/org/openstreetmap/josm/data/gpx/GpxData.java
@@ -1,6 +1,7 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.gpx;
 
+import java.awt.Color;
 import java.awt.geom.Area;
 import java.io.File;
 import java.util.Collection;
@@ -31,6 +32,9 @@ public class GpxData extends WithAttributes implements Data {
     public File storageFile;
     public boolean fromServer;
 
+    public Color color;
+    public Color markerColor;
+
     public String creator;
 
     public final Collection<GpxTrack> tracks = new LinkedList<>();
diff --git a/src/org/openstreetmap/josm/gui/MapView.java b/src/org/openstreetmap/josm/gui/MapView.java
index 530856e..2c0cc6a 100644
--- a/src/org/openstreetmap/josm/gui/MapView.java
+++ b/src/org/openstreetmap/josm/gui/MapView.java
@@ -1072,7 +1072,8 @@ implements PropertyChangeListener, PreferenceChangedListener, OsmDataLayer.Layer
         if (evt.getPropertyName().equals(Layer.VISIBLE_PROP)) {
             repaint();
         } else if (evt.getPropertyName().equals(Layer.OPACITY_PROP) ||
-                evt.getPropertyName().equals(Layer.FILTER_STATE_PROP)) {
+                evt.getPropertyName().equals(Layer.FILTER_STATE_PROP) ||
+                evt.getPropertyName().equals(Layer.COLOR_PROP)) {
             Layer l = (Layer) evt.getSource();
             if (l.isVisible()) {
                 changedLayer = l;
diff --git a/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java b/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java
index 2fa5bc3..b562fb8 100644
--- a/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java
+++ b/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java
@@ -17,12 +17,18 @@ import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
 import org.openstreetmap.josm.gui.layer.Layer.MultiLayerAction;
 import org.openstreetmap.josm.tools.ImageProvider;
 
 public class CustomizeColor extends AbstractAction implements LayerAction, MultiLayerAction {
     private transient List<Layer> layers;
+    /**
+     * Use preferences to save and load customized settings for each layer
+     * where preferences key contains layer name
+     */
+    public static final BooleanProperty USE_PREF_LAYER_NAME = new BooleanProperty("dialog.layer.use-pref-layer-name", false);
 
     public CustomizeColor(List<Layer> l) {
         this();
@@ -78,17 +84,22 @@ public class CustomizeColor extends AbstractAction implements LayerAction, Multi
         switch (answer) {
         case 0:
             for (Layer layer : layers) {
-                Main.pref.putColor("layer "+layer.getName(), c.getColor());
+                if (USE_PREF_LAYER_NAME.get()) {
+                    Main.pref.putColor("layer "+layer.getName(), c.getColor());
+                }
+                layer.setColor(c.getColor());
             }
             break;
         case 1:
             return;
         case 2:
             for (Layer layer : layers) {
-                Main.pref.putColor("layer "+layer.getName(), null);
+                if (USE_PREF_LAYER_NAME.get()) {
+                    Main.pref.putColor("layer "+layer.getName(), null);
+                }
+                layer.setColor(null);
             }
             break;
         }
-        Main.map.repaint();
     }
 }
diff --git a/src/org/openstreetmap/josm/gui/layer/GpxLayer.java b/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
index 6c54410..e5ee02a 100644
--- a/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
+++ b/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
@@ -84,6 +84,15 @@ public class GpxLayer extends Layer {
         return drawHelper.getColor(getName(), ignoreCustom);
     }
 
+    @Override
+    public void setColor(Color color) {
+        Color oldValue = data.color;
+        data.color = color;
+        if (oldValue == null ? color != null : !oldValue.equals(color)) {
+            propertyChangeSupport.firePropertyChange(COLOR_PROP, oldValue, color);
+        }
+    }
+
     /**
      * Returns a human readable string that shows the timespan of the given track
      * @param trk The GPX track for which timespan is displayed
diff --git a/src/org/openstreetmap/josm/gui/layer/Layer.java b/src/org/openstreetmap/josm/gui/layer/Layer.java
index ed33791..2935922 100644
--- a/src/org/openstreetmap/josm/gui/layer/Layer.java
+++ b/src/org/openstreetmap/josm/gui/layer/Layer.java
@@ -85,6 +85,7 @@ public abstract class Layer implements Destroyable, MapViewPaintable, Projection
     public static final String OPACITY_PROP = Layer.class.getName() + ".opacity";
     public static final String NAME_PROP = Layer.class.getName() + ".name";
     public static final String FILTER_STATE_PROP = Layer.class.getName() + ".filterstate";
+    public static final String COLOR_PROP = Layer.class.getName() + ".color";
 
     public static final int ICON_SIZE = 16;
 
@@ -191,6 +192,12 @@ public abstract class Layer implements Destroyable, MapViewPaintable, Projection
     }
 
     /**
+     * Set a Color for this layer.
+     */
+    public void setColor(Color color) {
+    }
+
+    /**
      * @return A small tooltip hint about some statistics for this layer.
      */
     public abstract String getToolTipText();
diff --git a/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java b/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
index ed925af..eeefe55 100644
--- a/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
+++ b/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
@@ -23,6 +23,7 @@ import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.WayPoint;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.CustomizeColor;
 import org.openstreetmap.josm.tools.ColorScale;
 
 /**
@@ -137,14 +138,17 @@ public class GpxDrawHelper {
      * @return the color or null if the color is not constant
      */
     public Color getColor(String layerName, boolean ignoreCustom) {
-        Color c = Main.pref.getColor(marktr("gps point"), specName(layerName), DEFAULT_COLOR);
-        return ignoreCustom || getColorMode(layerName) == ColorMode.NONE ? c : null;
+        Color color = data.color;
+        if (color == null) {
+            color = Main.pref.getColor(marktr("gps point"), CustomizeColor.USE_PREF_LAYER_NAME.get() ? specName(layerName) : null, DEFAULT_COLOR);
+        }
+        return ignoreCustom || getColorMode(layerName) == ColorMode.NONE ? color : null;
     }
 
     /**
      * Read coloring mode for specified layer from preferences
      * @param layerName name of the GpxLayer
-     * @return coloting mode
+     * @return coloring mode
      */
     public ColorMode getColorMode(String layerName) {
         try {
diff --git a/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java b/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
index e62d62b..9c73ae0 100644
--- a/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
+++ b/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
@@ -190,8 +190,20 @@ public class MarkerLayer extends Layer implements JumpToMarkerLayer {
 
     @Override
     public Color getColor(boolean ignoreCustom) {
-        String name = getName();
-        return Main.pref.getColor(marktr("gps marker"), name != null ? "layer "+name : null, DEFAULT_COLOR);
+        Color color = fromLayer.data.markerColor;
+        if (color == null) {
+            color = Main.pref.getColor(marktr("gps marker"), CustomizeColor.USE_PREF_LAYER_NAME.get() ? specName(getName()) : null, DEFAULT_COLOR);
+        }
+        return color;
+    }
+
+    @Override
+    public void setColor(Color color) {
+        fromLayer.data.markerColor = color;
+    }
+
+    private static String specName(String layerName) {
+        return "layer " + layerName;
     }
 
     /* for preferences */
diff --git a/src/org/openstreetmap/josm/io/GpxReader.java b/src/org/openstreetmap/josm/io/GpxReader.java
index 73372e2..4abd8cd 100644
--- a/src/org/openstreetmap/josm/io/GpxReader.java
+++ b/src/org/openstreetmap/josm/io/GpxReader.java
@@ -26,6 +26,7 @@ import org.openstreetmap.josm.data.gpx.GpxLink;
 import org.openstreetmap.josm.data.gpx.GpxRoute;
 import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -332,8 +333,6 @@ public class GpxReader implements GpxConstants {
                 case "bounds":
                     // do nothing, has been parsed on startElement
                     break;
-                default:
-                    //TODO: parse extensions
                 }
                 break;
             case author:
@@ -468,7 +467,22 @@ public class GpxReader implements GpxConstants {
                     currentState = states.pop();
                 } else if (JOSM_EXTENSIONS_NAMESPACE_URI.equals(namespaceURI)) {
                     // only interested in extensions written by JOSM
-                    currentExtensions.put(localName, accumulator.toString());
+                    switch (localName) {
+                    case "extensions":
+                        currentState = states.pop();
+                        break;
+                    case "from-server":
+                        data.fromServer = "true".equals(accumulator.toString());
+                        break;
+                    case "color":
+                        data.color = ColorHelper.html2color(accumulator.toString());
+                        break;
+                    case "marker-color":
+                        data.markerColor = ColorHelper.html2color(accumulator.toString());
+                        break;
+                    default:
+                        currentExtensions.put(localName, accumulator.toString());
+                    }
                 }
                 break;
             default:
@@ -489,10 +503,6 @@ public class GpxReader implements GpxConstants {
         public void endDocument() throws SAXException  {
             if (!states.empty())
                 throw new SAXException(tr("Parse error: invalid document structure for GPX document."));
-            Extensions metaExt = (Extensions) data.get(META_EXTENSIONS);
-            if (metaExt != null && "true".equals(metaExt.get("from-server"))) {
-                data.fromServer = true;
-            }
             gpxData = data;
         }
 
diff --git a/src/org/openstreetmap/josm/io/GpxWriter.java b/src/org/openstreetmap/josm/io/GpxWriter.java
index 9a04d09..25fb2d4 100644
--- a/src/org/openstreetmap/josm/io/GpxWriter.java
+++ b/src/org/openstreetmap/josm/io/GpxWriter.java
@@ -26,6 +26,7 @@ import org.openstreetmap.josm.data.gpx.GpxTrack;
 import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
 import org.openstreetmap.josm.data.gpx.IWithAttributes;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.tools.ColorHelper;
 
 /**
  * Writes GPX files from GPX data or OSM data.
@@ -50,6 +51,7 @@ public class GpxWriter extends XmlWriter implements GpxConstants {
 
     private GpxData data;
     private String indent = "";
+    private boolean hasExtensions;
 
     private static final int WAY_POINT = 0;
     private static final int ROUTE_POINT = 1;
@@ -67,7 +69,10 @@ public class GpxWriter extends XmlWriter implements GpxConstants {
         // and some extra synchronization info for export of AudioMarkers.
         // It is checked in advance, if any extensions are used, so we know whether
         // a namespace declaration is necessary.
-        boolean hasExtensions = data.fromServer;
+        hasExtensions = data.fromServer ||
+                data.color != null ||
+                data.markerColor != null;
+
         if (!hasExtensions) {
             for (WayPoint wpt : data.waypoints) {
                 Extensions extensions = (Extensions) wpt.get(META_EXTENSIONS);
@@ -174,9 +179,17 @@ public class GpxWriter extends XmlWriter implements GpxConstants {
             inline("bounds", b);
         }
 
-        if (data.fromServer) {
+        if (hasExtensions) {
             openln("extensions");
-            simpleTag("josm:from-server", "true");
+            if (data.fromServer) {
+                simpleTag("josm:from-server", "true");
+            }
+            if (data.color != null) {
+                simpleTag("josm:color", ColorHelper.color2html(data.color, true));
+            }
+            if (data.markerColor != null) {
+                simpleTag("josm:marker-color", ColorHelper.color2html(data.markerColor, true));
+            }
             closeln("extensions");
         }
 
