diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py
index 592441fee7f6f85cd2f235185c4a4720a968d67f..fd6569c1bac231784e942b70bee67e9f002bcfa5 100644
--- a/rigify/rigs/experimental/super_chain.py
+++ b/rigify/rigs/experimental/super_chain.py
@@ -3,9 +3,9 @@ from mathutils import Vector
 from ...utils import copy_bone, put_bone, org, align_bone_y_axis, align_bone_x_axis, align_bone_z_axis
 from ...utils import strip_org, make_deformer_name, connected_children_names
 from ...utils import create_chain_widget
-from ...utils import make_mechanism_name, create_cube_widget
+from ...utils import make_mechanism_name
 from ...utils import ControlLayersOption
-from ...utils.mechanism import make_property, make_driver
+from rna_prop_ui import rna_idprop_ui_prop_get
 from ..limbs.limb_utils import get_bone_name
 
 
@@ -114,7 +114,13 @@ class Rig:
             self.obj.data.bones[def_bones[-1]].bbone_easeout = 1.0
         bpy.ops.object.mode_set(mode='EDIT')
 
-        return def_bones
+        conv_def = ""
+        if self.params.conv_bone and self.params.conv_def:
+            b = org(self.params.conv_bone)
+            conv_def = make_deformer_name(strip_org(b))
+            conv_def = copy_bone(self.obj, b, conv_def)
+
+        return def_bones, conv_def
 
     def create_chain(self):
         org_bones = self.org_bones
@@ -147,28 +153,23 @@ class Rig:
                 eb[mch_name].length /= 4
                 put_bone(self.obj, mch_name, eb[b].head - (eb[mch_name].tail - eb[mch_name].head))
                 align_bone_z_axis(self.obj, mch_name, eb[b].z_axis)
-                if '.' in mch_name:
-                    mch_rev_name = mch_name.split('.')[0] + '_reverse.' + mch_name.split('.')[1]
-                else:
-                    mch_rev_name = mch_name + '_reverse'
-                mch_rev_name = copy_bone(self.obj, org(b), mch_rev_name)
-                eb[mch_rev_name].length /= 4
-                eb[mch_rev_name].tail = eb[mch_name].head
-                align_bone_z_axis(self.obj, mch_rev_name, eb[b].z_axis)
                 mch += [mch_name]
-                mch += [mch_rev_name]
-                break
-
-            mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
-            eb[mch_name].length /= 4
-
-            mch += [mch_name]
-
-            if b == org_bones[-1]:  # Add extra
                 mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
                 eb[mch_name].length /= 4
                 put_bone(self.obj, mch_name, eb[b].tail)
                 mch += [mch_name]
+                break
+            else:
+                mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+                eb[mch_name].length /= 4
+
+                mch += [mch_name]
+
+                if b == org_bones[-1]:  # Add extra
+                    mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+                    eb[mch_name].length /= 4
+                    put_bone(self.obj, mch_name, eb[b].tail)
+                    mch += [mch_name]
 
         # Tweak & Ctrl bones
         v = eb[org_bones[-1]].tail - eb[org_bones[0]].head  # Create a vector from head of first ORG to tail of last
@@ -193,7 +194,7 @@ class Rig:
                 align_bone_x_axis(self.obj, name, eb[org(b)].x_axis)
                 ctrl += [name]
             else:
-                name = get_bone_name(b, 'ctrl', 'tweak')
+                name = 'tweak_' + strip_org(b)
                 name = copy_bone(self.obj, org(b), name)
                 twk += [name]
 
@@ -238,12 +239,16 @@ class Rig:
         conv_twk = ''
         # Convergence tweak
         if self.params.conv_bone:
-            conv_twk = get_bone_name(self.params.conv_bone, 'ctrl', 'tweak')
+            conv_twk = 'tweak_' + strip_org(self.params.conv_bone)
 
             if not(conv_twk in eb.keys()):
                 conv_twk = copy_bone(self.obj, org(self.params.conv_bone), conv_twk)
 
         for b in org_bones:
+
+            if self.SINGLE_BONE:
+                break
+
             # Mch controls
             suffix = ''
             if '.L' in b:
@@ -252,7 +257,7 @@ class Rig:
                 suffix = '.R'
 
             mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix
-            mch_ctrl_name = copy_bone(self.obj, twk[0], mch_ctrl_name)
+            mch_ctrl_name = copy_bone(self.obj, twk[0] if twk else ctrl[0], mch_ctrl_name)
 
             eb[mch_ctrl_name].length /= 6
 
