diff --git a/src/main/jastadd/JastAddAPIExtension.jadd b/src/main/jastadd/JastAddAPIExtension.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..a2a97601f956515551eea2dfc9779029a057a934
--- /dev/null
+++ b/src/main/jastadd/JastAddAPIExtension.jadd
@@ -0,0 +1,47 @@
+aspect JastAddAPIExtension {
+
+  /**
+   * removes the object from the AST, i.e. removes the reference from its parent to the object
+   *
+   * Please note that any intrinsic non-containment relations to the object are not removed.
+   * @return true, if the object had a parent.
+   */
+  public boolean ASTNode.removeSelf() {
+    if (getParent() == null) {
+      return false;
+    } else {
+      for (int childIndex = 0; childIndex < getParent().numChildren(); childIndex++) {
+        if (getParent().getChild(childIndex) == this) {
+          getParent().removeChild(childIndex);
+          return true;
+        }
+      }
+    }
+    throw new RuntimeException("unable to remove child, because it was not contained in its parent!");
+  }
+
+  public int ASTNode.containedChildren() {
+    int result = 0;
+    for (ASTNode child: this.astChildren()) {
+      if (child instanceof JastAddList) {
+        result += child.numChildren();
+      } else if (child instanceof Opt) {
+        if (getChild(0).numChildren() != 0) {
+          result += 1;
+        }
+      } else {
+        result += 1;
+      }
+    }
+    return result;
+  }
+
+  public ASTNode ASTNode.root() {
+    if (getParent() == null) {
+      return this;
+    } else {
+      return getParent().root();
+    }
+  }
+
+}
diff --git a/src/main/jastadd/XMI/XMIWriter.jadd b/src/main/jastadd/XMI/XMIWriter.jadd
index 4096a537a60ef290e36e44c4bfb5fcbd07d102d9..cc0714b8af6c8a1bde07789859117abbcffac159 100644
--- a/src/main/jastadd/XMI/XMIWriter.jadd
+++ b/src/main/jastadd/XMI/XMIWriter.jadd
@@ -31,12 +31,25 @@ aspect XMIWriter {
     // opening tag
     b.append(indentString(indentationLevel)).append("<");
     startXMIElement(b, "ecore:EPackage", context);
-    b.append(" name=\"").append(getName()).append("\"")
-      .append(" nsURI=\"").append(getNsURI()).append("\"")
-      .append(" nsPrefix=\"").append(getNsPrefix()).append("\"")
-      .append(">\n");
 
+    // attributes
+    // from ENamedElement
+    b.append(" name=\"").append(getName()).append("\"");
+    // from EPackage
+    b.append(" nsURI=\"").append(getNsURI()).append("\"")
+      .append(" nsPrefix=\"").append(getNsPrefix()).append("\"");
+    if (containedChildren() == 0) {
+      b.append("/>\n");
+      return;
+    }
+    b.append(">\n");
 
+    // child nodes
+    // from EModelElement
+    for (EAnnotation eAnnotation : getEAnnotationList()) {
+      eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1);
+    }
+    // from EPackage
     for (EClassifier eClassifier : getEClassifierList()) {
       eClassifier.writeXMI(b, "eClassifiers", indentationLevel + 1);
     }
@@ -56,10 +69,44 @@ aspect XMIWriter {
     b.append(indentString(indentationLevel)).append("<");
     startXMIElement(b, "ecore:EClass", context);
     // attributes
+    // from ENamedElement
     b.append(" name=\"").append(getName()).append("\"");
-
+    // from EClassifier
+    if (getInstanceClassName() != "") {
+      b.append(" instanceClassName=\"").append(getInstanceClassName()).append("\"");
+    }
+    // from EClass
+    if (getAbstract() == true) {
+      b.append(" abstract=\"true\"");
+    }
+    if (getInterface() == true) {
+      b.append(" interface=\"true\"");
+    }
+    if (containedChildren() == 0) {
+      b.append("/>\n");
+      return;
+    }
     b.append(">\n");
+
     // child nodes
+    // from EModelElement
+    for (EAnnotation eAnnotation : getEAnnotationList()) {
+      eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1);
+    }
+    // from EClassifier
+    for (ETypeParameter eTypeParameter : getETypeParameterList()) {
+      eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1);
+    }
+    // from EClass
+    for (EStructuralFeature eStructuralFeature : getEStructuralFeatureList()) {
+      eStructuralFeature.writeXMI(b, "eStructuralFeatures", indentationLevel + 1);
+    }
+    for (EOperation eOperation : getEOperationList()) {
+      eOperation.writeXMI(b, "eOperations", indentationLevel + 1);
+    }
+    for (EGenericType eGenericSuperType : getEGenericSuperTypeList()) {
+      eGenericSuperType.writeXMI(b, "eGenericSuperTypes", indentationLevel + 1);
+    }
 
     // closing tag
     b.append(indentString(indentationLevel)).append("</");
