diff --git a/invenio/modules/workflows/models.py b/invenio/modules/workflows/models.py
index c5131986f..a19c49929 100644
--- a/invenio/modules/workflows/models.py
+++ b/invenio/modules/workflows/models.py
@@ -1,719 +1,717 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013, 2014 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """Models for BibWorkflow Objects."""
 
 import collections
 import os
 import tempfile
 import base64
 import logging
 from six.moves import cPickle
 from six import string_types, iteritems, callable
 from datetime import datetime
 from sqlalchemy import desc
 from sqlalchemy.orm.exc import NoResultFound
 from invenio.ext.sqlalchemy import db
 from invenio.base.globals import cfg
 
 from .utils import (redis_create_search_entry, WorkflowsTaskResult,
                     session_manager)
 from .logger import get_logger, BibWorkflowLogHandler
 
 
 class ObjectVersion(object):
-
     """Specify the different ObjectVersion possible."""
 
     INITIAL = 0
     FINAL = 1
     HALTED = 2
     RUNNING = 3
     MAPPING = {0: "New,", 1: "Done,", 2: "Need action,",
-                             3: "In process,"}
+               3: "In process,"}
+    REVERSE_MAPPING = {"New": 0, "Done": 1, "Need action": 2,
+                       "In process": 3}
 
 
 def get_default_data():
     """Return the base64 representation of the data default value."""
     data_default = {}
     return base64.b64encode(cPickle.dumps(data_default))
 
 
 def get_default_extra_data():
     """Return the base64 representation of the extra_data default value."""
     extra_data_default = {"_tasks_results": {},
                           "owner": {},
                           "_task_counter": {},
                           "_error_msg": None,
                           "_last_task_name": "",
                           "latest_object": -1,
                           "_action": None,
                           "redis_search": {},
                           "source": ""}
     return base64.b64encode(cPickle.dumps(extra_data_default))
 
 
 class Workflow(db.Model):
-
     """It is a class representing a workflow."""
 
     __tablename__ = "bwlWORKFLOW"
 
     uuid = db.Column(db.String(36), primary_key=True, nullable=False)
 
     name = db.Column(db.String(255), default="Default workflow",
                      nullable=False)
     created = db.Column(db.DateTime, default=datetime.now, nullable=False)
     modified = db.Column(db.DateTime, default=datetime.now,
                          onupdate=datetime.now, nullable=False)
     id_user = db.Column(db.Integer, default=0, nullable=False)
     _extra_data = db.Column(db.LargeBinary,
                             nullable=False,
                             default=get_default_extra_data())
     status = db.Column(db.Integer, default=0, nullable=False)
     current_object = db.Column(db.Integer, default="0", nullable=False)
     objects = db.relationship("BibWorkflowObject", backref="bwlWORKFLOW")
     counter_initial = db.Column(db.Integer, default=0, nullable=False)
     counter_halted = db.Column(db.Integer, default=0, nullable=False)
     counter_error = db.Column(db.Integer, default=0, nullable=False)
     counter_finished = db.Column(db.Integer, default=0, nullable=False)
     module_name = db.Column(db.String(64), nullable=False)
 
     child_logs = db.relationship("BibWorkflowEngineLog")
 
     def __repr__(self):
         """ Represent a workflow object."""
         return "<Workflow(name: %s, module: %s, cre: %s, mod: %s," \
                "id_user: %s, status: %s)>" % \
                (str(self.name), str(self.module_name), str(self.created),
                 str(self.modified), str(self.id_user), str(self.status))
 
     def __str__(self):
         """ Print a workflow object."""
         return """Workflow:
 
         Uuid: %s
         Name: %s
         User id: %s
         Module name: %s
         Created: %s
         Modified: %s
         Status: %s
         Current object: %s
         Counters: initial=%s, halted=%s, error=%s, finished=%s
         Extra data: %s""" % (str(self.uuid), str(self.name), str(self.id_user),
                              str(self.module_name), str(self.created),
                              str(self.modified), str(self.status),
                              str(self.current_object),
                              str(self.counter_initial),
                              str(self.counter_halted), str(self.counter_error),
                              str(self.counter_finished), str(self._extra_data))
 
     @classmethod
     def get(cls, *criteria, **filters):
         """Wrapper to get a specified object.
 
         A wrapper for the filter and filter_by functions of sqlalchemy.
         Define a dict with which columns should be filtered by which values.
 
         e.g. Workflow.get(uuid=uuid)
              Workflow.get(Workflow.uuid != uuid)
 
         The function supports also "hybrid" arguments.
         e.g. Workflow.get(Workflow.module_name != 'i_hate_this_module',
                           user_id=user_id)
 
         look up also sqalchemy BaseQuery's filter and filter_by documentation
         """
         return cls.query.filter(*criteria).filter_by(**filters)
 
     @classmethod
     def get_status(cls, uuid=None):
         """Return the status of the workflow."""
         return cls.get(Workflow.uuid == uuid).one().status
 
     @classmethod
     def get_most_recent(cls, *criteria, **filters):
         """Return the most recently modified workflow. """
         most_recent = cls.get(*criteria, **filters). \
             order_by(desc(Workflow.modified)).first()
         if most_recent is None:
             raise NoResultFound
         else:
             return most_recent
 
     @classmethod
     def get_objects(cls, uuid=None):
         """Return the objects of the workflow."""
         return cls.get(Workflow.uuid == uuid).one().objects
 
     def get_extra_data(self, user_id=0, uuid=None, key=None, getter=None):
         """Get the unpickle extra_data.
 
         Returns a json of the column extra_data or
         if any of the other arguments are defined,
         a specific value.
         You can define either the key or the getter function.
 
         :param key: the key to access the desirable value
         :param getter: a callable that takes a dict as param and returns a
         value
         """
         extra_data = Workflow.get(Workflow.id_user == self.id_user,
                                   Workflow.uuid == self.uuid).one()._extra_data
 
         extra_data = cPickle.loads(base64.b64decode(extra_data))
         if key:
             return extra_data[key]
         elif callable(getter):
             return getter(extra_data)
         elif not key:
             return extra_data
 
     def set_extra_data(self, user_id=0, uuid=None,
                        key=None, value=None, setter=None):
         """Replace extra_data.
 
         Modifies the json of the column extra_data or
         if any of the other arguments are defined, a specific value.
         You can define either the key, value or the setter function.
 
         :param key: the key to access the desirable value
         :param value: the new value
         :param setter: a callable that takes a dict as param and modifies it
         """
         extra_data = Workflow.get(Workflow.id_user == user_id,
                                   Workflow.uuid == uuid).one()._extra_data
         extra_data = cPickle.loads(base64.b64decode(extra_data))
         if key is not None and value is not None:
             extra_data[key] = value
         elif callable(setter):
             setter(extra_data)
 
         Workflow.get(Workflow.uuid == self.uuid).update(
             {'_extra_data': base64.b64encode(cPickle.dumps(extra_data))}
         )
 
     @classmethod
     @session_manager
     def delete(cls, uuid=None):
         """Delete a workflow."""
         cls.get(Workflow.uuid == uuid).delete()
 
     @session_manager
     def save(self, status):
         """Save object to persistent storage."""
         self.modified = datetime.now()
         if status is not None:
             self.status = status
         db.session.add(self)
 
 
 class BibWorkflowObject(db.Model):
-
     """Represent a BibWorkflowObject."""
 
     # db table definition
     __tablename__ = "bwlOBJECT"
 
     id = db.Column(db.Integer, primary_key=True)
 
     # Our internal data column. Default is encoded dict.
     _data = db.Column(db.LargeBinary,
                       nullable=False,
                       default=get_default_data())
     _extra_data = db.Column(db.LargeBinary,
                             nullable=False,
                             default=get_default_extra_data())
 
     id_workflow = db.Column(db.String(36),
                             db.ForeignKey("bwlWORKFLOW.uuid"), nullable=True)
     version = db.Column(db.Integer(3),
                         default=ObjectVersion.INITIAL, nullable=False)
     id_parent = db.Column(db.Integer, db.ForeignKey("bwlOBJECT.id"),
                           default=None)
     child_objects = db.relationship("BibWorkflowObject",
                                     remote_side=[id_parent])
     created = db.Column(db.DateTime, default=datetime.now, nullable=False)
     modified = db.Column(db.DateTime, default=datetime.now,
                          onupdate=datetime.now, nullable=False)
     status = db.Column(db.String(255), default="", nullable=False)
     data_type = db.Column(db.String(150), default="",
                           nullable=True)
     uri = db.Column(db.String(500), default="")
     id_user = db.Column(db.Integer, default=0, nullable=False)
     child_logs = db.relationship("BibWorkflowObjectLog")
     workflow = db.relationship(
         Workflow, foreign_keys=[id_workflow], remote_side=Workflow.uuid
     )
 
     _log = None
 
     @property
     def log(self):
         """ Allow logging functionnality."""
         if not self._log:
             db_handler_obj = BibWorkflowLogHandler(BibWorkflowObjectLog, "id")
             self._log = get_logger(logger_name="object.%s" %
                                                (self.id,),
                                    db_handler_obj=db_handler_obj,
                                    loglevel=logging.DEBUG,
                                    obj=self)
         return self._log
 
     def get_data(self):
         """Main method to retrieve data saved to the object. """
         return cPickle.loads(base64.b64decode(self._data))
 
     def set_data(self, value):
         """Main method to update data saved to the object."""
         self._data = base64.b64encode(cPickle.dumps(value))
 
     def get_extra_data(self):
         """Main method to retrieve data saved to the object."""
         return cPickle.loads(base64.b64decode(self._extra_data))
 
     def set_extra_data(self, value):
         """Main method to update data saved to the object.
 
         :param value: value that you want to replace extra_data
         """
         self._extra_data = base64.b64encode(cPickle.dumps(value))
 
     def __repr__(self):
         """Represent a BibWorkflowObject."""
         return "<BibWorkflowObject(id = %s, data = %s, id_workflow = %s, " \
                "version = %s, id_parent = %s, created = %s, extra_data = %s)" \
                % (str(self.id), str(self.get_data()), str(self.id_workflow),
                   str(self.version), str(self.id_parent), str(self.created),
                   str(self.get_extra_data()))
 
     def __eq__(self, other):
         """ Enable equal operators on BibWorkflowObjects."""
         if isinstance(other, BibWorkflowObject):
             if self._data == other._data and \
