diff --git a/ui_layer_manager.py b/ui_layer_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a94c2cfdf9f8316184e555b4bb48d41ec4bb669
--- /dev/null
+++ b/ui_layer_manager.py
@@ -0,0 +1,557 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+#
+bl_info = {
+    "name": "Layer Management",
+    "author": "Alfonso Annarumma",
+    "version": (1, 5, 1),
+    "blender": (2, 70, 0),
+    "location": "View3D > Properties panel > Layer Management",
+    "warning": "",
+    "description": "Display and Edit Layer Name",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/layer_manager",
+    "category": "3D View",
+}
+
+import bpy
+from bpy.types import Menu, Panel, UIList, PropertyGroup
+from bpy.props import StringProperty, BoolProperty, IntProperty, CollectionProperty, BoolVectorProperty, PointerProperty
+from bpy.app.handlers import persistent
+
+EDIT_MODES = {'EDIT_MESH', 'EDIT_CURVE', 'EDIT_SURFACE', 'EDIT_METABALL', 'EDIT_TEXT', 'EDIT_ARMATURE'}
+
+
+class NamedLayer(PropertyGroup):
+    name = StringProperty(name="Layer Name")
+    use_lock = BoolProperty(name="Lock Layer", default=False)
+    use_object_select = BoolProperty(name="Object Select", default=True)
+    use_wire = BoolProperty(name="Wire Layer", default=False)
+
+
+class NamedLayers(PropertyGroup):
+    layers = CollectionProperty(type=NamedLayer)
+    use_hide_empty_layers = BoolProperty(name="Hide Empty Layer", default=False)
+    use_extra_options = BoolProperty(name="Show Extra Options", default=True)
+    use_layer_indices = BoolProperty(name="Show Layer Indices", default=False)
+    use_classic = BoolProperty(name="Classic", default=False, description="Use a classic layer selection visibility")
+
+    use_init = BoolProperty(default=True, options={'HIDDEN'})
+
+
+# Stupid, but only solution currently is to use a handler to init that layers collection...
+@persistent
+def check_init_data(scene):
+    namedlayers = scene.namedlayers
+    if namedlayers.use_init:
+        while namedlayers.layers:
+            namedlayers.layers.remove(0)
+        for i in range(20):
+            layer = namedlayers.layers.add()
+            layer.name = "Layer%.2d" % i
+        namedlayers.use_init = False
+
+
+class LayerGroup(PropertyGroup):
+    use_toggle = BoolProperty(name="", default=False)
+    use_wire = BoolProperty(name="", default=False)
+    use_lock = BoolProperty(name="", default=False)
+
+    layers = BoolVectorProperty(name="Layers", default=([False] * 20), size=20, subtype='LAYER')
+
+
+class SCENE_OT_namedlayer_group_add(bpy.types.Operator):
+    """Add and select a new layer group"""
+    bl_idname = "scene.namedlayer_group_add"
+    bl_label = "Add Layer Group"
+
+    layers = BoolVectorProperty(name="Layers", default=([False] * 20), size=20)
+
+    @classmethod
+    def poll(cls, context):
+        return bool(context.scene)
+
+    def execute(self, context):
+        scene = context.scene
+        layergroups = scene.layergroups
+        layers = self.layers
+
+        group_idx = len(layergroups)
+        layer_group = layergroups.add()
+        layer_group.name = "LayerGroup.%.3d" % group_idx
+        layer_group.layers = layers
+        scene.layergroups_index = group_idx
+
+        return {'FINISHED'}
+
+
+class SCENE_OT_namedlayer_group_remove(bpy.types.Operator):
+    """Remove selected layer group"""
+    bl_idname = "scene.namedlayer_group_remove"
+    bl_label = "Remove Layer Group"
+
+    group_idx = bpy.props.IntProperty()
+
+    @classmethod
+    def poll(cls, context):
+        return bool(context.scene)
+
+    def execute(self, context):
+        scene = context.scene
+        group_idx = self.group_idx
+
+        scene.layergroups.remove(group_idx)
+        if scene.layergroups_index > len(scene.layergroups) - 1:
+            scene.layergroups_index = len(scene.layergroups) - 1
+
+        return {'FINISHED'}
+
+
+class SCENE_OT_namedlayer_toggle_visibility(bpy.types.Operator):
+    """Show or hide given layer (shift to extend)"""
+    bl_idname = "scene.namedlayer_toggle_visibility"
+    bl_label = "Show/Hide Layer"
+
+    layer_idx = IntProperty()
+    group_idx = IntProperty()
+    use_spacecheck = BoolProperty()
+    extend = BoolProperty(options={'SKIP_SAVE'})
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene and (context.area.spaces.active.type == 'VIEW_3D')
+
+    def execute(self, context):
+        scene = context.scene
+        layer_cont = context.area.spaces.active if self.use_spacecheck else context.scene
+        layer_idx = self.layer_idx
+
+        if layer_idx == -1:
+            group_idx = self.group_idx
+            layergroups = scene.layergroups[group_idx]
+            group_layers = layergroups.layers
+            layers = layer_cont.layers
+
+            if layergroups.use_toggle:
+                layer_cont.layers = [not group_layer and layer for group_layer, layer in zip(group_layers, layers)]
+                layergroups.use_toggle = False
+            else:
+                layer_cont.layers = [group_layer or layer for group_layer, layer in zip(group_layers, layers)]
+                layergroups.use_toggle = True
+        else:
+            if self.extend:
+                layer_cont.layers[layer_idx] = not layer_cont.layers[layer_idx]
+            else:
+                layers = [False] * 20
+                layers[layer_idx] = True
+                layer_cont.layers = layers
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        self.extend = event.shift
+        return self.execute(context)
+
+
+class SCENE_OT_namedlayer_move_to_layer(bpy.types.Operator):
+    """Move selected objects to this Layer (shift to extend)"""
+    bl_idname = "scene.namedlayer_move_to_layer"
+    bl_label = "Move Objects To Layer"
+
+    layer_idx = IntProperty()
+    extend = BoolProperty(options={'SKIP_SAVE'})
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene
+
+    def execute(self, context):
+        layer_idx = self.layer_idx
+        scene = context.scene
+
+        # Cycle all objects in the layer
+        for obj in scene.objects:
+            if obj.select:
+                # If object is in at least one of the scene's visible layers...
+                if True in {ob_layer and sce_layer for ob_layer, sce_layer in zip(obj.layers, scene.layers)}:
+                    if self.extend:
+                        obj.layers[layer_idx] = not obj.layers[layer_idx]
+                    else:
+                        layer = [False] * 20
+                        layer[layer_idx] = True
+                        obj.layers = layer
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        self.extend = event.shift
+        return self.execute(context)
+
+
+class SCENE_OT_namedlayer_toggle_wire(bpy.types.Operator):
+    """Toggle all objects on this layer draw as wire"""
+    bl_idname = "scene.namedlayer_toggle_wire"
+    bl_label = "Toggle Objects Draw Wire"
+
+    layer_idx = IntProperty()
+    use_wire = BoolProperty()
+    group_idx = IntProperty()
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene and (context.area.spaces.active.type == 'VIEW_3D')
+
+    def execute(self, context):
+        scene = context.scene
+        layer_idx = self.layer_idx
+        use_wire = self.use_wire
+
+        view_3d = context.area.spaces.active
+
+        # Check if layer have some thing
+        if view_3d.layers_used[layer_idx] or layer_idx == -1:
+            display = 'WIRE' if use_wire else 'TEXTURED'
+            # Cycle all objects in the layer.
+            for obj in context.scene.objects:
+                if layer_idx == -1:
+                    group_idx = self.group_idx
+                    group_layers = scene.layergroups[group_idx].layers
+                    layers = obj.layers
+                    if True in {layer and group_layer for layer, group_layer in zip(layers, group_layers)}:
+                        obj.draw_type = display
+                        scene.layergroups[group_idx].use_wire = use_wire
+                else:
+                    if obj.layers[layer_idx]:
+                        obj.draw_type = display
+                        scene.namedlayers.layers[layer_idx].use_wire = use_wire
+
+        return {'FINISHED'}
+
+
+class SCENE_OT_namedlayer_lock_selected(bpy.types.Operator):
+    """Lock all selected objects on this layer"""
+    bl_idname = "scene.namedlayer_lock_selected"
+    bl_label = "Lock Objects"
+
+    layer_idx = IntProperty()
+    use_lock = BoolProperty()
+    group_idx = IntProperty()
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene and (context.area.spaces.active.type == 'VIEW_3D')
+
+    def execute(self, context):
+        scene = context.scene
+        view_3d = context.area.spaces.active
+        layer_idx = self.layer_idx
+        group_idx = self.group_idx
+        group_layers = scene.layergroups[group_idx].layers
+        use_lock = self.use_lock
+
+        # check if layer have some thing
+        if layer_idx == -1 or view_3d.layers_used[layer_idx]:
+            # Cycle all objects in the layer.
+            for obj in context.scene.objects:
+                if layer_idx == -1:
+                    layers = obj.layers
+                    if True in {layer and group_layer for layer, group_layer in zip(layers, group_layers)}:
+                        obj.hide_select = not use_lock
+                        obj.select = False
+                        scene.layergroups[group_idx].use_lock = not use_lock
+                else:
+                    if obj.layers[layer_idx]:
+                        obj.hide_select = not use_lock
+                        obj.select = False
+                        scene.namedlayers.layers[layer_idx].use_lock = not use_lock
+
+        return {'FINISHED'}
+
+
+class SCENE_OT_namedlayer_select_objects_by_layer(bpy.types.Operator):
+    """Select all the objects on this Layer (shift for multi selection, ctrl to make active the last selected object)"""
+    bl_idname = "scene.namedlayer_select_objects_by_layer"
+    bl_label = "Select Objects In Layer"
+
+    select_obj = BoolProperty()
+    layer_idx = IntProperty()
+
+    extend = BoolProperty(options={'SKIP_SAVE'})
+    active = BoolProperty(options={'SKIP_SAVE'})
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene and (context.area.spaces.active.type == 'VIEW_3D')
+
+    def execute(self, context):
+        scene = context.scene
+        view_3d = context.area.spaces.active
+        select_obj = self.select_obj
+        layer_idx = self.layer_idx
+
+        not_all_selected = 0
+        # check if layer have some thing
+        if view_3d.layers_used[layer_idx]:
+            objects = []
+            for obj in context.scene.objects:
+                if obj.layers[layer_idx]:
+                    objects.append(obj)
+                    not_all_selected -= 1
+                    if self.active:
+                        context.scene.objects.active = obj
+                    if obj.select:
+                        not_all_selected += 1
+            if not not_all_selected:
+                for obj in objects:
+                    obj.select = False
+            else:
+                bpy.ops.object.select_by_layer(extend=self.extend, layers=layer_idx + 1)
+
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        self.extend = event.shift
+        self.active = event.ctrl
+        return self.execute(context)
+
+
+class SCENE_OT_namedlayer_show_all(bpy.types.Operator):
+    """Show or hide all layers in the scene"""
+    bl_idname = "scene.namedlayer_show_all"
+    bl_label = "Select All Layers"
+
+    show = BoolProperty()
+
+    @classmethod
+    def poll(cls, context):
+        return context.scene and (context.area.spaces.active.type == 'VIEW_3D')
+
+    def execute(self, context):
+        scene = context.scene
+        view_3d = context.area.spaces.active
+        show = self.show
+        active_layer = scene.active_layer
+
+        # check for lock camera and layer is active
+        layer_cont = scene if view_3d.lock_camera_and_layers else view_3d
+
+        if show:
+            layer_cont.layers[:] = [True] * 20
+            # Restore active layer (stupid, but Scene.active_layer is readonly).
+            layer_cont.layers[active_layer] = False
+            layer_cont.layers[active_layer] = True
+        else:
+            layers = [False] * 20
+            # Keep selection of active layer
+            layers[active_layer] = True
+            layer_cont.layers[:] = layers
+
+        return {'FINISHED'}
+
+
+class SCENE_PT_namedlayer_layers(bpy.types.Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'TOOLS'
+    bl_label = "Layer Management"
+    bl_options = {'DEFAULT_CLOSED'}
+    bl_category = "Layer"
+
+    @classmethod
+    def poll(self, context):
+        return ((getattr(context, "mode", 'EDIT_MESH') not in EDIT_MODES) and
+                (context.area.spaces.active.type == 'VIEW_3D'))
+
+    def draw(self, context):
+        scene = context.scene
+        view_3d = context.area.spaces.active
+        actob = context.object
+        namedlayers = scene.namedlayers
+        use_extra = namedlayers.use_extra_options
+        use_hide = namedlayers.use_hide_empty_layers
+        use_indices = namedlayers.use_layer_indices
+        use_classic = namedlayers.use_classic
+
+        # Check for lock camera and layer is active
+        if view_3d.lock_camera_and_layers:
+            layer_cont = scene
+            use_spacecheck = False
+        else:
+            layer_cont = view_3d
+            use_spacecheck = True
+
+        layout = self.layout
+        row = layout.row()
+        col = row.column()
+        col.prop(view_3d, "lock_camera_and_layers", text="")
+        # Check if there is a layer off
+        show = (False in {layer for layer in layer_cont.layers})
+        icon = 'RESTRICT_VIEW_ON' if show else 'RESTRICT_VIEW_OFF'
+        col.operator("scene.namedlayer_show_all", emboss=False, icon=icon, text="").show = show
+
+        col = row.column()
+        col.prop(namedlayers, "use_classic")
+        col.prop(namedlayers, "use_extra_options", text="Options")
+
+        col = row.column()
+        col.prop(namedlayers, "use_layer_indices", text="Indices")
+        col.prop(namedlayers, "use_hide_empty_layers", text="Hide Empty")
+
+        col = layout.column()
+        for layer_idx in range(20):
+            namedlayer = namedlayers.layers[layer_idx]
+            is_layer_used = view_3d.layers_used[layer_idx]
+
+            if (use_hide and not is_layer_used):
+                # Hide unused layers and this one is unused, skip.
+                continue
+
+            row = col.row(align=True)
+
+            # layer index
+            if use_indices:
+                row.label(text="%.2d." % (layer_idx + 1))
+
+            # visualization
+            icon = 'RESTRICT_VIEW_OFF' if layer_cont.layers[layer_idx] else 'RESTRICT_VIEW_ON'
+            if use_classic:
+                op = row.operator("scene.namedlayer_toggle_visibility", text="", icon=icon, emboss=True)
+                op.layer_idx = layer_idx
+                op.use_spacecheck = use_spacecheck
+            else:
+                row.prop(layer_cont, "layers", index=layer_idx, emboss=True, icon=icon, toggle=True, text="")
+
+            # Name (use special icon for active layer).
+            icon = 'FILE_TICK' if (getattr(layer_cont, "active_layer", -1) == layer_idx) else 'NONE'
+            row.prop(namedlayer, "name", text="", icon=icon)
+
+            if use_extra:
+                use_lock = namedlayer.use_lock
+
+                # Select by type operator
+                sub = row.column(align=True)
+                sub.enabled = not use_lock
+                sub.operator("scene.namedlayer_select_objects_by_layer", icon='RESTRICT_SELECT_OFF',
+                             text="", emboss=True).layer_idx = layer_idx
+
+                # Lock operator
+                icon = 'LOCKED' if use_lock else 'UNLOCKED'
+                op = row.operator("scene.namedlayer_lock_selected", text="", emboss=True, icon=icon)
+                op.layer_idx = layer_idx
+                op.use_lock = use_lock
+
+                # Merge layer
+                # check if layer has something
+                has_active = (actob and actob.layers[layer_idx])
+                icon = ('LAYER_ACTIVE' if has_active else 'LAYER_USED') if is_layer_used else 'RADIOBUT_OFF'
+                row.operator("scene.namedlayer_move_to_layer", text="", emboss=True, icon=icon).layer_idx = layer_idx
+
+                # Wire view
+                use_wire = namedlayer.use_wire
+                icon = 'WIRE' if use_wire else 'POTATO'
+                op = row.operator("scene.namedlayer_toggle_wire", text="", emboss=True, icon=icon)
+                op.layer_idx = layer_idx
+                op.use_wire = not use_wire
+
+        if len(scene.objects) == 0:
+            layout.label(text="No objects in scene")
+
+
+class SCENE_UL_namedlayer_groups(UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        layer_group = item
+
+        # check for lock camera and layer is active
+        view_3d = context.area.spaces.active  # Ensured it is a 'VIEW_3D' in panel's poll(), weak... :/
+        use_spacecheck = False if view_3d.lock_camera_and_layers else True
+
+        if self.layout_type in {'DEFAULT', 'COMPACT'}:
+            layout.prop(layer_group, "name", text="", emboss=False)
+            # lock operator
+            use_lock = layer_group.use_lock
+            icon = 'LOCKED' if use_lock else 'UNLOCKED'
+            op = layout.operator("scene.namedlayer_lock_selected", text="", emboss=False, icon=icon)
+            op.use_lock = use_lock
+            op.group_idx = index
+            op.layer_idx = -1
+
+            # view operator
+            icon = 'RESTRICT_VIEW_OFF' if layer_group.use_toggle else 'RESTRICT_VIEW_ON'
+            op = layout.operator("scene.namedlayer_toggle_visibility", text="", emboss=False, icon=icon)
+            op.use_spacecheck = use_spacecheck
+            op.group_idx = index
+            op.layer_idx = -1
+
+            # wire operator
+            use_wire = layer_group.use_wire
+            icon = 'WIRE' if use_wire else 'POTATO'
+            op = layout.operator("scene.namedlayer_toggle_wire", text="", emboss=False, icon=icon)
+            op.use_wire = not use_wire
+            op.group_idx = index
+            op.layer_idx = -1
+
+        elif self.layout_type in {'GRID'}:
+            layout.alignment = 'CENTER'
+
+
+class SCENE_PT_namedlayer_groups(bpy.types.Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'TOOLS'
+    bl_category = "Layer"
+    bl_label = "Layer Groups"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(self, context):
+        return ((getattr(context, "mode", 'EDIT_MESH') not in EDIT_MODES) and
+                (context.area.spaces.active.type == 'VIEW_3D'))
+
+    def draw(self, context):
+        scene = context.scene
+        group_idx = scene.layergroups_index
+
+        layout = self.layout
+        row = layout.row()
+        row.template_list("SCENE_UL_namedlayer_groups", "", scene, "layergroups", scene, "layergroups_index")
+
+        col = row.column(align=True)
+        col.operator("scene.namedlayer_group_add", icon='ZOOMIN', text="").layers = scene.layers
+        col.operator("scene.namedlayer_group_remove", icon='ZOOMOUT', text="").group_idx = group_idx
+
+        if bool(scene.layergroups):
+            layout.prop(scene.layergroups[group_idx], "layers", text="", toggle=True)
+            layout.prop(scene.layergroups[group_idx], "name", text="Name:")
+
+
+def register():
+    bpy.utils.register_module(__name__)
+    bpy.types.Scene.layergroups = CollectionProperty(type=LayerGroup)
+    # Unused, but this is needed for the TemplateList to work...
+    bpy.types.Scene.layergroups_index = IntProperty(default=-1)
+    bpy.types.Scene.namedlayers = PointerProperty(type=NamedLayers)
+    bpy.app.handlers.scene_update_post.append(check_init_data)
+
+
+def unregister():
+    bpy.app.handlers.scene_update_post.remove(check_init_data)
+    del bpy.types.Scene.layergroups
+    del bpy.types.Scene.layergroups_index
+    del bpy.types.Scene.namedlayers
+    bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+    register()