@@ -262,7 +267,7 @@ class Rig:
 
             if b == org_bones[-1]:  # Add extra
                 mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix
-                mch_ctrl_name = copy_bone(self.obj, twk[0], mch_ctrl_name)
+                mch_ctrl_name = copy_bone(self.obj, twk[0] if twk else ctrl[0], mch_ctrl_name)
 
                 eb[mch_ctrl_name].length /= 6
 
@@ -289,6 +294,9 @@ class Rig:
             if i > 0:   # For all bones but the first (which has no parent)
                 eb[b].parent = eb[bones['def'][i-1]]  # to previous
                 eb[b].use_connect = True
+            elif self.SINGLE_BONE:
+                eb[b].parent = eb[bones['chain']['mch'][0]]
+                eb[b].use_connect = True
 
         # Todo check case when sup_chain is in bigger rig
         eb[bones['def'][0]].parent = eb[bones['chain']['mch'][0]]
@@ -297,9 +305,9 @@ class Rig:
             eb[twk].parent = eb[bones['chain']['mch_ctrl'][i+1]]
             eb[twk].use_inherit_scale = False
 
-        eb[bones['chain']['ctrl'][0]].parent = eb[bones['chain']['mch_ctrl'][0]]
+        eb[bones['chain']['ctrl'][0]].parent = eb[bones['chain']['mch_ctrl'][0]] if bones['chain']['mch_ctrl'] else None
         eb[bones['chain']['ctrl'][0]].use_inherit_scale = False
-        eb[bones['chain']['ctrl'][1]].parent = eb[bones['chain']['mch_ctrl'][-1]]
+        eb[bones['chain']['ctrl'][1]].parent = eb[bones['chain']['mch_ctrl'][-1]] if bones['chain']['mch_ctrl'] else None
         eb[bones['chain']['ctrl'][1]].use_inherit_scale = False
 
         if 'pivot' in bones.keys():
@@ -314,9 +322,13 @@ class Rig:
                 eb[mch].parent = eb[bones['chain']['tweak'][i-1]]
 
         if 'parent' in bones.keys():
-            eb[bones['chain']['mch_auto']].parent = eb[bones['parent']]
-            eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['parent']]
-            eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['parent']]
+            if self.SINGLE_BONE:
+                eb[bones['chain']['ctrl'][0]].parent = eb[bones['parent']]
+                eb[bones['chain']['ctrl'][-1]].parent = eb[bones['parent']]
+            else:
+                eb[bones['chain']['mch_auto']].parent = eb[bones['parent']]
+                eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['parent']]
+                eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['parent']]
 
         for i, mch_ctrl in enumerate(bones['chain']['mch_ctrl'][1:-1]):
             eb[mch_ctrl].parent = eb[bones['chain']['mch_auto']]
@@ -326,14 +338,11 @@ class Rig:
 
         if bones['chain']['conv']:
             eb[bones['chain']['ctrl'][-1]].parent = eb[bones['chain']['conv']]
+            eb[bones['chain']['conv']].parent = eb[bones['chain']['conv']].parent
 
         if self.SINGLE_BONE:
-            eb[bones['chain']['ctrl'][0]].parent = None
-            eb[bones['chain']['ctrl'][-1]].parent = None
-            eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['chain']['ctrl'][0]]
-            eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['chain']['ctrl'][-1]]
-            eb[bones['chain']['mch'][0]].parent = eb[bones['chain']['mch'][1]]
-            eb[bones['chain']['mch'][1]].parent = eb[bones['chain']['mch_ctrl'][0]]
+            eb[bones['chain']['mch'][0]].parent = eb[bones['chain']['ctrl'][0]]
+            eb[bones['chain']['mch'][1]].parent = eb[bones['chain']['ctrl'][1]]
 
         return
 
@@ -351,7 +360,6 @@ class Rig:
             setattr(const, p, constraint[p])
 
     def constrain_bones(self, bones):
-        # DEF bones
 
         deform = bones['def']
         mch = bones['chain']['mch']
@@ -359,6 +367,17 @@ class Rig:
         ctrls = bones['chain']['ctrl']
         tweaks = [ctrls[0]] + bones['chain']['tweak'] + [ctrls[-1]]
 
