diff --git a/rigify/__init__.py b/rigify/__init__.py
index 638260e1a72785480f8ab9c6121dfaf704c0b9b3..2e7953b1cf8335d43a8227866657242068847580 100644
--- a/rigify/__init__.py
+++ b/rigify/__init__.py
@@ -162,14 +162,75 @@ class RigifyName(bpy.types.PropertyGroup):
     name = bpy.props.StringProperty()
 
 
+class RigifyColorSet(bpy.types.PropertyGroup):
+    name = bpy.props.StringProperty(name="Color Set", default=" ")
+    active = bpy.props.FloatVectorProperty(
+                                   name="object_color",
+                                   subtype='COLOR',
+                                   default=(1.0, 1.0, 1.0),
+                                   min=0.0, max=1.0,
+                                   description="color picker"
+                                   )
+    normal = bpy.props.FloatVectorProperty(
+                                   name="object_color",
+                                   subtype='COLOR',
+                                   default=(1.0, 1.0, 1.0),
+                                   min=0.0, max=1.0,
+                                   description="color picker"
+                                   )
+    select = bpy.props.FloatVectorProperty(
+                                   name="object_color",
+                                   subtype='COLOR',
+                                   default=(1.0, 1.0, 1.0),
+                                   min=0.0, max=1.0,
+                                   description="color picker"
+                                   )
+    standard_colors_lock = bpy.props.BoolProperty(default=True)
+
+
+class RigifySelectionColors(bpy.types.PropertyGroup):
+
+    select = bpy.props.FloatVectorProperty(
+                                           name="object_color",
+                                           subtype='COLOR',
+                                           default=(0.314, 0.784, 1.0),
+                                           min=0.0, max=1.0,
+                                           description="color picker"
+                                           )
+
+    active = bpy.props.FloatVectorProperty(
+                                           name="object_color",
+                                           subtype='COLOR',
+                                           default=(0.549, 1.0, 1.0),
+                                           min=0.0, max=1.0,
+                                           description="color picker"
+                                           )
+
+
 class RigifyParameters(bpy.types.PropertyGroup):
     name = bpy.props.StringProperty()
 
 
 class RigifyArmatureLayer(bpy.types.PropertyGroup):
-    name = bpy.props.StringProperty(name="Layer Name", default=" ")
-    row = bpy.props.IntProperty(name="Layer Row", default=1, min=1, max=32)
 
+    def get_group(self):
+        if 'group_prop' in self.keys():
+            return self['group_prop']
+        else:
+            return 0
+
+    def set_group(self, value):
+        arm = bpy.context.object.data
+        if value > len(arm.rigify_colors):
+            self['group_prop'] = len(arm.rigify_colors)
+        else:
+            self['group_prop'] = value
+
+    name = bpy.props.StringProperty(name="Layer Name", default=" ")
+    row = bpy.props.IntProperty(name="Layer Row", default=1, min=1, max=32, description='UI row for this layer')
+    set = bpy.props.BoolProperty(name="Selection Set", default=False, description='Add Selection Set for this layer')
+    group = bpy.props.IntProperty(name="Bone Group", default=0, min=0, max=32,
+                                  get=get_group, set=set_group, description='Assign Bone Group to this layer')
 
 ##### REGISTER #####
 
@@ -179,6 +240,9 @@ def register():
 
     bpy.utils.register_class(RigifyName)
     bpy.utils.register_class(RigifyParameters)
+
+    bpy.utils.register_class(RigifyColorSet)
+    bpy.utils.register_class(RigifySelectionColors)
     bpy.utils.register_class(RigifyArmatureLayer)
     bpy.utils.register_class(RigifyPreferences)
     bpy.types.Armature.rigify_layers = bpy.props.CollectionProperty(type=RigifyArmatureLayer)
@@ -186,7 +250,33 @@ def register():
     bpy.types.PoseBone.rigify_type = bpy.props.StringProperty(name="Rigify Type", description="Rig type for this bone")
     bpy.types.PoseBone.rigify_parameters = bpy.props.PointerProperty(type=RigifyParameters)
 
