var
  uuid        = require("uuid"),
  bluebird    = require("bluebird"),
  taskLock    = require("../task/lock.js")
;

// @TODO - ***ensure that only the key holder may retrieve a locked task.***
// @TODO - ***ensure that only the key holder may update a locked task.***
// @TODO - implement a search for new ready tasks every tick.

function MemoryStore () {
  this.store  = {};
}
MemoryStore.prototype = {

  createTask: function (task) {
    if (task.id) {
      return bluebird.reject(new TypeError("InvalidTaskObject"));
    }
    task.id               = uuid.v4();
    this.store[task.id]   = task;

    return bluebird.resolve(task);
  },

  updateTask: function (task) {
    if(!task.id) {
      return bluebird.reject(new TypeError("InvalidTaskObject"));
    }
    this.store[task.id]   = task;

    return bluebird.resolve(task);
  },

  getTaskById: function (id) {
    if(!id) {
      return bluebird.reject(new TypeError("TaskIdNotProvided"));
    }
    return bluebird.resolve(this.store[id] || null);
  },

  lockTask: function (workerId, taskId, timeToLive) {
    if(!workerId) {
      return bluebird.reject(new TypeError('WorkerIdNotProvided'));
    }
    if(!taskId) {
      return bluebird.reject(new TypeError("TaskIdNotProvided"));
    }

    return this.getTaskById(taskId)

    .then(taskLock.acquire.bind(null, timeToLive, workerId))

    .then(this.updateTask.bind(this));

  },

  unlockTask: function (workerId, taskId) {
    if(!workerId) {
      return bluebird.reject(new TypeError('WorkerIdNotProvided'));
    }
    if(!taskId) {
      return bluebird.reject(new TypeError('TaskIdNotProvided'));
    }

    return this.getTaskById(taskId)

    .then(taskLock.release.bind(null, workerId))

    .then(this.updateTask.bind(this));
  }
};

module.exports  = MemoryStore;

@@ -403,16 +403,153 @@
 pe = %7B%0A%0A
+  /**%0A   * Store a represention of the given task object.%0A   * @param %7BTask%7D%0A   * @return %7BPromise::Task%7D%0A   * @throws %7BTypeError%7D%0A   */%0A
   create
@@ -778,16 +778,189 @@
 ;%0A  %7D,%0A%0A
+  /**%0A   * Update a task's stored representation.%0A   * --------------------------------------%0A   * @param %7BTask%7D%0A   * @return %7BPromise::Task%7D%0A   * @throws %7BTypeError%7D%0A   */%0A
   update
@@ -1156,181 +1156,747 @@
 %0A%0A  
-getTaskById: function (id) %7B%0A    if(!id) %7B%0A      return bluebird.reject(new TypeError(%22TaskIdNotProvided%22));%0A    %7D%0A    return bluebird.resolve(this.store%5Bid%5D %7C%7C null);%0A  %7D,%0A
+/**%0A   * Retrieve a task object by its assigned identifier.%0A   * --------------------------------------------------%0A   * - If the task is locked only allowed the lock holder to access the task.%0A   * @param %7Bstring%7D id%0A   * @return %7BPromise::Task%7D%0A   * @throws %7BTypeError%7D%0A   */%0A  getTaskById: function (id) %7B%0A    if(!id) %7B%0A      return bluebird.reject(new TypeError(%22TaskIdNotProvided%22));%0A    %7D%0A    return bluebird.resolve(this.store%5Bid%5D %7C%7C null);%0A  %7D,%0A%0A  /**%0A   * Attempt to acquire a lock for the given task ID.%0A   * ------------------------------------------------%0A   * @param %7Bstring%7D workerId%0A   * @param %7Bstring%7D taskId%0A   * @param %7Bint%7D timeToLive%0A   * @return %7BPromise::Task%7D%0A   * @throws %7BTypeError%7D%0A   * @throws %7BLockError%7D%0A   */
 %0A  l
@@ -2276,16 +2276,206 @@
 %0A%0A  %7D,%0A%0A
+  /**%0A   * Release a lock from a task.%0A   * ---------------------------%0A   * @param %7Bstring%7D workerId%0A   * @param %7Bstring%7D taskId%0A   * @return %7BPromise::Task%7D%0A   * @throws %7BTypeError%7D%0A   */%0A
   unlock

add documentation.