docs: function propagateMetaDefinitionRename(core, node, parameters, callback) {
          var deferred = Q.defer(),
              nodePath = core.getPath(node),
              visitFn;
  
          function visitForAttribute(visited, next) {
              if (parameters.excludeOriginNode === true && core.getPath(visited) === nodePath) {
                  next(null);
                  return;
              }
  
              if (core.getValidAttributeNames(visited).indexOf(parameters.newName) === -1 ||
                  core.getOwnAttributeNames(visited).indexOf(parameters.oldName) === -1) {
                  next(null);
                  return;
              }
  
              if (core.getPath(core.getAttributeDefinitionOwner(visited, parameters.newName)) === nodePath) {
                  core.renameAttribute(visited, parameters.oldName, parameters.newName);
              }
              next(null);
          }
  
          function visitForPointer(visited, next) {
              var definitionInfo,
                  deferred = Q.defer();
  
              if (parameters.excludeOriginNode === true && core.getPath(visited) === nodePath) {
                  return Q.resolve(null).nodeify(next);
              }
  
              if (core.getValidPointerNames(visited).indexOf(parameters.newName) === -1 ||
                  core.getOwnPointerPath(visited, parameters.oldName) === undefined) {
                  return Q.resolve(null).nodeify(next);
              }
  
              core.loadPointer(visited, parameters.oldName)
                  .then(function (target) {
                      if (target !== null) {
                          definitionInfo = core.getPointerDefinitionInfo(visited, parameters.newName, target);
  
                          if (definitionInfo.ownerPath === nodePath &&
                              definitionInfo.targetPath === parameters.targetPath) {
                              core.renamePointer(visited, parameters.oldName, parameters.newName);
                          }
                      } else if (core.getPath(visited) === nodePath) {
                          core.renamePointer(visited, parameters.oldName, parameters.newName);
                      }
                      deferred.resolve(null);
                  })
                  .catch(deferred.reject);
  
              return deferred.promise.nodeify(next);
          }
  
          function visitForSet(visited, next) {
              var definitionInfo,
                  deferred = Q.defer();
  
              if (parameters.excludeOriginNode === true && core.getPath(visited) === nodePath) {
                  return Q.resolve(null).nodeify(next);
              }
  
              if (core.getValidSetNames(visited).indexOf(parameters.newName) === -1 ||
                  core.getOwnSetNames(visited, parameters.oldName).indexOf(parameters.oldName) === -1) {
                  return Q.resolve(null).nodeify(next);
              }
  
              core.loadOwnMembers(visited, parameters.oldName)
                  .then(function (members) {
                      var i,
                          ownMemberPaths = core.getOwnMemberPaths(visited, parameters.oldName);
  
                      for (i = 0; i < members.length; i += 1) {
                          if (ownMemberPaths.indexOf(core.getPath(members[i])) !== -1) {
                              definitionInfo = core.getSetDefinitionInfo(visited, parameters.newName, members[i]);
                              if (definitionInfo.ownerPath === nodePath &&
                                  definitionInfo.targetPath === parameters.targetPath) {
                                  core.moveMember(visited, core.getPath(members[i]),
                                      parameters.oldName, parameters.newName);
                              }
                          }
                      }
  
                      if (members.length === 0) {
                          core.renameSet(visited, parameters.oldName, parameters.newName);
                      }
  
                      deferred.resolve(null);
                      return;
                  })
                  .catch(deferred.reject);
  
              return deferred.promise.nodeify(next);
          }
  
          function visitForAspect(visited, next) {
              var definitionInfo,
                  deferred = Q.defer();
  
              if (parameters.excludeOriginNode === true && core.getPath(visited) === nodePath) {
                  next(null);
                  return;
              }
  
              if (core.getValidAspectNames(visited).indexOf(parameters.newName) === -1 ||
                  core.getOwnSetNames(visited).indexOf(parameters.oldName) === -1) {
                  next(null);
                  return;
              }
  
              core.loadMembers(visited, parameters.oldName)
                  .then(function (members) {
                      var i;
  
                      for (i = 0; i < members.length; i += 1) {
                          definitionInfo = core.getAspectDefinitionInfo(visited, parameters.newName, members[i]);
                          if (definitionInfo.ownerPath === nodePath &&
                              definitionInfo.targetPath === parameters.targetPath) {
                              core.moveMember(visited, core.getPath(members[i]), parameters.oldName, parameters.newName);
                          }
                      }
                      deferred.resolve(null);
                      return;
                  })
                  .catch(deferred.reject);
  
              return deferred.promise.nodeify(next);
          }
  
          switch (parameters.type) {
              case 'attribute':
                  visitFn = visitForAttribute;
                  break;
              case 'pointer':
                  visitFn = visitForPointer;
                  break;
              case 'set':
                  visitFn = visitForSet;
                  break;
              case 'aspect':
                  visitFn = visitForAspect;
                  break;
              default:
                  return Q.reject(new Error('Invalid parameter misses a correct type for renaming.')).nodeify(callback);
          }
  
          core.traverse(core.getRoot(node), {excludeRoot: true, stopOnError: true}, visitFn)
              .then(deferred.resolve)
              .catch(deferred.reject);
  
          return deferred.promise.nodeify(callback);
      }