diff --git a/src/main/jastadd/Navigation.jrag b/src/main/jastadd/Navigation.jrag
index 35efffbe10ef5c7eeced2562dcbf9e922c72539f..59043ee36178bcbef0a1aac9670e3075acf6e6d9 100644
--- a/src/main/jastadd/Navigation.jrag
+++ b/src/main/jastadd/Navigation.jrag
@@ -37,6 +37,9 @@ aspect Navigation {
   syn boolean TransitionInformation.isServiceTransitionInformation() = false;
   eq ServiceTransitionInformation.isServiceTransitionInformation() = true;
 
+  syn boolean TransitionInformation.isDefaultTransitionInformation() = false;
+  eq DefaultTransitionInformation.isDefaultTransitionInformation() = true;
+
   syn TransitionNode Node.asTransitionNode() = null;
   eq TransitionNode.asTransitionNode() = this;
 
@@ -52,6 +55,9 @@ aspect Navigation {
   syn ServiceTransitionInformation TransitionInformation.asServiceTransitionInformation() = null;
   eq ServiceTransitionInformation.asServiceTransitionInformation() = this;
 
+  syn DefaultTransitionInformation TransitionInformation.asDefaultTransitionInformation() = null;
+  eq DefaultTransitionInformation.asDefaultTransitionInformation() = this;
+
   syn Place PlaceNode.place();
   eq Place.place() = this;
   eq RefPlace.place() = getRef().place();
diff --git a/src/main/jastadd/distribution/DistributedPN.jadd b/src/main/jastadd/distribution/DistributedPN.jadd
index 3c24f07d41b8d5afaacb92812d387ae47c19d4ca..7414924cd771afa14823154b32df8cae9c3a0ff5 100644
--- a/src/main/jastadd/distribution/DistributedPN.jadd
+++ b/src/main/jastadd/distribution/DistributedPN.jadd
@@ -17,7 +17,7 @@ aspect PnDistribution {
         return pInfo;
     }*/
 
-    syn lazy PlaceInformation OutputSignalPlace.getStaticTransitionInformation() {
+    syn lazy PlaceInformation OutputSignalPlace.getStaticPlaceInformation() {
 
         if(this.getMutualPlaceInformation() == null){
             PlaceInformation tInfo = de.tudresden.inf.st.pnml.ToolSpecificsParser.getPlaceInformationInformation(this.getToolspecificList());
diff --git a/src/main/jastadd/io/IoPN.relast b/src/main/jastadd/io/IoPN.relast
index 014ee8a2ef3349b8027ca7781f8cae4edf582007..e16c996f0c36d188a1137f8fe46abc876e7696e0 100644
--- a/src/main/jastadd/io/IoPN.relast
+++ b/src/main/jastadd/io/IoPN.relast
@@ -1,9 +1,11 @@
 InputSignalBinding : PnObject ::= <TransitionID:String> <InputSignalID:String> <InputSignalValue:int>;
 OutputSignalBinding : PnObject ::= <PlaceID:String> <OutputSignalID:String> /<OutputSignalValue:String>/ EqualityOM:EqualityOutputMapping* ThresholdOM:ThresholdOutputMapping* RangeOM:RangeOutputMapping*;
 
-TransitionInformation ::= <Location:String> <Type:String> <InputLimit:java.lang.Integer> <OutputLimit:java.lang.Integer> <SubNet:String> <Instance:String>;
+abstract TransitionInformation ::= <Location:String> <Type:String> <InputLimit:java.lang.Integer> <OutputLimit:java.lang.Integer> <SubNet:String> <Instance:String>;
 TopicTransitionInformation : TransitionInformation ::= <Topic:String>;
 ServiceTransitionInformation : TransitionInformation ::= <ServiceName:String>;
+DefaultTransitionInformation : TransitionInformation;
+
 PlaceInformation ::= <Location:String> <Type:String> <SubNet:String> <Instance:String>;
 
 InputSignalTransition : Transition ::= /StaticInputSignalBinding:InputSignalBinding*/ MutualInputSignalBinding:InputSignalBinding* /StaticTransitionInformation:TransitionInformation/ [MutualTransitionInformation:TransitionInformation];
diff --git a/src/main/java/de/tudresden/inf/st/copy/CopyPrimitiveElements.java b/src/main/java/de/tudresden/inf/st/copy/CopyPrimitiveElements.java
new file mode 100644
index 0000000000000000000000000000000000000000..06a4b5ff027d785b97bf68c36b4ba99568d655d2
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/copy/CopyPrimitiveElements.java
@@ -0,0 +1,50 @@
+package de.tudresden.inf.st.copy;
+
+import de.tudresden.inf.st.pnml.jastadd.model.DefaultTransitionInformation;
+import de.tudresden.inf.st.pnml.jastadd.model.InputSignalBinding;
+import de.tudresden.inf.st.pnml.jastadd.model.InputSignalTransition;
+import de.tudresden.inf.st.pnml.jastadd.model.TransitionInformation;
+
+public class CopyPrimitiveElements {
+
+    public static InputSignalTransition copyInputSignalTransition(InputSignalTransition ist, String idPrefix, String instance){
+
+        InputSignalTransition istCopy = new InputSignalTransition();
+
+        istCopy.setId(idPrefix + ist.getId());
+
+        for(InputSignalBinding isb : ist.getStaticInputSignalBindingList()){
+            istCopy.addMutualInputSignalBinding(copyInputputSignalBinding(isb, idPrefix));
+        }
+
+        istCopy.setMutualTransitionInformation(copyDefaultTransitionInformation(ist.getStaticTransitionInformation(), idPrefix, instance));
+
+        return istCopy;
+    }
+
+    public static InputSignalBinding copyInputputSignalBinding(InputSignalBinding isb, String idPrefix){
+
+        InputSignalBinding isbCopy = new InputSignalBinding();
+
+        isbCopy.setId(idPrefix + isb.getId());
+        isbCopy.setInputSignalID(isb.getInputSignalID());
+        isbCopy.setTransitionID(isb.getTransitionID());
+        isbCopy.setInputSignalValue(isb.getInputSignalValue());
+
+        return isbCopy;
+    }
+
+    public static TransitionInformation copyDefaultTransitionInformation (TransitionInformation ti, String idPrefix, String instance){
+
+        DefaultTransitionInformation tiCopy = new DefaultTransitionInformation();
+
+        tiCopy.setInstance(instance);
+        tiCopy.setSubNet(ti.getSubNet());
+        tiCopy.setType(ti.getType());
+        tiCopy.setLocation(tiCopy.getLocation());
+        tiCopy.setOutputLimit(ti.getOutputLimit());
+        tiCopy.setInputLimit(ti.getInputLimit());
+
+        return tiCopy;
+    }
+}
diff --git a/src/main/java/de/tudresden/inf/st/data/Tuple3.java b/src/main/java/de/tudresden/inf/st/data/Tuple3.java
new file mode 100644
index 0000000000000000000000000000000000000000..90892dee2e820dcbdf1d1d69f491fa4789bce765
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/data/Tuple3.java
@@ -0,0 +1,26 @@
+package de.tudresden.inf.st.data;
+
+public class Tuple3<K, V, L> {
+
+    private K _1;
+    private V _2;
+    private L _3;
+
+    public Tuple3(K _1, V _2, L _3){
+        this._1 = _1;
+        this._2 = _2;
+        this._3 = _3;
+    }
+
+    public K get_1() {
+        return _1;
+    }
+
+    public V get_2() {
+        return _2;
+    }
+
+    public L get_3() {
+        return _3;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/de/tudresden/inf/st/pnml/Main.java b/src/main/java/de/tudresden/inf/st/pnml/Main.java
index bed9d1f0fae070595edf25af24e55e1dbe7bf177..8a69caaf8d460b2d47f546271a2520726ad2a973 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/Main.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/Main.java
@@ -24,7 +24,7 @@ public class Main {
             return;
         }*/
 
-        List<PetriNet> petriNets = PnmlParser.parsePnml("src/main/nets/serviceTestNet1.pnml");
+        List<PetriNet> petriNets = PnmlParser.parsePnml("src/main/nets/testNet5.pnml");
         //List<PetriNet> petriNets = PnmlParser.parsePnml(inputPath);
 
         List<List<PetriNet>> disconnectedPetriNets = new ArrayList<>();
diff --git a/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java b/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java
index c51d1f4f1abf03580fd9e24b435c927690fe1342..45dcf890dcd615eda1df56569f65fbb528e597c5 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java
@@ -210,7 +210,9 @@ public class ToolSpecificsParser {
             topicTransition.setTopic(getTransitionTopicFromToolSpecifics(toolInfos));
             topicTransition.setSubNet(getTransitionSubnetInfo(toolInfos));
             return topicTransition;
-        }else{
+        }
+
+        if(getTransitionServiceNameFromToolSpecifics(toolInfos) != null){
             ServiceTransitionInformation serviceTransition = new ServiceTransitionInformation();
             serviceTransition.setInputLimit(getTransitionInputLimit(toolInfos));
             serviceTransition.setOutputLimit(getTransitionOutputLimit(toolInfos));
@@ -220,6 +222,15 @@ public class ToolSpecificsParser {
             serviceTransition.setSubNet(getTransitionSubnetInfo(toolInfos));
             return serviceTransition;
         }
+
+        DefaultTransitionInformation transitionInformation = new DefaultTransitionInformation();
+        transitionInformation.setInputLimit(getTransitionInputLimit(toolInfos));
+        transitionInformation.setOutputLimit(getTransitionOutputLimit(toolInfos));
+        transitionInformation.setLocation(getLocationFromToolSpecifics(toolInfos));
+        transitionInformation.setType(getTransitionTypeFromToolSpecifics(toolInfos));
+        transitionInformation.setSubNet(getTransitionSubnetInfo(toolInfos));
+
+        return transitionInformation;
     }
 
     public static PlaceInformation getPlaceInformationInformation(JastAddList<ToolInfo> toolInfos){
diff --git a/src/main/java/de/tudresden/inf/st/postprocessing/GlobalToLocalNetsPostProcessor.java b/src/main/java/de/tudresden/inf/st/postprocessing/GlobalToLocalNetsPostProcessor.java
index 22ffbb702158abf4f3ba3cf16e50c86a93c772f1..3686233050340108b2a54b80126fe964c9815b22 100644
--- a/src/main/java/de/tudresden/inf/st/postprocessing/GlobalToLocalNetsPostProcessor.java
+++ b/src/main/java/de/tudresden/inf/st/postprocessing/GlobalToLocalNetsPostProcessor.java
@@ -26,6 +26,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import static de.tudresden.inf.st.postprocessing.PostProcessingUtils.printNet;
+
 public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
 
     private static final Logger logger = LoggerFactory.getLogger(GlobalToLocalNetsPostProcessor.class);
@@ -36,16 +38,15 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
             // init list of distributed nets
             List<PetriNet> pns = new ArrayList<>();
 
-            // cut the service transitions
-            PetriNet serviceCuttedNet = cutServiceTransitions(petriNet);
-
             // cut the topic transitions
-            PetriNet cuttedNet = cutTopicTransitions(serviceCuttedNet);
-            //logger.error("cuttedNet: --------------------------------------------");
-            //printNet(cuttedNet);
+            PetriNet topicCuttedNet = cutTopicTransitions(petriNet);
+         //   logger.error("topicCuttedNet: --------------------------------------------");
+        //    printNet(topicCuttedNet);
+
+            // cut the service transitions
+       //     PetriNet serviceCuttedNet = cutServiceTransitions(topicCuttedNet);
 
-            Set<String> locations = getLocations(cuttedNet);
-            //logger.error("LOCATIONS: " + locations);
+            Set<String> locations = getLocations(topicCuttedNet);
 
             // serialize for deep copy
             String serializedNetPath = PnmlExporter.serializeToPnmlFile(petriNet, "-pre-split.pnml");
@@ -55,14 +56,15 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
 
                 List<PetriNet> reParsedPetriNets = PnmlParser.parsePnml(serializedNetPath);
 
-                //logger.error("REPARSED: ");
-                //printNet(reParsedPetriNets.get(0));
+         //       logger.error("REPARSED: ");
+         //       printNet(reParsedPetriNets.get(0));
 
                 for (PetriNet pn : reParsedPetriNets) {
 
+              //      logger.info("----------------------------------------------------");
                     PetriNet separatedNet = createdSeparatedNetByLocation(pn, location);
-                    //logger.error("SEPARATED NET");
-                    //printNet(separatedNet);
+              //      logger.error("SEPARATED NET");
+              //      printNet(separatedNet);
                     pns.add(separatedNet);
                 }
             }
@@ -80,8 +82,8 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
         Set<String> allLocations = new HashSet<>();
 
         for (Place place : petriNet.allPlaces()) {
-            if (place.asOutputSignalPlace().getStaticTransitionInformation().getSubNet() != null) {
-                allLocations.add(place.asOutputSignalPlace().getStaticTransitionInformation().getSubNet());
+            if (place.asOutputSignalPlace().getStaticPlaceInformation().getSubNet() != null) {
+                allLocations.add(place.asOutputSignalPlace().getStaticPlaceInformation().getSubNet());
             } else {
                 logger.error("Found place without location.");
             }
@@ -111,14 +113,14 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
                 String outSubNet = null;
 
                 for (Place p : channelIst.incomingPlaces()) {
-                    inLocation = p.asOutputSignalPlace().getStaticTransitionInformation().getLocation();
-                    inSubNet = p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet();
+                    inLocation = p.asOutputSignalPlace().getStaticPlaceInformation().getLocation();
+                    inSubNet = p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet();
                     break;
                 }
 
                 for (Place p : channelIst.outgoingPlaces()) {
-                    outLocation = p.asOutputSignalPlace().getStaticTransitionInformation().getLocation();
-                    outSubNet = p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet();
+                    outLocation = p.asOutputSignalPlace().getStaticPlaceInformation().getLocation();
+                    outSubNet = p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet();
                     break;
                 }
 
@@ -132,8 +134,6 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
 
     private static PetriNet cutTopicTransitions(PetriNet petriNet) {
 
-        //printNet(petriNet);
-
         Set<Transition> transitionsToAdd = new HashSet<>();
         Set<Transition> transitionsToRemove = new HashSet<>();
 
@@ -145,125 +145,144 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
 
                 logger.info("Found topic transition: " + transition.getId());
 
-                // TODO: handle refs?
+                // TODO: handle refs & multi pages?
 
+                // Add to the deprecated transitions
                 transitionsToRemove.add(transition);
 
-                // STEP 1: Get location/subnet of source/target - places
-                String inLocation = null;
-                String outLocation = null;
-                String inSubNet = null;
-                String outSubNet = null;
+                // Create and integrate new publisher transitions
+                refactorPublisherSide(transitionsToAdd, transition, channelIst);
 
-                for (Place p : channelIst.incomingPlaces()) {
-                    inLocation = p.asOutputSignalPlace().getStaticTransitionInformation().getLocation();
-                    inSubNet = p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet();
-                    break;
-                }
+                // Create and integrate new subscriber transitions
+                refactorSubscriberSide(transitionsToAdd, transition, channelIst);
+            }
+        }
 
-                for (Place p : channelIst.outgoingPlaces()) {
-                    outLocation = p.asOutputSignalPlace().getStaticTransitionInformation().getLocation();
-                    outSubNet = p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet();
-                    break;
-                }
+        // Remove "old transition"
+        for (Transition t : transitionsToRemove) {
+            t.removeSelf();
+        }
 
-                // STEP 1: Create new source and target Transition
-                InputSignalTransition sourceIst = new InputSignalTransition();
-                sourceIst.setName(new Name().setText(channelIst.getName().getText() + "-source"));
-                sourceIst.setId(channelIst.getId() + "-source");
+        for (Transition t : transitionsToAdd) {
+            petriNet.getPage(0).addObject(t);
+        }
 
-                TopicTransitionInformation tInfoSource = new TopicTransitionInformation();
-                tInfoSource.setSubNet(inSubNet);
-                tInfoSource.setLocation(inLocation);
-                tInfoSource.setTopic(channelIst.getStaticTransitionInformation().asTopicTransitionInformation().getTopic());
+        //petriNet.flushAttrAndCollectionCache();
+        petriNet.flushTreeCache();
 
-                // attributized infos need to be written back to XML
-                JastAddList<ToolInfo> inputToolInfoJastAddList = new JastAddList<>();
+        return petriNet;
+    }
 
-                if (channelIst.getStaticTransitionInformation().getInputLimit() >= 0) {
+    private static void refactorSubscriberSide(Set<Transition> transitionsToAdd, Transition transition, InputSignalTransition channelIst) {
 
-                    tInfoSource.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_OUT);
-                    inputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_OUT, inLocation, inSubNet, tInfoSource.getTopic(),
-                            channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), channelIst.getStaticInputSignalBindingList()));
+        int subscriberCount = 0;
 
-                } else {
-                    tInfoSource.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_OUT);
-                    inputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_OUT, inLocation, inSubNet, tInfoSource.getTopic(),
-                            channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), channelIst.getStaticInputSignalBindingList()));
-                }
+        for (Place p : channelIst.outgoingPlaces()) {
 
-                sourceIst.setToolspecificList(inputToolInfoJastAddList);
-                sourceIst.setMutualTransitionInformation(tInfoSource);
-
-                InputSignalTransition targetIst = new InputSignalTransition();
-                targetIst.setName(new Name().setText(channelIst.getName().getText() + "-target"));
-                targetIst.setId(channelIst.getId() + "-target");
-
-                TopicTransitionInformation tInfoTarget = new TopicTransitionInformation();
-                tInfoTarget.setSubNet(outSubNet);
-                tInfoTarget.setLocation(outLocation);
-                tInfoTarget.setTopic(channelIst.getStaticTransitionInformation().asTopicTransitionInformation().getTopic());
-
-                // attributized infos need to be written back to XML
-                JastAddList<ToolInfo> outputToolInfoJastAddList = new JastAddList<>();
-
-                if (channelIst.getStaticTransitionInformation().getOutputLimit() >= 0) {
-                    tInfoTarget.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_IN);
-                    outputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_IN, outLocation, outSubNet, tInfoTarget.getTopic(),
-                            channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), null));
-                } else {
-                    tInfoTarget.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_IN);
-                    outputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_IN, outLocation, outSubNet, tInfoTarget.getTopic(),
-                            channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), null));
-                }
+            String outLocation = p.asOutputSignalPlace().getStaticPlaceInformation().getLocation();
+            String outSubNet = p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet();
 
