Improving viewer loading instances procedure to faster
authorlaurent
Fri, 24 Jul 2009 10:47:35 +0200
changeset 383 25ffba02b6a8
parent 382 42a9b03bba82
child 384 ed27a676d5c9
Improving viewer loading instances procedure to faster
LDViewer.py
PLCControler.py
SFCViewer.py
Viewer.py
graphics/FBD_Objects.py
graphics/LD_Objects.py
graphics/SFC_Objects.py
plcopen/plcopen.py
--- a/LDViewer.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/LDViewer.py	Fri Jul 24 10:47:35 2009 +0200
@@ -193,8 +193,8 @@
             else:
                 self.RungComments.insert(i, None)
     
-    def loadInstance(self, instance, ids):
-        Viewer.loadInstance(self, instance, ids)
+    def loadInstance(self, instance, ids, selection):
+        Viewer.loadInstance(self, instance, ids, selection)
         if self.GetDrawingMode() != FREEDRAWING_MODE:
             if instance["type"] == "leftPowerRail":
                 element = self.FindElementById(instance["id"])
--- a/PLCControler.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/PLCControler.py	Fri Jul 24 10:47:35 2009 +0200
@@ -1592,282 +1592,10 @@
             else:
                 instance = element.getrandomInstance(exclude)
         if instance is not None:
-            if id is not None:
-                infos["id"] = id
-            else:
-                infos["id"] = instance.getlocalId() 
-            infos["x"] = instance.getx()
-            infos["y"] = instance.gety()
-            infos["height"] = instance.getheight()
-            infos["width"] = instance.getwidth()
-            if isinstance(instance, plcopen.fbdObjects_block):
-                infos["name"] = instance.getinstanceName()
-                infos["type"] = instance.gettypeName()
-                executionOrder = instance.getexecutionOrderId()
-                if executionOrder is not None:
-                    infos["executionOrder"] = executionOrder
-                else:
-                    infos["executionOrder"] = 0
-                infos["connectors"] = {"inputs":[],"outputs":[]}
-                for variable in instance.inputVariables.getvariable():
-                    connector = {}
-                    connector["name"] = variable.getformalParameter()
-                    connector["position"] = variable.connectionPointIn.getrelPositionXY()
-                    connector["negated"] = variable.getnegated()
-                    connector["edge"] = variable.getedge()
-                    connector["links"] = []
-                    connections = variable.connectionPointIn.getconnections()
-                    if connections:
-                        for link in connections:
-                            dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                            connector["links"].append(dic)
-                    infos["connectors"]["inputs"].append(connector)
-                for variable in instance.outputVariables.getvariable():
-                    connector = {}
-                    connector["name"] = variable.getformalParameter()
-                    connector["position"] = variable.connectionPointOut.getrelPositionXY()
-                    connector["negated"] = variable.getnegated()
-                    connector["edge"] = variable.getedge()
-                    infos["connectors"]["outputs"].append(connector)
-            elif isinstance(instance, plcopen.fbdObjects_inVariable):
-                infos["name"] = instance.getexpression()
-                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
-                infos["type"] = "input"
-                executionOrder = instance.getexecutionOrderId()
-                if executionOrder is not None:
-                    infos["executionOrder"] = executionOrder
-                else:
-                    infos["executionOrder"] = 0
-                infos["connector"] = {}
-                infos["connector"]["position"] = instance.connectionPointOut.getrelPositionXY()
-                infos["connector"]["negated"] = instance.getnegated()
-                infos["connector"]["edge"] = instance.getedge()
-            elif isinstance(instance, plcopen.fbdObjects_outVariable):
-                infos["name"] = instance.getexpression()
-                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
-                infos["type"] = "output"
-                executionOrder = instance.getexecutionOrderId()
-                if executionOrder is not None:
-                    infos["executionOrder"] = executionOrder
-                else:
-                    infos["executionOrder"] = 0
-                infos["connector"] = {}
-                infos["connector"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connector"]["negated"] = instance.getnegated()
-                infos["connector"]["edge"] = instance.getedge()
-                infos["connector"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connector"]["links"].append(dic)
-            elif isinstance(instance, plcopen.fbdObjects_inOutVariable):
-                infos["name"] = instance.getexpression()
-                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
-                infos["type"] = "inout"
-                executionOrder = instance.getexecutionOrderId()
-                if executionOrder is not None:
-                    infos["executionOrder"] = executionOrder
-                else:
-                    infos["executionOrder"] = 0
-                infos["connectors"] = {"input":{},"output":{}}
-                infos["connectors"]["output"]["position"] = instance.connectionPointOut.getrelPositionXY()
-                infos["connectors"]["output"]["negated"] = instance.getnegatedOut()
-                infos["connectors"]["output"]["edge"] = instance.getedgeOut()
-                infos["connectors"]["input"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connectors"]["input"]["negated"] = instance.getnegatedIn()
-                infos["connectors"]["input"]["edge"] = instance.getedgeIn()
-                infos["connectors"]["input"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connectors"]["input"]["links"].append(dic)
-            elif isinstance(instance, plcopen.commonObjects_continuation):
-                infos["name"] = instance.getname()
-                infos["type"] = "continuation"
-                infos["connector"] = {}
-                infos["connector"]["position"] = instance.connectionPointOut.getrelPositionXY()
-            elif isinstance(instance, plcopen.commonObjects_connector):
-                infos["name"] = instance.getname()
-                infos["type"] = "connection"
-                infos["connector"] = {}
-                infos["connector"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connector"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connector"]["links"].append(dic)
-            elif isinstance(instance, plcopen.commonObjects_comment):
-                infos["type"] = "comment"
-                infos["content"] = instance.getcontentText()
-            elif isinstance(instance, plcopen.ldObjects_leftPowerRail):
-                infos["type"] = "leftPowerRail"
-                infos["connectors"] = []
-                for connection in instance.getconnectionPointOut():
-                    connector = {}
-                    connector["position"] = connection.getrelPositionXY()
-                    infos["connectors"].append(connector)
-            elif isinstance(instance, plcopen.ldObjects_rightPowerRail):
-                infos["type"] = "rightPowerRail"
-                infos["connectors"] = []
-                for connection in instance.getconnectionPointIn():
-                    connector = {}
-                    connector["position"] = connection.getrelPositionXY()
-                    connector["links"] = []
-                    connections = connection.getconnections()
-                    if connections:
-                        for link in connection.getconnections():
-                            dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                            connector["links"].append(dic)
-                    infos["connectors"].append(connector)
-            elif isinstance(instance, plcopen.ldObjects_contact):
-                infos["name"] = instance.getvariable()
-                infos["type"] = "contact"
-                executionOrder = instance.getexecutionOrderId()
-                if executionOrder is not None:
-                    infos["executionOrder"] = executionOrder
-                else:
-                    infos["executionOrder"] = 0
-                infos["negated"] = instance.getnegated()
-                infos["edge"] = instance.getedge()
-                infos["connectors"] = {"input":{},"output":{}}
-                infos["connectors"]["input"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connectors"]["input"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connectors"]["input"]["links"].append(dic)
-                infos["connectors"]["output"]["position"] = instance.connectionPointOut.getrelPositionXY()
-            elif isinstance(instance, plcopen.ldObjects_coil):
-                infos["name"] = instance.getvariable()
-                infos["type"] = "coil"
-                executionOrder = instance.getexecutionOrderId()
-                if executionOrder is not None:
-                    infos["executionOrder"] = executionOrder
-                else:
-                    infos["executionOrder"] = 0
-                infos["negated"] = instance.getnegated()
-                infos["edge"] = instance.getedge()
-                infos["storage"] = instance.getstorage()
-                infos["connectors"] = {"input":{},"output":{}}
-                infos["connectors"]["input"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connectors"]["input"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connectors"]["input"]["links"].append(dic)
-                infos["connectors"]["output"]["position"] = instance.connectionPointOut.getrelPositionXY()
-            elif isinstance(instance, plcopen.sfcObjects_step):
-                infos["name"] = instance.getname()
-                infos["type"] = "step"
-                infos["initial"] = instance.getinitialStep()
-                infos["connectors"] = {}
-                if instance.connectionPointIn:
-                    infos["connectors"]["input"] = {}
-                    infos["connectors"]["input"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                    infos["connectors"]["input"]["links"] = []
-                    connections = instance.connectionPointIn.getconnections()
-                    if connections:
-                        for link in connections:
-                            dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                            infos["connectors"]["input"]["links"].append(dic)
-                if instance.connectionPointOut:
-                    infos["connectors"]["output"] = {"position" : instance.connectionPointOut.getrelPositionXY()}
-                if instance.connectionPointOutAction:
-                    infos["connectors"]["action"] = {"position" : instance.connectionPointOutAction.getrelPositionXY()}
-            elif isinstance(instance, plcopen.sfcObjects_transition):
-                infos["type"] = "transition"
-                condition = instance.getconditionContent()
-                priority = instance.getpriority()
-                if priority == None:
-                    infos["priority"] = 0
-                else:
-                    infos["priority"] = priority
-                infos["condition_type"] = condition["type"]
-                infos["connectors"] = {"input":{},"output":{}}
-                infos["connectors"]["input"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connectors"]["input"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connectors"]["input"]["links"].append(dic)
-                infos["connectors"]["output"]["position"] = instance.connectionPointOut.getrelPositionXY()
-                if infos["condition_type"] == "connection":
-                    infos["connectors"]["connection"] = {}
-                    infos["connectors"]["connection"]["links"] = []
-                    connections = instance.getconnections()
-                    if connections:
-                        for link in connections:
-                            dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                            infos["connectors"]["connection"]["links"].append(dic)
-                    infos["condition"] = None
-                else:
-                    infos["condition"] = condition["value"]
-            elif isinstance(instance, (plcopen.sfcObjects_selectionDivergence, plcopen.sfcObjects_simultaneousDivergence)):
-                if isinstance(instance, plcopen.sfcObjects_selectionDivergence):
-                    infos["type"] = "selectionDivergence"
-                else:
-                    infos["type"] = "simultaneousDivergence"
-                infos["connectors"] = {"inputs":[],"outputs":[]}
-                connector = {}
-                connector["position"] = instance.connectionPointIn.getrelPositionXY()
-                connector["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        connector["links"].append(dic)
-                infos["connectors"]["inputs"].append(connector)
-                for sequence in instance.getconnectionPointOut():
-                    connector = {}
-                    connector["position"] = sequence.getrelPositionXY()
-                    infos["connectors"]["outputs"].append(connector)
-            elif isinstance(instance, (plcopen.sfcObjects_selectionConvergence, plcopen.sfcObjects_simultaneousConvergence)):
-                if isinstance(instance, plcopen.sfcObjects_selectionConvergence):
-                    infos["type"] = "selectionConvergence"
-                else:
-                    infos["type"] = "simultaneousConvergence"
-                infos["connectors"] = {"inputs":[],"outputs":[]}
-                for sequence in instance.getconnectionPointIn():
-                    connector = {}
-                    connector["position"] = sequence.getrelPositionXY()
-                    connector["links"] = []
-                    connections = sequence.getconnections()
-                    if connections:
-                        for link in connections:
-                            dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                            connector["links"].append(dic)
-                    infos["connectors"]["inputs"].append(connector)
-                connector = {}
-                connector["position"] = instance.connectionPointOut.getrelPositionXY()
-                infos["connectors"]["outputs"].append(connector)
-            elif isinstance(instance, plcopen.sfcObjects_jumpStep):
-                infos["type"] = "jump"
-                infos["target"] = instance.gettargetName()
-                infos["connector"] = {}
-                infos["connector"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connector"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connector"]["links"].append(dic)
-            elif isinstance(instance, plcopen.commonObjects_actionBlock):
-                infos["type"] = "actionBlock"
-                infos["actions"] = instance.getactions()
-                infos["connector"] = {}
-                infos["connector"]["position"] = instance.connectionPointIn.getrelPositionXY()
-                infos["connector"]["links"] = []
-                connections = instance.connectionPointIn.getconnections()
-                if connections:
-                    for link in connections:
-                        dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
-                        infos["connector"]["links"].append(dic)
+            infos = instance.getinfos()
+            if infos["type"] in ["input", "output", "inout"]:
+                var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug)
+                infos["specific_values"]["value_type"] = var_type
             return infos
         return None
     
@@ -2067,39 +1795,29 @@
                 elif param == "y":
                     variable.sety(value)
                 elif param == "connectors":
-                    if isinstance(variable, plcopen.fbdObjects_inVariable):
-                        if value["output"].IsNegated():
-                            variable.setnegated(True)
-                        if value["output"].GetEdge() != "none":
-                            variable.setedge(value["output"].GetEdge())
-                        position = value["output"].GetRelPosition()
+                    if len(value["outputs"]) > 0:
+                        output = value["outputs"][0]
+                        if len(value["inputs"]) > 0:
+                            variable.setnegatedOut(output.IsNegated())
+                            variable.setedgeOut(output.GetEdge())
+                        else:
+                            variable.setnegated(output.IsNegated())
+                            variable.setedge(output.GetEdge())
+                        position = output.GetRelPosition()
                         variable.addconnectionPointOut()
                         variable.connectionPointOut.setrelPositionXY(position.x, position.y)
-                    elif isinstance(variable, plcopen.fbdObjects_outVariable):
-                        if value["input"].IsNegated():
-                            variable.setnegated(True)
-                        if value["input"].GetEdge() != "none":
-                            variable.setedge(value["input"].GetEdge())
-                        position = value["input"].GetRelPosition()
+                    if len(value["inputs"]) > 0:
+                        input = value["inputs"][0]
+                        if len(value["outputs"]) > 0:
+                            variable.setnegatedIn(input.IsNegated())
+                            variable.setedgeIn(input.GetEdge())
+                        else:
+                            variable.setnegated(input.IsNegated())
+                            variable.setedge(input.GetEdge())
+                        position = input.GetRelPosition()
                         variable.addconnectionPointIn()
                         variable.connectionPointIn.setrelPositionXY(position.x, position.y)
-                        self.SetConnectionWires(variable.connectionPointIn, value["input"])
-                    elif isinstance(variable, plcopen.fbdObjects_inOutVariable):
-                        if value["input"].IsNegated():
-                            variable.setnegatedIn(True)
-                        if value["input"].GetEdge() != "none":
-                            variable.setedgeIn(value["input"].GetEdge())
-                        if value["output"].IsNegated():
-                            variable.setnegatedOut(True)
-                        if value["output"].GetEdge() != "none":
-                            variable.setedgeOut(value["output"].GetEdge())
-                        position = value["output"].GetRelPosition()
-                        variable.addconnectionPointOut()
-                        variable.connectionPointOut.setrelPositionXY(position.x, position.y)
-                        position = value["input"].GetRelPosition()
-                        variable.addconnectionPointIn()
-                        variable.connectionPointIn.setrelPositionXY(position.x, position.y)
-                        self.SetConnectionWires(variable.connectionPointIn, value["input"])
+                        self.SetConnectionWires(variable.connectionPointIn, input)
 
     def AddEditedElementConnection(self, tagname, id, type):
         element = self.GetEditedElement(tagname)
@@ -2193,14 +1911,14 @@
                 elif param == "connectors":
                     if isinstance(powerrail, plcopen.ldObjects_leftPowerRail):
                         powerrail.setconnectionPointOut([])
-                        for connector in value:
+                        for connector in value["outputs"]:
                             position = connector.GetRelPosition()
                             connection = plcopen.leftPowerRail_connectionPointOut()
                             connection.setrelPositionXY(position.x, position.y)
                             powerrail.connectionPointOut.append(connection)
                     elif isinstance(powerrail, plcopen.ldObjects_rightPowerRail):
                         powerrail.setconnectionPointIn([])
-                        for connector in value:
+                        for connector in value["inputs"]:
                             position = connector.GetRelPosition()
                             connection = plcopen.connectionPointIn()
                             connection.setrelPositionXY(position.x, position.y)
@@ -2245,12 +1963,12 @@
                 elif param == "y":
                     contact.sety(value)
                 elif param == "connectors":
-                    input_connector = value["input"]
+                    input_connector = value["inputs"][0]
                     position = input_connector.GetRelPosition()
                     contact.addconnectionPointIn()
                     contact.connectionPointIn.setrelPositionXY(position.x, position.y)
                     self.SetConnectionWires(contact.connectionPointIn, input_connector)
-                    output_connector = value["output"]
+                    output_connector = value["outputs"][0]
                     position = output_connector.GetRelPosition()
                     contact.addconnectionPointOut()
                     contact.connectionPointOut.setrelPositionXY(position.x, position.y)
@@ -2305,12 +2023,12 @@
                 elif param == "y":
                     coil.sety(value)
                 elif param == "connectors":
-                    input_connector = value["input"]
+                    input_connector = value["inputs"][0]
                     position = input_connector.GetRelPosition()
                     coil.addconnectionPointIn()
                     coil.connectionPointIn.setrelPositionXY(position.x, position.y)
                     self.SetConnectionWires(coil.connectionPointIn, input_connector)
-                    output_connector = value["output"]
+                    output_connector = value["outputs"][0]
                     position = output_connector.GetRelPosition()
                     coil.addconnectionPointOut()
                     coil.connectionPointOut.setrelPositionXY(position.x, position.y)
@@ -2342,24 +2060,24 @@
                 elif param == "y":
                     step.sety(value)
                 elif param == "connectors":
-                    input_connector = value["input"]
-                    if input_connector:
+                    if len(value["inputs"]) > 0:
+                        input_connector = value["inputs"][0]
                         position = input_connector.GetRelPosition()
                         step.addconnectionPointIn()
                         step.connectionPointIn.setrelPositionXY(position.x, position.y)
                         self.SetConnectionWires(step.connectionPointIn, input_connector)
                     else:
                         step.deleteconnectionPointIn()
-                    output_connector = value["output"]
-                    if output_connector:
+                    if len(value["outputs"]) > 0:
+                        output_connector = value["outputs"][0]
                         position = output_connector.GetRelPosition()
                         step.addconnectionPointOut()
                         step.connectionPointOut.setrelPositionXY(position.x, position.y)
                     else:
                         step.deleteconnectionPointOut()
-                    action_connector = value["action"]
-                    if action_connector:
-                        position = action_connector.GetRelPosition()
+                elif param == "action":
+                    if value:
+                        position = value.GetRelPosition()
                         step.addconnectionPointOutAction()
                         step.connectionPointOutAction.setrelPositionXY(position.x, position.y)
                     else:
@@ -2395,19 +2113,18 @@
                     else:
                         transition.setpriority(None)
                 elif param == "connectors":
-                    input_connector = value["input"]
+                    input_connector = value["inputs"][0]
                     position = input_connector.GetRelPosition()
                     transition.addconnectionPointIn()
                     transition.connectionPointIn.setrelPositionXY(position.x, position.y)
                     self.SetConnectionWires(transition.connectionPointIn, input_connector)
-                    output_connector = value["output"]
+                    output_connector = value["outputs"][0]
                     position = output_connector.GetRelPosition()
                     transition.addconnectionPointOut()
                     transition.connectionPointOut.setrelPositionXY(position.x, position.y)
-                    if infos.get("type", None) == "connection":
-                        transition.setconditionContent("connection", None)
-                        connection_connector = value["connection"]
-                        self.SetConnectionWires(transition, connection_connector)
+                elif infos.get("type", None) == "connection" and param == "connection" and value:
+                    transition.setconditionContent("connection", None)
+                    self.SetConnectionWires(transition, value)
     
     def AddEditedElementDivergence(self, tagname, id, type):
         element = self.GetEditedElement(tagname)
--- a/SFCViewer.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/SFCViewer.py	Fri Jul 24 10:47:35 2009 +0200
@@ -148,7 +148,7 @@
             self.RemoveWire(output_wire)
         else:
             next = None
-        action = step.GetActionConnector()
+        action = step.GetActionConnected()
         if action:
             self.DeleteActionBlock(action.GetParentBlock())
         step.Clean()
--- a/Viewer.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/Viewer.py	Fri Jul 24 10:47:35 2009 +0200
@@ -76,6 +76,102 @@
 
 ZOOM_FACTORS = [math.sqrt(2) ** x for x in xrange(-6, 7)]
 
+
+def GetVariableCreationFunction(variable_type):
+    def variableCreationFunction(viewer, id, specific_values):
+        return FBD_Variable(viewer, variable_type, 
+                                    specific_values["name"], 
+                                    specific_values["value_type"], 
+                                    id,
+                                    specific_values["executionOrder"])
+    return variableCreationFunction
+
+def GetConnectorCreationFunction(connector_type):
+    def connectorCreationFunction(viewer, id, specific_values):
+        return FBD_Connector(viewer, connector_type, 
+                                     specific_values["name"], id)
+    return connectorCreationFunction
+
+def commentCreationFunction(viewer, id, specific_values):
+    return Comment(viewer, specific_values["content"], id)
+
+def GetPowerRailCreationFunction(powerrail_type):
+    def powerRailCreationFunction(viewer, id, specific_values):
+        return LD_PowerRail(viewer, powerrail_type, id, 
+                                    specific_values["connectors"])
+    return powerRailCreationFunction
+
+CONTACT_TYPES = {(True, "none"): CONTACT_REVERSE,
+                 (False, "rising"): CONTACT_RISING,
+                 (False, "falling"): CONTACT_FALLING}
+
+def contactCreationFunction(viewer, id, specific_values):
+    contact_type = CONTACT_TYPES.get((specific_values.get("negated", False), 
+                                      specific_values.get("edge", "none")),
+                                     CONTACT_NORMAL)
+    return LD_Contact(viewer, contact_type, specific_values["name"], id)
+
+COIL_TYPES = {(True, "none", "none"): COIL_REVERSE,
+              (False, "none", "set"): COIL_SET,
+              (False, "none", "reset"): COIL_RESET,
+              (False, "rising", "none"): COIL_RISING,
+              (False, "falling", "none"): COIL_FALLING}
+
+def coilCreationFunction(viewer, id, specific_values):
+    coil_type = COIL_TYPES.get((specific_values.get("negated", False), 
+                                specific_values.get("edge", "none"),
+                                specific_values.get("storage", "none")),
+                               COIL_NORMAL)
+    return LD_Coil(viewer, coil_type, specific_values["name"], id)
+
+def stepCreationFunction(viewer, id, specific_values):
+    step = SFC_Step(viewer, specific_values["name"], 
+                            specific_values.get("initial", False), id)
+    if specific_values.get("action", None):
+        step.AddAction()
+        connector = step.GetActionConnector()
+        connector.SetPosition(wx.Point(*specific_values["action"]["position"]))
+    return step
+
+def transitionCreationFunction(viewer, id, specific_values):
+    transition = SFC_Transition(viewer, specific_values["condition_type"], 
+                                        specific_values.get("condition", None), 
+                                        specific_values["priority"], id)
+    return transition
+
+def GetDivergenceCreationFunction(divergence_type):
+    def divergenceCreationFunction(viewer, id, specific_values):
+        return SFC_Divergence(viewer, divergence_type, 
+                                      specific_values["connectors"], id)
+    return divergenceCreationFunction
+
+def jumpCreationFunction(viewer, id, specific_values):
+    return SFC_Jump(viewer, specific_values["target"], id)
+
+def actionBlockCreationFunction(viewer, id, specific_values):
+    return SFC_ActionBlock(viewer, specific_values["actions"], id)
+
+ElementCreationFunctions = {
+    "input": GetVariableCreationFunction(INPUT),
+    "output": GetVariableCreationFunction(OUTPUT),
+    "inout": GetVariableCreationFunction(INOUT),
+    "connector": GetConnectorCreationFunction(CONNECTOR),
+    "continuation": GetConnectorCreationFunction(CONTINUATION),
+    "comment": commentCreationFunction,
+    "leftPowerRail": GetPowerRailCreationFunction(LEFTRAIL),
+    "rightPowerRail": GetPowerRailCreationFunction(RIGHTRAIL),
+    "contact": contactCreationFunction,
+    "coil": coilCreationFunction,
+    "step": stepCreationFunction, 
+    "transition": transitionCreationFunction,
+    "selectionDivergence": GetDivergenceCreationFunction(SELECTION_DIVERGENCE), 
+    "selectionConvergence": GetDivergenceCreationFunction(SELECTION_CONVERGENCE), 
+    "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE), 
+    "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE), 
+    "jump": jumpCreationFunction,
+    "actionBlock": actionBlockCreationFunction,
+}
+
 #-------------------------------------------------------------------------------
 #                       Graphic elements Viewer base class
 #-------------------------------------------------------------------------------
@@ -381,7 +477,7 @@
         self.CurrentCursor = 0
         
         # Initialize Block, Wire and Comment numbers
-        self.block_id = self.wire_id = self.comment_id = 0
+        self.wire_id = 0
         
         # Initialize Viewer mode to Selection mode
         self.Mode = MODE_SELECTION
@@ -505,45 +601,43 @@
 #-------------------------------------------------------------------------------
 
     def AddBlock(self, block):
-        self.block_id += 1
-        self.Blocks[block] = self.block_id
+        self.Blocks[block.GetId()] = block
         
     def AddWire(self, wire):
         self.wire_id += 1
         self.Wires[wire] = self.wire_id
         
     def AddComment(self, comment):
-        self.comment_id += 1
-        self.Comments[comment] = self.comment_id
+        self.Comments[comment.GetId()] = comment
 
     def IsBlock(self, block):
-        return self.Blocks.get(block, False)
+        return self.Blocks.get(block.GetId(), False)
         
     def IsWire(self, wire):
         return self.Wires.get(wire, False)
         
     def IsComment(self, comment):
-        return self.Comments.get(comment, False)
+        return self.Comments.get(comment.GetId(), False)
 
     def RemoveBlock(self, block):
-        self.Blocks.pop(block)
+        self.Blocks.pop(block.GetId())
         
     def RemoveWire(self, wire):
         self.Wires.pop(wire)
         
     def RemoveComment(self, comment):
-        self.Comments.pop(comment)
+        self.Comments.pop(comment.GetId())
 
     def GetElements(self, sort_blocks=False, sort_wires=False, sort_comments=False):
-        blocks = self.Blocks.keys()
+        blocks = self.Blocks.values()
         wires = self.Wires.keys()
-        comments = self.Comments.keys()
+        comments = self.Comments.values()
         if sort_blocks:
-            blocks.sort(lambda x, y: cmp(self.Blocks[x], self.Blocks[y]))
+            blocks.sort(lambda x, y: cmp(x.GetId(), y.GetId()))
         if sort_wires:
             wires.sort(lambda x, y: cmp(self.Wires[x], self.Wires[y]))
         if sort_comments:
-            comments.sort(lambda x, y: cmp(self.Comments[x], self.Comments[y]))
+            comments.sort(lambda x, y: cmp(x.GetId(), y.GetId()))
         return blocks + wires + comments
 
     def RefreshVisibleElements(self, xp = None, yp = None):
@@ -555,11 +649,11 @@
         width, height = self.GetClientSize()
         screen = wx.Rect(int(x / self.ViewScale[0]), int(y / self.ViewScale[1]),
                          int(width / self.ViewScale[0]), int(height / self.ViewScale[1]))
-        for comment in self.Comments:
+        for comment in self.Comments.itervalues():
             comment.TestVisible(screen)
-        for wire in self.Wires:
+        for wire in self.Wires.iterkeys():
             wire.TestVisible(screen)
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             block.TestVisible(screen)
     
     def GetElementIECPath(self, element):
@@ -604,12 +698,12 @@
     
     def Flush(self):
         self.DeleteDataConsumers()
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             block.Flush()
     
     # Remove all elements
     def CleanView(self):
-        for block in self.Blocks.keys():
+        for block in self.Blocks.itervalues():
             block.Clean()
         self.ResetView()
     
@@ -689,7 +783,7 @@
         pass
 
     # Refresh Viewer elements
-    def RefreshView(self):
+    def RefreshView(self, selection=None):
         self.Inhibit(True)
         self.current_id = 0
         # Start by reseting Viewer
@@ -702,37 +796,19 @@
         while instance is not None:
             instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, exclude = ids, debug = self.Debug)
             if instance is not None:
-                self.loadInstance(instance, ids)
+                self.loadInstance(instance, ids, selection)
         self.RefreshScrollBars()
         
         for wire in self.Wires:
             if not wire.IsConnectedCompatible():
                 wire.SetValid(False)
             if self.Debug:
-                block = wire.EndConnected.GetParentBlock()
-                if isinstance(block, LD_PowerRail):
-                    wire.SetValue(True)
-                if isinstance(block, FBD_Block):
-                    blockname = block.GetName()
-                    connectorname = wire.EndConnected.GetName()
-                    if blockname != "":
-                        iec_path = "%s.%s.%s"%(self.InstancePath, blockname, connectorname)
-                    else:
-                        if connectorname == "":
-                            iec_path = "%s.%s%d"%(self.InstancePath, block.GetType(), block.GetId())
-                        else:
-                            iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname)
-                    if self.AddDataConsumer(iec_path.upper(), wire) is None:
-                        wire.SetValue("undefined")
-                elif isinstance(block, FBD_Variable):
-                    iec_path = "%s.%s"%(self.InstancePath, block.GetName())
-                    if self.AddDataConsumer(iec_path.upper(), wire) is None:
-                        wire.SetValue("undefined")
-                elif isinstance(block, FBD_Connector):
+                iec_path = self.GetElementIECPath(wire)
+                if self.AddDataConsumer(iec_path.upper(), wire) is None:
                     wire.SetValue("undefined")
 
         if self.Debug:
-            for block in self.Blocks.keys():
+            for block in self.Blocks.itervalues():
                 block.SpreadCurrent()
                 iec_path = self.GetElementIECPath(block)
                 if iec_path is not None:
@@ -792,229 +868,46 @@
         self.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
             round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, 
             xstart, ystart, True)
+    
+    def SelectInGroup(self, element):
+        element.SetSelected(True)
+        if self.SelectedElement is None:
+            self.SelectedElement = element
+        elif isinstance(self.SelectedElement, Graphic_Group):
+            self.SelectedElement.SelectElement(element)
+        else:
+            group = Graphic_Group(self)
+            group.SelectElement(self.SelectedElement)
+            group.SelectElement(element)
+            self.SelectedElement = group
         
     # Load instance from given informations
-    def loadInstance(self, instance, ids):
+    def loadInstance(self, instance, ids, selection):
         ids.append(instance["id"])
-        self.current_id = max(self.current_id, instance["id"]) 
-        if instance["type"] == "input":
-            variable = FBD_Variable(self, INPUT, instance["name"], instance["value_type"], instance["id"], instance["executionOrder"])
-            variable.SetPosition(instance["x"], instance["y"])
-            variable.SetSize(instance["width"], instance["height"])
-            self.AddBlock(variable)
-            connectors = variable.GetConnectors()
-            connectors["output"].SetPosition(wx.Point(*instance["connector"]["position"]))
-            if instance["connector"]["negated"]:
-                connectors["output"].SetNegated(True)
-            if instance["connector"]["edge"]:
-                connectors["output"].SetEdge(instance["connector"]["edge"])
-        elif instance["type"] == "output":
-            variable = FBD_Variable(self, OUTPUT, instance["name"], instance["value_type"], instance["id"], instance["executionOrder"])
-            variable.SetPosition(instance["x"], instance["y"])
-            variable.SetSize(instance["width"], instance["height"])
-            self.AddBlock(variable)
-            connectors = variable.GetConnectors()
-            connectors["input"].SetPosition(wx.Point(*instance["connector"]["position"]))
-            if instance["connector"]["negated"]:
-                connectors["input"].SetNegated(True)
-            if instance["connector"]["edge"]:
-                connectors["input"].SetEdge(instance["connector"]["edge"])
-            self.CreateWires(connectors["input"], instance["connector"]["links"], ids)
-        elif instance["type"] == "inout":
-            variable = FBD_Variable(self, INOUT, instance["name"], instance["value_type"], instance["id"], instance["executionOrder"])
-            variable.SetPosition(instance["x"], instance["y"])
-            variable.SetSize(instance["width"], instance["height"])
-            self.AddBlock(variable)
-            connectors = variable.GetConnectors()
-            connectors["output"].SetPosition(wx.Point(*instance["connectors"]["output"]["position"]))
-            connectors["input"].SetPosition(wx.Point(*instance["connectors"]["input"]["position"]))
-            if instance["connectors"]["output"]["negated"]:
-                connectors["output"].SetNegated(True)
-            if instance["connectors"]["output"]["edge"]:
-                connectors["output"].SetEdge(instance["connectors"]["output"]["edge"])
-            if instance["connectors"]["input"]["negated"]:
-                connectors["input"].SetNegated(True)
-            if instance["connectors"]["input"]["edge"]:
-                connectors["input"].SetEdge(instance["connectors"]["input"]["edge"])
-            self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids)
-        elif instance["type"] == "continuation":
-            connection = FBD_Connector(self, CONTINUATION, instance["name"], instance["id"])
-            connection.SetPosition(instance["x"], instance["y"])
-            connection.SetSize(instance["width"], instance["height"])
-            self.AddBlock(connection)
-            connector = connection.GetConnector()
-            connector.SetPosition(wx.Point(*instance["connector"]["position"]))
-        elif instance["type"] == "connection":
-            connection = FBD_Connector(self, CONNECTOR, instance["name"], instance["id"])
-            connection.SetPosition(instance["x"], instance["y"])
-            connection.SetSize(instance["width"], instance["height"])
-            self.AddBlock(connection)
-            connector = connection.GetConnector()
-            connector.SetPosition(wx.Point(*instance["connector"]["position"]))
-            self.CreateWires(connector, instance["connector"]["links"], ids)
-        elif instance["type"] == "comment":
-            comment = Comment(self, instance["content"], instance["id"])
-            comment.SetPosition(instance["x"], instance["y"])
-            comment.SetSize(instance["width"], instance["height"])
-            self.AddComment(comment)
-        elif instance["type"] == "leftPowerRail":
-            leftpowerrail = LD_PowerRail(self, LEFTRAIL, instance["id"], [True for i in range(len(instance["connectors"]))])
-            leftpowerrail.SetPosition(instance["x"], instance["y"])
-            leftpowerrail.SetSize(instance["width"], instance["height"])
-            self.AddBlock(leftpowerrail)
-            connectors = leftpowerrail.GetConnectors()
-            for i, connector in enumerate(instance["connectors"]):
-                connectors[i].SetPosition(wx.Point(*connector["position"]))
-        elif instance["type"] == "rightPowerRail":
-            rightpowerrail = LD_PowerRail(self, RIGHTRAIL, instance["id"], [True for i in range(len(instance["connectors"]))])
-            rightpowerrail.SetPosition(instance["x"], instance["y"])
-            rightpowerrail.SetSize(instance["width"], instance["height"])
-            self.AddBlock(rightpowerrail)
-            connectors = rightpowerrail.GetConnectors()
-            for i, connector in enumerate(instance["connectors"]):
-                connectors[i].SetPosition(wx.Point(*connector["position"]))
-                self.CreateWires(connectors[i], connector["links"], ids)
-        elif instance["type"] == "contact":
-            if instance["negated"]:
-                negated = instance["negated"]
-            else:
-                negated = False
-            if instance["edge"]:
-                edge = instance["edge"]
-            else:
-                edge = "none"
-            if negated and edge == "none":
-                contact_type = CONTACT_REVERSE
-            elif not negated and edge == "rising":
-                contact_type = CONTACT_RISING
-            elif not negated and edge == "falling":
-                contact_type = CONTACT_FALLING
-            else:
-                contact_type = CONTACT_NORMAL
-            contact = LD_Contact(self, contact_type, instance["name"], instance["id"])
-            contact.SetPosition(instance["x"], instance["y"])
-            contact.SetSize(instance["width"], instance["height"])
-            self.AddBlock(contact)
-            connectors = contact.GetConnectors()
-            connectors["input"].SetPosition(wx.Point(*instance["connectors"]["input"]["position"]))
-            self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids)
-            connectors["output"].SetPosition(wx.Point(*instance["connectors"]["output"]["position"]))
-        elif instance["type"] == "coil":
-            if instance["negated"]:
-                negated = instance["negated"]
-            else:
-                negated = False
-            if instance["storage"]:
-                storage = instance["storage"]
-            else:
-                storage = "none"
-            if instance["edge"]:
-                edge = instance["edge"]
-            else:
-                edge = "none"
-            if negated and storage == "none" and edge == "none":
-                coil_type = COIL_REVERSE
-            elif not negated and edge == "none" and storage == "set":
-                coil_type = COIL_SET
-            elif not negated and edge == "none" and storage == "reset":
-                coil_type = COIL_RESET
-            elif not negated and storage == "none" and edge == "rising":
-                coil_type = COIL_RISING
-            elif not negated and storage == "none" and edge == "falling":
-                coil_type = COIL_FALLING
-            else:
-                coil_type = COIL_NORMAL
-            coil = LD_Coil(self, coil_type, instance["name"], instance["id"])
-            coil.SetPosition(instance["x"], instance["y"])
-            coil.SetSize(instance["width"], instance["height"])
-            self.AddBlock(coil)
-            connectors = coil.GetConnectors()
-            connectors["input"].SetPosition(wx.Point(*instance["connectors"]["input"]["position"]))
-            self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids)
-            connectors["output"].SetPosition(wx.Point(*instance["connectors"]["output"]["position"]))
-        elif instance["type"] == "step":
-            if instance["initial"]:
-                initial = instance["initial"]
-            else:
-                initial = False
-            step = SFC_Step(self, instance["name"], initial, instance["id"])
-            step.SetPosition(instance["x"], instance["y"])
-            step.SetSize(instance["width"], instance["height"])
-            self.AddBlock(step)
-            if "output" in instance["connectors"]:
-                step.AddOutput()
-            if "action" in instance["connectors"]:
-                step.AddAction()
-            connectors = step.GetConnectors()
-            if connectors["input"]:
-                connectors["input"].SetPosition(wx.Point(*instance["connectors"]["input"]["position"]))
-                self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids)
-            if connectors["output"]:
-                connectors["output"].SetPosition(wx.Point(*instance["connectors"]["output"]["position"]))
-            if connectors["action"]:
-                connectors["action"].SetPosition(wx.Point(*instance["connectors"]["action"]["position"]))
-        elif instance["type"] == "transition":
-            transition = SFC_Transition(self, instance["condition_type"], instance["condition"], instance["priority"], instance["id"])
-            transition.SetPosition(instance["x"], instance["y"])
-            transition.SetSize(instance["width"], instance["height"])
-            self.AddBlock(transition)
-            connectors = transition.GetConnectors()
-            connectors["input"].SetPosition(wx.Point(*instance["connectors"]["input"]["position"]))
-            self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids)
-            connectors["output"].SetPosition(wx.Point(*instance["connectors"]["output"]["position"]))
-            if instance["condition_type"] == "connection":
-                self.CreateWires(connectors["connection"], instance["connectors"]["connection"]["links"], ids)
-        elif instance["type"] in ["selectionDivergence", "selectionConvergence", "simultaneousDivergence", "simultaneousConvergence"]:
-            if instance["type"] == "selectionDivergence":
-                divergence = SFC_Divergence(self, SELECTION_DIVERGENCE, 
-                    len(instance["connectors"]["outputs"]), instance["id"])
-            elif instance["type"] == "selectionConvergence":
-                divergence = SFC_Divergence(self, SELECTION_CONVERGENCE, 
-                    len(instance["connectors"]["inputs"]), instance["id"])
-            elif instance["type"] == "simultaneousDivergence":
-                divergence = SFC_Divergence(self, SIMULTANEOUS_DIVERGENCE, 
-                    len(instance["connectors"]["outputs"]), instance["id"])
-            else:
-                divergence = SFC_Divergence(self, SIMULTANEOUS_CONVERGENCE, 
-                    len(instance["connectors"]["inputs"]), instance["id"])
-            divergence.SetPosition(instance["x"], instance["y"])
-            divergence.SetSize(instance["width"], instance["height"])
-            self.AddBlock(divergence)
-            connectors = divergence.GetConnectors()
-            for i, input_connector in enumerate(instance["connectors"]["inputs"]):
-                connector = connectors["inputs"][i]
-                connector.SetPosition(wx.Point(*input_connector["position"]))
-                self.CreateWires(connector, input_connector["links"], ids)
-            for i, output_connector in enumerate(instance["connectors"]["outputs"]):
-                connector = connectors["outputs"][i]
-                connector.SetPosition(wx.Point(*output_connector["position"]))
-        elif instance["type"] == "jump":
-            jump = SFC_Jump(self, instance["target"], instance["id"])
-            jump.SetPosition(instance["x"], instance["y"])
-            jump.SetSize(instance["width"], instance["height"])
-            self.AddBlock(jump)
-            connector = jump.GetConnector()
-            connector.SetPosition(wx.Point(*instance["connector"]["position"]))
-            self.CreateWires(connector, instance["connector"]["links"], ids)
-        elif instance["type"] == "actionBlock":
-            actionBlock = SFC_ActionBlock(self, instance["actions"], instance["id"])
-            actionBlock.SetPosition(instance["x"], instance["y"])
-            actionBlock.SetSize(instance["width"], instance["height"])
-            self.AddBlock(actionBlock)
-            connector = actionBlock.GetConnector()
-            connector.SetPosition(wx.Point(*instance["connector"]["position"]))
-            self.CreateWires(connector, instance["connector"]["links"], ids)
+        self.current_id = max(self.current_id, instance["id"])
+        creation_function = ElementCreationFunctions.get(instance["type"], None)
+        connectors = {"inputs" : [], "outputs" : []}
+        specific_values = instance["specific_values"]
+        if creation_function is not None:
+            element = creation_function(self, instance["id"], specific_values)
+            if isinstance(element, SFC_Step):
+                if len(instance["inputs"]) > 0:
+                    element.AddInput()
+                if len(instance["outputs"]) > 0:
+                    element.AddOutput()
+            if isinstance(element, SFC_Transition) and specific_values["condition_type"] == "connection":
+                connector = element.GetConditionConnector()
+                self.CreateWires(connector, id, specific_values["connection"]["links"], ids, selection)
         else:
-            connectors = {"inputs" : [], "outputs" : []}
             executionControl = False
-            for input in instance["connectors"]["inputs"]:
+            for input in instance["inputs"]:
                 if input["negated"]:
                     connectors["inputs"].append((input["name"], None, "negated"))
                 elif input["edge"]:
                     connectors["inputs"].append((input["name"], None, input["edge"]))
                 else:
                     connectors["inputs"].append((input["name"], None, "none"))
-            for output in instance["connectors"]["outputs"]:
+            for output in instance["outputs"]:
                 if output["negated"]:
                     connectors["outputs"].append((output["name"], None, "negated"))
                 elif output["edge"]:
@@ -1022,47 +915,52 @@
                 else:
                     connectors["outputs"].append((output["name"], None, "none"))
             if len(connectors["inputs"]) > 0 and connectors["inputs"][0][0] == "EN":
-		connectors["inputs"].pop(0)
-	        executionControl = True
+                connectors["inputs"].pop(0)
+                executionControl = True
             if len(connectors["outputs"]) > 0 and connectors["outputs"][0][0] == "ENO":
                 connectors["outputs"].pop(0)
                 executionControl = True
-            if instance["name"] is None:
-                instance["name"] = ""
-            block = FBD_Block(self, instance["type"], instance["name"], 
-                    instance["id"], len(connectors["inputs"]), 
-                    connectors=connectors, executionControl=executionControl, 
-                    executionOrder=instance["executionOrder"])
-            block.SetPosition(instance["x"], instance["y"])
-            block.SetSize(instance["width"], instance["height"])
-            self.AddBlock(block)
-            connectors = block.GetConnectors()
-            for i, input_connector in enumerate(instance["connectors"]["inputs"]):
-                if i < len(connectors["inputs"]):
-                    connector = connectors["inputs"][i]
-                    connector.SetPosition(wx.Point(*input_connector["position"]))
-                    if input_connector["negated"]:
-                        connector.SetNegated(True)
-                    if input_connector["edge"] != "none":
-                        connector.SetEdge(input_connector["edge"])
-                    self.CreateWires(connector, input_connector["links"], ids)
-            for i, output_connector in enumerate(instance["connectors"]["outputs"]):
-                if i < len(connectors["outputs"]):
-                    connector = connectors["outputs"][i]
-                    if output_connector["negated"]:
-                        connector.SetNegated(True)
-                    if output_connector["edge"] != "none":
-                        connector.SetEdge(output_connector["edge"])
-                    connector.SetPosition(wx.Point(*output_connector["position"]))
-    
-    def CreateWires(self, start_connector, links, ids):
+            if specific_values["name"] is None:
+                specific_values["name"] = ""
+            element = FBD_Block(self, instance["type"], specific_values["name"], 
+                      instance["id"], len(connectors["inputs"]), 
+                      connectors=connectors, executionControl=executionControl, 
+                      executionOrder=specific_values["executionOrder"])
+        element.SetPosition(instance["x"], instance["y"])
+        element.SetSize(instance["width"], instance["height"])
+        if isinstance(element, Comment):
+            self.AddComment(element)
+        else:
+            self.AddBlock(element)
+            connectors = element.GetConnectors()
+        for i, input_connector in enumerate(instance["inputs"]):
+            if i < len(connectors["inputs"]):
+                connector = connectors["inputs"][i]
+                connector.SetPosition(wx.Point(*input_connector["position"]))
+                if input_connector.get("negated", False):
+                    connector.SetNegated(True)
+                if input_connector.get("edge", "none") != "none":
+                    connector.SetEdge(input_connector["edge"])
+                self.CreateWires(connector, instance["id"], input_connector["links"], ids, selection)
+        for i, output_connector in enumerate(instance["outputs"]):
+            if i < len(connectors["outputs"]):
+                connector = connectors["outputs"][i]
+                if output_connector.get("negated", False):
+                    connector.SetNegated(True)
+                if output_connector.get("edge", "none") != "none":
+                    connector.SetEdge(output_connector["edge"])
+                connector.SetPosition(wx.Point(*output_connector["position"]))
+        if selection is not None and selection[0].get(instance["id"], False):
+            self.SelectInGroup(element)
+
+    def CreateWires(self, start_connector, id, links, ids, selection=None):
         for link in links:
             refLocalId = link["refLocalId"]
             if refLocalId is not None:
                 if refLocalId not in ids:
                     new_instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, refLocalId, debug = self.Debug)
                     if new_instance is not None:
-                        self.loadInstance(new_instance, ids)
+                        self.loadInstance(new_instance, ids, selection)
                 connected = self.FindElementById(refLocalId)
                 if connected is not None:
                     points = link["points"]
@@ -1075,6 +973,10 @@
                         wire.ConnectStartPoint(None, start_connector)
                         wire.ConnectEndPoint(None, end_connector)
                         self.AddWire(wire)
+                        if selection is not None and (\
+                           selection[1].get((id, refLocalId), False) or \
+                           selection[1].get((refLocalId, id), False)):
+                            self.SelectInGroup(wire)
 
     def IsOfType(self, type, reference):
         return self.Controler.IsOfType(type, reference, self.Debug)
@@ -1090,7 +992,7 @@
 #-------------------------------------------------------------------------------
 
     def FindBlock(self, pos):
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             if block.HitTest(pos) or block.TestHandle(pos) != (0, 0):
                 return block
         return None
@@ -1111,19 +1013,19 @@
         return None
     
     def FindBlockConnector(self, pos, direction = None, exclude = None):
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             result = block.TestConnector(pos, direction, exclude)
             if result:
                 return result
         return None
     
     def FindElementById(self, id):
-        for element in self.Blocks:
-            if element.GetId() == id:
-                return element
-        for element in self.Comments:
-            if element.GetId() == id:
-                return element
+        block = self.Blocks.get(id, None)
+        if block is not None:
+            return block
+        comment = self.Comments.get(id, None)
+        if comment is not None:
+            return comment
         return None
     
     def SearchElements(self, bbox):