-    bpy.types.Armature.rigify_layers = bpy.props.CollectionProperty(type=RigifyArmatureLayer)
+    bpy.types.Armature.rigify_colors = bpy.props.CollectionProperty(type=RigifyColorSet)
+
+    bpy.types.Armature.rigify_selection_colors = bpy.props.PointerProperty(type=RigifySelectionColors)
+
+    bpy.types.Armature.rigify_colors_index = bpy.props.IntProperty(default=-1)
+    bpy.types.Armature.rigify_colors_lock = bpy.props.BoolProperty(default=True)
+    bpy.types.Armature.rigify_theme_to_add = bpy.props.EnumProperty(items=(('THEME01', 'THEME01', ''),
+                                                                          ('THEME02', 'THEME02', ''),
+                                                                          ('THEME03', 'THEME03', ''),
+                                                                          ('THEME04', 'THEME04', ''),
+                                                                          ('THEME05', 'THEME05', ''),
+                                                                          ('THEME06', 'THEME06', ''),
+                                                                          ('THEME07', 'THEME07', ''),
+                                                                          ('THEME08', 'THEME08', ''),
+                                                                          ('THEME09', 'THEME09', ''),
+                                                                          ('THEME10', 'THEME10', ''),
+                                                                          ('THEME11', 'THEME11', ''),
+                                                                          ('THEME12', 'THEME12', ''),
+                                                                          ('THEME13', 'THEME13', ''),
+                                                                          ('THEME14', 'THEME14', ''),
+                                                                          ('THEME15', 'THEME15', ''),
+                                                                          ('THEME16', 'THEME16', ''),
+                                                                          ('THEME17', 'THEME17', ''),
+                                                                          ('THEME18', 'THEME18', ''),
+                                                                          ('THEME19', 'THEME19', ''),
+                                                                          ('THEME20', 'THEME20', '')
+                                                                           ), name='Theme')
 
     IDStore = bpy.types.WindowManager
     IDStore.rigify_collection = bpy.props.EnumProperty(items=rig_lists.col_enum_list, default="All",
@@ -220,6 +310,10 @@ def unregister():
 
     bpy.utils.unregister_class(RigifyName)
     bpy.utils.unregister_class(RigifyParameters)
+
+    bpy.utils.unregister_class(RigifyColorSet)
+    bpy.utils.unregister_class(RigifySelectionColors)
+
     bpy.utils.unregister_class(RigifyArmatureLayer)
     bpy.utils.unregister_class(RigifyPreferences)
 
diff --git a/rigify/generate.py b/rigify/generate.py
index 3fe4e3b8e512a8b631104a1071957fa67f034558..f86d5eb9bde1d806e4e5683e4db582f8e6ca9a74 100644
--- a/rigify/generate.py
+++ b/rigify/generate.py
@@ -437,6 +437,12 @@ def generate_rig(context, metarig):
     # Run UI script
     exec(script.as_string(), {})
 
+    # Create Selection Sets
+    create_selection_sets(obj, metarig)
+
+    # Create Bone Groups
+    create_bone_groups(obj, metarig)
+
     t.tick("The rest: ")
     #----------------------------------
     # Deconfigure
@@ -445,6 +451,75 @@ def generate_rig(context, metarig):
     obj.data.pose_position = 'POSE'
 
 
+def create_selection_sets(obj, metarig):
+
+    # Check if selection sets addon is installed
+    if 'bone_selection_groups' not in bpy.context.user_preferences.addons \
+            and 'bone_selection_sets' not in bpy.context.user_preferences.addons:
+        return
+
+    bpy.ops.object.mode_set(mode='POSE')
+
+    bpy.context.scene.objects.active = obj
+    obj.select = True
+    metarig.select = False
+    pbones = obj.pose.bones
+
+    for i, name in enumerate(metarig.data.rigify_layers.keys()):
+        if name == '' or not metarig.data.rigify_layers[i].set:
+            continue
+
+        bpy.ops.pose.select_all(action='DESELECT')
+        for b in pbones:
+            if b.bone.layers[i]:
+                b.bone.select = True
+
+        #bpy.ops.pose.selection_set_add()
+        obj.selection_sets.add()
+        obj.selection_sets[-1].name = name
+        if 'bone_selection_sets' in bpy.context.user_preferences.addons:
+            act_sel_set = obj.selection_sets[-1]
+
+            # iterate only the selected bones in current pose that are not hidden
+            for bone in bpy.context.selected_pose_bones:
+                if bone.name not in act_sel_set.bone_ids:
+                    bone_id = act_sel_set.bone_ids.add()
+                    bone_id.name = bone.name
+
+
+def create_bone_groups(obj, metarig):
+
+    bpy.ops.object.mode_set(mode='OBJECT')
+    pb = obj.pose.bones
+    layers = metarig.data.rigify_layers
+    groups = metarig.data.rigify_colors
+
+    # Create BGs
+    for l in layers:
+        if l.group == 0:
+            continue
+        g_id = l.group - 1
+        name = groups[g_id].name
+        if name not in obj.pose.bone_groups.keys():
+            bg = obj.pose.bone_groups.new(name)
+            bg.color_set = 'CUSTOM'
+            bg.colors.normal = groups[g_id].normal
+            bg.colors.select = groups[g_id].select
+            bg.colors.active = groups[g_id].active
+
+    for b in pb:
+        try:
+            layer_index = b.bone.layers[:].index(True)
+        except ValueError:
+            continue
+        if layer_index > len(layers) - 1:   # bone is on reserved layers
+            continue
+        g_id = layers[layer_index].group - 1
+        if g_id >= 0:
+            name = groups[g_id].name
+            b.bone_group = obj.pose.bone_groups[name]
+
+
 def get_bone_rigs(obj, bone_name, halt_on_missing=False):
     """ Fetch all the rigs specified on a bone.
     """
diff --git a/rigify/ui.py b/rigify/ui.py
index 689911052951dd29f9719e15fe9cd2ee69d98fa2..c75470421d7889544adb55bf478230abbef63899 100644
--- a/rigify/ui.py
+++ b/rigify/ui.py
@@ -23,6 +23,7 @@ from bpy.props import StringProperty
 
 from .utils import get_rig_type, MetarigError
 from .utils import write_metarig, write_widget
+from .utils import unique_name
 from . import rig_lists
 from . import generate
 
@@ -128,14 +129,325 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel):
                 else:
                     col.label(text="Bottom Row:")
             if (i % 8) == 0:
