diff --git a/src/item/Item.js b/src/item/Item.js
index 299c13cb..fd6c844a 100644
--- a/src/item/Item.js
+++ b/src/item/Item.js
@@ -105,10 +105,9 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
         // is false, or if the props are setting a different parent anyway.
         if (internal || hasProps && props.insert === false) {
             this._setProject(project);
-        } else if (hasProps && props.parent) {
-            props.parent.addChild(this);
         } else {
-            this._addToProject(project);
+            (hasProps && props.parent || project)
+                    ._insertItem(undefined, this, true, true);
         }
         // Filter out Item.NO_INSERT before _set(), for performance reasons.
         if (hasProps && props !== Item.NO_INSERT) {
@@ -122,16 +121,6 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
         return hasProps;
     },
 
-    /*
-     * Private helper used in the constructor function to add the created item
-     * to the project scene graph. Overridden in Layer.
-     */
-    _addToProject: function(project) {
-        // Create a new layer if there is no active one. This will
-        // automatically make it the new activeLayer.
-        (project._activeLayer || new Layer()).addChild(this);
-    },
-
     _events: Base.each(['onMouseDown', 'onMouseUp', 'onMouseDrag', 'onClick',
             'onDoubleClick', 'onMouseMove', 'onMouseEnter', 'onMouseLeave'],
         function(name) {
@@ -1540,20 +1529,6 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
             this.setName(name);
     },
 
-    /**
-     * When passed a project, copies the item to the project,
-     * or duplicates it within the same project. When passed an item,
-     * copies the item into the specified item.
-     *
-     * @param {Project|Layer|Group|CompoundPath} owner the item or project to
-     * copy the item to
-     * @return {Item} the new copy of the item
-     */
-    copyTo: function(owner) {
-        // Pass false fo insert, since we're inserting at a specific location.
-        return owner.addChild(this.clone(false));
-    },
-
     /**
      * Rasterizes the item into a newly created Raster object. The item itself
      * is not removed after rasterization.
@@ -2257,12 +2232,9 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
         return items;
     },
 
-    // Private helper for #insertAbove() / #insertBelow()
-    _insertSibling: function(index, item, _preserve) {
-        return this._parent
-                ? this._parent.insertChild(index, item, _preserve)
-                : null;
-    },
+    // Internal alias, so both Project and Item can be used in #copyTo(), and
+    // through _getOwner() in the various Item#insert*() methods.
+    _insertItem: '#insertChild',
 
     /**
      * Inserts this item above the specified item.
@@ -2271,7 +2243,9 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
      * @return {Item} the inserted item, or `null` if inserting was not possible
      */
     insertAbove: function(item, _preserve) {
-        return item._insertSibling(item._index + 1, this, _preserve);
+        var owner = item && item._getOwner();
+        return owner ? owner._insertItem(item._index + 1, this, _preserve)
+                : null;
     },
 
     /**
@@ -2281,7 +2255,8 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
      * @return {Item} the inserted item, or `null` if inserting was not possible
      */
     insertBelow: function(item, _preserve) {
-        return item._insertSibling(item._index, this, _preserve);
+        var owner = item && item._getOwner();
+        return owner ? owner._insertItem(item._index, this, _preserve) : null;
     },
 
     /**
@@ -2289,7 +2264,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
      */
     sendToBack: function() {
         var owner = this._getOwner();
-        return owner ? owner.insertChild(0, this) : null;
+        return owner ? owner._insertItem(0, this) : null;
     },
 
     /**
@@ -2297,7 +2272,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
      */
     bringToFront: function() {
         var owner = this._getOwner();
-        return owner ? owner.addChild(this) : null;
+        return owner ? owner._insertItem(undefined, this) : null;
     },
 
     /**
@@ -2343,6 +2318,20 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
      */
     moveBelow: '#insertBelow',
 
+    /**
+     * When passed a project, copies the item to the project,
+     * or duplicates it within the same project. When passed an item,
+     * copies the item into the specified item.
+     *
+     * @param {Project|Layer|Group|CompoundPath} owner the item or project to
+     * copy the item to
+     * @return {Item} the new copy of the item
+     */
+    copyTo: function(owner) {
+        // Pass false for insert, since we're inserting at a specific location.
+        return owner._insertItem(undefined, this.clone(false));
+    },
+
     /**
      * If this is a group, layer or compound-path with only one child-item,
      * the child-item is moved outside and the parent is erased. Otherwise, the
diff --git a/src/item/Layer.js b/src/item/Layer.js
index a830fe0b..0f69f7a7 100644
--- a/src/item/Layer.js
+++ b/src/item/Layer.js
@@ -66,16 +66,6 @@ var Layer = Group.extend(/** @lends Layer# */{
         Group.apply(this, arguments);
     },
 
-    /**
-     * Private helper used in the constructor function to add the newly created
-     * item to the project scene graph.
-     */
-    _addToProject: function(project) {
-        project.addChild(this);
-        // When inserted, also activate the layer by default.
-        this.activate();
-    },
-
     /**
      * Private helper to return the owner, either the parent, or the project
      * for top-level layers.
@@ -132,15 +122,6 @@ var Layer = Group.extend(/** @lends Layer# */{
         this._project._activeLayer = this;
     },
 
-    // Private helper for #insertAbove() / #insertBelow()
-    _insertSibling: function _insertSibling(index, item, _preserve) {
-        // If the item is a layer and contained within Project#layers, use
-        // our own version of move().
-        return !this._parent
-                ? this._project.insertChild(index, item, _preserve)
-                : _insertSibling.base.call(this, index, item, _preserve);
-    },
-
     _hitTestSelf: function() {
         return null;
     }
diff --git a/src/project/Project.js b/src/project/Project.js
index 06d654a5..940109e7 100644
--- a/src/project/Project.js
+++ b/src/project/Project.js
@@ -243,10 +243,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
     },
     // TODO: Implement setSelectedItems?
 
