function planner(origin, dest, opts)  {

  var tasks   = new TaskPlanner();
  var cmds    = generateCommands(origin, dest);
  var state   = _.cloneDeep(origin);
  var result;

  opts = xtend(defaults, opts);

  assert(opts.mode === 'quick' || opts.mode === 'safe', 'unknown mode');

  tasks.addTask({ cmd: 'nop' }, {});
  generateDetachTasks(tasks, origin, opts);
  generateDetachTasks(tasks, dest, opts); // needed because of safe mode
  generateConfigureTasks(tasks, origin, dest, opts);

  _.forIn(state.topology.containers, function(container) {
    container.running = true;
    container.started = true;
    container.added = true;
  });

  _.forIn(dest.topology.containers, function(container) {
    var containers = state.topology.containers;

    if (!containers[container.id]) {
      containers[container.id] = {
        id: container.id,
        containedBy: container.containedBy,
        running: false,
        started: false,
        added: false
      };
    }
  });

  result = cmds.reduce(function(acc, cmd) {
    var plan = tasks.plan(state, cmd);
    if (!plan) {
      throw new Error('unable to generate ' + cmd.cmd + ' for id ' + cmd.id);
    }
    return acc.concat(plan);
  }, []).filter(function(cmd) {
    return cmd && cmd.cmd !== 'nop';
  });

  if (!opts.noLinkUnlinkRemove) {
    result = linkFilter(result);
  }

  return result;
}
function planner(origin, dest, opts)  {

  var tasks   = new TaskPlanner();
  var cmds    = generateCommands(origin, dest);
  var state   = _.cloneDeep(origin);
  var result;

  opts = xtend(defaults, opts);

  assert(opts.mode === 'quick' || opts.mode === 'safe', 'unknown mode');

  tasks.addTask({ cmd: 'nop' }, {});
  generateDetachTasks(tasks, origin, opts);
  generateDetachTasks(tasks, dest, opts); // needed because of safe mode
  generateConfigureTasks(tasks, origin, dest, opts);

  _.forIn(state.topology.containers, function(container) {
    container.running = true;
    container.started = true;
    container.added = true;
  });

  _.forIn(dest.topology.containers, function(container) {
    var containers = state.topology.containers;

    if (!containers[container.id]) {
      containers[container.id] = {
        id: container.id,
        containedBy: container.containedBy,
        running: false,
        started: false,
        added: false
      };
    }
  });

  result = cmds.reduce(function(acc, cmd) {
    var plan = tasks.plan(state, cmd);
    if (!plan) {
      throw new Error('unable to generate ' + cmd.cmd + ' for id ' + cmd.id);
    }
    return acc.concat(plan);
  }, []).filter(function(cmd) {
    return cmd && cmd.cmd !== 'nop';
  });

  if (!opts.noLinkUnlinkRemove) {
    result = linkFilter(result);
  }

  return result;
}
function planner ( origin , dest , opts ) { var tasks = new TaskPlanner ( ) ; var cmds = generateCommands ( origin , dest ) ; var state = _ . cloneDeep ( origin ) ; var result ; opts = xtend ( defaults , opts ) ; assert ( opts . mode === 'quick' || opts . mode === 'safe' , 'unknown mode' ) ; tasks . addTask ( { cmd : 'nop' } , { } ) ; generateDetachTasks ( tasks , origin , opts ) ; generateDetachTasks ( tasks , dest , opts ) ; // needed because of safe mode generateConfigureTasks ( tasks , origin , dest , opts ) ; _ . forIn ( state . topology . containers , function ( container ) { container . running = true ; container . started = true ; container . added = true ; } ) ; _ . forIn ( dest . topology . containers , function ( container ) { var containers = state . topology . containers ; if ( ! containers [ container . id ] ) { containers [ container . id ] = { id : container . id , containedBy : container . containedBy , running : false , started : false , added : false } ; } } ) ; result = cmds . reduce ( function ( acc , cmd ) { var plan = tasks . plan ( state , cmd ) ; if ( ! plan ) { throw new Error ( 'unable to generate ' + cmd . cmd + ' for id ' + cmd . id ) ; } return acc . concat ( plan ) ; } , [ ] ) . filter ( function ( cmd ) { return cmd && cmd . cmd !== 'nop' ; } ) ; if ( ! opts . noLinkUnlinkRemove ) { result = linkFilter ( result ) ; } return result ; }
Creates a new planner

@param {object} origin - The origin system definition
@param {object} dest - The destination system definition
@param {object} opts - The options
Creates a new planner