moveNode = function (oldNode) {
          var newId = nodeIds.changeLetter(oldNode.id, newLetter);
          var newNode = oldNode.clone(newId);
          var affectedWidgetsBySourceChange = widgetDefinitionsCollection.where({ source: oldNode.id });

          analysisDefinitionNodesCollection.invoke('changeSourceIds', oldNode.id, newId);

          _.each(affectedWidgetsBySourceChange, function (m) {
            // Store attrs from affected widget for creating a new
            // instance when layer is created
            affectedWidgetAttrsBySourceChange.push(
              _.extend(
                _.omit(m.toJSON(), 'id', 'layer_id', 'source', 'order'),
                {
                  avoidNotification: true,
                  source: {
                    id: newId
                  }
                }
              )
            );

            // Destroy widgets pointing to that source until new layer is created
            m.attributes.avoidNotification = true;
            m.destroy();
          });

          return newNode;
        }
A layer for an existing node have different side-effects depending on the context in which the node exists.
@param {string} nodeid
@param {string} letter of the layer where the node change comes
@param {object} cfg
 @param {number} cfg.at