diff --git a/src/main/jastadd/flatter/transforms/SignalTransforms.jadd b/src/main/jastadd/flatter/transforms/SignalTransforms.jadd
index 90bb155f22c88198976c9546b3906bd384cc1aa2..9e6cc4b78f202bbe68e7ef645ff17a598a196b84 100644
--- a/src/main/jastadd/flatter/transforms/SignalTransforms.jadd
+++ b/src/main/jastadd/flatter/transforms/SignalTransforms.jadd
@@ -2,29 +2,56 @@ aspect SignalTransforms {
 
     syn PetriNet PetriNet.transformSingleUseSignals(){
 
-        Map<String, String> signalDefs = this.getInputSignalDefinition();
-        Map<String, List<DinerosTransition>> signalMapping = TransformationUtils.getSignalToUsageMapping(this);
-
-        for (Map.Entry<String, String> entry : signalDefs.entrySet()) {
-            if (signalMapping.get(entry.getKey()).size() == 1) {
-
-                Transition toTrue = this.getTransitionById(TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_TRUE + "-" + entry.getKey());
-                Transition toFalse = this.getTransitionById(TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_FALSE + "-" + entry.getKey());
-
-                for (Place p : signalMapping.get(entry.getKey()).get(0).incomingPlaces()) {
-                    if(!p.getId().startsWith(TemplateConstants.PD_PLACE_PREFIX)){
-                        System.out.println("[SignalPostProcessing] Creating new linkage between "+p.getId()+" and "+toTrue.getId());
-                        TransformationUtils.createAndIncludeArc(this.getPage(0),p.getId()+"-to-"+toTrue.getId(),p,toTrue);
-                        TransformationUtils.createAndIncludeArc(this.getPage(0),toTrue.getId()+"-to-"+p.getId(),toTrue,p);
-
-                        System.out.println("[SignalPostProcessing] Creating new linkage between "+p.getId()+" and "+toFalse.getId());
-                        TransformationUtils.createAndIncludeArc(this.getPage(0),p.getId()+"-to-"+toFalse.getId(),p,toFalse);
-                        TransformationUtils.createAndIncludeArc(this.getPage(0),toFalse.getId()+"-to-"+p.getId(),toFalse,p);
-                    }
-                }
+      //  Map<String, String> signalDefs = this.getInputSignalDefinition();
+      Map<String, List<DinerosTransition>> signalMapping = TransformationUtils.getSignalToUsageMapping(this);
+
+      for (Map.Entry<String, List<DinerosTransition>> entry : signalMapping.entrySet()) {
+
+        Transition toTrue = this.getTransitionById(TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_TRUE + "-" + entry.getKey());
+        Transition toFalse = this.getTransitionById(TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_FALSE + "-" + entry.getKey());
+        Place placeTrue = this.getPlaceById(TemplateConstants.INPUT_SIGNAL_PLACE_TRUE + "-" + entry.getKey());
+        Place placeFalse = this.getPlaceById(TemplateConstants.INPUT_SIGNAL_PLACE_FALSE + "-" + entry.getKey());
+
+        int usageCount = 0;
+        for (DinerosTransition dt : entry.getValue()) {
+          for (Place p : dt.incomingPlaces()) {
+            if (!p.getId().startsWith(TemplateConstants.PD_PLACE_PREFIX)) {
+              if (usageCount == 1) {
+                System.out.println("[SignalPostProcessing] Creating new linkage between " + p.getId() + " and " + toTrue.getId());
+                TransformationUtils.createAndIncludeArc(this.getPage(0), p.getId() + "-to-" + toTrue.getId(), p, toTrue);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), toTrue.getId() + "-to-" + p.getId(), toTrue, p);
+
+                System.out.println("[SignalPostProcessing] Creating new linkage between " + p.getId() + " and " + toFalse.getId());
+                TransformationUtils.createAndIncludeArc(this.getPage(0), p.getId() + "-to-" + toFalse.getId(), p, toFalse);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), toFalse.getId() + "-to-" + p.getId(), toFalse, p);
+              } else {
+                DinerosTransition newToTrue = PrimitiveTemplates.getDinerosTransition();
+                newToTrue.setId(toTrue.getId() + "-" + usageCount);
+                newToTrue.getName().setText(newToTrue.getId());
+                DinerosTransition newToFalse = PrimitiveTemplates.getDinerosTransition();
+                newToFalse.setId(toFalse.getId() + "-" + usageCount);
+                newToFalse.getName().setText(newToFalse.getId());
+                this.getPage(0).addObject(newToTrue);
+                this.getPage(0).addObject(newToFalse);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), placeTrue.getId() + "-to-" + newToFalse.getId(), placeTrue, newToFalse);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), newToFalse.getId() + "-to-" + placeFalse.getId(), toFalse, placeFalse);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), placeFalse.getId() + "-to-" + newToTrue.getId(), placeFalse, newToTrue);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), newToTrue.getId() + "-to-" + placeTrue.getId(), toTrue, placeTrue);
+
+                System.out.println("[SignalPostProcessing] Creating new linkage between " + p.getId() + " and " + newToTrue.getId());
+                TransformationUtils.createAndIncludeArc(this.getPage(0), p.getId() + "-to-" + newToTrue.getId(), p, newToTrue);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), newToTrue.getId() + "-to-" + p.getId(), newToTrue, p);
+
+                System.out.println("[SignalPostProcessing] Creating new linkage between " + p.getId() + " and " + newToFalse.getId());
+                TransformationUtils.createAndIncludeArc(this.getPage(0), p.getId() + "-to-" + newToFalse.getId(), p, newToFalse);
+                TransformationUtils.createAndIncludeArc(this.getPage(0), newToFalse.getId() + "-to-" + p.getId(), newToFalse, p);
+              }
             }
