diff --git a/rocolib/api/components/Component.py b/rocolib/api/components/Component.py
index 8e81033f833af106d8eb5308e3be028197e0c154..e7c50ee3ce9d1d7bf0e193597e6b3169073fb51d 100644
--- a/rocolib/api/components/Component.py
+++ b/rocolib/api/components/Component.py
@@ -273,10 +273,10 @@ class Component(Parameterized):
 
         fromPort = self.getInterfaces(*fromInterface)
         toPort = self.getInterfaces(*toInterface)
-        if fromPort.canMate(toPort):
+        if fromPort.canMate(toPort) or toPort.canMate(fromPort):
             self.connections.setdefault(name, [fromInterface, toInterface, kwargs])
         else:
-            raise AttributeError(f"{fromInterface} cannot connect to {toInterface} according to getMate")
+            raise AttributeError(f"{fromInterface} ({fromPort} : {type(fromPort)}) cannot connect to {toInterface} ({toPort} : {type(toPort)}) according to getMate")
 
     def delConnection(self, name):
       self.connections.pop(name)
diff --git a/rocolib/api/composables/graph/Face.py b/rocolib/api/composables/graph/Face.py
index aaaad3650d54b5b5c2d61e34755b9b95503ca918..2f574070330605d24fa31ff193b10a051c9420e0 100644
--- a/rocolib/api/composables/graph/Face.py
+++ b/rocolib/api/composables/graph/Face.py
@@ -220,8 +220,11 @@ class Face(object):
   def addDecoration(self, pts):
     self.decorations.append(pts)
 
-  def addFace(self, face, transform):
+  def addFace(self, face, transform, copyDecorations=False):
     self.joinedFaces.append((face, transform))
+    if copyDecorations:
+      for d in self.decorations:
+        face.addDecoration(d)
 
   def preTransform(self, edge):
     index = self.edges.index(edge)
diff --git a/rocolib/api/composables/graph/Graph.py b/rocolib/api/composables/graph/Graph.py
index 17f4dc40aa3bd9b5d2446d4a2d601cb3a63866ac..f39c28108414954f5a6cf3ae3ff440b3dc2827d6 100644
--- a/rocolib/api/composables/graph/Graph.py
+++ b/rocolib/api/composables/graph/Graph.py
@@ -107,13 +107,14 @@ class Graph():
     self.addFace(toFace, prefix)
     self.mergeFace(fromFace, toFace.name, transform)
 
-  def mergeFace(self, fromFaceName, toFaceName, transform=None):
+  def mergeFace(self, fromFaceName, toFaceName, transform=None, offset=(0,0), copyDecorations=False):
     fromFace = self.getFace(fromFaceName)
     toFace = self.getFace(toFaceName)
+    toFace.transform(origin=offset)
     if transform is None:
         transform = np.eye(4)
-    fromFace.addFace(toFace, transform)
-    toFace.addFace(fromFace, np.inv(transform))
+    fromFace.addFace(toFace, transform, copyDecorations)
+    toFace.addFace(fromFace, np.inv(transform), copyDecorations)
 
   def attachEdge(self, fromEdge, newFace, newEdge, prefix=None, root=False, angle=0, edgeType=None, joints=None):
     # XXX should set angle from a face, not absolute angle of the face
diff --git a/rocolib/api/ports/FacePort.py b/rocolib/api/ports/FacePort.py
index 3b3a162605a22763c9b63a5f931a7cf4ea380337..9bfa32a47fbfb28bd6a7d34f419c2f1d97112198 100644
--- a/rocolib/api/ports/FacePort.py
+++ b/rocolib/api/ports/FacePort.py
@@ -1,5 +1,7 @@
 from rocolib.api.ports import Port
 from rocolib.utils.utils import prefix as prefixString
+from rocolib.utils.numsym import deg2rad
+from rocolib.utils.transforms import RotateX
 
 class FacePort(Port):
   def __init__(self, parent, graph, face):
@@ -36,4 +38,8 @@ class FacePort(Port):
     if isinstance(toPort, FacePort):
       face1 = graph.getFace(self.getFaceName())
       face2 = graph.getFace(toPort.getFaceName())
-      graph.mergeFace(face1.name, face2.name)
+      if kwargs.get("flip"):
+        transform = RotateX(deg2rad(180))
+      else:
+        transform = None
+      graph.mergeFace(face1.name, face2.name, transform=transform, offset=kwargs.get("offset", (0,0)), copyDecorations=True)
diff --git a/rocolib/utils/numsym.py b/rocolib/utils/numsym.py
index 42855a4a31921d07795e872ecc2257441e1aa251..758684c8f8d3c9d74d85b8abec13bdcee2f0e2f9 100644
--- a/rocolib/utils/numsym.py
+++ b/rocolib/utils/numsym.py
@@ -19,7 +19,7 @@ def cumsum(iterable):
 
 # Numpy mods
 def numpy_rows(x):
-    return x.shape[0]
+    return numpy.array(x)
   
 def numpy_N(x):
     return x
@@ -79,9 +79,6 @@ def sympy_difference(pts1, pts2):
 def sympy_dex(pts1, pts2, tol):
     return sympy_difference(pts1, pts2) > tol
 
-def sympy_rows(x):
-    return x.rows
-
 def sympy_pi():
     return sympy.pi