-                    self._extra_data == other._extra_data and \
-                    self.id_workflow == other.id_workflow and \
-                    self.version == other.version and \
-                    self.id_parent == other.id_parent and \
+                            self._extra_data == other._extra_data and \
+                            self.id_workflow == other.id_workflow and \
+                            self.version == other.version and \
+                            self.id_parent == other.id_parent and \
                     isinstance(self.created, datetime) and \
                     isinstance(self.modified, datetime):
                 return True
             else:
                 return False
         return NotImplemented
 
     def __ne__(self, other):
         """ Enable equal operators on BibWorkflowObjects."""
         return not self.__eq__(other)
 
     def add_task_result(self, name, result):
         """Save a task result.
 
         Adds given task results to extra_data in order to be accessed
         and displayed later on by Holding Pen templates.
         """
         task_name = self.extra_data["_last_task_name"]
         res_obj = WorkflowsTaskResult(task_name, name, result)
         if isinstance(self.extra_data["_tasks_results"], list):
             if not self.extra_data["_tasks_results"]:
                 self.extra_data["_tasks_results"] = {task_name: result}
         else:
             if task_name in self.extra_data["_tasks_results"]:
                 self.extra_data["_tasks_results"][task_name].append(res_obj)
             else:
                 self.extra_data["_tasks_results"][task_name] = [res_obj]
 
     def get_tasks_results(self):
         """Return the complete set of tasks results."""
         return self.get_extra_data()["_tasks_results"]
 
     def add_action(self, action, message):
         """Save an action for holdingpen for this object.
 
         Assign an special "action" to this object to be taken
         in consideration in holdingpen. The widget is referred to
         by a string with the filename minus extension.
 
         Ex: 'approval' for an action 'approval.py'.
 
         A message is also needed to tell the user the action
         required in a textual way.
 
         :param action: name of the action to add (i.e. "approval")
         :type action: string
 
         :param message: message to show to the user
         :type message: string
         """
         extra_data = self.get_extra_data()
         extra_data["_action"] = action
         extra_data["_message"] = message
         self.set_extra_data(extra_data)
 
     def get_action(self):
         """Retrieve the currently assigned action, if any.
 
         :return: name of action assigned as string, or None
         """
         try:
             return self.get_extra_data()["_action"]
         except KeyError:
             # No widget, try old _widget
             extra_data = self.get_extra_data()
             if "_widget" in extra_data:
                 import warnings
+
                 warnings.warn("Widget's are now stored in '_action'",
                               DeprecationWarning)
                 # Migrate to new naming
                 extra_data["_action"] = extra_data['_widget']
                 del extra_data["_widget"]
                 self.set_extra_data(extra_data)
                 return extra_data["_action"]
             return None
 
     def get_action_message(self):
         """ Retrieve the currently assigned widget, if any."""
         try:
             return self.get_extra_data()["_message"]
         except KeyError:
             # No widget
             return ""
 
     def set_error_message(self, msg):
         """Set an error message."""
         extra_data = self.get_extra_data()
         extra_data["_error_msg"] = msg
         self.set_extra_data(extra_data)
 
     def get_error_message(self):
         """Retrieve the error message, if any."""
         if "error_msg" in self.get_extra_data():
             # Backwards compatibility
             extra_data = self.get_extra_data()
             msg = extra_data["error_msg"]
             del extra_data["error_msg"]
             self.set_extra_data(extra_data)
             self.set_error_message(msg)
         try:
             return self.get_extra_data()["_error_msg"]
         except KeyError:
             # No message
             return ""
 
     def remove_action(self):
         """Remove the currently assigned action."""
         extra_data = self.get_extra_data()
         extra_data["_action"] = None
         extra_data["_message"] = ""
         if "_widget" in extra_data:
             del extra_data["_widget"]
         self.set_extra_data(extra_data)
 
     def start_workflow(self, workflow_name, delayed=False, **kwargs):
         """Run the workflow specified on the object.
 
         Will start a new workflow execution for the object using
         workflows.api.
 
         :param workflow_name: name of workflow to run
         :type str
 
         :param delayed: should the workflow run asynchronously?
         :type bool
         """
         if delayed:
             from .api import start_delayed as start_func
         else:
             from .api import start as start_func
         self.save()
         return start_func(workflow_name, data=[self], **kwargs)
 
     def continue_workflow(self, start_point="continue_next", delayed=False, **kwargs):
         """Run the workflow specified on the object.
 
         Will continue a previous execution for the object using
         workflows.api.
 
         :param start_point: where should the workflow start from? One of:
            * restart_prev: will restart from the previous task
            * continue_next: will continue to the next task
            * restart_task: will restart the current task
         :type str
 
         :param delayed: should the workflow run asynchronously?
         :type bool
         """
         from .errors import WorkflowAPIError
 
         self.save()
         if not self.id_workflow:
             raise WorkflowAPIError("No workflow associated with object: %r"
                                    % (repr(self),))
         if delayed:
             from .api import continue_oid_delayed as continue_func
         else:
             from .api import continue_oid as continue_func
         return continue_func(self.id, start_point, **kwargs)
 
     def change_status(self, message):
         """Change the status."""
         self.status = message
 
     def get_current_task(self):
         """Return the current task from the workflow engine for this object."""
         extra_data = self.get_extra_data()
         try:
             return extra_data["_task_counter"]
         except KeyError:
             # Assume old version "task_counter"
             return extra_data["task_counter"]
 
     def save_to_file(self, directory=None,
                      prefix="workflow_object_data_", suffix=".obj"):
         """Save the contents of self.data['data'] to file.
 
         Returns path to saved file.
 
         Warning: Currently assumes non-binary content.
         """
         if directory is None:
             directory = cfg['CFG_TMPSHAREDIR']
         tmp_fd, filename = tempfile.mkstemp(dir=directory,
                                             prefix=prefix,
                                             suffix=suffix)
         os.write(tmp_fd, self.get_data())
         os.close(tmp_fd)
         return filename
 
     def __getstate__(self):
         """Pickling needed function."""
         return self.__dict__
 
     def __setstate__(self, state):
         """ unpickling needed function."""
         self.__dict__ = state
 
     def copy(self, other):
         """Copy data and metadata except id and id_workflow."""
         self._data = other._data
         self._extra_data = other._extra_data
         self.version = other.version
         self.id_parent = other.id_parent
         self.created = other.created
         self.modified = other.modified
         self.status = other.status
         self.data_type = other.data_type
         self.uri = other.uri
 
     @session_manager
     def save(self, version=None, task_counter=None, id_workflow=None):
         """Save object to persistent storage."""
         if task_counter is not None:
             self.log.debug("Saving task counter: %s" % (task_counter,))
             extra_data = self.get_extra_data()
             extra_data["_task_counter"] = task_counter
             self.set_extra_data(extra_data)
 
         if version is not None:
             if version != self.version:
                 self.modified = datetime.now()
             self.version = version
             if version in (ObjectVersion.FINAL, ObjectVersion.HALTED):
                 redis_create_search_entry(self)
         if id_workflow is not None:
             self.id_workflow = id_workflow
         db.session.add(self)
         if self.id is not None:
             self.log.debug("Saving object: %s" % (self.id or "new",))
 
     @classmethod
     def get(cls, *criteria, **filters):
         """Wrapper of Sqlalchemy to get a BibWorkflowObject.
 
         A wrapper for the filter and filter_by functions of sqlalchemy.
         Define a dict with which columns should be filtered by which values.
 
         e.g. Workflow.get(uuid=uuid)
              Workflow.get(Workflow.uuid != uuid)
 
         The function supports also "hybrid" arguments.
         e.g. Workflow.get(Workflow.module_name != 'i_hate_this_module',
                           user_id=user_id)
 
         look up also sqalchemy BaseQuery's filter and filter_by documentation
         """
         return cls.query.filter(*criteria).filter_by(**filters)
 
     @classmethod
     @session_manager
     def delete(cls, oid):
         """Delete a BibWorkflowObject."""
         cls.get(BibWorkflowObject.id == oid).delete()
 
     @classmethod
     @session_manager
     def create_object(cls, **kwargs):
         """Create a new Workflow Object with given content."""
         obj = BibWorkflowObject(**kwargs)
         db.session.add(obj)
         return obj
 
     @classmethod
     @session_manager
     def create_object_revision(cls, old_obj, version, **kwargs):
         """Create a Workflow Object copy with customized values."""
         # Create new object and copy it
         obj = BibWorkflowObject(**kwargs)
         obj.copy(old_obj)
 
         # Overwrite some changes
 
         obj.version = version
         obj.created = datetime.now()
         obj.modified = datetime.now()
         for key, value in iteritems(kwargs):
             setattr(obj, key, value)
         db.session.add(obj)
         return obj
 
 
 class BibWorkflowObjectLog(db.Model):