-    // Project#insertChild() and #addChild() are helper functions called in
-    // Item#copyTo(), Layer#initialize(), Layer#_insertSibling()
-    // They are called the same as the functions on Item so duck-typing works.
-    insertChild: function(index, item, _preserve) {
+    insertLayer: function(index, item) {
         if (item instanceof Layer) {
             item._remove(false, true);
             Base.splice(this._children, [item], index, 0);
@@ -258,22 +255,30 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
             // Also activate this layer if there was none before
             if (!this._activeLayer)
                 this._activeLayer = item;
-        } else if (item instanceof Item) {
-            // Anything else than layers needs to be added to a layer first
-            (this._activeLayer
-                // NOTE: If there is no layer and this project is not the active
-                // one, passing insert: false and calling addChild on the
-                // project will handle it correctly.
-                || this.insertChild(index, new Layer(Item.NO_INSERT)))
-                    .insertChild(index, item, _preserve);
         } else {
             item = null;
         }
         return item;
     },
 
-    addChild: function(item, _preserve) {
-        return this.insertChild(undefined, item, _preserve);
+    addLayer: function(item) {
+        return this.insertLayer(undefined, item);
+    },
+
+    // Project#_insertItem() and Item#_insertItem() are helper functions called
+    // in Item#copyTo(), and through _getOwner() in the various Item#insert*()
+    // methods. They are called the same to facilitate so duck-typing.
+    _insertItem: function(index, item, _preserve, _created) {
+        item = this.insertLayer(index, item)
+                // Anything else than layers needs to be added to a layer first.
+                // If none exists yet, create one now, then add the item to it.
+                || (this._activeLayer || this._insertItem(undefined,
+                        new Layer(Item.NO_INSERT), true, true))
+                        .insertChild(index, item, _preserve);
+        // If a layer was newly created, also activate it.
+        if (_created && item.activate)
+            item.activate();
+        return item;
     },
 
     _updateSelection: function(item) {