@@ -73,12 +120,165 @@ aspect XMIWriter {
     // attributes
     b.append(" name=\"").append(getName()).append("\"");
 
+    if (containedChildren() == 0) {
+      b.append("/>\n");
+      return;
+    }
+    b.append(">\n");
+    // child nodes
+
+    // closing tag
+    b.append(indentString(indentationLevel)).append("</");
+    endXMIElement(b, "ecore:EPackage", context);
+    b.append(">\n");
+  }
+
+  void EGenericType.writeXMI(StringBuilder b, String context, int indentationLevel) {
+    // TODO implement
+  }
+
+  void EOperation.writeXMI(StringBuilder b, String context, int indentationLevel) {
+    // TODO implement
+  }
+
+  abstract void EStructuralFeature.writeXMI(StringBuilder b, String context, int indentationLevel);
+
+  void EReference.writeXMI(StringBuilder b, String context, int indentationLevel) {
+    b.append(indentString(indentationLevel)).append("<");
+    startXMIElement(b, "ecore:EReference", context);
+    // attributes
+    // from ENamedElement
+    b.append(" name=\"").append(getName()).append("\"");
+    // from ETypedElement
+    if (getOrdered() == false) {
+      b.append(" ordered=\"false\"");
+    }
+    if (getUnique() == false) {
+      b.append(" unique=\"false\"");
+    }
+    if (getLowerBound() != 0) {
+      b.append(" lowerBound=\"" + getLowerBound() + "\"");
+    }
+    if (getUpperBound() != 1) {
+      b.append(" upperBound=\"" + getUpperBound() + "\"");
+    }
+    // from EStructuralFEature
+    if (getChangeable() == false) {
+      b.append(" changeable=\"false\"");
+    }
+    if (getVolatile() == true) {
+      b.append(" volatile=\"true\"");
+    }
+    if (getTransient() == true) {
+      b.append(" transient=\"true\"");
+    }
+    if (getDefaultValueLiteral() != "") {
+      b.append(" defaultValueLiteral=\"").append(getDefaultValueLiteral()).append("\"");
+    }
+    if (getUnsettable() == true) {
+      b.append(" unsettable=\"true\"");
+    }
+    if (getDerived() == true) {
+      b.append(" derived=\"true\"");
+    }
+    // from EReference
+    if (getContainment() == true) {
+      b.append(" containment=\"true\"");
+    }
+    if (getResolveProxies() == false) {
+      b.append(" resolveProxies=\"false\"");
+    }
+    if (getNumChild() == 0) {
+      b.append("/>\n");
+      return;
+    }
+    if (containedChildren() == 0) {
+      b.append("/>\n");
+      return;
+    }
+    System.out.println(containedChildren());
+    b.append(">\n");
+    // child nodes
+    // from EModelElement
+    for (EAnnotation eAnnotation : getEAnnotationList()) {
+      eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1);
+    }
+
+    // closing tag
+    b.append(indentString(indentationLevel)).append("</");
+    endXMIElement(b, "ecore:EPackage", context);
+    b.append(">\n");
+  }
+
+  void EAttribute.writeXMI(StringBuilder b, String context, int indentationLevel) {
+    b.append(indentString(indentationLevel)).append("<");
+    startXMIElement(b, "ecore:EAttribute", context);
+    // attributes
+    // from ENamedElement
+    b.append(" name=\"").append(getName()).append("\"");
+    // from ETypedElement
+    if (getOrdered() == false) {
+      b.append(" ordered=\"false\"");
+    }
+    if (getUnique() == false) {
+      b.append(" unique=\"false\"");
+    }
+    if (getLowerBound() != 0) {
+      b.append(" lowerBound=\"" + getLowerBound() + "\"");
+    }
+    if (getUpperBound() != 1) {
+      b.append(" upperBound=\"" + getUpperBound() + "\"");
+    }
+    // from EStructuralFEature
+    if (getChangeable() == false) {
+      b.append(" changeable=\"false\"");
+    }
+    if (getVolatile() == true) {
+      b.append(" volatile=\"true\"");
+    }
+    if (getTransient() == true) {
+      b.append(" transient=\"true\"");
+    }
+    if (getDefaultValueLiteral() != "") {
+      b.append(" defaultValueLiteral=\"").append(getDefaultValueLiteral()).append("\"");
+    }
+    if (getUnsettable() == true) {
+      b.append(" unsettable=\"true\"");
+    }
+    if (getDerived() == true) {
+      b.append(" derived=\"true\"");
+    }
+    // from EAttribute
+    if (getID() == true) {
+      b.append(" iD=\"true\"");
+    }
+    if (getNumChild() == 0) {
+      b.append("/>\n");
+      return;
+    }
+    if (containedChildren() == 0) {
+      b.append("/>\n");
+      return;
+    }
+    System.out.println(containedChildren());
     b.append(">\n");
     // child nodes
+    // from EModelElement
+    for (EAnnotation eAnnotation : getEAnnotationList()) {
+      eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1);
+    }
 
     // closing tag
     b.append(indentString(indentationLevel)).append("</");
     endXMIElement(b, "ecore:EPackage", context);
     b.append(">\n");
   }