@@ -1977,7 +1879,7 @@
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
         dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
-        dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
+        dialog.SetStepNames([block.GetName() for block in self.Blocks.itervalues() if isinstance(block, SFC_Step)])
         dialog.SetMinStepSize((bbox.width, bbox.height))
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
@@ -2049,7 +1951,7 @@
 
     def AddNewJump(self, bbox):
         choices = []
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             if isinstance(block, SFC_Step):
                 choices.append(block.GetName())
         dialog = wx.SingleChoiceDialog(self.ParentWindow, "Add a new jump", "Please choose a target", choices, wx.OK|wx.CANCEL)
@@ -2287,7 +2189,7 @@
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
         dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
-        dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()])
+        dialog.SetStepNames([block.GetName() for block in self.Blocks.itervalues() if isinstance(block, SFC_Step) and block.GetName() != step.GetName()])
         dialog.SetMinStepSize(step.GetSize())
         values = {"name" : step.GetName()}
         connectors = step.GetConnectors()
@@ -2340,7 +2242,7 @@
 
     def EditJumpContent(self, jump):
         choices = []
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             if isinstance(block, SFC_Step):
                 choices.append(block.GetName())
         dialog = wx.SingleChoiceDialog(self.ParentWindow, "Edit jump target", "Please choose a target", choices, wx.OK|wx.CANCEL)