+        # ORG bones
+        for i, org_bone in enumerate(self.org_bones):
+            self.make_constraint(org_bone, {
+                'constraint': 'COPY_TRANSFORMS',
+                'subtarget': tweaks[i],
+                'owner_space': 'WORLD',
+                'target_space': 'WORLD'
+            })
+
+        # DEF bones
+
         for i, d in enumerate(deform):
 
             if len(deform) > 1:
@@ -374,6 +393,14 @@ class Rig:
                 'subtarget': tweaks[i+1]
             })
 
+        if bones['conv_def']:
+            self.make_constraint(bones['conv_def'], {
+                'constraint': 'COPY_TRANSFORMS',
+                'subtarget': bones['chain']['conv'],
+                'owner_space': 'POSE',
+                'target_space': 'POSE'
+            })
+
         if 'pivot' in bones.keys():
             step = 2/(len(self.org_bones))
             for i, b in enumerate(mch_ctrl):
@@ -441,7 +468,7 @@ class Rig:
         ctrl_start = pb[bones['chain']['ctrl'][0]]
         ctrl_end = pb[bones['chain']['ctrl'][-1]]
         mch_start = pb[bones['chain']['mch'][0]]
-        mch_end = pb[bones['chain']['mch_ctrl'][-1]]
+        mch_end = pb[bones['chain']['mch_ctrl'][-1]] if bones['chain']['mch_ctrl'] else pb[bones['chain']['mch'][-1]]
 
         if 'bbone_custom_handle_start' in dir(def_pb) and 'bbone_custom_handle_end' in dir(def_pb):
             if not self.SINGLE_BONE:
@@ -498,19 +525,25 @@ class Rig:
 
         # Assigning a widget to main ctrl bone
         if 'pivot' in bones.keys():