+          }
+          usageCount++;
         }
-        return this;
+      }
+      return this;
     }
 
     // apply rule I4
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java
index 7878f1948429726f6a92b439583732dec6cac9c1..8736cba06b7d1a0710b1e5eb3115ba5468aafb26 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java
@@ -26,15 +26,20 @@ public class Main {
 
         String configPath = (args.length > 1) ? args[1] : null;
         String pnmlPath = (args.length > 0) ? args[0] : null;
+        //"/home/sebastian/git/dineros-public/dineros/pnml-relast-apps/" +
+               // "robotic-sorting/rpn-models/full-models/sorting-wf-synced-safe-sensor-grpn-sig.pnml";//
                 //"/home/sebastian/git/dineros-public/dineros/pnml-relast-apps/robotic-sorting/test-models/pubsub.pnml";
-              //  "/home/sebastian/git/dineros-public/dineros/pnml-relast-apps/robotic-sorting/rpn-models/full-models/sorting-wf-synced-safe-sensor-grpn-sig.pnml";
+
         boolean flagInhibitor = Boolean.parseBoolean(args[2]);
-        boolean flagSignal =  Boolean.parseBoolean(args[3]);
-        doFlattening(configPath, pnmlPath, flagInhibitor, flagSignal);
+        boolean flagSignal = Boolean.parseBoolean(args[3]);
+        boolean flagPurge = Boolean.parseBoolean(args[4]);
+        doFlattening(configPath, pnmlPath, flagInhibitor, flagSignal, flagPurge);
 
     }
 