-                targetIst.setToolspecificList(outputToolInfoJastAddList);
-                targetIst.setMutualTransitionInformation(tInfoTarget);
+            InputSignalTransition subscriberIst = new InputSignalTransition();
+            subscriberIst.setName(new Name().setText(channelIst.getName().getText() + "-subscriber-" + subscriberCount));
+            subscriberIst.setId(channelIst.getId() + "-subscriber-" + subscriberCount);
 
-                // STEP 2: Reconnect Input Signals
-                for (InputSignalBinding isb : channelIst.getStaticInputSignalBindingList()) {
+            TopicTransitionInformation tInfoTarget = new TopicTransitionInformation();
+            tInfoTarget.setSubNet(outSubNet);
+            tInfoTarget.setLocation(outLocation);
+            tInfoTarget.setTopic(channelIst.getStaticTransitionInformation().asTopicTransitionInformation().getTopic());
 
-                    InputSignalBinding newIsb = new InputSignalBinding();
-                    newIsb.setInputSignalValue(isb.getInputSignalValue());
-                    newIsb.setTransitionID(isb.getTransitionID());
-                    newIsb.setId(isb.getId());
-                    newIsb.setInputSignalID(isb.getInputSignalID());
+            // attributized infos need to be written back to XML
+            JastAddList<ToolInfo> outputToolInfoJastAddList = new JastAddList<>();
 
-                    sourceIst.addMutualInputSignalBinding(newIsb);
-                }
+            if (channelIst.getStaticTransitionInformation().getOutputLimit() >= 0) {
+                tInfoTarget.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_IN);
+                outputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_IN, outLocation, outSubNet, tInfoTarget.getTopic(),
+                        channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), null));
+            } else {
+                tInfoTarget.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_IN);
+                outputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_IN, outLocation, outSubNet, tInfoTarget.getTopic(),
+                        channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), null));
+            }
 
