diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0929e2b17f43180aebf64d7089941a6fd37e7df5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.gradle/
+src/gen
+.idea/
+build/
+out/
+logs/
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..32ff87ebd78416b9397a39a35906e4d7e3c48a0c
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,155 @@
+// General configuration (plugins, settings, dependencies)
+group 'de.tudresden.inf.st'
+version '0.1'
+
+apply plugin: 'java'
+apply plugin: 'java-library'
+apply plugin: 'jastadd'
+apply plugin: 'application'
+apply plugin: "idea"
+apply plugin: 'java-library'
+
+sourceCompatibility = 1.8
+targetCompatibility = 1.8
+
+repositories.mavenCentral()
+
+buildscript {
+    repositories.mavenCentral()
+    dependencies {
+        classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
+    }
+}
+
+idea.module.generatedSourceDirs += file('src/gen/java')
+
+sourceSets.main.java.srcDir "src/gen/java"
+jar.manifest.attributes('Main-Class': 'de.tudresden.inf.st.pnml.Main')
+
+dependencies {
+    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}"
+    implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
+    implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
+    implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.13.2'
+    implementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
+
+    // pnml lib
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore', version: '2.12.0'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore.xmi', version: '2.12.0'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.common', version: '2.12.0'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.mwe.core', version: '1.3.13'
+    api group: 'fr.lip6.pnml', name: 'fr.lip6.pnml.framework.ptnet', version: '2.2.12'
+    api group: 'fr.lip6.pnml', name: 'fr.lip6.pnml.framework.utils', version: '2.2.12'
+    implementation group: 'org.apache.ws.commons.axiom', name: 'axiom-api', version: '1.2.22'
+    implementation group: 'org.apache.ws.commons.axiom', name: 'axiom-impl', version: '1.2.22'
+    implementation group: 'com.thaiopensource', name: 'jing', version: '20091111'
+    implementation 'org.jetbrains:annotations:19.0.0'
+
+    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
+
+    jastadd2 "org.jastadd:jastadd:2.3.4"
+}
+
+// Default run configuration
+run {
+    mainClassName = 'de.tudresden.inf.st.pnml.Main'
+    standardInput = System.in
+}
+
+// Generated files
+def ecoreFile = "./src/main/resources/placeTransition.ecore"
+def relastAspect = "./src/gen/jastadd/pnml/placeTransition.ecore.jadd"
+def relastFile = "./src/gen/jastadd/pnml/placeTransition.relast"
+
+// First phase: Ecore -> RelAst
+task ecoreToRelast(type: JavaExec) {
+    group = 'Build'
+    main = "-jar"
+
+
+    doFirst {
+        delete "src/gen/jastadd"
+        mkdir "src/gen/jastadd/pnml"
+    }
+
+    args "libs/ecore2relast-0.1.jar", ecoreFile, relastFile
+
+    inputs.files file(ecoreFile)
+    outputs.files file(relastFile), file(relastAspect)
+}
+
+// Second phase: RelAst -> JastAdd
+task relastToJastAdd(type: JavaExec) {
+    group = 'Build'
+    main = "-jar"
+
+    args "libs/relast.jar",
+            "--grammarName=./src/gen/jastadd/placeTransition",
+            "--useJastAddNames",
+            "--listClass=ArrayList",
+            "--jastAddList=JastAddList",
+            "--resolverHelper",
+            "--file",
+            relastFile,
+            "./src/main/jastadd/marking/Marking.relast",
+            "./src/main/jastadd/io/IoPN.relast"
+}
+
+// Third phase: JastAdd -> Java (using JastAdd Gradle plugin)
+jastadd {
+    configureModuleBuild()
+    modules {
+        module("pnml") {
+
+            java {
+                basedir "src/"
+                include "main/**/*.java"
+                include "gen/**/*.java"
+            }
+
+            jastadd {
+                basedir "src/"
+                include "main/jastadd/**/*.ast"
+                include "main/jastadd/**/*.jadd"
+                include "main/jastadd/**/*.jrag"
+                include "gen/jastadd/**/*.ast"
+                include "gen/jastadd/**/*.jadd"
+                include "gen/jastadd/**/*.jrag"
+            }
+
+            scanner {
+                include "src/main/jastadd/PnmlScanner.flex"
+            }
+
+            parser {
+                include "src/main/jastadd/PnmlParser.parser"
+            }
+        }
+    }
+
+    cleanGen.doFirst {
+        delete "src/gen/java/de"
+        delete "src/gen-res/BuildInfo.properties"
+    }
+
+    module = "pnml"
+
+    astPackage = 'de.tudresden.inf.st.pnml.jastadd.model'
+
+    genDir = 'src/gen/java'
+
+    buildInfoDir = 'src/gen-res'
+
+    scanner.genDir = "src/gen/java/de/tudresden/inf/st/pnml/jastadd/scanner"
+    parser.genDir = "src/gen/java/de/tudresden/inf/st/pnml/jastadd/parser"
+
+//  default options are: '--rewrite=cnta', '--safeLazy', '--visitCheck=false', '--cacheCycle=false'
+    extraJastAddOptions = ['--List=JastAddList'] // '--incremental=param'
+}
+
+// Workflow configuration for phases
+relastToJastAdd.dependsOn ecoreToRelast
+generateAst.dependsOn relastToJastAdd
+
+//// always run jastadd
+//jastadd.outputs.upToDateWhen {false}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..8dfaf2b21cba4862b382e4bb5d7a3173956f99d0
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,2 @@
+jackson_version = 2.9.8
+apache_httpcomponents_version = 4.5.8
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..5c2d1cf016b3885f6930543d57b744ea8c220a1a
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..30bda3b74e65e2f3b2006eb11fb752c9395a977b
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Mar 27 11:59:50 CET 2020
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000000000000000000000000000000000..83f2acfdc319a24e8766cca78f32474ad7a22dd6
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,188 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..9618d8d9607cd91a0efb866bcac4810064ba6fac
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,100 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/libs/dumpAst-0.3.3.jar b/libs/dumpAst-0.3.3.jar
new file mode 100644
index 0000000000000000000000000000000000000000..9db9b053aa1d931139e4bf83a1d1cfaa1e6e0dfb
Binary files /dev/null and b/libs/dumpAst-0.3.3.jar differ
diff --git a/libs/ecore2relast-0.1.jar b/libs/ecore2relast-0.1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..0b4405335f990892b3a6731579d64b4698d3aec6
Binary files /dev/null and b/libs/ecore2relast-0.1.jar differ
diff --git a/libs/ragconnect-0.2.5.jar b/libs/ragconnect-0.2.5.jar
new file mode 100644
index 0000000000000000000000000000000000000000..459d1282cedfcd9502eb329c3596c31a3cca4173
Binary files /dev/null and b/libs/ragconnect-0.2.5.jar differ
diff --git a/libs/relast.jar b/libs/relast.jar
new file mode 100644
index 0000000000000000000000000000000000000000..a3430dfc1754b92676e2beb6b9f8ce4f1bb4429f
Binary files /dev/null and b/libs/relast.jar differ
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0d4ff7823810ae1346d8b16bcd15feefda06e314
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'pnml-splitter'
diff --git a/src/gen-res/BuildInfo.properties b/src/gen-res/BuildInfo.properties
new file mode 100644
index 0000000000000000000000000000000000000000..a2440a72cfa851ff722e40e349041a718103b316
--- /dev/null
+++ b/src/gen-res/BuildInfo.properties
@@ -0,0 +1,7 @@
+#Mon, 22 Mar 2021 15:24:06 +0100
+
+moduleId=pnml
+moduleName=null
+moduleVariant=null
+timestamp=2021-03-22T15\:24Z
+build.date=2021-03-22
diff --git a/src/main/jastadd/Constraints.jrag b/src/main/jastadd/Constraints.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..f713c77bc4faad5090def9447b155f98b5e12452
--- /dev/null
+++ b/src/main/jastadd/Constraints.jrag
@@ -0,0 +1,91 @@
+aspect Constraints {
+
+  coll Set<ConstraintViolation> PetriNet.constraintViolations() [new java.util.HashSet()] root PetriNet;
+
+}
+
+aspect ConstraintViolations {
+
+  abstract class ConstraintViolation {
+
+
+    public String toString() {
+      return "Constraint " + getTitle() + " violated in object " + id() + ": " + getMessage();
+    }
+
+    protected ASTNode location;
+
+    public String id() {
+      if (location instanceof PnObject) return ((PnObject) location).getId();
+      if (location instanceof PetriNet) return ((PetriNet) location).getId();
+      return location.toString();
+    }
+
+    protected String title;
+    protected String description;
+    protected String message;
+
+    public String getTitle() { return title; }
+    public String getDescription() { return description; }
+    public String getMessage() { return message; }
+
+  }
+
+  class CheckIdsConstraint extends ConstraintViolation {
+    public CheckIdsConstraint(ASTNode location) {
+      this.location = location;
+      this.title = "CheckIds";
+      this.description = "Checks id attribute existence";
+      this.message = "A node of type '" + location.getClass().getSimpleName() + "' must have an id attribute.";
+    }
+  }
+
+  class CheckIdUniquenessConstraint extends ConstraintViolation {
+    public CheckIdUniquenessConstraint(ASTNode location) {
+      this.location = location;
+      this.title = "CheckIdUniquess";
+      this.description = "Checks id attribute uniqueness";
+      this.message = "The id attribute value " + id() + " of the node of type '" + location.getClass().getSimpleName() + "' is not unique.";
+    }
+  }
+
+  PetriNet contributes new CheckIdsConstraint(this)
+      when checkIdsConstraintViolated()
+      to PetriNet.constraintViolations();
+  PnObject contributes new CheckIdsConstraint(this)
+      when checkIdsConstraintViolated()
+      to PetriNet.constraintViolations();
+}
+
+aspect CoreModelConstraints {
+
+  syn boolean PetriNet.checkIdsConstraintViolated() = getId() == null || getId().equals("");
+  syn boolean PnObject.checkIdsConstraintViolated() = getId() == null || getId().equals("");
+
+  coll List<String> PetriNet.ids() [new ArrayList()] root PetriNet;
+  PnObject contributes getId() to PetriNet.ids();
+
+  syn Map<String, Long> PetriNet.idCount() =
+      ids().stream().collect(Collectors.groupingBy(java.util.function.Function.identity(), Collectors.counting()));
+
+  syn boolean PetriNet.uniqueId(String id) = idCount().get(id) <= 1;
+  syn boolean PnObject.uniqueId(String id) = petriNet().idCount().get(id) <= 1;
+
+  syn Optional<CheckIdUniquenessConstraint> PetriNet.checkIdUniqueness() {
+    if(uniqueId(getId())) return Optional.empty();
+    else return Optional.of(new CheckIdUniquenessConstraint(this));
+  }
+  syn Optional<CheckIdUniquenessConstraint> PnObject.checkIdUniqueness() {
+    if(petriNet().uniqueId(getId())) return Optional.empty();
+    else return Optional.of(new CheckIdUniquenessConstraint(this));
+  }
+
+  PetriNet contributes checkIdUniqueness().get()
+      when checkIdUniqueness().isPresent()
+      to PetriNet.constraintViolations();
+  PnObject contributes checkIdUniqueness().get()
+      when checkIdUniqueness().isPresent()
+      to PetriNet.constraintViolations();
+
+
+}
diff --git a/src/main/jastadd/Graphviz.jrag b/src/main/jastadd/Graphviz.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..07ca5fcfd74cf449178e5a55b0a77dbed2074be6
--- /dev/null
+++ b/src/main/jastadd/Graphviz.jrag
@@ -0,0 +1,42 @@
+aspect Graphviz {
+  syn String PetriNet.toDot() {
+
+    StringBuffer b = new StringBuffer();
+
+    b.append("digraph \"").append(name()).append("\" {\n")
+        .append("  rankdir=LR;\n")
+        .append("  center=true; margin=1;\n")
+        .append("\n")
+        .append("  subgraph places {\n")
+        .append("    node [shape=circle,fixedsize=true,label=\"\", height=.3,width=.3];\n");
+
+    for (Place place : allPlaces()) {
+      b.append("    ").append(place.dotId()).append(" [");
+      if (place.hasName()) b.append("xlabel=\"").append(place.name()).append("\", ");
+      b.append("label=\"").append("0").append("\"];\n");
+    }
+
+    b.append("  }\n\n");
+
+    b.append("  subgraph transitions {\n")
+        .append("    node [shape=rect,height=0.4,width=.4];\n");
+    for (Transition transition : allTransitions()) {
+      b.append("    ").append(transition.dotId()).append(" [");
+      if (transition.hasName()) b.append("label=\"").append(transition.name()).append("\"");
+      b.append("]\n");
+    }
+
+    b.append("  }\n\n");
+
+    for (Arc arc : allArcs()) {
+      b.append("  ").append(arc.getSource().dotId()).append("->").append(arc.getTarget().dotId()).append(";\n");
+    }
+    b.append("}\n");
+
+    return b.toString();
+  }
+
+  syn String PetriNet.dotId() = "\"" + getId().replaceAll("\"", "\\\"") + "\"";
+  syn String PnObject.dotId() = "\"" + getId().replaceAll("\"", "\\\"") + "\"";
+
+}
diff --git a/src/main/jastadd/Navigation.jrag b/src/main/jastadd/Navigation.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..38b4d06c7c82c1b90cd69591abaa68dc432e0c20
--- /dev/null
+++ b/src/main/jastadd/Navigation.jrag
@@ -0,0 +1,67 @@
+aspect Navigation {
+  inh PetriNet PnObject.petriNet();
+  eq PetriNet.getChild().petriNet() = this;
+
+  java.util.Collection<Place> Transition.incomingPlaces() {
+    java.util.Set<Place> incomingPlaces = new java.util.HashSet<>();
+    for (Arc incomingArc : getInArcList()) {
+      incomingPlaces.add(incomingArc.getSource().asPlaceNode().place());
+    }
+    return incomingPlaces;
+  }
+
+  java.util.Collection<Place> Transition.outgoingPlaces() {
+    java.util.Set<Place> outgoingPlaces = new java.util.HashSet<>();
+    for (Arc outgoingArc : getOutArcList()) {
+      outgoingPlaces.add(outgoingArc.getTarget().asPlaceNode().place());
+    }
+    return outgoingPlaces;
+  }
+
+  syn boolean Node.isPlaceNode() = false;
+  eq PlaceNode.isPlaceNode() = true;
+
+  syn PlaceNode Node.asPlaceNode() = null;
+  eq PlaceNode.asPlaceNode() = this;
+
+  syn boolean Node.isTransitionNode() = false;
+  eq TransitionNode.isTransitionNode() = true;
+
+  syn TransitionNode Node.asTransitionNode() = null;
+  eq TransitionNode.asTransitionNode() = this;
+
+  syn InputSignalTransition Transition.asInputSignalTransition() = null;
+  eq InputSignalTransition.asInputSignalTransition() = this;
+
+  syn OutputSignalPlace Place.asOutputSignalPlace() = null;
+  eq OutputSignalPlace.asOutputSignalPlace() = this;
+
+  syn Place PlaceNode.place();
+  eq Place.place() = this;
+  eq RefPlace.place() = getRef().place();
+
+  syn Transition TransitionNode.transition();
+  eq Transition.transition() = this;
+  eq RefTransition.transition() = getRef().transition();
+
+  coll java.util.Set<PnObject> PetriNet.allObjects() [new java.util.HashSet()] root PetriNet;
+  PnObject contributes this
+    to PetriNet.allObjects()
+    for petriNet();
+
+  coll java.util.Set<Place> PetriNet.allPlaces() [new java.util.HashSet()] root PetriNet;
+  Place contributes this
+    to PetriNet.allPlaces()
+    for petriNet();
+
+  coll java.util.Set<Transition> PetriNet.allTransitions() [new java.util.HashSet()] root PetriNet;
+  Transition contributes this
+    to PetriNet.allTransitions()
+    for petriNet();
+
+  coll java.util.Set<Arc> PetriNet.allArcs() [new java.util.HashSet()] root PetriNet;
+  Arc contributes this
+    to PetriNet.allArcs()
+    for petriNet();
+
+}
diff --git a/src/main/jastadd/References.jrag b/src/main/jastadd/References.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..bce6451f2d7dd420d92c767b7a282df31381a3b2
--- /dev/null
+++ b/src/main/jastadd/References.jrag
@@ -0,0 +1,18 @@
+aspect References {
+
+  syn PnObject PetriNet.resolve(String id) {
+    for (PnObject object : allObjects()) {
+      if (object.getId().equals(id)) {
+        return object;
+      }
+    }
+    throw new RuntimeException(new de.tudresden.inf.st.pnml.PnmlParseException("Unable to resolve id " + id));
+  }
+
+  eq PnObject.globallyResolveArcByToken(String id) = (Arc) petriNet().resolve(id);
+  eq PnObject.globallyResolveNodeByToken(String id) = (Node) petriNet().resolve(id);
+  eq PnObject.globallyResolvePlaceNodeByToken(String id) = (PlaceNode) petriNet().resolve(id);
+  eq PnObject.globallyResolveTransitionNodeByToken(String id) = (TransitionNode) petriNet().resolve(id);
+  eq PnObject.globallyResolveRefPlaceByToken(String id) = (RefPlace) petriNet().resolve(id);
+  eq PnObject.globallyResolveRefTransitionByToken(String id) = (RefTransition) petriNet().resolve(id);
+}
diff --git a/src/main/jastadd/Util.jadd b/src/main/jastadd/Util.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..fb2cf4befd6e539ded5d88b88cb7c6940113b0d7
--- /dev/null
+++ b/src/main/jastadd/Util.jadd
@@ -0,0 +1,31 @@
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import java.util.*;
+import java.util.stream.Collectors;
+
+aspect Logging {
+  static Logger ASTNode.logger = LogManager.getLogger(ASTNode.class);
+}
+
+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!");
+  }
+}
diff --git a/src/main/jastadd/distribution/DistributedPN.jadd b/src/main/jastadd/distribution/DistributedPN.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..08110b5376eb37090d0f6f6b758a15d967f8ec55
--- /dev/null
+++ b/src/main/jastadd/distribution/DistributedPN.jadd
@@ -0,0 +1,30 @@
+aspect PnDistribution {
+
+    syn lazy String Transition.location() {
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.getLocationFromToolSpecifics(this.getToolspecificList());
+    }
+
+    syn lazy String Transition.type() {
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.getTransitionTypeFromToolSpecifics(this.getToolspecificList());
+    }
+
+    syn lazy String Place.location() {
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.getLocationFromToolSpecifics(this.getToolspecificList());
+    }
+
+    syn lazy String Place.type() {
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.getPlaceTypeFromToolSpecifics(this.getToolspecificList());
+    }
+
+    syn lazy Boolean Transition.isLimitedChannelTransition() {
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.isLimitedChannelTransitionType(this.getToolspecificList());
+    }
+
+    syn lazy int Transition.channelLimit() {
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.getLimitedChannelTransitionValue(this.getToolspecificList());
+    }
+
+    syn lazy String Transition.getTopic(){
+        return de.tudresden.inf.st.pnml.ToolSpecificsParser.getTopic(this.getToolspecificList());
+    }
+}
\ No newline at end of file
diff --git a/src/main/jastadd/io/IoPN.jadd b/src/main/jastadd/io/IoPN.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..5a37d6028d8813d51b225921c1d3a24ac53d44c3
--- /dev/null
+++ b/src/main/jastadd/io/IoPN.jadd
@@ -0,0 +1,82 @@
+aspect IoPnExtension{
+
+        inh Marking OutputSignalPlace.marking();
+
+        eq PetriNetDoc.getChild().marking() = null;
+
+        eq Marking.getPetriNet().marking() = this;
+
+        inh Place OutputSignalBinding.containingPlace();
+
+        eq OutputSignalPlace.getOutputSignalBinding().containingPlace() = this;
+
+        eq Page.getObject().containingPlace() = null;
+
+        syn lazy JastAddList<InputSignalBinding> InputSignalTransition.getInputSignalBindingList() {
+
+            JastAddList<InputSignalBinding> isBindings = de.tudresden.inf.st.postprocessing.IoPetriNetPostProcessor.parseInputSignalBindingDefinitions(this.getToolspecificList());
+
+            return isBindings;
+        }
+
+        syn lazy JastAddList<OutputSignalBinding> OutputSignalPlace.getOutputSignalBindingList() {
+
+            JastAddList<OutputSignalBinding> osBindings = de.tudresden.inf.st.postprocessing.IoPetriNetPostProcessor.parseOutputSignalBindingDefinitions(this.getToolspecificList());
+
+            return osBindings;
+        }
+
+        // updates automatically based on dependencies to the corresponding place
+        syn String OutputSignalBinding.getOutputSignalValue(){
+
+            OutputSignalPlace osp = this.containingPlace().asOutputSignalPlace();
+            Marking marking = osp.marking();
+            MarkedPlace markedPlace = marking.resolvePlaceById(this.getPlaceID());
+
+            JastAddList<EqualityOutputMapping> eomList = this.getEqualityOMListNoTransform();
+            JastAddList<ThresholdOutputMapping> tomList = this.getThresholdOMListNoTransform();
+            JastAddList<RangeOutputMapping> romList = this.getRangeOMListNoTransform();
+
+            // eom
+
+            int result = -1;
+
+            for(EqualityOutputMapping eom : eomList){
+                if((eom.getValue() == markedPlace.getMarking()) && result == -1){
+                    result = eom.getResult();
+                    break;
+                }
+            }
+
+            // tom
+
+            if(result > -1){
+                for(ThresholdOutputMapping tom : tomList){
+                    if(tom.getValue() <= markedPlace.getMarking()){
+                        result = tom.getResult();
+                        break;
+                    }
+                }
+            }
+
+            // rom
+
+            if(result > -1){
+                for(RangeOutputMapping rom: romList){
+                    if((rom.getLowerBound() <= markedPlace.getMarking()) && (rom.getUpperBound() >= markedPlace.getMarking())){
+                        result = rom.getResult();
+                        break;
+                    }
+                }
+            }
+
+            // 0 (disabled Signal) is default
+            if(result == -1){
+                result = 0;
+            }
+
+            String output = String.valueOf(result) + "-" + this.getOutputSignalID();
+
+            return output;
+        }
+}
\ No newline at end of file
diff --git a/src/main/jastadd/io/IoPN.relast b/src/main/jastadd/io/IoPN.relast
new file mode 100644
index 0000000000000000000000000000000000000000..b659cb7a2cd2edc98e3a60b37e7059bd9b81f5ff
--- /dev/null
+++ b/src/main/jastadd/io/IoPN.relast
@@ -0,0 +1,11 @@
+InputSignalBinding : PnObject ::= <TransitionID:String> <InputSignalID:String> <InputSignalValue:int>;
+OutputSignalBinding : PnObject ::= <PlaceID:String> <OutputSignalID:String> /<OutputSignalValue:String>/ EqualityOM:EqualityOutputMapping* ThresholdOM:ThresholdOutputMapping* RangeOM:RangeOutputMapping*;
+
+InputSignalTransition : Transition ::= /InputSignalBinding*/;
+OutputSignalPlace : Place ::= /OutputSignalBinding*/;
+
+OutputMapping;
+
+EqualityOutputMapping : OutputMapping ::= <Value:java.lang.Integer> <Result:java.lang.Integer>;
+ThresholdOutputMapping : OutputMapping ::= <Value:java.lang.Integer> <Result:java.lang.Integer>;
+RangeOutputMapping : OutputMapping ::= <UpperBound:java.lang.Integer> <LowerBound:java.lang.Integer> <Result:java.lang.Integer>;
diff --git a/src/main/jastadd/marking/Execution.jadd b/src/main/jastadd/marking/Execution.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..e6bda62525b76b1f417843802a6ed622ac30ead5
--- /dev/null
+++ b/src/main/jastadd/marking/Execution.jadd
@@ -0,0 +1,99 @@
+import de.tudresden.inf.st.pnml.PnmlConstants;
+
+aspect Execution {
+
+  public boolean Marking.fireInPlace() {
+    return fireInPlace(new Random());
+  }
+
+  public boolean Marking.fireInPlace(java.util.Random random) {
+    return fireInPlace(random, true).isPresent();
+  }
+
+  public Optional<Marking> Marking.fireTransition(Transition transition, boolean requireFlush) {
+
+    if(transition.type().equals(PnmlConstants.TRANSITION_TYPE_DISCRETE)){
+
+        transition.incomingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()-1));
+        transition.outgoingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()+1));
+
+        if (requireFlush) {
+          this.flushTreeCache();
+        }
+
+        return Optional.of(this);
+    }
+    return null;
+  }
+
+  public Optional<Marking> Marking.fireChannelTransitionOutput(Transition transition, boolean requireFlush) {
+
+    if(transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT)
+        || transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)){
+
+        transition.incomingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()-1));
+
+        if (requireFlush) {
+          this.flushTreeCache();
+        }
+
+        return Optional.of(this);
+    }
+    return null;
+  }
+
+  public Optional<Marking> Marking.fireChannelTransitionInput(Transition transition, boolean requireFlush) {
+
+     if(transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN)
+        || transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN)){
+
+        transition.outgoingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()+1));
+
+     if (requireFlush) {
+       this.flushTreeCache();
+     }
+
+     return Optional.of(this);
+     }
+  return null;
+  }
+
+  private Optional<Marking> Marking.fireInPlace(java.util.Random random, boolean requireFlush) {
+    if(enabledTransitions().isEmpty()) return Optional.empty();
+
+    // select a random transition
+    Transition transition = enabledTransitions().stream()
+        .sorted((t1, t2) -> t1.getId().compareTo(t2.getId()))
+        .skip(random.nextInt(enabledTransitions().size()))
+        .findFirst().get();
+
+    // take a token from each incoming place
+    transition.incomingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()-1));
+
+    // place a token in each outgoing place
+    transition.outgoingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()+1));
+
+    if (requireFlush) {
+      // flush the entire marking tree
+      this.flushTreeCache();
+    }
+
+    return Optional.of(this);
+  }
+
+  public java.util.Collection<Place> Marking.collectIncomingPlace(Transition transition){
+    return transition.incomingPlaces();
+  }
+
+  public java.util.Collection<Place> Marking.collectOutgoingPlace(Transition transition){
+    return transition.outgoingPlaces();
+  }
+
+  public Optional<Marking> Marking.fire() {
+    return fire(new Random());
+  }
+
+  public Optional<Marking> Marking.fire(java.util.Random random) {
+    return treeCopyNoTransform().fireInPlace(random, false);
+  }
+}
diff --git a/src/main/jastadd/marking/Marking.jrag b/src/main/jastadd/marking/Marking.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..17c5f98908ce0dacea26bacc346e8a9d2fad9bf6
--- /dev/null
+++ b/src/main/jastadd/marking/Marking.jrag
@@ -0,0 +1,74 @@
+aspect Marking {
+  public Marking PetriNet.initialMarking(PetriNet pn) {
+    Marking marking = new Marking();
+    marking.setPetriNet(pn);
+    for (Place place : allPlaces()) {
+      MarkedPlace markedPlace = new MarkedPlace();
+      markedPlace.setPlace(place);
+      if (place.hasInitialMarking() && place.getInitialMarking().getText() != null) {
+        markedPlace.setMarking(place.getInitialMarking().getText());
+      } else {
+        markedPlace.setMarking(0);
+      }
+      marking.addPlace(markedPlace);
+    }
+    return marking;
+  }
+
+  public Marking PetriNet.setupMarking(PetriNet pn) {
+
+    Marking marking = new Marking();
+    marking.setPetriNet(pn);
+
+    for (Place place : allPlaces()) {
+
+        MarkedPlace markedPlace = new MarkedPlace();
+        markedPlace.setPlace(place);
+        markedPlace.setMarking(1);
+
+        marking.addPlace(markedPlace);
+    }
+    return marking;
+  }
+
+  syn MarkedPlace Marking.resolvePlace(Place place) = placeMap().get(place);
+
+  syn lazy java.util.Map<Place, MarkedPlace> Marking.placeMap() {
+    java.util.Map<Place, MarkedPlace> map = new java.util.HashMap<>();
+    for (MarkedPlace markedPlace : getPlaceList()) {
+      map.put(markedPlace.getPlace(), markedPlace);
+    }
+    return map;
+  }
+
+  syn MarkedPlace Marking.resolvePlaceById(String placeID) {
+
+    for (MarkedPlace markedPlace : getPlaceList()) {
+          if(markedPlace.getPlace().getId().equals(placeID)){
+            return markedPlace;
+        }
+    }
+    return null;
+  }
+
+  syn int Marking.marking(Place place) = resolvePlace(place).getMarking();
+
+  syn boolean Marking.isEnabled(Transition t) {
+    for (Place place : t.incomingPlaces()) {
+      if (marking(place) == 0) return false;
+    }
+    return true;
+  }
+
+  syn boolean Marking.isDead() {
+    for (Transition transition : getPetriNet().allTransitions()) {
+      if (isEnabled(transition)) return false;
+    }
+    return true;
+  }
+
+  syn java.util.Set<Transition> Marking.enabledTransitions()
+      = getPetriNet().allTransitions().stream()
+          .filter(t -> isEnabled(t))
+          .collect(Collectors.toSet());
+}
diff --git a/src/main/jastadd/marking/Marking.relast b/src/main/jastadd/marking/Marking.relast
new file mode 100644
index 0000000000000000000000000000000000000000..487b28226d7c9f73686ea4eb78495bbcee7bf488
--- /dev/null
+++ b/src/main/jastadd/marking/Marking.relast
@@ -0,0 +1,4 @@
+Marking ::= PetriNet:PetriNet Place:MarkedPlace*;
+MarkedPlace ::= <Marking:int>;
+
+rel MarkedPlace.Place -> Place;
diff --git a/src/main/jastadd/marking/Printing.jrag b/src/main/jastadd/marking/Printing.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..e89c16e4610fcfd8afaced338844e5f122b54f86
--- /dev/null
+++ b/src/main/jastadd/marking/Printing.jrag
@@ -0,0 +1,17 @@
+aspect Printing {
+  syn String Marking.print() {
+    StringBuilder b = new StringBuilder();
+    b.append("Marking for Petri net '").append(getPetriNet().name()).append("':\n");
+    for (MarkedPlace place : getPlaceList()) {
+      b.append("  ").append(place.getPlace().name()).append(": ").append(place.getMarking()).append("\n");
+    }
+    b.append("Transitions for Petri net '").append(getPetriNet().name()).append("':\n");
+    for (Transition trans : getPetriNet().allTransitions()) {
+      b.append("  ").append(trans.name()).append(": ").append(isEnabled(trans)?"true":"false").append("\n");
+    }
+    return b.toString();
+  }
+
+  syn String PetriNet.name() = hasName()?getName().getText():getId();
+  syn String PnObject.name() = hasName()?getName().getText():getId();
+}
diff --git a/src/main/java/de/tudresden/inf/st/pnml/Main.java b/src/main/java/de/tudresden/inf/st/pnml/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1358a44192b498e5d6ee23ad8d51933d43aa706
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/pnml/Main.java
@@ -0,0 +1,13 @@
+package de.tudresden.inf.st.pnml;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Main {
+
+    private static final Logger logger = LoggerFactory.getLogger(Main.class);
+
+    public static void main(String[] args) {
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/de/tudresden/inf/st/pnml/PnmlConstants.java b/src/main/java/de/tudresden/inf/st/pnml/PnmlConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..956ffaa8191504651e31b32e462c1bca07102d86
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/pnml/PnmlConstants.java
@@ -0,0 +1,45 @@
+package de.tudresden.inf.st.pnml;
+
+public final class PnmlConstants {
+
+    public static final String TRANSITION_TYPE_DISCRETE = "discreteTransitionType";
+    public static final String TRANSITION_TYPE_CONTINUOUS = "continuousTransitionType";
+
+    public static final String TRANSITION_TYPE_CHANNEL_AC = "acChannelTransitionType";
+    public static final String TRANSITION_TYPE_CHANNEL_NOT_AC = "notAcChannelTransitionType";
+    public static final String TRANSITION_TYPE_CHANNEL_ACK_AC = "ackAcChannelTransitionType";
+    public static final String TRANSITION_TYPE_CHANNEL_LIMITED_IN = "limitedChannelInType";
+    public static final String TRANSITION_TYPE_CHANNEL_UNLIMITED_IN = "unlimitedChannelInType";
+
+    public static final String TRANSITION_TYPE_CHANNEL_LIMITED_OUT = "limitedChannelOutType";
+    public static final String TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT = "unlimitedChannelOutType";
+
+    public static final String PLACE_TYPE_DISCRETE = "discretePlaceType";
+    public static final String PLACE_TYPE_CONTINUOUS = "continuousPlaceType";
+
+    public static final String LOCATION_KEY = "location";
+    public static final String TYPE_KEY = "type";
+    public static final String LIMIT_KEY = "limit";
+    public static final String TOPIC_KEY = "topic";
+
+    public static final String INPUT_SIGNAL_BINDINGS_KEY = "inputsignalbindings";
+    public static final String OUTPUT_SIGNAL_BINDINGS_KEY = "outputsignalbindings";
+
+    public static final String INPUT_SIGNAL_BINDING_KEY = "inputsignalbinding";
+    public static final String OUTPUT_SIGNAL_BINDING_KEY = "outputsignalbinding";
+
+    public static final String TRANSITION_ID_KEY = "transitionID";
+    public static final String INPUT_SIGNAL_ID_KEY = "inputsignalID";
+    public static final String PLACE_ID_KEY = "placeID";
+    public static final String OUTPUT_SIGNAL_ID_KEY = "outputsignalID";
+    public static final String CURRENT_VALUE_KEY = "initialvalue";
+
+    public static final String EQUAL_OS_KEY = "equal";
+    public static final String RANGE_OS_KEY = "range";
+    public static final String TRESHOLD_KEY = "threshold";
+
+    public static final String VALUE_KEY = "value";
+    public static final String RESULT_KEY = "result";
+    public static final String UPPER_BOUND_KEY = "upperbound";
+    public static final String LOWER_BOUND_KEY = "lowerbound";
+}
diff --git a/src/main/java/de/tudresden/inf/st/pnml/PnmlParseException.java b/src/main/java/de/tudresden/inf/st/pnml/PnmlParseException.java
new file mode 100644
index 0000000000000000000000000000000000000000..0af92a3440ba07e3b3b028e212960d89b6247e4b
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/pnml/PnmlParseException.java
@@ -0,0 +1,17 @@
+package de.tudresden.inf.st.pnml;
+
+public class PnmlParseException extends Exception {
+
+  public PnmlParseException(String message) {
+    super(message);
+  }
+
+  public PnmlParseException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public PnmlParseException(Throwable cause) {
+    super(cause);
+  }
+
+}
diff --git a/src/main/java/de/tudresden/inf/st/pnml/PnmlParser.java b/src/main/java/de/tudresden/inf/st/pnml/PnmlParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..766adc5d2d9fbc9750efc0c97b3256813a79354b
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/pnml/PnmlParser.java
@@ -0,0 +1,422 @@
+package de.tudresden.inf.st.pnml;
+
+import de.tudresden.inf.st.pnml.jastadd.model.*;
+
+public class PnmlParser {
+
+  private final PetriNet petriNet;
+
+  public PnmlParser(fr.lip6.move.pnml.ptnet.PetriNet source) throws PnmlParseException {
+    this.petriNet = getPetriNet(source);
+    petriNet.treeResolveAll();
+  }
+
+  public PetriNet getPetriNet() {
+    return petriNet;
+  }
+
+  // the get methods
+
+  private PetriNet getPetriNet(fr.lip6.move.pnml.ptnet.PetriNet source) throws PnmlParseException {
+    PetriNet result = new PetriNet();
+    fillPetriNet(source, result);
+    return result;
+  }
+
+  private Page getPage(fr.lip6.move.pnml.ptnet.Page source) throws PnmlParseException {
+    Page result = new Page();
+    fillPage(source, result);
+    return result;
+  }
+
+  private NodeGraphics getNodeGraphics(fr.lip6.move.pnml.ptnet.NodeGraphics source) {
+    NodeGraphics result = new NodeGraphics();
+    fillNodeGraphics(source, result);
+    return result;
+  }
+
+  private Line getLine(fr.lip6.move.pnml.ptnet.Line source) {
+    Line result = new Line();
+    fillLine(source, result);
+    return result;
+  }
+
+  private Fill getFill(fr.lip6.move.pnml.ptnet.Fill source) {
+    Fill result = new Fill();
+    fillFill(source, result);
+    return result;
+  }
+
+  private Dimension getDimension(fr.lip6.move.pnml.ptnet.Dimension source) {
+    Dimension result = new Dimension();
+    fillDimension(source, result);
+    return result;
+  }
+
+  private Offset getOffset(fr.lip6.move.pnml.ptnet.Offset source) {
+    Offset result = new Offset();
+    fillOffset(source, result);
+    return result;
+  }
+
+  private Position getPosition(fr.lip6.move.pnml.ptnet.Position source) {
+    Position result = new Position();
+    fillPosition(source, result);
+    return result;
+  }
+
+  private Name getName(fr.lip6.move.pnml.ptnet.Name source) {
+    Name result = new Name();
+    fillName(source, result);
+    return result;
+  }
+
+  private AnnotationGraphics getAnnotationGraphics(fr.lip6.move.pnml.ptnet.AnnotationGraphics source) {
+    AnnotationGraphics result = new AnnotationGraphics();
+    fillAnnotationGraphics(source, result);
+    return result;
+  }
+
+  private Font getFont(fr.lip6.move.pnml.ptnet.Font source) {
+    Font result = new Font();
+    fillFont(source, result);
+    return result;
+  }
+
+  private ToolInfo getToolInfo(fr.lip6.move.pnml.ptnet.ToolInfo source) {
+    ToolInfo result = new ToolInfo();
+    fillToolInfo(source, result);
+    return result;
+  }
+
+  private Node getNode(fr.lip6.move.pnml.ptnet.Node source) throws PnmlParseException {
+    if (source instanceof fr.lip6.move.pnml.ptnet.PlaceNode) {
+      return getPlaceNode((fr.lip6.move.pnml.ptnet.PlaceNode) source);
+    } else if (source instanceof fr.lip6.move.pnml.ptnet.TransitionNode) {
+      return getTransitionNode((fr.lip6.move.pnml.ptnet.TransitionNode) source);
+    } else {
+      throw new PnmlParseException("Encountered illegal unknown subtype of Node " + source.getClass().getCanonicalName());
+    }
+  }
+
+  private PlaceNode getPlaceNode(fr.lip6.move.pnml.ptnet.PlaceNode source) throws PnmlParseException {
+    if (source instanceof fr.lip6.move.pnml.ptnet.Place) {
+      return getPlace((fr.lip6.move.pnml.ptnet.Place) source);
+    } else if (source instanceof fr.lip6.move.pnml.ptnet.RefPlace) {
+      return getRefPlace((fr.lip6.move.pnml.ptnet.RefPlace) source);
+    } else {
+      throw new PnmlParseException("Encountered illegal unknown subtype of PlaceNode " + source.getClass().getCanonicalName());
+    }
+  }
+
+  private Place getPlace(fr.lip6.move.pnml.ptnet.Place source) {
+    Place result = new OutputSignalPlace();
+    fillPlace(source, result);
+    return result;
+  }
+
+  private PTMarking getPTMarking(fr.lip6.move.pnml.ptnet.PTMarking source) {
+    PTMarking result = new PTMarking();
+    fillPTMarking(source, result);
+    return result;
+  }
+
+  private RefPlace getRefPlace(fr.lip6.move.pnml.ptnet.RefPlace source) {
+    RefPlace result = new RefPlace();
+    fillRefPlace(source, result);
+    return result;
+  }
+
+  private TransitionNode getTransitionNode(fr.lip6.move.pnml.ptnet.TransitionNode source) throws PnmlParseException {
+    if (source instanceof fr.lip6.move.pnml.ptnet.Transition) {
+      return getTransition((fr.lip6.move.pnml.ptnet.Transition) source);
+    } else if (source instanceof fr.lip6.move.pnml.ptnet.RefTransition) {
+      return getRefTransition((fr.lip6.move.pnml.ptnet.RefTransition) source);
+    } else {
+      throw new PnmlParseException("Encountered illegal unknown subtype of TransitionNode " + source.getClass().getCanonicalName());
+    }
+  }
+
+  private RefTransition getRefTransition(fr.lip6.move.pnml.ptnet.RefTransition source) {
+    RefTransition result = new RefTransition();
+    fillRefTransition(source, result);
+    return result;
+  }
+
+  private Transition getTransition(fr.lip6.move.pnml.ptnet.Transition source) {
+    Transition result = new InputSignalTransition();
+    fillTransition(source, result);
+    return result;
+  }
+
+  private Arc getArc(fr.lip6.move.pnml.ptnet.Arc source) {
+    Arc result = new Arc();
+    fillArc(source, result);
+    return result;
+  }
+
+  private PTArcAnnotation getPTArcannotation(fr.lip6.move.pnml.ptnet.PTArcAnnotation source) {
+    PTArcAnnotation result = new PTArcAnnotation();
+    fillPTAnnotation(source, result);
+    return result;
+  }
+
+  private ArcGraphics getArcGraphics(fr.lip6.move.pnml.ptnet.ArcGraphics source) {
+    ArcGraphics result = new ArcGraphics();
+    fillArcGraphics(source, result);
+    return result;
+  }
+
+  private PnObject getPnObject(fr.lip6.move.pnml.ptnet.PnObject source) throws PnmlParseException {
+    if (source instanceof fr.lip6.move.pnml.ptnet.Page) {
+      return getPage((fr.lip6.move.pnml.ptnet.Page) source);
+    } else if (source instanceof Node) {
+      return getNode((fr.lip6.move.pnml.ptnet.Node) source);
+    } else if (source instanceof fr.lip6.move.pnml.ptnet.Arc) {
+      return getArc((fr.lip6.move.pnml.ptnet.Arc) source);
+    } else if (source instanceof fr.lip6.move.pnml.ptnet.Node) {
+      return getNode((fr.lip6.move.pnml.ptnet.Node) source);
+    } else {
+      throw new PnmlParseException("Encountered illegal unknown subtype of PnObject " + source.getClass().getCanonicalName());
+    }
+  }
+
+  // the fill methods
+
+  private void fillPetriNet(fr.lip6.move.pnml.ptnet.PetriNet source, PetriNet result) throws PnmlParseException {
+    for (fr.lip6.move.pnml.ptnet.Page page : source.getPages()) {
+      result.addPage(getPage(page));
+    }
+    if (source.getName() != null) {
+      result.setName(getName(source.getName()));
+    }
+    for (fr.lip6.move.pnml.ptnet.ToolInfo toolInfo : source.getToolspecifics()) {
+      result.addToolspecific(getToolInfo(toolInfo));
+    }
+
+   // if(source.getToolspecifics().size() > 0) {
+   //   System.out.println("-->" + source.getToolspecifics());
+   // }
+
+    result.setId(source.getId());
+    if (source.getType() == fr.lip6.move.pnml.ptnet.PNType.PTNET) {
+      result.setType(PNType.PTNET);
+    } else {
+      throw new PnmlParseException("Illegal Petri Net type '" + source.getType().getLiteral() + "' encountered.");
+    }
+
+  }
+
+  private void fillPage(fr.lip6.move.pnml.ptnet.Page source, Page result) throws PnmlParseException {
+    fillPnObject(source, result);
+
+    for (fr.lip6.move.pnml.ptnet.PnObject object : source.getObjects()) {
+      result.addObject(getPnObject(object));
+    }
+    if (source.getNodegraphics() != null) {
+      result.setNodeGraphics(getNodeGraphics(source.getNodegraphics()));
+    }
+  }
+
+  private void fillPnObject(fr.lip6.move.pnml.ptnet.PnObject source, PnObject result) {
+    if (source.getName() != null) {
+      result.setName(getName(source.getName()));
+    }
+    for (fr.lip6.move.pnml.ptnet.ToolInfo toolInfo : source.getToolspecifics()) {
+      result.addToolspecific(getToolInfo(toolInfo));
+    }
+
+    result.setId(source.getId());
+  }
+
+  private void fillNodeGraphics(fr.lip6.move.pnml.ptnet.NodeGraphics source, NodeGraphics result) {
+    if (source.getPosition() != null) {
+      result.setPosition(getPosition(source.getPosition()));
+    }
+    if (source.getDimension() != null) {
+      result.setDimension(getDimension(source.getDimension()));
+    }
+    if (source.getFill() != null) {
+      result.setFill(getFill(source.getFill()));
+    }
+    if (source.getLine() != null) {
+      result.setLine(getLine(source.getLine()));
+    }
+  }
+
+  private void fillLine(fr.lip6.move.pnml.ptnet.Line source, Line result) {
+    result.setColor(CSS2Color.valueOf(source.getColor().getName()));
+    result.setShape(LineShape.valueOf(source.getShape().getName()));
+    result.setWidth(source.getWidth());
+    result.setStyle(LineStyle.valueOf(source.getStyle().getName()));
+  }
+
+  private void fillFill(fr.lip6.move.pnml.ptnet.Fill source, Fill result) {
+    result.setColor(CSS2Color.valueOf(source.getColor().getName()));
+    result.setGradientcolor(CSS2Color.valueOf(source.getGradientcolor().getName()));
+    result.setGradientrotation(Gradient.valueOf(source.getGradientrotation().getName()));
+    result.setImage(source.getImage());
+  }
+
+  private void fillDimension(fr.lip6.move.pnml.ptnet.Dimension source, Dimension result) {
+    fillCoordinate(source, result);
+  }
+
+  private void fillCoordinate(fr.lip6.move.pnml.ptnet.Coordinate source, Coordinate result) {
+    result.setX(source.getX());
+    result.setY(source.getY());
+  }
+
+  private void fillOffset(fr.lip6.move.pnml.ptnet.Offset source, Offset result) {
+    fillCoordinate(source, result);
+  }
+
+  private void fillPosition(fr.lip6.move.pnml.ptnet.Position source, Position result) {
+    fillCoordinate(source, result);
+  }
+
+  private void fillName(fr.lip6.move.pnml.ptnet.Name source, Name result) {
+    fillAnnotation(source, result);
+
+    result.setText(source.getText());
+  }
+
+  private void fillAnnotation(fr.lip6.move.pnml.ptnet.Annotation source, Annotation result) {
+    if (source.getAnnotationgraphics() != null) {
+      result.setAnnotationGraphics(getAnnotationGraphics(source.getAnnotationgraphics()));
+    }
+    fillLabel(source, result);
+  }
+
+  private void fillLabel(fr.lip6.move.pnml.ptnet.Annotation source, Annotation result) {
+    for (fr.lip6.move.pnml.ptnet.ToolInfo info : source.getToolspecifics()) {
+      result.addToolspecific(getToolInfo(info));
+    }
+  }
+
+  private void fillAnnotationGraphics(fr.lip6.move.pnml.ptnet.AnnotationGraphics source, AnnotationGraphics result) {
+    if (source.getOffset() != null) {
+      result.setOffset(getOffset(source.getOffset()));
+    }
+    if (source.getFill() != null) {
+      result.setFill(getFill(source.getFill()));
+    }
+    if (source.getLine() != null) {
+      result.setLine(getLine(source.getLine()));
+    }
+    if (source.getFont() != null) {
+      result.setFont(getFont(source.getFont()));
+    }
+  }
+
+  private void fillFont(fr.lip6.move.pnml.ptnet.Font source, Font result) {
+    result.setAlign(FontAlign.valueOf(source.getAlign().getName()));
+    result.setDecoration(FontDecoration.valueOf(source.getDecoration().getName()));
+    result.setFamily(CSS2FontFamily.valueOf(source.getFamily().getName()));
+    result.setRotation(source.getRotation());
+    result.setSize(CSS2FontSize.valueOf(source.getSize().getName()));
+    result.setStyle(CSS2FontStyle.valueOf(source.getStyle().getName()));
+    result.setWeight(CSS2FontWeight.valueOf(source.getWeight().getName()));
+  }
+
+  private void fillToolInfo(fr.lip6.move.pnml.ptnet.ToolInfo source, ToolInfo result) {
+    result.setTool(source.getTool());
+    result.setVersion(source.getVersion());
+    result.setFormattedXMLBuffer(source.getFormattedXMLBuffer());
+    result.setToolInfoGrammarURI(source.getToolInfoGrammarURI());
+  }
+
+  private void fillPlace(fr.lip6.move.pnml.ptnet.Place source, Place result) {
+    fillPlaceNode(source, result);
+
+    if (source.getInitialMarking() != null) {
+      result.setInitialMarking(getPTMarking(source.getInitialMarking()));
+    }
+  }
+
+  private void fillPTMarking(fr.lip6.move.pnml.ptnet.PTMarking source, PTMarking result) {
+    fillAnnotation(source, result);
+
+    // whatever this is supposed to be. they changed the Integer to Long
+    result.setText(Math.toIntExact(source.getText()));
+  }
+
+  private void fillRefPlace(fr.lip6.move.pnml.ptnet.RefPlace source, RefPlace result) {
+    fillPlaceNode(source, result);
+
+    result.setRef(PlaceNode.createRefDirection(source.getRef().getId()));
+  }
+
+  private void fillPlaceNode(fr.lip6.move.pnml.ptnet.PlaceNode source, PlaceNode result) {
+    fillNode(source, result);
+
+    for (fr.lip6.move.pnml.ptnet.RefPlace referencingPlace : source.getReferencingPlaces()) {
+      result.addReferencingPlace(RefPlace.createRefDirection(referencingPlace.getId()));
+    }
+  }
+
+  private void fillRefTransition(fr.lip6.move.pnml.ptnet.RefTransition source, RefTransition result) {
+    fillTransitionNode(source, result);
+
+    result.setRef(TransitionNode.createRefDirection(source.getRef().getId()));
+  }
+
+  private void fillTransitionNode(fr.lip6.move.pnml.ptnet.TransitionNode source, TransitionNode result) {
+    fillNode(source, result);
+
+    for (fr.lip6.move.pnml.ptnet.RefTransition refTransition : source.getReferencingTransitions()) {
+      result.addReferencingTransition(RefTransition.createRefDirection(refTransition.getId()));
+    }
+  }
+
+  private void fillTransition(fr.lip6.move.pnml.ptnet.Transition source, Transition result) {
+    fillTransitionNode(source, result);
+  }
+
+  private void fillNode(fr.lip6.move.pnml.ptnet.Node source, Node result) {
+
+    fillPnObject(source, result);
+
+    if (source.getNodegraphics() != null) {
+      result.setNodeGraphics(getNodeGraphics(source.getNodegraphics()));
+    }
+
+    for (fr.lip6.move.pnml.ptnet.Arc outArc : source.getOutArcs()) {
+      result.addOutArc(Arc.createRefDirection(outArc.getId()));
+    }
+    for (fr.lip6.move.pnml.ptnet.Arc inArc : source.getInArcs()) {
+      result.addInArc(Arc.createRefDirection(inArc.getId()));
+    }
+  }
+
+  private void fillArc(fr.lip6.move.pnml.ptnet.Arc source, Arc result) {
+    fillPnObject(source, result);
+
+    if (source.getArcgraphics() != null) {
+      result.setArcGraphics(getArcGraphics(source.getArcgraphics()));
+    }
+    if (source.getInscription() != null) {
+      result.setInscription(getPTArcannotation(source.getInscription()));
+    }
+
+    result.setSource(Node.createRefDirection(source.getSource().getId()));
+    result.setTarget(Node.createRefDirection(source.getTarget().getId()));
+  }
+
+  private void fillPTAnnotation(fr.lip6.move.pnml.ptnet.PTArcAnnotation source, PTArcAnnotation result) {
+    fillAnnotation(source, result);
+
+    // whatever this is supposed to be. they changed the Integer to Long
+    result.setText(Math.toIntExact(source.getText()));
+  }
+
+  private void fillArcGraphics(fr.lip6.move.pnml.ptnet.ArcGraphics source, ArcGraphics result) {
+    for (fr.lip6.move.pnml.ptnet.Position position : source.getPositions()) {
+      result.addPosition(getPosition(position));
+    }
+    if (source.getLine() != null) {
+      result.setLine(getLine(source.getLine()));
+    }
+  }
+
+}
diff --git a/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java b/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..3979a5928fdc47c4ad3b5819349c5c16dc20467a
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java
@@ -0,0 +1,185 @@
+package de.tudresden.inf.st.pnml;
+
+import de.tudresden.inf.st.pnml.jastadd.model.JastAddList;
+import de.tudresden.inf.st.pnml.jastadd.model.ToolInfo;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ToolSpecificsParser {
+
+    private static final Logger logger = LoggerFactory.getLogger(ToolSpecificsParser.class);
+
+    public static String getLocationFromToolSpecifics(JastAddList<ToolInfo> toolInfos) {
+
+        if (toolInfos.getNumChild() > 0) {
+            try {
+                Document doc = parseToolSpecifics(toolInfos);
+                NodeList locationList = doc.getElementsByTagName(PnmlConstants.LOCATION_KEY);
+
+                if (locationList.getLength() > 0 && locationList.item(0) != null) {
+                    return locationList.item(0).getTextContent();
+                }
+
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+
+        return "";
+    }
+
+    public static String getTransitionTypeFromToolSpecifics(JastAddList<ToolInfo> toolInfos) {
+
+        if (toolInfos.getNumChild() > 0) {
+            try {
+                Document doc = parseToolSpecifics(toolInfos);
+                NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY);
+
+                if (typeList.getLength() > 0 && typeList.item(0) != null) {
+                    String type = typeList.item(0).getTextContent();
+                    if (type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_AC) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_ACK_AC) ||
+                            type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_NOT_AC) || !type.equals(PnmlConstants.TRANSITION_TYPE_CONTINUOUS)
+                            || type.equals(PnmlConstants.TRANSITION_TYPE_DISCRETE) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN)
+                            || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN)|| type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT)
+                            || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)) {
+                        return type;
+                    } else {
+                        logger.error("Error: Invalid transition type configured.");
+                    }
+                }
+
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+
+        return "";
+    }
+
+    public static String getPlaceTypeFromToolSpecifics(JastAddList<ToolInfo> toolInfos) {
+
+        if (toolInfos.getNumChild() > 0) {
+            try {
+                Document doc = parseToolSpecifics(toolInfos);
+                NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY);
+
+                if (typeList.getLength() > 0 && typeList.item(0) != null) {
+                    String type = typeList.item(0).getTextContent();
+                    if (type.equals(PnmlConstants.PLACE_TYPE_DISCRETE) || type.equals(PnmlConstants.PLACE_TYPE_CONTINUOUS)) {
+                        return type;
+                    } else {
+                        logger.error("Error: Invalid transition type configured.");
+                    }
+                }
+
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+
+        return "";
+    }
+
+    public static Boolean isLimitedChannelTransitionType(JastAddList<ToolInfo> toolInfos) {
+
+        if (toolInfos.getNumChild() > 0) {
+            try {
+                Document doc = parseToolSpecifics(toolInfos);
+                NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY);
+
+                if (typeList.getLength() > 0 && typeList.item(0) != null) {
+                    String type = typeList.item(0).getTextContent();
+                    if ( type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN)
+                            || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+        return false;
+    }
+
+    public static String getTopic(JastAddList<ToolInfo> toolInfos) {
+
+        if (toolInfos.getNumChild() > 0) {
+            try {
+                Document doc = parseToolSpecifics(toolInfos);
+                NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY);
+                NodeList topicList = doc.getElementsByTagName(PnmlConstants.TOPIC_KEY);
+
+                if (typeList.getLength() > 0 && typeList.item(0) != null
+                        && topicList.getLength() > 0 && topicList.item(0) != null) {
+
+                    String type = typeList.item(0).getTextContent();
+
+                    if ( type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN)
+                            || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)) {
+                        return topicList.item(0).getTextContent();
+                    }
+                }
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+
+        logger.error("Error: Tried to get sender transition of non-channel transition.");
+        return null;
+    }
+
+    public static int getLimitedChannelTransitionValue(JastAddList<ToolInfo> toolInfos) {
+
+        if (toolInfos.getNumChild() > 0) {
+            try {
+                Document doc = parseToolSpecifics(toolInfos);
+                NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY);
+
+                if (typeList.getLength() > 0 && typeList.item(0) != null) {
+                    String type = typeList.item(0).getTextContent();
+                    if (type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN)
+                            ||type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) ||type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN)) {
+                        NodeList boundList = doc.getElementsByTagName(PnmlConstants.LIMIT_KEY);
+                        return Integer.valueOf(boundList.item(0).getTextContent());
+                    } else {
+                        return -1;
+                    }
+                }
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                logger.error(e.getMessage());
+            }
+        }
+        return -1;
+    }
+
+    private static Document parseToolSpecifics(JastAddList<ToolInfo> toolInfos) throws ParserConfigurationException, SAXException, IOException {
+
+        StringBuffer toolInfoStringBuffer = toolInfos.getChild(0).getFormattedXMLBuffer();
+
+        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+
+        Document doc = dBuilder.parse(fromStringBuffer(toolInfoStringBuffer));
+        doc.getDocumentElement().normalize();
+
+        return doc;
+    }
+
+    private static InputStream fromStringBuffer(StringBuffer buf) {
+        return new ByteArrayInputStream(buf.toString().getBytes());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/de/tudresden/inf/st/postprocessing/IoPetriNetPostProcessor.java b/src/main/java/de/tudresden/inf/st/postprocessing/IoPetriNetPostProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..310c538baa909c17cbb0c442eaf19bd868e8d2fe
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/postprocessing/IoPetriNetPostProcessor.java
@@ -0,0 +1,255 @@
+package de.tudresden.inf.st.postprocessing;
+
+import de.tudresden.inf.st.pnml.PnmlConstants;
+import de.tudresden.inf.st.pnml.jastadd.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class IoPetriNetPostProcessor implements PostProcessor<PetriNet> {
+
+    private static final Logger logger = LoggerFactory.getLogger(IoPetriNetPostProcessor.class);
+
+    public static JastAddList<InputSignalBinding> parseInputSignalBindingDefinitions(JastAddList<ToolInfo> toolInfos){
+
+        try {
+            Document doc = parseToolSpecifics(toolInfos);
+            return parseInputSignalBindingDefinitionsInternal(doc);
+
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            logger.error(e.getMessage());
+        }
+
+        return null;
+    }
+
+    private static JastAddList<InputSignalBinding> parseInputSignalBindingDefinitionsInternal(Document doc) {
+
+        NodeList isBindingDefList = doc.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_BINDINGS_KEY);
+        JastAddList<InputSignalBinding> jastAddBindingList = new JastAddList<>();
+
+        if (isBindingDefList.getLength() > 0 && isBindingDefList.item(0) != null) {
+
+            Node isBindingsNode = isBindingDefList.item(0);
+
+
+            if (isBindingsNode.getNodeType() == Node.ELEMENT_NODE) {
+
+                Element isBindingsElement = (Element) isBindingsNode;
+
+                NodeList isBindingNodes = isBindingsElement.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_BINDING_KEY);
+
+                for (int i = 0; i < isBindingNodes.getLength(); i++) {
+
+                    Node isBindingNode = isBindingNodes.item(i);
+                    Element isBindingElement = (Element) isBindingNode;
+
+                    String tID = isBindingElement.getElementsByTagName(PnmlConstants.TRANSITION_ID_KEY).item(0).getTextContent();
+                    String isID = isBindingElement.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_ID_KEY).item(0).getTextContent();
+                    int cVal = Integer.valueOf(isBindingElement.getElementsByTagName(PnmlConstants.CURRENT_VALUE_KEY).item(0).getTextContent());
+
+                    if(cVal != 1 && cVal != 0){
+                        logger.error("[PARSER] Initial value of input signal " + isID + " is not value. Falling back to 0.");
+                        cVal = 0;
+                    }
+
+                    InputSignalBinding isb = new InputSignalBinding();
+                    isb.setInputSignalValue(cVal);
+                    isb.setInputSignalID(isID);
+                    isb.setTransitionID(tID);
+
+                    jastAddBindingList.add(isb);
+                }
+            }
+        }
+        return jastAddBindingList;
+    }
+
+    public static JastAddList<OutputSignalBinding> parseOutputSignalBindingDefinitions(JastAddList<ToolInfo> toolInfos){
+
+        try {
+            Document doc = parseToolSpecifics(toolInfos);
+            return parseOutputSignalBindingDefinitionsInternal(doc);
+
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            logger.error(e.getMessage());
+        }
+
+        return null;
+    }
+
+    private static JastAddList<OutputSignalBinding> parseOutputSignalBindingDefinitionsInternal(Document doc) {
+
+        NodeList osBindingDefList = doc.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_BINDINGS_KEY);
+        JastAddList<OutputSignalBinding> jastAddBindingList = new JastAddList<>();
+
+        if (osBindingDefList.getLength() > 0 && osBindingDefList.item(0) != null) {
+
+            Node osBindingsNode = osBindingDefList.item(0);
+
+            if (osBindingsNode.getNodeType() == Node.ELEMENT_NODE) {
+
+                Element osBindingsElement = (Element) osBindingsNode;
+
+                NodeList osBindingNodes = osBindingsElement.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_BINDING_KEY);
+
+                for (int i = 0; i < osBindingNodes.getLength(); i++) {
+
+                    Node osBindingNode = osBindingNodes.item(i);
+                    Element osBindingElement = (Element) osBindingNode;
+
+                    String pID = osBindingElement.getElementsByTagName(PnmlConstants.PLACE_ID_KEY).item(0).getTextContent();
+                    String osID = osBindingElement.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_ID_KEY).item(0).getTextContent();
+                    String cVal = String.valueOf(osBindingElement.getElementsByTagName(PnmlConstants.CURRENT_VALUE_KEY).item(0).getTextContent());
+
+                    OutputSignalBinding osb = new OutputSignalBinding();
+                    parseOutputMappings(osBindingElement, pID, osID, cVal, osb);
+                    jastAddBindingList.add(osb);
+                }
+            }
+        }
+
+        return jastAddBindingList;
+    }
+
+    private static void parseOutputMappings(Element osBindingElement, String pID, String osID, String cVal, OutputSignalBinding osb) {
+        //osb.setCurrentValue(cVal);
+        osb.setOutputSignalID(osID);
+        osb.setPlaceID(pID);
+
+        NodeList eqMappingNodeList = osBindingElement.getElementsByTagName(PnmlConstants.EQUAL_OS_KEY);
+        NodeList thresholdMappingNodeList = osBindingElement.getElementsByTagName(PnmlConstants.TRESHOLD_KEY);
+        NodeList rangeMappingNodeList = osBindingElement.getElementsByTagName(PnmlConstants.RANGE_OS_KEY);
+
+        for (int j = 0; j < eqMappingNodeList.getLength(); j++) {
+            Element eqElement = (Element) eqMappingNodeList.item(j);
+            EqualityOutputMapping eom = new EqualityOutputMapping();
+            eom.setValue(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.VALUE_KEY).item(0).getTextContent()));
+            eom.setResult(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.RESULT_KEY).item(0).getTextContent()));
+            osb.addEqualityOM(eom);
+        }
+
+        for (int k = 0; k < thresholdMappingNodeList.getLength(); k++) {
+            Element eqElement = (Element) thresholdMappingNodeList.item(k);
+            ThresholdOutputMapping tom = new ThresholdOutputMapping();
+            tom.setValue(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.VALUE_KEY).item(0).getTextContent()));
+            tom.setResult(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.RESULT_KEY).item(0).getTextContent()));
+            osb.addThresholdOM(tom);
+        }
+
+        for (int l = 0; l < rangeMappingNodeList.getLength(); l++) {
+            Element eqElement = (Element) rangeMappingNodeList.item(l);
+            RangeOutputMapping rom = new RangeOutputMapping();
+            rom.setLowerBound(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.LOWER_BOUND_KEY).item(0).getTextContent()));
+            rom.setUpperBound(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.UPPER_BOUND_KEY).item(0).getTextContent()));
+            rom.setResult(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.RESULT_KEY).item(0).getTextContent()));
+            osb.addRangeOM(rom);
+        }
+    }
+
+    private static Document parseToolSpecifics(JastAddList<ToolInfo> toolInfos) throws ParserConfigurationException, SAXException, IOException {
+
+        StringBuffer toolInfoStringBuffer = toolInfos.getChild(0).getFormattedXMLBuffer();
+
+        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+
+        Document doc = dBuilder.parse(fromStringBuffer(toolInfoStringBuffer));
+        doc.getDocumentElement().normalize();
+
+        return doc;
+    }
+
+    private static InputStream fromStringBuffer(StringBuffer buf) {
+        return new ByteArrayInputStream(buf.toString().getBytes());
+    }
+
+        /*public IoPetriNet doPostProcessing(PetriNet petriNet) {
+
+        System.out.println("doPostProcessing called");
+
+        try {
+            IoPetriNet ioPetriNet = new IoPetriNet();
+            ioPetriNet.setPN(petriNet);
+
+            if (petriNet.getToolspecificList() != null && petriNet.getToolspecificList().getNumChild() > 0) {
+
+                Document doc = parseToolSpecifics(petriNet.getToolspecificList());
+                this.parseSignalDefinitions(doc, ioPetriNet);
+                this.parseInputSignalBindingDefinitions(doc, ioPetriNet);
+                this.parseOutputSignalBindingDefinitions(doc, ioPetriNet);
+            }
+
+            return ioPetriNet;
+
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            logger.error(e.getMessage());
+        }
+        return null;
+    }/*
+
+
+    /*private void parseSignalDefinitions(Document doc, IoPetriNet ioPetriNet) {
+
+        NodeList isDefList = doc.getElementsByTagName(PnmlConstants.INPUT_SIGNALS_KEY);
+        NodeList osDefList = doc.getElementsByTagName(PnmlConstants.OUTPUT_SIGNALS_KEY);
+
+        ArrayList<String> inputSignalIds = new ArrayList<>();
+        ArrayList<String> outputSignalIds = new ArrayList<>();
+
+        if (isDefList.getLength() > 0 && isDefList.item(0) != null) {
+
+            Node nNode = isDefList.item(0);
+
+            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+
+                Element eElement = (Element) nNode;
+
+                NodeList inputSignals = eElement.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_KEY);
+
+                for (int i = 0; i < inputSignals.getLength(); i++) {
+                    inputSignalIds.add(inputSignals.item(i).getTextContent());
+                }
+            }
+        }
+
+        if (osDefList.getLength() > 0 && osDefList.item(0) != null) {
+
+            Node nNode = osDefList.item(0);
+
+            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+
+                Element eElement = (Element) nNode;
+
+                NodeList outputSignals = eElement.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_KEY);
+
+                for (int i = 0; i < outputSignals.getLength(); i++) {
+                    outputSignalIds.add(outputSignals.item(i).getTextContent());
+                }
+            }
+        }
+
+        for (String isId : inputSignalIds) {
+            InputSignal is = new InputSignal();
+            is.setID(isId);
+            ioPetriNet.addIS(is);
+        }
+
+        for (String osId : outputSignalIds) {
+            OutputSignal os = new OutputSignal();
+            os.setID(osId);
+            ioPetriNet.addOS(os);
+        }
+    }*/
+}
\ No newline at end of file
diff --git a/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessor.java b/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..a553ebef66f54b17b3c5a83ac15b1916f100bdab
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessor.java
@@ -0,0 +1,5 @@
+package de.tudresden.inf.st.postprocessing;
+
+public interface PostProcessor<InputModelType> {
+
+}
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..38dc0735d33a8cf955e91f530b601f339aec709f
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <Console name="Console">
+            <PatternLayout pattern="%highlight{%d{HH:mm:ss.SSS} %-5level} %c{1.} - %msg%n"/>
+        </Console>
+        <RollingFile name="RollingFile" fileName="logs/statemachine.log"
+                    filePattern="logs/pnml-%i.log">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/>
+            <Policies>
+                <OnStartupTriggeringPolicy/>
+            </Policies>
+            <DefaultRolloverStrategy max="20"/>
+        </RollingFile>
+    </Appenders>
+    <Loggers>
+        <Root level="info">
+            <AppenderRef ref="Console"/>
+            <AppenderRef ref="RollingFile"/>
+        </Root>
+    </Loggers>
+</Configuration>
diff --git a/src/main/resources/minimal.pnml b/src/main/resources/minimal.pnml
new file mode 100644
index 0000000000000000000000000000000000000000..ca40464368969be37dad3c871331227c1de11f07
--- /dev/null
+++ b/src/main/resources/minimal.pnml
@@ -0,0 +1,237 @@
+<pnml xmlns="http://www.pnml.org/version-2009/grammar/pnml">
+ <net id="n-E2D0-BCF46-0" type ="http://www.pnml.org/version-2009/grammar/ptnet">
+  <name>
+   <text>minimal</text>
+  </name>
+  <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+  </toolspecific>
+  <page id="g-E2D0-BCF68-1">
+   <place id="p1">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>discretePlaceType</type>
+     <outputsignalbindings>
+      <outputsignalbinding>
+       <placeID>p1</placeID>
+       <outputsignalID>os2</outputsignalID>
+       <initialvalue>1</initialvalue> <!-- -1 = undefined -->
+       <outputmappings>
+        <equal>
+         <value>1</value>
+         <result>3</result>
+        </equal>
+        <equal>
+         <value>0</value>
+         <result>2</result>
+        </equal>
+        <threshold>
+         <value>6</value>
+         <result>0</result>
+        </threshold>
+        <range>
+         <upperbound>5</upperbound>
+         <lowerbound>3</lowerbound>
+         <result>1</result>
+        </range>
+       </outputmappings>
+      </outputsignalbinding>
+     </outputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>p1</text>
+     <graphics>
+      <offset x="0" y="-10" />
+     </graphics>
+    </name>
+    <initialMarking>
+     <text>1</text>
+    </initialMarking>
+    <graphics>
+     <position x="30" y="50"/>
+    </graphics>
+   </place>
+   <place id="p2">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>discretePlaceType</type>
+     <outputsignalbindings>
+      <outputsignalbinding>
+       <placeID>p2</placeID>
+       <outputsignalID>os1</outputsignalID>
+       <initialvalue>4</initialvalue> <!-- -1 = undefined -->
+       <outputmappings>
+        <equal>
+         <value>1</value>
+         <result>1</result>
+        </equal>
+        <threshold>
+         <value>6</value>
+         <result>0</result>
+        </threshold>
+        <range>
+         <upperbound>5</upperbound>
+         <lowerbound>3</lowerbound>
+         <result>1</result>
+        </range>
+       </outputmappings>
+      </outputsignalbinding>
+     </outputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>p1</text>
+     <graphics>
+      <offset x="0" y="-10" />
+     </graphics>
+    </name>
+    <initialMarking>
+     <text>1</text>
+    </initialMarking>
+    <graphics>
+     <position x="635" y="90"/>
+    </graphics>
+   </place>
+   <place id="p3">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>discretePlaceType</type>
+     <outputsignalbindings>
+      <outputsignalbinding>
+       <placeID>p3</placeID>
+       <outputsignalID>os5</outputsignalID>
+       <initialvalue>4</initialvalue> <!-- -1 = undefined -->
+       <outputmappings>
+        <equal>
+         <value>1</value>
+         <result>1</result>
+        </equal>
+        <threshold>
+         <value>2</value>
+         <result>0</result>
+        </threshold>
+       </outputmappings>
+      </outputsignalbinding>
+     </outputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>p3</text>
+     <graphics>
+      <offset x="0" y="-10" />
+     </graphics>
+    </name>
+    <initialMarking>
+     <text>1</text>
+    </initialMarking>
+    <graphics>
+     <position x="635" y="90"/>
+    </graphics>
+   </place>
+   <transition id="t1">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>discreteTransitionType</type>
+     <inputsignalbindings>
+      <inputsignalbinding>
+       <transitionID>t1</transitionID>
+       <inputsignalID>is1</inputsignalID>
+       <initialvalue>1</initialvalue>
+      </inputsignalbinding>
+      <inputsignalbinding>
+       <transitionID>t1</transitionID>
+       <inputsignalID>is3</inputsignalID>
+       <initialvalue>1</initialvalue>
+      </inputsignalbinding>
+     </inputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>t0</text>
+     <graphics>
+      <offset x="0" y="0" />
+     </graphics>
+    </name>
+    <graphics>
+     <position x="300" y="50"/>
+    </graphics>
+   </transition>
+   <transition id="t2">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>discreteTransitionType</type>
+     <inputsignalbindings>
+      <inputsignalbinding>
+       <transitionID>t2</transitionID>
+       <inputsignalID>is2</inputsignalID>
+       <initialvalue>0</initialvalue>
+      </inputsignalbinding>
+     </inputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>t1</text>
+     <graphics>
+      <offset x="0" y="0" />
+     </graphics>
+    </name>
+    <graphics>
+     <position x="285" y="205"/>
+    </graphics>
+   </transition>
+   <transition id="t3">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>unlimitedChannelOutType</type>
+     <topic>c1</topic>
+     <inputsignalbindings>
+      <inputsignalbinding>
+       <transitionID>t3</transitionID>
+       <inputsignalID>is3</inputsignalID>
+       <initialvalue>1</initialvalue>
+      </inputsignalbinding>
+     </inputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>t3</text>
+     <graphics>
+      <offset x="0" y="0" />
+     </graphics>
+    </name>
+    <graphics>
+     <position x="265" y="205"/>
+    </graphics>
+   </transition>
+   <transition id="t4">
+    <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1">
+     <location>node-1</location>
+     <type>unlimitedChannelInType</type>
+     <topic>c1</topic>
+     <inputsignalbindings>
+      <inputsignalbinding>
+       <transitionID>t4</transitionID>
+       <inputsignalID>is4</inputsignalID>
+       <initialvalue>1</initialvalue>
+      </inputsignalbinding>
+     </inputsignalbindings>
+    </toolspecific>
+    <name>
+     <text>t4</text>
+     <graphics>
+      <offset x="0" y="0" />
+     </graphics>
+    </name>
+    <graphics>
+     <position x="205" y="205"/>
+    </graphics>
+   </transition>
+   <arc id="arc-t2-p1" source="t2" target="p1">
+   </arc>
+   <arc id="arc-p2-t2" source="p2" target="t2">
+   </arc>
+   <arc id="arc-t1-p2" source="t1" target="p2">
+   </arc>
+   <arc id="arc-p1-t1" source="p1" target="t1">
+   </arc>
+   <arc id="arc-p1-t3" source="p1" target="t3">
+   </arc>
+   <arc id="arc-t4-p3" source="t4" target="p3">
+   </arc>
+  </page>
+ </net>
+</pnml>
\ No newline at end of file
diff --git a/src/main/resources/placeTransition.ecore b/src/main/resources/placeTransition.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..f4c4351b6a8ef6e4751beae215ef9b8eddaa4c7a
--- /dev/null
+++ b/src/main/resources/placeTransition.ecore
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Meta-model for PNML specification -->
+<!-- Provided by www.pnml.org -->
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ptnet"
+    nsURI="http:///ptnet.ecore" nsPrefix="ptnet">
+  <eClassifiers xsi:type="ecore:EClass" name="PTMarking" eSuperTypes="#//Annotation">
+    <eAnnotations source="http://www.pnml.org/models/OCL">
+      <details key="markingValueRange" value="self.text >= 0"/>
+    </eAnnotations>
+    <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
+      <details key="constraints" value="markingValueRange"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" lowerBound="1" eType="#//Natural"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPlace" eType="#//Place"
+        eOpposite="#//Place/initialMarking"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PTArcAnnotation" eSuperTypes="#//Annotation">
+    <eAnnotations source="http://www.pnml.org/models/OCL">
+      <details key="inscriptionValueRange" value="self.text > 0"/>
+    </eAnnotations>
+    <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
+      <details key="constraints" value="inscriptionValueRange"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" lowerBound="1" eType="#//PositiveInteger"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerArc" eType="#//Arc"
+        eOpposite="#//Arc/inscription"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EDataType" name="PositiveInteger" instanceClassName="java.lang.Integer"/>
+  <eClassifiers xsi:type="ecore:EDataType" name="Natural" instanceClassName="java.lang.Integer"/>
+  <eClassifiers xsi:type="ecore:EClass" name="PetriNetDoc">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="nets" ordered="false" lowerBound="1"
+        upperBound="-1" eType="#//PetriNet" containment="true" eOpposite="#//PetriNet/containerPetriNetDoc"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="xmlns" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        changeable="false" defaultValueLiteral="http://www.pnml.org/version-2009/grammar/pnml"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PetriNet">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" ordered="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" defaultValueLiteral=""
+        iD="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" ordered="false" lowerBound="1"
+        eType="#//PNType" defaultValueLiteral=""/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="pages" ordered="false"
+        lowerBound="1" upperBound="-1" eType="#//Page" containment="true" eOpposite="#//Page/containerPetriNet"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="name" ordered="false" eType="#//Name"
+        containment="true" eOpposite="#//Name/containerNamePetriNet"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="toolspecifics" ordered="false"
+        upperBound="-1" eType="#//ToolInfo" containment="true" eOpposite="#//ToolInfo/containerPetriNet"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPetriNetDoc" ordered="false"
+        eType="#//PetriNetDoc" eOpposite="#//PetriNetDoc/nets"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="PNType">
+    <eLiterals name="PTNET" value="1" literal="http://www.pnml.org/version-2009/grammar/ptnet"/>
+    <eLiterals name="COREMODEL" literal="http://www.pnml.org/version-2009/grammar/pnmlcoremodel"/>
+    <eLiterals name="SYMNET" value="2" literal="http://www.pnml.org/version-2009/grammar/snnet"/>
+    <eLiterals name="HLPN" value="3" literal="http://www.pnml.org/version-2009/grammar/highlevelnet"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Page" eSuperTypes="#//PnObject">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="objects" ordered="false"
+        upperBound="-1" eType="#//PnObject" containment="true" eOpposite="#//PnObject/containerPage"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPetriNet" ordered="false"
+        eType="#//PetriNet" eOpposite="#//PetriNet/pages"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="nodegraphics" eType="#//NodeGraphics"
+        containment="true" eOpposite="#//NodeGraphics/containerPage"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PnObject" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" ordered="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" iD="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="name" ordered="false" eType="#//Name"
+        containment="true" eOpposite="#//Name/containerNamePnObject"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="toolspecifics" ordered="false"
+        upperBound="-1" eType="#//ToolInfo" containment="true" eOpposite="#//ToolInfo/containerPnObject"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPage" ordered="false"
+        eType="#//Page" eOpposite="#//Page/objects"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Name" eSuperTypes="#//Annotation">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" ordered="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerNamePetriNet"
+        eType="#//PetriNet" eOpposite="#//PetriNet/name"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerNamePnObject"
+        eType="#//PnObject" eOpposite="#//PnObject/name"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ToolInfo">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="tool" ordered="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" ordered="false"
+        lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="formattedXMLBuffer" ordered="false"
+        eType="#//LongString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="toolInfoGrammarURI" ordered="false"
+        eType="#//URI"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPetriNet" ordered="false"
+        eType="#//PetriNet" eOpposite="#//PetriNet/toolspecifics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPnObject" ordered="false"
+        eType="#//PnObject" eOpposite="#//PnObject/toolspecifics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerLabel" ordered="false"
+        eType="#//Label" eOpposite="#//Label/toolspecifics"/>
+<!--    <eStructuralFeatures xsi:type="ecore:EReference" name="toolInfoModel" eType="#//AnyObject"-->
+<!--        containment="true" eOpposite="#//AnyObject/containerToolInfo"/>-->
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Label" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="toolspecifics" ordered="false"
+        upperBound="-1" eType="#//ToolInfo" containment="true" eOpposite="#//ToolInfo/containerLabel"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="NodeGraphics" eSuperTypes="#//Graphics">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="position" ordered="false"
+        eType="#//Position" containment="true" eOpposite="#//Position/containerPNodeGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="dimension" ordered="false"
+        eType="#//Dimension" containment="true" eOpposite="#//Dimension/containerDNodeGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fill" ordered="false" eType="#//Fill"
+        containment="true" eOpposite="#//Fill/containerNodeGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="line" ordered="false" eType="#//Line"
+        containment="true" eOpposite="#//Line/containerNodeGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerNode" eType="#//Node"
+        eOpposite="#//Node/nodegraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPage" eType="#//Page"
+        eOpposite="#//Page/nodegraphics"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Graphics" abstract="true"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Coordinate" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="x" ordered="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="y" ordered="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Position" eSuperTypes="#//Coordinate">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerArcGraphics" ordered="false"
+        eType="#//ArcGraphics" eOpposite="#//ArcGraphics/positions"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerPNodeGraphics"
+        eType="#//NodeGraphics" eOpposite="#//NodeGraphics/position"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Offset" eSuperTypes="#//Coordinate">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics"
+        ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/offset"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Dimension" eSuperTypes="#//Coordinate">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerDNodeGraphics"
+        ordered="false" eType="#//NodeGraphics" eOpposite="#//NodeGraphics/dimension"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AnnotationGraphics" eSuperTypes="#//Graphics">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="offset" ordered="false"
+        eType="#//Offset" containment="true" eOpposite="#//Offset/containerAnnotationGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fill" ordered="false" eType="#//Fill"
+        containment="true" eOpposite="#//Fill/containerAnnotationGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="line" ordered="false" eType="#//Line"
+        containment="true" eOpposite="#//Line/containerAnnotationGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="font" ordered="false" eType="#//Font"
+        containment="true" eOpposite="#//Font/containerAnnotationGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotation" eType="#//Annotation"
+        eOpposite="#//Annotation/annotationgraphics"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Fill">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="color" ordered="false"
+        eType="#//CSS2Color" defaultValueLiteral="BLACK"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="gradientcolor" ordered="false"
+        eType="#//CSS2Color" defaultValueLiteral="BLACK"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="gradientrotation" ordered="false"
+        eType="#//Gradient"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="image" ordered="false"
+        eType="#//URI"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerNodeGraphics"
+        ordered="false" eType="#//NodeGraphics" eOpposite="#//NodeGraphics/fill"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics"
+        ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/fill"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="CSS2Color">
+    <eLiterals name="AQUA" literal="aqua"/>
+    <eLiterals name="BLACK" value="1" literal="black"/>
+    <eLiterals name="BLUE" value="2" literal="blue"/>
+    <eLiterals name="FUCHSIA" value="3" literal="fuchsia"/>
+    <eLiterals name="GRAY" value="4" literal="gray"/>
+    <eLiterals name="GREEN" value="5" literal="green"/>
+    <eLiterals name="LIME" value="6" literal="lime"/>
+    <eLiterals name="MAROON" value="7" literal="maroon"/>
+    <eLiterals name="NAVY" value="8" literal="navy"/>
+    <eLiterals name="OLIVE" value="9" literal="olive"/>
+    <eLiterals name="ORANGE" value="10" literal="orange"/>
+    <eLiterals name="PURPLE" value="11" literal="purple"/>
+    <eLiterals name="RED" value="12" literal="red"/>
+    <eLiterals name="SILVER" value="13" literal="silver"/>
+    <eLiterals name="TEAL" value="14" literal="teal"/>
+    <eLiterals name="WHITE" value="15" literal="white"/>
+    <eLiterals name="YELLOW" value="16" literal="yellow"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Gradient">
+    <eLiterals name="HORIZONTAL" literal="horizontal"/>
+    <eLiterals name="VERTICAL" value="1" literal="vertical"/>
+    <eLiterals name="DIAGONAL" value="2" literal="diagonal"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Line">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="color" ordered="false"
+        eType="#//CSS2Color" defaultValueLiteral="BLACK"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="shape" ordered="false"
+        eType="#//LineShape" defaultValueLiteral="LINE"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="width" ordered="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerNodeGraphics"
+        ordered="false" eType="#//NodeGraphics" eOpposite="#//NodeGraphics/line"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerArcGraphics" ordered="false"
+        eType="#//ArcGraphics" eOpposite="#//ArcGraphics/line"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics"
+        ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/line"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="style" eType="#//LineStyle"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="LineShape">
+    <eLiterals name="LINE" literal="line"/>
+    <eLiterals name="CURVE" value="1" literal="curve"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ArcGraphics" eSuperTypes="#//Graphics">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="positions" upperBound="-1"
+        eType="#//Position" containment="true" eOpposite="#//Position/containerArcGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="line" ordered="false" eType="#//Line"
+        containment="true" eOpposite="#//Line/containerArcGraphics"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerArc" eType="#//Arc"
+        eOpposite="#//Arc/arcgraphics"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Arc" eSuperTypes="#//PnObject">
+    <eAnnotations source="http://www.pnml.org/models/OCL">
+      <details key="samePageSourceTarget" value="self.source.containerPage = self.target.containerPage"/>
+      <details key="differentSourceTarget" value="(self.source.oclIsKindOf(PlaceNode) and self.target.oclIsKindOf(TransitionNode)) or (self.source.oclIsKindOf(TransitionNode) and self.target.oclIsKindOf(PlaceNode))"/>
+    </eAnnotations>
+    <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
+      <details key="constraints" value="samePageSourceTarget differentSourceTarget"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="source" ordered="false"
+        lowerBound="1" eType="#//Node" eOpposite="#//Node/OutArcs"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="target" ordered="false"
+        lowerBound="1" eType="#//Node" eOpposite="#//Node/InArcs"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="arcgraphics" ordered="false"
+        eType="#//ArcGraphics" containment="true" eOpposite="#//ArcGraphics/containerArc"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="inscription" eType="#//PTArcAnnotation"
+        containment="true" eOpposite="#//PTArcAnnotation/containerArc"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//PnObject">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="InArcs" ordered="false"
+        upperBound="-1" eType="#//Arc" changeable="false" eOpposite="#//Arc/target"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="OutArcs" ordered="false"
+        upperBound="-1" eType="#//Arc" changeable="false" eOpposite="#//Arc/source"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="nodegraphics" eType="#//NodeGraphics"
+        containment="true" eOpposite="#//NodeGraphics/containerNode"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Font">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="align" ordered="false"
+        eType="#//FontAlign" defaultValueLiteral="LEFT"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="decoration" ordered="false"
+        eType="#//FontDecoration" defaultValueLiteral="UNDERLINE"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="family" ordered="false"
+        eType="#//CSS2FontFamily" defaultValueLiteral="VERDANA"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="rotation" ordered="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="size" ordered="false" eType="#//CSS2FontSize"
+        defaultValueLiteral="SMALL"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="style" ordered="false"
+        eType="#//CSS2FontStyle" defaultValueLiteral="NORMAL"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="weight" ordered="false"
+        eType="#//CSS2FontWeight"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics"
+        ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/font"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="FontAlign">
+    <eLiterals name="LEFT" literal="left"/>
+    <eLiterals name="CENTER" value="1" literal="center"/>
+    <eLiterals name="RIGHT" value="2" literal="right"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="FontDecoration">
+    <eLiterals name="UNDERLINE" literal="underline"/>
+    <eLiterals name="OVERLINE" value="1" literal="overline"/>
+    <eLiterals name="LINETHROUGH" value="2" literal="linethrough"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontFamily">
+    <eLiterals name="VERDANA" literal="verdana"/>
+    <eLiterals name="ARIAL" value="1" literal="arial"/>
+    <eLiterals name="TIMES" value="2" literal="times"/>
+    <eLiterals name="GEORGIA" value="3" literal="georgia"/>
+    <eLiterals name="TREBUCHET" value="4" literal="trebuchet"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontSize">
+    <eLiterals name="XXSMALL" literal="xxsmall"/>
+    <eLiterals name="XSMALL" value="1" literal="xsmall"/>
+    <eLiterals name="SMALL" value="2" literal="small"/>
+    <eLiterals name="MEDIUM" value="3" literal="medium"/>
+    <eLiterals name="LARGE" value="4" literal="large"/>
+    <eLiterals name="XLARGE" value="5" literal="xlarge"/>
+    <eLiterals name="XXLARGE" value="6" literal="xxlarge"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontStyle">
+    <eLiterals name="NORMAL" literal="normal"/>
+    <eLiterals name="ITALIC" value="1" literal="italic"/>
+    <eLiterals name="OBLIQUE" value="2" literal="oblique"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontWeight">
+    <eLiterals name="NORMAL" literal="normal"/>
+    <eLiterals name="BOLD" value="1" literal="bold"/>
+    <eLiterals name="BOLDER" value="2" literal="bolder"/>
+    <eLiterals name="LIGHTER" value="3" literal="lighter"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PlaceNode" abstract="true" eSuperTypes="#//Node">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="referencingPlaces" upperBound="-1"
+        eType="#//RefPlace" changeable="false" eOpposite="#//RefPlace/ref"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="TransitionNode" abstract="true" eSuperTypes="#//Node">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="referencingTransitions"
+        upperBound="-1" eType="#//RefTransition" changeable="false" eOpposite="#//RefTransition/ref"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Place" eSuperTypes="#//PlaceNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="initialMarking" eType="#//PTMarking"
+        containment="true" eOpposite="#//PTMarking/containerPlace"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="RefTransition" eSuperTypes="#//TransitionNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" ordered="false" lowerBound="1"
+        eType="#//TransitionNode" eOpposite="#//TransitionNode/referencingTransitions"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Transition" eSuperTypes="#//TransitionNode"/>
+  <eClassifiers xsi:type="ecore:EClass" name="RefPlace" eSuperTypes="#//PlaceNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" ordered="false" lowerBound="1"
+        eType="#//PlaceNode" eOpposite="#//PlaceNode/referencingPlaces"/>
+  </eClassifiers>
+<!--  <eClassifiers xsi:type="ecore:EClass" name="Attribute" abstract="true" eSuperTypes="#//Label"/>-->
+  <eClassifiers xsi:type="ecore:EEnum" name="LineStyle">
+    <eLiterals name="SOLID" literal="solid"/>
+    <eLiterals name="DASH" value="1" literal="dash"/>
+    <eLiterals name="DOT" value="2" literal="dot"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Annotation" abstract="true" eSuperTypes="#//Label">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="annotationgraphics" ordered="false"
+        eType="#//AnnotationGraphics" containment="true" eOpposite="#//AnnotationGraphics/containerAnnotation"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EDataType" name="URI" instanceClassName="java.net.URI"/>
+  <eClassifiers xsi:type="ecore:EDataType" name="LongString" instanceClassName="java.lang.StringBuffer"/>
+<!--  <eClassifiers xsi:type="ecore:EClass" name="AnyObject" abstract="true">-->
+<!--    <eStructuralFeatures xsi:type="ecore:EReference" name="containerToolInfo" eType="#//ToolInfo"-->
+<!--        changeable="false" eOpposite="#//ToolInfo/toolInfoModel"/>-->
+<!--  </eClassifiers>-->
+</ecore:EPackage>