-                col = layout.column(align=True)
-            row = col.row()
-            row.prop(arm, "layers", index=i, text="", toggle=True)
-            split = row.split(percentage=0.8)
-            split.prop(rigify_layer, "name",  text="Layer %d" % (i + 1))
-            split.prop(rigify_layer, "row",   text="")
+                col = layout.column()
+            if i != 28:
+                row = col.row(align=True)
+                icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON'
+                row.prop(arm, "layers", index=i, text="", toggle=True, icon=icon)
+                #row.prop(arm, "layers", index=i, text="Layer %d" % (i + 1), toggle=True, icon=icon)
+                row.prop(rigify_layer, "name", text="")
+                row.prop(rigify_layer, "row", text="UI Row")
+                icon = 'RADIOBUT_ON' if rigify_layer.set else 'RADIOBUT_OFF'
+                row.prop(rigify_layer, "set", text="", toggle=True, icon=icon)
+                row.prop(rigify_layer, "group", text="Bone Group")
+            else:
+                row = col.row(align=True)
+
+                icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON'
+                row.prop(arm, "layers", index=i, text="", toggle=True, icon=icon)
+                # row.prop(arm, "layers", index=i, text="Layer %d" % (i + 1), toggle=True, icon=icon)
+                row1 = row.split(align=True).row(align=True)
+                row1.prop(rigify_layer, "name", text="")
+                row1.prop(rigify_layer, "row", text="UI Row")
+                row1.enabled = False
+                icon = 'RADIOBUT_ON' if rigify_layer.set else 'RADIOBUT_OFF'
+                row.prop(rigify_layer, "set", text="", toggle=True, icon=icon)
+                row.prop(rigify_layer, "group", text="Bone Group")
+            if rigify_layer.group == 0:
+                row.label(text='None')
+            else:
+                row.label(text=arm.rigify_colors[rigify_layer.group-1].name)
+
+        col = layout.column()
+        col.label(text="Reserved:")
+        # reserved_names = {28: 'Root', 29: 'DEF', 30: 'MCH', 31: 'ORG'}
+        reserved_names = {29: 'DEF', 30: 'MCH', 31: 'ORG'}
+        # for i in range(28, 32):
+        for i in range(29, 32):
+            row = col.row(align=True)
+            icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON'
+            row.prop(arm, "layers", index=i, text="", toggle=True, icon=icon)
+            row.label(text=reserved_names[i])
+
 
