diff --git a/data/defaultpresets.xml b/data/defaultpresets.xml
index 1af1e86..e877a2d 100755
--- a/data/defaultpresets.xml
+++ b/data/defaultpresets.xml
@@ -1329,7 +1329,7 @@ Note that for a match, at least one positive and no negative is required.
         <item name="Border Control" icon="presets/douane.png" type="node">
             <label text="Edit Border Control" />
             <key key="barrier" value="border_control" />
-            <optional text="Allowed traffic:">
+            <optional text="Allowed traffic:" id="barrier">
                 <check key="foot" text="Foot" default="on" />
                 <check key="bicycle" text="Bicycle" default="on" />
                 <check key="horse" text="Horse" default="off" />
@@ -1447,13 +1447,7 @@ Note that for a match, at least one positive and no negative is required.
                   ru.href="http://wiki.openstreetmap.org/wiki/RU:Tag:barrier=entrance" />
             <label text="Edit Entrance (barrier opening)" />
             <key key="barrier" value="entrance" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
             </optional>
@@ -1468,13 +1462,7 @@ Note that for a match, at least one positive and no negative is required.
                   ru.href="http://wiki.openstreetmap.org/wiki/RU:Tag:barrier=gate" />
             <label text="Edit Gate" />
             <key key="barrier" value="gate" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
             </optional>
@@ -1488,13 +1476,7 @@ Note that for a match, at least one positive and no negative is required.
                   ru.href="http://wiki.openstreetmap.org/wiki/RU:Tag:barrier=lift_gate" />
             <label text="Edit Lift Gate" />
             <key key="barrier" value="lift_gate" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
             </optional>
@@ -1502,13 +1484,7 @@ Note that for a match, at least one positive and no negative is required.
         <item name="Hampshire Gate" icon="presets/empty.png" type="node">
             <label text="Edit Hampshire Gate" />
             <key key="barrier" value="hampshire_gate" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
             </optional>
@@ -1516,13 +1492,7 @@ Note that for a match, at least one positive and no negative is required.
         <item name="Bump Gate" icon="presets/empty.png" type="node">
             <label text="Edit Bump Gate" />
             <key key="barrier" value="bump_gate" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
             </optional>
@@ -1544,13 +1514,7 @@ Note that for a match, at least one positive and no negative is required.
                   pl.href="http://wiki.openstreetmap.org/wiki/Pl:Tag:barrier=chain" />
             <label text="Edit Chain" />
             <key key="barrier" value="chain" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
             </optional>
@@ -1584,13 +1548,7 @@ Note that for a match, at least one positive and no negative is required.
             <link href="http://wiki.openstreetmap.org/wiki/Tag:highway=sally_port" />
             <label text="Edit Sally Port" />
             <key key="barrier" value="sally_port" />
-            <optional text="Allowed traffic:">
-                <check key="foot" text="Foot" default="on" />
-                <check key="bicycle" text="Bicycle" default="on" />
-                <check key="horse" text="Horse" default="off" />
-                <check key="motorcycle" text="Motorcycle" default="off" />
-                <check key="motorcar" text="Motorcar" default="off" />
-            </optional>
+            <reference ref="barrier" />
             <optional>
                 <text key="maxheight" text="Max. height (meters)" length="7" />
                 <text key="maxwidth" text="Max. width (meters)" length="7" />
diff --git a/data/tagging-preset.xsd b/data/tagging-preset.xsd
index 1ec6353..c7ea4c0 100644
--- a/data/tagging-preset.xsd
+++ b/data/tagging-preset.xsd
@@ -8,7 +8,16 @@
 		errors, elements have specified prohibited attributes -->
 
 	<element name="annotations" type="tns:root" />
-	<element name="presets" type="tns:root" />
+    <element name="presets" type="tns:root">
+        <unique name="optional_id">
+            <selector xpath=".//tns:optional"/>
+            <field xpath="@id"/>
+        </unique>
+        <keyref name="optional_ref" refer="tns:optional_id">
+            <selector xpath=".//tns:reference"/>
+            <field xpath="@ref"/>
+        </keyref>
+    </element>
 
 	<complexType name="root">
 		<complexContent>
@@ -55,6 +64,7 @@
 				<group ref="tns:optional_elements" />
 				<element name="key" type="tns:key" />
 				<element name="optional" type="tns:optional" minOccurs="0" />
+				<element name="reference" type="tns:reference" minOccurs="0" />
 			</choice>
 			<element name="roles" type="tns:roles" minOccurs="0" maxOccurs="1" />
 		</sequence>
@@ -72,8 +82,13 @@
 		<group ref="tns:optional_elements" maxOccurs="unbounded" />
 		<attribute name="text" type="string" />
 		<attribute name="text_context" type="string" />
+        <attribute name="id" type="ID" use="optional" />
 	</complexType>
 