-            create_cube_widget(
+            create_chain_widget(
                 self.obj,
                 bones['pivot']['ctrl'],
+                cube=True,
                 radius=0.15,
-                bone_transform_name=None
+                bone_transform_name=None,
+                axis=self.params.wgt_align_axis,
+                offset=self.params.wgt_offset*pb[bones['chain']['ctrl'][0]].length
             )
 
         for bone in bones['chain']['tweak']:
-            create_cube_widget(
+            create_chain_widget(
                 self.obj,
                 bone,
+                cube=True,
                 radius=0.2,
-                bone_transform_name=None
+                bone_transform_name=None,
+                axis=self.params.wgt_align_axis,
+                offset=self.params.wgt_offset*pb[bones['chain']['ctrl'][0]].length
             )
 
         create_chain_widget(
@@ -518,23 +551,34 @@ class Rig:
             bones['chain']['ctrl'][0],
             invert=False,
             radius=0.3,
-            bone_transform_name=None
+            bone_transform_name=None,
+            axis=self.params.wgt_align_axis,
+            offset=self.params.wgt_offset*pb[bones['chain']['ctrl'][0]].length
         )
 
+        invert_last = True
+        if self.params.wgt_align_axis is not 'y' or '-y':
+            invert_last = False
+
         create_chain_widget(
             self.obj,
             bones['chain']['ctrl'][-1],
-            invert=True,
+            invert=invert_last,
             radius=0.3,
-            bone_transform_name=None
+            bone_transform_name=None,
+            axis=self.params.wgt_align_axis,
+            offset=self.params.wgt_offset*pb[bones['chain']['ctrl'][0]].length
         )
 
         if bones['chain']['conv']:
-            create_cube_widget(
+            create_chain_widget(
                 self.obj,
                 bones['chain']['conv'],
+                cube=True,
                 radius=0.5,
-                bone_transform_name=None
+                bone_transform_name=None,
+                axis=self.params.wgt_align_axis,
+                offset=self.params.wgt_offset*pb[bones['chain']['ctrl'][0]].length
             )
 
         # Assigning layers to tweaks and ctrls
@@ -542,6 +586,39 @@ class Rig:
 
         return
 
+    def aggregate_ctrls(self, bones):
+
+        if not self.params.cluster_ctrls:
+            return
+
+        other_ctrls = []
+        all_ctrls = []
+        eb = self.obj.data.edit_bones
+
+        head_start = eb[bones['chain']['ctrl'][0]].head
+        head_tip = eb[bones['chain']['ctrl'][-1]].head
+
+        all_ctrls.extend(bones['chain']['ctrl'])
+        all_ctrls.extend(bones['chain']['tweak'])
+        all_ctrls.extend(bones['chain']['conv'])
+        for bname in eb.keys():
+            if bname not in all_ctrls and (bname.startswith('tweak') or 'ctrl' in bname):
+                other_ctrls.append(bname)
+
+        for bname in other_ctrls:
+            if eb[bname].head == head_start:
+                for child in eb[bones['chain']['ctrl'][0]].children:
+                    child.parent = eb[bname]
+                eb.remove(eb[bones['chain']['ctrl'][0]])
+                bones['chain']['ctrl'][0] = bname
+                break
+
+        for bname in other_ctrls:
+            if eb[bname].head == head_tip:
+                eb.remove(eb[bones['chain']['ctrl'][-1]])
+                bones['chain']['ctrl'][-1] = bname
+                break
+
     def generate(self):
 
         bpy.ops.object.mode_set(mode='EDIT')
@@ -549,19 +626,27 @@ class Rig:
 
         bones = {}
         if eb[self.org_bones[0]].parent:
-            bones['parent'] = eb[self.org_bones[0]].parent.name
+            def_name = make_deformer_name(strip_org(eb[self.org_bones[0]].parent.name))
+            if self.params.def_parenting and def_name in eb.keys():
+                bones['parent'] = def_name
+            else:
+                bones['parent'] = eb[self.org_bones[0]].parent.name
 
         # Clear parents for org bones
         for bone in self.org_bones[0:]:
             eb[bone].use_connect = False
             eb[bone].parent = None
 
-        bones['def'] = self.create_deform()
+        bones['def'], bones['conv_def'] = self.create_deform()
         if len(self.org_bones) > 2:
             bones['pivot'] = self.create_pivot()
         bones['chain'] = self.create_chain()
 
         self.parent_bones(bones)
+
+        # ctrls snapping pass
+        self.aggregate_ctrls(bones)
+
         self.constrain_bones(bones)
         self.stick_to_bendy_bones(bones)
         self.locks_and_widgets(bones)
@@ -576,22 +661,57 @@ def add_parameters(params):
 
     items = [
         ('auto', 'Auto', ''),
-        ('x', 'X', ''),
-        ('y', 'Y', ''),
-        ('z', 'Z', '')
+        ('x', 'X-Global', ''),
+        ('y', 'Y-Global', ''),
+        ('z', 'Z-Global', '')
     ]
 
     params.tweak_axis = bpy.props.EnumProperty(
         items=items,
-        name="Tweak Axis",
+        name="Orient y-axis to",
+        description="Targets all ctrls y-axis to defined axis (global space)",
         default='auto'
     )
 
+    axes = [
+        ('x', 'X', ''),
+        ('y', 'Y', ''),
+        ('z', 'Z', ''),
+        ('-x', '-X', ''),
+        ('-y', '-Y', ''),
+        ('-z', '-Z', '')
+    ]
+
+    params.wgt_align_axis = bpy.props.EnumProperty(
+        items=axes,
+        name="Custom Widget orient",
+        description="Targets custom WGTs to defined axis (global space)",
+        default='y'
+    )
+
     params.conv_bone = bpy.props.StringProperty(
         name='Convergence bone',
         default=''
     )
 
+    params.conv_def = bpy.props.BoolProperty(
+        name="Add DEF on convergence",
+        default=False,
+        description=""
+        )
+
+    params.def_parenting = bpy.props.BoolProperty(
+        name="Prefer DEF parenting",
+        default=False,
+        description=""
+        )
+
+    params.cluster_ctrls = bpy.props.BoolProperty(
+        name="Cluster controls",
+        default=False,
+        description="Clusterize controls in the same position"
+        )
+
     params.bbones = bpy.props.IntProperty(
         name='bbone segments',
         default=10,
@@ -599,6 +719,13 @@ def add_parameters(params):
         description='Number of segments'
     )
 
+    params.wgt_offset = bpy.props.FloatProperty(
+        name='Widget Offset',
+        default=0.0,
+        min=-10.0,
+        max=10.0
+    )
+
     ControlLayersOption.TWEAK.add_parameters(params)
 
 
@@ -612,12 +739,27 @@ def parameters_ui(layout, params):
     row = col.row(align=True)
     row.prop(params, "tweak_axis")
 
+    r = layout.row()
+    r.prop(params, "wgt_align_axis")
+
+    r = layout.row()
+    r.prop(params, "wgt_offset")
+
     r = layout.row()
     r.prop(params, "bbones")
 
     r = layout.row()
     r.prop_search(params, 'conv_bone', pb, "bones", text="Convergence Bone")
 
+    r = layout.row()
+    r.prop(params, 'conv_def')
+
+    r = layout.row()
+    r.prop(params, 'def_parenting')
+
+    r = layout.row()
+    r.prop(params, 'cluster_ctrls')
+
     ControlLayersOption.TWEAK.parameters_ui(layout, params)
 
 
diff --git a/rigify/utils/widgets.py b/rigify/utils/widgets.py
index fad1065af81b45e71dae59f9a23d12bdeae780f1..6d83264ac926971450728e8d0216fa687098c255 100644
--- a/rigify/utils/widgets.py
+++ b/rigify/utils/widgets.py
@@ -21,6 +21,8 @@
 import bpy
 import math
 
+from mathutils import Matrix
+
 from .errors import MetarigError
 from .collections import ensure_widget_collection
 
@@ -132,13 +134,39 @@ def create_circle_polygon(number_verts, axis, radius=1.0, head_tail=0.0):
     return verts, edges
 
 
+def adjust_widget_axis(obj, axis='y', offset=0.0):
+    mesh = obj.data
+
+    if axis[0] == '-':
+        s = -1.0
+        axis = axis[1]
+    else:
+        s = 1.0
+
+    trans_matrix = Matrix.Translation((0.0, offset, 0.0))
+    rot_matrix = Matrix.Diagonal((1.0, s, 1.0, 1.0))
+
+    if axis == "x":
+        rot_matrix = Matrix.Rotation(-s*math.pi/2, 4, 'Z')
+        trans_matrix = Matrix.Translation((offset, 0.0, 0.0))
+
+    elif axis == "z":
+        rot_matrix = Matrix.Rotation(s*math.pi/2, 4, 'X')
+        trans_matrix = Matrix.Translation((0.0, 0.0, offset))
+
+    matrix = trans_matrix @ rot_matrix
+
+    for vert in mesh.vertices:
+        vert.co = matrix @ vert.co
+
+
 def write_widget(obj):
     """ Write a mesh object as a python script for widget use.
     """
     script = ""
     script += "def create_thing_widget(rig, bone_name, size=1.0, bone_transform_name=None):\n"
     script += "    obj = create_widget(rig, bone_name, bone_transform_name)\n"
-    script += "    if obj != None:\n"
+    script += "    if obj is not None:\n"
 
     # Vertices
     script += "        verts = ["
@@ -168,7 +196,6 @@ def write_widget(obj):
     script += "\n        mesh = obj.data\n"
     script += "        mesh.from_pydata(verts, edges, faces)\n"
     script += "        mesh.update()\n"
-    script += "        mesh.update()\n"
     script += "        return obj\n"
     script += "    else:\n"
     script += "        return None\n"
diff --git a/rigify/utils/widgets_basic.py b/rigify/utils/widgets_basic.py
index de04aecc0f3c6db0f93d2f808a1444c6b9b37aee..bb60237c434c3b59ef88f9ab03af60bec7dcd808 100644
--- a/rigify/utils/widgets_basic.py
+++ b/rigify/utils/widgets_basic.py
@@ -67,13 +67,16 @@ def create_cube_widget(rig, bone_name, radius=0.5, bone_transform_name=None):
         mesh.update()
 
 
-def create_chain_widget(rig, bone_name, radius=0.5, invert=False, bone_transform_name=None):
+def create_chain_widget(rig, bone_name, cube=False, radius=0.5, invert=False, bone_transform_name=None, axis="y", offset=0.0):
     """Creates a basic chain widget
     """
     obj = create_widget(rig, bone_name, bone_transform_name)
-    if obj != None:
+    if obj is not None:
         r = radius
-        rh = radius/2
+        if cube:
+            rh = r
+        else:
+            rh = radius/2
         if invert:
             verts = [(rh, rh, rh), (r, -r, r), (-r, -r, r), (-rh, rh, rh), (rh, rh, -rh), (r, -r, -r), (-r, -r, -r), (-rh, rh, -rh)]
         else:
@@ -82,6 +85,9 @@ def create_chain_widget(rig, bone_name, radius=0.5, invert=False, bone_transform
         mesh = obj.data
         mesh.from_pydata(verts, edges, [])
         mesh.update()
+        from .widgets import adjust_widget_axis
+        adjust_widget_axis(obj, axis=axis, offset=offset)
+        return obj
 
 
 def create_sphere_widget(rig, bone_name, bone_transform_name=None):