-            #split.prop(rigify_layer, "column", text="")
+class DATA_OT_rigify_add_bone_groups(bpy.types.Operator):
+    bl_idname = "armature.rigify_add_bone_groups"
+    bl_label = "Rigify Add Standard Bone Groups"
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+        armature = obj.data
+        if not hasattr(armature, 'rigify_colors'):
+            return {'FINISHED'}
+
+        groups = ['Face', 'Face Primary', 'Face Secondary', 'FK', 'IK', 'Tweaks', 'Torso', 'Upper Body', 'Upper Spine']
+        themes = {'Face': 'THEME11', 'Face Primary': 'THEME01', 'Face Secondary': 'THEME09',
+                  'FK': 'THEME04', 'IK': 'THEME01', 'Tweaks': 'THEME14',
+                  'Torso': 'THEME03', 'Upper Body': 'THEME09', 'Upper Spine': 'THEME02'}
+
+        for g in groups:
+            if g in armature.rigify_colors.keys():
+                continue
+            armature.rigify_colors.add()
+            armature.rigify_colors[-1].name = g
+            id = int(themes[g][-2:]) - 1
+            armature.rigify_colors[-1].normal = bpy.context.user_preferences.themes[0].bone_color_sets[id].normal
+            armature.rigify_colors[-1].select = bpy.context.user_preferences.themes[0].bone_color_sets[id].select
+            armature.rigify_colors[-1].active = bpy.context.user_preferences.themes[0].bone_color_sets[id].active
+
+        return {'FINISHED'}
+
+
+class DATA_OT_rigify_use_standard_colors(bpy.types.Operator):
+    bl_idname = "armature.rigify_use_standard_colors"
+    bl_label = "Rigify Get active/select colors from current theme"
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+        armature = obj.data
+        if not hasattr(armature, 'rigify_colors'):
+            return {'FINISHED'}
+
+        current_theme = bpy.context.user_preferences.themes.items()[0][0]
+        theme = bpy.context.user_preferences.themes[current_theme]
+
+        armature.rigify_selection_colors.select = theme.view_3d.bone_pose
+        armature.rigify_selection_colors.active = theme.view_3d.bone_pose_active
+
+        # for col in armature.rigify_colors:
+        #     col.select = theme.view_3d.bone_pose
+        #     col.active = theme.view_3d.bone_pose_active
+
+        return {'FINISHED'}
+
+
+class DATA_OT_rigify_apply_selection_colors(bpy.types.Operator):
+    bl_idname = "armature.rigify_apply_selection_colors"
+    bl_label = "Rigify Apply user defined active/select colors"
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+        armature = obj.data
+        if not hasattr(armature, 'rigify_colors'):
+            return {'FINISHED'}
+
+        #current_theme = bpy.context.user_preferences.themes.items()[0][0]
+        #theme = bpy.context.user_preferences.themes[current_theme]
+
+        for col in armature.rigify_colors:
+            col.select = armature.rigify_selection_colors.select
+            col.active = armature.rigify_selection_colors.active
+
+        return {'FINISHED'}
+
+
+class DATA_OT_rigify_bone_group_add(bpy.types.Operator):
+    bl_idname = "armature.rigify_bone_group_add"
+    bl_label = "Rigify Add Bone Group color set"
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+        armature = obj.data
+
+        if hasattr(armature, 'rigify_colors'):
+            armature.rigify_colors.add()
+            armature.rigify_colors[-1].name = unique_name(armature.rigify_colors, 'Group')
+
+            current_theme = bpy.context.user_preferences.themes.items()[0][0]
+            theme = bpy.context.user_preferences.themes[current_theme]
+
+            armature.rigify_colors[-1].normal = theme.view_3d.wire
+            armature.rigify_colors[-1].normal.hsv = theme.view_3d.wire.hsv
+            armature.rigify_colors[-1].select = theme.view_3d.bone_pose
+            armature.rigify_colors[-1].select.hsv = theme.view_3d.bone_pose.hsv
+            armature.rigify_colors[-1].active = theme.view_3d.bone_pose_active
+            armature.rigify_colors[-1].active.hsv = theme.view_3d.bone_pose_active.hsv
+
+        return {'FINISHED'}
+
+
+class DATA_OT_rigify_bone_group_add_theme(bpy.types.Operator):
+    bl_idname = "armature.rigify_bone_group_add_theme"
+    bl_label = "Rigify Add Bone Group color set from Theme"
+    bl_options = {"REGISTER", "UNDO"}
+
+    theme = bpy.props.EnumProperty(items=(('THEME01', 'THEME01', ''),
+                                          ('THEME02', 'THEME02', ''),
+                                          ('THEME03', 'THEME03', ''),
+                                          ('THEME04', 'THEME04', ''),
+                                          ('THEME05', 'THEME05', ''),
+                                          ('THEME06', 'THEME06', ''),
+                                          ('THEME07', 'THEME07', ''),
+                                          ('THEME08', 'THEME08', ''),
+                                          ('THEME09', 'THEME09', ''),
+                                          ('THEME10', 'THEME10', ''),
+                                          ('THEME11', 'THEME11', ''),
+                                          ('THEME12', 'THEME12', ''),
+                                          ('THEME13', 'THEME13', ''),
+                                          ('THEME14', 'THEME14', ''),
+                                          ('THEME15', 'THEME15', ''),
+                                          ('THEME16', 'THEME16', ''),
+                                          ('THEME17', 'THEME17', ''),
+                                          ('THEME18', 'THEME18', ''),
+                                          ('THEME19', 'THEME19', ''),
+                                          ('THEME20', 'THEME20', '')
+                                          ),
+                                   name='Theme')
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+        armature = obj.data
+
+        if hasattr(armature, 'rigify_colors'):
+
+            if self.theme in armature.rigify_colors.keys():
+                return {'FINISHED'}
+            armature.rigify_colors.add()
+            armature.rigify_colors[-1].name = self.theme
+
+            id = int(self.theme[-2:]) - 1
+
+            theme_color_set = bpy.context.user_preferences.themes[0].bone_color_sets[id]
+
+            armature.rigify_colors[-1].normal = theme_color_set.normal
+            armature.rigify_colors[-1].select = theme_color_set.select
+            armature.rigify_colors[-1].active = theme_color_set.active
+
+        return {'FINISHED'}
+
+
+class DATA_OT_rigify_bone_group_remove(bpy.types.Operator):
+    bl_idname = "armature.rigify_bone_group_remove"
+    bl_label = "Rigify Remove Bone Group color set"
+
+    idx = bpy.props.IntProperty()
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+        obj.data.rigify_colors.remove(self.idx)
+
+        # set layers references to 0
+        for l in obj.data.rigify_layers:
+            if l.group == self.idx + 1:
+                l.group = 0
+            elif l.group > self.idx + 1:
+                l.group -= 1
+
+        return {'FINISHED'}
+
+
+class DATA_OT_rigify_bone_group_remove_all(bpy.types.Operator):
+    bl_idname = "armature.rigify_bone_group_remove_all"
+    bl_label = "Rigify Remove All Bone Groups"
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def execute(self, context):
+        obj = context.object
+
+        for i, col in enumerate(obj.data.rigify_colors):
+            obj.data.rigify_colors.remove(0)
+            # set layers references to 0
+            for l in obj.data.rigify_layers:
+                if l.group == i + 1:
+                    l.group = 0
+
+        return {'FINISHED'}
+
+
+class DATA_UL_rigify_bone_groups(bpy.types.UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        row = layout.row(align=True)
+        row = row.split(percentage=0.1)
+        row.label(text=str(index+1))
+        row = row.split(percentage=0.7)
+        row.prop(item, "name", text='', emboss=False)
+        row = row.row(align=True)
+        icon = 'LOCKED' if item.standard_colors_lock else 'UNLOCKED'
+        #row.prop(item, "standard_colors_lock", text='', icon=icon)
+        row.prop(item, "normal", text='')
+        row2 = row.row(align=True)
+        row2.prop(item, "select", text='')
+        row2.prop(item, "active", text='')
+        #row2.enabled = not item.standard_colors_lock
+        row2.enabled = not bpy.context.object.data.rigify_colors_lock
+
+
+class DATA_PT_rigify_bone_groups_specials(bpy.types.Menu):
+    bl_label = 'Rigify Bone Groups Specials'
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator('armature.rigify_bone_group_remove_all')
+
+
+class DATA_PT_rigify_bone_groups(bpy.types.Panel):
+    bl_label = "Rigify Bone Groups"
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        return context.object.type == 'ARMATURE'
+
+    def draw(self, context):
+        obj = context.object
+        armature = obj.data
+        color_sets = obj.data.rigify_colors
+        idx = obj.data.rigify_colors_index
+
+        layout = self.layout
+        row = layout.row()
+        row.operator("armature.rigify_use_standard_colors", icon='FILE_REFRESH', text='')
+        row = row.row(align=True)
+        row.prop(armature.rigify_selection_colors, 'select', text='')
+        row.prop(armature.rigify_selection_colors, 'active', text='')
+        row = layout.row(align=True)
+        icon = 'LOCKED' if armature.rigify_colors_lock else 'UNLOCKED'
+        row.prop(armature, 'rigify_colors_lock', text = 'Unified select/active colors', icon=icon)
+        row.operator("armature.rigify_apply_selection_colors", icon='FILE_REFRESH', text='Apply')
+        row = layout.row()
+        row.template_list("DATA_UL_rigify_bone_groups", "", obj.data, "rigify_colors", obj.data, "rigify_colors_index")
+
+        col = row.column(align=True)
+        col.operator("armature.rigify_bone_group_add", icon='ZOOMIN', text="")
+        col.operator("armature.rigify_bone_group_remove", icon='ZOOMOUT', text="").idx = obj.data.rigify_colors_index
+        col.menu("DATA_PT_rigify_bone_groups_specials", icon='DOWNARROW_HLT', text="")
+        row = layout.row()
+        row.prop(armature, 'rigify_theme_to_add', text = 'Theme')
+        op = row.operator("armature.rigify_bone_group_add_theme", text="Add From Theme")
+        op.theme = armature.rigify_theme_to_add
+        row = layout.row()
+        row.operator("armature.rigify_add_bone_groups", text="Add Standard")
 
 
 class BONE_PT_rigify_buttons(bpy.types.Panel):
@@ -421,6 +733,17 @@ class EncodeWidget(bpy.types.Operator):
 #from bl_ui import space_info  # ensure the menu is loaded first
 
 def register():
+
+    bpy.utils.register_class(DATA_OT_rigify_add_bone_groups)
+    bpy.utils.register_class(DATA_OT_rigify_use_standard_colors)
+    bpy.utils.register_class(DATA_OT_rigify_apply_selection_colors)
+    bpy.utils.register_class(DATA_OT_rigify_bone_group_add)
+    bpy.utils.register_class(DATA_OT_rigify_bone_group_add_theme)
+    bpy.utils.register_class(DATA_OT_rigify_bone_group_remove)
+    bpy.utils.register_class(DATA_OT_rigify_bone_group_remove_all)
+    bpy.utils.register_class(DATA_UL_rigify_bone_groups)
+    bpy.utils.register_class(DATA_PT_rigify_bone_groups_specials)
+    bpy.utils.register_class(DATA_PT_rigify_bone_groups)
     bpy.utils.register_class(DATA_PT_rigify_layer_names)
     bpy.utils.register_class(DATA_PT_rigify_buttons)
     bpy.utils.register_class(BONE_PT_rigify_buttons)
@@ -435,6 +758,17 @@ def register():
 
 
 def unregister():
+
+    bpy.utils.unregister_class(DATA_OT_rigify_add_bone_groups)
+    bpy.utils.unregister_class(DATA_OT_rigify_use_standard_colors)
+    bpy.utils.unregister_class(DATA_OT_rigify_apply_selection_colors)
+    bpy.utils.unregister_class(DATA_OT_rigify_bone_group_add)
+    bpy.utils.unregister_class(DATA_OT_rigify_bone_group_add_theme)
+    bpy.utils.unregister_class(DATA_OT_rigify_bone_group_remove)
+    bpy.utils.unregister_class(DATA_OT_rigify_bone_group_remove_all)
+    bpy.utils.unregister_class(DATA_UL_rigify_bone_groups)
+    bpy.utils.unregister_class(DATA_PT_rigify_bone_groups_specials)
+    bpy.utils.unregister_class(DATA_PT_rigify_bone_groups)
     bpy.utils.unregister_class(DATA_PT_rigify_layer_names)
     bpy.utils.unregister_class(DATA_PT_rigify_buttons)
     bpy.utils.unregister_class(BONE_PT_rigify_buttons)
diff --git a/rigify/utils.py b/rigify/utils.py
index 0225a8461e3c04a6a22db645918f4facdea7b257..09f5ee9d03e10a8a3ec2ead5eff96c5bc4d5c2a2 100644
--- a/rigify/utils.py
+++ b/rigify/utils.py
@@ -24,6 +24,7 @@ import importlib
 import math
 import random
 import time
+import re
 from mathutils import Vector, Matrix
 from rna_prop_ui import rna_idprop_ui_prop_get
 
@@ -57,6 +58,23 @@ class MetarigError(Exception):
 #=======================================================================
 # Name manipulation
 #=======================================================================
+
+def strip_trailing_number(s):
+    m = re.search(r'\.(\d{3})$', s)
+    return s[0:-4] if m else s
+
+
+def unique_name(collection, base_name):
+    base_name = strip_trailing_number(base_name)
+    count = 1
+    name = base_name
+
+    while collection.get(name):
+        name = "%s.%03d" % (base_name, count)
+        count += 1
+    return name
+
+
 def org_name(name):
     """ Returns the name with ORG_PREFIX stripped from it.
     """