-    private static void doFlattening(String configPath, String pnmlPath, boolean flagInhibitor, boolean flagSignal) throws InvalidIDException, IOException, InterruptedException {
+    private static void doFlattening(String configPath, String pnmlPath, boolean flagInhibitor, boolean flagSignal, boolean flagPurge)
+            throws InvalidIDException, IOException, InterruptedException {
+
         if (pnmlPath == null) {
             System.out.println("[ERROR] No model found on given input path.");
             return;
@@ -125,6 +130,8 @@ public class Main {
         System.out.println("[FLATTENER] Running postprocessing.");
         if(flagSignal) {
             petriNet.transformSingleUseSignals();
+            petriNet.flushAttrAndCollectionCache();
+            petriNet.flushTreeCache();
         }
 
         // [STAGE 8] export flatted net to pnml
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java
index 48ff661fcdd18fc163ed6b5a8902e22a18cf5947..06cd961cfdccaca55665f4fc4289408b0f87f289 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/TransformationUtils.java
@@ -7,7 +7,6 @@ import java.util.*;
 
 public class TransformationUtils {
 
-
     /**
      *
      * @param petriNet before signals are flatted
@@ -27,8 +26,8 @@ public class TransformationUtils {
         for (Map.Entry<java.lang.String, java.lang.String> signalDef : signalDefinitions.entrySet()) {
             for(DinerosTransition dt : petriNet.allDinerosTransitions()){
                 if(dt.getStaticTransitionInformation().isSignalTransitionInformation()){
-                    if(clauseHasSignal(dt.getStaticTransitionInformation().
-                            asSignalTransitionInformation().getClause(), signalDef.getKey())){
+                    if(dt.getStaticTransitionInformation().
+                            asSignalTransitionInformation().getClause().hasLiteral(signalDef.getKey())){
                         mapping.get(signalDef.getKey()).add(dt);
                     }
                 }
@@ -37,19 +36,6 @@ public class TransformationUtils {
         return mapping;
     }
 
-    private static boolean clauseHasSignal(InputSignalClause clause, String signalId){
-
-        for(Disjunction d : clause.getDisjunctions()){
-            for(Literal l : d.getLiterals()){
-                if(l.getName().equals(signalId)){
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
     public static Arc createArc(String id, Node s, Node t) {
 
         Arc a = new Arc();
@@ -310,4 +296,80 @@ public class TransformationUtils {
 
         return null;
     }
+
+    public static List<Page> getSourceNodePages(PetriNet petriNet){
+
+        List<Page> pages = new ArrayList<>();
+
+        for(Page page : petriNet.allPages()){
+            for(ToolInfo ti : page.getToolspecifics()){
+                if(ti.getFormattedXMLBuffer().indexOf("nodePage") != -1){
+
+                    // check if source node
+                    Set<String> placesInPage = new HashSet<>();
+                    placesInPage(page, placesInPage);
+
+                    boolean isPublisher = false;
+                    boolean isSubscriber = false;
+                    boolean isServer = false;
+                    boolean isClient = false;
+
+                    for(DinerosTransition t : petriNet.allDinerosTransitions()){
+                        if(t.getStaticTransitionInformation().isServiceTransitionInformation()){
+                            if(placesInPage.contains(t.getStaticTransitionInformation().
+                                    asServiceTransitionInformation().getServerChannel().getRequestPlaceId())){
+                                isServer = true;
+                                break;
+                            }
+
+                            for(ServiceChannel sc : t.getStaticTransitionInformation()
+                                    .asServiceTransitionInformation().getClientChannels()){
+                                if(placesInPage.contains(sc.getRequestPlaceId())){
+                                    isClient = true;
+                                    break;
+                                }
+                            }
+                        }
+
+                        if(t.getStaticTransitionInformation().isTopicTransitionInformation()){
+                            for(SubscriberPort sp : t.getStaticTransitionInformation().
+                                    asTopicTransitionInformation().getSubscriberPorts()){
+                                if(placesInPage.contains(sp.getPlaceId())){
+                                    isSubscriber = true;
+                                    break;
+                                }
+                            }
+
+                            for(PublisherPort pp : t.getStaticTransitionInformation().
+                                    asTopicTransitionInformation().getPublisherPorts()){
+                                if(placesInPage.contains(pp.getPlaceId())){
+                                    isPublisher = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    if(isPublisher && !isSubscriber && !isClient && !isServer){
+                        pages.add(page);
+                    }
+
+                    break;
+                }
+            }
+        }
+        return pages;
+    }
+
+    private static void placesInPage(Page page, Set<String> places){
+
+        for(PnObject po : page.getObjects()){
+            if(po.isPlaceObject()){
+                places.add(po.getId());
+            }
+            if(po.isPageNode()){
+                placesInPage(po.asPage(), places);
+            }
+        }
+    }
 }