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 656246e38e66f5a56ca3527a12203902e7309cdd..007ad946153ae28e540203e9b390ce0f5aa65f8e 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
@@ -4,11 +4,10 @@ import de.tudresden.inf.st.pnml.flatter.config.ConfigReader;
 import de.tudresden.inf.st.pnml.flatter.tina.TinaProxy;
 import de.tudresden.inf.st.pnml.flatter.transform.ChannelFlatter;
 import de.tudresden.inf.st.pnml.flatter.transform.ReferenceFlatter;
+import de.tudresden.inf.st.pnml.flatter.transform.SignalFlatter;
 import de.tudresden.inf.st.pnml.jastadd.model.*;
 import de.tudresden.inf.st.pnml.jastadd.model.PnmlParser;
 import fr.lip6.move.pnml.framework.utils.exception.InvalidIDException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import de.tudresden.inf.st.pnml.flatter.tina.NdrioProxy;
 import de.tudresden.inf.st.pnml.jastadd.model.PetriNet;
@@ -18,8 +17,6 @@ import java.util.UUID;
 
 public class Main {
 
-    private static final Logger logger = LoggerFactory.getLogger(Main.class);
-
     public static void main(String[] args) throws IOException, InvalidIDException {
 
         String configPath = (args.length > 1) ? args[1] : null;
@@ -70,8 +67,8 @@ public class Main {
 
         // flat input signals
         System.out.println("[FLATTER] Breaking down signals.");
-        PetriNet signalFlattedPetriNet = ChannelFlatter.flatSignals(serviceFlattedPetriNet);
-        // printNet(signalFlattedPetriNet);
+        PetriNet signalFlattedPetriNet = SignalFlatter.flatSignals(serviceFlattedPetriNet);
+        printNet(signalFlattedPetriNet);
 
         // export flatted net to pnml
         System.out.println("[FLATTER] Exporting to pnml.");
@@ -178,7 +175,6 @@ public class Main {
         System.out.println("----------------- ARCS -----------------");
 
         for (Arc a : petriNet.allArcs()) {
-            System.out.println("Arc: " + a.getId());
             System.out.println("Arc: " + a.getId() + " -- source: " + a.getSource().getId() + " -- target: " + a.getTarget().getId());
 
             if(a.getNumToolspecific() > 0){
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/template/TemplateConstants.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/template/TemplateConstants.java
index 4599232b3ac284d259e05035085bcb4f27e00854..cc4f7ce05962acf6fc17b6e6be1298bde8331fbc 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/template/TemplateConstants.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/template/TemplateConstants.java
@@ -37,18 +37,15 @@ public final class TemplateConstants {
     public static final String INPUT_SIGNAL_TEMPLATE_PAGE = "InputSignalTemplatePage";
     public static final String INPUT_SIGNAL_PLACE_ACTIVE = "InputSignalActivePlace";
     public static final String INPUT_SIGNAL_PLACE_INACTIVE = "InputSignalInactivePlace";
-    public static final String INPUT_SIGNAL_PLACE_OR_CONNECTION = "InputSignalOrConnection";
-    public static final String INPUT_SIGNAL_PLACE_OR_RESET = "InputSignalOrReset";
-    public static final String INPUT_SIGNAL_TO_OR = "InputSignalToOr";
+    public static final String INPUT_SIGNAL_PLACE_OR_CONNECTION_FALSE_PREFIX = "DINEROS-InputSignalOrConnectionFalse";
+    public static final String INPUT_SIGNAL_PLACE_OR_CONNECTION_TRUE_PREFIX = "DINEROS-InputSignalOrConnectionTrue";
     public static final String INPUT_SIGNAL_TRANSITION_TO_ACTIVE = "InputSignalInactiveToActiveTransition";
     public static final String INPUT_SIGNAL_TRANSITION_TO_INACTIVE = "InputSignalActiveToInactiveTransition";
 
-    public static final String ARC_ACTIVE_TO_OR = "ArcActiveToOr";
-    public static final String ARC_OR_TO_ACTIVE = "ArcOrToActive";
-    public static final String ARC_OR_TO_PLACE = "ArcOrToPlace";
-    public static final String ARC_PLACE_TO_OR = "ArcPlaceToOr";
-    public static final String ARC_TO_OR_RESET = "ArcToOrReset";
-    public static final String ARC_FROM_OR_RESET = "ArcFromOrReset";
+    public static final String ARC_T_ACTIVE_TO_TRUE = "DINEROS-ArcTActiveToTrue";
+    public static final String ARC_FALSE_TO_T_ACTIVE = "DINEROS-ArcFalseToTActive";
+    public static final String ARC_T_INACTIVE_TO_FALSE = "DINEROS-ArcTInactiveToFalse";
+    public static final String ARC_TRUE_TO_T_INACTIVE = "DINEROS-ArcTrueToTInactive";
 
     // services
     public static final String SERVICE_THREAD_PLACE = "ServiceThreadPlace";
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java
index 7a1b68c5c82cac4ce077ad0aa5af0c6530aa6a63..48d0c1caefca8b6688557b0899a83a7794154167 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java
@@ -13,279 +13,10 @@ import java.util.*;
 /**
  * only works if pages / references got flatted before
  */
-public class ChannelFlatter {
+public class ChannelFlatter extends Flatter {
 
     private static final Logger logger = LoggerFactory.getLogger(ChannelFlatter.class);
 
-    public static PetriNet flatSignals(PetriNet petriNet) {
-
-        Page topPage = petriNet.getPage(0);
-
-        Map<String, List<InputSignalTransition>> signalMap = new HashMap<>();
-
-        // construct signal-id to transition mapping
-        for (Transition t : petriNet.allTransitions()) {
-
-            if (t.asInputSignalTransition().getStaticInputSignalBindingList() != null) {
-                for (InputSignalBinding isb : t.asInputSignalTransition().getStaticInputSignalBindingList()) {
-
-                    if (signalMap.containsKey(isb.getInputSignalID())) {
-                        signalMap.get(isb.getInputSignalID()).add(t.asInputSignalTransition());
-                    } else {
-                        List<InputSignalTransition> transitionList = new ArrayList<>();
-                        transitionList.add(t.asInputSignalTransition());
-                        signalMap.put(isb.getInputSignalID(), transitionList);
-                    }
-                }
-            }
-        }
-
-        // build clauses
-        int signalCount = 0;
-        for (Map.Entry<String, List<InputSignalTransition>> entry : signalMap.entrySet()) {
-
-            // build signal root net
-            PetriNet signalTemplate = SignalTemplates.getInputSignalTemplate(entry.getKey() + "-base");
-            includeTemplateInstance(petriNet, signalTemplate, "signals", "signals");
-
-            String targetId = TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + entry.getKey() + "-base";
-            String targetId2 = TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + entry.getKey() + "-base";
-            Place coreInPlace = getPlaceByID(petriNet, targetId);
-
-            for (InputSignalBinding isb : entry.getValue().get(0).getStaticInputSignalBindingList()) {
-                if (isb.getInputSignalID().equals(entry.getKey())) {
-
-                    if (isb.getInputSignalValue() == 1) {
-                        getPlaceByID(petriNet, targetId).getInitialMarking().setText(1);
-                    } else {
-                        getPlaceByID(petriNet, targetId2).getInitialMarking().setText(1);
-                    }
-                }
-            }
-
-            int andCount = 0;
-            int orCount = 0;
-
-            for (int i = 0; i < entry.getValue().size(); i++) {
-                String actToInActId = TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_INACTIVE + "-" + entry.getKey() + "-base";
-                String inActToActId = TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_ACTIVE + "-" + entry.getKey() + "-base";
-
-                boolean isActiveSignal = false;
-                for (InputSignalBinding isb : entry.getValue().get(i).getStaticInputSignalBindingList()) {
-                    if (isb.getInputSignalID().equals(entry.getKey())) {
-                        isActiveSignal = isb.getInputSignalValue() == 1;
-                        break;
-                    }
-                }
-
-                // build AND-based clauses
-                if (!entry.getValue().get(i).getInputSignalClause().printExp().contains("OR")) {
-
-                    if (andCount == 0) {
-                        createAndIncludeArc(topPage, "IoTransitionToSignal-" + entry.getKey() + "-base", entry.getValue().get(i), coreInPlace);
-                        createAndIncludeArc(topPage, "IoTransitionFromSignal-" + entry.getKey() + "-base", coreInPlace, entry.getValue().get(i));
-                        petriNet.flushTreeCache();
-                    } else {
-                        attachANDSignalNetToBaseSignalNet(petriNet, entry.getValue().get(i),
-                                Objects.requireNonNull(getTransitionByID(petriNet, actToInActId)).asInputSignalTransition(),
-                                getTransitionByID(petriNet, inActToActId).asInputSignalTransition(), i, entry.getKey(), isActiveSignal);
-                    }
-
-                    andCount++;
-                }
-
-                // build OR-based clauses
-                if (entry.getValue().get(i).getInputSignalClause().printExp().contains("OR")) {
-                    // has already connected or signal connecting place?
-                    Place orPlace = null;
-                    for (Place p : entry.getValue().get(i).incomingPlaces()) {
-                        if (p.getId().contains(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION)) {
-                            orPlace = p;
-                            break;
-                        }
-                    }
-
-                    if (orPlace == null) {
-                        orPlace = buildOrBaseNetElements(petriNet, topPage, signalCount, i, entry.getValue().get(i));
-                    }
-
-                    InputSignalTransition activeToOrConnector = PrimitiveTemplates.getInputSignalTransition();
-                    activeToOrConnector.setId(TemplateConstants.INPUT_SIGNAL_TO_OR + "-" + entry.getKey() + "-" + i);
-                    Name nameT = new Name();
-                    nameT.setText(TemplateConstants.INPUT_SIGNAL_TO_OR + "-" + entry.getKey() + "-" + i);
-                    activeToOrConnector.setName(nameT);
-                    TransitionInformation pi3 = new DefaultTransitionInformation();
-                    pi3.setLocation("signal");
-                    pi3.setSubNet("signal");
-                    activeToOrConnector.setMutualTransitionInformation(pi3);
-
-                    topPage.addObject(activeToOrConnector);
-                    petriNet.flushTreeCache();
-
-                    if (andCount == 0 && orCount == 0) {
-                        attachORSignalNetToBaseSignalNet(petriNet, getTransitionByID(petriNet, actToInActId).asInputSignalTransition(),
-                                getTransitionByID(petriNet, inActToActId).asInputSignalTransition(), activeToOrConnector,
-                                orPlace.asOutputSignalPlace(), i, entry.getKey(), true, isActiveSignal);
-
-                    } else {
-                        attachORSignalNetToBaseSignalNet(petriNet, getTransitionByID(petriNet, actToInActId).asInputSignalTransition(),
-                                getTransitionByID(petriNet, inActToActId).asInputSignalTransition(), activeToOrConnector,
-                                orPlace.asOutputSignalPlace(), i, entry.getKey(), false, isActiveSignal);
-                    }
-                    orCount++;
-                }
-            }
-
-            signalCount++;
-        }
-
-        // include negations
-        // TODO
-
-        return petriNet;
-    }
-
-    @NotNull
-    private static Place buildOrBaseNetElements(PetriNet petriNet, Page topPage, int signalCount, int i, Transition transition) {
-        OutputSignalPlace newOrPlace = PrimitiveTemplates.getOutputSignalPlace();
-        newOrPlace.setId(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION + "-" + signalCount + "-" + i);
-        Name name = new Name();
-        name.setText(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION + "-" + signalCount + "-" + i);
-        newOrPlace.setName(name);
-        PlaceInformation pi = new PlaceInformation();
-        pi.setLocation("signal");
-        pi.setSubNet("signal");
-        newOrPlace.setMutualPlaceInformation(pi);
-
-        InputSignalTransition orResetTransition = PrimitiveTemplates.getInputSignalTransition();
-        orResetTransition.setId(TemplateConstants.INPUT_SIGNAL_PLACE_OR_RESET + "-" + signalCount + "-" + i);
-        Name nameT = new Name();
-        nameT.setText(TemplateConstants.INPUT_SIGNAL_PLACE_OR_RESET + "-" + signalCount + "-" + i);
-        orResetTransition.setName(nameT);
-        TransitionInformation pi2 = new DefaultTransitionInformation();
-        pi2.setLocation("signal");
-        pi2.setSubNet("signal");
-        orResetTransition.setMutualTransitionInformation(pi2);
-
-        topPage.addObject(newOrPlace);
-        topPage.addObject(orResetTransition);
-
-        createAndIncludeArc(topPage, newOrPlace.getId() + "-to-" + orResetTransition.getId(), newOrPlace, orResetTransition);
-        createAndIncludeArc(topPage, newOrPlace.getId() + "-to-" + transition.getId(), newOrPlace, transition);
-
-        petriNet.flushTreeCache();
-        return newOrPlace;
-    }
-
-    private static void attachORSignalNetToBaseSignalNet(PetriNet petriNet, InputSignalTransition inactiveT,
-                                                         InputSignalTransition activeT, InputSignalTransition activeToOrConnector,
-                                                         OutputSignalPlace orPlace, int count, String signalId, boolean isBase, boolean isActive) {
-
-        Page topPage = petriNet.getPage(0);
-        OutputSignalPlace aOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-base").asOutputSignalPlace();
-        OutputSignalPlace iOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-base").asOutputSignalPlace();
-
-        if (!isBase) {
-            aOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
-            iOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
-            aOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-" + count);
-            iOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-" + count);
-        }
-
-        // marking
-        if (isActive) {
-            aOsp.getInitialMarking().setText(1);
-        } else {
-            iOsp.getInitialMarking().setText(1);
-        }
-
-        InputSignalTransition resetTransition = null;
-
-        for (Arc a : orPlace.getOutArcList()) {
-            if (a.getTarget().getId().contains(TemplateConstants.INPUT_SIGNAL_PLACE_OR_RESET)) {
-                resetTransition = a.getTarget().asTransitionNode().asTransition().asInputSignalTransition();
-                break;
-            }
-        }
-
-        createAndIncludeArc(topPage, TemplateConstants.ARC_ACTIVE_TO_OR + "-" + signalId + "-" + count, aOsp, activeToOrConnector);
-        createAndIncludeArc(topPage, TemplateConstants.ARC_OR_TO_ACTIVE + "-" + signalId + "-" + count, activeToOrConnector, aOsp);
-        createAndIncludeInhibitorArc(topPage, TemplateConstants.ARC_OR_TO_PLACE + "-" + signalId + "-" + count, orPlace, activeToOrConnector);
-        createAndIncludeArc(topPage, TemplateConstants.ARC_PLACE_TO_OR + "-" + signalId + "-" + count, activeToOrConnector, orPlace);
-
-        if (!isBase) {
-            createAndIncludeArc(topPage, "arc-or-1-" + signalId + "-" + count, aOsp, inactiveT);
-            createAndIncludeArc(topPage, "arc-or-2-" + signalId + "-" + count, inactiveT, iOsp);
-            createAndIncludeArc(topPage, "arc-or-3-" + signalId + "-" + count, iOsp, activeT);
-            createAndIncludeArc(topPage, "arc-or-4-" + signalId + "-" + count, activeT, aOsp);
-        }
-
-        createAndIncludeArc(topPage, TemplateConstants.ARC_TO_OR_RESET + "-" + signalId + "-" + count, iOsp, resetTransition);
-        createAndIncludeArc(topPage, TemplateConstants.ARC_FROM_OR_RESET + "-" + signalId + "-" + count, resetTransition, iOsp);
-
-    }
-
-    private static void attachANDSignalNetToBaseSignalNet(PetriNet petriNet, InputSignalTransition transition, InputSignalTransition inactiveT, InputSignalTransition activeT, int count, String signalId, boolean isActive) {
-
-        Page topPage = petriNet.getPage(0);
-
-        OutputSignalPlace aOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
-        OutputSignalPlace iOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
-        aOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-" + count);
-        iOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-" + count);
-
-        createAndIncludeArc(topPage, "arc-and-1-" + signalId + "-" + count, aOsp, inactiveT);
-        createAndIncludeArc(topPage, "arc-and-2-" + signalId + "-" + count, inactiveT, iOsp);
-        createAndIncludeArc(topPage, "arc-and-3-" + signalId + "-" + count, iOsp, activeT);
-        createAndIncludeArc(topPage, "arc-and-4-" + signalId + "-" + count, activeT, aOsp);
-
-        createAndIncludeArc(topPage, "IoTransitionToSignal-" + signalId + "-" + count, transition, aOsp);
-        createAndIncludeArc(topPage, "IoTransitionFromSignal-" + signalId + "-" + count, aOsp, transition);
-
-        topPage.addObject(aOsp);
-        topPage.addObject(iOsp);
-
-        // marking
-        if (isActive) {
-            aOsp.getInitialMarking().setText(1);
-        } else {
-            iOsp.getInitialMarking().setText(1);
-        }
-
-        petriNet.flushTreeCache();
-    }
-
-    private static Arc createArc(String id, Node s, Node t) {
-
-        Arc a = new Arc();
-        a.setId(id);
-        a.setSource(s);
-        a.setTarget(t);
-        return a;
-    }
-
-    private static Arc createAndIncludeArc(Page page, String id, Node s, Node t) {
-
-        Arc a = createArc(id, s, t);
-        page.addObject(a);
-        return a;
-    }
-
-    private static Arc createAndIncludeInhibitorArc(Page page, String id, Node s, Node t) {
-
-        Arc a = createArc(id, s, t);
-        ToolInfo ti = new ToolInfo();
-        String xml = "<toolspecific xmlns=\"http://www.pnml.org/version-2009/grammar/pnml\" tool=\"de.tudresden.inf.st.pnml.distributedPN\" version=\"0.1\">\n" +
-                "                    <type>inhibitor</type>\n" +
-                "                </toolspecific>";
-        ti.setFormattedXMLBuffer(new StringBuffer(xml));
-        ti.setTool("de.tudresden.inf.st.pnml.distributedPN");
-        ti.setVersion("0.1");
-        a.addToolspecific(ti);
-        page.addObject(a);
-        return a;
-    }
-
     public static PetriNet flatTopicChannels(PetriNet petriNet) {
 
         int publisherCount = 0;
@@ -1092,89 +823,4 @@ public class ChannelFlatter {
         return pnObjects;
     }
 
-    private static void includeTemplateInstance(PetriNet petriNet, PetriNet templateInstance, String subnet, String location) {
-
-        // after tina-flat we do only have on page
-        Page topPage = petriNet.getPage(0);
-
-        // include places, transitions
-        for (Transition t : templateInstance.allTransitions()) {
-
-            TransitionInformation newTi = new DefaultTransitionInformation();
-            newTi.setLocation(location);
-            newTi.setSubNet(subnet);
-            newTi.setType(t.asInputSignalTransition().getStaticTransitionInformation().getType());
-            t.asInputSignalTransition().setMutualTransitionInformation(newTi);
-
-            topPage.addObject(t);
-        }
-
-        for (Place p : templateInstance.allPlaces()) {
-
-            PlaceInformation newPi = new PlaceInformation();
-            newPi.setLocation(location);
-            newPi.setSubNet(subnet);
-            newPi.setType(p.asOutputSignalPlace().getStaticPlaceInformation().getType());
-            p.asOutputSignalPlace().setMutualPlaceInformation(newPi);
-
-            topPage.addObject(p);
-        }
-
-        petriNet.flushTreeCache();
-
-        // connect elements by arcs
-        for (Arc a : templateInstance.allArcs()) {
-            Arc newArc = new Arc();
-            newArc.setId("arc-" + a.getSource().getId() + "-" + a.getTarget().getId());
-            //     System.out.println("Target: " + a.getTarget().getId());
-            newArc.setTarget((Node) getPnObjectByID(petriNet, a.getTarget().getId()));
-            newArc.setSource((Node) getPnObjectByID(petriNet, a.getSource().getId()));
-
-            if (a.getNumToolspecific() > 0) {
-                ToolInfo ti = new ToolInfo();
-                ti.setFormattedXMLBuffer(a.getToolspecific(0).getFormattedXMLBuffer());
-                ti.setTool(a.getToolspecific(0).getTool());
-                ti.setVersion(a.getToolspecific(0).getVersion());
-                newArc.addToolspecific(ti);
-            }
-
-            topPage.addObject(newArc);
-        }
-
-        petriNet.flushTreeCache();
-    }
-
-
-    private static Place getPlaceByID(PetriNet petriNet, String Id) {
-
-        for (Place p : petriNet.allPlaces()) {
-            if (p.getId().equals(Id)) {
-                return p;
-            }
-        }
-
-        return null;
-    }
-
-    private static Transition getTransitionByID(PetriNet petriNet, String Id) {
-
-        for (Transition t : petriNet.allTransitions()) {
-            if (t.getId().equals(Id)) {
-                return t;
-            }
-        }
-
-        return null;
-    }
-
-    private static PnObject getPnObjectByID(PetriNet petriNet, String Id) {
-
-        for (PnObject po : petriNet.allObjects()) {
-            if (po.getId().equals(Id)) {
-                return po;
-            }
-        }
-
-        return null;
-    }
 }
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/Flatter.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/Flatter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b18bc4658c12bdb8a4675132e37501a6fdef900
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/Flatter.java
@@ -0,0 +1,123 @@
+package de.tudresden.inf.st.pnml.flatter.transform;
+
+import de.tudresden.inf.st.pnml.jastadd.model.*;
+
+public abstract class Flatter {
+
+    protected static Arc createArc(String id, Node s, Node t) {
+
+        Arc a = new Arc();
+        a.setId(id);
+        a.setSource(s);
+        a.setTarget(t);
+        return a;
+    }
+
+    protected static Arc createAndIncludeArc(Page page, String id, Node s, Node t) {
+
+        Arc a = createArc(id, s, t);
+        page.addObject(a);
+        return a;
+    }
+
+    protected static Arc createAndIncludeInhibitorArc(Page page, String id, Node s, Node t) {
+
+        Arc a = createArc(id, s, t);
+        ToolInfo ti = new ToolInfo();
+        String xml = "<toolspecific xmlns=\"http://www.pnml.org/version-2009/grammar/pnml\" tool=\"de.tudresden.inf.st.pnml.distributedPN\" version=\"0.1\">\n" +
+                "                    <type>inhibitor</type>\n" +
+                "                </toolspecific>";
+        ti.setFormattedXMLBuffer(new StringBuffer(xml));
+        ti.setTool("de.tudresden.inf.st.pnml.distributedPN");
+        ti.setVersion("0.1");
+        a.addToolspecific(ti);
+        page.addObject(a);
+        return a;
+    }
+
+    protected static void includeTemplateInstance(PetriNet petriNet, PetriNet templateInstance, String subnet, String location) {
+
+        // after tina-flat we do only have on page
+        Page topPage = petriNet.getPage(0);
+
+        // include places, transitions
+        for (Transition t : templateInstance.allTransitions()) {
+
+            TransitionInformation newTi = new DefaultTransitionInformation();
+            newTi.setLocation(location);
+            newTi.setSubNet(subnet);
+            newTi.setType(t.asInputSignalTransition().getStaticTransitionInformation().getType());
+            t.asInputSignalTransition().setMutualTransitionInformation(newTi);
+
+            topPage.addObject(t);
+        }
+
+        for (Place p : templateInstance.allPlaces()) {
+
+            PlaceInformation newPi = new PlaceInformation();
+            newPi.setLocation(location);
+            newPi.setSubNet(subnet);
+            newPi.setType(p.asOutputSignalPlace().getStaticPlaceInformation().getType());
+            p.asOutputSignalPlace().setMutualPlaceInformation(newPi);
+
+            topPage.addObject(p);
+        }
+
+        petriNet.flushTreeCache();
+
+        // connect elements by arcs
+        for (Arc a : templateInstance.allArcs()) {
+            Arc newArc = new Arc();
+            newArc.setId("arc-" + a.getSource().getId() + "-" + a.getTarget().getId());
+            //     System.out.println("Target: " + a.getTarget().getId());
+            newArc.setTarget((Node) getPnObjectByID(petriNet, a.getTarget().getId()));
+            newArc.setSource((Node) getPnObjectByID(petriNet, a.getSource().getId()));
+
+            if (a.getNumToolspecific() > 0) {
+                ToolInfo ti = new ToolInfo();
+                ti.setFormattedXMLBuffer(a.getToolspecific(0).getFormattedXMLBuffer());
+                ti.setTool(a.getToolspecific(0).getTool());
+                ti.setVersion(a.getToolspecific(0).getVersion());
+                newArc.addToolspecific(ti);
+            }
+
+            topPage.addObject(newArc);
+        }
+
+        petriNet.flushTreeCache();
+    }
+
+
+    protected static Place getPlaceByID(PetriNet petriNet, String Id) {
+
+        for (Place p : petriNet.allPlaces()) {
+            if (p.getId().equals(Id)) {
+                return p;
+            }
+        }
+
+        return null;
+    }
+
+    protected static Transition getTransitionByID(PetriNet petriNet, String Id) {
+
+        for (Transition t : petriNet.allTransitions()) {
+            if (t.getId().equals(Id)) {
+                return t;
+            }
+        }
+
+        return null;
+    }
+
+    protected static PnObject getPnObjectByID(PetriNet petriNet, String Id) {
+
+        for (PnObject po : petriNet.allObjects()) {
+            if (po.getId().equals(Id)) {
+                return po;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java
index 4539aadebf850e725b2590e8936d9fcbfc3a5527..8dd23eff2cbe4bed55a9615d81ae373eaddda8f3 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ReferenceFlatter.java
@@ -5,7 +5,7 @@ import de.tudresden.inf.st.pnml.jastadd.model.*;
 import java.util.HashSet;
 import java.util.Set;
 
-public class ReferenceFlatter {
+public class ReferenceFlatter extends Flatter{
 
     private static void findPlaceReferences(PlaceNode placeNode, Set<PlaceNode> nodes){
 
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/SignalFlatter.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/SignalFlatter.java
index d506dcca1efa0d7a177f436d30e1e0509fcb4918..bee6f42a6382f2e1a938dcb59f7a07d062f8bffe 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/SignalFlatter.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/SignalFlatter.java
@@ -1,4 +1,243 @@
 package de.tudresden.inf.st.pnml.flatter.transform;
 
-public class SignalFlatter {
+import de.tudresden.inf.st.pnml.flatter.template.PrimitiveTemplates;
+import de.tudresden.inf.st.pnml.flatter.template.SignalTemplates;
+import de.tudresden.inf.st.pnml.flatter.template.TemplateConstants;
+import de.tudresden.inf.st.pnml.jastadd.model.*;
+
+import java.util.*;
+
+public class SignalFlatter extends Flatter{
+
+    public static PetriNet flatSignals(PetriNet petriNet) {
+
+        Page topPage = petriNet.getPage(0);
+
+        Map<String, List<InputSignalTransition>> signalMap = new HashMap<>();
+        Map<String, OutputSignalPlace> orPlacePairs = new HashMap<>();
+
+        // construct signal-id to transition mapping
+        for (Transition t : petriNet.allTransitions()) {
+
+            if (t.asInputSignalTransition().getStaticInputSignalBindingList() != null) {
+                for (InputSignalBinding isb : t.asInputSignalTransition().getStaticInputSignalBindingList()) {
+
+                    if (signalMap.containsKey(isb.getInputSignalID())) {
+                        signalMap.get(isb.getInputSignalID()).add(t.asInputSignalTransition());
+                    } else {
+                        List<InputSignalTransition> transitionList = new ArrayList<>();
+                        transitionList.add(t.asInputSignalTransition());
+                        signalMap.put(isb.getInputSignalID(), transitionList);
+                    }
+                }
+            }
+        }
+
+        // build clauses
+        int signalCount = 0;
+        for (Map.Entry<String, List<InputSignalTransition>> entry : signalMap.entrySet()) {
+
+            // build signal root net
+            PetriNet signalTemplate = SignalTemplates.getInputSignalTemplate(entry.getKey() + "-base");
+            includeTemplateInstance(petriNet, signalTemplate, "signals", "signals");
+
+            String targetId = TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + entry.getKey() + "-base";
+            String targetId2 = TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + entry.getKey() + "-base";
+            Place coreInPlace = getPlaceByID(petriNet, targetId);
+
+            for (InputSignalBinding isb : entry.getValue().get(0).getStaticInputSignalBindingList()) {
+                if (isb.getInputSignalID().equals(entry.getKey())) {
+
+                    if (isb.getInputSignalValue() == 1) {
+                        getPlaceByID(petriNet, targetId).getInitialMarking().setText(1);
+                    } else {
+                        getPlaceByID(petriNet, targetId2).getInitialMarking().setText(1);
+                    }
+                }
+            }
+
+            int andCount = 0;
+            int orCount = 0;
+
+            for (int i = 0; i < entry.getValue().size(); i++) {
+                String actToInActId = TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_INACTIVE + "-" + entry.getKey() + "-base";
+                String inActToActId = TemplateConstants.INPUT_SIGNAL_TRANSITION_TO_ACTIVE + "-" + entry.getKey() + "-base";
+
+                boolean isActiveSignal = false;
+                for (InputSignalBinding isb : entry.getValue().get(i).getStaticInputSignalBindingList()) {
+                    if (isb.getInputSignalID().equals(entry.getKey())) {
+                        isActiveSignal = isb.getInputSignalValue() == 1;
+                        break;
+                    }
+                }
+
+                // build AND-based clauses
+                if (!entry.getValue().get(i).getInputSignalClause().printExp().contains("OR")) {
+
+                    if (andCount == 0) {
+                        createAndIncludeArc(topPage, "IoTransitionToSignal-" + entry.getKey() + "-base", entry.getValue().get(i), coreInPlace);
+                        createAndIncludeArc(topPage, "IoTransitionFromSignal-" + entry.getKey() + "-base", coreInPlace, entry.getValue().get(i));
+                        petriNet.flushTreeCache();
+                    } else {
+                        attachANDSignalNetToBaseSignalNet(petriNet, entry.getValue().get(i),
+                                Objects.requireNonNull(getTransitionByID(petriNet, actToInActId)).asInputSignalTransition(),
+                                getTransitionByID(petriNet, inActToActId).asInputSignalTransition(), i, entry.getKey(), isActiveSignal);
+                    }
+
+                    andCount++;
+                }
+
+                // build OR-based clauses
+                if (entry.getValue().get(i).getInputSignalClause().printExp().contains("OR")) {
+                    // has already connected or signal connecting place?
+                    OutputSignalPlace orTruePlace = null;
+                    OutputSignalPlace orFalsePlace = null;
+
+                    for (Place p : entry.getValue().get(i).incomingPlaces()) {
+                        if (p.getId().contains(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION_TRUE_PREFIX)) {
+                            orTruePlace = p.asOutputSignalPlace();
+                            orFalsePlace = orPlacePairs.get(orTruePlace.getId());
+                            break;
+                        }
+                    }
+
+                    if (orTruePlace == null) {
+                        Pair<OutputSignalPlace, OutputSignalPlace> res =
+                                buildOrBaseNetElements(petriNet, topPage, signalCount, i, entry.getValue().get(i), orPlacePairs);
+                        orTruePlace = res._1;
+                        orFalsePlace = res._2;
+                    }
+
+                    if (andCount == 0 && orCount == 0) {
+                        attachORSignalNetToBaseSignalNet(petriNet, getTransitionByID(petriNet, actToInActId).asInputSignalTransition(),
+                                getTransitionByID(petriNet, inActToActId).asInputSignalTransition(), orTruePlace,
+                                orFalsePlace, i, entry.getKey(), true, isActiveSignal);
+                        System.out.println("BASE");
+
+                    } else {
+                        attachORSignalNetToBaseSignalNet(petriNet, getTransitionByID(petriNet, actToInActId).asInputSignalTransition(),
+                                getTransitionByID(petriNet, inActToActId).asInputSignalTransition(), orTruePlace,
+                                orFalsePlace, i, entry.getKey(), false, isActiveSignal);
+                        System.out.println("EXTEND");
+                    }
+                    orCount++;
+                }
+            }
+
+            signalCount++;
+        }
+
+        // include negations
+        // TODO
+
+        return petriNet;
+    }
+
+    private static Pair<OutputSignalPlace, OutputSignalPlace> buildOrBaseNetElements(
+            PetriNet petriNet, Page topPage, int signalCount, int i, Transition transition, Map<String, OutputSignalPlace> orPlacePairs) {
+
+        OutputSignalPlace orPlaceFalse = PrimitiveTemplates.getOutputSignalPlace();
+        orPlaceFalse.setId(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION_FALSE_PREFIX + "-" + signalCount + "-" + i);
+        Name fName = new Name();
+        fName.setText(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION_FALSE_PREFIX + "-" + signalCount + "-" + i);
+        orPlaceFalse.setName(fName);
+        PlaceInformation fPi = new PlaceInformation();
+        fPi.setLocation("signals");
+        fPi.setSubNet("signals");
+        orPlaceFalse.setMutualPlaceInformation(fPi);
+
+        OutputSignalPlace orPlaceTrue = PrimitiveTemplates.getOutputSignalPlace();
+        orPlaceTrue.setId(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION_TRUE_PREFIX + "-" + signalCount + "-" + i);
+        Name tName = new Name();
+        tName.setText(TemplateConstants.INPUT_SIGNAL_PLACE_OR_CONNECTION_TRUE_PREFIX + "-" + signalCount + "-" + i);
+        orPlaceTrue.setName(tName);
+        PlaceInformation tPi = new PlaceInformation();
+        tPi.setLocation("signals");
+        tPi.setSubNet("signals");
+        orPlaceTrue.setMutualPlaceInformation(tPi);
+
+        topPage.addObject(orPlaceTrue);
+        topPage.addObject(orPlaceFalse);
+
+        createAndIncludeArc(topPage, orPlaceTrue.getId() + "-to-" + transition.getId(), orPlaceTrue, transition);
+        createAndIncludeArc(topPage, transition.getId() + "-to-" + orPlaceTrue.getId(), transition, orPlaceTrue);
+
+        petriNet.flushTreeCache();
+
+        orPlacePairs.put(orPlaceTrue.getId(), orPlaceFalse);
+        return new Pair<>(orPlaceTrue, orPlaceFalse);
+    }
+
+    private static void attachORSignalNetToBaseSignalNet(PetriNet petriNet, InputSignalTransition inactiveT,
+                                                         InputSignalTransition activeT, OutputSignalPlace orTruePlace, OutputSignalPlace orFalsePlace,
+                                                         int count, String signalId, boolean isBase, boolean isActive) {
+
+        Page topPage = petriNet.getPage(0);
+        OutputSignalPlace aOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-base").asOutputSignalPlace();
+        OutputSignalPlace iOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-base").asOutputSignalPlace();
+
+        if (!isBase) {
+            aOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
+            iOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
+            aOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-" + count);
+            iOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-" + count);
+
+            topPage.addObject(aOsp);
+            topPage.addObject(iOsp);
+            petriNet.flushTreeCache();
+        }
+
+        // marking
+        if (isActive) {
+            aOsp.getInitialMarking().setText(1);
+            int orTruePlaceMarking = Integer.valueOf(orTruePlace.getInitialMarking().getText());
+            orTruePlace.getInitialMarking().setText(orTruePlaceMarking + 1);
+        } else {
+            iOsp.getInitialMarking().setText(1);
+            int orFalsePlaceMarking = Integer.valueOf(orFalsePlace.getInitialMarking().getText());
+            orFalsePlace.getInitialMarking().setText(orFalsePlaceMarking + 1);
+        }
+
+        createAndIncludeArc(topPage, TemplateConstants.ARC_T_ACTIVE_TO_TRUE + "-" + signalId + "-" + count, activeT, orTruePlace);
+        createAndIncludeArc(topPage, TemplateConstants.ARC_FALSE_TO_T_ACTIVE + "-" + signalId + "-" + count, orFalsePlace, activeT);
+        createAndIncludeArc(topPage, TemplateConstants.ARC_T_INACTIVE_TO_FALSE + "-" + signalId + "-" + count, inactiveT, orFalsePlace);
+        createAndIncludeArc(topPage, TemplateConstants.ARC_TRUE_TO_T_INACTIVE + "-" + signalId + "-" + count, orTruePlace, inactiveT);
+
+        if (!isBase) {
+            createAndIncludeArc(topPage, "arc-or-1-" + signalId + "-" + count, aOsp, inactiveT);
+            createAndIncludeArc(topPage, "arc-or-2-" + signalId + "-" + count, inactiveT, iOsp);
+            createAndIncludeArc(topPage, "arc-or-3-" + signalId + "-" + count, iOsp, activeT);
+            createAndIncludeArc(topPage, "arc-or-4-" + signalId + "-" + count, activeT, aOsp);
+        }
+    }
+
+    private static void attachANDSignalNetToBaseSignalNet(PetriNet petriNet, InputSignalTransition transition, InputSignalTransition inactiveT, InputSignalTransition activeT, int count, String signalId, boolean isActive) {
+
+        Page topPage = petriNet.getPage(0);
+
+        OutputSignalPlace aOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
+        OutputSignalPlace iOsp = getPlaceByID(petriNet, TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-base").asOutputSignalPlace().treeCopy();
+        aOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_ACTIVE + "-" + signalId + "-" + count);
+        iOsp.setId(TemplateConstants.INPUT_SIGNAL_PLACE_INACTIVE + "-" + signalId + "-" + count);
+
+        createAndIncludeArc(topPage, "arc-and-1-" + signalId + "-" + count, aOsp, inactiveT);
+        createAndIncludeArc(topPage, "arc-and-2-" + signalId + "-" + count, inactiveT, iOsp);
+        createAndIncludeArc(topPage, "arc-and-3-" + signalId + "-" + count, iOsp, activeT);
+        createAndIncludeArc(topPage, "arc-and-4-" + signalId + "-" + count, activeT, aOsp);
+
+        createAndIncludeArc(topPage, "IoTransitionToSignal-" + signalId + "-" + count, transition, aOsp);
+        createAndIncludeArc(topPage, "IoTransitionFromSignal-" + signalId + "-" + count, aOsp, transition);
+
+        topPage.addObject(aOsp);
+        topPage.addObject(iOsp);
+
+        // marking
+        if (isActive) {
+            aOsp.getInitialMarking().setText(1);
+        } else {
+            iOsp.getInitialMarking().setText(1);
+        }
+
+        petriNet.flushTreeCache();
+    }
 }