-
     """Represent a BibWorkflowObjectLog.
 
     This class represent a record of a log emit by an object
     into the database the object must be saved before using
     this class. Indeed it needs the id of the object into
     the database.
     """
 
     __tablename__ = 'bwlOBJECTLOGGING'
     id = db.Column(db.Integer, primary_key=True)
     id_object = db.Column(db.Integer(255),
                           db.ForeignKey('bwlOBJECT.id'),
                           nullable=False)
     log_type = db.Column(db.Integer, default=0, nullable=False)
     created = db.Column(db.DateTime, default=datetime.now)
     message = db.Column(db.TEXT, default="", nullable=False)
 
     def __str__(self):
         """Print a log."""
         return "%(severity)s: %(created)s - %(message)s" % {
             "severity": self.log_type,
             "created": self.created,
             "message": self.message
         }
 
     def __repr__(self):
         """Represent a log message."""
         return "BibWorkflowObjectLog(%s)" % (", ".join([
             "log_type='%s'" % self.log_type,
             "created='%s'" % self.created,
             "message='%s'" % self.message,
             "id_object='%s'" % self.id_object,
         ]))
 
     @classmethod
     def get(cls, *criteria, **filters):
         """ Sqlalchemy wrapper to get BibworkflowLogs.
 
         A wrapper for the filter and filter_by functions of sqlalchemy.
         Define a dict with which columns should be filtered by which values.
 
         look up also sqalchemy BaseQuery's filter and filter_by documentation
         """
         return cls.query.filter(*criteria).filter_by(**filters)
 
     @classmethod
     def get_most_recent(cls, *criteria, **filters):
         """ Return the most recently created log. """
         most_recent = cls.get(*criteria, **filters).order_by(
             desc(BibWorkflowObjectLog.created)).first()
         if most_recent is None:
             raise NoResultFound
         else:
             return most_recent
 
     @classmethod
     def delete(cls, id=None):
         """Delete an instance in database. """
         cls.get(BibWorkflowObjectLog.id == id).delete()
         db.session.commit()
 
 
 class BibWorkflowEngineLog(db.Model):
-
     """ Represent a BibWorkflowEngineLog object."""
 
     __tablename__ = "bwlWORKFLOWLOGGING"
     id = db.Column(db.Integer, primary_key=True)
     id_object = db.Column(db.String(255),
                           db.ForeignKey('bwlWORKFLOW.uuid'),
                           nullable=False)
     log_type = db.Column(db.Integer, default=0, nullable=False)
     created = db.Column(db.DateTime, default=datetime.now)
     message = db.Column(db.TEXT, default="", nullable=False)
 
     def __str__(self):
         """Print a log."""
         return "%(severity)s: %(created)s - %(message)s" % {
             "severity": self.log_type,
             "created": self.created,
             "message": self.message
         }
 
     def __repr__(self):
         """Represent a log message."""
         return "BibWorkflowEngineLog(%s)" % (", ".join([
             "log_type='%s'" % self.log_type,
             "created='%s'" % self.created,
             "message='%s'" % self.message,
             "id_object='%s'" % self.id_object
         ]))
 
     @classmethod
     def get(cls, *criteria, **filters):
         """Sqlalchemy wrapper to get BibWorkflowEngineLog.
 
         A wrapper for the filter and filter_by functions of sqlalchemy.
         Define a dict with which columns should be filtered by which values.
 
         look up also sqalchemy BaseQuery's filter and filter_by documentation
         """
         return cls.query.filter(*criteria).filter_by(**filters)
 
     @classmethod
     def get_most_recent(cls, *criteria, **filters):
         """ Return the most recently created log. """
         most_recent = cls.get(*criteria, **filters).order_by(
             desc(BibWorkflowEngineLog.created)).first()
         if most_recent is None:
             raise NoResultFound
         else:
             return most_recent
 
     @classmethod
     def delete(cls, uuid=None):
         """Delete an instance in database. """
         cls.get(BibWorkflowEngineLog.id == uuid).delete()
         db.session.commit()
 
 
 __all__ = ['Workflow', 'BibWorkflowObject',
            'BibWorkflowObjectLog', 'BibWorkflowEngineLog']
diff --git a/invenio/modules/workflows/static/js/workflows/hp_maintable.js b/invenio/modules/workflows/static/js/workflows/hp_maintable.js
index 96658b4d2..61bde05fd 100644
--- a/invenio/modules/workflows/static/js/workflows/hp_maintable.js
+++ b/invenio/modules/workflows/static/js/workflows/hp_maintable.js
@@ -1,112 +1,111 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013, 2014 CERN.
  *
  * Invenio is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  *
  * Invenio is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with Invenio; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
 
 var WORKFLOWS_HOLDINGPEN = (function ($) {
     var oTable,
         oSettings,
         selectedRow,
         rowList = [],
         rowIndexList = [],
         recordsToApprove = [],
         defaultcss = "#example tbody tr.even:hover, #example tbody tr.odd:hover {background-color: #FFFFCC;}",
         context = {},
         datatable = {},
         tag = {},
         utilities = {},
         actions = [];
 
     return {
         oTable: oTable,
         oSettings: oSettings,
         selectedRow: selectedRow,
         rowList: rowList,
         rowIndexList: rowIndexList,
         recordsToApprove: recordsToApprove,
         defaultcss: defaultcss,
         context: context,
         datatable: datatable,
         tag: tag,
         actions: actions,
         utilities: utilities,
 
         init: function (data) {
             this.context = data;
             this.tag = window.WORKFLOWS_HP_TAGS;
             this.tag.init();
             this.datatable = window.WORKFLOWS_HP_SELECTION;
             this.utilities = window.WORKFLOWS_HP_UTILITIES;
-            this.utilities.init();
             this.datatable.init(this.oTable, this.oSettings);
             this.utilities.autorefresh();
         },
 
         init_datatable: function (datatable) {
             oSettings = {
                 "dom": '<"top"iflp<"clear">>rt<"bottom"iflp<"clear">>',
                 "bFilter": false,
                 "bJQueryUI": true,
                 "bProcessing": true,
                 "bServerSide": true,
                 "bDestroy": true,
                 "sAjaxSource": this.context.holdingpen.url_load,
                 "oColVis": {
                     "buttonText": "Select Columns",
                     "bRestore": true,
                     "sAlign": "left",
                     "iOverlayFade": 1
                 },
                 "aoColumnDefs": [{'bSortable': false, 'aTargets': [1]},
                                  {'bSearchable': false, 'bVisible': false, 'aTargets': [0]},
                                  {'sWidth': "25%", 'aTargets': [2]},
                                  {'sWidth': "25%", 'aTargets': [3]}],
                 "fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
                     var id = aData[0];
                     datatable.rememberSelected(nRow, id);
                     nRow.row_id = id;
                     nRow.checkbox = nRow.cells[0].firstChild;
                     $(nRow).on("click", "td", function (event) {
                         console.log(event);
                         if(event.target.nodeName != "INPUT") {
                             datatable.selectRow(nRow, event, oTable.fnSettings());
                         }
                     });
                 },
                 "fnDrawCallback": function () {
                     $('table#maintable td').bind('mouseenter', function () {
                         $(this).parent().children().each(function () {
                             $(this).addClass('maintablerowhover');
                         });
                     });
                     $('table#maintable td').bind('mouseleave', function () {
                         $(this).parent().children().each(function () {
                             $(this).removeClass('maintablerowhover');
                         });
                     });
                     $('#select-all')[0].checked = false;
                 }
             };
             oTable = $('#maintable').dataTable(oSettings);
             $('.dropdown-toggle').dropdown();
             this.oSettings = oTable.fnSettings();
             this.oTable = oTable;
 
         }
     };
 })(window.jQuery);
 
diff --git a/invenio/modules/workflows/static/js/workflows/hp_tags.js b/invenio/modules/workflows/static/js/workflows/hp_tags.js
index 6478a01b4..d0ec677c4 100644
--- a/invenio/modules/workflows/static/js/workflows/hp_tags.js
+++ b/invenio/modules/workflows/static/js/workflows/hp_tags.js
@@ -1,112 +1,93 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013, 2014 CERN.
  *
  * Invenio is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  *
  * Invenio is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with Invenio; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
 
 // Tags functions
 //***********************************
 var WORKFLOWS_HP_TAGS = function ($, holdingpen) {
     "use strict";
     var tagList = [];
 
     $("#tags").tagsinput({
         tagClass: function (item) {
             switch (item) {
             case 'In process':
                 return 'label label-warning';
             case 'Need action':
                 return 'label label-danger';
             case 'Done':
                 return 'label label-success';
             case 'New':
                 return 'label label-info';
             default:
                 return 'badge badge-warning';
             }
         }
     });
 
     var init = function () {
         $('.task-btn').on('click', function () {
             if ($.inArray($(this)[0].name, tagList) <= -1) {
                 var widget_name = $(this)[0].name;
                 $("#tags").tagsinput('add', $(this)[0].text);
                 WORKFLOWS_HP_UTILITIES.requestNewObjects();
             } else {
                 closeTag(widget_name);
                 holdingpen.oTable.fnFilter('^$', 4, true, false);
                 holdingpen.oTable.fnDraw(false);
             }
         });
 
         $('#option-autorefresh').on('click', function () {
              console.log($('#option-autorefresh').hasClass("btn-danger"));
              if($('#option-autorefresh').hasClass("btn-danger")) {
                 $('#option-autorefresh').removeClass("btn-danger");
              } else {
                 $('#option-autorefresh').addClass("btn-danger");
              }
         });
 
         $('.version-selection').on('click', function () {
             if ($.inArray($(this)[0].name, tagList) <= -1) {
                 $('#tags').tagsinput('add', $(this)[0].text);
             }
         });
 
         $("#tags").on('itemRemoved', function (event) {
             tagList = $("#tags").val().split(',');
-            tagList = taglist_translation(tagList);
             WORKFLOWS_HP_UTILITIES.requestNewObjects();
-            holdingpen.oTable.fnDraw(false);
         });
 
         $("#tags").on('itemAdded', function (event) {
             tagList =  $("#tags").val().split(',');
-            tagList = taglist_translation(tagList);
             WORKFLOWS_HP_UTILITIES.requestNewObjects();
         });
     };
 
-    function taglist_translation(my_taglist) {
-        var i;
-        for (i = 0; i <= my_taglist.length; i++) {
-            if (my_taglist[i] === 'Done') {
-                my_taglist[i] = 'Completed';
-            } else if (my_taglist[i] === 'Need action') {
-                my_taglist[i] = 'Halted';
-            } else if (my_taglist[i] === 'In process') {
-                my_taglist[i] = 'Running';
-            } else if (my_taglist[i] === 'New') {
-                my_taglist[i] = 'Initial';
-            }
-        }
-        return my_taglist;
-    }
-
     var closeTag = function (tag_name) {
         tagList.splice(tagList.indexOf(tag_name), 1);
         $('#tags').tagsinput('remove', tag_name);
     };
 
     return {
         init: init,
         tagList: function () { return tagList; },
         closeTag: closeTag
     };
 }($, WORKFLOWS_HOLDINGPEN);