@@ -2474,6 +2376,7 @@
         infos["x"], infos["y"] = step.GetPosition()
         infos["width"], infos["height"] = step.GetSize()
         infos["connectors"] = step.GetConnectors()
+        infos["action"] = step.GetActionConnector()
         self.Controler.SetEditedElementStepInfos(self.TagName, stepid, infos)
 
     def RefreshTransitionModel(self, transition):
@@ -2485,6 +2388,7 @@
         infos["x"], infos["y"] = transition.GetPosition()
         infos["width"], infos["height"] = transition.GetSize()
         infos["connectors"] = transition.GetConnectors()
+        infos["connection"] = transition.GetConditionConnector()
         self.Controler.SetEditedElementTransitionInfos(self.TagName, transitionid, infos)
 
     def RefreshDivergenceModel(self, divergence):
@@ -2535,8 +2439,8 @@
         
     def DeleteVariable(self, variable):
         connectors = variable.GetConnectors()
-        if connectors["output"]:
-            elements = connectors["output"].GetConnectedBlocks()
+        if len(connectors["outputs"]) > 0:
+            elements = connectors["outputs"][0].GetConnectedBlocks()
         else:
             elements = []
         variable.Clean()
@@ -2570,7 +2474,7 @@
 
     def DeleteContact(self, contact):
         connectors = contact.GetConnectors()
-        elements = connectors["output"].GetConnectedBlocks()
+        elements = connectors["outputs"][0].GetConnectedBlocks()
         contact.Clean()
         self.RemoveBlock(contact)
         self.Controler.RemoveEditedElementInstance(self.TagName, contact.GetId())
@@ -2579,7 +2483,7 @@
 
     def DeleteCoil(self, coil):
         connectors = coil.GetConnectors()
-        elements = connectors["output"].GetConnectedBlocks()
+        elements = connectors["outputs"][0].GetConnectedBlocks()
         coil.Clean()
         self.RemoveBlock(coil)
         self.Controler.RemoveEditedElementInstance(self.TagName, coil.GetId())
@@ -2589,7 +2493,8 @@
     def DeletePowerRail(self, powerrail):
         elements = []
         if powerrail.GetType() == LEFTRAIL:
-            for connector in powerrail.GetConnectors():
+            connectors = powerrail.GetConnectors()
+            for connector in connectors["outputs"]:
                 for element in connector.GetConnectedBlocks():
                     if element not in elements:
                         elements.append(element)
@@ -2602,12 +2507,13 @@
     def DeleteStep(self, step):
         elements = []
         connectors = step.GetConnectors()
-        if connectors["output"]:
-            for element in connectors["output"].GetConnectedBlocks():
+        action_connector = step.GetActionConnector()
+        if len(connectors["outputs"]) > 0:
+            for element in connectors["outputs"][0].GetConnectedBlocks():
                 if element not in elements:
                     elements.append(element)
-        if connectors["action"]:
-            for element in connectors["action"].GetConnectedBlocks():
+        if action_connector is not None:
+            for element in action_connector.GetConnectedBlocks():
                 if element not in elements:
                     elements.append(element)
         step.Clean()
@@ -2619,10 +2525,9 @@
     def DeleteTransition(self, transition):
         elements = []
         connectors = transition.GetConnectors()
-        if connectors["output"]:
-            for element in connectors["output"].GetConnectedBlocks():
-                if element not in elements:
-                    elements.append(element)
+        for element in connectors["outputs"][0].GetConnectedBlocks():
+            if element not in elements:
+                elements.append(element)
         transition.Clean()
         self.RemoveBlock(transition)
         self.Controler.RemoveEditedElementInstance(self.TagName, transition.GetId())
@@ -2897,18 +2802,18 @@
                             int((xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[1]), ystart * SCROLLBAR_UNIT + y + 1)
         
         # Draw all elements
-        for comment in self.Comments:
+        for comment in self.Comments.itervalues():
             if comment != self.SelectedElement and (comment.IsVisible() or printing):
                 comment.Draw(dc)
-        for wire in self.Wires:
+        for wire in self.Wires.iterkeys():
             if wire != self.SelectedElement and (wire.IsVisible() or printing):
                  if not self.Debug or wire.GetValue() != True:
                     wire.Draw(dc)
         if self.Debug:
-            for wire in self.Wires:
+            for wire in self.Wires.iterkeys():
                 if wire != self.SelectedElement and (wire.IsVisible() or printing) and wire.GetValue() == True:
                     wire.Draw(dc)
-        for block in self.Blocks:
+        for block in self.Blocks.itervalues():
             if block != self.SelectedElement and (block.IsVisible() or printing):
                 block.Draw(dc)
         
--- a/graphics/FBD_Objects.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/graphics/FBD_Objects.py	Fri Jul 24 10:47:35 2009 +0200
@@ -572,7 +572,12 @@
     
     # Returns all the block connectors 
     def GetConnectors(self):
-        return {"input" : self.Input, "output" : self.Output}
+        connectors = {"inputs": [], "outputs": []}
+        if self.Input:
+            connectors["inputs"].append(self.Input)
+        if self.Output:
+            connectors["outputs"].append(self.Output)
+        return connectors
     
     # Changes the negated property of the variable connector if handled
     def SetConnectorNegated(self, negated):
@@ -785,6 +790,15 @@
     def GetConnector(self, position = None, name = None):
         return self.Connector
     