-                // STEP 3: Get all incoming arcs and connect them to new output transition
-                for (Arc arc : channelIst.getInArcList().toArray(new Arc[0])) {
-                    arc.setTarget(sourceIst);
-                }
+            subscriberIst.setToolspecificList(outputToolInfoJastAddList);
+            subscriberIst.setMutualTransitionInformation(tInfoTarget);
 
-                // STEP 4: Gel all outgoing arcs and connect them to new input transition
-                for (Arc arc : channelIst.getOutArcList().toArray(new Arc[0])) {
-                    arc.setSource(targetIst);
-                }
+            // Gel all outgoing arcs and connect them to new input transition
+            for(Arc arc : p.asOutputSignalPlace().getInArcList().toArray(new Arc[0])){
 
-                // STEP 5: Add new transitions to net
-                transitionsToAdd.add(sourceIst);
-                transitionsToAdd.add(targetIst);
+                if(arc.getSource().getId().equals(transition.getId())){
+                    arc.setSource(subscriberIst);
+                }
             }
-        }
 
-        // STEP 6: Remove "old transition"
-        for (Transition t : transitionsToRemove) {
-            t.removeSelf();
-        }
+            // Add new transitions to net
+            transitionsToAdd.add(subscriberIst);
 
-        //petriNet.allTransitions().removeAll(transitionsToRemove);
-        for (Transition t : transitionsToAdd) {
-            petriNet.getPage(0).addObject(t);
+            subscriberCount++;
         }
