       "failed"
       "wait"
     ]
-    #I could add stuck, but(callback)  I won"t support mass modifying "stuck" jobs because it"s very possible for things to be in a "stuck" state temporarily, while transitioning between states
-
-    unless type in validTypes
-      return callback success: false, message: "Invalid type: #{type} not in list of supported types"
-
-    ideally = errify (message) -> callback {success: false, message}
-
-    allKeyObjects = Object.keys(allKeys.keys)
-    i = 0
-    ii = allKeyObjects.length
-    while i < ii
-      firstPartOfKey = "bull:" + allKeyObjects[i] + ":"
-      k = 0
-      kk = allKeys.keys[allKeyObjects[i]].length
-      while k < kk
-        item = allKeys.keys[allKeyObjects[i]][k]
-        #Brute force remove from everything
-        multi.push ["lrem", firstPartOfKey + "active", 0, item]
-        multi.push ["lrem", firstPartOfKey + "wait", 0, item]
-        multi.push ["srem", firstPartOfKey + "completed", item]
-        multi.push ["srem", firstPartOfKey + "failed", item]
-        multi.push ["del",  firstPartOfKey + item]
-
-    await (@redis.multi multi).exec ideally defer data
-    callback success: true, message: "Successfully deleted all jobs of status #{type}."
-
-  #Deletes a job by ID. Requires type as the first parameter and ID as the second.
-  deleteJobById = (type, id, callback) ->
-    unless id
-      return callback success: false, message: "There was no ID provided."
-    unless type
-      return callback success: false, message: "There was no type provided."
-
-    ideally = errify (message) -> callback {success: false, message}
-
-    firstPartOfKey = "bull:#{type}:"
-    multi = []
-    multi.push ["lrem", firstPartOfKey + "active", 0, id]
-    multi.push ["lrem", firstPartOfKey + "wait", 0, id]
-    multi.push ["srem", firstPartOfKey + "completed", id]
-    multi.push ["srem", firstPartOfKey + "failed", id]
-    multi.push ["del", firstPartOfKey + id]
-    await (@redis.multi multi).exec ideally defer data
-    callback null, success: true, message: "Successfully deleted job #{type} ##{id}."
-
-  #Gets the progress for the keys passed in
-  getProgressForKeys = (keys, callback) ->
-    ideally = errify callback
-    multi = []
-
-    for key in keys
-      multi.push ["hget", "bull:" + key.type + ":" + key.id, "progress"]
+    #I could add stuck, but I won't support mass modifying "stuck" jobs because it's very possible for things to be in a "stuck" state temporarily, while transitioning between states
+
+    return callback "Invalid type: #{type} not in list of supported types" unless type in validTypes
+    ideally = errify callback
+
+    await @statusKeys type, ideally defer allKeys
+    multi = []
+    for type, keys of allKeys.keys
+      prefix = "bull:#{type}:"
+      for id in keys
+        multi.push ["del", "#{prefix}#{id}"]
+        multi.concat @commandRemoveFromStateLists prefix, id
+
+    await (@redis.multi multi).exec ideally defer data
+    callback null, "Successfully deleted all jobs of status #{type}."
+
+  deleteById: (type, id, callback) ->
+    return callback "id required"   unless id
+    return callback "type required" unless type
+    ideally = errify callback
+
+    prefix = "bull:#{type}:"
+    multi  = [["del", "#{prefix}#{id}"]]
+    multi.concat @commandRemoveFromStateLists prefix, id
+    await (@redis.multi multi).exec ideally defer data
+    callback null, "Successfully deleted job #{type} ##{id}."
+
+  dataById: (type, id, callback) ->
+    return callback "id required"   unless id
+    return callback "type required" unless type
+    ideally = errify callback
+
+    prefix = "bull:#{type}:"
+    await redis.hgetall "#{prefix}id", ideally defer err, result
+    callback null, result
+
+  progressForKeys: (keys, callback) ->
+    ideally = errify callback
+
+    multi = for key in keys
+      ["hget", "bull:#{key.type}:#{key.id}", "progress"]
 
     await (@redis.multi multi).exec ideally defer results