+        # Returns all the block connectors 
+    def GetConnectors(self):
+        connectors = {"inputs": [], "outputs": []}
+        if self.Type == CONNECTOR:
+            connectors["inputs"].append(self.Connector)
+        else:
+            connectors["outputs"].append(self.Connector)
+        return connectors
+    
     # Changes the variable type
     def SetType(self, type):
         if type != self.Type:
--- a/graphics/LD_Objects.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/graphics/LD_Objects.py	Fri Jul 24 10:47:35 2009 +0200
@@ -246,7 +246,11 @@
     
     # Returns all the power rail connectors 
     def GetConnectors(self):
-        return [connector for connector in self.Connectors if connector]
+        connectors = [connector for connector in self.Connectors if connector]
+        if self.Type == LEFTRAIL:
+            return {"inputs": [], "outputs": connectors}
+        else:
+            return {"inputs": connectors, "outputs": []}
     
     # Test if point given is on one of the power rail connectors
     def TestConnector(self, pt, direction = None, exclude = True):
@@ -548,7 +552,7 @@
     
     # Returns input and output contact connectors 
     def GetConnectors(self):
-        return {"input":self.Input,"output":self.Output}
+        return {"inputs": [self.Input], "outputs": [self.Output]}
     
     # Test if point given is on contact input or output connector
     def TestConnector(self, pt, direction = None, exclude=True):
@@ -837,7 +841,7 @@
     
     # Returns input and output coil connectors 
     def GetConnectors(self):
-        return {"input":self.Input,"output":self.Output}
+        return {"inputs": [self.Input], "outputs": [self.Output]}
     
     # Test if point given is on coil input or output connector
     def TestConnector(self, pt, direction = None, exclude=True):
--- a/graphics/SFC_Objects.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/graphics/SFC_Objects.py	Fri Jul 24 10:47:35 2009 +0200
@@ -272,9 +272,18 @@
                 return self.Action
         return None
     
+    # Returns action step connector 
+    def GetActionConnector(self):
+        return self.Action
+        
     # Returns input and output step connectors 
     def GetConnectors(self):
-        return {"input":self.Input,"output":self.Output,"action":self.Action}
+        connectors = {"inputs": [], "outputs": []}
+        if self.Input:
+            connectors["inputs"].append(self.Input)
+        if self.Output:
+            connectors["outputs"].append(self.Output)
+        return connectors
     
     # Test if point given is on step input or output connector
     def TestConnector(self, pt, direction = None, exclude=True):
@@ -319,7 +328,7 @@
         return None
     
     # Returns the connector connected to action
-    def GetActionConnector(self):
+    def GetActionConnected(self):
         if self.Action:
             wires = self.Action.GetWires()
             if len(wires) == 1:
@@ -491,7 +500,7 @@
     def RefreshModel(self, move=True):
         self.Parent.RefreshStepModel(self)
         if self.Action:
-            action = self.GetActionConnector()
+            action = self.GetActionConnected()
             if action:
                 action_block = action.GetParentBlock()
                 action_block.RefreshModel(False)
@@ -748,13 +757,16 @@
                 return self.Condition
         return None
     
+    # Returns the transition condition connector
+    def GetConditionConnector(self):
+        if self.Type == "connection":
+            return self.Condition
+        return None
+        
     # Returns input and output transition connectors
     def GetConnectors(self):
-        connectors = {"input":self.Input,"output":self.Output}
-        if self.Type == "connection":
-            connectors["connection"] = self.Condition
-        return connectors
-    
+        return {"inputs": [self.Input], "outputs": [self.Output]}
+        
     # Test if point given is on transition input or output connector
     def TestConnector(self, pt, direction = None, exclude=True):
         # Test input connector
@@ -1206,7 +1218,7 @@
     
     # Returns input and output divergence connectors 
     def GetConnectors(self):
-        return {"inputs":self.Inputs,"outputs":self.Outputs}
+        return {"inputs": self.Inputs, "outputs": self.Outputs}
     
     # Test if point given is on divergence input or output connector
     def TestConnector(self, pt, direction = None, exclude=True):
@@ -1553,6 +1565,10 @@
     def GetConnector(self, position = None, name = None):
         return self.Input
     
+    # Returns all the jump connectors 
+    def GetConnectors(self):
+        return {"inputs": [self.Input], "outputs": []}
+    
     # Test if point given is on jump input connector
     def TestConnector(self, pt, direction = None, exclude = True):
         # Test input connector
@@ -1782,6 +1798,10 @@
     def GetConnector(self, position = None, name = None):
         return self.Input
     
+    # Returns all the action block connectors 
+    def GetConnectors(self):
+        return {"inputs": [self.Input], "outputs": []}
+    
     # Test if point given is on action block input connector
     def TestConnector(self, pt, direction = None, exclude = True):
         # Test input connector
--- a/plcopen/plcopen.py	Fri Jul 24 09:55:11 2009 +0200
+++ b/plcopen/plcopen.py	Fri Jul 24 10:47:35 2009 +0200
@@ -1223,13 +1223,158 @@
 def sety(self, y):
     self.position.sety(y)
 
-cls = PLCOpenClasses.get("commonObjects_comment", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
+def _updateElementName(self, old_name, new_name):
+    pass
+
+def _initElementClass(name, classname, connectionPointInType="none"):
+    cls = PLCOpenClasses.get(classname, None)
+    if cls:
+        setattr(cls, "getx", getx)
+        setattr(cls, "gety", gety)
+        setattr(cls, "setx", setx)
+        setattr(cls, "sety", sety)
+        setattr(cls, "updateElementName", _updateElementName)
+    return cls
+
+def _getexecutionOrder(instance, specific_values):
+    executionOrder = instance.getexecutionOrderId()
+    if executionOrder is None:
+        executionOrder = 0
+    specific_values["executionOrder"] = executionOrder
+    
+def _getdefaultmodifiers(instance, infos):
+    infos["negated"] = instance.getnegated()
+    infos["edge"] = instance.getedge()
+
+def _getinputmodifiers(instance, infos):
+    infos["negated"] = instance.getnegatedIn()
+    infos["edge"] = instance.getedgeIn()
+
+def _getoutputmodifiers(instance, infos):
+    infos["negated"] = instance.getnegatedOut()
+    infos["edge"] = instance.getedgeOut()
+
+MODIFIERS_FUNCTIONS = {"default": _getdefaultmodifiers,
+                       "input": _getinputmodifiers,
+                       "output": _getoutputmodifiers}
+
+def _getconnectioninfos(instance, connection, links=False, modifiers=None, parameter=False):
+    infos = {"position": connection.getrelPositionXY()}
+    if parameter:
+        infos["name"] = instance.getformalParameter()
+    MODIFIERS_FUNCTIONS.get(modifiers, lambda x, y: None)(instance, infos)
+    if links:
+        infos["links"] = []
+        connections = connection.getconnections()
+        if connections is not None:
+            for link in connections:
+                dic = {"refLocalId": link.getrefLocalId(),
+                       "points": link.getpoints(),
+                       "formalParameter": link.getformalParameter()}
+                infos["links"].append(dic)
+    return infos
+
+def _getelementinfos(instance):
+    return {"id": instance.getlocalId(),
+            "x": instance.getx(),
+            "y": instance.gety(),
+            "height": instance.getheight(),
+            "width": instance.getwidth(),
+            "specific_values": {},
+            "inputs": [],
+            "outputs": []}
+
+def _getvariableinfosFunction(type, input, output):
+    def getvariableinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = type
+        specific_values = infos["specific_values"]
+        specific_values["name"] = self.getexpression()
+        _getexecutionOrder(self, specific_values)
+        if input and output:
+            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "input"))
+            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "output"))
+        elif input:
+            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "default"))
+        elif output:
+            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "default"))
+        return infos
+    return getvariableinfos
+
+def _getconnectorinfosFunction(type):
+    def getvariableinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = type
+        infos["specific_values"]["name"] = self.getname()
+        if type == "connector":
+            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+        elif type == "continuation":
+            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
+        return infos
+    return getvariableinfos
+
+def _getpowerrailinfosFunction(type):
+    def getpowerrailinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = type
+        if type == "rightPowerRail":
+            for connectionPointIn in self.getconnectionPointIn():
+                infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True))
+            infos["specific_values"]["connectors"] = [True for input in infos["inputs"]]
+        elif type == "leftPowerRail":
+            for connectionPointOut in self.getconnectionPointOut():
+                infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
+            infos["specific_values"]["connectors"] = [True for output in infos["outputs"]]
+        return infos
+    return getpowerrailinfos
+
+def _getldelementinfosFunction(type):
+    def getldelementinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = type
+        specific_values = infos["specific_values"]
+        specific_values["name"] = self.getvariable()
+        _getexecutionOrder(self, specific_values)
+        specific_values["negated"] = self.getnegated()
+        specific_values["edge"] = self.getedge()
+        if type == "coil":
+            specific_values["storage"] = self.getstorage()
+        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+        infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
+        return infos
+    return getldelementinfos
+
+DIVERGENCE_TYPES = {(True, True): "simultaneousDivergence",
+                    (True, False): "selectionDivergence",
+                    (False, True): "simultaneousConvergence",
+                    (False, False): "selectionConvergence"}
+
+def _getdivergenceinfosFunction(divergence, simultaneous):
+    def getdivergenceinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = DIVERGENCE_TYPES[(divergence, simultaneous)]
+        if divergence:
+            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+            for connectionPointOut in self.getconnectionPointOut():
+                infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
+            infos["specific_values"]["connectors"] = len(infos["outputs"])
+        else:
+            for connectionPointIn in self.getconnectionPointIn():
+                infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True))
+            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
+            infos["specific_values"]["connectors"] = len(infos["inputs"])
+        return infos
+    return getdivergenceinfos
+
+cls = _initElementClass("comment", "commonObjects_comment")
+if cls:
+    def getinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = "comment"
+        infos["specific_values"]["content"] = self.getcontentText()
+        return infos
+    setattr(cls, "getinfos", getinfos)
+    
     def setcontentText(self, text):
         self.content.settext(text)
     setattr(cls, "setcontentText", setcontentText)