+
+  void EAnnotation.writeXMI(StringBuilder b, String context, int indentationLevel) {
+    // TODO implement
+  }
+
+  void ETypeParameter.writeXMI(StringBuilder b, String context, int indentationLevel) {
+    // TODO implement
+  }
 }
diff --git a/src/main/jastadd/ecore.relast b/src/main/jastadd/ecore.relast
index f03a19a331f43e12098574f511500fa95440e1c6..a3cc7bb64606ad7520f8ce1ba1f9b1a3afd1b699 100644
--- a/src/main/jastadd/ecore.relast
+++ b/src/main/jastadd/ecore.relast
@@ -18,7 +18,7 @@ EClass : EClassifier ::= EStructuralFeature* EOperation* EGenericSuperType:EGene
 EDataType : EClassifier;
 EEnum : EDataType ::= ELiteral:EEnumLiteral*;
 
-EStructuralFeature : ETypedElement ::= <Changeable:boolean> <Volatile:boolean> <Transient:boolean> <defaultValueLiteral:String> <Unsettable:boolean> <Derived:boolean>;
+abstract EStructuralFeature : ETypedElement ::= <Changeable:boolean> <Volatile:boolean> <Transient:boolean> <DefaultValueLiteral:String> <Unsettable:boolean> <Derived:boolean>;
 EAttribute : EStructuralFeature ::= <ID:boolean>;
 EReference : EStructuralFeature ::= <Containment:boolean> <ResolveProxies:boolean>;
 EOperation : ETypedElement ::= GenericException:EGenericType* ETypeParameter* EParameter*;
diff --git a/src/main/java/de/tudresden/inf/st/e2j/parser/EcoreParser.java b/src/main/java/de/tudresden/inf/st/e2j/parser/EcoreParser.java
index 33848110e7309a2780e7d8f5865b17e3f3056aa9..d05d28cda590632892347e9b57ba448084260f8d 100644
--- a/src/main/java/de/tudresden/inf/st/e2j/parser/EcoreParser.java
+++ b/src/main/java/de/tudresden/inf/st/e2j/parser/EcoreParser.java
@@ -286,6 +286,12 @@ public class EcoreParser {
 
     EAttribute eAttribute = new EAttribute();
 
+    // set default values
+    eAttribute.setOrdered(true);
+    eAttribute.setUnique(true);
+    eAttribute.setUpperBound(1);
+    eAttribute.setChangeable(true);
+
     // get all the properties out of the element
     StartElement startElement = reader.nextEvent().asStartElement();
 
@@ -319,6 +325,7 @@ public class EcoreParser {
             break;
           case "eType":
             eAttribute.setEType(EClassifier.createRefDirection(attribute.getValue()));
+            break;
             // from EStructuralFeature
           case "changeable":
             eAttribute.setChangeable(Boolean.valueOf(attribute.getValue()));
@@ -330,7 +337,7 @@ public class EcoreParser {
             eAttribute.setTransient(Boolean.valueOf(attribute.getValue()));
             break;
           case "defaultValueLiteral":
-            eAttribute.setdefaultValueLiteral(attribute.getValue());
+            eAttribute.setDefaultValueLiteral(attribute.getValue());
             break;
           case "defaultValue":
             logger.warn("ignoring attribute 'defaultValue' with value '{}'", attribute.getValue());
@@ -375,6 +382,13 @@ public class EcoreParser {
 
     EReference eReference = new EReference();
 
+    // set default values
+    eReference.setOrdered(true);
+    eReference.setUnique(true);
+    eReference.setUpperBound(1);
+    eReference.setChangeable(true);
+    eReference.setResolveProxies(true);
+
     // get all the properties out of the element
     StartElement startElement = reader.nextEvent().asStartElement();
 
@@ -409,6 +423,7 @@ public class EcoreParser {
             break;
           case "eType":
             eReference.setEType(EClassifier.createRefDirection(attribute.getValue()));
+            break;
             // from EStructuralFeature
           case "changeable":
             eReference.setChangeable(Boolean.valueOf(attribute.getValue()));
@@ -420,7 +435,7 @@ public class EcoreParser {
             eReference.setTransient(Boolean.valueOf(attribute.getValue()));
             break;
           case "defaultValueLiteral":
-            eReference.setdefaultValueLiteral(attribute.getValue());
+            eReference.setDefaultValueLiteral(attribute.getValue());
             break;
           case "unsettable":
             eReference.setUnsettable(Boolean.valueOf(attribute.getValue()));