// check if the redis native extension is available
//if (typeof redis !== "undefined" || typeof redis.RedisAccess !== "undefined") {

redis.RedisDocStore = function (settings) {

  // reference to this for use within instance methods
  var self = this;

  this.redis = redis.RedisAccess.Create(0);

  // default settings for redis db
  var host = "127.0.0.1";
  var port = 6379;
  var scope = "substance";

  // use the settings object to override the default settings
  if (arguments.length == 1) {
    if (typeof settings.host != "undefined") {
      host = settings.host;
    }
    if (typeof settings.port != "undefined") {
      port = settings.port;
    }
    if (typeof settings.scope != "undefined") {
      scope = settings.scope;
    }
  }

  this.redis.setHost(host);
  this.redis.setPort(port);
  this.redis.connect();

  // the scope is useful to keep parts of the redis db separated
  // e.g. tests would use its own, or one could separate user spaces
  this.redis.setScope(scope);

  /**
   *  Checks if a document exists
   *  @param id the document's id
   *  @param cb callback
   */
  this.exists = function (id, cb) {
    var result = self.redis.exists(id);

    if(typeof cb !== "undefined")
      cb({err: 0, result: result});

    return result;
  };

  /**
   * Creates a new document with the provided id
   * @param cb callback
   */
  this.create = function (id, cb) {

    if(self.exists(id, cb) && typeof cb !== "undefined") {
      cb({err: -1, msg: "Document already exists."});
    }

    // TODO: more initial fields?
    // initial id field
    self.redis.set(id, {"id": id});
    // TODO create initial list for commits

    if (typeof cb !== "undefined")
      cb({err: 0});

    return true;
  };

  /**
   *  Deletes a document
   *  @param cb callback
   */
  this.delete = function (id, cb) {
    self.redis.remove(id);

    if (arguments.length == 2)
      cb({err: 0});

    return true;
  }

  /**
   *  Stores a sequence of commits for a given document id.
   *
   *  @param newCommits an array of commit objects
   *  @param cb callback
   */
  this.update = function(id, newCommits, cb) {
    var commits = self.redis.asList(id + ":commits");

    var lastSha = undefined;
    if(commits.size() > 0)
      lastSha = commits.get();

    self.redis.beginTransaction();
    for(var idx=0; idx<newCommits.length; idx++) {

      // commit must be in proper order
      if (typeof lastSha !== undefined && newCommits[idx].parent != lastSha) {
        self.redis.cancelTransaction();
	var err = {err: -1, msg: "Invalid commit chain."};
        // TODO: maybe give more details about the problem
	if (typeof cb !== "undefined")
	  cb(err);
	else
	  console.log(err.msg);
        return false;
      }

      // note: these commands will be executed when executeTransaction is called
      //       if something is wrong, e.g., invalid sha sequence, then the transaction is cancelled.
      commits.add(newCommits[idx].sha);

      // store the commit's data into an own field
      self.redis.set(id + ":commits:" + newCommits[idx].sha, newCommits[idx]);

      lastSha = newCommits[idx].sha;
    }

    self.redis.executeTransaction();

    if (typeof cb !== "undefined")
      cb({err: 0});
    else
      return true;
  };

  /**
   * Retrieves a document
   *
   * @param id the document's id
   * @param cb callback
   */
  this.get = function(id, cb) {

    if(!self.exists(id) && typeof cb !== "undefined") {
      cb({err: -1, msg: "Document does not exist.", doc: undefined});
      return undefined;
    }

    var doc = self.redis.getJSON(id);
    doc.commits = {};

    var commits = self.redis.asList(id + ":commits");
    var shas = commits.asArray();
    for (var idx=0; idx<shas.length; ++idx) {
      var commit = self.redis.getJSON( id + ":commits:" + shas[idx]);
      doc.commits[shas[idx]] = commit;
    }

    if(!self.exists(id, cb) && typeof cb !== "undefined")
      cb({err: 0, doc: doc});

    return doc;
  };
};

//}

@@ -991,16 +991,82 @@
 cope);%0A%0A
+  var documentId = function(id) %7B%0A    return %22document:%22+id;%0A  %7D%0A%0A
   /**%0A  
@@ -1233,18 +1233,30 @@
 .exists(
-i
 d
+ocumentId(id)
 );%0A%0A    
@@ -1480,34 +1480,46 @@
  if(self.exists(
-i
 d
+ocumentId(id)
 , cb) && typeof 
@@ -1939,18 +1939,30 @@
 .remove(
-i
 d
+ocumentId(id)
 );%0A%0A    
@@ -2223,32 +2223,82 @@
 wCommits, cb) %7B%0A
+    var commitsKey = documentId(id) + %22:commits%22;%0A
     var commits 
@@ -2317,31 +2317,26 @@
 .asList(
-id + %22:
 commits
-%22
+Key
 );%0A%0A    
@@ -2665,17 +2665,24 @@
 tion();%0A
-%09
+        
 var err 
@@ -2783,17 +2783,24 @@
 problem%0A
-%09
+        
 if (type
@@ -2822,17 +2822,24 @@
 fined%22)%0A
-%09
+        
   cb(err
@@ -2845,15 +2845,29 @@
 r);%0A
-%09else%0A%09
+        else%0A        
   co
@@ -3212,30 +3212,30 @@
 dis.set(
-id + %22:
 commits
+Key + %22
 :%22 + new
@@ -3571,24 +3571,58 @@
 (id, cb) %7B%0A%0A
+    var doc_id = documentId(id);%0A%0A
     if(!self
@@ -3799,16 +3799,20 @@
 getJSON(
+doc_
 id);%0A   
@@ -3867,16 +3867,20 @@
 .asList(
+doc_
 id + %22:c
@@ -4008,16 +4008,20 @@
 etJSON( 
+doc_
 id + %22:c

Use scoped ids for documents.