@@ -1242,81 +1387,97 @@
         self.content.updateElementName(old_name, new_name)
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("fbdObjects_block", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
+cls = _initElementClass("block", "fbdObjects_block")
+if cls:
+    def getBoundingBox(self):
+        bbox = _getBoundingBox(self)
+        for input in self.inputVariables.getvariable():
+            bbox.union(_getConnectionsBoundingBox(input.connectionPointIn))
+        return bbox
+    setattr(cls, "getBoundingBox", getBoundingBox)
+
+    def getinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = self.gettypeName()
+        specific_values = infos["specific_values"]
+        specific_values["name"] = self.getinstanceName()
+        _getexecutionOrder(self, specific_values)
+        for variable in self.inputVariables.getvariable():
+            infos["inputs"].append(_getconnectioninfos(variable, variable.connectionPointIn, True, "default", True))
+        for variable in self.outputVariables.getvariable():
+            infos["outputs"].append(_getconnectioninfos(variable, variable.connectionPointOut, False, "default", True))
+        return infos
+    setattr(cls, "getinfos", getinfos)
 
     def updateElementName(self, old_name, new_name):
         if self.typeName == old_name:
             self.typeName = new_name
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("ldObjects_leftPowerRail", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("ldObjects_rightPowerRail", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("ldObjects_contact", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
+cls = _initElementClass("leftPowerRail", "ldObjects_leftPowerRail")
+if cls:
+    setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail"))
+
+cls = _initElementClass("rightPowerRail", "ldObjects_rightPowerRail", "multiple")
+if cls:
+    setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail"))
+
+cls = _initElementClass("contact", "ldObjects_contact", "single")
+if cls:
+    setattr(cls, "getinfos", _getldelementinfosFunction("contact"))
+    
     def updateElementName(self, old_name, new_name):
         if self.variable == old_name:
             self.variable = new_name
     setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("ldObjects_coil", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
+    
+cls = _initElementClass("coil", "ldObjects_coil", "single")
+if cls:
+    setattr(cls, "getinfos", _getldelementinfosFunction("coil"))
+    
     def updateElementName(self, old_name, new_name):
         if self.variable == old_name:
             self.variable = new_name
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("sfcObjects_step", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("sfcObjects_transition", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
+cls = _initElementClass("step", "sfcObjects_step", "single")
+if cls:
+    def getinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = "step"
+        specific_values = infos["specific_values"]
+        specific_values["name"] = self.getname()
+        specific_values["initial"] = self.getinitialStep()
+        if self.connectionPointIn:
+            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+        if self.connectionPointOut:
+            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
+        if self.connectionPointOutAction:
+            specific_values["action"] = _getconnectioninfos(self, self.connectionPointOutAction)
+        return infos
+    setattr(cls, "getinfos", getinfos)
+
+cls = _initElementClass("transition", "sfcObjects_transition", "single")
+if cls:
+    def getinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = "transition"
+        specific_values = infos["specific_values"]
+        priority = self.getpriority()
+        if priority is None:
+            priority = 0
+        specific_values["priority"] = priority
+        condition = self.getconditionContent()
+        specific_values["condition_type"] = condition["type"]
+        if specific_values["condition_type"] == "connection":
+            
+            specific_values["connection"] = _getconnectioninfos(self, self, True)
+        else:
+            specific_values["condition"] = condition["value"]
+        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+        infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
+        return infos
+    setattr(cls, "getinfos", getinfos)
 
     def setconditionContent(self, type, value):
         if not self.condition:
@@ -1355,6 +1516,14 @@
                 content["value"].updateElementName(old_name, new_name)
     setattr(cls, "updateElementName", updateElementName)
 
+    def setrelPositionXY(self, x, y):
+        pass
+    setattr(cls, "setrelPositionXY", setrelPositionXY)
+
+    def getrelPositionXY(self):
+        return None
+    setattr(cls, "getrelPositionXY", getrelPositionXY)
+
     def addconnection(self):
         if self.condition:
             content = self.condition.getcontent()
@@ -1385,7 +1554,7 @@
             if content["name"] == "connection":
                 return content["value"]
     setattr(cls, "getconnections", getconnections)
-    
+
     def setconnectionId(self, idx, id):
         if self.condition:
             content = self.condition.getcontent()
@@ -1427,64 +1596,35 @@
         if self.condition:
             content = self.condition.getcontent()
             if content["name"] == "connection":
-                return content["value"][idx].getformalParameter()
+                content["value"][idx].getformalParameter()
         return None
     setattr(cls, "getconnectionParameter", getconnectionParameter)
-
-cls = PLCOpenClasses.get("sfcObjects_selectionDivergence", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("sfcObjects_selectionConvergence", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-    
-cls = PLCOpenClasses.get("sfcObjects_simultaneousDivergence", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-    
-cls = PLCOpenClasses.get("sfcObjects_simultaneousConvergence", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("sfcObjects_jumpStep", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
+    
+cls = _initElementClass("selectionDivergence", "sfcObjects_selectionDivergence", "single")
+if cls:
+    setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False))
+
+cls = _initElementClass("selectionConvergence", "sfcObjects_selectionConvergence", "multiple")
+if cls:
+    setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False))
+
+cls = _initElementClass("simultaneousDivergence", "sfcObjects_simultaneousDivergence", "single")
+if cls:
+    setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True))
+
+cls = _initElementClass("simultaneousConvergence", "sfcObjects_simultaneousConvergence", "multiple")
+if cls:
+    setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True))
+
+cls = _initElementClass("jumpStep", "sfcObjects_jumpStep", "single")
+if cls:
+    def getinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = "jump"
+        infos["specific_values"]["target"] = self.gettargetName()
+        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+        return infos
+    setattr(cls, "getinfos", getinfos)
 
 cls = PLCOpenClasses.get("actionBlock_action", None)
 if cls:
@@ -1518,13 +1658,22 @@
             self.inline.updateElementName(old_name, new_name)
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("commonObjects_actionBlock", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
+cls = _initElementClass("actionBlock", "commonObjects_actionBlock", "single")
+if cls:
+    def compatibility(self, tree):
+        for child in tree.childNodes[:]:
+            if child.nodeName == "connectionPointOut":
+                tree.childNodes.remove(child)
+    setattr(cls, "compatibility", compatibility)
+    
+    def getinfos(self):
+        infos = _getelementinfos(self)
+        infos["type"] = "actionBlock"
+        infos["specific_values"]["actions"] = self.getactions()
+        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
+        return infos
+    setattr(cls, "getinfos", getinfos)
+    
     def setactions(self, actions):
         self.action = []
         for params in actions:
@@ -1571,63 +1720,40 @@
             action.updateElementName(old_name, new_name)
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("fbdObjects_inVariable", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
+cls = _initElementClass("inVariable", "fbdObjects_inVariable")
+if cls:
+    setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True))
     
     def updateElementName(self, old_name, new_name):
         if self.expression == old_name:
             self.expression = new_name
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("fbdObjects_outVariable", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
+cls = _initElementClass("outVariable", "fbdObjects_outVariable", "single")
+if cls:
+    setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False))
+    
     def updateElementName(self, old_name, new_name):
         if self.expression == old_name:
             self.expression = new_name
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("fbdObjects_inOutVariable", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-
+cls = _initElementClass("inOutVariable", "fbdObjects_inOutVariable", "single")
+if cls:
+    setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True))
+    
     def updateElementName(self, old_name, new_name):
         if self.expression == old_name:
             self.expression = new_name
     setattr(cls, "updateElementName", updateElementName)
 
-cls = PLCOpenClasses.get("commonObjects_continuation", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
-
-cls = PLCOpenClasses.get("commonObjects_connector", None)
-if cls:
-    setattr(cls, "getx", getx)
-    setattr(cls, "gety", gety)
-    setattr(cls, "setx", setx)
-    setattr(cls, "sety", sety)
-    
-    def updateElementName(self, old_name, new_name):
-        pass
-    setattr(cls, "updateElementName", updateElementName)
+cls = _initElementClass("continuation", "commonObjects_continuation")
+if cls:
+    setattr(cls, "getinfos", _getconnectorinfosFunction("continuation"))
+
+cls = _initElementClass("connector", "commonObjects_connector", "single")
+if cls:
+    setattr(cls, "getinfos", _getconnectorinfosFunction("connector"))
 
 cls = PLCOpenClasses.get("connection", None)
 if cls: