code: function(jobid, config) {
    if(!jobid || !config || !config.jobs || !config.dependencies) {
      throw Error('invalid job config');
    }
    this.id = jobid;
    this.name = config.name || jobid;
    this.description = config.description || '';
    this.dag = new dag.DAG(config.dependencies);
    this.results = {};
    this.tasksConfig = {};
    var self = this;
    // if there are jobs that are without
    // any dependencies, they can be picked up
    // first
    var nodeps=_.difference(_.keys(config.jobs), self.dag.tasks);
    self.dag.tasks = _.union(nodeps, self.dag.tasks);
    _.each(self.dag.tasks, function(tid) { 
      if(!config.jobs.hasOwnProperty(tid)) {
        throw Error('invalid task configuration:'+tid);
      }
      self.tasksConfig[tid]={
        meta:new task.Task(jobid, tid, config.jobs[tid]),
        instances: 1
      };
    });
    self.outstandingTasks = 0;
    winston.info(_pkgname + 'new job [' + jobid + '] with tasks:'+self.dag.tasks);
  }
docs: Job - Collection of 'Task's with dependencies  JobList - list of Jobs with their definitions  Datastructure keys: - job (job identifier) others: - name - description - dag     - DAG which captures the dependencies & ordered tasks - q       - tasks that are ready in the order they should be run - results - result of tasks - index   - current task index  @todo - check in config for minimum attributes