+    }
 
-        //petriNet.flushAttrAndCollectionCache();
-        petriNet.flushTreeCache();
+    private static void refactorPublisherSide(Set<Transition> transitionsToAdd, Transition transition, InputSignalTransition channelIst) {
 
-        //printNet(petriNet);
+        int publisherCount = 0;
 
-        return petriNet;
+        for (Place p : channelIst.incomingPlaces()) {
+
+            String inLocation = p.asOutputSignalPlace().getStaticPlaceInformation().getLocation();
+            String inSubNet = p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet();
+
+            InputSignalTransition publisherIst = new InputSignalTransition();
+            publisherIst.setName(new Name().setText(channelIst.getName().getText() + "-publisher-" + publisherCount));
+            publisherIst.setId(channelIst.getId() + "-publisher-" + publisherCount);
+
+            TopicTransitionInformation tInfoSource = new TopicTransitionInformation();
+            tInfoSource.setSubNet(inSubNet);
+            tInfoSource.setLocation(inLocation);
+            tInfoSource.setTopic(channelIst.getStaticTransitionInformation().asTopicTransitionInformation().getTopic());
+
+            // attributized infos need to be written back to XML
+            JastAddList<ToolInfo> inputToolInfoJastAddList = new JastAddList<>();
+
+            if (channelIst.getStaticTransitionInformation().getInputLimit() >= 0) {
+
+                tInfoSource.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_OUT);
+                inputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_LIMITED_OUT, inLocation, inSubNet, tInfoSource.getTopic(),
+                        channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), channelIst.getStaticInputSignalBindingList()));
+
+            } else {
+                tInfoSource.setType(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_OUT);
+                inputToolInfoJastAddList.add(buildToolSpecifics(PnmlConstants.TRANSITION_TYPE_TOPIC_UNLIMITED_OUT, inLocation, inSubNet, tInfoSource.getTopic(),
+                        channelIst.getStaticTransitionInformation().getInputLimit(), channelIst.getStaticTransitionInformation().getOutputLimit(), channelIst.getStaticInputSignalBindingList()));
+            }
+
+            publisherIst.setToolspecificList(inputToolInfoJastAddList);
+            publisherIst.setMutualTransitionInformation(tInfoSource);
+
+            // Reconnect Input Signals
+            for (InputSignalBinding isb : channelIst.getStaticInputSignalBindingList()) {
+
+                InputSignalBinding newIsb = new InputSignalBinding();
+                newIsb.setInputSignalValue(isb.getInputSignalValue());
+                newIsb.setTransitionID(isb.getTransitionID());
+                newIsb.setId(isb.getId());
+                newIsb.setInputSignalID(isb.getInputSignalID());
+
+                publisherIst.addMutualInputSignalBinding(newIsb);
+            }
+
+            // Get all incoming arcs and connect them to new output transition
+            for(Arc arc : p.asOutputSignalPlace().getOutArcList().toArray(new Arc[0])){
+
+                if(arc.getTarget().getId().equals(transition.getId())){
+                    arc.setTarget(publisherIst);
+                }
+            }
+
+            // Add new transitions to net
+            transitionsToAdd.add(publisherIst);
+
+            publisherCount++;
+        }
     }
 
     private static PetriNet createdSeparatedNetByLocation(PetriNet petriNet, String location) {
@@ -273,7 +292,7 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
         Set<String> removePlaceIds = new HashSet<>();
 
         for (Place place : separatedNet.allPlaces()) {
-            if (!place.asOutputSignalPlace().getStaticTransitionInformation().getSubNet().equals(location)) {
+            if (!place.asOutputSignalPlace().getStaticPlaceInformation().getSubNet().equals(location)) {
                 removePlaceIds.add(place.getId());
             }
         }
@@ -293,14 +312,14 @@ public class GlobalToLocalNetsPostProcessor implements PostProcessor<PetriNet> {
         }
 
         for (Place place : separatedNet.allPlaces()) {
-            if (!place.asOutputSignalPlace().getStaticTransitionInformation().getSubNet().equals(location)) {
+            if (!place.asOutputSignalPlace().getStaticPlaceInformation().getSubNet().equals(location)) {
                 logger.info("removing place " + place.getId() + " from net");
                 place.removeSelf();
             }
         }
 
         for (Transition transition : separatedNet.allTransitions()) {
-            if (!transition.asInputSignalTransition().getStaticTransitionInformation().asTopicTransitionInformation().getTopic().equals(location)) {
+            if (!transition.asInputSignalTransition().getStaticTransitionInformation().asTopicTransitionInformation().getSubNet().equals(location)) {
                 logger.info("removing transition " + transition.getId() + " from net");
                 transition.removeSelf();
             }
diff --git a/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessingUtils.java b/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessingUtils.java
index 432b969a58abf61b82187014c1f6a98165238b5a..458327c145bc9ec735100322c89d57033e4ff1b2 100644
--- a/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessingUtils.java
+++ b/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessingUtils.java
@@ -1,6 +1,8 @@
 package de.tudresden.inf.st.postprocessing;
 
 import de.tudresden.inf.st.constants.PnmlConstants;
+import de.tudresden.inf.st.copy.CopyPrimitiveElements;
+import de.tudresden.inf.st.data.Tuple3;
 import de.tudresden.inf.st.pnml.jastadd.model.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -17,50 +19,50 @@ public class PostProcessingUtils {
     // NET INFORMATION ////////////
     ///////////////////////////////
 
-    private static Set<Transition> getTransitionsBySubnet(String subNet, PetriNet petriNet){
+    private static Set<Transition> getTransitionsBySubnet(String subNet, PetriNet petriNet) {
 
         return petriNet.allTransitions().stream().filter(t -> t.asInputSignalTransition()
                 .getStaticTransitionInformation().getSubNet().equals(subNet)).collect(Collectors.toSet());
     }
 
-    private static Set<String> getTransitionIDsBySubnet(String subNet, PetriNet petriNet){
+    private static Set<String> getTransitionIDsBySubnet(String subNet, PetriNet petriNet) {
 
         Set<String> transitionIds = new HashSet<>();
 
-        for(Transition t : getTransitionsBySubnet(subNet, petriNet)){
+        for (Transition t : getTransitionsBySubnet(subNet, petriNet)) {
             transitionIds.add(t.getId());
         }
 
         return transitionIds;
     }
 
-    private static Set<String> getPlaceIDsBySubnet(String subNet, PetriNet petriNet){
+    private static Set<String> getPlaceIDsBySubnet(String subNet, PetriNet petriNet) {
 
         Set<String> placeIds = new HashSet<>();
 
-        for(Place p : getPlacesBySubnet(subNet, petriNet)){
+        for (Place p : getPlacesBySubnet(subNet, petriNet)) {
             placeIds.add(p.getId());
         }
 
         return placeIds;
     }
 
-    private static Set<Place> getPlacesBySubnet(String subNet, PetriNet petriNet){
+    private static Set<Place> getPlacesBySubnet(String subNet, PetriNet petriNet) {
 
         return petriNet.allPlaces().stream().filter(t -> t.asOutputSignalPlace()
-                .getStaticTransitionInformation().getSubNet().equals(subNet)).collect(Collectors.toSet());
+                .getStaticPlaceInformation().getSubNet().equals(subNet)).collect(Collectors.toSet());
     }
 
-    private static Set<Arc> getInternalArcsBySubnet(String subNet, PetriNet petriNet){
+    private static Set<Arc> getInternalArcsBySubnet(String subNet, PetriNet petriNet) {
 
         Set<Arc> internalArcs = new HashSet<>();
         Set<String> subNetTransitionIds = getTransitionIDsBySubnet(subNet, petriNet);
         Set<String> subNetPlaceIds = getPlaceIDsBySubnet(subNet, petriNet);
 
 
-        for(Arc arc : petriNet.allArcs()){
-            if((subNetTransitionIds.contains(arc.getSource().getId()) && subNetPlaceIds.contains(arc.getTarget().getId()))
-                    || (subNetTransitionIds.contains(arc.getTarget().getId()) && subNetPlaceIds.contains(arc.getSource().getId()))){
+        for (Arc arc : petriNet.allArcs()) {
+            if ((subNetTransitionIds.contains(arc.getSource().getId()) && subNetPlaceIds.contains(arc.getTarget().getId()))
+                    || (subNetTransitionIds.contains(arc.getTarget().getId()) && subNetPlaceIds.contains(arc.getSource().getId()))) {
                 internalArcs.add(arc);
             }
         }
@@ -68,15 +70,15 @@ public class PostProcessingUtils {
         return internalArcs;
     }
 
-    private static Set<Arc> getExternalArcsBySubnet(String subNet, PetriNet petriNet){
+    private static Set<Arc> getExternalArcsBySubnet(String subNet, PetriNet petriNet) {
 
         Set<Arc> externalArcs = new HashSet<>();
         Set<String> subNetTransitionIds = getTransitionIDsBySubnet(subNet, petriNet);
         Set<String> subNetPlaceIds = getPlaceIDsBySubnet(subNet, petriNet);
 
-        for(Arc arc : petriNet.allArcs()){
-            if(subNetTransitionIds.contains(arc.getSource().getId()) || subNetPlaceIds.contains(arc.getTarget().getId())
-                    || subNetTransitionIds.contains(arc.getTarget().getId()) || subNetPlaceIds.contains(arc.getSource().getId())){
+        for (Arc arc : petriNet.allArcs()) {
+            if (subNetTransitionIds.contains(arc.getSource().getId()) || subNetPlaceIds.contains(arc.getTarget().getId())
+                    || subNetTransitionIds.contains(arc.getTarget().getId()) || subNetPlaceIds.contains(arc.getSource().getId())) {
                 externalArcs.add(arc);
             }
         }
@@ -88,45 +90,93 @@ public class PostProcessingUtils {
     // NET MANIPULATION ///////////
     ///////////////////////////////
 
-    public static void setSubNetInstanceId(PetriNet petriNet, String subNet, String instanceId){
+    /**
+     * Updates the mutual instance ids, and (if not already existing creates a nre mutual information, based on the static one.
+     * @param petriNet
+     * @param subNet
+     * @param instanceId
+     */
+    public static void setSubNetInstanceId(PetriNet petriNet, String subNet, String instanceId) {
 
         Set<Transition> subNetTransitions = getTransitionsBySubnet(subNet, petriNet);
         Set<Place> subNetPlaces = getPlacesBySubnet(subNet, petriNet);
 
+        // update transition instance ids
         subNetTransitions.forEach(t -> {
 
-            if(t.asInputSignalTransition().getMutualTransitionInformation() == null){
-                // todo
+            if (t.asInputSignalTransition().getMutualTransitionInformation() == null) {
+
+                if (t.asInputSignalTransition().getStaticTransitionInformation().isServiceTransitionInformation()) {
+
+                    ServiceTransitionInformation oldSti = t.asInputSignalTransition().getStaticTransitionInformation().asServiceTransitionInformation();
+                    t.asInputSignalTransition().setMutualTransitionInformation(new ServiceTransitionInformation(oldSti.getLocation(), oldSti.getType(),
+                            oldSti.getInputLimit(), oldSti.getOutputLimit(), oldSti.getSubNet(), instanceId, oldSti.getServiceName()));
+
+                } else if (t.asInputSignalTransition().getStaticTransitionInformation().isTopicTransitionInformation()) {
+
+                    TopicTransitionInformation oldTti = t.asInputSignalTransition().getStaticTransitionInformation().asTopicTransitionInformation();
+                    t.asInputSignalTransition().setMutualTransitionInformation(new TopicTransitionInformation(oldTti.getLocation(), oldTti.getType(),
+                            oldTti.getInputLimit(), oldTti.getOutputLimit(), oldTti.getSubNet(), instanceId, oldTti.getTopic()));
+
+                } else if (t.asInputSignalTransition().getStaticTransitionInformation().isDefaultTransitionInformation()) {
+
+                    TransitionInformation oldTi = t.asInputSignalTransition().getStaticTransitionInformation();
+                    t.asInputSignalTransition().setMutualTransitionInformation(new DefaultTransitionInformation(oldTi.getLocation(), oldTi.getType(),
+                            oldTi.getInputLimit(), oldTi.getOutputLimit(), oldTi.getSubNet(), instanceId));
+                }
+            } else {
                 t.asInputSignalTransition().getMutualTransitionInformation().setInstance(instanceId);
             }
         });
-        //subNetPlaces.forEach(p -> p.asOutputSignalPlace());
 
-    }
+        // update place instance ids
+        subNetPlaces.forEach(p -> {
 
-    public static PetriNet copySubNet(PetriNet petriNet, String subNet, String instanceId){
+            if (p.asOutputSignalPlace().getMutualPlaceInformation() == null) {
 
-        Set<Transition> transitionsToAdd = new HashSet<>();
-        Set<Place> placesToRemove = new HashSet<>();
-        Set<Arc> arcsToRemove = new HashSet<>();
+                PlaceInformation oldPi = p.asOutputSignalPlace().getStaticPlaceInformation();
+                p.asOutputSignalPlace().setMutualPlaceInformation(new PlaceInformation(oldPi.getLocation(), oldPi.getType(), oldPi.getSubNet(), instanceId));
 
+            }else{
+                p.asOutputSignalPlace().getMutualPlaceInformation().setInstance(instanceId);
+            }
+        });
 
+    }
 
+    public static Tuple3<Set<Transition>, Set<Place>, Set<Arc>> copyServiceSubNet(PetriNet petriNet, String subNet, Page parentPage, String instanceId, String templateNetInstanceId) {
 
+        // new elements
+        Set<Transition> transitionsToAdd = new HashSet<>();
+        Set<Place> placesToAdd = new HashSet<>();
+        Set<Arc> arcsToAdd = new HashSet<>();
+
+        Set<Place> placesToRemove = new HashSet<>();
+        Set<Arc> arcsToRemove = new HashSet<>();
 
         for (Transition transition : petriNet.allTransitions()) {
 
             InputSignalTransition channelIst = transition.asInputSignalTransition();
 
-            // just process service transitions
-            if(channelIst.getStaticTransitionInformation().isServiceTransitionInformation()
-                    && channelIst.getStaticTransitionInformation().getType().equals(PnmlConstants.TRANSITION_TYPE_SERVICE_REQUEST)){
+            // just process "subnets" of service transitions
+            if (channelIst.getStaticTransitionInformation().isServiceTransitionInformation()
+                    && channelIst.getStaticTransitionInformation().getType().equals(PnmlConstants.TRANSITION_TYPE_SERVICE_REQUEST)) {
 
                 int numInArcs = channelIst.getInArcList().toArray(new Arc[0]).length;
+                String iterSubnet = channelIst.getStaticTransitionInformation().getSubNet();
+
+                // create deep copies of the transitions
+                for(Transition t: petriNet.allTransitions()){
+                    if(t.asInputSignalTransition().getStaticTransitionInformation().getSubNet().equals(iterSubnet)) {
+                        transitionsToAdd.add(CopyPrimitiveElements.copyInputSignalTransition(t.asInputSignalTransition(), instanceId + "-", instanceId));
+                    }
+                }
             }
 
         }
-        return null;
+
+
+        return new Tuple3<>(transitionsToAdd, placesToAdd, arcsToAdd);
     }
 
     ///////////////////////////////
@@ -139,29 +189,29 @@ public class PostProcessingUtils {
         logger.info("----------------- PLACES ----------------");
 
         for (Place p : petriNet.allPlaces()) {
-            logger.info("Place " + p.asOutputSignalPlace().getName().getText() + " -- " + p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet());
+            logger.info("Place " + p.asOutputSignalPlace().getName().getText() + " -- " + p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet());
         }
 
         logger.info("-------------- TRANSITIONS --------------");
 
         for (Transition t : petriNet.allTransitions()) {
 
-            if(t.asInputSignalTransition().getStaticTransitionInformation().isServiceTransitionInformation()) {
+            if (t.asInputSignalTransition().getStaticTransitionInformation().isServiceTransitionInformation()) {
                 logger.info("--- Transition: " + t.getName().getText() + " subnet: " + t.asInputSignalTransition().getStaticTransitionInformation().getSubNet()
                         + " service: " + t.asInputSignalTransition().getStaticTransitionInformation().asServiceTransitionInformation().getServiceName() + " ---------");
-            }else{
+            } else {
                 logger.info("--- Transition: " + t.getName().getText() + " subnet: " + t.asInputSignalTransition().getStaticTransitionInformation().getSubNet()
                         + " topic: " + t.asInputSignalTransition().getStaticTransitionInformation().asTopicTransitionInformation().getTopic() + " ---------");
             }
 
             for (Place p : t.asInputSignalTransition().incomingPlaces()) {
 
-                logger.info("------ Inputplace:  " + p.getName().getText() + " subnet: " + p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet() + " ---------");
+                logger.info("------ Inputplace:  " + p.getName().getText() + " subnet: " + p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet() + " ---------");
             }
 
             for (Place p : t.asInputSignalTransition().outgoingPlaces()) {
 
-                logger.info("------ Outputplace: " + p.getName().getText() + " subnet: " + p.asOutputSignalPlace().getStaticTransitionInformation().getSubNet() + " ---------");
+                logger.info("------ Outputplace: " + p.getName().getText() + " subnet: " + p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet() + " ---------");
             }
         }