Index: src/org/openstreetmap/josm/data/osm/tag/ArrayTag.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/tag/ArrayTag.java	(nonexistent)
+++ src/org/openstreetmap/josm/data/osm/tag/ArrayTag.java	(working copy)
@@ -0,0 +1,31 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.tag;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.openstreetmap.josm.data.osm.Tag;
+
+public class ArrayTag extends Tag implements IValueTag<List<Tag>> {
+
+    private List<Tag> value;
+
+    public ArrayTag(String key, List<Tag> value) {
+        super(key, convertToString(value));
+        this.value = value;
+    }
+
+    @Override
+    public List<Tag> getRealValue() {
+        return value;
+    }
+
+    @Override
+    public String getValue() {
+        return convertToString(value);
+    }
+
+    private static String convertToString(List<Tag> value) {
+        return value.stream().map(Tag::getValue).collect(Collectors.joining(", ", "[", "]"));
+    }
+}
Index: src/org/openstreetmap/josm/data/osm/tag/BooleanTag.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/tag/BooleanTag.java	(nonexistent)
+++ src/org/openstreetmap/josm/data/osm/tag/BooleanTag.java	(working copy)
@@ -0,0 +1,18 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.tag;
+
+import org.openstreetmap.josm.data.osm.Tag;
+
+public class BooleanTag extends Tag implements IValueTag<Boolean> {
+    private Boolean value;
+
+    public BooleanTag(Boolean value) {
+        super(value.toString());
+        this.value = value;
+    }
+
+    @Override
+    public Boolean getRealValue() {
+        return value;
+    }
+}
Index: src/org/openstreetmap/josm/data/osm/tag/IValueTag.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/tag/IValueTag.java	(nonexistent)
+++ src/org/openstreetmap/josm/data/osm/tag/IValueTag.java	(working copy)
@@ -0,0 +1,6 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.tag;
+
+public interface IValueTag<T> {
+    T getRealValue();
+}
Index: src/org/openstreetmap/josm/data/osm/tag/NumberTag.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/tag/NumberTag.java	(nonexistent)
+++ src/org/openstreetmap/josm/data/osm/tag/NumberTag.java	(working copy)
@@ -0,0 +1,19 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.tag;
+
+import org.openstreetmap.josm.data.osm.Tag;
+
+public class NumberTag extends Tag implements IValueTag<Number> {
+
+    private Number value;
+    public NumberTag(String key, Number value) {
+        super(key, value.toString());
+        this.value = value;
+    }
+
+    @Override
+    public Number getRealValue() {
+        return this.value;
+    }
+
+}
Index: src/org/openstreetmap/josm/data/osm/tag/ObjectTag.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/tag/ObjectTag.java	(nonexistent)
+++ src/org/openstreetmap/josm/data/osm/tag/ObjectTag.java	(working copy)
@@ -0,0 +1,29 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.tag;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.openstreetmap.josm.data.osm.Tag;
+
+public class ObjectTag extends Tag implements IValueTag<Map<String, Tag>> {
+    private Map<String, Tag> value;
+    public ObjectTag(String key, Map<String, Tag> value) {
+        super(key, convertToString(value));
+        this.value = value;
+    }
+
+    @Override
+    public Map<String, Tag> getRealValue() {
+        return value;
+    }
+
+    @Override
+    public String getValue() {
+        return convertToString(value);
+    }
+
+    private static String convertToString(Map<String, Tag> value) {
+        return value.entrySet().stream().map(e -> e.getKey() + ":" + e.getValue().getValue()).collect(Collectors.joining(",", "{", "}"));
+    }
+}
Index: src/org/openstreetmap/josm/data/osm/tag/StringTag.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/tag/StringTag.java	(nonexistent)
+++ src/org/openstreetmap/josm/data/osm/tag/StringTag.java	(working copy)
@@ -0,0 +1,23 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.tag;
+
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.osm.Tagged;
+
+/**
+* Tag represents an immutable key/value-pair. Both the key and the value may be empty, but not null.
+* <p>
+* It implements the {@link Tagged} interface. However, since instances of this class are immutable,
+* the modifying methods throw an {@link UnsupportedOperationException}.
+*/
+public class StringTag extends Tag implements IValueTag<String> {
+
+   public StringTag(String key, String value) {
+       super(key, value);
+   }
+
+    @Override
+    public String getRealValue() {
+        return super.getValue();
+    }
+}