-//***********************************
\ No newline at end of file
+//***********************************
diff --git a/invenio/modules/workflows/static/js/workflows/hp_utilities.js b/invenio/modules/workflows/static/js/workflows/hp_utilities.js
index 4543e9e55..6861d691a 100644
--- a/invenio/modules/workflows/static/js/workflows/hp_utilities.js
+++ b/invenio/modules/workflows/static/js/workflows/hp_utilities.js
@@ -1,124 +1,77 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013, 2014 CERN.
  *
  * Invenio is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  *
  * Invenio is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with Invenio; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
 
 //Utility functions
 //***********************************
 var WORKFLOWS_HP_UTILITIES = function ($, holdingpen) {
 
-    var tagList = holdingpen.tag.tagList,
-        version_showing = [holdingpen.context.version_showing];
-
     $.fn.exists = function () {
         return this.length !== 0;
     };
 
     var _requestNewObjects = function () {
-        var version_showing = [],
-            i,
-            search_tags = [];
-            console.log(holdingpen);
-        var tempTagList = holdingpen.tag.tagList();
-        for(i = 0 ; i< tempTagList.length; i++)
-        {
-            if ("Completed" == tempTagList[i]) {
-                version_showing.push("final");
-            } else if ("Halted" == tempTagList[i]) {
-                version_showing.push("halted")
-            } else if ("Running" ==  tempTagList[i]) {
-                version_showing.push("running")
-            } else if ("Initial" ==  tempTagList[i]){
-                version_showing.push("initial");
-            } else {
-                search_tags.push(tempTagList[i]);
-            }
-        }
-        my_data = JSON.stringify({'version':version_showing, 'tags':search_tags});
+        my_data = JSON.stringify({'tags': holdingpen.tag.tagList()});
         $.ajax({
             type : "POST",
             url : holdingpen.context.holdingpen.url_load,
             data: my_data,
             contentType: "application/json;charset=UTF-8",
             traditional: true,
             success: function(result) {
                 holdingpen.oTable.fnDraw(false);
             }
         });
     };
 
-    var _init = function () {
-        var i;
-        if (version_showing) {
-            for (i = 0; i < version_showing.length; i++) {
-                if (version_showing[i] === 1) {
-                    if ($.inArray('Completed', tagList) <= -1) {
-                        tagList.push('Completed');
-                    }
-                    $('#version-completed').click();
-                } else if (version_showing[i] === 2) {
-                    if ($.inArray('Halted', tagList) <= -1) {
-                        tagList.push('Halted');
-                    }
-                    $('#version-halted').click();
-                } else if (version_showing[i] === 3) {
-                    if ($.inArray("Running", tagList) <= -1) {
-                        tagList.push("Running");
-                    }
-                    $("#version-running").click();
-                }
-            }
-        }
-    };
-
     var utilities =  {
-        init: _init,
         requestNewObjects: _requestNewObjects,
 
         fnGetSelected: function (oTableLocal) {
             var aReturn = [],
                 aTrs = oTableLocal.fnGetNodes(),
                 i;
 
             for (i = 0; i < aTrs.length; i++) {
                 if ($(aTrs[i]).hasClass("row_selected")) {
                     aReturn.push(aTrs[i]);
                 }
             }
             return aReturn;
         },
 
         isInt: function (n) {
             return typeof n === "number" && n % 1 === 0;
         },
 
         emptyLists: function () {
             holdingpen.rowList = [];
             holdingpen.rowIndexList = [];
         },
 
         autorefresh: function () {
             window.setInterval( function() {
                 if($('#option-autorefresh').hasClass("btn-danger")) {
                     WORKFLOWS_HP_UTILITIES.requestNewObjects();
                 }}, 3000);
         },
     };
 
     return utilities;
 }($, WORKFLOWS_HOLDINGPEN);
 //***********************************