+    <complexType name="reference">
+        <attribute name="ref" type="IDREF" use="required" />
+    </complexType>
+
 	<group name="optional_elements">
 		<choice>
 			<element name="label" type="tns:label" />
diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItem.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItem.java
index 3b66147..f9c569e 100644
--- a/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItem.java
+++ b/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItem.java
@@ -20,6 +20,8 @@ import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
  */
 public abstract class TaggingPresetItem {
 
+    public String id;
+
     protected void initAutoCompletionField(AutoCompletingTextField field, String key) {
         if (Main.main == null) return;
         OsmDataLayer layer = Main.main.getEditLayer();
diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPresetReader.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPresetReader.java
index 0efe5fe..86c0ed9 100644
--- a/src/org/openstreetmap/josm/gui/tagging/TaggingPresetReader.java
+++ b/src/org/openstreetmap/josm/gui/tagging/TaggingPresetReader.java
@@ -10,9 +10,14 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import javax.swing.JOptionPane;
 
@@ -45,6 +50,13 @@ public final class TaggingPresetReader {
 
         return sources;
     }
+
+    /**
+     * Holds a reference to an earlier item/object.
+     */
+    public static class Reference {
+        public String ref;
+    }
     
     public static List<TaggingPreset> readAll(Reader in, boolean validate) throws SAXException {
         XmlObjectParser parser = new XmlObjectParser();
@@ -53,7 +65,7 @@ public final class TaggingPresetReader {
         parser.mapBoth("group", TaggingPresetMenu.class);
         parser.map("text", TaggingPresetItems.Text.class);
         parser.map("link", TaggingPresetItems.Link.class);
-        parser.mapOnStart("optional", TaggingPresetItems.Optional.class);
+        parser.mapBoth("optional", TaggingPresetItems.Optional.class);
         parser.mapOnStart("roles", TaggingPresetItems.Roles.class);
         parser.map("role", TaggingPresetItems.Role.class);
         parser.map("checkgroup", TaggingPresetItems.CheckGroup.class);
@@ -65,12 +77,16 @@ public final class TaggingPresetReader {
         parser.map("key", TaggingPresetItems.Key.class);
         parser.map("list_entry", TaggingPresetItems.PresetListEntry.class);
         parser.map("item_separator", TaggingPresetItems.ItemSeparator.class);
+        parser.map("reference", Reference.class);
         
         LinkedList<TaggingPreset> all = new LinkedList<TaggingPreset>();
         TaggingPresetMenu lastmenu = null;
         TaggingPresetItems.Roles lastrole = null;
         final List<TaggingPresetItems.Check> checks = new LinkedList<TaggingPresetItems.Check>();
         List<TaggingPresetItems.PresetListEntry> listEntries = new LinkedList<TaggingPresetItems.PresetListEntry>();
+        final Map<String, List<Object>> byId = new HashMap<String, List<Object>>();
+        String lastId = null;
+        Iterator<Object> lastIdIterator = null;
 
         if (validate) {
             parser.startWithValidation(in, Main.JOSM_WEBSITE+"/tagging-preset-1.0", "resource://data/tagging-preset.xsd");
@@ -78,7 +94,42 @@ public final class TaggingPresetReader {
             parser.start(in);
         }
         while (parser.hasNext()) {
-            Object o = parser.next();
+            final Object o;
+            if (lastIdIterator != null && lastIdIterator.hasNext()) {
+                // obtain elements from lastIdIterator with higher priority
+                o = lastIdIterator.next();
+                System.out.println(o);
+            } else {
+                o = parser.next();
+            }
+            if (o instanceof TaggingPresetItem && ((TaggingPresetItem) o).id != null) {
+                if (((TaggingPresetItem) o).id.equals(lastId)) {
+                    // reset last id on end of object, don't process further
+                    lastId = null;
+                    ((TaggingPresetItem) o).id = null;
+                    continue;
+                } else if (lastId == null) {
+                    // if preset item contains an id, store a mapping for later usage
+                    lastId = ((TaggingPresetItem) o).id;
+                    byId.put(lastId, new ArrayList<Object>(Arrays.asList(o)));
+                } else {
+                    throw new IllegalStateException("Cannot deal with nested id objects (lastId was expected to be null)");
+                }
+            } else if (lastId != null) {
+                // add object to mapping for later usage
+                byId.get(lastId).add(o);
+            }
+            if (o instanceof Reference) {
+                // if o is a reference, obtain the corresponding objects from the mapping,
+                // and iterate over those before consuming the next element from parser.
+                final String ref = ((Reference) o).ref;
+                if (byId.get(ref) == null) {
+                    throw new SAXException(tr("Reference {0} is being used before it was defined", ref));
+                }
+                System.out.println(ref + byId.get(ref));
+                lastIdIterator = byId.get(ref).iterator();
+                continue;
+            }
             if (!(o instanceof TaggingPresetItem) && !checks.isEmpty()) {
                 all.getLast().data.addAll(checks);
                 checks.clear();