-      `var i`
-      `var ii`
-      i = 0
-      ii = keys.length
-      while i < ii
-        key.progress = results[i]
+    key.progress = results[i] for key, i in keys
+    callback null, keys
 
 
 module.exports = RedisModel

      "failed"
      "wait"
    ]
    #I could add stuck, but(callback)  I won"t support mass modifying "stuck" jobs because it"s very possible for things to be in a "stuck" state temporarily, while transitioning between states

    ideally = errify (message) -> callback {success: false, message}

    console.log validTypes.indexOf(type)
    unless type in validTypes
      return callback success: false, message: "Invalid type: #{type} not in list of supported types"

    await getStatus type, ideally defer allKeys
      multi = []
      allKeyObjects = Object.keys(allKeys.keys)

      i = 0
      ii = allKeyObjects.length
      while i < ii
        firstPartOfKey = "bull:" + allKeyObjects[i] + ":"
        k = 0
        kk = allKeys.keys[allKeyObjects[i]].length
        while k < kk
          item = allKeys.keys[allKeyObjects[i]][k]
          #Brute force remove from everything
          multi.push ["lrem", firstPartOfKey + "active", 0, item]
          multi.push ["srem", firstPartOfKey + "completed", item]
          multi.push ["srem", firstPartOfKey + "failed", item]
          #Add to pending
          multi.push ["rpush", firstPartOfKey + "wait", item]

      await (@redis.multi multi).exec ideally defer data
      callback success: true, message: "Successfully made all #{type} jobs pending."

  #Makes a job with a specific ID pending, requires the type of job as the first parameter and ID as second.
  makePendingById = (type, id, callback) ->
    unless id
      return callback success: false, message: "There was no ID provided."
    unless type
      return callback success: false, message: "There was no type provided."

    ideally = errify (message) -> callback {success: false, message}

    firstPartOfKey = "bull:#{type}:"

    multi = []
    multi.push ["lrem", firstPartOfKey + "active", 0, id]
    multi.push ["lrem", firstPartOfKey + "wait", 0, id]
    multi.push ["srem", firstPartOfKey + "completed", id]
    multi.push ["srem", firstPartOfKey + "failed", id]
    #Add to pending
    multi.push ["rpush", firstPartOfKey + "wait", id]
    await (@redis.multi multi).exec ideally defer data
    callback success: true, message: "Successfully made #{type} job ##{id} pending."

  #Deletes all jobs in a specific status
  deleteJobByStatus = (type, callback) ->
    type = type.toLowerCase()
    validTypes = [
      "active"

        status = "pending"
      {id, type, status}

    keyList = keyList.sort (a, b) ->
      aid = parseInt a.id
      bid = parseInt b.id
      if aid < bid then -1
      else if aid > bid then 1
      else 0

    callback null, keyList

  commandRemoveFromStateLists: (prefix, id) -> [
    ["lrem", "#{prefix}active",     0, id]
    ["lrem", "#{prefix}wait",       0, id]
    ["srem", "#{prefix}completed",  id]
    ["srem", "#{prefix}failed",     id]
  ]

  #Removes one or  more jobs by ID, also removes the job from any state list it's in
  remove: (list) ->
    return unless list
    #Expects {id: 123, type: "video transcoding"}
    multi = []
    for item in list
      prefix = "bull:#{item.type}:"
      multi.push ["del", "#{prefix}#{item.id}"]
      multi.concat @commandRemoveFromStateLists prefix, item.id

    (@redis.multi multi).exec()

  #Makes all jobs in a specific status pending
  makePendingByType: (type, callback) ->
    type = type.toLowerCase()
    validTypes = [
      "active"