diff --git a/invenio/modules/workflows/templates/workflows/hp_maintable.html b/invenio/modules/workflows/templates/workflows/hp_maintable.html
index a597918dd..fd2945f24 100644
--- a/invenio/modules/workflows/templates/workflows/hp_maintable.html
+++ b/invenio/modules/workflows/templates/workflows/hp_maintable.html
@@ -1,112 +1,112 @@
 {#
 ## This file is part of Invenio.
 ## Copyright (C) 2014 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 #}
 {% extends "workflows/hp_base.html" %}
 {% import 'workflows/utils.html' as utils %}
 
 {% block header%}
     {{ super() }}
     {% bundles "workflows.js", "datatables.css", "datatables.js", "actions.js", "jquery.js" %}
 {% endblock header %}
 
 {% block javascript %}
     {{ super() }}
 
 
 <script type="text/javascript">
     $(document).ready(function(){
         var context_url = "{{ url_for('holdingpen.get_context')|safe }}";
         window.jQuery.ajax({
             url: context_url,
             success: function(data) {
                 WORKFLOWS_HOLDINGPEN.init(data);
                 WORKFLOWS_HOLDINGPEN.init_datatable(WORKFLOWS_HP_SELECTION);
             }
         });
     });
 </script>
 {% endblock javascript %}
 
 {% block hpbody %}
     <nav class="navbar navbar-default navbar-static-top" role="navigation">
       <!-- Brand and toggle get grouped for better mobile display -->
 
       <!-- Collect the nav links, forms, and other content for toggling -->
       <div id="bs-example-navbar-collapse-1" class="collapse navbar-collapse">
         <ul class="nav navbar-nav">
            <!--  <li><a href="#">Assigned to me</a></li> -->
             <p class="navbar-text" style="margin-right:0px; color:light gray;">Show Records by:</p>
             <li class="dropdown">
                 <a class="dropdown-toggle dropdown-headline" data-toggle="dropdown" href="#">Actions<b class="caret"></b></a>
                     <ul class="dropdown-menu">
                     {% if user_list %}
                         {% set i = 0 %}
                         {% for task, object_count in action_list.items() %}
                             <li><a id="task{{i}}" class="task-btn" tabindex="-1" name="{{task}}">{{task}}: {{object_count}}</a></li>
                             {% set i = i + 1 %}
                         {% endfor %}
                     {% else %}
                             <li><a class="task-btn">No actions left</a></li>
                     {% endif %}
                     </ul>
             </li>
             <li class="dropdown">
                 <a href="#" class="dropdown-toggle dropdown-headline" data-toggle="dropdown">Status<b class="caret"></b></a>
                 <ul class="dropdown-menu" role="menu">
-                    <li><a id="version-halted" class="version-selection" name="Halted">Need action</a></li>
-                    <li><a id="version-completed" class="version-selection" name="Completed">Done</a></li>
-                    <li><a id="version-running" class="version-selection" name="Running">In process</a></li>
-                    <li><a id="version-initial" class="version-selection" name="Initial">New</a></li>
+                    <li><a id="version-halted" class="version-selection" name="Nedd action">Need action</a></li>
+                    <li><a id="version-completed" class="version-selection" name="Done">Done</a></li>
+                    <li><a id="version-running" class="version-selection" name="In process">In process</a></li>
+                    <li><a id="version-initial" class="version-selection" name="New">New</a></li>
                 </ul>
             </li>
             <li class="dropdown">
                 <a href="#" class="dropdown-toggle dropdown-headline" data-toggle="dropdown">Options<b class="caret"></b></a>
                 <ul class="dropdown-menu" role="menu">
                     <li><a id="option-autorefresh" name="autorefresh-option">Auto-refresh</a></li>
                 </ul>
             </li>
         </ul>
         <ul id="navbar-right" class="nav navbar-nav navbar-right">
         </ul>
       </div>
     </nav>
     <input class="tags" id="tags" type="text" placeholder="{{ _("Add to search") }}" value="{{tags}}"/>
     <br>
 
     <div class="container">
         <div class="row">
             <table id="maintable" cellpadding="0" cellspacing="0" border="0" class="table table-bordered">
                 <thead>
                     <tr>
                         <th>Id</th>
                         <th><input id="select-all" type="checkbox"></th>
                         <th>Title</th>
                         <th>Description</th>
                         <th>Created</th>
                         <th>Status</th>
                         <th>Type</th>
                         <th>Actions</th>
                     </tr>
                 </thead>
                 <tbody>
 
                 </tbody>
             </table>
         </div>
     </div>
 {% endblock %}
diff --git a/invenio/modules/workflows/utils.py b/invenio/modules/workflows/utils.py
index efbb66197..a4563a3d9 100644
--- a/invenio/modules/workflows/utils.py
+++ b/invenio/modules/workflows/utils.py
@@ -1,305 +1,294 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013, 2014 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 import redis
 import traceback
 from six import iteritems
 from .errors import WorkflowDefinitionError
 
 
 def session_manager(orig_func):
     """Decorator to wrap function with the session."""
     from invenio.ext.sqlalchemy import db
 
     def new_func(self, *a, **k):
         """Wrappend function to manage DB session."""
         try:
             resp = orig_func(self, *a, **k)
             db.session.commit()
             return resp
         except:
             db.session.rollback()
             raise
 
     return new_func
 
 
 def convert_marcxml_to_bibfield(marcxml):
     """
 
     :param marcxml:
     :return:
     """
     from invenio.modules.jsonalchemy.reader import Reader
     from invenio.modules.jsonalchemy.wrappers import SmartJson
     if isinstance(marcxml, unicode):
         marcxml = marcxml.encode(errors='ignore')
     return Reader.translate(marcxml,
                             SmartJson,
                             master_format='marc',
                             namespace='recordext')
 
 
 def test_teardown(self):
     """ Clean up created objects """
     from invenio.modules.workflows.models import (BibWorkflowObject,
                                                   Workflow,
                                                   BibWorkflowEngineLog,
                                                   BibWorkflowObjectLog)
     from invenio.ext.sqlalchemy import db
 
     workflows = Workflow.get(Workflow.module_name == "unit_tests").all()
     for workflow in workflows:
         BibWorkflowObject.query.filter(
             BibWorkflowObject.id_workflow == workflow.uuid
         ).delete()
 
         objects = BibWorkflowObjectLog.query.filter(
             BibWorkflowObject.id_workflow == workflow.uuid
         ).all()
         for obj in objects:
             db.session.delete(obj)
         db.session.delete(workflow)
 
         objects = BibWorkflowObjectLog.query.filter(
             BibWorkflowObject.id_workflow == workflow.uuid
         ).all()
         for obj in objects:
             BibWorkflowObjectLog.delete(id=obj.id)
         BibWorkflowEngineLog.delete(uuid=workflow.uuid)
 
     # Deleting dummy object created in tests
     Workflow.query.filter(Workflow.module_name == "unit_tests").delete()
     db.session.commit()
 
 
 class BibWorkflowObjectIdContainer(object):
     """
     This class is only made to be able to store a workflow ID and
     to retrieve easily the workflow from this ID. It is used maily
     to overide some problem with SQLAlchemy when we change of
     execution thread ( for example Celery )
     """
 
     def __init__(self, bibworkflowobject=None):
         if bibworkflowobject is not None:
             self.id = bibworkflowobject.id
         else:
             self.id = None
 
     def get_object(self):
         from ..workflows.models import BibWorkflowObject as bwlObject
 
         if self.id is not None:
             return bwlObject.query.filter(bwlObject.id == self.id).one()
         else:
             return None
 
     def from_dict(self, dict_to_process):
         self.id = dict_to_process[str(self.__class__)]["id"]
         return self
 
     def to_dict(self):
         return {str(self.__class__): self.__dict__}
 
 
 class WorkflowsTaskResult(object):
 
     """The class to contain the current task results."""
 
     def __init__(self, task_name, name, result):
         self.task_name = task_name
         self.name = name
         self.result = result
 
     def to_dict(self):
         return {'name': self.name,'task_name': self.task_name, 'result':self.result}
 
 def get_workflow_definition(name):
     """ Tries to load the given workflow from the system. """
     from .registry import workflows
 
     if name in workflows:
         return getattr(workflows[name], "workflow", None)
     else:
         return WorkflowMissing.workflow
 
 
 class dictproperty(object):
     class _proxy(object):
         def __init__(self, obj, fget, fset, fdel):
             self._obj = obj
             self._fget = fget
             self._fset = fset
             self._fdel = fdel
 
         def __getitem__(self, key):
             return self._fget(self._obj, key)
 
         def __setitem__(self, key, value):
             self._fset(self._obj, key, value)
 
         def __delitem__(self, key):
             self._fdel(self._obj, key)
 
     def __init__(self, fget=None, fset=None, fdel=None, doc=None):
         self._fget = fget
         self._fset = fset
         self._fdel = fdel
         self.__doc__ = doc
 
     def __get__(self, obj, objtype=None):
         if obj is None:
             return self
         return self._proxy(obj, self._fget, self._fset, self._fdel)
 
 
 def redis_create_search_entry(bwobject):
     redis_server = set_up_redis()
 
     extra_data = bwobject.get_extra_data()
     #creates database entries to not loose key value pairs in redis
 
     for key, value in iteritems(extra_data["redis_search"]):
         redis_server.sadd("holdingpen_sort", str(key))
         redis_server.sadd("holdingpen_sort:%s" % (str(key),), str(value))
         redis_server.sadd("holdingpen_sort:%s:%s" % (str(key), str(value),),
                           bwobject.id)
 
     redis_server.sadd("holdingpen_sort", "owner")
     redis_server.sadd("holdingpen_sort:owner", extra_data['owner'])
     redis_server.sadd("holdingpen_sort:owner:%s" % (extra_data['owner'],),
                       bwobject.id)
     redis_server.sadd("holdingpen_sort:last_task_name:%s" %
                       (extra_data['_last_task_name'],), bwobject.id)
 
 
 def filter_holdingpen_results(key, *args):
     """Function filters holdingpen entries by given key: value pair.
     It returns list of IDs."""
     redis_server = set_up_redis()
     new_args = []
     for a in args:
         new_args.append("holdingpen_sort:" + a)
     return redis_server.sinter("holdingpen_sort:" + key, *new_args)
 
 
 def get_redis_keys(key=None):
     redis_server = set_up_redis()
     if key:
         return list(redis_server.smembers("holdingpen_sort:%s" % (str(key),)))
     else:
         return list(redis_server.smembers("holdingpen_sort"))
 
 
 def get_redis_values(key):
     redis_server = set_up_redis()
     return redis_server.smembers("holdingpen_sort:%s" % (str(key),))
 
 
 def set_up_redis():
     """
     Sets up the redis server for the saving of the HPContainers
 
     @return: Redis server object.
     """
     from flask import current_app
 
     redis_server = redis.Redis.from_url(
         current_app.config.get('CACHE_REDIS_URL', 'redis://localhost:6379')
     )
     return redis_server
 
 
 def empty_redis():
     redis_server = set_up_redis()
     redis_server.flushall()
 
 
 def sort_bwolist(bwolist, iSortCol_0, sSortDir_0):
-    #from invenio.modules.workflows.views.holdingpen import (get_title,
-    #                                                        get_identifiers,
-    #                                                        get_subject_categories
-    #)
     should_we_reverse = False
     if sSortDir_0 == 'desc':
         should_we_reverse = True
-
     if iSortCol_0 == 0:
         bwolist.sort(key=lambda x: x.id, reverse=should_we_reverse)
     elif iSortCol_0 == 1:
         bwolist.sort(key=lambda x: x.id, reverse=should_we_reverse)
-    #elif iSortCol_0 == 2:
-    #    bwolist.sort(key=lambda x: get_title(x.get_data()), reverse=should_we_reverse)
-    #elif iSortCol_0 == 3:
-    #    bwolist.sort(key=lambda x: get_identifiers(x.get_data()), reverse=should_we_reverse)
-    #elif iSortCol_0 == 4:
-    #    bwolist.sort(key=lambda x: get_subject_categories(x.get_data()), reverse=should_we_reverse)
     elif iSortCol_0 == 4:
         bwolist.sort(key=lambda x: x.created, reverse=should_we_reverse)
     elif iSortCol_0 == 5:
         bwolist.sort(key=lambda x: x.version, reverse=should_we_reverse)
     elif iSortCol_0 == 6:
         bwolist.sort(key=lambda x: x.data_type, reverse=should_we_reverse)
     elif iSortCol_0 == 7:
         bwolist.sort(key=lambda x: x.version, reverse=should_we_reverse)
     elif iSortCol_0 == 8:
         bwolist.sort(key=lambda x: x.version, reverse=should_we_reverse)
     return bwolist
 
 
 def parse_bwids(bwolist):
     import ast
 
     return list(ast.literal_eval(bwolist))
 
 
 def dummy_function(obj, eng):
     """Workflow function not found for workflow."""
     pass
 
 
 class WorkflowMissing(object):
 
     """ Workflow is missing """
 
     workflow = [dummy_function]
 
 
 class WorkflowBase(object):
 
     """Base class for workflow.
 
     Interface to define which functions should be imperatively implemented,
     All workflows shoud inherit from this class.
     """
 
     @staticmethod
     def get_title(bwo, **kwargs):
         """Return the value to put in the title column of HoldingPen."""
         return "No title"
 
     @staticmethod
     def get_description(bwo, **kwargs):
         """Return the value to put in the title  column of HoldingPen."""
         return "No description"
 
     @staticmethod
     def formatter(obj, **kwargs):
         raise NotImplementedError
diff --git a/invenio/modules/workflows/views/holdingpen.py b/invenio/modules/workflows/views/holdingpen.py
index e387e2001..1d497011c 100644
--- a/invenio/modules/workflows/views/holdingpen.py
+++ b/invenio/modules/workflows/views/holdingpen.py
@@ -1,650 +1,636 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
 ## Copyright (C) 2013, 2014 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 """
 Holding Pen
 
 Holding Pen is an overlay over all objects (BibWorkflowObject) that
 have run through a workflow (BibWorkflowEngine). This area is targeted
 to catalogers and super users for inspecting ingestion workflows and
 submissions/depositions.
 
 Note: Currently work-in-progress.
 """
 
 import re
 import collections
 
 from six import iteritems, text_type
 
 from flask import (render_template, Blueprint, request, jsonify,
                    url_for, flash, session)
 from flask.ext.login import login_required
 from flask.ext.breadcrumbs import default_breadcrumb_root, register_breadcrumb
 from flask.ext.menu import register_menu
 
 from invenio.base.decorators import templated, wash_arguments
 from invenio.base.i18n import _
 from invenio.utils.date import pretty_date
 
 from ..models import BibWorkflowObject, Workflow, ObjectVersion
 from ..registry import actions, workflows
 from ..utils import get_workflow_definition, sort_bwolist, WorkflowBase
 from ..api import continue_oid_delayed, start_delayed
 
-
 blueprint = Blueprint('holdingpen', __name__, url_prefix="/admin/holdingpen",
                       template_folder='../templates',
                       static_folder='../static')
 
 default_breadcrumb_root(blueprint, '.holdingpen')
 
 REG_TD = re.compile("<td title=\"(.+?)\">(.+?)</td>", re.DOTALL)
 
 
 @blueprint.route('/', methods=['GET', 'POST'])
 @blueprint.route('/index', methods=['GET', 'POST'])
 @login_required
 @register_menu(blueprint, 'personalize.holdingpen', _('Your Pending Actions'))
 @register_breadcrumb(blueprint, '.', _('Holdingpen'))
 @templated('workflows/hp_index.html')
 def index():
     """
     Display main interface of Holdingpen.
 
     Acts as a hub for catalogers (may be removed)
     """
     # FIXME: Add user filtering
     bwolist = get_holdingpen_objects(version_showing=[ObjectVersion.HALTED])
     action_list = get_action_list(bwolist)
 
     return dict(tasks=action_list)
 
 
 @blueprint.route('/maintable', methods=['GET', 'POST'])
 @register_breadcrumb(blueprint, '.records', _('Records'))
 @login_required
 @templated('workflows/hp_maintable.html')
 def maintable():
     """Display main table interface of Holdingpen."""
     bwolist = get_holdingpen_objects()
     action_list = get_action_list(bwolist)
     my_tags = []
 
-    if 'tags' in session:
-        my_tags += session['tags']
-    else:
-        session['tags'] = my_tags
-    if 'workflows_version_showing' in session:
-        my_tags += session['workflows_version_showing']
-    else:
-        session['workflows_version_showing'] = my_tags
+    if 'holdingpen_tags' in session:
+        my_tags = session["holdingpen_tags"]
+
     if 'version' in request.args:
-        try:
-            if ObjectVersion.MAPPING[int(request.args.get('version'))] not in my_tags:
-                my_tags += [int(request.args.get('version'))]
-            if int(request.args.get('version')) not in session["workflows_version_showing"]:
-                session["workflows_version_showing"] += [int(request.args.get('version'))]
-        except Exception:
-            if request.args.get('version') not in my_tags:
-                my_tags += [request.args.get('version')]
-            if [request.args.get('version')] not in session["tags"]:
-                session["workflows_version_showing"] += [request.args.get('version')]
+        if ObjectVersion.MAPPING[int(request.args.get('version'))] not in my_tags:
+            my_tags += ObjectVersion.MAPPING[[int(request.args.get('version'))]]
     tags_to_print = ""
     for tag in my_tags:
-        try:
-            tags_to_print += ObjectVersion.MAPPING[tag]
-        except:
-            if tag:
-                tags_to_print += tag + ','
+        if tag:
+            tags_to_print += tag + ','
     return dict(bwolist=bwolist,
                 action_list=action_list,
                 tags=tags_to_print)
 
 
-@blueprint.route('/load_table', methods=['GET', 'POST'])
+@blueprint.route('/batch_action', methods=['GET', 'POST'])
 @login_required
-@templated('workflows/hp_maintable.html')
-def load_table():
-    """Get JSON data for the Holdingpen table.
+@wash_arguments({'bwolist': (text_type, "")})
+def batch_action(bwolist):
+    """Render action accepting single or multiple records."""
+    from ..utils import parse_bwids
+
+    bwolist = parse_bwids(bwolist)
 
-    Function used for the passing of JSON data to the DataTable
-    1] First checks for what record version to show
-    2] then sorting direction,
-    3] then if the user searched for something
-    and finally it builds the JSON to send.
-    """
-    workflows_cache = {}
-    version_showing = []
-    req = None
-    req_search = []
-    if request.json:
-        if "version" in request.json:
-            req = request.json["version"]
-        if "tags" in request.json:
-            req_search = request.json["tags"]
-            session["tags"] = req_search
-    if req is not None:
-        if "final" in req:
-            version_showing.append(ObjectVersion.FINAL)
-        if "halted" in req:
-            version_showing.append(ObjectVersion.HALTED)
-        if "running" in req:
-            version_showing.append(ObjectVersion.RUNNING)
-        if "initial" in req:
-            version_showing.append(ObjectVersion.INITIAL)
-        session['workflows_version_showing'] = version_showing
-        if req == []:
-            version_showing = ObjectVersion.MAPPING.keys()
-    elif 'workflows_version_showing' in session:
-        version_showing = session.get('workflows_version_showing', [])
-    try:
-        i_sortcol_0 = request.args.get('iSortCol_0')
-        s_sortdir_0 = request.args.get('sSortDir_0')
-        i_display_start = int(request.args.get('iDisplayStart'))
-        i_display_length = int(request.args.get('iDisplayLength'))
-        sEcho = int(request.args.get('sEcho')) + 1
-    except:
-        i_sortcol_0 = session.get('iSortCol_0', 0)
-        s_sortdir_0 = session.get('sSortDir_0', None)
-        i_display_start = session.get('iDisplayLength', 10)
-        i_display_length = session.get('iDisplayLength', 0)
-        sEcho = session.get('sEcho', 0) + 1
-
-    s_search = request.args.get('sSearch', None)
-    if s_search:
-        if req_search:
-            s_search = s_search.split(',') + req_search
-        else:
-            s_search = s_search.split(',') + session["tags"]
-    elif req_search:
-        s_search = req_search
-
-    if s_search is [u'']:
-        s_search = []
-    bwolist = get_holdingpen_objects(ssearch=s_search,
-                                     version_showing=version_showing)
-    if 'iSortCol_0' in session:
-        i_sortcol_0 = int(i_sortcol_0)
-        if i_sortcol_0 != session['iSortCol_0'] \
-                or s_sortdir_0 != session['sSortDir_0']:
-            bwolist = sort_bwolist(bwolist, i_sortcol_0, s_sortdir_0)
-    session['iDisplayStart'] = i_display_start
-    session['iDisplayLength'] = i_display_length
-    session['iSortCol_0'] = i_sortcol_0
-    session['sSortDir_0'] = s_sortdir_0
-    session['sEcho'] = sEcho
-
-    table_data = {
-        "aaData": []
-    }
     try:
-        table_data['iTotalRecords'] = len(bwolist)
-        table_data['iTotalDisplayRecords'] = len(bwolist)
-    except TypeError:
-        bwolist = get_holdingpen_objects(version_showing=version_showing)
-        table_data['iTotalRecords'] = len(bwolist)
-        table_data['iTotalDisplayRecords'] = len(bwolist)
-
-    # This will be simplified once Redis is utilized.
-    records_showing = 0
-    for bwo in bwolist[i_display_start:i_display_start + i_display_length]:
-        records_showing += 1
+        bwolist = map(int, bwolist)
+    except ValueError:
+        # Bad ID, we just pass for now
+        pass
 
-        action_name = bwo.get_action()
-        action_message = bwo.get_action_message()
-        if not action_message:
-            action_message = ""
-
-        action = actions.get(action_name, None)
-
-        workflows_uuid = bwo.id_workflow
-        if workflows_uuid and workflows_uuid not in workflows_cache:
-            workflows_cache[workflows_uuid] = workflows[Workflow.query.filter(Workflow.uuid == workflows_uuid).one().name]()
-
-        mini_action = None
-        if action:
-            mini_action = getattr(action, "render_mini", None)
-
-        record = bwo.get_data()
-        if not hasattr(record, "get"):
-            try:
-                record = dict(record)
-            except:
-                record = {}
-
-        if not workflows_uuid:
-            title = "No title"
-            description = "No description"
-            extra_data = bwo.get_extra_data()
-        else:
-            title = workflows_cache[workflows_uuid].get_title(bwo)
-            description = workflows_cache[workflows_uuid].get_description(bwo)
-            extra_data = bwo.get_extra_data()
-
-        row = render_template('workflows/row_formatter.html',
-                              title=title,
-                              object=bwo,
-                              record=record,
-                              extra_data=extra_data,
-                              description=description,
-                              action=action,
-                              mini_action=mini_action,
-                              action_message=action_message,
-                              pretty_date=pretty_date,
-                              )
-        d = {}
-        for key, value in REG_TD.findall(row):
-            d[key] = value.strip()
-
-        table_data['aaData'].append(
-            [d['id'],
-             d['checkbox'],
-             d['title'],
-             d['description'],
-             d['pretty_date'],
-             d['version'],
-             d['type'],
-             d['action']]
-        )
-    table_data['sEcho'] = sEcho
-    table_data['iTotalRecords'] = len(bwolist)
-    table_data['iTotalDisplayRecords'] = len(bwolist)
-    return jsonify(table_data)
+    objlist = []
+    workflow_func_list = []
+    w_metadata_list = []
+    info_list = []
+    actionlist = []
+    bwo_parent_list = []
+    logtext_list = []
+
+    objlist = [BibWorkflowObject.query.get(i) for i in bwolist]
+
+    for bwobject in objlist:
+        extracted_data = extract_data(bwobject)
+        bwo_parent_list.append(extracted_data['bwparent'])
+        logtext_list.append(extracted_data['logtext'])
+        info_list.append(extracted_data['info'])
+        w_metadata_list.append(extracted_data['w_metadata'])
+        workflow_func_list.append(extracted_data['workflow_func'])
+        if bwobject.get_action() not in actionlist:
+            actionlist.append(bwobject.get_action())
+
+    action_form = actions[actionlist[0]]
+
+    result = action_form().render(objlist, bwo_parent_list, info_list,
+                                  logtext_list, w_metadata_list,
+                                  workflow_func_list)
+    url, parameters = result
+
+    return render_template(url, **parameters)
 
 
 @blueprint.route('/get_version_showing', methods=['GET', 'POST'])
 @login_required
 def get_version_showing():
     """Return current version showing, from flask session."""
     try:
         return session['workflows_version_showing']
     except KeyError:
         return None
 
 
 @blueprint.route('/details/<int:objectid>', methods=['GET', 'POST'])
 @register_breadcrumb(blueprint, '.details', _("Record Details"))
 @login_required
 def details(objectid):
     """Display info about the object."""
     of = "hd"
     bwobject = BibWorkflowObject.query.get(objectid)
     from invenio.ext.sqlalchemy import db
 
     #formatted_data = bwobject.get_formatted_data(of)
     workflows_uuid = bwobject.id_workflow
     if workflows_uuid:
-        formatted_data = workflows[Workflow.query.filter(Workflow.uuid == workflows_uuid).one().name]().formatter(bwobject, formatter=None, format=of)
+        formatted_data = workflows[Workflow.query.get(workflows_uuid).name]().formatter(bwobject, formatter=None, format=of)
     else:
         formatted_data = ""
 
     extracted_data = extract_data(bwobject)
 
     action_name = bwobject.get_action()
     if action_name:
         action = actions[action_name]
         rendered_actions = action().render(bwobject)
     else:
         rendered_actions = {}
 
     if bwobject.id_parent:
         hbwobject_db_request = BibWorkflowObject.query.filter(
             db.or_(BibWorkflowObject.id_parent == bwobject.id_parent,
                    BibWorkflowObject.id == bwobject.id_parent,
                    BibWorkflowObject.id == bwobject.id)).all()
 
     else:
         hbwobject_db_request = BibWorkflowObject.query.filter(
             db.or_(BibWorkflowObject.id_parent == bwobject.id,
                    BibWorkflowObject.id == bwobject.id)).all()
 
     hbwobject = {ObjectVersion.FINAL: [], ObjectVersion.HALTED: [],
                  ObjectVersion.INITIAL: [], ObjectVersion.RUNNING: []}
 
     for hbobject in hbwobject_db_request:
         hbwobject[hbobject.version].append({"id": hbobject.id,
                                             "version": hbobject.version,
                                             "date": pretty_date(hbobject.created),
                                             "true_date": hbobject.modified})
 
     for list_of_object in hbwobject:
         hbwobject[list_of_object].sort(key=lambda x: x["true_date"], reverse=True)
 
     hbwobject_final = hbwobject[ObjectVersion.INITIAL] + \
         hbwobject[ObjectVersion.HALTED] + \
         hbwobject[ObjectVersion.FINAL]
 
     results = []
     for label, res in bwobject.get_tasks_results().iteritems():
         res_dicts = [item.to_dict() for item in res]
         results.append((label, res_dicts))
 
     return render_template('workflows/hp_details.html',
                            bwobject=bwobject,
                            rendered_actions=rendered_actions,
                            hbwobject=hbwobject_final,
                            bwparent=extracted_data['bwparent'],
                            info=extracted_data['info'],
                            log=extracted_data['logtext'],
                            data_preview=formatted_data,
                            workflow_func=extracted_data['workflow_func'],
                            workflow=extracted_data['w_metadata'],
                            task_results=results)
 
 
 @blueprint.route('/restart_record', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'objectid': (int, 0)})
 def restart_record(objectid, start_point='continue_next'):
     """Restart the initial object in its workflow."""
     bwobject = BibWorkflowObject.query.get(objectid)
 
     workflow = Workflow.query.filter(
         Workflow.uuid == bwobject.id_workflow).first()
 
     start_delayed(workflow.name, [bwobject.get_data()])
     return 'Record Restarted'
 
 
 @blueprint.route('/continue_record', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'objectid': (int, 0)})
 def continue_record(objectid):
     """Continue workflow for current object."""
     continue_oid_delayed(oid=objectid, start_point='continue_next')
     return 'Record continued workflow'
 
 
 @blueprint.route('/restart_record_prev', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'objectid': (int, 0)})
 def restart_record_prev(objectid):
     """Restart the last task for current object."""
     continue_oid_delayed(oid=objectid, start_point="restart_task")
     return 'Record restarted current task'
 
 
 @blueprint.route('/delete', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'objectid': (int, 0)})
 def delete_from_db(objectid):
     """Delete the object from the db."""
     BibWorkflowObject.delete(objectid)
     return 'Record Deleted'
 
 
 @blueprint.route('/delete_multi', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'bwolist': (text_type, "")})
 def delete_multi(bwolist):
     """Delete list of objects from the db."""
     from ..utils import parse_bwids
 
     bwolist = parse_bwids(bwolist)
     for objectid in bwolist:
         delete_from_db(objectid)
     return 'Records Deleted'
 
 
 @blueprint.route('/resolve', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'objectid': (text_type, '-1')})
 def resolve_action(objectid):
     """Resolve the action taken.
 
     Will call the run() function of the specific action.
     """
     bwobject = BibWorkflowObject.query.get(int(objectid))
     action_name = bwobject.get_action()
     action_form = actions[action_name]
     res = action_form().resolve(bwobject)
     return jsonify(res)
 
 
 @blueprint.route('/entry_data_preview', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'objectid': (text_type, '0'),
                  'of': (text_type, None)})
 def entry_data_preview(objectid, of):
     """Present the data in a human readble form or in xml code."""
     from flask import Markup
     from pprint import pformat
 
     bwobject = BibWorkflowObject.query.get(int(objectid))
 
     if not bwobject:
         flash("No object found for %s" % (objectid,))
         return jsonify(data={})
 
     workflows_uuid = bwobject.id_workflow
     if workflows_uuid:
-        formatted_data = workflows[Workflow.query.filter(Workflow.uuid == workflows_uuid).one().name]().formatter(bwobject, formatter=None, format=of)
+        formatted_data = workflows[Workflow.query.get(workflows_uuid).name]().formatter(bwobject, formatter=None, format=of)
     else:
         formatted_data = ""
     if isinstance(formatted_data, dict):
         formatted_data = pformat(formatted_data)
     if of and of in ("xm", "xml", "marcxml"):
         data = Markup.escape(formatted_data)
     else:
         data = formatted_data
     return jsonify(data=data)
 
 
 @blueprint.route('/get_context', methods=['GET', 'POST'])
 @login_required
 def get_context():
     """Return the a JSON structure with URL maps and actions."""
     context = {}
     context['url_prefix'] = blueprint.url_prefix
     context['holdingpen'] = {
         "url_load": url_for('holdingpen.load_table'),
         "url_preview": url_for('holdingpen.entry_data_preview'),
         "url_restart_record": url_for('holdingpen.restart_record'),
         "url_restart_record_prev": url_for('holdingpen.restart_record_prev'),
         "url_continue_record": url_for('holdingpen.continue_record'),
     }
     try:
         context['version_showing'] = session['workflows_version_showing']
     except KeyError:
         context['version_showing'] = ObjectVersion.HALTED
 
     return jsonify(context)
 
 
 def get_info(bwobject):
     """Parses the hpobject and extracts its info to a dictionary."""
     info = {}
     if bwobject.get_extra_data()['owner'] != {}:
         info['owner'] = bwobject.get_extra_data()['owner']
     else:
         info['owner'] = 'None'
     info['parent id'] = bwobject.id_parent
     info['workflow id'] = bwobject.id_workflow
     info['object id'] = bwobject.id
     info['action'] = bwobject.get_action()
     return info
 
 
 def extract_data(bwobject):
     """Extract needed metadata from BibWorkflowObject.
 
     Used for rendering the Record's holdingpen table row and
     details and action page.
     """
     extracted_data = {}
     if bwobject.id_parent is not None:
         extracted_data['bwparent'] = \
             BibWorkflowObject.query.get(bwobject.id_parent)
     else:
         extracted_data['bwparent'] = None
 
     # TODO: read the logstuff from the db
     extracted_data['loginfo'] = ""
     extracted_data['logtext'] = {}
 
     for log in extracted_data['loginfo']:
         extracted_data['logtext'][log.get_extra_data()['_last_task_name']] = \
             log.message
 
     extracted_data['info'] = get_info(bwobject)
     try:
         extracted_data['info']['action'] = bwobject.get_action()
     except (KeyError, AttributeError):
         pass
 
     extracted_data['w_metadata'] = \
         Workflow.query.filter(Workflow.uuid == bwobject.id_workflow).first()
     if extracted_data['w_metadata']:
         workflow_def = get_workflow_definition(extracted_data['w_metadata'].name)
         extracted_data['workflow_func'] = workflow_def
     else:
         extracted_data['workflow_func'] = [None]
     return extracted_data
 
 
 def get_action_list(object_list):
     """Return a dict of action names mapped to halted objects.
 
     Get a dictionary mapping from action name to number of Pending
     actions (i.e. halted objects). Used in the holdingpen.index page.
     """
     action_dict = {}
     found_actions = []
 
     # First get a list of all to count up later
     for bwo in object_list:
         action_name = bwo.get_action()
         if action_name is not None:
             found_actions.append(action_name)
 
     # Get "real" action name only once per action
     for action_name in set(found_actions):
         if action_name not in actions:
             # Perhaps some old action? Use stored name.
             action_nicename = action_name
         else:
             action = actions[action_name]
             action_nicename = getattr(action, "name", action_name)
         action_dict[action_nicename] = found_actions.count(action_name)
     return action_dict
 
 
-def get_holdingpen_objects(isortcol_0=None,
-                           ssortdir_0=None,
-                           ssearch=None,
-                           version_showing=(ObjectVersion.HALTED,)):
+@blueprint.route('/load_table', methods=['GET', 'POST'])
+@login_required
+@templated('workflows/hp_maintable.html')
+def load_table():
+    """Get JSON data for the Holdingpen table.
+
+    Function used for the passing of JSON data to the DataTable
+    1] First checks for what record version to show
+    2] then sorting direction,
+    3] then if the user searched for something
+    and finally it builds the JSON to send.
+    """
+    import time
+    StartA = time.time()
+    try:
+        workflows_cache = {}
+        if request.method == "POST":
+            if "holdingpen_tags" not in session:
+                session["holdingpen_tags"] = []
+            if request.json and "tags" in request.json:
+                tags = request.json["tags"]
+                session["holdingpen_tags"] = tags
+            elif "holdingpen_tags" in session:
+                tags = session["holdingpen_tags"]
+            else:
+                tags = []
+                session["holdingpen_tags"] = []
+                print "global request  {0}".format(time.time() - StartA)
+            return None
+        else:
+            if "holdingpen_tags" in session:
+                tags = session["holdingpen_tags"]
+            else:
+                tags = []
+                session["holdingpen_tags"] = []
+
+        i_sortcol_0 = request.args.get('iSortCol_0', session.get('iSortCol_0', 0))
+        s_sortdir_0 = request.args.get('sSortDir_0', session.get('sSortDir_0', None))
+
+        session["holdingpen_iDisplayStart"] = int(request.args.get('iDisplayStart', session.get('iDisplayLength', 10)))
+        session["holdingpen_iDisplayLength"] = int(request.args.get('iDisplayLength', session.get('iDisplayLength', 0)))
+        session["holdingpen_sEcho"] = int(request.args.get('sEcho', session.get('sEcho', 0))) + 1
+        bwolist = get_holdingpen_objects(tags)
+        print "get holdingpen object {0}".format(time.time() - StartA)
+        if 'iSortCol_0' in session and "sSortDir_0" in session:
+            i_sortcol_0 = int(str(i_sortcol_0))
+            if i_sortcol_0 != session['iSortCol_0'] or s_sortdir_0 != session['sSortDir_0']:
+                bwolist = sort_bwolist(bwolist, i_sortcol_0, s_sortdir_0)
+        session["holdingpen_iSortCol_0"] = i_sortcol_0
+        session["holdingpen_sSortDir_0"] = s_sortdir_0
+
+        table_data = {'aaData': [],
+                      'iTotalRecords': len(bwolist),
+                      'iTotalDisplayRecords': len(bwolist),
+                      'sEcho': session["holdingpen_sEcho"]}
+
+        # This will be simplified once Redis is utilized.
+        records_showing = 0
+        for bwo in bwolist[session["holdingpen_iDisplayStart"]:session["holdingpen_iDisplayStart"] + session["holdingpen_iDisplayLength"]]:
+            action_name = bwo.get_action()
+            action_message = bwo.get_action_message()
+            if not action_message:
+                action_message = ""
+
+            action = actions.get(action_name, None)
+            records_showing += 1
+            workflows_uuid = bwo.id_workflow
+            if workflows_uuid and workflows_uuid not in workflows_cache:
+                workflows_cache[workflows_uuid] = workflows[Workflow.query.get(workflows_uuid).name]()
+            mini_action = getattr(action, "mini_action", None)
+            record = bwo.get_data()
+            if not hasattr(record, "get"):
+                try:
+                    record = dict(record)
+                except:
+                    record = {}
+            if not workflows_uuid:
+                title = "No title"
+                description = "No description"
+                extra_data = bwo.get_extra_data()
+            else:
+                title = workflows_cache[workflows_uuid].get_title(bwo)
+                description = workflows_cache[workflows_uuid].get_description(bwo)
+                extra_data = bwo.get_extra_data()
+            row = render_template('workflows/row_formatter.html',
+                                  title=title,
+                                  object=bwo,
+                                  record=record,
+                                  extra_data=extra_data,
+                                  description=description,
+                                  action=action,
+                                  mini_action=mini_action,
+                                  action_message=action_message,
+                                  pretty_date=pretty_date,
+                                  )
+            d = {}
+            for key, value in REG_TD.findall(row):
+                d[key] = value.strip()
+
+            table_data['aaData'].append(
+                [d['id'],
+                 d['checkbox'],
+                 d['title'],
+                 d['description'],
+                 d['pretty_date'],
+                 d['version'],
+                 d['type'],
+                 d['action']]
+            )
+        print "global request  {0}".format(time.time() - StartA)
+        return jsonify(table_data)
+    except Exception as e:
+        print e
+
+
+def get_holdingpen_objects(ptags=[]):
     """Get BibWorkflowObject's for display in Holding Pen.
 
     Uses DataTable naming for filtering/sorting. Work in progress.
     """
+    import time
     workflows_cache = {}
-
-    if isortcol_0:
-        isortcol_0 = int(isortcol_0)
+    tags = ptags[:]
+    temp_list = ["New", "Done", "Need action", "In process"]
+    version_showing = []
+    for i in range(len(tags) - 1, -1, -1):
+        if tags[i] in temp_list:
+            version_showing.append(ObjectVersion.REVERSE_MAPPING[tags[i]])
+            del tags[i]
+
+    if version_showing is None:
+        version_showing = ObjectVersion.MAPPING.keys()
+    ssearch = tags
     bwobject_list = BibWorkflowObject.query.filter(
         BibWorkflowObject.id_parent == None
     ).filter(not version_showing or BibWorkflowObject.version.in_(
         version_showing)).all()
+
     if ssearch:
+        if not isinstance(ssearch, list):
+            if "," in ssearch:
+                ssearch = ssearch.split(",")
+            else:
+                ssearch = [ssearch]
+
         bwobject_list_tmp = []
         for bwo in bwobject_list:
-            extra_data = bwo.get_extra_data()
-            data = bwo.get_data()
-            if not isinstance(data, collections.Mapping):
-                data = {}
+            startA = time.time()
             workflows_uuid = bwo.id_workflow
             if workflows_uuid and workflows_uuid not in workflows_cache:
-                workflows_cache[workflows_uuid] = workflows[Workflow.query.filter(Workflow.uuid == workflows_uuid).one().name]()
-            all_parameters = {"record": data, "extra_data": extra_data,
-                              "bwo": bwo}
-            if not isinstance(ssearch, list):
-                if "," in ssearch:
-                    ssearch = ssearch.split(",")
-                else:
-                    ssearch = [ssearch]
+                workflows_cache[workflows_uuid] = workflows[Workflow.query.get(workflows_uuid).name]()
+
             if workflows_uuid:
                 checking_functions = {"title": workflows_cache[workflows_uuid].get_title,
                                       "description": workflows_cache[workflows_uuid].get_description,
                                       "created": get_pretty_date,
                                       "type": get_type
                                       }
             else:
                 checking_functions = {"title": WorkflowBase.get_title,
                                       "description": WorkflowBase.get_description,
                                       "created": get_pretty_date,
                                       "type": get_type
                                       }
-            confirm = 0
-            to_add = True
-
-            for term in ssearch:
-                for function in checking_functions:
-                    function = checking_functions[function]
-                    func_code = function.func_code
-                    if check_ssearch_over_data(term, function(
-                                               **dict((func_code.co_varnames[i],
-                                                       all_parameters[func_code.co_varnames[i]])
-                                                      for i in range(0, func_code.co_argcount)))):
-                        confirm += 1
-                if confirm == 0:
-                    to_add = False
-                confirm = 0
-
-            if to_add:
-                bwobject_list_tmp.append(bwo)
+            startB = time.time()
+            for function in checking_functions:
+                if check_ssearch_over_data(ssearch, checking_functions[function](bwo)):
+                    bwobject_list_tmp.append(bwo)
+                    break
+            else:
+                print "A {0}, B {1}, ratio {2}".format(time.time() - startA,time.time() - startB,(time.time() - startB)/(time.time() - startA))
+                break  # executed if the loop ended normally (no break)
+            print "A {0}, B {1}, ratio {2}".format(time.time() - startA,time.time() - startB,(time.time() - startB)/(time.time() - startA))
+            continue
+
         bwobject_list = bwobject_list_tmp
-    if isortcol_0 == -6:
-        if ssortdir_0 == 'desc':
-            bwobject_list.reverse()
     return bwobject_list
 
 
 def check_ssearch_over_data(ssearch, data):
     """
     Check if the data match with one of the search tag in data.
 
     :param ssearch: list of tags used for filtering.
     :param data: data to check.
     :return: True if present False otherwise.
     """
     if not isinstance(ssearch, list):
         if "," in ssearch:
             ssearch = ssearch.split(",")
         else:
             ssearch = [ssearch]
     if not isinstance(data, list):
         data = [data]
-    count = 0
+
+    result = True
+
     for terms in ssearch:
         for datum in data:
-            if terms.lower() in datum.lower():
-                count += 1
-    if count > 0:
-        return True
-    else:
-        return False
+            if terms.lower() not in datum.lower():
+                result = False
+                break
+    return result
 
 
 def get_pretty_date(bwo):
     return pretty_date(bwo.created)
 
 
 def get_type(bwo):
     """Get the type of the Object."""
     return bwo.data_type