diff --git a/bower.json b/bower.json
index ba7c4c074..f923d569d 100644
--- a/bower.json
+++ b/bower.json
@@ -1,41 +1,42 @@
 {
   "name": "invenio-grunt",
   "version": "0.1.0",
   "dependencies": {
     "bootstrap": "3.1.1",
     "jquery": "2.1.0",
     "font-awesome": "~4.0.3",
     "ckeditor": "latest"
   },
   "devDependencies": {
     "typeahead.js": "0.10.1",
     "hogan": "3.0.0",
     "jquery-tokeninput": "*",
     "MathJax": "v2.1-latest",
     "jquery_jeditable": "http://invenio-software.org/download/jquery/v1.5/js/jquery.jeditable.mini.js",
     "jquery.treeview": "1.4.1",
     "jquery.tablesorter": "http://invenio-software.org/download/jquery/jquery.tablesorter.20111208.zip",
     "jqueryui": "1.10.4",
     "jquery.ui.timepicker": "http://invenio-software.org/download/jquery/jquery-ui-timepicker-addon-1.0.3.js",
     "jquery.multifile": "http://jquery-multifile-plugin.googlecode.com/svn/trunk/jquery.MultiFile.pack.js",
     "jquery.ajaxpager": "http://invenio-software.org/download/jquery/v1.5/js/jquery.ajaxPager.js",
     "jquery.bookmark": "http://invenio-software.org/download/jquery/jquery.bookmark.package-1.4.0.zip",
     "DataTables": "1_9",
     "jquery-flot": "*",
     "form": "https://raw.github.com/malsup/form/master/jquery.form.js",
     "jquery.hotkeys": "*",
     "uploadify": "*",
     "json2": "*",
     "prism": "gh-pages",
     "swfobject": "https://github.com/swfobject/swfobject/blob/master/swfobject/swfobject.js",
     "datatables-colvis": "*",
     "typeahead.js-bootstrap3.less": "0.2.2",
     "DataTables-Plugins": "https://github.com/DataTables/Plugins.git",
     "plupload": "*",
     "bootstrap-switch": "https://github.com/nostalgiaz/bootstrap-switch.git#3.0",
-    "font-awesome": "*"
+    "font-awesome": "*",
+    "bootstrap-tagsinput": "*"
   },
   "resolutions": {
     "jquery": "2.1.0"
   }
 }
diff --git a/grunt/copy.js b/grunt/copy.js
index 099192b7b..2a16875a8 100644
--- a/grunt/copy.js
+++ b/grunt/copy.js
@@ -1,258 +1,261 @@
 /*
  * 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.
  */
 
 'use strict';
 
 /*jshint laxcomma:true */  // FIXME?
 
 
 module.exports = {
     css: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>',
         src: ['bootstrap/dist/css/bootstrap*'
                ,'font-awesome/css/font-awesome.*'
                ,'jquery-tokeninput/styles/token-input-facebook.css'
                ,'jquery-tokeninput/styles/token-input.css'
                ,'jquery.bookmark/jquery.bookmark.css'
                ,'datatables-colvis/media/css/ColVis.css'
                ,'DataTables-Plugins/integration/bootstrap/3/dataTables.bootstrap.css'
-               ,'prism/prism.css'],
+               ,'prism/prism.css'
+               ,'bootstrap-tagsinput/dist/bootstrap-tagsinput.css'],
         dest: '<%= globalConfig.installation_path %>/css/'
     },
     jquery_css: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>',
         src: ['jqueryui/themes/base/jquery.ui.datepicker.css'
              ,'jqueryui/themes/base/jquery.ui.theme.css'],
         dest: '<%= globalConfig.installation_path %>/img/jquery-ui/themes/base/'
     },
     jquery_imgs: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>',
         src: ['jqueryui/themes/base/images/ui-bg_flat_75_ffffff_40x100.png'],
         dest: '<%= globalConfig.installation_path %>/img/jquery-ui/themes/base/images/'
     },
     img: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['jquery.bookmark/bookmarks.png'
                ,'uploadify/uploadify*'
                ,'!uploadify/uploadify.php'
                ,'datatables-colvis/media/images/button.png'
                ,'DataTables-Plugins/integration/bootstrap/3/images/*.png'],
         dest: '<%= globalConfig.installation_path %>/img/'
     },
     js: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['bootstrap/dist/js/bootstrap.js'
              ,'bootstrap/dist/js/bootstrap.min.js'
              ,'jquery/dist/jquery.min.js'
              ,'jquery/dist/jquery.min.map'
              ,'jquery-tokeninput/src/jquery.tokeninput.js'
              ,'jquery.bookmark/jquery.bookmark.min.js'
              ,'DataTables/media/js/jquery.dataTables.js'
              ,'jquery-flot/excanvas.min.js'
              ,'jquery-flot/jquery.flot.js'
              ,'jquery-flot/jquery.flot.selection.js'
              ,'jquery.hotkeys/jquery.hotkeys.js'
              ,'uploadify/jquery.uploadify.min.js'
              ,'json2/json2.js'
              ,'datatables-colvis/media/js/ColVis.js'
              ,'DataTables-Plugins/integration/bootstrap/3/dataTables.bootstrap.js'
-             ,'prism/prism.js'],
+             ,'prism/prism.js'
+             ,'bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js'
+             ,'bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js.map'],
         dest: '<%= globalConfig.installation_path %>/js/'
     },
     fonts: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['bootstrap/dist/fonts/glyphicons-halflings-regular.*'
              ,'font-awesome/fonts/*'],
         dest: '<%= globalConfig.installation_path %>/fonts/'
     },
     typeahead: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['typeahead.js/dist/typeahead.bundle.min.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0),
                                   'typeahead.js');
             return dest + res;
         }
     },
     typeaheadBootstrap3Css: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/typeahead.js-bootstrap3.less',
         src: ['typeahead.css'],
         dest: '<%= globalConfig.installation_path %>/css/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0),
                                   'typeahead.js-bootstrap.css');
             return dest + res;
         }
     },
     hogan: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['hogan/web/builds/2.0.0/hogan-2.0.0.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             return dest + src.substring(0, src.indexOf('-')) + '.js';
         }
     },
     jqueryUI: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/jqueryui',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/js/jqueryui'
     },
     jqueryUISortable: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['jquery.ui/ui/jquery.ui.sortable.js'],
         dest: '<%= globalConfig.installation_path %>/js/'
     },
     jqueryTimePicker: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['jquery.ui.timepicker/index.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0),
                                   'jquery-ui-timepicker-addon.js');
             return dest + res;
         }
     },
     MultiFile: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['jquery.multifile/index.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0),
                                   'jquery.MultiFile.pack.js');
             return dest + res;
         }
     },
     ajaxPager: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['jquery.ajaxpager/index.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0),
                                   'jquery.ajaxPager.js');
             return dest + res;
         }
     },
     form: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['form/index.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0),
                                   'jquery.form.js');
             return dest + res;
         }
     },
     swfobject: {
         expand: true,
         flatten: true,
         cwd: '<%= globalConfig.bower_path %>/',
         src: ['swfobject/index.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             var res = src.replace(src.substring(0), 'swfobject.js');
             return dest + res;
         }
     },
     MathJax: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/MathJax/',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/MathJax/'
     },
     ckeditor: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/ckeditor/',
         src: ['**', '!**_samples/**', '!**_source/**', '!**php**',
               '!**_**', '!**pack**', '!**ckeditor.asp'],
         dest: '<%= globalConfig.installation_path %>/ckeditor/'
     },
     jqueryTreeview: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/jquery.treeview/',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/js/jquery-treeview/'
     },
     jqueryTableSorter: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/jquery.tablesorter/',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/js/tablesorter/'
     },
     themesUI: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/jquery.ui/themes/',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/img/jquery-ui/themes'
     },
     imagesUI: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/jquery.ui/themes/base/images/',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/img/images/'
     },
     jeditable: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/jquery_jeditable/',
         src: ['index.js'],
         dest: '<%= globalConfig.installation_path %>/js/',
         rename: function(dest, src) {
             if (src === 'index.js') {
                 return dest + 'jquery.jeditable.mini.js';
             }
             return dest + src;
         }
     },
     plupload: {
         expand: true,
         cwd: '<%= globalConfig.bower_path %>/plupload/js',
         src: ['**'],
         dest: '<%= globalConfig.installation_path %>/plupload/'
     }
 };
diff --git a/invenio/modules/deposit/models.py b/invenio/modules/deposit/models.py
index 189ddab69..f8090d7ac 100644
--- a/invenio/modules/deposit/models.py
+++ b/invenio/modules/deposit/models.py
@@ -1,1500 +1,1499 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
 ## Copyright (C) 2013 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.
 """
 Classes for wrapping BibWorkflowObject and friends to make it easier to
 work with the data attributes.
 """
 
 from uuid import uuid4
 import copy
 import json
 import os
 from datetime import datetime
 from dateutil.tz import tzutc
 
 from sqlalchemy.orm.exc import NoResultFound
 from werkzeug.datastructures import MultiDict
 from werkzeug.utils import secure_filename
 from flask import redirect, render_template, flash, url_for, request, \
     session
 from flask.ext.login import current_user
 from flask.ext.restful import fields, marshal
 from invenio.ext.restful import UTCISODateTime
 from invenio.base.helpers import unicodifier
 
 from invenio.ext.sqlalchemy import db
-from invenio.modules.workflows.config import CFG_OBJECT_VERSION, CFG_WORKFLOW_STATUS
-from invenio.modules.workflows.models import BibWorkflowObject, Workflow
-from invenio.modules.workflows.engine import BibWorkflowEngine
+from invenio.modules.workflows.models import BibWorkflowObject, Workflow, ObjectVersion
+from invenio.modules.workflows.engine import BibWorkflowEngine, WorkflowStatus
 from invenio.modules.workflows.api import continue_oid
 
 from . import forms
 from .form import CFG_FIELD_FLAGS, DataExporter
 from .signals import file_uploaded
 from .storage import Storage, DepositionStorage
 
 
 #
 # Exceptions
 #
 class DepositionError(Exception):
     """ Base class for deposition errors """
     pass
 
 
 class InvalidDepositionType(DepositionError):
     """ Raised when a deposition type cannot be found """
     pass
 
 
 class DepositionDoesNotExists(DepositionError):
     """ Raised when a deposition does not exists """
     pass
 
 
 class DraftDoesNotExists(DepositionError):
     """ Raised when a draft does not exists """
     pass
 
 
 class FormDoesNotExists(DepositionError):
     """ Raised when a draft does not exists """
     pass
 
 
 class FileDoesNotExists(DepositionError):
     """ Raised when a draft does not exists """
     pass
 
 
 class DepositionNotDeletable(DepositionError):
     """ Raised when a deposition cannot be deleted """
     pass
 
 
 class FilenameAlreadyExists(DepositionError):
     """ Raised when an identical filename is already present in a deposition"""
     pass
 
 
 class ForbiddenAction(DepositionError):
     """
     Raised when an action on a deposition, draft or file is not
     authorized
     """
     pass
 
 
 class InvalidApiAction(DepositionError):
     """ Raised when an invalid API action is requested """
     pass
 
 
 #
 # Helpers
 #
 class FactoryMixin(object):
     """
     Mix-in class to help create objects from persisted object state.
     """
     @classmethod
     def factory(cls, state, *args, **kwargs):
         obj = cls(*args, **kwargs)
         obj.__setstate__(state)
         return obj
 
 
 #
 # Primary classes
 #
 class DepositionType(object):
     """
     A base class for the deposition types to ensure certain
     properties are defined on each type.
 
     A deposition type is just a BibWorkflow with a couple of extra methods.
 
     To customize rendering behavior of the workflow for a given deposition type
     you can override the render_error(), render_step() and render_completed()
     methods.
     """
     workflow = []
     """ Workflow definition """
 
     name = ""
     """ Display name for this deposition type """
 
     name_plural = ""
     """ Plural version of display name for this deposition type """
 
     enabled = False
     """ Determines if type is enabled - TODO: REMOVE"""
 
     default = False
     """
     Determines if type is the default - warnings are issed if conflicts exsists
     TODO: remove
     """
 
     deletable = False
     """
     Determine if a deposition is deletable after submission.
     """
 
     editable = False
     """
     Determine if a deposition is editable after submission.
     """
 
     stopable = False
     """
     Determine if a deposition workflow can be stopped (i.e. discard changes).
     """
 
     group = None
     """ Name of group to include this type in. """
 
     api = False
     """
     Determines if API is enabled for this type (requires workflow to be
     compatible with the API).
     """
 
     draft_definitions = {'_default': None}
     """
     Dictionary of all drafts for this deposition type
     """
 
     marshal_file_fields = dict(
         checksum=fields.String,
         filename=fields.String(attribute='name'),
         id=fields.String(attribute='uuid'),
         filesize=fields.String(attribute='size'),
     )
     """ REST API structure of a file """
 
     marshal_draft_fields = dict(
         metadata=fields.Raw(attribute='values'),
         completed=fields.Boolean,
         id=fields.String,
     )
     """ REST API structure of a draft """
 
     marshal_deposition_fields = dict(
         id=fields.Integer,
         title=fields.String,
         created=UTCISODateTime,
         modified=UTCISODateTime,
         owner=fields.Integer(attribute='user_id'),
         state=fields.String,
         submitted=fields.Boolean,
         files=fields.Nested(marshal_file_fields),
         drafts=fields.Nested(marshal_draft_fields, attribute='drafts_list'),
     )
     """ REST API structure of a deposition """
 
     @classmethod
     def default_draft_id(cls, deposition):
         return '_default'
 
     @classmethod
     def render_error(cls, dummy_deposition):
         """
         Render a page when deposition had an workflow error.
 
         Method can be overwritten by subclasses to provide custom
         user interface.
         """
         flash('%(name)s deposition has returned error.' %
               {'name': cls.name}, 'error')
         return redirect(url_for('.index'))
 
     @classmethod
     def render_step(self, deposition):
         """
         Render a page for a given deposition step.
 
         Method can be overwritten by subclasses to provide custom
         user interface.
         """
         ctx = deposition.get_render_context()
         if ctx:
             return render_template(**ctx)
         else:
             return render_template('deposit/error.html', **dict(
                 depostion=deposition,
                 deposition_type=(
                     None if deposition.type.is_default()
                     else deposition.type.get_identifier()
                 ),
                 uuid=deposition.id,
                 my_depositions=Deposition.get_depositions(
                     current_user, type=deposition.type
                 ),
             ))
 
     @classmethod
     def render_completed(cls, dummy_deposition):
         """
         Render page when deposition was successfully completed (i.e workflow
         just finished successfully).
 
         Method can be overwritten by subclasses to provide custom
         user interface.
         """
         flash('%(name)s was successfully finished.' %
               {'name': cls.name}, 'success')
         return redirect(url_for('.index'))
 
     @classmethod
     def render_final(cls, deposition):
         """
         Render page when deposition was *already* successfully completed (i.e
         a finished workflow is being executed a second time).
 
         This allows you render e.g. a preview of the record. The distinction
         between render_completed and render_final is primarily useful for the
         REST API (see api_final and api_completed)
 
         Method can be overwritten by subclasses to provide custom
         user interface.
         """
         return cls.render_completed(deposition)
 
     @classmethod
     def api_completed(cls, deposition):
         """
         Workflow just finished processing so return an 202 Accepted, since
         usually further background processing may happen.
         """
         return deposition.marshal(), 202
 
     @classmethod
     def api_final(cls, deposition):
         """
         Workflow already finished, and the user tries to re-execute the
         workflow, so send a 400 Bad Request back.
         """
         return dict(
             message="Deposition workflow already completed",
             status=400,
         ), 400
 
     @classmethod
     def api_step(cls, deposition):
         """
         Workflow was halted during processing. The workflow task that halted
         processing is expected to provide a response to send back to the
         client.
 
         The default response code is 500 Internal Server Error. A workflow task
         is expected to use Deposition.set_render_context() with a dictionary
         which is returned to the client. Set the key 'status', to change the
         status code, e.g.::
 
             d.set_render_context(dict(status=400, message="Bad request"))
 
         If no response is provided by the workflow task, it is regarded as
         an internal server error.
         """
         ctx = deposition.get_render_context()
         if ctx:
             return ctx.get('response', {}), ctx.get('status', 500)
         return cls.api_error(deposition)
 
     @classmethod
     def api_error(cls, deposition):
         return dict(message='Internal Server Error', status=500), 500
 
     @classmethod
     def api_action(cls, deposition, action_id):
         if action_id == 'run':
             return deposition.run_workflow(headless=True)
         elif action_id == 'reinitialize':
             deposition.reinitialize_workflow()
             return deposition.run_workflow(headless=True)
         elif action_id == 'stop':
             deposition.stop_workflow()
             return deposition.run_workflow(headless=True)
         raise InvalidApiAction(action_id)
 
     @classmethod
     def api_metadata_schema(cls, draft_id):
         """
         Get the input validation schema for this draft_id
 
         Allows you to override API defaults.
         """
         from wtforms.fields.core import FieldList, FormField
 
         if draft_id in cls.draft_definitions:
             schema = dict()
             formclass = cls.draft_definitions[draft_id]
             for fname, fclass in formclass()._fields.items():
 
                 if isinstance(fclass, FieldList):
                     schema[fname] = dict(type='list')
                 elif isinstance(fclass, FormField):
                     schema[fname] = dict(type='dict')
                 else:
                     schema[fname] = dict(type='any')
             return dict(type='dict', schema=schema)
         return None
 
     @classmethod
     def marshal_deposition(cls, obj):
         """
         Generate a JSON representation for REST API of a Deposition
         """
         return marshal(obj, cls.marshal_deposition_fields)
 
     @classmethod
     def marshal_draft(cls, obj):
         """
         Generate a JSON representation for REST API of a DepositionDraft
         """
         return marshal(obj, cls.marshal_draft_fields)
 
     @classmethod
     def marshal_file(cls, obj):
         """
         Generate a JSON representation for REST API of a DepositionFile
         """
         return marshal(obj, cls.marshal_file_fields)
 
     @classmethod
     def authorize(cls, deposition, action):
         if action == 'create':
             return True  # Any authenticated user
         elif action == 'delete':
             if deposition.has_sip():
                 return deposition.type.deletable
             return True
         elif action == 'reinitialize':
             return deposition.type.editable
         elif action == 'stop':
             return deposition.type.stopable
         elif action in ['add_file', 'remove_file', 'sort_files']:
             # Don't allow to add/remove/sort files after first submission
             return not deposition.has_sip()
         elif action in ['add_draft', ]:
             # Allow adding drafts when inprogress (independent of SIP exists
             # or not).
             return deposition.state == 'inprogress'
         else:
             return not deposition.has_sip()
 
     @classmethod
     def authorize_draft(cls, deposition, draft, action):
         if action == 'update':
             # If deposition allows adding  a draft, then allow editing the
             # draft.
             return cls.authorize(deposition, 'add_draft')
         return cls.authorize(deposition, 'add_draft')
 
     @classmethod
     def authorize_file(cls, deposition, deposition_file, action):
         return cls.authorize(deposition, 'add_file')
 
     @classmethod
     def get_identifier(cls):
         """ Get type identifier (identical to workflow name) """
         return cls.__name__
 
     @classmethod
     def is_enabled(cls):
         """ Check if workflow is enabled """
         # Wrapping in a method to eventually allow enabling/disabling
         # via configuration.
         return cls.enabled
 
     @classmethod
     def is_default(cls):
         """ Check if workflow is the default """
         # Wrapping in a method to eventually allow configuration
         # via configuration.
         return cls.default
 
     @classmethod
     def run_workflow(cls, deposition):
         """
         Run workflow for the given BibWorkflowObject.
 
         Usually not invoked directly, but instead indirectly through
         Deposition.run_workflow().
         """
         return continue_oid(
             deposition.id,
             start_point="restart_task",
         )
 
     @classmethod
     def reinitialize_workflow(cls, deposition):
         # Only reinitialize if really needed (i.e. you can only
         # reinitialize a fully completed workflow).
         wo = deposition.workflow_object
-        if wo.version == CFG_OBJECT_VERSION.FINAL and \
-           wo.workflow.status == CFG_WORKFLOW_STATUS.COMPLETED:
+        if wo.version == ObjectVersion.FINAL and \
+           wo.workflow.status == WorkflowStatus.COMPLETED:
 
-            wo.version = CFG_OBJECT_VERSION.RUNNING
-            wo.workflow.status = CFG_WORKFLOW_STATUS.RUNNING
+            wo.version = ObjectVersion.RUNNING
+            wo.workflow.status = WorkflowStatus.RUNNING
 
             # Clear deposition drafts
             deposition.drafts = {}
 
     @classmethod
     def stop_workflow(cls, deposition):
         # Only stop workflow if really needed
         wo = deposition.workflow_object
-        if wo.version != CFG_OBJECT_VERSION.FINAL and \
-           wo.workflow.status != CFG_WORKFLOW_STATUS.COMPLETED:
+        if wo.version != ObjectVersion.FINAL and \
+           wo.workflow.status != WorkflowStatus.COMPLETED:
 
             # Only workflows which has been fully completed once before
             # can be stopped
             if deposition.has_sip():
-                wo.version = CFG_OBJECT_VERSION.FINAL
-                wo.workflow.status = CFG_WORKFLOW_STATUS.COMPLETED
+                wo.version = ObjectVersion.FINAL
+                wo.workflow.status = WorkflowStatus.COMPLETED
 
                 # Clear all drafts
                 deposition.drafts = {}
 
                 # Set title - FIXME: find better way to set title
                 sip = deposition.get_latest_sip(sealed=True)
                 title = sip.metadata.get('title', 'Untitled')
                 deposition.title = title
 
     @classmethod
     def all(cls):
         """ Get a dictionary of deposition types """
         from .registry import deposit_types
         return deposit_types.mapping()
 
     @classmethod
     def get(cls, identifier):
         try:
             return cls.all()[identifier]
         except KeyError:
             raise InvalidDepositionType(identifier)
 
     @classmethod
     def keys(cls):
         """ Get a list of deposition type names """
         return cls.all().keys()
 
     @classmethod
     def values(cls):
         """ Get a list of deposition type names """
         return cls.all().values()
 
     @classmethod
     def get_default(cls):
         """ Get a list of deposition type names """
         from .registry import deposit_default_type
         return deposit_default_type.get()
 
     def __unicode__(self):
         """ Return a name for this class """
         return self.get_identifier()
 
 
 class DepositionFile(FactoryMixin):
     """
     Represents an uploaded file
 
     Creating a normal deposition file::
 
         uploaded_file = request.files['file']
         filename = secure_filename(uploaded_file.filename)
         backend = DepositionStorage(deposition_id)
 
         d = DepositionFile(backend=backend)
         d.save(uploaded_file, filename)
 
     Creating a chunked deposition file::
 
         uploaded_file = request.files['file']
         filename = secure_filename(uploaded_file.filename)
         chunk = request.files['chunk']
         chunks = request.files['chunks']
         backend = ChunkedDepositionStorage(deposition_id)
 
         d = DepositionFile(id=file_id, backend=backend)
         d.save(uploaded_file, filename, chunk, chunks)
         if chunk == chunks:
             d.save(finish=True, filename=filename)
 
     Reading a file::
 
         d = DepositionFile.from_json(data)
 
         if d.is_local():
             send_file(d.get_syspath())
         else:
             redirect(d.get_url())
 
         d.delete()
 
     Deleting a file::
 
         d = DepositionFile.from_json(data)
         d.delete()
 
     """
     def __init__(self, uuid=None, backend=None):
         self.uuid = uuid or str(uuid4())
         self._backend = backend
         self.name = ''
 
     def __getstate__(self):
         # TODO: Add content_type attributes
         return dict(
             id=self.uuid,
             path=self.path,
             name=self.name,
             size=self.size,
             checksum=self.checksum,
             #bibdoc=self.bibdoc
         )
 
     def __setstate__(self, state):
         self.uuid = state['id']
         self._path = state['path']
         self.name = state['name']
         self.size = state['size']
         self.checksum = state['checksum']
 
     def __repr__(self):
         data = self.__getstate__()
         del data['path']
         return json.dumps(data)
 
     @property
     def backend(self):
         if not self._backend:
             self._backend = Storage(None)
         return self._backend
 
     @property
     def path(self):
         if self._path is None:
             raise Exception("No path set")
         return self._path
 
     def save(self, incoming_file, filename=None, *args, **kwargs):
         self.name = secure_filename(filename or incoming_file.filename)
         (self._path, self.size, self.checksum, result) = self.backend.save(
             incoming_file, filename, *args, **kwargs
         )
         return result
 
     def delete(self):
         """ Delete the file on storage """
         return self.backend.delete(self.path)
 
     def is_local(self):
         """ Determine if file is a local file """
         return self.backend.is_local(self.path)
 
     def get_url(self):
         """ Get a URL for the file """
         return self.backend.get_url(self.path)
 
     def get_syspath(self):
         """ Get a local system path to the file """
         return self.backend.get_syspath(self.path)
 
 
 class DepositionDraftCacheManager(object):
     """
     Draft cache manager takes care of storing draft values in the cache prior
     to a workflow being run. The data can be loaded by the prefill_draft()
     workflow task.
     """
     def __init__(self, user_id):
         self.user_id = user_id
         self.data = {}
 
     @classmethod
     def from_request(cls):
         """
         Create a new draft cache from the current request.
         """
         obj = cls(current_user.get_id())
 
         # First check if we can get it via a json
         data = request.get_json(silent=True)
         if not data:
             # If, not simply merge all both query parameters and request body
             # parameters.
             data = request.values.to_dict()
         obj.data = data
         return obj
 
     @classmethod
     def get(cls):
         obj = cls(current_user.get_id())
         obj.load()
         return obj
 
     def save(self):
         """ Save data to session """
         if self.has_data():
             session['deposit_prefill'] = self.data
             session.modified = True
         else:
             self.delete()
 
     def load(self):
         """ Load data from session """
         self.data = session.get('deposit_prefill', {})
 
     def delete(self):
         """ Delete data in session """
         if 'deposit_prefill' in session:
             del session['deposit_prefill']
             session.modified = True
 
     def has_data(self):
         """
         Determine if the cache has data.
         """
         return bool(self.data)
 
     def fill_draft(self, deposition, draft_id, clear=True):
         """
         Fill a draft with cached draft values
         """
         draft = deposition.get_or_create_draft(draft_id)
         draft.process(self.data)
 
         if clear:
             self.data = {}
             self.delete()
         return draft
 
 
 class DepositionDraft(FactoryMixin):
     """
     Represents the state of a form
     """
     def __init__(self, draft_id, form_class=None, deposition_ref=None):
         self.id = draft_id
         self.completed = False
         self.form_class = form_class
         self.values = {}
         self.flags = {}
         self._form = None
         # Back reference to the depositions
         self._deposition_ref = deposition_ref
         self.validate = False
 
     def __getstate__(self):
         return dict(
             completed=self.completed,
             values=self.values,
             flags=self.flags,
             validate=self.validate,
         )
 
     def __setstate__(self, state):
         self.completed = state['completed']
         self.form_class = None
         if self._deposition_ref:
             self.form_class = self._deposition_ref.type.draft_definitions.get(
                 self.id
             )
         self.values = state['values']
         self.flags = state['flags']
         self.validate = state.get('validate', True)
 
     def is_completed(self):
         return self.completed
 
     def has_form(self):
         return self.form_class is not None
 
     def authorize(self, action):
         if not self._deposition_ref:
             return True  # Not connected to deposition so authorize anything.
         return self._deposition_ref.type.authorize_draft(
             self._deposition_ref, self, action
         )
 
     def complete(self):
         """
         Set state of draft to completed.
         """
         self.completed = True
 
     def update(self, form):
         """
         Update draft values and flags with data from form.
         """
         data = dict((key, value) for key, value in form.data.items()
                     if value is not None)
 
         self.values = data
         self.flags = form.get_flags()
 
     def process(self, data, complete_form=False):
         """
         Process, validate and store incoming form data and return response.
         """
         if not self.authorize('update'):
             raise ForbiddenAction('update', self)
 
         if not self.has_form():
             raise FormDoesNotExists(self.id)
 
         # The form is initialized with form and draft data. The original
         # draft_data is accessible in Field.object_data, Field.raw_data is the
         # new form data and Field.data is the processed form data or the
         # original draft data.
         #
         # Behind the scences, Form.process() is called, which in turns call
         # Field.process_data(), Field.process_formdata() and any filters
         # defined.
         #
         # Field.object_data contains the value of process_data(), while
         # Field.data contains the value of process_formdata() and any filters
         # applied.
         form = self.get_form(formdata=data)
 
         # Run form validation which will call Field.pre_valiate(),
         # Field.validators, Form.validate_<field>() and Field.post_validate().
         # Afterwards Field.data has been validated and any errors will be
         # present in Field.errors.
         validated = form.validate()
 
         # Call Form.run_processors() which in turn will call
         # Field.run_processors() that allow fields to set flags (hide/show)
         # and values of other fields after the entire formdata has been
         # processed and validated.
         validated_flags, validated_data, validated_msgs = (
             form.get_flags(), form.data, form.messages
         )
         form.post_process(formfields=[] if complete_form else data.keys())
         post_processed_flags, post_processed_data, post_processed_msgs = (
             form.get_flags(), form.data, form.messages
         )
 
         # Save form values
         self.update(form)
 
         # Build result dictionary
         process_field_names = None if complete_form else data.keys()
 
         # Determine if some fields where changed during post-processing.
         changed_values = dict(
             (name, value) for name, value in post_processed_data.items()
             if validated_data[name] != value
         )
         # Determine changed flags
         changed_flags = dict(
             (name, flags) for name, flags in post_processed_flags.items()
             if validated_flags[name] != flags
         )
         # Determine changed messages
         changed_msgs = dict(
             (name, messages) for name, messages in post_processed_msgs.items()
             if validated_msgs[name] != messages or process_field_names is None
             or name in process_field_names
         )
 
         result = {}
 
         if changed_msgs:
             result['messages'] = changed_msgs
         if changed_values:
             result['values'] = changed_values
         if changed_flags:
             for flag in CFG_FIELD_FLAGS:
                 fields = [
                     (name, flag in field_flags)
                     for name, field_flags in changed_flags.items()
                 ]
                 result[flag + '_on'] = map(
                     lambda x: x[0], filter(lambda x: x[1], fields)
                 )
                 result[flag + '_off'] = map(
                     lambda x: x[0], filter(lambda x: not x[1], fields)
                 )
 
         return form, validated, result
 
     def get_form(self, formdata=None, load_draft=True,
                  validate_draft=False):
         """
         Create form instance with draft data and form data if provided.
 
         :param formdata: Incoming form data.
         :param files: Files to ingest into form
         :param load_draft: True to initialize form with draft data.
         :param validate_draft: Set to true to validate draft data, when no form
              data is provided.
         """
         if not self.has_form():
             raise FormDoesNotExists(self.id)
 
         # If a field is not present in formdata, Form.process() will assume it
         # is blank instead of using the draft_data value. Most of the time we
         # are only submitting a single field in JSON via AJAX requests. We
         # therefore reset non-submitted fields to the draft_data value with
         # form.reset_field_data().
 
         # WTForms deal with unicode - we deal with UTF8 so convert all
         draft_data = unicodifier(self.values) if load_draft else {}
         formdata = MultiDict(formdata or {})
 
         form = self.form_class(
             formdata=formdata, **draft_data
         )
         if formdata:
             form.reset_field_data(exclude=formdata.keys())
 
         # Set field flags
         if load_draft and self.flags:
             form.set_flags(self.flags)
 
         # Ingest files in form
         if self._deposition_ref:
             form.files = self._deposition_ref.files
         else:
             form.files = []
 
         if validate_draft and draft_data and formdata is None:
             form.validate()
 
         return form
 
     @classmethod
     def merge_data(cls, drafts):
         """
         Merge data of multiple drafts
 
         Duplicate keys will be overwritten without warning.
         """
         data = {}
         # Don't include *) disabled fields, and *) empty optional fields
         func = lambda f: not f.flags.disabled and (f.flags.required or f.data)
 
         for d in drafts:
             if d.has_form():
                 visitor = DataExporter(
                     filter_func=func
                 )
                 visitor.visit(d.get_form())
                 data.update(visitor.data)
             else:
                 data.update(d.values)
 
         return data
 
 
 class Deposition(object):
     """
     Wraps a BibWorkflowObject
 
     Basically an interface to work with BibWorkflowObject data attribute in an
     easy manner.
     """
     def __init__(self, workflow_object, type=None, user_id=None):
         self.workflow_object = workflow_object
         if not workflow_object:
             self.files = []
             self.drafts = {}
             self.type = self.get_type(type)
             self.title = ''
             self.sips = []
 
             self.engine = BibWorkflowEngine(
                 name=self.type.get_identifier(),
                 id_user=user_id,
                 module_name="webdeposit"
             )
             self.workflow_object = BibWorkflowObject(
                 id_workflow=self.engine.uuid,
                 id_user=user_id,
-                version=CFG_OBJECT_VERSION.RUNNING,
+                version=ObjectVersion.RUNNING,
             )
             self.workflow_object.set_data({})
         else:
             self.__setstate__(workflow_object.get_data())
             self.engine = None
 
     #
     # Properties proxies to BibWorkflowObject
     #
     @property
     def id(self):
         return self.workflow_object.id
 
     @property
     def user_id(self):
         return self.workflow_object.id_user
 
     @property
     def created(self):
         return self.workflow_object.created
 
     @property
     def modified(self):
         return self.workflow_object.modified
 
     @property
     def drafts_list(self):
         # Needed for easy marshaling by API
         return self.drafts.values()
 
     #
     # Proxy methods
     #
     def authorize(self, action):
         """
         Determine if certain action is authorized
 
         Delegated to deposition type to allow overwriting default behavior.
         """
         return self.type.authorize(self, action)
 
     #
     #  Serialization related methods
     #
     def marshal(self):
         """
         API representation of an object.
 
         Delegated to the DepositionType, to allow overwriting default
         behaviour.
         """
         return self.type.marshal_deposition(self)
 
     def __getstate__(self):
         """
         Serialize deposition state for storing in the BibWorkflowObject
         """
         # The bibworkflow object id and owner is implicit, as the Deposition
         # object only wraps the data attribute of a BibWorkflowObject.
 
         # FIXME: Find better solution for setting the title.
         for d in self.drafts.values():
             if 'title' in d.values:
                 self.title = d.values['title']
                 break
 
         return dict(
             type=self.type.get_identifier(),
             title=self.title,
             files=[f.__getstate__() for f in self.files],
             drafts=dict(
                 [(d_id, d.__getstate__()) for d_id, d in self.drafts.items()]
             ),
             sips=[f.__getstate__() for f in self.sips],
         )
 
     def __setstate__(self, state):
         """
         Deserialize deposition from state stored in BibWorkflowObject
         """
         self.type = DepositionType.get(state['type'])
         self.title = state['title']
         self.files = [
             DepositionFile.factory(
                 f_state,
                 uuid=f_state['id'],
                 backend=DepositionStorage(self.id),
             )
             for f_state in state['files']
         ]
         self.drafts = dict(
             [(d_id, DepositionDraft.factory(d_state, d_id,
                                             deposition_ref=self))
              for d_id, d_state in state['drafts'].items()]
         )
         self.sips = [
             SubmissionInformationPackage.factory(s_state, uuid=s_state['id'])
             for s_state in state.get('sips', [])
         ]
 
     #
     # Persistence related methods
     #
     def update(self):
         """
         Update workflow object with latest data.
         """
         data = self.__getstate__()
         # BibWorkflow calls get_data() before executing any workflow task, and
         # and calls set_data() after. Hence, unless we update the data
         # attribute it will be overwritten.
         try:
             self.workflow_object.data = data
         except AttributeError:
             pass
         self.workflow_object.set_data(data)
 
     def reload(self):
         """
         Get latest data from workflow object
         """
         self.__setstate__(self.workflow_object.get_data())
 
     def save(self):
         """
         Save the state of the deposition.
 
         Uses the __getstate__ method to make a JSON serializable
         representation which, sets this as data on the workflow object
         and saves it.
         """
         self.update()
         if self.engine:
-            self.engine.save(status=CFG_WORKFLOW_STATUS.RUNNING)
+            self.engine.save(status=WorkflowStatus.RUNNING)
         self.workflow_object.save(
-            version=self.workflow_object.version or CFG_OBJECT_VERSION.RUNNING
+            version=self.workflow_object.version or ObjectVersion.RUNNING
         )
 
     def delete(self):
         """
         Delete the current deposition
         """
         if not self.authorize('delete'):
             raise DepositionNotDeletable(self)
 
         for f in self.files:
             f.delete()
 
         if self.workflow_object.id_workflow != '':
             if self.workflow_object.id_workflow:
                 Workflow.delete(uuid=self.workflow_object.id_workflow)
 
             BibWorkflowObject.query.filter_by(
                 id_workflow=self.workflow_object.id_workflow
             ).delete()
         else:
             db.session.remove(self.workflow_object)
         db.session.commit()
 
     #
     # Workflow execution
     #
     def run_workflow(self, headless=False):
         """
         Execute the underlying workflow
 
         If you made modifications to the deposition you must save if before
         running the workflow, using the save() method.
         """
         current_status = self.workflow_object.workflow.status
-        if current_status == CFG_WORKFLOW_STATUS.COMPLETED:
+        if current_status == WorkflowStatus.COMPLETED:
             return self.type.api_final(self) if headless \
                 else self.type.render_final(self)
 
         self.update()
         status = self.type.run_workflow(self).status
         self.reload()
 
-        if status == CFG_WORKFLOW_STATUS.ERROR:
+        if status == WorkflowStatus.ERROR:
             return self.type.api_error(self) if headless else \
                 self.type.render_error(self)
-        elif status != CFG_WORKFLOW_STATUS.COMPLETED:
+        elif status != WorkflowStatus.COMPLETED:
             return self.type.api_step(self) if headless else \
                 self.type.render_step(self)
-        elif status == CFG_WORKFLOW_STATUS.COMPLETED:
+        elif status == WorkflowStatus.COMPLETED:
             return self.type.api_completed(self) if headless else \
                 self.type.render_completed(self)
 
     def reinitialize_workflow(self):
         """
         Reinitialize a workflow object (i.e. prepare it for editing)
         """
         if self.state != 'done':
             raise DepositionError("Action only allowed for depositions in "
                                   "state 'done'.")
 
         if not self.authorize('reinitialize'):
             raise ForbiddenAction('reinitialize', self)
 
         self.type.reinitialize_workflow(self)
 
     def stop_workflow(self):
         """
         Stop a running workflow object (e.g. discard changes while editing).
         """
         if self.state != 'inprogress' or not self.submitted:
             raise DepositionError("Action only allowed for depositions in "
                                   "state 'inprogress'.")
 
         if not self.authorize('stop'):
             raise ForbiddenAction('stop', self)
 
         self.type.stop_workflow(self)
 
     def set_render_context(self, ctx):
         """
         Set rendering context - used in workflow tasks to set what is to be
         rendered (either by API or UI)
         """
         self.workflow_object.deposition_context = ctx
 
     def get_render_context(self):
         """
         Get rendering context - used by DepositionType.render_step/api_step
         """
         return getattr(self.workflow_object, 'deposition_context', {})
 
     @property
     def state(self):
         """
         Return simplified workflow state - inprogress, done or error
         """
         try:
             status = self.workflow_object.workflow.status
-            if status == CFG_WORKFLOW_STATUS.ERROR:
+            if status == WorkflowStatus.ERROR:
                 return "error"
-            elif status == CFG_WORKFLOW_STATUS.COMPLETED:
+            elif status == WorkflowStatus.COMPLETED:
                 return "done"
         except AttributeError:
             pass
         return "inprogress"
 
     #
     # Draft related methods
     #
     def get_draft(self, draft_id):
         """
         Get draft
         """
         if draft_id not in self.drafts:
             raise DraftDoesNotExists(draft_id)
         return self.drafts[draft_id]
 
     def get_or_create_draft(self, draft_id):
         """
         Get or create a draft for given draft_id
         """
         if draft_id not in self.drafts:
             if draft_id not in self.type.draft_definitions:
                 raise DraftDoesNotExists(draft_id)
 
             if not self.authorize('add_draft'):
                 raise ForbiddenAction('add_draft', self)
 
             self.drafts[draft_id] = DepositionDraft(
                 draft_id,
                 form_class=self.type.draft_definitions[draft_id],
                 deposition_ref=self,
             )
         return self.drafts[draft_id]
 
     def get_default_draft_id(self):
         """
         Get the default draft id for this deposition.
         """
         return self.type.default_draft_id(self)
 
     #
     # Submission information package related methods
     #
     def get_latest_sip(self, sealed=None):
         """
         Get the latest submission information package
 
         :param sealed: Set to true to only returned latest sealed SIP. Set to
             False to only return latest unsealed SIP.
         """
         if len(self.sips) > 0:
             for sip in reversed(self.sips):
                 if sealed is None:
                     return sip
                 elif sealed and sip.is_sealed():
                     return sip
                 elif not sealed and not sip.is_sealed():
                     return sip
         return None
 
     def create_sip(self):
         """
         Create a new submission information package (SIP) with metadata from
         the drafts.
         """
         metadata = DepositionDraft.merge_data(self.drafts.values())
         metadata['files'] = map(
             lambda x: dict(path=x.path, name=os.path.splitext(x.name)[0]),
             self.files
         )
 
         sip = SubmissionInformationPackage(metadata=metadata)
         self.sips.append(sip)
 
         return sip
 
     def has_sip(self, sealed=True):
         """
         Determine if deposition has a sealed submission information package.
         """
         for sip in self.sips:
             if (sip.is_sealed() and sealed) or \
                (not sealed and not sip.is_sealed()):
                 return True
         return False
 
     @property
     def submitted(self):
         return self.has_sip()
 
     #
     # File related methods
     #
     def get_file(self, file_id):
         for f in self.files:
             if f.uuid == file_id:
                 return f
         return None
 
     def add_file(self, deposition_file):
         if not self.authorize('add_file'):
             raise ForbiddenAction('add_file', self)
 
         for f in self.files:
             if f.name == deposition_file.name:
                 raise FilenameAlreadyExists(deposition_file.name)
         self.files.append(deposition_file)
         file_uploaded.send(
             self.type.get_identifier(),
             deposition=self,
             deposition_file=deposition_file,
         )
 
     def remove_file(self, file_id):
         if not self.authorize('remove_file'):
             raise ForbiddenAction('remove_file', self)
 
         idx = None
         for i, f in enumerate(self.files):
             if f.uuid == file_id:
                 idx = i
 
         if idx is not None:
             return self.files.pop(idx)
         return None
 
     def sort_files(self, file_id_list):
         """
         Order the files according the list of ids provided to this function.
         """
         if not self.authorize('sort_files'):
             raise ForbiddenAction('sort_files', self)
 
         search_dict = dict(
             [(f, i) for i, f in enumerate(file_id_list)]
         )
 
         def _sort_files_cmp(f_x, f_y):
             i_x = search_dict.get(f_x.uuid, None)
             i_y = search_dict.get(f_y.uuid, None)
             if i_x == i_y:
                 return 0
             elif i_x is None or i_x > i_y:
                 return 1
             elif i_y is None or i_x < i_y:
                 return -1
 
         self.files = sorted(self.files, _sort_files_cmp)
 
     #
     # Class methods
     #
     @classmethod
     def get_type(self, type_or_id):
         if type_or_id and isinstance(type_or_id, type) and \
            issubclass(type_or_id, DepositionType):
                 return type_or_id
         else:
             return DepositionType.get(type_or_id) if type_or_id else \
                 DepositionType.get_default()
 
     @classmethod
     def create(cls, user, type=None):
         """
         Create a new deposition object.
 
         To persist the deposition, you must call save() on the created object.
         If no type is defined, the default deposition type will be assigned.
 
         @param user: The owner of the deposition
         @param type: Deposition type identifier.
         """
         t = cls.get_type(type)
 
         if not t.authorize(None, 'create'):
             raise ForbiddenAction('create')
 
         obj = cls(None, type=type, user_id=user.get_id())
         return obj
 
     @classmethod
     def get(cls, object_id, user=None, type=None):
         """
         Get the deposition with specified object id.
 
         @param object_id: The BibWorkflowObject id.
         @param user: Owner of the BibWorkflowObject
         @param type: Deposition type identifier.
         """
         if type:
             type = DepositionType.get(type)
 
         try:
             workflow_object = BibWorkflowObject.query.filter_by(
                 id=object_id
             ).one()
         except NoResultFound:
             raise DepositionDoesNotExists(object_id)
 
         if user and workflow_object.id_user != user.get_id():
             raise DepositionDoesNotExists(object_id)
 
         obj = cls(workflow_object)
         if type and obj.type != type:
             raise DepositionDoesNotExists(object_id, type)
         return obj
 
     @classmethod
     def get_depositions(cls, user=None, type=None):
         params = [
             Workflow.module_name == 'webdeposit',
         ]
 
         if user:
             params.append(BibWorkflowObject.id_user == user.get_id())
 
         if type:
             params.append(Workflow.name == type.get_identifier())
 
         objects = BibWorkflowObject.query.join("workflow").options(
             db.contains_eager('workflow')).filter(*params).order_by(
             BibWorkflowObject.modified.desc()).all()
 
         def _create_obj(o):
             obj = cls(o)
             if type is None or obj.type == type:
                 return obj
             return None
 
         return filter(lambda x: x is not None, map(_create_obj, objects))
 
 
 class SubmissionInformationPackage(FactoryMixin):
     """
     Submission information package (SIP)
 
     :param uuid: Unique identifier for this SIP
     :param metadata: Metadata in JSON for this submission information package
     :param package: Full generated metadata for this package (i.e. normally
         MARC for records, but could anything).
     :param timestamp: UTC timestamp in ISO8601 format of when package was
         sealed.
     :param agents: List of agents for this package (e.g. creator, ...)
     :param task_ids: List of task ids submitted to ingest this package (may be
         appended to after SIP has been sealed).
     """
     def __init__(self, uuid=None, metadata={}):
         self.uuid = uuid or str(uuid4())
         self.metadata = metadata
         self.package = ""
         self.timestamp = None
         self.agents = []
         self.task_ids = []
 
     def __getstate__(self):
         return dict(
             id=self.uuid,
             metadata=self.metadata,
             package=self.package,
             timestamp=self.timestamp,
             task_ids=self.task_ids,
             agents=[a.__getstate__() for a in self.agents],
         )
 
     def __setstate__(self, state):
         self.uuid = state['id']
         self._metadata = state.get('metadata', {})
         self.package = state.get('package', None)
         self.timestamp = state.get('timestamp', None)
         self.agents = [Agent.factory(a_state)
                        for a_state in state.get('agents', [])]
         self.task_ids = state.get('task_ids', [])
 
     def seal(self):
         self.timestamp = datetime.now(tzutc()).isoformat()
 
     def is_sealed(self):
         return self.timestamp is not None
 
     @property
     def metadata(self):
         return self._metadata
 
     @metadata.setter
     def metadata(self, value):
         import datetime
         import json
 
         class DateTimeEncoder(json.JSONEncoder):
             def default(self, obj):
                 if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date):
                     encoded_object = obj.isoformat()
                 else:
                     encoded_object = json.JSONEncoder.default(self, obj)
                 return encoded_object
 
         data = json.dumps(value, cls=DateTimeEncoder)
         self._metadata = json.loads(data)
 
 
 class Agent(FactoryMixin):
     def __init__(self, role=None, from_request_context=False):
         self.role = role
         self.user_id = None
         self.ip_address = None
         self.email_address = None
         if from_request_context:
             self.from_request_context()
 
     def __getstate__(self):
         return dict(
             role=self.role,
             user_id=self.user_id,
             ip_address=self.ip_address,
             email_address=self.email_address,
         )
 
     def __setstate__(self, state):
         self.role = state['role']
         self.user_id = state['user_id']
         self.ip_address = state['ip_address']
         self.email_address = state['email_address']
 
     def from_request_context(self):
         from flask import request
         from invenio.ext.login import current_user
         self.ip_address = request.remote_addr
         self.user_id = current_user.get_id()
         self.email_address = current_user.info.get('email', '')
diff --git a/invenio/modules/workflows/api.py b/invenio/modules/workflows/api.py
index a5793e2cb..21472543e 100644
--- a/invenio/modules/workflows/api.py
+++ b/invenio/modules/workflows/api.py
@@ -1,299 +1,298 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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.
 
 """
 BibWorkflow API - functions to run workflows
 """
 
 from werkzeug.utils import (import_string,
                             cached_property)
 from invenio.base.globals import cfg
 from invenio.base.config import CFG_BIBWORKFLOW_WORKER
 
 from .utils import BibWorkflowObjectIdContainer
 from .models import BibWorkflowObject
 from .errors import WorkflowWorkerError
 
 
 class WorkerBackend(object):
 
     @cached_property
     def worker(self):
         try:
             return import_string('invenio.modules.workflows.workers.%s:%s' % (
                 cfg['CFG_BIBWORKFLOW_WORKER'], cfg['CFG_BIBWORKFLOW_WORKER']))
         except:
             from invenio.ext.logging import register_exception
             ## Let's report about broken plugins
             register_exception(alert_admin=True)
 
     def __call__(self, *args, **kwargs):
         if not self.worker:
             raise WorkflowWorkerError('No worker configured')
         return self.worker(*args, **kwargs)
 
 
 WORKER = WorkerBackend()
 
 
 def start(workflow_name, data, **kwargs):
     """
     Starts a workflow by given name for specified data *immediately*
     in the current process.
 
     The name of the workflow to start is considered unique and it is
     equal to the name of a file containing the workflow definition.
 
     The data passed should be a list of object(s) to run through the
     workflow. For example: a list of dict, JSON string, BibWorkflowObjects
     etc.
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     The workflow engine object generated is returned upon completion.
 
     @param workflow_name: the workflow name to run. Ex: "my_workflow"
     @type workflow_name: str
 
     @param data: the workflow name to run. Ex: "my_workflow"
     @type data: list of objects/dicts
 
     @return: BibWorkflowEngine that ran the workflow.
     """
     from .worker_engine import run_worker
     return run_worker(workflow_name, data, **kwargs)
 
 
 def start_delayed(workflow_name, data, **kwargs):
     """
     Starts a *delayed* workflow by using one of the defined workers
     available. For example, enqueueing the execution of the workflow in
     a task queue such as Celery (http://celeryproject.org).
 
     Otherwise, see documentation of start().
 
     @param workflow_name: the workflow name to run. Ex: "my_workflow"
     @type workflow_name: str
 
     @param data: the workflow name to run. Ex: "my_workflow"
     @type data: list of objects/dicts
 
     @return: BibWorkflowEngine that ran the workflow.
     """
     if not CFG_BIBWORKFLOW_WORKER:
         raise WorkflowWorkerError('No worker configured')
 
     #The goal of this part is to avoid a SQLalchemy decoherence in case
     #some one try to send a Bibworkflow object. To avoid to send the
     #complete object and get SQLAlchemy error of mapping, we save the id
     #into our Id container, In the celery process the object is reloaded
     #from the database !
     if isinstance(data, list):
         for i in range(0, len(data)):
             if isinstance(data[i], BibWorkflowObject):
                 data[i] = BibWorkflowObjectIdContainer(data[i]).to_dict()
     else:
         if isinstance(data, BibWorkflowObject):
             data = BibWorkflowObjectIdContainer(data).to_dict()
     return WORKER().run_worker(workflow_name, data, **kwargs)
 
 
 def start_by_wid(wid, **kwargs):
     """
     Will re-start given workflow, by workflow uuid (wid),
     from the beginning with the original data given.
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     @param wid: the workflow uuid. Ex: "550e8400-e29b-41d4-a716-446655440000"
     @type wid: string
 
     @return: BibWorkflowEngine that ran the workflow.
     """
     from .worker_engine import restart_worker
     return restart_worker(wid, **kwargs)
 
 
 def start_by_wid_delayed(wid, **kwargs):
     """
     Will re-start given workflow, by workflow uuid (wid),
     from the beginning with the original data given.
 
     Starts the workflow *delayed* by using one of the defined workers
     available. For example, enqueueing the execution of the workflow in
     a task queue such as Celery (http://celeryproject.org).
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     @param wid: the workflow uuid. Ex: "550e8400-e29b-41d4-a716-446655440000"
     @type wid: string
 
     @return: BibWorkflowEngine that ran the workflow.
     """
     return WORKER().restart_worker(wid, **kwargs)
 
 
 def start_by_oids(workflow_name, oids, **kwargs):
     """
     Will start given workflow, by name, using the given
     list of BibWorkflowObject ids (oids) from beginning.
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     @param workflow_name: the workflow name to run. Ex: "my_workflow"
     @type workflow_name: str
 
     @param oids: list of BibWorkflowObject id's to run.
     @type oids: list of strings/integers
 
     @return: BibWorkflowEngine that ran the workflow.
     """
     from .models import BibWorkflowObject
     objects = BibWorkflowObject.query.filter(
         BibWorkflowObject.id.in_(list(oids))
     ).all()
     return start(workflow_name, objects, **kwargs)
 
 
 def start_by_oids_delayed(workflow_name, oids, **kwargs):
     """
     Will start given workflow, by name, using the given
     list of BibWorkflowObject ids (oids) from beginning.
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     Starts the workflow *delayed* by using one of the defined workers
     available. For example, enqueueing the execution of the workflow in
     a task queue such as Celery (http://celeryproject.org).
 
     @param workflow_name: the workflow name to run. Ex: "my_workflow"
     @type workflow_name: str
 
     @param oids: list of BibWorkflowObject id's to run.
     @type oids: list of strings/integers
 
     @return: BibWorkflowEngine that ran the workflow.
     """
     from .models import BibWorkflowObject
     objects = BibWorkflowObject.query.filter(
         BibWorkflowObject.id.in_(list(oids))
     ).all()
 
     return start_delayed(workflow_name, objects, **kwargs)
 
 
 def continue_oid(oid, start_point="continue_next", **kwargs):
     """
     Continue workflow asociated with object given by object id (oid).
     It can start from previous, current or next task.
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     Starts the workflow *delayed* by using one of the defined workers
     available. For example, enqueueing the execution of the workflow in
     a task queue such as Celery (http://celeryproject.org).
 
     @param oid: id of BibWorkflowObject to run.
     @type oid: string
 
     @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 start_point: string
 
     @return: BibWorkflowEngine that ran the workflow
     """
     from .worker_engine import continue_worker
     return continue_worker(oid, start_point, **kwargs)
 
 
 def continue_oid_delayed(oid, start_point="continue_next", **kwargs):
     """
     Continue workflow associated with object given by object id (oid).
     It can start from previous, current or next task.
 
     Special custom keyword arguments can be given to the workflow engine
     in order to pass certain variables to the tasks in the workflow execution,
     such as a taskid from BibSched, the current user etc.
 
     Starts the workflow *delayed* by using one of the defined workers
     available. For example, enqueueing the execution of the workflow in
     a task queue such as Celery (http://celeryproject.org).
 
     @param oid: id of BibWorkflowObject to run.
     @type oid: string
 
     @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 start_point: string
 
     @return: BibWorkflowEngine that ran the workflow
     """
     return WORKER().continue_worker(oid, start_point, **kwargs)
 
 
 def resume_objects_in_workflow(id_workflow, start_point="continue_next",
                                **kwargs):
     """
     Resume workflow for any halted or failed objects from given workflow.
 
     This is a generator function and will yield every workflow created per
     object which needs to be resumed.
 
     To identify the original workflow containing the halted objects,
     the ID (or UUID) of the workflow is required. The starting point
     to resume the objects from can optionally be given. By default,
     the objects resume with their next task in the workflow.
 
     @param id_workflow: id of Workflow with objects to resume.
     @type id_workflow: string
 
     @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 start_point: string
 
     @yield: BibWorkflowEngine that ran the workflow
     """
-    from .models import BibWorkflowObject
-    from .config import CFG_OBJECT_VERSION
+    from .models import BibWorkflowObject, ObjectVersion
 
     # Resume workflow if there are objects to resume
     objects = BibWorkflowObject.query.filter(
         BibWorkflowObject.id_workflow == id_workflow,
-        BibWorkflowObject.version == CFG_OBJECT_VERSION.HALTED
+        BibWorkflowObject.version == ObjectVersion.HALTED
     ).all()
     for obj in objects:
         yield continue_oid(oid=obj.id, start_point=start_point,
                            **kwargs)
diff --git a/invenio/modules/workflows/client.py b/invenio/modules/workflows/client.py
index d8c246606..7b97d7016 100644
--- a/invenio/modules/workflows/client.py
+++ b/invenio/modules/workflows/client.py
@@ -1,119 +1,119 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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 traceback
 from .errors import (WorkflowHalt, WorkflowError)
-from .config import (CFG_OBJECT_VERSION,
-                     CFG_WORKFLOW_STATUS)
+from .models import ObjectVersion
+from .engine import WorkflowStatus
 
 
 def run_workflow(wfe, data, stop_on_halt=False, stop_on_error=False,
                  initial_run=True, **kwargs):
     """
     Main function running the workflow.
     """
     while True:
         try:
             if initial_run:
                 initial_run = False
                 wfe.process(data)
                 # We processed the workflow. We're done.
                 break
             else:
                 wfe._unpickled = True
                 wfe.restart('current', 'current')
                 # We processed the restarted workflow. We're done.
                 break
         except WorkflowHalt as e:
             # Processing was halted. Lets save current object and continue.
 
             # Save current object progress
             current_obj = wfe.get_current_object()
             if current_obj:
                 if e.widget:
                     current_obj.add_widget(e.widget, e.message)
-                current_obj.save(version=CFG_OBJECT_VERSION.HALTED,
+                current_obj.save(version=ObjectVersion.HALTED,
                                  task_counter=wfe.getCurrTaskId(),
                                  id_workflow=wfe.uuid)
             else:
                 wfe.log.warning("No active object found!")
 
             # Save workflow progress
-            wfe.save(status=CFG_WORKFLOW_STATUS.HALTED)
+            wfe.save(status=WorkflowStatus.HALTED)
             wfe.setPosition(wfe.getCurrObjId() + 1, [0, 0])
 
             message = "Workflow '%s' halted at task %s with message: %s" % \
                       (wfe.name,
                        wfe.get_current_taskname() or "Unknown",
                        e.message)
             wfe.log.warning(message)
             if stop_on_halt:
                 break
         except Exception as e:
             # We print the stacktrace, save the object and continue
             # unless instructed otherwise.
             msg = "Error: %r\n%s" % (e, traceback.format_exc())
             wfe.log.error(msg)
 
             # Changing counter should be moved to wfe object
             # together with default exception handling
             wfe.increase_counter_error()
-            wfe._objects[wfe.getCurrObjId()].save(CFG_OBJECT_VERSION.HALTED,
+            wfe._objects[wfe.getCurrObjId()].save(ObjectVersion.HALTED,
                                                   wfe.getCurrTaskId(),
                                                   id_workflow=wfe.uuid)
-            wfe.save(CFG_WORKFLOW_STATUS.ERROR)
+            wfe.save(WorkflowStatus.ERROR)
             wfe.setPosition(wfe.getCurrObjId() + 1, [0, 0])
             # if stop_on_halt or stop_on_error:
             if isinstance(e, WorkflowError):
                 raise e
             else:
                 raise WorkflowError(message=msg,
                                     id_workflow=wfe.uuid,
                                     id_object=wfe.getCurrObjId())
 
 
 def continue_execution(wfe, data, restart_point="restart_task",
                        stop_on_halt=False, stop_on_error=False, **kwargs):
     """
     Continue execution of workflow for given object (wfe) from "restart_point".
 
     restart_point can be 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
 
     You can use stop_on_error to raise exception's and stop the processing.
     Use stop_on_halt to stop processing the workflow
     if HaltProcessing is raised.
     """
     wfe.log.info("Continue execution from: %s" % (str(restart_point),))
     pos = data[0].get_current_task()
 
     if restart_point == "restart_prev":
         pos[-1] -= 1
         wfe.setPosition(wfe.db_obj.current_object, pos)
     elif restart_point == "continue_next":
         pos[-1] += 1
         wfe.setPosition(wfe.db_obj.current_object, pos)
     else:
         # restart_task
         wfe.setPosition(wfe.db_obj.current_object, pos)
     wfe._objects = data
     run_workflow(wfe, data, stop_on_halt, stop_on_error,
                  initial_run=False, **kwargs)
diff --git a/invenio/modules/workflows/config.py b/invenio/modules/workflows/config.py
deleted file mode 100644
index 500725647..000000000
--- a/invenio/modules/workflows/config.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-## This file is part of Invenio.
-## Copyright (C) 2012, 2013 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.
-
-"""Invenio BibWorkflow config."""
-
-
-def enum(**enums):
-    return type('Enum', (), enums)
-
-CFG_WORKFLOW_STATUS = enum(NEW=0, RUNNING=1, HALTED=2, ERROR=3,
-                           FINISHED=4, COMPLETED=5)
-CFG_OBJECT_VERSION = enum(INITIAL=0, FINAL=1, HALTED=2, RUNNING=3)
-CFG_OBJECT_STATUS = enum(ERROR="ERROR - Something went wrong!",
-                         RUNNING="RUNNING - Workflow in process",
-                         FINISHED="FINISHED - Workflow was finished" +
-                                  "for this object"
-                         )
-CFG_LOG_TYPE = enum(INFO=0, ERROR=1, DEBUG=2)
-CFG_EXTRA_DATA_KEY = enum(PUBLISHER=0, SOURCE=1, OWNER=2,
-                          CATEGORY=3, LAST_TASK_NAME=4)
diff --git a/invenio/modules/workflows/containers.py b/invenio/modules/workflows/containers.py
index 3fa338091..737241768 100644
--- a/invenio/modules/workflows/containers.py
+++ b/invenio/modules/workflows/containers.py
@@ -1,88 +1,80 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2013 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.
 
-from .config import CFG_OBJECT_VERSION
+from .models import ObjectVersion
 from .loader import widgets
 
 
 def create_hp_containers(iSortCol_0=None, sSortDir_0=None,
-                         sSearch=None, version_showing=[CFG_OBJECT_VERSION.HALTED]):
+                         sSearch=None, version_showing=[ObjectVersion.HALTED],
+                         type_showing=[]):
     """
     Looks for related HPItems and groups them together in HPContainers
 
     @type hpitems: list
     @return: A list containing all the HPContainers.
     """
     from .models import BibWorkflowObject
 
     if iSortCol_0:
         iSortCol_0 = int(iSortCol_0)
 
-    print '************************version_showing', version_showing
-
     bwobject_list = BibWorkflowObject.query.filter(
-        BibWorkflowObject.id_parent != 0 and \
-        BibWorkflowObject.version.in_(version_showing)).all()
+        BibWorkflowObject.id_parent != 0 and
+        not version_showing or BibWorkflowObject.version.in_(version_showing)
+    ).all()
 
-    print 'GOT THAT MANY RECORDS HERE:', len(bwobject_list)
     if sSearch:
-        print sSearch
         if len(sSearch) < 4:
             pass
         else:
             bwobject_list_tmp = []
             for bwo in bwobject_list:
                 extra_data = bwo.get_extra_data()
                 if bwo.id_parent == sSearch:
                     bwobject_list_tmp.append(bwo)
                 elif bwo.id_user == sSearch:
                     bwobject_list_tmp.append(bwo)
                 elif bwo.id_workflow == sSearch:
                     bwobject_list_tmp.append(bwo)
                 elif extra_data['_last_task_name'] == sSearch:
                     bwobject_list_tmp.append(bwo)
                 else:
                     try:
-                        widget = widgets[extra_data['widget']]
-                        if sSearch in widget.__title__ or sSearch in extra_data['widget']:
+                        widget_name = bwo.get_widget()
+                        widget = widgets[widget_name]
+                        if sSearch in widget.__title__ or sSearch in widget_name:
                             bwobject_list_tmp.append(bwo)
                     except:
                         pass
                 try:
                     if sSearch in extra_data['redis_search']['category']:
                         bwobject_list_tmp.append(bwo)
                     elif sSearch in extra_data['redis_search']['source']:
                         bwobject_list_tmp.append(bwo)
                     elif sSearch in extra_data['redis_search']['title']:
                         bwobject_list_tmp.append(bwo)
                 except KeyError:
                     pass
             bwobject_list = bwobject_list_tmp
 
     if iSortCol_0 == -6:
         if sSortDir_0 == 'desc':
             bwobject_list.reverse()
-    
-    return bwobject_list
 
-try:
-    bwolist = create_hp_containers(version_showing=current_app.config['VERSION_SHOWING'])
-    print "try succeded"
-except:    
-    print "try failed"
-    bwolist = create_hp_containers()
+    return bwobject_list
diff --git a/invenio/modules/workflows/engine.py b/invenio/modules/workflows/engine.py
index 92391d3d1..cc2c41423 100644
--- a/invenio/modules/workflows/engine.py
+++ b/invenio/modules/workflows/engine.py
@@ -1,449 +1,475 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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.
 
 from six.moves import cPickle
 
 import sys
 
 from datetime import datetime
 from six import iteritems
 from uuid import uuid1 as new_uuid
 
 import base64
 
 from workflow.engine import (GenericWorkflowEngine,
                              ContinueNextToken,
                              HaltProcessing,
                              StopProcessing,
                              JumpTokenBack,
                              JumpTokenForward,
                              WorkflowError)
 from invenio.ext.sqlalchemy import db
 from invenio.config import CFG_DEVEL_SITE
 from .models import (Workflow,
                      BibWorkflowObject,
-                     BibWorkflowEngineLog)
-from .utils import dictproperty, get_workflow_definition
-from .config import (CFG_WORKFLOW_STATUS,
-                     CFG_OBJECT_VERSION)
+                     BibWorkflowEngineLog,
+                     ObjectVersion)
+from .utils import (dictproperty,
+                    get_workflow_definition)
 from .logger import (get_logger,
                      BibWorkflowLogHandler)
 from .errors import WorkflowHalt
 
 DEBUG = CFG_DEVEL_SITE > 0
 
 
+class WorkflowStatus(object):
+    NEW, RUNNING, HALTED, ERROR, FINISHED, COMPLETED = range(6)
+
+
 class BibWorkflowEngine(GenericWorkflowEngine):
+    """
+    Subclass of GenericWorkflowEngine representing a workflow in
+    the workflows module.
+
+    Adds a SQLAlchemy database model to save workflow states and
+    workflow data.
+
+    Overrides key functions in GenericWorkflowEngine to implement
+    logging and certain workarounds for storing data before/after
+    task calls (This part will be revisited in the future).
+    """
     def __init__(self, name=None, uuid=None, curr_obj=0,
                  workflow_object=None, id_user=0, module_name="Unknown",
                  **kwargs):
         super(BibWorkflowEngine, self).__init__()
 
         self.db_obj = None
         if isinstance(workflow_object, Workflow):
             self.db_obj = workflow_object
         else:
             # If uuid is defined we try to get the db object from DB.
             if uuid is not None:
                 self.db_obj = \
                     Workflow.get(Workflow.uuid == uuid).first()
             else:
                 uuid = new_uuid()
             if self.db_obj is None:
                 self.db_obj = Workflow(name=name, id_user=id_user,
                                        current_object=curr_obj,
                                        module_name=module_name, uuid=uuid)
                 self._create_db_obj()
 
         db_handler_obj = BibWorkflowLogHandler(BibWorkflowEngineLog, "uuid")
         self.log = get_logger(logger_name="workflow.%s" % self.db_obj.uuid,
                               db_handler_obj=db_handler_obj,
                               obj=self)
 
         self.set_workflow_by_name(self.name)
         self.set_extra_data_params(**kwargs)
 
     def get_extra_data(self):
         """
         Main method to retrieve data saved to the object.
         """
         return cPickle.loads(base64.b64decode(self.db_obj._extra_data))
 
     def set_extra_data(self, value):
         """
         Main method to update data saved to the object.
         """
         self.db_obj._extra_data = base64.b64encode(cPickle.dumps(value))
 
     def extra_data_get(self, key):
         if key not in self.db_obj.get_extra_data():
             raise KeyError("%s not in extra_data" % (key,))
         return self.db_obj.get_extra_data()[key]
 
     def extra_data_set(self, key, value):
         tmp = self.db_obj.get_extra_data()
         tmp[key] = value
         self.db_obj.set_extra_data(tmp)
 
     extra_data = dictproperty(fget=extra_data_get, fset=extra_data_set,
                               doc="Sets up property")
 
     del extra_data_get, extra_data_set
 
     @property
     def counter_object(self):
         return self.db_obj.counter_object
 
     @property
     def uuid(self):
         return self.db_obj.uuid
 
     @property
     def id_user(self):
         return self.db_obj.id_user
 
     @property
     def module_name(self):
         return self.db_obj.module_name
 
     @property
     def name(self):
         return self.db_obj.name
 
     @property
     def status(self):
         return self.db_obj.status
 
     def __getstate__(self):
         if not self._picklable_safe:
             raise cPickle.PickleError("The instance of the workflow engine "
                                       "cannot be serialized, "
                                       "because it was constructed with "
                                       "custom, user-supplied callbacks. "
                                       "Either use PickableWorkflowEngine or "
                                       "provide your own __getstate__ method.")
         state = self.__dict__.copy()
         del state['log']
         return state
 
     def __setstate__(self, state):
         if len(self._objects) < self._i[0]:
             raise cPickle.PickleError("The workflow instance "
                                       "inconsistent state, "
                                       "too few objects")
 
         db_handler_obj = BibWorkflowLogHandler(BibWorkflowEngineLog, "uuid")
         state['log'] = get_logger(logger_name="workflow.%s" % state['uuid'],
                                   db_handler_obj=db_handler_obj,
                                   obj=self)
 
         self.__dict__ = state
 
     def __repr__(self):
         return "<BibWorkflow_engine(%s)>" % (self.db_obj.name,)
 
     def __str__(self, log=False):
         return """-------------------------------
 BibWorkflowEngine
 -------------------------------
     %s
 -------------------------------
 """ % (self.db_obj.__str__(),)
 
     @staticmethod
     def before_processing(objects, self):
         """
         Executed before processing the workflow.
         """
         # 1. Save workflow (ourselves).
         if not self.db_obj.uuid:
             self.save()
         self.set_counter_initial(len(objects))
         self.log.info("Workflow has been started")
         # 2. We want to save all the objects as version 0.
         for obj in objects:
             same_workflow = \
                 obj.id_workflow and \
                 obj.id_workflow == self.db_obj.uuid
             if obj.id and same_workflow:
                 # If object exists and we are running the same workflow,
                 # do nothing
                 obj.log.info("object saving process : was already existing")
                 continue
                 # Set the current workflow id in the object
-            if obj.version == CFG_OBJECT_VERSION.INITIAL \
+            if obj.version == ObjectVersion.INITIAL \
                 and obj.id_workflow is not None:
                 obj.log.info("object saving process : was already existing")
                 pass
             else:
                 obj.id_workflow = self.uuid
             obj.save(obj.version)
         GenericWorkflowEngine.before_processing(objects, self)
 
     @staticmethod
     def after_processing(objects, self):
         self._i = [-1, [0]]
         if self.has_completed():
-            self.save(CFG_WORKFLOW_STATUS.COMPLETED)
+            self.save(WorkflowStatus.COMPLETED)
         else:
-            self.save(CFG_WORKFLOW_STATUS.FINISHED)
+            self.save(WorkflowStatus.FINISHED)
 
     def _create_db_obj(self):
         db.session.add(self.db_obj)
         db.session.commit()
         self.log.info("Workflow saved to db as new object.")
 
     def _update_db(self):
         db.session.commit()
         self.log.info("Workflow saved to db.")
 
     def has_completed(self):
         """
         Returns True of workflow is fully completed meaning
         that all associated objects are in FINAL state.
         """
         number_of_objects = BibWorkflowObject.query.filter(
             BibWorkflowObject.id_workflow == self.uuid,
-            BibWorkflowObject.version.in_([CFG_OBJECT_VERSION.HALTED,
-                                           CFG_OBJECT_VERSION.RUNNING])
+            BibWorkflowObject.version.in_([ObjectVersion.HALTED,
+                                           ObjectVersion.RUNNING])
         ).count()
         return number_of_objects == 0
 
-    def save(self, status=CFG_WORKFLOW_STATUS.NEW):
+    def save(self, status=WorkflowStatus.NEW):
         """
         Save the workflow instance to database.
         Just storing the necessary data.
         No serialization (!).
 
         Status: 0 - new, 1 - running, 2 - halted, 3 - error, 4 - finished
         """
         if not self.db_obj.uuid:
             # We do not have an ID,
             # so we need to add ourselves (first execution).
             self._create_db_obj()
         else:
             # This workflow continues a previous execution.
-            if status in (CFG_WORKFLOW_STATUS.FINISHED,
-                          CFG_WORKFLOW_STATUS.HALTED):
+            if status in (WorkflowStatus.FINISHED,
+                          WorkflowStatus.HALTED):
                 self.db_obj.current_object = 0
             self.db_obj.modified = datetime.now()
             self.db_obj.status = status
             self._update_db()
 
     def process(self, objects):
         super(BibWorkflowEngine, self).process(objects)
 
     def restart(self, obj, task):
         """Restart the workflow engine after it was deserialized
         """
         self.log.info("Restarting workflow from %s object and %s task" %
                       (str(obj), str(task),))
 
         # set the point from which to start processing
         if obj == 'prev':
             # start with the previous object
             self._i[0] -= 2
             #TODO: check if there is any object there
         elif obj == 'current':
             # continue with the current object
             self._i[0] -= 1
         elif obj == 'next':
             pass
         else:
             raise Exception('Unknown start point for object: %s' % obj)
 
         # set the task that will be executed first
         if task == 'prev':
             # the previous
             self._i[1][-1] -= 1
         elif task == 'current':
             # restart the task again
             self._i[1][-1] -= 0
         elif task == 'next':
             # continue with the next task
             self._i[1][-1] += 1
         else:
             raise Exception('Unknown start pointfor task: %s' % obj)
 
         self.process(self._objects)
         self._unpickled = False
 
     @staticmethod
     def processing_factory(objects, self):
         """Default processing factory extended with saving objects
         before succesful processing.
 
         Default processing factory, will process objects in order
 
         @var objects: list of objects (passed in by self.process())
         @keyword cls: engine object itself, because this method may
             be implemented by the standalone function, we pass the
             self also as a cls argument
 
         As the WFE proceeds, it increments the internal counter, the
         first position is the number of the element. This pointer increases
         before the object is taken
 
         2nd pos is reserved for the array that points to the task position.
         The number there points to the task that is currently executed;
         when error happens, it will be there unchanged. The pointer is
         updated after the task finished running.
         """
 
         self.before_processing(objects, self)
 
         i = self._i
         # negative index not allowed, -1 is special
         while len(objects) - 1 > i[0] >= -1:
             i[0] += 1
             obj = objects[i[0]]
             obj.log.info("Object is selected for processing")
             callbacks = self.callback_chooser(obj, self)
 
             if callbacks:
                 try:
                     self.run_callbacks(callbacks, objects, obj)
                     i[1] = [0]  # reset the callbacks pointer
                 except StopProcessing:
                     if DEBUG:
                         self.log.debug("Processing was stopped: '%s' "
                                        "(object: %s)" %
                                        (str(callbacks), repr(obj)))
                         obj.log.debug("Processing has stopped")
                     break
                 except JumpTokenBack as step:
                     if step.args[0] > 0:
                         raise WorkflowError("JumpTokenBack cannot"
                                             " be positive number")
                     if DEBUG:
                         self.log.debug('Warning, we go back [%s] objects' %
                                        step.args[0])
                         obj.log.debug("Object preempted")
                     i[0] = max(-1, i[0] - 1 + step.args[0])
                     i[1] = [0]  # reset the callbacks pointer
                 except JumpTokenForward as step:
                     if step.args[0] < 0:
                         raise WorkflowError("JumpTokenForward cannot"
                                             " be negative number")
                     if DEBUG:
                         self.log.debug('We skip [%s] objects' % step.args[0])
                         obj.log.debug("Object preempted")
                     i[0] = min(len(objects), i[0] - 1 + step.args[0])
                     i[1] = [0]  # reset the callbacks pointer
                 except ContinueNextToken:
                     if DEBUG:
                         self.log.debug('Stop processing for this object, '
                                        'continue with next')
                         obj.log.debug("Object preempted")
                     i[1] = [0]  # reset the callbacks pointer
                     continue
                 except HaltProcessing as e:
                     self.increase_counter_halted()
                     extra_data = obj.get_extra_data()
                     obj.set_extra_data(extra_data)
 
                     if DEBUG:
                         self.log.info('Processing was halted at step: %s' % i)
                         # reraise the exception,
                         #this is the only case when a WFE can be completely
                         # stopped
                         obj.log.info("Object proccesing is halted")
                     if type(e) == WorkflowHalt:
                         raise e
                     else:
                         raise WorkflowHalt(e)
                 except Exception as e:
                     obj.log.error("Something terribly wrong happend to this object")
                     extra_data = obj.get_extra_data()
                     obj.set_extra_data(extra_data)
                     raise
                 # We save the object once it is fully run through
-            obj.save(CFG_OBJECT_VERSION.FINAL)
+            obj.save(ObjectVersion.FINAL)
             obj.log.info("Object proccesing is finished")
             self.increase_counter_finished()
             self.log.info("Done saving object: %i" % (obj.id, ))
         self.after_processing(objects, self)
 
     def execute_callback(self, callback, obj):
         """Executes the callback - override this method to implement logging"""
         obj.data = obj.get_data()
         obj.extra_data = obj.get_extra_data()
         obj.extra_data["_last_task_name"] = self.get_current_taskname()
         self.log.info(obj.extra_data["_last_task_name"])
         self.extra_data = self.get_extra_data()
         try:
             callback(obj, self)
         finally:
             self.set_extra_data(self.extra_data)
             obj.set_data(obj.data)
             obj.set_extra_data(obj.extra_data)
 
     def get_current_taskname(self):
         """
         Will attempt to return name of current task/step.
         Otherwise returns None.
         """
         callback_list = self.getCallbacks()
         if callback_list:
+            self.log.info(str(self.getCallbacks()))
+            self.log.info(str(self.getCurrTaskId()))
             for i in self.getCurrTaskId():
                 callback_list = callback_list[i]
             return callback_list.func_name
 
     def get_current_object(self):
         """
         Returns the currently active BibWorkflowObject or
         None if no object is active.
         """
         obj_id = self.getCurrObjId()
         if obj_id < 0:
             return None
         return self._objects[obj_id]
 
     def halt(self, msg, widget=None):
         """Halt the workflow (stop also any parent wfe)"""
         raise WorkflowHalt(message=msg,
                            widget=widget,
                            id_workflow=self.uuid)
 
+    def get_default_data_type(self):
+        """
+        Returns default data type from workflow
+        definition.
+        """
+        return getattr(self.workflow_definition,
+                       "object_type",
+                       "")
+
     def set_counter_initial(self, obj_count):
         self.db_obj.counter_initial = obj_count
         self.db_obj.counter_halted = 0
         self.db_obj.counter_error = 0
         self.db_obj.counter_finished = 0
 
     def increase_counter_halted(self):
         self.db_obj.counter_halted += 1
 
     def increase_counter_error(self):
         self.db_obj.counter_error += 1
 
     def increase_counter_finished(self):
         self.db_obj.counter_finished += 1
 
     def set_workflow_by_name(self, workflow_name):
         workflow = get_workflow_definition(workflow_name)
         self.workflow_definition = workflow
         self.setWorkflow(self.workflow_definition.workflow)
 
     def set_extra_data_params(self, **kwargs):
         tmp = self.get_extra_data()
         if not tmp:
             tmp = {}
         for key, value in iteritems(kwargs):
             tmp[key] = value
         self.set_extra_data(tmp)
diff --git a/invenio/modules/workflows/errors.py b/invenio/modules/workflows/errors.py
index 3f880ea25..408f510b7 100644
--- a/invenio/modules/workflows/errors.py
+++ b/invenio/modules/workflows/errors.py
@@ -1,136 +1,158 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2013 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.
 
 """
     invenio.modules.workflows.errors
     ------------------------
 
     Contains standard error messages for workflows module.
 """
 
 from workflow.engine import HaltProcessing
 
 
 class WorkflowHalt(HaltProcessing):
     """
     Raised when workflow should be halted.
     Also contains the widget to be displayed.
     """
 
     def __init__(self, message, widget=None, **kwargs):
         HaltProcessing.__init__(self)
         self.message = message
         self.widget = widget
         self.payload = kwargs
 
     def to_dict(self):
         rv = dict(self.payload or ())
         rv['message'] = self.message
         rv['widget'] = self.widget
         return rv
 
     def __str__(self):
         """String representation."""
         return "WorkflowHalt(%s, widget: %s, payload: %r)" % \
                (repr(self.message), repr(self.widget), repr(self.payload))
 
 
 # class WorkflowError(Exception):
 #     """Raised when workflow experiences an error."""
 #
 #     def __init__(self, message, id_workflow=None, id_object=None, **kwargs):
 #         self.message = message
 #         self.id_workflow = id_workflow
 #         self.id_object = id_object
 #         self.payload = kwargs
 #         super(WorkflowError, self).__init__(message, id_workflow, id_object, kwargs)
 #
 #     def to_dict(self):
 #         rv = dict(self.payload or ())
 #         rv['message'] = self.message
 #         rv['id_workflow'] = self.id_workflow
 #         rv['id_object'] = self.id_object
 #         return rv
 #
 #     def __str__(self):
 #         """String representation."""
 #         return "WorkflowError(%s, id_workflow: %s, id_object: %s, payload: %r)" % \
 #                (self.message, str(self.id_workflow), str(self.id_object), repr(self.payload))
 
 class WorkflowError(Exception):
     """Raised when workflow experiences an error."""
 
     def __init__(self, message, id_workflow, id_object, payload=[]):
         self.message = message
         self.id_workflow = id_workflow
         self.id_object = id_object
         self.payload = payload
         Exception.__init__(self, message, message, id_object, payload)  # <-- REQUIRED
 
     def to_dict(self):
         rv = list(self.payload or [])
         rv['message'] = self.message
         rv['id_workflow'] = self.id_workflow
         rv['id_object'] = self.id_object
         return rv
 
     def __str__(self):
         """String representation."""
         return "WorkflowError(%s, id_workflow: %s, id_object: %s, payload: %r)" % \
                (self.message, str(self.id_workflow), str(self.id_object), repr(self.payload))
 
+
 class WorkflowDefinitionError(Exception):
     """Raised when workflow definition is missing."""
 
     def __init__(self, message, workflow_name, **kwargs):
         Exception.__init__(self)
         self.message = message
         self.workflow_name = workflow_name
         self.payload = kwargs
 
     def to_dict(self):
         rv = dict(self.payload or ())
         rv['message'] = self.message
         rv['workflow_name'] = self.workflow_name
         return rv
 
     def __str__(self):
         """String representation."""
         return "WorkflowDefinitionError(%s, workflow_name: %s, payload: %r)" % \
                (repr(self.message), self.workflow_name, repr(self.payload) or "None")
 
 
 class WorkflowWorkerError(Exception):
     """Raised when there is a problem with workflow workers."""
 
     def __init__(self, message, worker_name, **kwargs):
         Exception.__init__(self)
         self.message = message
         self.worker_name = worker_name
         self.payload = kwargs
 
     def to_dict(self):
         rv = dict(self.payload or ())
         rv['message'] = self.message
         rv['worker_name'] = self.worker_name
         return rv
 
     def __str__(self):
         """String representation."""
         return "WorkflowDefinitionError(%s, worker_name: %s, payload: %r)" % \
-               (repr(self.message), self.worker_name, repr(self.payload) or "None")
\ No newline at end of file
+               (repr(self.message), self.worker_name, repr(self.payload) or "None")
+
+
+class WorkflowObjectVersionError(Exception):
+    """ Raised when workflow object has an unknown or missing version """
+    
+    def __init__(self, message, id_object, obj_version):
+        self.message = message
+        self.obj_version = obj_version
+        self.id_object = id_object
+
+    def to_dict(self):
+        rv = {}
+        rv['message'] = self.message
+        rv['obj_version'] = self.obj_version
+        rv['id_object'] = self.id_object
+        return rv
+
+    def __str__(self):
+        """String representation."""
+        return "WorkflowObjectVersionError(%s, obj_version: %s, id_object: %s)" % \
+               (self.message, str(self.obj_version), str(self.id_object))
diff --git a/invenio/modules/workflows/hp_field_widgets.py b/invenio/modules/workflows/hp_field_widgets.py
index 9c16d2c48..18d62bee7 100644
--- a/invenio/modules/workflows/hp_field_widgets.py
+++ b/invenio/modules/workflows/hp_field_widgets.py
@@ -1,81 +1,88 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
 ## Copyright (C) 2013, 2013 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.
 
 from wtforms.widgets import html_params, HTMLString
 
 
-def bootstrap_submit(field):
+def bootstrap_accept(field):
+    """
+    Accept button for hp
+    """
     html = u'<input %s >' \
            % html_params(id="submitButton",
-                         class_="btn btn-primary btn-lg",
+                         class_="btn btn-success",
                          name="submitButton",
                          type="submit",
                          value=field.label.text,)
     return HTMLString(u''.join(html))
 
 
-def bootstrap_accept(field):
+def bootstrap_submit(field):
     """
-    Accept button for hp
+    Submit button for edit record widget
     """
     html = u'<input %s >' \
            % html_params(id="submitButton",
-                         class_="btn btn-success",
+                         class_="btn btn-sm btn-primary",
                          name="submitButton",
-                         type="submit",
-                         value=field.label.text,)
+                         type="submit",)
     return HTMLString(u''.join(html))
 
-def bootstrap_accept_mini(field):
+
+def bootstrap_accept_mini(field, **kwargs):
     """
     Mini Accept button for hp
     """
+    objectid = kwargs.pop('objectid', '')
     html = u'<input %s >' \
            % html_params(id="submitButtonMini",
                          class_="btn btn-success btn-xs",
                          name="submitButton",
                          type="submit",
                          value=field.label.text,
-                         onclick="mini_approval('Accept', event);",)
+                         onclick="mini_approval('Accept', event, %s);" % (objectid,),)
     return HTMLString(u''.join(html))
 
+
 def bootstrap_reject(field):
     """
     Reject button for hp
     """
     html = u'<input %s >' \
            % html_params(id="submitButton",
                          class_="btn btn-danger",
                          name="submitButton",
                          type="submit",
                          value=field.label.text,)
     return HTMLString(u''.join(html))
 
-def bootstrap_reject_mini(field):
+
+def bootstrap_reject_mini(field, **kwargs):
     """
     Mini Reject button for hp
     """
+    objectid = kwargs.pop('objectid', '')
     html = u'<input %s >' \
            % html_params(id="submitButtonMini",
                          class_="btn btn-danger btn-xs",
                          name="submitButton",
                          type="submit",
                          value=field.label.text,
-                         onclick="mini_approval('Reject', event);",)
+                         onclick="mini_approval('Reject', event, %s);" % (objectid,),)
     return HTMLString(u''.join(html))
diff --git a/invenio/modules/workflows/models.py b/invenio/modules/workflows/models.py
index 061124485..de3adbcfb 100644
--- a/invenio/modules/workflows/models.py
+++ b/invenio/modules/workflows/models.py
@@ -1,574 +1,591 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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 os
 import tempfile
 from six.moves import cPickle
 import base64
 import logging
 import six
 
 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 .config import CFG_OBJECT_VERSION
-from .utils import redis_create_search_entry, WorkflowsTaskResult
 
+from .utils import redis_create_search_entry, WorkflowsTaskResult
 from .logger import (get_logger,
                      BibWorkflowLogHandler)
 
 
+class ObjectVersion(object):
+    INITIAL = 0
+    FINAL = 1
+    HALTED = 2
+    RUNNING = 3
+
+
 def get_default_data():
     """ Returns the base64 representation of the data default value """
     data_default = {}
     return base64.b64encode(cPickle.dumps(data_default))
 
 
 def get_default_extra_data():
     """ Returns the base64 representation of the extra_data default value """
     extra_data_default = {"_tasks_results": [],
                           "owner": {},
-                          "task_counter": {},
+                          "_task_counter": {},
                           "error_msg": "",
                           "_last_task_name": "",
                           "latest_object": -1,
                           "widget": None,
-                          "redis_search": {}}
+                          "redis_search": {},
+                          "source": ""}
     return base64.b64encode(cPickle.dumps(extra_data_default))
 
 
 class Workflow(db.Model):
 
     __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())
+    _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)
 
     def __repr__(self):
         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):
         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):
         """ 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):
         """ Returns the status of the workflow """
         return cls.get(Workflow.uuid == uuid).one().status
 
     @classmethod
     def get_most_recent(cls, *criteria, **filters):
         """ Returns 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):
         """ Returns 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):
         """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 is not None:
             return extra_data[key]
         elif callable(getter):
             return getter(extra_data)
 
     def set_extra_data(self, user_id=0, uuid=None,
                        key=None, value=None, setter=None):
         """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))})
+        Workflow.get(Workflow.uuid == self.uuid).update(
+            {'_extra_data': base64.b64encode(cPickle.dumps(extra_data))}
+        )
 
     @classmethod
     def delete(cls, uuid=None):
         cls.get(Workflow.uuid == uuid).delete()
         db.session.commit()
 
 
 class BibWorkflowObject(db.Model):
     # 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())
+    _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=CFG_OBJECT_VERSION.RUNNING, nullable=False)
+                        default=ObjectVersion.RUNNING, 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)
-    persistent_ids = db.Column(db.JSON, default= {} ,nullable=True)
-    data_type = db.Column(db.String(150), default=DATA_TYPES.ANY,
+    persistent_ids = db.Column(db.JSON, default={}, nullable=True)
+    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):
         if not self._log:
             db_handler_obj = BibWorkflowLogHandler(BibWorkflowObjectLog, "id")
-            self._log = get_logger(logger_name="object.%s_%s" % (self.id_workflow, self.id),
+            self._log = get_logger(logger_name="object.%s_%s" %
+                                               (self.id_workflow, 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.
         """
         self._extra_data = base64.b64encode(cPickle.dumps(value))
 
     def _create_db_obj(self):
         db.session.add(self)
         db.session.commit()
 
     def __repr__(self):
         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 __str__(self, log=False):
-        return """
--------------------------------
-BibWorkflowObject
--------------------------------
-    Extra object class:
-    Self status: %s
--------------------------------
-    BibWorkflowObject:
-
-        Id: %s
-        Parent id: %s
-        Workflow id: %s
-        Created: %s
-        Modified: %s
-        Version: %s
-        DB_obj status: %s
-        Data type: %s
-        URI: %s
-        Data: %s
-        Extra data: %s
--------------------------------
-""" % (str(self.status),
-       str(self.id),
-       str(self.id_parent),
-       str(self.id_workflow),
-       str(self.created),
-       str(self.modified),
-       str(self.version),
-       str(self.status),
-       str(self.data_type),
-       str(self.uri),
-       str(self.get_data()),
-       str(self.get_extra_data),)
-
     def __eq__(self, other):
         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 \
                     isinstance(self.created, datetime) and \
                     isinstance(self.modified, datetime):
                 return True
             else:
                 return False
         return NotImplemented
 
     def __ne__(self, other):
         return not self.__eq__(other)
 
     def add_task_result(self, name, 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)
         self.extra_data["_tasks_results"].append(res_obj)
 
     def add_widget(self, widget, message):
+        """
+        Assign a widget to this object for an action to be taken
+        in holdingpen. The widget is reffered to by a string with
+        the filename minus extension. Ex: approval_widget.
+
+        A message is also needed to tell the user the action
+        required.
+        """
         extra_data = self.get_extra_data()
         extra_data["_widget"] = widget
         extra_data["_message"] = message
         self.set_extra_data(extra_data)
 
+    def get_widget(self):
+        """
+        Retrive the currently assigned widget, if any.
+        """
+        try:
+            return self.get_extra_data()["_widget"]
+        except KeyError:
+            # No widget
+            return None
+
     def remove_widget(self):
+        """
+        Removes the currently assigned widget.
+        """
         extra_data = self.get_extra_data()
         extra_data["_widget"] = None
         extra_data["_message"] = ""
         self.set_extra_data(extra_data)
 
     def change_status(self, message):
         self.status = message
 
     def get_current_task(self):
-        return self.get_extra_data()["task_counter"]
+        """
+        Returns the current progress structure 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 _create_version_obj(self, id_workflow, version, id_parent=None,
                             no_update=False):
 
         obj = BibWorkflowObject(_data=self._data,
                                 id_workflow=id_workflow,
                                 version=version,
                                 id_parent=id_parent,
                                 _extra_data=self._extra_data,
                                 status=self.status,
                                 data_type=self.data_type)
 
         db.session.add(obj)
         db.session.commit()
-        if version is CFG_OBJECT_VERSION.INITIAL and not no_update:
+        if version is ObjectVersion.INITIAL and not no_update:
             self.id_parent = obj.id
             db.session.commit()
         return obj.id
 
     def _update_db(self):
         db.session.add(self)
         db.session.commit()
 
     def save(self, version=None, task_counter=[0], id_workflow=None):
         """
         Saved object
         """
         if not self.id:
             db.session.add(self)
             db.session.commit()
 
         extra_data = self.get_extra_data()
         extra_data["_task_counter"] = task_counter
         self.set_extra_data(extra_data)
 
         if not id_workflow:
             id_workflow = self.id_workflow
 
         if version:
             self.version = version
-            if version in (CFG_OBJECT_VERSION.FINAL, CFG_OBJECT_VERSION.HALTED):
+            if version in (ObjectVersion.FINAL, ObjectVersion.HALTED):
                 redis_create_search_entry(self)
             self._update_db()
 
     def save_to_file(self, directory=None,
                      prefix="workflow_object_data_", suffix=".obj"):
         """
         Saves 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):
         return self.__dict__
 
     def __setstate__(self, state):
         self.__dict__ = state
 
     def copy(self, other):
         """Copies 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
 
     def get_formatted_data(self, format=None, formatter=None):
         """
         Returns the data in some chewable format.
         """
         from invenio.modules.records.api import Record
         from invenio.modules.formatter.engine import format_record
 
         data = self.get_data()
 
         if formatter:
             # A seperate formatter is supplied
             return formatter(data)
 
         if isinstance(data, dict):
             # Dicts are cool on its own, but maybe its SmartJson (record)
             try:
                 new_dict_representation = Record(data)
                 data = new_dict_representation.legacy_export_as_marc()
             except Exception as e:
-                raise e
+                # Maybe not, submission?
+                return data
 
         if isinstance(data, six.string_types):
             # Its a string type, lets try to convert
             if format:
                 # We can try formatter!
                 # If already XML, format_record does not like it.
                 if format != 'xm':
                     try:
                         return format_record(recID=None,
                                              of=format,
                                              xml_record=data)
                     except TypeError as e:
                         # Wrong kind of type
                         pass
                 else:
                     # So, XML then
                     from xml.dom.minidom import parseString
                     try:
                         pretty_data = parseString(data)
                         return pretty_data.toprettyxml()
                     except TypeError:
                         # Probably not proper XML string then
                         return "Data cannot be parsed: %s" % (data,)
                     except Exception:
                         # Some other parsing error
                         pass
             # Just return raw string
             return data
         # Not any of the above types. How juicy!
         return data
 
+    @classmethod
+    def delete(cls, oid):
+        cls.get(BibWorkflowObject.id == oid).delete()
+        db.session.commit()
+
 
 class BibWorkflowObjectLog(db.Model):
     """
     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 __repr__(self):
         return "<BibWorkflowObjectLog(%i, %s, %s, %s)>" % \
                (self.id, self.id_object, self.message, self.created)
 
     @classmethod
     def get(cls, *criteria, **filters):
         """ 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):
         """ Returns 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):
         cls.get(BibWorkflowObjectLog.id == id).delete()
         db.session.commit()
 
 
 class BibWorkflowEngineLog(db.Model):
     __tablename__ = "bwlWORKFLOWLOGGING"
     id = db.Column(db.Integer, primary_key=True)
     id_object = db.Column(db.String(255), 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 __repr__(self):
         return "<BibWorkflowEngineLog(%i, %s, %s, %s)>" % \
                (self.id, self.id_object, self.message, self.created)
 
     @classmethod
     def get(cls, *criteria, **filters):
         """ 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):
         """ Returns 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):
         cls.get(BibWorkflowEngineLog.id == uuid).delete()
         db.session.commit()
 
 
-__all__ = ['Workflow', 'BibWorkflowObject', 'BibWorkflowObjectLog', 'BibWorkflowEngineLog']
+__all__ = ['Workflow', 'BibWorkflowObject',
+           'BibWorkflowObjectLog', 'BibWorkflowEngineLog']
diff --git a/invenio/modules/workflows/static/css/workflows/style.css b/invenio/modules/workflows/static/css/workflows/style.css
index 13073c7db..f918d5efd 100644
--- a/invenio/modules/workflows/static/css/workflows/style.css
+++ b/invenio/modules/workflows/static/css/workflows/style.css
@@ -1,250 +1,276 @@
 span.glyphicon-link {
     font-size: 1.2em;
 }
+    
+.editField{
+    width: 50px;
+}
+
+.dropdown-headline {
+    font-weight: bold;
+}
+
+#slide-down-menu{
+    background-color:black;
+    opacity: 75%;
+    width:400px;
+    height:100px;
+    margin:0 auto; 
+}
+
+.slide-down-btns{
+    
+}
 
 .mini-approval-btn{
     text-decoration: none;
     color: #fff;
 }
 
 .mini-approval-btn:hover{
     text-decoration: none;
     color: #fff
 }
 
+.maintablerowhover{
+    background-color: #ffa;
+}
+
 .active2 {
     background-color:rgba(255,255,255,0.7);
     position:absolute;
     float:left;
     top:0;
     left:0;
     width:100%;
     height:100%;
 }
 
 .tag-alert{
     width: 120px;
     padding: 4px;
-    font-size: 14px;
+    font-size: 12px;
+    font-weight: bold;
+    margin:  10px;
 }
 
+
 .close-btn:hover{
     text-decoration:none;
     cursor:pointer;
 }
 
 #goodbye-msg{
     /*text-align: center;*/
     font-size: 36px;
     font-color:green;
 }
 
 #datatables-top{
     background-color: #FF2;
 }
 
 .details_link{
     padding-bottom: 5px;
 }
 
 #example tbody tr.even:hover, #example tbody tr.odd:hover {
     background-color: #FFFFCC;
 }
 
 #example tbody tr td {
     user-select: none; /* CSS3 */
     -moz-user-select: none; /* Gecko (Firefox) */
     -khtml-user-select:none; /* Webkit (Safari, Chrome) */
 }
 
 .task-btns{
     padding-bottom:5px;
 }
 
 #accept-btn-bibmatch{
     width: 100px;
     margin: 0 auto;
     padding-top: 5px;
 }
 
 .decision-btns{
     width:500px;
     padding-top: 10px;
     margin: 0 auto;
 }
 
 #usermessage{
     margin-top: 10px;
     text-align: center;
 }
 
 #successmessage{
     margin-top: 10px;
     text-align: center;
 }
 
 #record_preview{
     position: fixed;
     width: 550px;
     height: 700px;
     overflow: auto;
 }
 
 #match_preview{
     width: 550px;
     height: 700px;
     overflow: auto;   
 }
 
 .object_preview_container{
     padding-top: 10px;
     padding-left: 50px;
     width: 750px;
-    height: 700px;
     overflow: auto;
 }
 
 #object_preview_container{
     padding-top: 10px;
     padding-left: 50px;
     width: 750px;
     height: 700px;
     overflow: auto;
 }
 
 #entry_detiles > span {
     position:absolute;
     right:11%;
     cursor:pointer;
 }
 .entry_message_button {
     display:block;
     background: orange url("images/icons/next.png") no-repeat 110px;
     width:120px;
     height:15px;
     border-radius:10px;
     padding:5px 0 5px 10px;
 }
 .entry_message_button_back {
     display:block;
     background: white url("images/icons/prev.png") no-repeat 10px;
     border: 1px gray solid;
     width:80px;
     height:15px;
     border-radius:10px;
     padding:5px 0 5px 60px;
 }
 #entry_info {
     width: 70%;
     height: 65px;
     float: left;
 }
 #entry_detiles h1, #workflow_detiles h1{
     font-size:18px;
 }
 #entry_detiles h2, #workflow_detiles h2{
     font-size:16px;
 }
 #entry_detiles, #workflow_detiles {
     font-size: 12px;
 }
 #entry_metadata {
     float: left;
     width: 30%;
     height: 35px;
     text-align: right;
     padding-top: 20px;
 }
 #actions {
     float: right;
     width: 480px;
     overflow-y:auto;
     height:450px;
 }
 .entry_message {
     background-color: lightYellow;
     border: solid 1px;
     padding: 5px;
     margin-bottom: 10px;
 }
 #entry_preview {
     text-align:right;
     display:block;
     clear:left;
     border:1px gray solid;
     width:300px;
     height:450px;
 }
 #entry_preview textarea, #workflow_tasks textarea, #workflow_preview textarea{
     width:100%;
     min-height:14em;
 }
 
 tr.child_workflow {
     background-color: lightgray;
     font-size: 12px;
 }
 #preview_type {
     position:absolute;
     top:52?
 0px;
 }
 #preview_type button{
     font-size:10px;
 }
 #preview_type .other_btn{
     margin-left:10px;
 }
 
 .widget_list {
     background-color:red;
     margin:5px;
 }
 
 .widget_list span {
     display:block;
     width:30px;
     height:30px;
     background-color:white;
     float: left;
     margin-right: 8px;
 }
 #entry_keywords {
     float: left;
     margin:10px 0 0 0;
     width:600px;
     height:75px;
 }
 #action_buttons {
     margin:40px 0 0 0;
     width:150px;
     float:right;
 }
 #action_buttons #extra{
     width:150px;
 }
 
 /****** bootstrap CSS hacks *******/
 #myModal {
     margin-top: -350px;
     width: 80%;
     left: 25%;
 }
 .modal-body {
     max-height:600px;
     overflow:none;
 }
 
 /****** tinybox ******/
 .tbox {position:absolute; display:none; padding:14px 17px; z-index:900}
 .tinner {padding:15px; -moz-border-radius:5px; border-radius:5px; background:#fff url(images/preload.gif) no-repeat 50% 50%; border-right:1px solid #333; border-bottom:1px solid #333}
 .tmask {position:absolute; display:none; top:0px; left:0px; height:100%; width:100%; background:#000; z-index:800}
 .tclose {position:absolute; top:0px; right:0px; width:30px; height:30px; cursor:pointer; background:url(images/close.png) no-repeat}
 .tclose:hover {background-position:0 -30px}
 
 #error {background:#ff6969; color:#fff; text-shadow:1px 1px #cf5454; border-right:1px solid #000; border-bottom:1px solid #000; padding:0}
 #error .tcontent {padding:10px 14px 11px; border:1px solid #ffb8b8; -moz-border-radius:5px; border-radius:5px}
 #success {background:#2ea125; color:#fff; text-shadow:1px 1px #1b6116; border-right:1px solid #000; border-bottom:1px solid #000; padding:10; -moz-border-radius:0; border-radius:0}
 #notification {background:lightgreen; color:black; border-right:1px solid #000; border-bottom:1px solid #000; padding:0}
 #frameless {padding:0}
 #frameless .tclose {left:6px}
diff --git a/invenio/modules/workflows/static/js/workflows/entry_details.js b/invenio/modules/workflows/static/js/workflows/entry_details.js
index c4d4ea1b9..00f213958 100644
--- a/invenio/modules/workflows/static/js/workflows/entry_details.js
+++ b/invenio/modules/workflows/static/js/workflows/entry_details.js
@@ -1,38 +1,38 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013 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.
  */
 
-
-function bind_object_preview(url_prefix, entry_id) {
-    $("div.btn-group[name='object_preview_btn']").bind('click', function(event){
-          var format = event.target.name;
-          jQuery.ajax({
-                url: url_prefix,
-                data: {'oid': entry_id,
-                       'format': format},
-                success: function(json){
-                    if(format == 'xm' || format == 'marcxml'){
-                        $('div[name="object_preview"]').wrapAll('<debug>').text(json);
-                    }else{
-                        $('div[name="object_preview"]').html(json);
+function($){
+    function bind_object_preview(url_prefix, entry_id) {
+        $("div.btn-group[name='object_preview_btn']").bind('click', function(event){
+            var format = event.target.name;
+            jQuery.ajax({
+                    url: url_prefix,
+                    data: {'oid': entry_id,
+                          'format': format},
+                    success: function(json){
+                        if(format == 'xm' || format == 'marcxml'){
+                            $('div[name="object_preview"]').wrapAll('<debug>').text(json);
+                        }else{
+                            $('div[name="object_preview"]').html(json);
+                        }
                     }
-                }
-         })
-    });
-}
+            })
+        });
+    }
 
diff --git a/invenio/modules/workflows/static/js/workflows/hp_datapreview.js b/invenio/modules/workflows/static/js/workflows/hp_datapreview.js
index 6b9a88cce..afbc897fa 100644
--- a/invenio/modules/workflows/static/js/workflows/hp_datapreview.js
+++ b/invenio/modules/workflows/static/js/workflows/hp_datapreview.js
@@ -1,43 +1,43 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013 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.
  */
 
 function data_preview(url_preview, bwoid, format) {
     jQuery.ajax({
         url: url_preview,
         data: {'oid': bwoid,
-               'recformat': format},
+               'of': format},
         success: function(json){
             if(format == "xm" || format == "marcxml"){
                 if( json.data === ""){
                     json.data = "Preview not available";
                 }
                 $('div[id="object_preview_container'+bwoid+'"]').empty();
                 $('div[id="object_preview_container'+bwoid+'"]').append("<pre><code id='object_preview' class='language-markup'></code></pre>");
                 $('code[id="object_preview"]').append(json.data);
                 Prism.highlightElement($('code[id="object_preview"]')[0]);
             }else{
                 if( json.data === ""){
                     json.data = "Preview not available";
                 }
                 $('div[id="object_preview_container'+bwoid+'"]').empty();
                 $('div[id="object_preview_container'+bwoid+'"]').append(json.data);
             }
         }
     });
-};
+};
\ No newline at end of file
diff --git a/invenio/modules/workflows/static/js/workflows/hp_details.js b/invenio/modules/workflows/static/js/workflows/hp_details.js
index b8d86ebd2..358f8c88e 100644
--- a/invenio/modules/workflows/static/js/workflows/hp_details.js
+++ b/invenio/modules/workflows/static/js/workflows/hp_details.js
@@ -1,74 +1,97 @@
 // -*- coding: utf-8 -*-
 // This file is part of Invenio.
 // Copyright (C) 2013 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.
 
+url = new Object();
+var bwoid;
+
+function init_url_details(url_, bwoid_){
+    url = url_;
+    bwoid = bwoid_;
+}
 
-function action_buttons (url_restart_record, url_restart_record_prev, url_continue) {
+
+function action_buttons(url, bwoid) {
 
     $('#restart_button').on('click', function() {
-        bwo_id = $(this).attr('name');
-        console.log(bwo_id);
         jQuery.ajax({
-            url: url_restart_record,
-            data: bwo_id,
+            url: url.url_restart_record,
+            data: {'bwobject_id': bwoid},
             success: function(json){
                 bootstrap_alert('Object restarted');
             }
         });
     });
 
     $('#restart_button_prev').on('click', function() {
-        bwo_id = $(this).attr('name');
-        console.log(bwo_id);
+        console.log(bwoid);
         jQuery.ajax({
-            url: url_restart_record_prev,
-            data: bwo_id,
+            url: url.url_restart_record_prev,
+            data: {'bwobject_id': bwoid},
             success: function(json){
                 bootstrap_alert('Object restarted from previous task');
             }
         });
     });
 
     $('#continue_button').on('click', function() {
-        bwo_id = $(this).attr('name');
-        console.log(bwo_id);
         jQuery.ajax({
-            url: url_continue,
-            data: bwo_id,
+            url: url.url_continue,
+            data: {'bwobject_id': bwoid},
             success: function(json){
                 bootstrap_alert('Object continued from next task');
             }
         });
     });
-}
 
-// function bootstrap_alert(message) {
-//     $('#alert_placeholder').html('<div class="alert"><a class="close" data-dismiss="alert">×</a><span>'+message+'</span></div>');
-// }
+    $('#edit_form').on('submit', function(event){
+        event.preventDefault();
+        var form_data = new Object;
+        $("#edit_form input").each(function() {
+            console.log($(this)[0].name);
+            if($(this)[0].name != 'submitButton'){
+                if($(this)[0].name == 'core'){
+                    form_data[$(this)[0].name] = $(this)[0].checked;
+                }
+                else{
+                    form_data[$(this)[0].name] = $(this)[0].value;
+                }
+            }
+        });
+
+        console.log(form_data);
+        jQuery.ajax({
+            type: 'POST',
+            url: url.url_resolve_edit,
+            data: {'objectid': bwoid,
+                   'data': form_data},
+            success: function(json){
+                bootstrap_alert('Record successfully edited');
+            }
+        });
+    });
+}
 
-// window.setTimeout(function() {
-//     $("#alert_placeholder").fadeTo(500, 0).slideUp(500, function(){
-//     });
-// }, 2000);
+function bootstrap_alert(message) {
+    $('#alert_placeholder').html('<div class="alert"><a class="close" data-dismiss="alert">×</a><span>'+message+'</span></div>');
+}
 
 if ( window.addEventListener ) {
     $("div.btn-group[name='data_version']").bind('click', function(event){
         version = event.target.name;
     });
-}
-
-// bwoid = getURLParameter('bwobject_id');
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/invenio/modules/workflows/static/js/workflows/hp_maintable.js b/invenio/modules/workflows/static/js/workflows/hp_maintable.js
index d4bc956f1..1bb0bd05c 100644
--- a/invenio/modules/workflows/static/js/workflows/hp_maintable.js
+++ b/invenio/modules/workflows/static/js/workflows/hp_maintable.js
@@ -1,413 +1,486 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013 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 oTable;
 var selectedRow;
 var rowList = [];
 var rowIndexList = [];
 var hoveredRow = -1;
 var tagList = [];
 var recordsToApprove = [];
 var defaultcss='#example tbody tr.even:hover, #example tbody tr.odd:hover {background-color: #FFFFCC;}';
 
 url = new Object();
 
 function init_urls(url_) {
     url.load_table = url_.load_table;
     url.batch_widget = url_.batch_widget;
     url.resolve_widget = url_.resolve_widget;
     url.delete_single = url_.delete_single;
     url.refresh = url_.refresh;
     url.widget = url_.widget;
     url.details = url_.details;
-
-    init_datatable();
 }
 
-function init_datatable(){
-    oTable = $('#example').dataTable({
+function init_datatable(version_showing){
+    oSettings = {
         "sDom": 'lf<"clear">rtip',
         "bJQueryUI": true,
         "bProcessing": true,
         "bServerSide": true,
         "bDestroy": true,
         "sAjaxSource": url.load_table,
         "oColVis": {
             "buttonText": "Select Columns",
             "bRestore": true,
             "sAlign": "left",
             "iOverlayFade": 1
         },
-        "aoColumnDefs":[{'bSortable': false, 'aTargets': [0]}],
+        "aoColumnDefs":[{'bSortable': false, 'aTargets': [1]},
+                        {'bSearchable': false, 'bVisible': false, 'aTargets': [0]},
+                        {'sWidth': "25%", 'aTargets': [2]},
+                        {'sWidth': "15%", 'aTargets': [4]}],
         "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
-            rememberSelected(nRow);
+            var id = aData[0];
+            rememberSelected(nRow, id);
             oSettings = oTable.fnSettings();
+            nRow.row_id = id;
+            nRow.checkbox = nRow.cells[0].firstChild;
             nRow.addEventListener("click", function(e) {
                 selectRow(nRow, e, oSettings);
             });
+        },
+        "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');
+                });
+            });
         }
+    };
+    oTable = $('#maintable').dataTable(oSettings);
+    oTable.on('page', function( e, o) {
+        $('#select-all')[0].checked = false;
     });
-    oSettings = oTable.fnSettings();
+    initialize_versions(version_showing);
+    $('.dropdown-toggle').dropdown();
+
     return oTable;
-    // $('#version-halted').click();
 }
 
-$('#batch_btn').on('click', function() {
-    if (rowList.length >= 1){
-        var rowList_out = JSON.stringify(rowList);
-        console.log(rowList_out);
-        window.location = url.batch_widget + "?bwolist=" + rowList_out;
-        $(this).prop("disabled", true);
-        return false;
-    }
-});
-
-$('#refresh_button').on('click', function() {
-    jQuery.ajax({
-        url: url.refresh,
-        success: function(json){
+// $('#refresh_button').on('click', function() {
+//     jQuery.ajax({
+//         url: url.refresh,
+//         success: function(json){
             
-        }
-    });
-    oTable.fnDraw(false);
-});
+//         }
+//     });
+//     oTable.fnDraw(false);
+// });
 
 // DataTables row selection functions
 //***********************************
 $("#select-all").on("click", function(){
-    selectAll();
+    console.log($(this)[0].checked);
+    if($(this)[0].checked == true){
+        selectAll();
+    }
+    else{
+        deselectAllFromPage();
+    }
 })
 
 function hoverRow(row) {
     row.style.background = "#FFFFEE";
 }
 
 function unhoverRow(row) {
-    if($.inArray(selectCellByTitle(row, 'Id').innerText, rowList) > -1){
+    console.log(row.row_id);
+    if($.inArray(row.row_id, rowList) > -1){
         row.style.background = "#ffa";
     }
     else{
         row.style.cssText = defaultcss;
     }
 }
 
 function removeSelection () {
     if (window.getSelection) {  // all browsers, except IE before version 9
         var selection = window.getSelection ();                                        
         selection.removeAllRanges ();
     }
     else {
         if (document.selection.createRange) {        // Internet Explorer
             var range = document.selection.createRange ();
             document.selection.empty ();
         }
     }
 }
 
 function selectRange(row){
     var toPos = oTable.fnGetPosition(row) + oSettings._iDisplayStart;
     var fromPos = rowIndexList[rowIndexList.length-1];
     var i;
+    var current_row = null;
 
     if (toPos > fromPos){
         for (i=fromPos; i<=toPos; i++){
             j = i % 10;
             if($.inArray(i, rowIndexList) <= -1){
-                if (selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[j]].nTr, 'Actions').innerText != 'N/A'){
+                current_row = oSettings.aoData[oSettings.aiDisplay[j]].nTr;
+                if (selectCellByTitle(current_row, 'Actions').innerText != 'N/A'){
                     rowIndexList.push(i);
-                    rowList.push(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[j]].nTr, 'Id').innerText);
-                    oSettings.aoData[oSettings.aiDisplay[j]].nTr.style.background = "#ffa";
-                    checkbox = selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[j]].nTr, "").childNodes[1];
-                    checkbox.checked = true;
+                    rowList.push(current_row.row_id);
+                    current_row.style.background = "#ffa";
+                    current_row.checkbox.checked = true;
                 }
             }
         }
     }
     else{
         for (i=fromPos; i>=toPos; i--){
             j = i % 10;
             if($.inArray(i, rowIndexList) <= -1){
-                console.log(oSettings.aoData[oSettings.aiDisplay[j]].nTr);
-                if (selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[j]].nTr, 'Actions').innerText != 'N/A'){
+                current_row = oSettings.aoData[oSettings.aiDisplay[j]].nTr
+                if (selectCellByTitle(current_row, 'Actions').innerText != 'N/A'){
                     rowIndexList.push(i);
-                    rowList.push(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[j]].nTr, 'Id').innerText);
-                    oSettings.aoData[oSettings.aiDisplay[j]].nTr.style.background = "#ffa";
-                    checkbox = selectCellByTitle(oSettings.aiDisplay[j].nTr, "").childNodes[1];
-                    checkbox.checked = false;
+                    rowList.push(current_row.row_id);
+                    current_row.style.background = "#ffa";
+                    current_row.checkbox.checked = false;
                 }
             }
         }
     }
     document.getSelection().removeAllRanges();
 }
 
 function selectAll(){
-    console.log("selecting all");
-    var toPos = oSettings._iDisplayEnd - 1;
-    var fromPos = 0;
-
+    var fromPos = oSettings._iDisplayStart;
+    var toPos = oSettings._iDisplayLength-1 + fromPos;
+    var j;
+
+    console.log(Object.keys(oSettings));
+    console.log(oSettings._iDisplayLength);
+    console.log(oSettings._iRecordsTotal);
+    var current_row = null;
     for (var i=fromPos; i<=toPos; i++){
-        if($.inArray(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[i]].nTr, 'Id').innerText, rowList) <= -1){
-            if (selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[i]].nTr, 'Actions').innerText != 'N/A'){
+        j = i%10;
+        current_row = oSettings.aoData[oSettings.aiDisplay[j]].nTr;
+        if($.inArray(current_row.row_id, rowList) <= -1){
+            if (selectCellByTitle(current_row, 'Actions').innerText != 'N/A'){
                 rowIndexList.push(i);
-                rowList.push(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[i]].nTr, 'Id').innerText);
-                oSettings.aoData[oSettings.aiDisplay[i]].nTr.style.background = "#ffa";
+                rowList.push(current_row.row_id);
+                current_row.style.background = "#ffa";
+                current_row.cells[0].firstChild.checked = true;
             }
         }
     }
 }
 
-function rememberSelected(row) {
-    selectedRow = row;
-    if($.inArray($.trim(selectCellByTitle(row, 'Id').innerText), rowList) > -1){
-        selectedRow.style.background = "#ffa";
-        selectedRow.cells[0].childNodes[1].checked = true;
+function rememberSelected(row, id) {
+    if($.inArray(id, rowList) > -1){
+        row.style.background = "#ffa";
+        row.cells[0].firstChild.checked = true;
     }
 }
 
 window.addEventListener("keydown", function(e){
     var currentRowIndex;
+    var current_row;
     if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
         e.preventDefault();
     }
     if (e.keyCode == 40) {
         if (e.shiftKey === true){
             currentRowIndex = rowIndexList[rowIndexList.length-1];
             if (currentRowIndex < 9){
-                rowToAdd = currentRowIndex + 1;
-                if($.inArray(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr, 'Id').innerText, rowList) <= -1){
-                    rowIndexList.push(rowToAdd);
-                    rowList.push(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr, 'Id').innerText);
-                    oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr.style.background = "#ffa";
+                row_index = currentRowIndex + 1;
+                current_row = oSettings.aoData[oSettings.aiDisplay[row_index]].nTr;
+                if($.inArray(current_row.row_id, rowList) <= -1){
+                    rowIndexList.push(row_index);
+                    rowList.push(current_row.row_id);
+                    current_row.style.background = "#ffa";
                 }
             }
         }
         else{
             if (hoveredRow < 9){
                 if (hoveredRow != -1){
                     unhoverRow(oSettings.aoData[oSettings.aiDisplay[hoveredRow]].nTr);
                 }
                 hoveredRow++;
                 hoverRow(oSettings.aoData[oSettings.aiDisplay[hoveredRow]].nTr);
             }
         }
     }
     else if (e.keyCode == 38) {
         if (e.shiftKey === true){
             currentRowIndex = rowIndexList[rowIndexList.length-1];
             if (currentRowIndex > 0){
                 rowToAdd = currentRowIndex - 1;
-                if($.inArray(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr, 'Id').innerText, rowList) <= -1){
+                var current_row = oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr;
+                if($.inArray(current_row.row_id, rowList) <= -1){
                     rowIndexList.push(rowToAdd);
-                    rowList.push(selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr, 'Id').innerText);
-                    oSettings.aoData[oSettings.aiDisplay[rowToAdd]].nTr.style.background = "#ffa";
+                    rowList.push(current_row.row_id);
+                    current_row.style.background = "#ffa";
                 }
             }
         }
         else{
             if (hoveredRow > 0){
                 unhoverRow(oSettings.aoData[oSettings.aiDisplay[hoveredRow]].nTr);
                 hoveredRow--;
                 hoverRow(oSettings.aoData[oSettings.aiDisplay[hoveredRow]].nTr);
             }
         }
     }
     else if (e.keyCode == 37){
         oTable.fnPageChange('previous');
     }
     else if( e.keyCode == 39){
         oTable.fnPageChange('next');
     }
     else if (e.keyCode == 65 && e.ctrlKey === true){
         selectAll();
         removeSelection();
     }
     else if (e.keyCode == 13 && hoveredRow != -1){
         selectCellByTitle(oSettings.aoData[oSettings.aiDisplay[hoveredRow]].nTr, 'Details').click();
     }
     else if(e.keyCode == 46){
         if (rowList.length >= 1){
             var rowList_out = JSON.stringify(rowList);
             deleteRecords(rowList_out);
             rowList = [];
             rowIndexList = [];
         }
     }
 });
 
 function selectCellByTitle(row, title){
     for(var i=0; i<oSettings.aoHeader[0].length; i++){
         var trimmed_title = $.trim(oSettings.aoHeader[0][i].cell.innerText);
         if(trimmed_title === title){
-            return row.cells[i];
+            return $(row).children()[i - 1];
         }
     }
 }
 
+function getCellIndex(row, title){
+    for(var i=0; i<oSettings.aoHeader[0].length; i++){
+        var trimmed_title = $.trim(oSettings.aoHeader[0][i].cell.innerText);
+        if(trimmed_title === title){
+            return i
+        }
+    }   
+}
+
 function selectRow(row, e, oSettings) {
     selectedRow = row;
+    var widget_name;
     if( e.shiftKey === true ){
         selectRange(row);
     }
     else{
-        var widget_name = selectCellByTitle(row, 'Actions').innerText;    
-        widget_name = widget_name.substring(0, widget_name.length-4);
-        
-        if($.inArray(selectCellByTitle(row, 'Id').innerText, rowList) <= -1){
-            if (selectCellByTitle(row, 'Actions').innerText != 'N/A'){
-                rowList.push(selectCellByTitle(row, 'Id').innerText);
-                rowIndexList.push(row._DT_RowIndex+oSettings._iDisplayStart);
-                selectedRow.style.background = "#ffa";
-                
+        if(selectCellByTitle(row, 'Actions').childNodes[0].id === 'submitButtonMini'){
+            widget_name = 'Approve Record';
+        }
+        if($.inArray(row.row_id, rowList) <= -1){
+            // Select row
+            rowList.push(row.row_id);
+            rowIndexList.push(row._DT_RowIndex+oSettings._iDisplayStart);
+            row.style.background = "#ffa";
+
+            if (selectCellByTitle(row, 'Actions').innerText != 'N/A'){                    
                 if(widget_name === 'Approve Record'){
-                    recordsToApprove.push(selectCellByTitle(row, 'Id').innerText);
+                    recordsToApprove.push(row.row_id);
+                    console.log(recordsToApprove);
                 }
-                checkbox = selectCellByTitle(row, "").childNodes[1];
-                console.log(checkbox);
-                checkbox.checked = true;
-            }
-        }
+            }   
+            row.checkbox.checked = true;
+        }   
         else{
-            rowList.splice(rowList.indexOf(selectCellByTitle(row, 'Id').innerText), 1);
+            // De-Select
+            rowList.splice(rowList.indexOf(row.row_id), 1);
             rowIndexList.splice(rowIndexList.indexOf(row._DT_RowIndex+oSettings._iDisplayStart), 1);
-            selectedRow.style.background = "white";
+            row.style.background = "white";
             
             if(widget_name === 'Approve Record'){
-                recordsToApprove.splice(recordsToApprove.indexOf(selectCellByTitle(row, 'Id').innerText), 1);
+                recordsToApprove.splice(recordsToApprove.indexOf(row.row_id), 1);
             }
-            checkbox = selectCellByTitle(row, "").childNodes[1];
-            checkbox.checked = false;
+            row.checkbox.checked = false;
         }
     }
     checkRecordsToApprove();
-
-    console.log(rowList);
-    console.log(rowIndexList);
-    console.log(recordsToApprove);
 }
 
 function deselectAll(){
     rowList = [];
     rowIndexList = [];
     oTable.fnDraw(false);
     window.getSelection().removeAllRanges();
 }
 
+function deselectAllFromPage(){
+    var fromPos = oSettings._iDisplayStart;
+    var toPos = oSettings._iDisplayLength-1 + fromPos;
+
+    for (i=fromPos; i<=toPos; i++){
+        j = i % 10;
+        if($.inArray(i, rowIndexList) > -1){
+            current_row = oSettings.aoData[oSettings.aiDisplay[j]].nTr;
+            selectRow(current_row, event, oSettings);
+        }
+    }
+}
+
 $(document).keyup(function(e){
     if (e.keyCode == 27) {  // esc           
         deselectAll();
     }   
 });
 //***********************************
 
 // Tags functions
 //***********************************
 $('.task-btn').on('click', function(){
     if($.inArray($(this)[0].name, tagList) <= -1){
         var widget_name = $(this)[0].name;
-        $('#tag-area').append('<div class="alert alert-info tag-alert col-md-1">'+widget_name+'<a id="'+widget_name+'class="close-btn" data-dismiss="alert" name='+widget_name+' onclick="closeTag(this.parentElement)">&times;</a></div>');
+        $('#tagsinput').tagsinput('add', $(this)[0].name);
         tagList.push($(this)[0].name);
-        oTable.fnFilter($(this)[0].name);
-
+        requestNewObjects();
     }
     else{
-        closeTag($('#'+widget_name));
+        closeTag(widget_name);
         oTable.fnFilter( '^$', 4, true, false );
-        $('#refresh_button').click();
+        oTable.fnDraw(false);
     }   
-    // requestNewObjects();
 });
 
 $('.version-selection').on('click', function(){
-    console.log($(this)[0].name);
-    console.log(tagList);
-
     if($.inArray($(this)[0].name, tagList) <= -1){
-        console.log("TAG NOT IN TAGLIST");
-        $('#tag-area').append('<div id="tag-version-'+$(this)[0].name+'" name="'+$(this)[0].name+'" class="alert alert-info tag-alert col-md-1">'+$(this)[0].name+'<a class="close-btn pull-right" data-dismiss="alert" onclick="closeTag(this.parentElement)">&times;</a></div>');
+        $('#tagsinput').tagsinput('add', $(this)[0].name);
         tagList.push($(this)[0].name);
-    } 
-    else{
-        closeTag($('#tag-version-'+$(this)[0].name)[0]);
-    }    
+        requestNewObjects();
+    }
+});
+
+$("#tagsinput").on('itemRemoved', function(event) {
+    tagList.splice(tagList.indexOf(event.item), 1);
+    console.log('item removed : '+event.item);
+    oTable.fnFilter('');
     requestNewObjects();
 });
 
-function closeTag(obj){
-    // console.log(tagList);
-    // console.log(obj);
-    // console.log(obj.name);
-    var tag_name = obj.innerText.substr(0,obj.innerText.length-1);
+$("#tagsinput").on('itemAdded', function(event){
+    if(event.item != 'Halted' && event.item != 'Final' && event.item != 'Running'){
+        oTable.fnFilter(event.item);
+    }
+});
+
+function closeTag(tag_name){
     console.log(tag_name);
-    tagList.splice(tagList.indexOf(obj.name), 1);
-    
-    obj.remove();
+    tagList.splice(tagList.indexOf(tag_name), 1);
+    $('#tagsinput').tagsinput('remove', tag_name);
+    console.log($("#tagsinput").tagsinput('items'));
     requestNewObjects();
 };
 //***********************************
 
 //Utility functions
 //***********************************
+function initialize_versions(version_showing){
+    if(version_showing){
+        for(var i=0; i<version_showing.length; i++){
+            if(version_showing[i] == 1){
+                if ($.inArray('Final', tagList) <= -1){
+                    tagList.push('Final');  
+                } 
+                $('#version-final').click();
+            }
+            else if(version_showing[i] == 2){
+                // tagList.push('Halted');
+                $('#version-halted').click();  
+            }
+            else if(version_showing[i] == 3){
+                if ($.inArray('Halted', tagList) <= -1){
+                    tagList.push('Running');
+                } 
+                $('#version-running').click();  
+            }
+        }
+    }
+}
+
 function fnGetSelected( oTableLocal ){
     var aReturn = [];
     var aTrs = oTableLocal.fnGetNodes();
     
     for ( var i=0 ; i<aTrs.length ; i++ ){
         if ($(aTrs[i]).hasClass('row_selected')){
             aReturn.push( aTrs[i] );
         }
     }
     return aReturn;
 }
 
 function requestNewObjects(){
     var version_showing = new Object;
     // var widget_showing = new Object;
 
     version_showing['final'] = ($.inArray('Final', tagList) <= -1) ? false : true;
     version_showing['halted'] = ($.inArray('Halted', tagList) <= -1) ? false : true;
     version_showing['running'] = ($.inArray('Running', tagList) <= -1) ? false : true;
 
     $.ajax({
         type : "POST",
         url : url.load_table,
         data: JSON.stringify(version_showing),
         contentType: 'application/json;charset=UTF-8',
         traditional: true,
         success: function(result) {
-            $('#refresh_button').click();
+            oTable.fnDraw(false);
         }
     });
 }
 
 function isInt(n) {
    return typeof n === 'number' && n % 1 === 0;
 }
 
 function emptyLists(){
     rowList = [];
     rowIndexList = [];
 }
 
+$.fn.exists = function () {
+    return this.length !== 0;
+}
+
 function bootstrap_alert(message) {
     $('#alert-message').html('<span class="alert"><a class="close" data-dismiss="alert"> ×</a><span>'+message+'</span></span>');
 }
 //***********************************
 
 
diff --git a/invenio/modules/workflows/static/js/workflows/index.js b/invenio/modules/workflows/static/js/workflows/index.js
index d3aa1479b..3640c9275 100644
--- a/invenio/modules/workflows/static/js/workflows/index.js
+++ b/invenio/modules/workflows/static/js/workflows/index.js
@@ -1,86 +1,85 @@
 /*
  * This file is part of Invenio.
  * Copyright (C) 2013 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.
  */
 
 
 function get_redis_data(url){
     a = "";
     tags = $("span.sort_tag");
     for (i=0; i<tags.length; i++){
         a += $(tags[i]).attr('name')+" ";
     }
     jQuery.ajax({
                 url: url,
                 data: {'key': a},
                 success: function(json){
-                    alert(json)}
                 })
 }
 
 function init_index(url_redis_get, url_entry, url_workflow) {
     $("tbody > tr.workflow").bind('click', function(){
                     hp_id = $(this).attr('name');
                     jQuery.ajax({
                         url: url_workflow,
                         data: {'id_workflow': hp_id},
                         success: function(json){
                             $("#myModal").html(json);
                             $('#myModal').modal('show');}
                         })
     });
     $("tbody > tr.object").bind('click', function(){
                     hp_id = $(this).attr('name');
                     jQuery.ajax({
                         url: url_entry,
                         data: {'id_entry': hp_id},
                         success: function(json){
                             $("#myModal").html(json);
                             $('#myModal').modal('show');}
                         })
     });
 
     $(".entry_message_button").bind('click', function(){
                     hp_id = $(this).attr('name');
                     TINY.box.show({url:"/match_details/1" + hp_id,width:"800",height:"600", animate:false});
     });
 
     jQuery.ajax({
                 url: url_redis_get,
                 data: {'key': $("form select#search_key_1").val()},
                 success: function(json){
                     $("form select#search_key_2").html(json);
                     $("form select#search_key_2").removeAttr('disabled');
                 }});
     $("form select#search_key_1").bind('change', function(){
                     key = $(this).val();
                     jQuery.ajax({
                         url: url_redis_get,
                         data: {'key': key},
                         success: function(json){
                             $("form select#search_key_2").html(json);
                             $("form select#search_key_2").removeAttr('disabled');
                         }});
     });
 
     $("form span#search_button").bind('click', function(){
         a = $("div#search_tags").html()
         a += "<span class='label sort_tag' name='"+$("form select#search_key_1").val()+":"+$("form select#search_key_2").val()+"'>"+$("form select#search_key_1").val()+": "+$("form select#search_key_2").val()+"&nbsp;<i class='icon-remove remove_sort_tag'></i></span>&nbsp;"
         $("div#search_tags").html(a)
         get_redis_data(url_redis_get);
     });
 }
diff --git a/invenio/modules/workflows/static/js/workflows/widgets/approval.js b/invenio/modules/workflows/static/js/workflows/widgets/approval.js
index 9d29340fd..ad1e1c44e 100644
--- a/invenio/modules/workflows/static/js/workflows/widgets/approval.js
+++ b/invenio/modules/workflows/static/js/workflows/widgets/approval.js
@@ -1,191 +1,211 @@
 // -*- coding: utf-8 -*-
 // This file is part of Invenio.
 // Copyright (C) 2013 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 bwoid;
 var datapreview = "hd";
 var number_of_objs = $(".theform").length;
 var current_number = number_of_objs-1;
 url = new Object();
 
 function init_urls_approval(url_){
     url = url_;
 }
 
 function checkRecordsToApprove(){
     if(recordsToApprove.length > 1){
         hideApproveAll();
         approveAll();
     }
     else{
         hideApproveAll();
     }
 }
 
 function disapproveRecords(){
     console.log("deleting");
     deleteRecords(recordsToApprove);
     recordsToApprove = [];
     // TODO: 
     // the bug here will occur when there are records with other widgets
     // than approval.
     emptyLists();
     checkRecordsToApprove();
 }
 
 function hideApproveAll(){
     $('#multi-approval').empty();
 }
 
 function approveAll() {
     var rejectBtn = '<button type="button" class="btn btn-danger">'+
                     '<a id="reject-multi" href="#confirmationModal" class="mini-approval-btn" data-toggle="modal">'+
                     'Reject</a></button>';
     var acceptBtn = '<button type="button" class="btn btn-success">'+
                     '<a id="accept-multi" href="javascript:void(0)" class="mini-approval-btn">'+
                     'Accept</a></button>';
-    $('#multi-approval').append(rejectBtn, acceptBtn);
-    $('#accept-multi').click( function(){
+
+    if(!$('#batch-btn').exists()){    
+        var accept_link = "<a id='drop-down-accept' class='drop-down-btns btn' href='#'>Accept All</a>";
+        var reject_link = "<a id='drop-down-reject' class='drop-down-btns btn' href='#'>Reject All</a>";
+
+        var batch_btn = '<li class="dropdown">'+
+              '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>'+
+              '<ul class="dropdown-menu">'+
+                '<li>'+accept_link+'</li>'+
+                '<li>'+reject_link+'</li>'+
+                '<li class="divider"></li>'+
+                '<li><a href="#">Go to Widget</a></li>'+
+              '</ul>'+
+            '</li>';
+
+        $('#navbar-right').append(batch_btn);
+        $('.dropdown-toggle').dropdown();
+    }
+
+    $('#drop-down-accept').on('click', function(){
         for(i=0; i<recordsToApprove.length; i++){
+            console.log(recordsToApprove[i]);
             jQuery.ajax({
                 type: "POST",
                 url: url.resolve_widget,
-                data: {'bwobject_id': recordsToApprove[i],
+                data: {'objectid': recordsToApprove[i],
                        'widget': 'approval_widget',
                        'decision': 'Accept'},
                 success: function(json){
                     recordsToApprove = [];
                     $('#refresh_button').click();
                     checkRecordsToApprove();
                 }
             });
         }
     });
-};
 
-function mini_approval(decision, event){
-    var bwobject_id = event.currentTarget.parentElement.parentElement.cells[1].innerText;
+    $('#drop-down-reject').on('click', function(){
+        for(i=0; i<recordsToApprove.length; i++){
+            console.log(recordsToApprove[i]);
+            jQuery.ajax({
+                type: "POST",
+                url: url.resolve_widget,
+                data: {'objectid': recordsToApprove[i],
+                       'widget': 'approval_widget',
+                       'decision': 'Reject'},
+                success: function(json){
+                    recordsToApprove = [];
+                    $('#refresh_button').click();
+                    checkRecordsToApprove();
+                }
+            });
+        }
+    });
+}
 
+function mini_approval(decision, event, objectid){
     jQuery.ajax({
         type: "POST",
         url: url.resolve_widget,
-        data: {'bwobject_id': bwobject_id,
+        data: {'objectid': objectid,
                'widget': "approval_widget",
                'decision': decision},
         success: function(json){
             deselectAll();
             recordsToApprove = [];
             $('#refresh_button').click();     
             checkRecordsToApprove();
         }
     });
     oTable.fnDraw(false);
 };
 
 function deleteRecords(bwolist){
     for(i=0; i<recordsToApprove.length; i++){
         console.log(bwolist[i]);
         jQuery.ajax({
             url: url.delete_single,
-            data: {'bwobject_id': bwolist[i]},
+            data: {'objectid': bwolist[i]},
             success: function(){
                 $('#refresh_button').click();
             }
         });
     }
 };
 
 $(document).ready(function(){
     $(".message").hide();
+    $("#batch-btn").popover();
 
     $('.theform #submitButton').click( function(event) {
         event.preventDefault();
 
-        var form_id = $(this)[0].form.parentElement.previousElementSibling.id;
-        id_number = form_id.substring(form_id.indexOf("d")+1);
-        btn_div_id = "decision-btns"+id_number;
-        hr_id = "hr"+id_number;
+        var form_name = $(this)[0].form.name;
+        var bwo_id = form_name.substring(form_name.indexOf('bwobject_id')+12);
+        var form_id = $(this)[0].form.id.substring(4);
+
+        btn_div_id = "decision-btns"+form_id;
+        hr_id = "hr"+form_id;
         
         formdata = $(this)[0].value;
         formurl = event.currentTarget.parentElement.name;
+        console.log(formurl);
         $.ajax({
             type: "POST",
             url: formurl,
             data: {'decision': formdata},
             success: function(data){
                 $("#"+form_id).fadeOut(400);                
                 $("#"+btn_div_id).fadeOut(400);
                 $("#"+hr_id).fadeOut(400);
                 current_number--;
             }
         });
         if (current_number === 0){
             $("#goodbye-msg").text("All Done!");
         }
     });
 
     window.setbwoid = function(id){
         bwoid = id;
         console.log(bwoid);
         data_preview(url_preview, bwoid, datapreview);
     };
 
     window.setDataPreview = function(dp, id){
         bwoid = id;
         datapreview = dp;
-        console.log(url_preview);
-        data_preview(url_preview, bwoid, datapreview);
+        console.log(url.preview);
+        data_preview(url.preview, bwoid, datapreview);
     }
 
     $('#submitButtonMini').click( function (event){
         console.log(event);
     });
 
     $('body').append(
         '<div id="confirmationModal" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">'+
             '<div class="modal-header">'+
                 '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'+
                 '<h3 id="myModalLabel">Please Confirm</h3>'+
             '</div>'+
             '<div class="modal-body">'+
                 '<p>Are you sure you want to delete the selected records?</p>'+
             '</div>'+
             '<div class="modal-footer">'+
                 '<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>'+
                 '<a class="btn btn-danger" href="#" data-dismiss="modal" onclick="disapproveRecords()">Delete Records</a>'+
             '</div>'+
         '</div>');
-    // $.ajax({
-    //     url: "hp_maintable.html",
-    //     success: function (data) { $('body').append(
-    //         '<div id="confirmationModal" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">'+
-    //             '<div class="modal-header">'+
-    //                 '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'+
-    //                 '<h3 id="myModalLabel">Please Confirm</h3>'+
-    //             '</div>'+
-    //             '<div class="modal-body">'+
-    //                 '<p>Are you sure you want to delete the selected records?</p>'+
-    //             '</div>'+
-    //             '<div class="modal-footer">'+
-    //                 '<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>'+
-    //                 '<a class="btn btn-danger" href="#" data-dismiss="modal" onclick="disapproveRecords()">Delete Records</a>'+
-    //             '</div>'+
-    //         '</div>'); },
-    //     dataType: 'html'
-    // });
-});
\ No newline at end of file
+});
diff --git a/invenio/modules/workflows/tasks/marcxml_tasks.py b/invenio/modules/workflows/tasks/marcxml_tasks.py
index bc4c510c0..8a035e8e3 100644
--- a/invenio/modules/workflows/tasks/marcxml_tasks.py
+++ b/invenio/modules/workflows/tasks/marcxml_tasks.py
@@ -1,941 +1,937 @@
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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 os
 import random
 import time
 import glob
 import re
 import traceback
 from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
 
 from invenio.legacy.bibupload.engine import (find_record_from_recid,
                                              find_record_from_sysno,
                                              find_records_from_extoaiid,
                                              find_record_from_oaiid,
                                              find_record_from_doi
                                              )
 from invenio.legacy.oaiharvest.dblayer import update_lastrun, create_oaiharvest_log_str
 from invenio.base.config import (CFG_TMPSHAREDDIR,
                                  CFG_TMPDIR,
                                  CFG_INSPIRE_SITE)
 from invenio.legacy.oaiharvest.utils import (record_extraction_from_file,
                                              collect_identifiers,
                                              harvest_step,
                                              translate_fieldvalues_from_latex,
                                              find_matching_files,
                                              )
 from invenio.legacy.bibsched.bibtask import (task_sleep_now_if_required,
                                              task_low_level_submission
                                              )
 from invenio.modules.oaiharvester.models import OaiHARVEST
-from invenio.modules.records.api import Record
+from invenio.modules.records.api import Record, create_record
 from invenio.modules.workflows.errors import WorkflowError
 from invenio.legacy.refextract.api import extract_references_from_file_xml
 from invenio.legacy.bibrecord import (create_records,
                                       record_xml_output
                                       )
 from invenio.utils.plotextractor.output_utils import (create_MARC,
                                                       create_contextfiles,
                                                       prepare_image_data,
                                                       remove_dups
                                                       )
 from invenio.utils.plotextractor.getter import (harvest_single,
                                                 make_single_directory
                                                 )
 
 from invenio.utils.plotextractor.cli import (get_defaults,
                                              extract_captions,
                                              extract_context
                                              )
 from invenio.utils.shell import (run_shell_command,
                                  Timeout
                                  )
 import invenio.legacy.template
 from invenio.utils.plotextractor.converter import (untar,
                                                    convert_images
                                                    )
 
 
 oaiharvest_templates = invenio.legacy.template.load('oaiharvest')
 
 REGEXP_REFS = re.compile("<record.*?>.*?<controlfield .*?>.*?</controlfield>(.*?)</record>", re.DOTALL)
 REGEXP_AUTHLIST = re.compile("<collaborationauthorlist.*?</collaborationauthorlist>", re.DOTALL)
 
 
 def add_metadata_to_extra_data(obj, eng):
     """
     Creates bibrecord from object data and
     populates extra_data with metadata
     @param obj:
     @param eng:
     """
     obj.extra_data["_last_task_name"] = "add_metadata_to_extra_data"
-    from invenio.legacy.bibrecord import create_record, record_get_field_value
+    from invenio.legacy.bibrecord import create_record as old_create_record, record_get_field_value
 
-    record = create_record(obj.data)
+    record = old_create_record(obj.data)
 
     obj.extra_data['redis_search']['category'] = \
         record_get_field_value(record[0], '037', code='c')
     obj.extra_data['redis_search']['title'] = \
         record_get_field_value(record[0], '245', code='a')
     obj.extra_data['redis_search']['source'] = \
         record_get_field_value(record[0], '035', code='9')
 
 
 add_metadata_to_extra_data.__title__ = "Metadata Extraction"
 add_metadata_to_extra_data.__description__ = "Populates object's extra_data with metadata"
 
 
 def approve_record(obj, eng):
     """
     Will add the approval widget to the record
     """
     try:
         eng.halt(widget="approval_widget",
                  msg='Record needs approval')
     except KeyError:
         # Log the error
         obj.extra_data["_error_msg"] = 'Could not assign widget'
 
 
 approve_record.__title__ = "Record Approval"
 approve_record.__description__ = "This task assigns the approval widget to a record."
 
 
 def filtering_oai_pmh_identifier(obj, eng):
     if not "_function_reserved_filtering_oai_pmh_identifier" in eng.extra_data:
         eng.extra_data["_function_reserved_filtering_oai_pmh_identifier"] = {}
     if not "identifiers" in eng.extra_data["_function_reserved_filtering_oai_pmh_identifier"]:
         eng.extra_data["_function_reserved_filtering_oai_pmh_identifier"]["identifiers"] = []
     try:
         if not isinstance(obj.data, list):
             obj_data_list = [obj.data]
         else:
             obj_data_list = obj.data
         for record in obj_data_list:
             substring = record[record.index("<identifier>") + 12:record.index("</identifier>")]
             if substring in eng.extra_data["_function_reserved_filtering_oai_pmh_identifier"]["identifiers"]:
                 return False
             else:
                 eng.extra_data["_function_reserved_filtering_oai_pmh_identifier"]["identifiers"].append(substring)
                 return True
     except TypeError:
         eng.log.error("object data type invalid. Ignoring this step!")
         return True
 
 
 def inspire_filter_custom(fields, custom_accepted=(), custom_refused=(),
                           custom_widgeted=(), widget=None):
     def _inspire_filter_custom(obj, eng):
 
         custom_to_process_current = []
         custom_to_process_next = []
         action_to_take = [0, 0, 0]
 
         fields_to_process = fields
         if not isinstance(fields_to_process, list):
             fields_to_process = [fields_to_process]
 
         for field in fields_to_process:
             if len(custom_to_process_current) == 0:
                 custom_to_process_current.append(obj.data[field])
             else:
                 while len(custom_to_process_current) > 0:
                     one_custom = custom_to_process_current.pop()
                     if isinstance(one_custom, list):
                         for i in one_custom:
                             custom_to_process_current.append(i)
                     else:
                         try:
                             custom_to_process_next.append(one_custom[field])
                         except KeyError:
                             eng.log.error("no %s in %s", field, one_custom)
                 custom_to_process_current = custom_to_process_next[:]
         if not custom_to_process_next:
             eng.log.error("%s not found in the record. Human intervention needed", fields_to_process)
             eng.halt(str(fields_to_process) + " not found in the record. Human intervention needed", widget=widget)
 
         for i in custom_widgeted:
             if i != '*':
                 i = re.compile('^' + re.escape(i) + '.*')
                 for y in custom_to_process_next:
                     if i.match(y):
                         action_to_take[0] += 1
 
         for i in custom_accepted:
             if i != '*':
                 i = re.compile('^' + re.escape(i) + '.*')
                 for y in custom_to_process_next:
                     if i.match(y):
                         action_to_take[1] += 1
 
         for i in custom_refused:
             if i != '*':
                 i = re.compile('^' + re.escape(i) + '.*')
                 for y in custom_to_process_next:
                     if i.match(y):
                         action_to_take[2] += 1
 
         sum_action = action_to_take[0] + action_to_take[1] + action_to_take[2]
 
         if sum_action == 0:
             #We allow the * option which means at final case
             if '*' in custom_widgeted:
                 return None
             elif '*' in custom_refused:
                 eng.stopProcessing()
             elif '*' in custom_accepted:
                 return None
             else:
                 # We don't know what we should do, in doubt query human... they are nice!
                 msg = ("Category out of task definition. "
                        "Human intervention needed")
                 eng.halt(msg, widget=widget)
         else:
             if sum_action == action_to_take[0]:
                 eng.halt("Category filtering needs human intervention",
                          widget=widget)
             elif sum_action == action_to_take[1]:
                 return None
             elif sum_action == action_to_take[2]:
                 eng.stopProcessing()
             else:
                 eng.halt("Category filtering needs human intervention, rules are incoherent !!!",
                          widget=widget)
 
     return _inspire_filter_custom
 
 
 def inspire_filter_category(category_accepted_param=(), category_refused_param=(),
                             category_widgeted_param=(), widget_param=None):
     def _inspire_filter_category(obj, eng):
         try:
             category_accepted = obj.extra_data["_repository"]["arguments"]["filtering"]['category_accepted']
         except KeyError:
             category_accepted = category_accepted_param
         try:
             category_refused = obj.extra_data["_repository"]["arguments"]["filtering"]['category_refused']
         except KeyError:
             category_refused = category_refused_param
         try:
             category_widgeted = obj.extra_data["_repository"]["arguments"]["filtering"]['category_widgeted']
         except KeyError:
             category_widgeted = category_widgeted_param
         try:
             widget = obj.extra_data["_repository"]["arguments"]["filtering"]['widget']
         except KeyError:
             widget = widget_param
 
         category_to_process = []
         action_to_take = [0, 0, 0]
         try:
             category = obj.data["report_number"]
             if isinstance(category, list):
                 for i in category:
                     category_to_process.append(i["arxiv_category"])
             else:
                 category_to_process.append(category["arxiv_category"])
             obj.add_task_result("Category filter", category_to_process)
         except KeyError:
             msg = "Category not found in the record. Human intervention needed"
             eng.log.error(msg)
             eng.halt(msg, widget=widget)
 
         for i in category_widgeted:
             if i != '*':
                 i = re.compile('^' + re.escape(i) + '.*')
                 for y in category_to_process:
                     if i.match(y):
                         action_to_take[0] += 1
 
         for i in category_accepted:
             if i != '*':
                 i = re.compile('^' + re.escape(i) + '.*')
                 for y in category_to_process:
                     if i.match(y):
                         action_to_take[1] += 1
 
         for i in category_refused:
             if i != '*':
                 i = re.compile('^' + re.escape(i) + '.*')
                 for y in category_to_process:
                     if i.match(y):
                         action_to_take[2] += 1
 
         sum_action = action_to_take[0] + action_to_take[1] + action_to_take[2]
 
         if sum_action == 0:
             #We allow the * option which means at final case
             if '*' in category_accepted:
                 return None
             elif '*' in category_refused:
                 eng.stopProcessing()
             else:
                 # We don't know what we should do, in doubt query human... they are nice!
                 msg = ("Category out of task definition. "
                        "Human intervention needed")
                 eng.halt(msg, widget=widget)
         else:
             if sum_action == action_to_take[0]:
                 eng.halt("Category filtering needs human intervention",
                          widget=widget)
             elif sum_action == action_to_take[1]:
                 return None
             elif sum_action == action_to_take[2]:
                 eng.stopProcessing()
             else:
                 eng.halt("Category filtering needs human intervention, rules are incoherent !!!",
                          widget=widget)
 
     return _inspire_filter_category
 
 
 def convert_record_to_bibfield(obj, eng):
     """
     Convert a record in data log.errorinto a 'dictionary'
     thanks to BibField
     """
+    obj.extra_data["last_task_name"] = "last task name: convert_record_to_bibfield"
     obj.data = create_record(obj.data, master_format="marc").dumps()
     eng.log.info("Field conversion succeeded")
 
 
 def init_harvesting(obj, eng):
     """
     This function gets all the option linked to the task and stores them into the
     object to be used later.
     """
     try:
         obj.extra_data["options"] = eng.extra_data["options"]
     except KeyError:
         eng.log.error("Non Critical Error: No options", "No options for this task have been found. It is possible"
                                                         "that the following task could failed or work not as expected")
         obj.extra_data["options"] = {}
     eng.log.info("end of init_harvesting")
 
 
 def get_repositories_list(repositories=()):
     """
     Here we are retrieving the oaiharvest configuration for the task.
     It will allows in the future to do all the correct operations.
     """
 
     def _get_repositories_list(obj, eng):
         repositories_to_harvest = repositories
         reposlist_temp = []
         if obj.extra_data["options"]["repository"]:
             repositories_to_harvest = obj.extra_data["options"]["repository"]
         if repositories_to_harvest:
             for reposname in repositories_to_harvest:
                 try:
                     reposlist_temp.append(OaiHARVEST.get(OaiHARVEST.name == reposname).one())
                 except (MultipleResultsFound, NoResultFound):
                     eng.log.error("CRITICAL: repository %s doesn't exit into our database", reposname)
         else:
             reposlist_temp = OaiHARVEST.get(OaiHARVEST.name != "").all()
         true_repo_list = []
         for repo in reposlist_temp:
             true_repo_list.append(repo.to_dict())
 
         if true_repo_list:
             return true_repo_list
         else:
             eng.halt("No Repository named %s. Impossible to harvest non-existing things." % repositories_to_harvest)
 
     return _get_repositories_list
 
 
 def harvest_records(obj, eng):
     """
     Run the harvesting task.  The row argument is the oaiharvest task
     queue row, containing if, arguments, etc.
     Return 1 in case of success and 0 in case of failure.
     """
     harvested_identifier_list = []
 
     harvestpath = "%s_%d_%s_" % ("%s/oaiharvest_%s" % (CFG_TMPSHAREDDIR, eng.uuid),
                                  1, time.strftime("%Y%m%d%H%M%S"))
 
     # ## go ahead: check if user requested from-until harvesting
     try:
         if "dates" not in obj.extra_data["options"]:
             obj.extra_data["options"]["dates"] = []
         if "identifiers" not in obj.extra_data["options"]:
             obj.extra_data["options"]["identifiers"] = []
     except TypeError:
         obj.extra_data["options"] = {"dates": [], "identifiers": []}
 
     task_sleep_now_if_required()
 
     arguments = obj.extra_data["_repository"]["arguments"]
     if arguments:
         eng.log.info("running with post-processes: %r" % (arguments,))
     else:
         eng.log.error("No arguments found... It can be causing major error after this point.")
 
     # Harvest phase
 
     try:
         harvested_files_list = harvest_step(obj,
                                             harvestpath)
     except Exception as e:
         eng.log.error("Error while harvesting %s. Skipping." % (obj.data,))
 
         raise WorkflowError("Error while harvesting %r. Skipping : %s." % (obj.data, repr(e)),
                             id_workflow=eng.uuid, id_object=obj.id)
 
     if len(harvested_files_list) == 0:
         eng.log.info("No records harvested for %s" % (obj.data["name"],))
         # Retrieve all OAI IDs and set active list
 
     harvested_identifier_list.append(collect_identifiers(harvested_files_list))
 
     if len(harvested_files_list) != len(harvested_identifier_list[0]):
         # Harvested files and its identifiers are 'out of sync', abort harvest
 
         raise WorkflowError("Harvested files miss identifiers for %s" % (arguments,), id_workflow=eng.uuid,
                             id_object=obj.id)
     obj.extra_data['harvested_files_list'] = harvested_files_list
     eng.log.info("%d files harvested and processed \n End harvest records task" % (len(harvested_files_list),))
 
 
 harvest_records.__id__ = "h"
 
 
 def get_records_from_file(path=None):
     def _get_records_from_file(obj, eng):
         if not "_LoopData" in eng.extra_data:
             eng.extra_data["_LoopData"] = {}
         if "get_records_from_file" not in eng.extra_data["_LoopData"]:
             eng.extra_data["_LoopData"]["get_records_from_file"] = {}
             if path:
                 eng.extra_data["_LoopData"]["get_records_from_file"].update({"data": record_extraction_from_file(path)})
             else:
                 eng.extra_data["_LoopData"]["get_records_from_file"].update(
                     {"data": record_extraction_from_file(obj.data)})
                 eng.extra_data["_LoopData"]["get_records_from_file"]["path"] = obj.data
 
         elif os.path.isfile(obj.data) and obj.data != eng.extra_data["_LoopData"]["get_records_from_file"]["path"]:
             eng.extra_data["_LoopData"]["get_records_from_file"].update({"data": record_extraction_from_file(obj.data)})
         return eng.extra_data["_LoopData"]["get_records_from_file"]["data"]
 
     return _get_records_from_file
 
 
 def get_eng_uuid_harvested(obj, eng):
     """
     Simple function which allows to retrieve the uuid of the eng in the workflow
     for printing by example
     """
     eng.log.info("last task name: get_eng_uuid_harvested")
     return "*" + str(eng.uuid) + "*.harvested"
 
 
 def get_files_list(path, parameter):
     def _get_files_list(obj, eng):
         if callable(parameter):
             unknown = parameter
             while callable(unknown):
                 unknown = unknown(obj, eng)
 
         else:
             unknown = parameter
         result = glob.glob1(path, unknown)
         for i in range(0, len(result)):
             result[i] = path + os.sep + result[i]
         return result
 
     return _get_files_list
 
 
 def get_obj_extra_data_key(name):
     def _get_obj_extra_data_key(obj, eng):
         return obj.extra_data[name]
 
     return _get_obj_extra_data_key
 
 
 def get_eng_extra_data_key(name):
     def _get_eng_extra_data_key(obj, eng):
         return eng.extra_data[name]
 
     return _get_eng_extra_data_key
 
 
 def convert_record(stylesheet="oaidc2marcxml.xsl"):
     def _convert_record(obj, eng):
         """
         Will convert the object data, if XML, using the given stylesheet
         """
         from invenio.legacy.bibconvert.xslt_engine import convert
 
         eng.log.info("Starting conversion using %s stylesheet" %
                      (stylesheet,))
 
         try:
             obj.data = convert(obj.data, stylesheet)
         except Exception as e:
             msg = "Could not convert record: %s\n%s" % \
                   (str(e), traceback.format_exc())
             obj.extra_data["_error_msg"] = msg
             raise WorkflowError("Error: %s" % (msg,),
                                 id_workflow=eng.uuid, id_object=obj.id)
 
     return _convert_record
 
 
 def convert_record_with_repository(stylesheet="oaidc2marcxml.xsl"):
     def _convert_record(obj, eng):
         """
         Will convert the object data, if XML, using the stylesheet
         in the OAIrepository stored in the object extra_data.
         """
         eng.log.info("my type: %s" % (obj.data_type,))
         try:
             if not obj.extra_data["_repository"]["arguments"]['c_stylesheet']:
                 stylesheet_to_use = stylesheet
             else:
                 stylesheet_to_use = obj.extra_data["_repository"]["arguments"]['c_stylesheet']
         except KeyError:
             eng.log.error("WARNING: HASARDOUS BEHAVIOUR EXPECTED, "
                           "You didn't specified style_sheet in argument for conversion,"
                           "try to recover by using the default one!")
             stylesheet_to_use = stylesheet
         convert_record(stylesheet_to_use)(obj, eng)
 
     return _convert_record
 
 
 def update_last_update(repository_list):
     def _update_last_update(obj, eng):
         if "_should_last_run_be_update" in obj.extra_data:
             if obj.extra_data["_should_last_run_be_update"]:
                 repository_list_to_process = repository_list
                 if not isinstance(repository_list_to_process, list):
                     if callable(repository_list_to_process):
                         while callable(repository_list_to_process):
                             repository_list_to_process = repository_list_to_process(obj, eng)
                     else:
                         repository_list_to_process = [repository_list_to_process]
                 for repository in repository_list_to_process:
                     update_lastrun(repository["id"])
 
     return _update_last_update
 
 
 def fulltext_download(obj, eng):
     """
     Performs the fulltext download step.
     Only for arXiv
     """
     if "result" not in obj.extra_data:
         obj.extra_data["_result"] = {}
     task_sleep_now_if_required()
     if "pdf" not in obj.extra_data["_result"]:
         extract_path = make_single_directory(CFG_TMPSHAREDDIR, eng.uuid)
         tarball, pdf = harvest_single(obj.data["system_number_external"]["value"],
                                       extract_path, ["pdf"])
         arguments = obj.extra_data["_repository"]["arguments"]
         try:
             if not arguments['t_doctype'] == '':
                 doctype = arguments['t_doctype']
             else:
                 doctype = 'arXiv'
         except KeyError:
             eng.log.error("WARNING: HASARDOUS BEHAVIOUR EXPECTED, "
                           "You didn't specified t_doctype in argument for fulltext_download,"
                           "try to recover by using the default one!")
             doctype = 'arXiv'
         if pdf:
             obj.extra_data["_result"]["pdf"] = pdf
             fulltext_xml = ("  <datafield tag=\"FFT\" ind1=\" \" ind2=\" \">\n"
                             "    <subfield code=\"a\">%(url)s</subfield>\n"
                             "    <subfield code=\"t\">%(doctype)s</subfield>\n"
                             "    </datafield>"
 
                             ) % {'url': obj.extra_data["_result"]["pdf"],
                                  'doctype': doctype}
             updated_xml = '<?xml version="1.0" encoding="UTF-8"?>\n<collection>\n<record>\n' + fulltext_xml + \
                           '</record>\n</collection>'
-            from invenio.modules.records.api import create_record
 
-            new_dict_representation = create_record(updated_xml).dumps()
+            new_dict_representation = create_record(updated_xml, master_format="marc").dumps()
             try:
                 obj.data['fft'].append(new_dict_representation["fft"])
             except (KeyError, TypeError):
                 obj.data['fft'] = [new_dict_representation['fft']]
 
             obj.add_task_result("filesfft", new_dict_representation["fft"])
     else:
         eng.log.info("There was already a pdf register for this record,"
                      "perhaps a duplicate task in you workflow.")
 
 
 def quick_match_record(obj, eng):
     """
     Retrieve the record Id from a record by using tag 001 or SYSNO or OAI ID or DOI
     tag. opt_mod is the desired mode.
 
     001 fields even in the insert mode
     """
     function_dictionnary = {'recid': find_record_from_recid, 'system_number': find_record_from_sysno,
                             'oaiid': find_record_from_oaiid, 'system_number_external': find_records_from_extoaiid,
                             'doi': find_record_from_doi}
 
     my_json_reader = Record(obj.data)
 
     try:
         identifiers = my_json_reader.get('_persistent_identifier')
         if not identifiers:
             return False
         else:
             obj.persistent_ids = identifiers
     except KeyError:
         identifiers = {}
 
     if not "recid" in identifiers:
         for identifier in identifiers:
             recid = function_dictionnary[identifier](identifiers[identifier]["value"])
             if recid:
                 obj.data['recid']['value'] = recid
                 obj.persistent_ids["recid"] = recid
                 return True
         return False
     else:
         return True
 
 
 def upload_record(mode="ir"):
     def _upload_record(obj, eng):
         from invenio.legacy.bibsched.bibtask import task_low_level_submission
 
         eng.log_info("Saving data to temporary file for upload")
         filename = obj.save_to_file()
         params = ["-%s" % (mode,), filename]
         task_id = task_low_level_submission("bibupload", "bibworkflow",
                                             *tuple(params))
         eng.log_info("Submitted task #%s" % (task_id,))
 
     _upload_record.__title__ = "Upload Record"
     _upload_record.__description__ = "Uploads the record using BibUpload"
     return _upload_record
 
 
 upload_record.__id__ = "u"
 
 
 def plot_extract(plotextractor_types):
     def _plot_extract(obj, eng):
         """
         Performs the plotextraction step.
         """
         # Download tarball for each harvested/converted record, then run plotextrator.
         # Update converted xml files with generated xml or add it for upload
         task_sleep_now_if_required()
         if "_result" not in obj.extra_data:
             obj.extra_data["_result"] = {}
 
         if not 'p_extraction-source' in obj.extra_data["_repository"]["arguments"]:
             p_extraction_source = plotextractor_types
         else:
             p_extraction_source = obj.extra_data["_repository"]["arguments"]['p_extraction-source']
 
         if not isinstance(p_extraction_source, list):
             p_extraction_source = [p_extraction_source]
 
         if 'latex' in p_extraction_source:
             # Run LaTeX plotextractor
             if "tarball" not in obj.extra_data["_result"]:
                 # turn oaiharvest_23_1_20110214161632_converted -> oaiharvest_23_1_material
                 # to let harvested material in same folder structure
                 extract_path = make_single_directory(CFG_TMPSHAREDDIR, eng.uuid)
                 tarball, pdf = harvest_single(obj.data["system_number_external"]["value"], extract_path, ["tarball"])
                 tarball = str(tarball)
                 if tarball is None:
                     raise WorkflowError(str("Error harvesting tarball from id: %s %s" %
                                             (obj.data["system_number_external"]["value"], extract_path)),
                                         eng.uuid, id_object=obj.id)
 
                 obj.extra_data["_result"]["tarball"] = tarball
             else:
                 tarball = obj.extra_data["_result"]["tarball"]
 
             sub_dir, refno = get_defaults(tarball, CFG_TMPDIR, "")
 
             tex_files = None
             image_list = None
             try:
                 extracted_files_list, image_list, tex_files = untar(tarball, sub_dir)
             except Timeout:
                 eng.log.error('Timeout during tarball extraction on %s' % (tarball,))
 
             converted_image_list = convert_images(image_list)
             eng.log.info('converted %d of %d images found for %s' % (len(converted_image_list),
                                                                      len(image_list),
                                                                      os.path.basename(tarball)))
             extracted_image_data = []
             if tex_files == [] or tex_files is None:
                 eng.log.error('%s is not a tarball' % (os.path.split(tarball)[-1],))
                 run_shell_command('rm -r %s', (sub_dir,))
             else:
                 for tex_file in tex_files:
                 # Extract images, captions and labels
                     partly_extracted_image_data = extract_captions(tex_file, sub_dir,
                                                                    converted_image_list)
                     if partly_extracted_image_data:
                         # Add proper filepaths and do various cleaning
                         cleaned_image_data = prepare_image_data(partly_extracted_image_data,
                                                                 tex_file, converted_image_list)
                         # Using prev. extracted info, get contexts for each image found
                         extracted_image_data.extend((extract_context(tex_file, cleaned_image_data)))
 
             if extracted_image_data:
                 extracted_image_data = remove_dups(extracted_image_data)
                 create_contextfiles(extracted_image_data)
                 marc_xml = '<?xml version="1.0" encoding="UTF-8"?>\n<collection>\n'
                 marc_xml += create_MARC(extracted_image_data, tarball, None)
                 marc_xml += "\n</collection>"
 
                 if marc_xml:
-                    from invenio.modules.records.api import create_record
                     # We store the path to the directory  the tarball contents live
                     # Read and grab MARCXML from plotextractor run
-                    new_dict_representation = create_record(marc_xml).dumps()
+                    new_dict_representation = create_record(marc_xml, master_format="marc").dumps()
                     try:
                         obj.data['fft'].append(new_dict_representation["fft"])
                     except KeyError:
                         obj.data['fft'] = [new_dict_representation['fft']]
                     obj.add_task_result("filesfft", new_dict_representation["fft"])
                     obj.add_task_result("number_picture_converted", len(converted_image_list))
                     obj.add_task_result("number_of_picture_total", len(image_list))
 
     return _plot_extract
 
 
 def refextract(obj, eng):
     """
     Performs the reference extraction step.
     """
 
     task_sleep_now_if_required()
     if "_result" not in obj.extra_data:
         obj.extra_data["_result"] = {}
     if "pdf" not in obj.extra_data["_result"]:
         extract_path = make_single_directory(CFG_TMPSHAREDDIR, eng.uuid)
         tarball, pdf = harvest_single(obj.data["system_number_external"]["value"], extract_path, ["pdf"])
 
         if pdf is not None:
             obj.extra_data["_result"]["pdf"] = pdf
 
     elif not os.path.isfile(obj.extra_data["_result"]["pdf"]):
         extract_path = make_single_directory(CFG_TMPSHAREDDIR, eng.uuid)
         tarball, pdf = harvest_single(obj.data["system_number_external"]["value"], extract_path, ["pdf"])
         if pdf is not None:
             obj.extra_data["_result"]["pdf"] = pdf
 
     if os.path.isfile(obj.extra_data["_result"]["pdf"]):
         cmd_stdout = extract_references_from_file_xml(obj.extra_data["_result"]["pdf"])
         references_xml = REGEXP_REFS.search(cmd_stdout)
         if references_xml:
             updated_xml = '<?xml version="1.0" encoding="UTF-8"?>\n<collection>\n<record>' + references_xml.group(1) + \
                           "</record>\n</collection>"
 
-            from invenio.modules.records.api import create_record
-
-            new_dict_representation = create_record(updated_xml).dumps()
+            new_dict_representation = create_record(updated_xml, master_format="marc").dumps()
             try:
                 obj.data['reference'].append(new_dict_representation["reference"])
             except KeyError:
                 if 'reference' in new_dict_representation:
                     obj.data['reference'] = [new_dict_representation['reference']]
             obj.add_task_result("reference", new_dict_representation['reference'])
 
     else:
         obj.log.error("Not able to download and process the PDF ")
 
 
 def author_list(obj, eng):
     """
     Performs the special authorlist extraction step (Mostly INSPIRE/CERN related).
     """
     identifiers = obj.data["system_number_external"]["value"]
     task_sleep_now_if_required()
     if "_result" not in obj.extra_data:
         obj.extra_data["_result"] = {}
     if "tarball" not in obj.extra_data["_result"]:
         extract_path = make_single_directory(CFG_TMPSHAREDDIR, eng.uuid)
         tarball, pdf = harvest_single(obj.data["system_number_external"]["value"], extract_path, ["tarball"])
         tarball = str(tarball)
         if tarball is None:
             raise WorkflowError(str("Error harvesting tarball from id: %s %s" % (identifiers, extract_path)),
                                 eng.uuid, id_object=obj.id)
         obj.extra_data["_result"]["tarball"] = tarball
 
     sub_dir, dummy = get_defaults(obj.extra_data["_result"]["tarball"], CFG_TMPDIR, "")
 
     try:
         untar(obj.extra_data["_result"]["tarball"], sub_dir)
     except Timeout:
         eng.log.error('Timeout during tarball extraction on %s' % (obj.extra_data["_result"]["tarball"]))
 
     xml_files_list = find_matching_files(sub_dir, ["xml"])
 
     authors = ""
 
     for xml_file in xml_files_list:
         xml_file_fd = open(xml_file, "r")
         xml_content = xml_file_fd.read()
         xml_file_fd.close()
 
         match = REGEXP_AUTHLIST.findall(xml_content)
         if not match == []:
             authors += match[0]
             # Generate file to store conversion results
     if authors is not '':
         from invenio.legacy.bibconvert.xslt_engine import convert
 
         authors = convert(authors, "authorlist2marcxml.xsl")
         authorlist_record = create_records(authors)
         if len(authorlist_record) == 1:
             if authorlist_record[0][0] is None:
                 eng.log.error("Error parsing authorlist record for id: %s" % (identifiers,))
             authorlist_record = authorlist_record[0][0]
             # Convert any LaTeX symbols in authornames
         translate_fieldvalues_from_latex(authorlist_record, '100', code='a')
         translate_fieldvalues_from_latex(authorlist_record, '700', code='a')
         # Look for any UNDEFINED fields in authorlist
         #key = "UNDEFINED"
         #matching_fields = record_find_matching_fields(key, authorlist_record, tag='100') +\
         #                  record_find_matching_fields(key, authorlist_record, tag='700')
 
         #if len(matching_fields) > 0:
 
         # UNDEFINED found. Create ticket in author queue
         #             ticketid = create_authorlist_ticket(matching_fields, \
         #                                                 identifiers, arguments.get('a_rt-queue'))
         #             if ticketid:
         #                 eng.log.info("authorlist RT ticket %d submitted for %s" % (ticketid, identifiers))
         #             else:
         #                 eng.log.error("Error while submitting RT ticket for %s" % (identifiers,))
         updated_xml = '<?xml version="1.0" encoding="UTF-8"?>\n<collection>\n' + record_xml_output(authorlist_record) \
                       + '</collection>'
         if not None == updated_xml:
-            from invenio.base.records.api import create_record
             # We store the path to the directory  the tarball contents live
             # Read and grab MARCXML from plotextractor run
-            new_dict_representation = create_record(updated_xml).dumps()
+            new_dict_representation = create_record(updated_xml, master_format="marc").dumps()
             obj.data['authors'] = new_dict_representation["authors"]
             obj.data['number_of_authors'] = new_dict_representation["number_of_authors"]
             obj.add_task_result("authors", new_dict_representation["authors"])
             obj.add_task_result("number_of_authors", new_dict_representation["number_of_authors"])
 
 
 author_list.__id__ = "u"
 
 
 def upload_step(obj, eng):
     """
     Perform the upload step.
     """
     uploaded_task_ids = []
     #Work comment:
     #
     #Prepare in case of filtering the files to up,
     #no filtering, no other things to do
     new_dict_representation = Record(obj.data)
     marcxml_value = new_dict_representation.legacy_export_as_marc()
     task_id = None
     # Get a random sequence ID that will allow for the tasks to be
     # run in order, regardless if parallel task execution is activated
     sequence_id = random.randrange(1, 60000)
     task_sleep_now_if_required()
     extract_path = make_single_directory(CFG_TMPSHAREDDIR, eng.uuid)
     # Now we launch BibUpload tasks for the final MARCXML files
     filepath = extract_path + os.sep + str(obj.id)
     file_fd = open(filepath, 'w')
     file_fd.write(marcxml_value)
     file_fd.close()
     mode = ["-r", "-i"]
 
     arguments = obj.extra_data["_repository"]["arguments"]
 
     if os.path.exists(filepath):
         try:
             args = mode
             if sequence_id:
                 args.extend(['-I', str(sequence_id)])
             if arguments.get('u_name', ""):
                 args.extend(['-N', arguments.get('u_name', "")])
             if arguments.get('u_priority', 5):
                 args.extend(['-P', str(arguments.get('u_priority', 5))])
             args.append(filepath)
             task_id = task_low_level_submission("bibupload", "oaiharvest", *tuple(args))
             create_oaiharvest_log_str(task_id, obj.extra_data["_repository"]["id"], marcxml_value)
         except Exception as msg:
             eng.log.error("An exception during submitting oaiharvest task occured : %s " % (str(msg)))
             return None
     else:
         eng.log.error("marcxmlfile %s does not exist" % (filepath,))
     if task_id is None:
         eng.log.error("an error occurred while uploading %s from %s" %
                       (filepath, obj.extra_data["_repository"]["name"]))
     else:
         uploaded_task_ids.append(task_id)
         eng.log.info("material harvested from source %s was successfully uploaded" %
                      (obj.extra_data["_repository"]["name"],))
 
     if CFG_INSPIRE_SITE:
         # Launch BibIndex,Webcoll update task to show uploaded content quickly
         bibindex_params = ['-w', 'collection,reportnumber,global',
                            '-P', '6',
                            '-I', str(sequence_id),
                            '--post-process',
                            'bst_run_bibtask[taskname="webcoll", user="oaiharvest", P="6", c="HEP"]']
         task_low_level_submission("bibindex", "oaiharvest", *tuple(bibindex_params))
     eng.log.info("end of upload")
 
 
 def bibclassify(taxonomy, rebuild_cache=False, no_cache=False, output_mode='text',
                 output_limit=20, spires=False, match_mode='full', with_author_keywords=False,
                 extract_acronyms=False, only_core_tags=False):
     def _bibclassify(obj, eng):
         import os.path
 
         if not os.path.isfile(taxonomy):
             eng.log.error("No RDF found, no bibclassify can run")
             return None
 
         from invenio.legacy.bibclassify import api
 
         if "_result" not in obj.extra_data:
             obj.extra_data["_result"] = {}
 
         if "pdf" in obj.extra_data["_result"]:
             obj.extra_data["_result"]["bibclassify"] = api.bibclassify_exhaustive_call(obj.extra_data["_result"]["pdf"],
                                                                                        taxonomy, rebuild_cache,
                                                                                        no_cache,
                                                                                        output_mode, output_limit,
                                                                                        spires,
                                                                                        match_mode, with_author_keywords,
                                                                                        extract_acronyms, only_core_tags
                                                                                        )
             obj.add_task_result("bibclassify", obj.extra_data["_result"]["bibclassify"])
         else:
             obj.log.error("No classification done due to missing fulltext."
                           "\n You need to get it before! see fulltext task")
 
     return _bibclassify
diff --git a/invenio/modules/workflows/tasks/simplified_data_tasks.py b/invenio/modules/workflows/tasks/simplified_data_tasks.py
index 7ee3ca15d..3b446a2a2 100644
--- a/invenio/modules/workflows/tasks/simplified_data_tasks.py
+++ b/invenio/modules/workflows/tasks/simplified_data_tasks.py
@@ -1,39 +1,35 @@
 ## This file is part of Invenio.
 ## Copyright (C) 2012 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.
 
 """Basic simplified data test functions - NOT FOR XML """
 
-from ..config import CFG_OBJECT_STATUS
-
 
 def task_a(a):
     def _task_a(obj, eng):
         """Function task_a docstring"""
         eng.log.info("executing task a " + str(a))
         obj.data += a
     return _task_a
 
 
 def task_b(obj, eng):
     """Function task_b docstring"""
     eng.log.info("executing task b")
     if obj.data < 20:
-        obj.change_status(CFG_OBJECT_STATUS.ERROR)
-        eng.log.info("Object status %s" % (obj.db_obj.status,))
         eng.log.info("data < 20")
         obj.add_task_result("task_b", {'a': 12, 'b': 13, 'c': 14})
         eng.halt("Value of filed: data in object is too small.")
diff --git a/invenio/modules/workflows/tasks/test_tasks.py b/invenio/modules/workflows/tasks/test_tasks.py
index 7f88fe3fa..ee56ca090 100644
--- a/invenio/modules/workflows/tasks/test_tasks.py
+++ b/invenio/modules/workflows/tasks/test_tasks.py
@@ -1,104 +1,101 @@
 ## This file is part of Invenio.
 ## Copyright (C) 2012 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.
 
 """Basic test functions - NOT FOR XML """
 
 import time
-from ..config import CFG_OBJECT_STATUS
 
 
 def task_a(a):
     def _task_a(obj, eng):
         """Function task_a docstring"""
         eng.log.info("executing task a " + str(a))
         obj.data['data'] += a
         if a > 5:
             obj.extra_data['redis_search']['publisher'] = "CERN"
         else:
             obj.extra_data['redis_search']['publisher'] = "Desy"
     return _task_a
 
 
 def task_b(obj, eng):
     """Function task_b docstring"""
     eng.log.info("executing task b")
     if obj.data['data'] < 20:
-        obj.change_status(CFG_OBJECT_STATUS.ERROR)
-        eng.log.info("Object status %s" % (obj.status,))
         eng.log.info("data < 20")
         obj.add_task_result("task_b", {'a': 12, 'b': 13, 'c': 14})
         obj.extra_data['redis_search']['category'] = "lower_than_20"
         eng.halt("Value of filed: data in object is too small.")
     else:
         obj.extra_data['redis_search']['category'] = "higher_than_20"
 
 
 def add_metadata():
     def _add_metadata(obj, eng):
         eng.log.info("executing task add_metadata on obj.type %s" %
                      (obj.content_type,))
         if(obj['content_type'] == 'book'):
             obj.add_field("meta1", "elefant")
         else:
             obj.add_field("meta1", "hippo")
     return _add_metadata
 
 
 def simple_task(times):
     def _simple_task(obj, eng):
         a = times
         eng.log.info("Running simple task %i times" % (times,))
         while a > 0:
             obj.data['data'] -= 1
             a -= 1
     return _simple_task
 
 
 def sleep_task(t):
     def _sleep_task(dummy_obj, eng):
         eng.log.info("Going to sleep...")
         time.sleep(t)
         eng.log.info("I've woken up :)")
     return _sleep_task
 
 
 def lower_than_20(obj, eng):
     """Function checks if variable is lower than 20"""
     if obj.data['data'] < 20:
         eng.log.info("data < 20")
         eng.halt("Value of filed: a in object is lower than 20.")
 
 
 def higher_than_20(obj, eng):
     """Function checks if variable is higher than 20"""
     if obj.data['data'] > 20:
         eng.log.info("data > 20")
         eng.halt("Value of filed: a in object is higher than 20.")
 
 
 def add(value):
     def _add(obj, dummy_eng):
         """Function adds value to variable"""
         obj.data['data'] += value
     return _add
 
 
 def subtract(value):
     def _subtract(obj, dummy_eng):
         """Function subtract value from variable"""
         obj.data['data'] -= value
     return _subtract
diff --git a/invenio/modules/workflows/tasks/workflows_tasks.py b/invenio/modules/workflows/tasks/workflows_tasks.py
index 9ccdc5560..d4fb55e3f 100644
--- a/invenio/modules/workflows/tasks/workflows_tasks.py
+++ b/invenio/modules/workflows/tasks/workflows_tasks.py
@@ -1,282 +1,297 @@
+# -*- 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 t
+## 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.
+
 from invenio.modules.workflows.models import (BibWorkflowObject,
-                                              BibWorkflowEngineLog,
-                                              DATA_TYPES
-                                              )
+                                              BibWorkflowEngineLog)
 from invenio.modules.workflows.api import start_delayed
-
 from invenio.modules.workflows.errors import WorkflowError
 
 from time import sleep
 
 
 def get_nb_workflow_created(obj, eng):
     try:
         return eng.extra_data["_nb_workflow"]
     except KeyError:
         return "0"
 
 
 def num_workflow_running_greater(num):
     def _num_workflow_running_greater(obj, eng):
         try:
             if (eng.extra_data["_nb_workflow"] - eng.extra_data["_nb_workflow_finish"]) > num:
                 return True
             else:
                 return False
         except KeyError:
             return False
     return _num_workflow_running_greater
 
 
 def get_nb_workflow_running(obj, eng):
 
     try:
         eng.log.error(str())
         return eng.extra_data["_nb_workflow"] - eng.extra_data["_nb_workflow_finish"]
     except KeyError:
         return "0"
 
 
 def start_workflow(workflow_to_run="default", data=None, copy=True, **kwargs):
     """
      This function allow you to run a new asynchronous workflow, this
      will be run on the celery node configurer into invenio
      configuration.
 
      The first argument is the name of the workflow.
 
      The second one is the data to use for this workflow
 
      The copy parameter allow you to pass to the workflow  a copy
      of the obj at the moment of the call .
 
      **kargs allow you to add some key:value into the extra data of
      the object.
      """
 
     def _start_workflow(obj, eng):
 
         myobject = BibWorkflowObject()
 
         if copy is True:
             myobject.copy(obj)
         if data is not None:
             myobject.data = data
         extra = myobject.get_extra_data()
         myobject.set_extra_data(extra)
-        myobject.data_type = DATA_TYPES.RECORD
+        myobject.data_type = "record"
         myobject.save()
         workflow_id = start_delayed(workflow_to_run, data=[myobject],
                                     stop_on_error=True, **kwargs)
 
         eng.log.info("Workflow launched")
         try:
             eng.extra_data["_workflow_ids"].append(workflow_id)
         except KeyError:
             eng.extra_data["_workflow_ids"] = [workflow_id]
 
         try:
             eng.extra_data["_nb_workflow"] += 1
         except KeyError:
             eng.extra_data["_nb_workflow"] = 1
 
         if "_nb_workflow_failed" not in eng.extra_data:
             eng.extra_data["_nb_workflow_failed"] = 0
         if "_nb_workflow_finish" not in eng.extra_data:
             eng.extra_data["_nb_workflow_finish"] = 0
         if "_uuid_workflow_crashed" not in eng.extra_data:
             eng.extra_data["_uuid_workflow_crashed"] = []
 
     return _start_workflow
 
 
 def wait_for_workflows_to_complete(obj, eng):
     """
      This function wait all the asynchronous workflow launched.
      It acts like a barrier
      """
     if '_workflow_ids' in eng.extra_data:
         for workflow_id in eng.extra_data['_workflow_ids']:
             try:
                 workflow_id.get()
                 eng.extra_data["_nb_workflow_finish"] += 1
             except WorkflowError as e:
                 eng.log.error(str(e))
                 workflowlog = BibWorkflowEngineLog.query.filter(
                     BibWorkflowEngineLog.id_object == e.id_workflow
                 ).filter(BibWorkflowEngineLog.log_type == 40).all()
                 for log in workflowlog:
                     eng.log.error(log.message)
 
                 eng.extra_data["_nb_workflow_failed"] += 1
                 eng.extra_data["_nb_workflow_finish"] += 1
             except Exception as e:
                 eng.log.error("Error: Workflow failed %s" % str(e))
                 eng.extra_data["_nb_workflow_failed"] += 1
                 eng.extra_data["_nb_workflow_finish"] += 1
     else:
         eng.extra_data["_nb_workflow"] = 0
         eng.extra_data["_nb_workflow_failed"] = 0
         eng.extra_data["_nb_workflow_finish"] = 0
 
 
 def wait_for_a_workflow_to_complete_obj(obj, eng):
     """
      This function wait for the asynchronous workflow specified
      in obj.data ( asyncresult )
      It acts like a barrier
      """
     if not obj.data:
         eng.extra_data["_nb_workflow"] = 0
         eng.extra_data["_nb_workflow_failed"] = 0
         eng.extra_data["_nb_workflow_finish"] = 0
         return None
     try:
         obj.data.get()
         eng.extra_data["_nb_workflow_finish"] += 1
     except WorkflowError as e:
         eng.log.error("Error: Workflow failed %s" % str(e))
         workflowlog = BibWorkflowEngineLog.query.filter(
             BibWorkflowEngineLog.id_object == e.id_workflow
         ).filter(BibWorkflowEngineLog.log_type == 40).all()
 
         for log in workflowlog:
             eng.log.error(log.message)
         eng.extra_data["_nb_workflow_failed"] += 1
         eng.extra_data["_nb_workflow_finish"] += 1
     except Exception as e:
         eng.log.error("Error: Workflow failed %s" % str(e))
         eng.extra_data["_nb_workflow_failed"] += 1
         eng.extra_data["_nb_workflow_finish"] += 1
 
 
 def wait_for_a_workflow_to_complete(obj, eng):
     """
      This function wait for the asynchronous workflow specified
      in obj.data ( asyncresult )
      It acts like a barrier
      """
     if '_workflow_ids' in eng.extra_data:
         to_wait = None
         i = 0
         while not to_wait and len(eng.extra_data["_workflow_ids"]) > 0:
             for i in range(0, len(eng.extra_data["_workflow_ids"])):
                 if eng.extra_data["_workflow_ids"][i].status == "SUCCESS":
                     to_wait = eng.extra_data["_workflow_ids"][i]
                     break
                 if eng.extra_data["_workflow_ids"][i].status == "FAILURE":
                     to_wait = eng.extra_data["_workflow_ids"][i]
                     break
             sleep(1)
         if not to_wait:
             return None
         try:
             to_wait.get()
             eng.extra_data["_nb_workflow_finish"] += 1
         except WorkflowError as e:
             eng.extra_data["_uuid_workflow_crashed"].append(e.id_workflow)
             eng.extra_data["_nb_workflow_failed"] += 1
             eng.extra_data["_nb_workflow_finish"] += 1
         except:
             eng.extra_data["_nb_workflow_failed"] += 1
             eng.extra_data["_nb_workflow_finish"] += 1
 
         del eng.extra_data["_workflow_ids"][i]
 
     else:
         eng.extra_data["_nb_workflow"] = 0
         eng.extra_data["_nb_workflow_failed"] = 0
         eng.extra_data["_nb_workflow_finish"] = 0
 
 
 def write_something_generic(messagea, func):
     """
     This function allows to send a message to bibsched...
     This messages will be store into log.
     """
 
     def _write_something_generic(obj, eng):
         if isinstance(messagea, basestring):
             if isinstance(func, list):
                 for function in func:
                     function(messagea)
             else:
                 func(messagea)
             return None
 
         if not isinstance(messagea, list):
             if callable(messagea):
                 func_messagea = messagea
                 while callable(func_messagea):
                     func_messagea = func_messagea(obj, eng)
                 if isinstance(func, list):
                     for function in func:
                         function(func_messagea)
                 else:
                     func(func_messagea)
             return None
 
         if len(messagea) > 0:
             temp = ""
             for func_messagea in messagea:
                 if callable(func_messagea):
                     while callable(func_messagea):
                         func_messagea = func_messagea(obj, eng)
                     temp += str(func_messagea)
                 elif isinstance(func_messagea, basestring):
                     temp += func_messagea
             if isinstance(func, list):
                 for function in func:
                     function(temp)
             else:
                 func(temp)
             return None
 
     return _write_something_generic
 
 
 def get_list_of_workflows_to_wait(obj, eng):
     """
      Return a list of asyncresult corresponding to running
      asynchrnous workflow
      """
     return eng.extra_data["_workflow_ids"]
 
 
 def get_status_async_result_obj_data(obj, eng):
     return obj.data.state
 
 
 def get_workflows_progress(obj, eng):
     try:
         return (eng.extra_data["_nb_workflow_finish"] * 100.0) / (eng.extra_data["_nb_workflow"])
     except KeyError:
         return "No progress (key missing)"
     except ZeroDivisionError:
         return "No workflows"
 
 
 def workflows_reviews(stop_if_error=False):
     def _workflows_reviews(obj, eng):
         """
          This function write a  little report about
          asynchronous workflows in this main workflow
          Raise an exception if a workflow is gone rogue
          """
         if eng.extra_data["_nb_workflow"] == 0:
             raise WorkflowError("Nothing has been harvested ! Look into logs for errors !", eng.uuid, obj.id)
         eng.log.info("%s / %s failed" % (eng.extra_data["_nb_workflow_failed"], eng.extra_data["_nb_workflow"]))
 
         if eng.extra_data["_nb_workflow_failed"] and stop_if_error:
             raise WorkflowError(
                 "%s / %s failed" % (eng.extra_data["_nb_workflow_failed"], eng.extra_data["_nb_workflow"]),
                 eng.uuid, obj.id, payload=eng.extra_data["_uuid_workflow_crashed"])
 
     return _workflows_reviews
 
 
 def log_info(message):
     def _log_info(obj, eng):
         eng.log.info(message)
 
     return _log_info
diff --git a/invenio/modules/workflows/templates/workflows/edit_field_macro.html b/invenio/modules/workflows/templates/workflows/edit_field_macro.html
new file mode 100644
index 000000000..c8e6ff185
--- /dev/null
+++ b/invenio/modules/workflows/templates/workflows/edit_field_macro.html
@@ -0,0 +1,44 @@
+{% macro render_field(field) %}
+  <div class="form-group">
+  {% if field.name != "core" %}
+      {% if field.name != "submit" %}
+        {{field.label}}
+      {% endif %}
+      <div class="col-sm-10">
+        {{ field(**kwargs)|safe }}
+      </div>
+  {% else %}
+      <div class="col-sm-10">
+        <div class="checkbox">
+          <label>
+             <b>Core</b> {{field(**kwargs)|safe}}
+          </label>
+        </div>
+      </div>
+  {% endif %}
+  </div>
+  {% if field.errors %}
+    <ul class=errors>
+    {% for error in field.errors %}
+      <li>{{ error }}</li>
+    {% endfor %}
+    </ul>
+  {% endif %}
+  </dd>
+{% endmacro %}
+
+<!-- div class="form-group">
+        <label for="recid" class="col-sm-2 control-label">Rec ID</label>
+        <div class="col-sm-10">
+            <input type="text" class="form-control" id="recid" placeholder="">
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-sm-offset-2 col-sm-10">
+          <div class="checkbox">
+            <label>
+              <b>Core</b> <input type="checkbox"> 
+            </label>
+          </div>
+        </div>
+    </div> -->
\ No newline at end of file
diff --git a/invenio/modules/workflows/templates/workflows/entry_details.html b/invenio/modules/workflows/templates/workflows/entry_details.html
index 02913912b..277b9ac7e 100644
--- a/invenio/modules/workflows/templates/workflows/entry_details.html
+++ b/invenio/modules/workflows/templates/workflows/entry_details.html
@@ -1,81 +1,81 @@
 {% extends "workflows/layout_workflow_details.html" %}
 {% import 'workflows/utils.html' as utils %}
 
 {% js url_for('workflows.static', filename='js/workflows/entry_details.js'), '50-workflows' %}
 
 {% block javascript %}
     {{ super() }}
     <script type="text/javascript">
         $(document).ready(function(){
             bind_object_preview("{{ url_for('workflows.entry_data_preview') }}", "{{ entry.id }}");
         });
     </script>
 {% endblock javascript %}
 
 {% block body %}
 
 <div class="modal-header">
         <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
         <h3 id="myModalLabel">{{ entry.id }}</h3>
 </div>
 <div class="modal-body">
     <div class="row">
         <div class="col-md-12">
                         Owner: <b>{{ entry.id_user }}</b> | Creation date: <b>{{ entry.created }}</b>
         </div>
     </div>
     <div class="row">
          <div class="col-md-5">
             Preview:
             <div class="well">
                 <div class="btn-group" name="object_preview_btn" data-toggle="buttons">
                     <button class="btn btn-xs btn-primary active" name="hd">HTML</button>
                     <button class="btn btn-xs btn-primary" name="marcxml">MARCXML</button>
                     <button class="btn btn-xs btn-primary" name="xm">MARC</button>
                 </div>
                 <div class="btn-group pull-right">
                     <button class="btn btn-xs">Show PDF</button>
                     <button class="btn btn-xs">Show log</button>
                 </div>
                 <div name="object_preview">{{- data_preview|safe -}}</div>
              </div>
          </div>
          <div class="col-md-3">
             Workflow definition:
             <div class="well">
-                {{ utils.function_display(workflow_func, entry.get_extra_data()['task_counter']) }}
+                {{ utils.function_display(workflow_func, entry.get_extra_data()['_task_counter']) }}
             </div>
          </div>
          <div class="col-md-4">
             Messages:
             <div class="well">
                 <h4>Matching is finished. Confirm match!</h4>
                 <p>There are 3 possible matches.</p>
                 <a href="#" class="btn">Resolve match <i class="glyphicon glyphicon-zoom-in"></i></a>
             </div>
          </div>
     </div>
     <div class="row">
         <div class="col-md-12">
             Keywords:
             <form>
                 <textarea id="entry_keywords" placeholder="Your keywords here...">ELECTRON POSITRON: COLLIDING BEAMS | COLLIDING BEAMS: ELECTRON POSITRON | ELECTRON POSITRON: ANNIHILATION | ANNIHILATION: ELECTRON POSITRON | JET: HADROPRODUCTION | HADROPRODUCTION: JET | HADRON: MULTIPLE PRODUCTION | MULTIPLE PRODUCTION: HADRON | QUARK: JET | charm | bottom | LEPTON: DIRECT PRODUCTION | DIRECT PRODUCTION: LEPTON | QUARK: SEMILEPTONIC DECAY | SEMILEPTONIC DECAY: QUARK | QUARK: NONLEPTONIC DECAY | NONLEPTONIC DECAY: QUARK | CHARGED PARTICLE: MULTIPLICITY | MARK II | EXPERIMENTAL RESULTS | SLAC PEP STOR | 29 GEV-CMS</textarea>
             </form>
         </div>
     </div>
     <div class="row">
         <div class="col-md-12">
             Log:
             <pre>{{ log }}</pre>
         </div>
     </div>
 </div>
 <div class="modal-footer">
     <a class="btn btn-primary" href="{{ url_for('holdingpen.details', bwobject_id=entry.id)}}" >Open in HoldingPen <i class="glyphicon glyphicon-wrench"></i></a>
     <button class="btn btn-success">Apply <i class="glyphicon glyphicon-ok"></i></button>
     <button class="btn btn-danger">Delete <i class="icon-remove icon-white"></i></button>
     <button class="btn">Edit <i class="glyphicon glyphicon-edit"></i></button>
     <button id="extra" class="btn">Assign ticket <i class="glyphicon glyphicon-flag"></i></button>
     <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
 </div>
 {% endblock %}
diff --git a/invenio/modules/workflows/templates/workflows/hp_approval_widget.html b/invenio/modules/workflows/templates/workflows/hp_approval_widget.html
index 20cec233b..d5b777f50 100644
--- a/invenio/modules/workflows/templates/workflows/hp_approval_widget.html
+++ b/invenio/modules/workflows/templates/workflows/hp_approval_widget.html
@@ -1,139 +1,90 @@
-{% extends "workflows/hp_layout.html" %}
+{% extends "workflows/hp_detailed_layout.html" %}
 {% import 'workflows/hp_utils.html' as utils %}
 
 {%- block header%}
     {{ super() }}
     {% css url_for('static', filename='css/prism.css') %}
 {%- endblock header %}
 
 {% js url_for('static', filename='js/prism.js'), '40-workflows' %}
 {% js url_for('workflows.static', filename='js/workflows/hp_details.js'), '50-workflows' %}
 {% js url_for('workflows.static', filename='js/workflows/widgets/approval.js'), '50-workflows' %}
 {% js url_for('workflows.static', filename='js/workflows/hp_datapreview.js'), '50-workflows' %}
 
 {%- block javascript %}
     {{ super() }}
 
     <script type="text/javascript">
         $(document).ready(function(){
             var url_preview = "{{ url_for('holdingpen.entry_data_preview') }}";
-            set_url_preview(url_preview);
+            $('button.preview').click(function() {
+                bwoid = $(this).attr('data-id');
+                format = $(this).attr('name');
+                data_preview(url_preview, bwoid, format);
+                $('button.preview').each(function() {
+                    $(this).removeClass('active');
+                });
+                $(this).addClass('active');
+            });
+
+            $('button.preview.active').each(function() {
+                bwoid = $(this).attr('data-id');
+                format = $(this).attr('name');
+                data_preview(url_preview, bwoid, format); 
+            });
         });
     </script>
 {%- endblock javascript %}
 
 {% block hpbody %}
-    <div class="row">
-        <div class="col-md-4 pull-left"><a href="{{url_for('holdingpen.maintable')}}"><span class="glyphicon glyphicon-hand-left"></span> Back to Main Table</a></div>
-        <div class="col-md-4"><h1>Approval Widget</h1></div>
-    </div>
 
+<div class="container" style="padding-left:0">
+    <div id="goodbye-msg" class="col-md-12 text-center">
+    </div>
     
-    <div class="container">
-        <div id="goodbye-msg" class="col-md-12 text-center">
-        </div>
-        {% for i in range(obj_number) %}
-        {% set bwobject = bwobject_list[i] %}
-        {% set bwparent = bwparent_list[i] %}
-        {% set data_preview = data_preview_list[i] %}
-        {% set workflow = w_metadata_list[i] %}
-        {% set workflow_func = workflow_func_list[i] %}
-        {% set info = info_list[i] %}
-        {% set log = logtext_list[i] %}
-            <div id="row_fluid{{i}}" class="row">
-                <div class="col-md-9">
-                    <div class="btn-group" name="object_preview_btn" data-toggle="buttons-radio">
-                        <button class="btn btn-xs btn-primary active" name="hd" onclick="setDataPreview('hd', {{bwobject.id}})">HTML</button>
-                        <button class="btn btn-xs btn-primary" name="marcxml" onclick="setDataPreview('xm', {{bwobject.id}})">MARCXML</button>
-                        <button class="btn btn-xs btn-primary" name="xm" onclick="setDataPreview('tm', {{bwobject.id}})">MARC</button>
-                        <!-- <button class="preview btn btn-xs btn-primary active" name="hd">HTML</button>
-                        <button class="preview btn btn-xs btn-primary" name="xm">MARCXML</button>
-                        <button class="preview btn btn-xs btn-primary" name="tm">MARC</button> -->
-                    </div>
-                    <div class="btn-group pull" name="data_version" data-toggle="buttons-radio">
-                        <button class="btn btn-xs active" name="initial" onclick="setbwoid({{bwparent.id}})">Initial</button>
-                        {% if bwobject.version == 1 %}
-                            <button class="btn btn-xs" name="error" onclick="setbwoid({{bwobject.id}})">Error</button>
-                        {% else %}
-                            <button class="btn btn-xs disabled" name="error">Error</button>
-                        {% endif %}
-                        {% if bwobject.version == 2 %}
-                            <button class="btn btn-xs" name="final" onclick="setbwoid({{bwobject.id}})">Final</button>
-                        {% else %}
-                            <button class="btn btn-mini disabled" name="final">Final</button>
-                        {% endif %}
-                    </div>
-                    <div id="object_preview_container{{bwobject.id}}" class="object_preview_container">
-                        {{ data_preview|safe }}
-                    </div>
-                </div>
-                <div class="col-md-3">
-                    <div class="details_link">
-                        <a href="/admin/holdingpen/details?bwobject_id={{bwobject.id}}"><button class="btn btn-primary" type="button"><i class="icon-eye-open icon-white"></i> Record Details</button></a>
-                    </div>
-                    <div class="well">
-                        <div class="muted"><b>Workflow Definition:</b></div>
-                        <b>{{workflow.name}}</b>
-                        {{ utils.function_display(workflow_func, bwobject.get_extra_data()['last_task_name'], bwobject.version) }}
-                    </div>
-
-                    <div class="well">
-                        <div class="muted"><b>Error Message:</b></div>
-                        {% if bwobject.get_extra_data()['error_msg'] != "" %}
-                            {{ info['last task name'] }} {{ bwobject.get_extra_data()['error_msg'] }}
-                            <div class="text-right">
-                                <h6 id="show-more" class="text-right"><a href="#moreinfoModal" role="button" data-toggle="modal" class="float-right">Show More</a>
-                                </h6>
-                            </div>
-                        {% else %}
-                            There were no errors.
-                        {% endif %}
-
-                        <div id="moreinfoModal" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
-                          <div class="modal-header">
-                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
-                            <h3 id="myModalLabel">Error Log</h3>
-                          </div>
-                          <div class="modal-body">
-                            {% for logobj in logtext_list %}
-                            {{logobj}}
-                            {% endfor %}
-                          </div>
-                          <div class="modal-footer">
-                            <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
-                          </div>
-                        </div>
-                    </div>
-
-                    <div class="well">
-                        <div class="muted"><b>Record Metadata:</b></div></br>
-                        <table class="table table-striped">
-                            <tbody>
-                                {% for key, value in info.items() %}
-                                    <b>{{ key }}</b> = {{ value }}
-                                    <hr>
-                                {% endfor %}
+{% for i in range(obj_number) %}
+{% set bwobject = bwobject_list[i] %}
+{% set bwparent = bwparent_list[i] %}
+{% set data_preview = data_preview_list[i] %}
+{% set workflow = w_metadata_list[i] %}
+{% set workflow_func = workflow_func_list[i] %}
+{% set info = info_list[i] %}
+{% set log = logtext_list[i] %}
 
-                                {% if bwobject.version == 1 %}
-                                    <span class="badge badge-success">Final</span>
-                                {% elif bwobject.version == 2 %}
-                                    <span class="badge badge-warning">Halted</span>
-                                {% else %}
-                                    <span class="badge badge-info">Initial</span>
-                                {% endif %}
-                            </tbody>
-                        </table>
-                    </div>
-                </div>
-            </div>
+    {% block navbar_right scoped %}
+        <ul class="nav navbar-nav pull-right">
+            <li>
+                <a href="{{ url_for('holdingpen.details', objectid=bwobject.id) }}" ><i class="icon-wrenchwhite icon-wrench"></i>More details</a>
+            </li>
+        </ul>
+    {% endblock navbar_right %}
+    {% block hp_navbar scoped%}
+        {{ super() }}
+    {% endblock hp_navbar %}
+    
+    <div id="row_fluid{{i}}" class="row">
+        <div class="col-md-3">
             <div id="decision-btns{{i}}" class="row decision-btns">
-                <form id="form{{i}}" class="theform" method="POST" name="{{ url_for('holdingpen.resolve_widget', bwobject_id=bwobject.id, widget='approval_widget') }}">
+                <form id="form{{i}}" class="theform" method="POST" name="{{ url_for('holdingpen.resolve_widget', object_id=bwobject.id, widget='approval_widget') }}">
                     {% for field in widget %}
                         {{ field }}
                     {% endfor %}
                 </form>
             </div>
-        <hr id="hr{{i}}">
-        {% endfor %}
+            </br>
+
+            {% block hpbody_details scoped %}
+            {{ super() }}
+            {% endblock hpbody_details %}
+            
+        </div>
+
+        {% block hp_preview scoped %}
+        {{ super() }}
+        {% endblock hp_preview %}
     </div>
+
+    <hr id="hr{{i}}">
+    {% endfor %}
+</div>
 {% endblock %}
diff --git a/invenio/modules/workflows/templates/workflows/hp_detailed_layout.html b/invenio/modules/workflows/templates/workflows/hp_detailed_layout.html
new file mode 100644
index 000000000..667eef161
--- /dev/null
+++ b/invenio/modules/workflows/templates/workflows/hp_detailed_layout.html
@@ -0,0 +1,137 @@
+{%- css url_for('workflows.static', filename='css/workflows/style.css'), '20-workflows' -%}
+{% extends "workflows/hp_layout.html" %}
+
+{% block hpbody_details %}
+        <div class="well">
+            <div class="muted">Workflow: <b>{{workflow.name}}</b></div>
+            <span type="button" class="pull-right" style="cursor:pointer" data-toggle="collapse" data-target="#workflow-definition"><span class="caret"></span></span>
+            <div id="workflow-definition" class="collapse">
+                <table class="table table-striped">
+                    <tbody>
+                        <div class="muted"><b>Workflow Tasks:</b></div>
+                        {{ utils.function_display(workflow_func, bwobject.get_extra_data()['last_task_name'], bwobject.version) }}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+
+        <div class="well">
+            <div class="muted"><b>Error Message:</b></div>
+             {% if bwobject.get_extra_data()['error_msg'] != "" %}
+                {{ info['last task name'] }} {{ bwobject.get_extra_data()['error_msg'] }}
+                <div class="text-right">
+                    <h6 id="show-more" class="text-right"><a href="#moreinfoModal" role="button" data-toggle="modal" class="float-right">Show More</a>
+                    </h6>
+                </div>
+            {% else %}
+                There were no errors.
+            {% endif %}
+
+            <div id="moreinfoModal" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+              <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+                <h3 id="myModalLabel">Error Log</h3>
+              </div>
+              <div class="modal-body">
+                {% for key, value in log.iteritems() %}
+                {{key}}: {{value}}
+                {% endfor %}
+              </div>
+              <div class="modal-footer">
+                <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
+              </div>
+            </div>
+        </div>
+
+        <div class="well">
+            <div class="muted"><b>Record Metadata</b>
+                <span type="button" class="pull-right" style="cursor:pointer" data-toggle="collapse" data-target="#record-metadata-table"><span class="caret"></span></span>
+            </div>
+            </br>
+            <div id="record-metadata-table" class="collapse">
+                <table class="table table-striped">
+                    <tbody>
+                        <!-- {% block record_metadata_table %} -->
+                        {% for key, value in info.iteritems() %}
+                            <b>{{ key }}</b> = {{ value }}
+                            <hr>
+                        {% endfor %}
+
+                        {% if bwobject.version == 1 %}
+                            <span class="label label-success">Final</span>
+                        {% elif bwobject.version == 2 %}
+                            <span class="label label-warning">Halted</span>
+                        {% else %}
+                            <span class="label label-info">Initial</span>
+                        {% endif %}
+                        <!-- {% endblock record_metadata_table %} -->
+                    </tbody>
+                </table>
+            </div>
+        </div>
+{% endblock %}
+
+{% block hp_navbar %}
+    <nav class="navbar navbar-default navbar-static-top" role="navigation">  
+      <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
+        <ul class="nav navbar-nav">
+            <li><a href="{{url_for('holdingpen.maintable')}}" class="navbar-btn-sm"><span class="glyphicon glyphicon-hand-left"></span> Back</a>
+            </li>
+            <li class="active">
+                <a href="#">Details</a>
+            </li>
+            <li class="dropdown">
+                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Actions<b class="caret"></b></a>
+                <ul class="dropdown-menu" role="menu">
+                    <li><button id="restart_button" class="btn btn-sm btn-primary btn-block" rel="popover" name="{{ bwobject.id }}"/><i class="icon-repeat"></i>Restart</button></li>
+                    <li><button id="restart_button_prev" class="btn btn-sm btn-block" rel="popover" name="{{ bwobject.id }}"/><i class="icon-step-backward"></i>Restart Task</button></li>
+                    <li><button id="continue_button" class="btn btn-sm btn-block" rel="popover" name="{{ bwobject.id }}"/><i class="icon-step-forward"></i>Skip Task</button></li>
+                    <li><a id="delete_btn" class="btn btn-sm btn-block btn-danger" data-toggle="modal" data-target="#confirmationModal" role="button"><i class="icon-trash"></i>Delete</a></li>
+                </ul>
+            </li>
+
+            <div id="confirmationModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+              <div class="modal-dialog">  
+                <div class="modal-content">
+                    <div class="modal-header">
+                      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+                      <h3 id="myModalLabel">Please Confirm</h3>
+                    </div>
+                    <div class="modal-body">
+                      <p>Are you sure you want to delete record #{{bwobject.id}}</p>
+                    </div>
+                    <div class="modal-footer">
+                      <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
+                      <a class="btn btn-danger" href="{{ url_for('holdingpen.delete_from_db', bwobject_id=bwobject.id) }}" >Delete Record</a>
+                    </div>
+                </div>
+              </div>
+            </div>
+        </ul>
+        {% block navbar_right %}
+        {% endblock navbar_right %}
+      </div>
+    </nav>
+{% endblock %}
+
+
+{% block hp_preview %}
+    <div class="col-md-9">
+        Show as:
+        <div class="btn-group" name="object_preview_btn" data-toggle="buttons-radio">
+
+            <button class="preview btn btn-xs btn-primary active"
+                    data-id="{{ bwobject.id }}"
+                    name="hd">HTML</button>
+            <button class="preview btn btn-xs btn-primary"
+                    data-id="{{ bwobject.id }}"
+                    name="xm">MARCXML</button>
+            <button class="preview btn btn-xs btn-primary"
+                    data-id="{{ bwobject.id }}"
+                    name="tm">MARC</button>
+        </div>
+        <div id="object_preview_container{{bwobject.id}}" class="object_preview_container">
+            {{ data_preview|safe }}
+        </div>
+    </div>
+{% endblock %}
diff --git a/invenio/modules/workflows/templates/workflows/hp_details.html b/invenio/modules/workflows/templates/workflows/hp_details.html
index 5fc6e3bf2..58398774f 100644
--- a/invenio/modules/workflows/templates/workflows/hp_details.html
+++ b/invenio/modules/workflows/templates/workflows/hp_details.html
@@ -1,198 +1,102 @@
-{% extends "workflows/hp_layout.html" %}
+{% extends "workflows/hp_detailed_layout.html" %}
 {% import 'workflows/hp_utils.html' as utils %}
+{% import 'workflows/edit_field_macro.html' as field_macro %}
 
 {% block header%}
     {{ super() }}
     {% css url_for('static', filename='css/prism.css') %}
 {% endblock header %}
 
 {% js url_for('static', filename='js/prism.js'), '40-workflows' %}
 {% js url_for('workflows.static', filename='js/workflows/hp_details.js'), '50-workflows' %}
 {% js url_for('workflows.static', filename='js/workflows/hp_datapreview.js'), '50-workflows' %}
 
 {% block javascript %}
     {{ super() }}
     
     <script type="text/javascript">
         $(document).ready(function(){
             var bwoid = "{{bwobject.id}}";
             var format = "hd";
-            var url_preview = "{{ url_for('holdingpen.entry_data_preview') }}";
-            var url_restart_record = "{{ url_for('holdingpen.restart_record') }}";
-            var url_restart_record_prev = "{{ url_for('holdingpen.restart_record_prev') }}";
-            var url_continue_record = "{{ url_for('holdingpen.continue_record') }}";
+            url = new Object();
+            url.url_preview = "{{ url_for('holdingpen.entry_data_preview') }}";
+            url.url_restart_record = "{{ url_for('holdingpen.restart_record') }}";
+            url.url_restart_record_prev = "{{ url_for('holdingpen.restart_record_prev') }}";
+            url.url_continue_record = "{{ url_for('holdingpen.continue_record') }}"; 
+            url.url_resolve_edit = "{{ url_for('holdingpen.resolve_edit') }}"
 
             $('button.preview').click(function() {
+                bwoid = $(this).attr('data-id');
                 format = $(this).attr('name');
-                data_preview(url_preview, bwoid, format);
+                data_preview(url.url_preview, bwoid, format);
+                $('button.preview').each(function() {
+                    $(this).removeClass('active');
+                });
+                $(this).addClass('active');
             });
 
-            data_preview(url_preview, bwoid, format);
-            action_buttons(url_restart_record, url_restart_record_prev, url_continue_record);
+            data_preview(url.url_preview, bwoid, format);
+            action_buttons(url, bwoid);
         });
     </script>
 {% endblock javascript %}
 
 {% block hpbody %}
-    <nav class="navbar navbar-default navbar-static-top" role="navigation">  
-      <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
-        <ul class="nav navbar-nav">
-            <li><a href="{{url_for('holdingpen.maintable')}}" class="navbar-btn-sm"><span class="glyphicon glyphicon-hand-left"></span> Back</a>
-            </li>
-            <li class="active">
-                <a href="#">Details</a>
-            </li>
-            <li class="dropdown">
-                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Actions<b class="caret"></b></a>
-                <ul class="dropdown-menu" role="menu">
-                    <li><button id="restart_button" class="btn btn-sm btn-primary btn-block" rel="popover" name="{{ bwobject.id }}"/><i class="icon-repeat"></i>Restart</button></li>
-                    <li><button id="restart_button_prev" class="btn btn-sm btn-block" rel="popover" name="{{ bwobject.id }}"/><i class="icon-step-backward"></i>Restart Task</button></li>
-                    <li><button id="continue_button" class="btn btn-sm btn-block" rel="popover" name="{{ bwobject.id }}"/><i class="icon-step-forward"></i>Skip Task</button></li>
-                    <li><a id="delete_btn" class="btn btn-sm btn-block btn-danger" data-toggle="modal" data-target="#confirmationModal" role="button"><i class="icon-trash"></i>Delete</a></li>
-                </ul>
-            </li>
-
-            <div id="confirmationModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
-              <div class="modal-dialog">  
-                <div class="modal-content">
-                    <div class="modal-header">
-                      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
-                      <h3 id="myModalLabel">Please Confirm</h3>
-                    </div>
-                    <div class="modal-body">
-                      <p>Are you sure you want to delete record #{{bwobject.id}}</p>
-                    </div>
-                    <div class="modal-footer">
-                      <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
-                      <a class="btn btn-danger" href="{{ url_for('holdingpen.delete_from_db', bwobject_id=bwobject.id) }}" >Delete Record</a>
-                    </div>
-                </div>
-              </div>
-            </div>
-
-        </ul>
+    
+    {% block navbar_right %}
         <ul class="nav navbar-nav pull-right">
             <li>
                 {% if bwobject.get_extra_data()['widget'] %}
-                <a href="{{ url_for('holdingpen.show_widget', bwobject_id=bwobject.id, widget=info['widget']) }}" ><i class="icon-wrenchwhite icon-wrench"></i>Widget</a>
+                <a href="{{ url_for('holdingpen.show_widget', objectid=bwobject.id) }}" ><i class="icon-wrenchwhite icon-wrench"></i>Action needed</a>
                 {% else %}
                 
                 {% endif %}
             </li>
-        </ul>    
-      </div>
-    </nav>
+        </ul>
+    {% endblock navbar_right %}
+    
+    {% block hp_navbar %}
+        {{ super() }}
+    {% endblock hp_navbar %}
 
     <div class="container" style="padding-left:0px;">
         <div class="row">
-            <div class="col-md-3">
-                
+            <div class="col-md-3"> 
                 <div class="well">
-                    <div class="muted">Workflow: <b>{{workflow.name}}</b></div>
-                    <span type="button" class="pull-right" style="cursor:pointer" data-toggle="collapse" data-target="#workflow-definition"><span class="caret"></span></span>
-                    <div id="workflow-definition" class="collapse">
-                        <table class="table table-striped">
-                            <tbody>
-                                <div class="muted"><b>Workflow Tasks:</b></div>
-                                {{ utils.function_display(workflow_func, bwobject.get_extra_data()['last_task_name'], bwobject.version) }}
-                            </tbody>
-                        </table>
-                    </div>
-                </div>
-
-                <div class="well">
-                    <div class="muted"><b>Error Message:</b></div>
-                    {% if bwobject.get_extra_data()['error_msg'] != "" %}
-                        {{ info['last task name'] }} {{ bwobject.get_extra_data()['error_msg'] }}
-                        <div class="text-right">
-                            <h6 id="show-more" class="text-right"><a href="#moreinfoModal" role="button" data-toggle="modal" class="pull-right">Show More</a>
-                            </h6>
-                        </div>
-                    {% else %}
-                        There were no errors.
-                    {% endif %}
-                    
-                    <div id="moreinfoModal" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
-                      <div class="modal-header">
-                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
-                        <h3 id="myModalLabel">Error Log</h3>
-                      </div>
-                      <div class="modal-body">
-                        {% for key, value in log.items() %}
-                        {{key}}: {{value}}
+                    <form id="edit_form" class="form-horizontal" role="form" method="POST" name="">
+                        {% for field in edit_record_widget %}
+                            {{ field_macro.render_field(field) }}
                         {% endfor %}
-                      </div>
-                      <div class="modal-footer">
-                        <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
-                      </div>
-                    </div>
+                    </form>
                 </div>
 
-                <div class="well">
-                    <div class="muted"><b>Record Metadata</b>
-                        <span type="button" class="pull-right" style="cursor:pointer" data-toggle="collapse" data-target="#record-metadata-table"><span class="caret"></span></span>
-                    </div>
-                </br>
-                    <div id="record-metadata-table" class="collapse">
-                        <table class="table table-striped">
-                            <tbody>
-                                {% for key, value in info.items() %}
-                                    <b>{{ key }}</b> = {{ value }}
-                                    <hr>
-                                {% endfor %}
+                {% block hpbody_details %}
+                    {{ super() }}
+                {% endblock hpbody_details %}
 
-                                {% if bwobject.version == 1 %}
-                                    <span class="badge badge-success">Final</span>
-                                {% elif bwobject.version == 2 %}
-                                    <span class="badge badge-warning">Halted</span>
-                                {% else %}
-                                    <span class="badge badge-info">Initial</span>
-                                {% endif %}
-                            </tbody>
-                        </table>
-                    </div>
-                </div>
             </div>
-            <div class="col-md-9">
-                Show as:
-                <div class="btn-group" name="object_preview_btn" data-toggle="buttons-radio">
-                    <button class="preview btn btn-xs btn-primary active" name="hd">HTML</button>
-                    <button class="preview btn btn-xs btn-primary" name="xm">MARCXML</button>
-                    <button class="preview btn btn-xs btn-primary" name="tm">MARC</button>
-                </div>
-                <!-- <div class="btn-group pull" name="data_version" data-toggle="buttons-radio">
-                    <button class="btn btn-xs active" name="initial" onclick="">Initial</button>
-                    {% if bwobject.version == 1 %}
-                        <button class="btn btn-xs" name="final" onclick="">Final</button>
-                    {% else %}
-                        <button class="btn btn-xs disabled" name="final">Final</button>                        
-                    {% endif %}
-                    {% if bwobject.version == 2 %}
-                        <button class="btn btn-xs" name="error" onclick="">Error</button>
-                    {% else %}
-                        <button class="btn btn-xs disabled" name="error">Error</button>
-                    {% endif %}
-                </div> -->
 
+            <div class="col-md-9">
+               
                 {% if 'message' in bwobject.get_extra_data() and 
                     bwobject.get_extra_data()['widget'] != None %}
                     <div id="usermessage" class="alert alert-warning alert-dismissable">
                         {{bwobject.get_extra_data()['message']}}
                         <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                     </div>
                 {% endif %}
 
+                {% block hp_preview %}
+                    {{ super() }}
+                {% endblock %}
+
                 {% if bwobject.version == 1 %}
                     <div id="successmessage" class="alert alert-success">
                         Record ran workflow successfully.
                         <a class="close" data-dismiss="alert">×</a>
                     </div>
                 {% endif %}
-
-                <div id="object_preview_container{{bwobject.id}}">
-                    {{ data_preview|safe }}
-                </div>
             </div>
         </div>
     </div>
 {% endblock %}
diff --git a/invenio/modules/workflows/templates/workflows/hp_edit_record_widget.html b/invenio/modules/workflows/templates/workflows/hp_edit_record_widget.html
new file mode 100644
index 000000000..57c4d2e48
--- /dev/null
+++ b/invenio/modules/workflows/templates/workflows/hp_edit_record_widget.html
@@ -0,0 +1,36 @@
+{%- css url_for('workflows.static', filename='css/workflows/style.css'), '20-workflows' -%}
+
+{% block hp_edit_record_widget %}
+
+<form id="edit_form" class="form-horizontal" role="form" method="POST" name="">
+    <div class="form-group">
+        <label for="recid" class="col-sm-2 control-label">Rec ID</label>
+        <div class="col-sm-10">
+            <input type="text" class="form-control" id="recid" placeholder="">
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-sm-offset-2 col-sm-10">
+          <div class="checkbox">
+            <label>
+              <b>Core</b> <input type="checkbox"> 
+            </label>
+          </div>
+        </div>
+    </div>
+    <div class="form-group">
+        <label for="recid" class="col-sm-2 control-label">Field Code</label>
+        <div class="col-sm-10">
+            <input type="text" class="form-control" id="recid" placeholder="">
+        </div>
+    </div>
+    <div class="form-group">
+        <label for="recid" class="col-sm-2 control-label">Type Code</label>
+        <div class="col-sm-10">
+            <input type="text" class="form-control" id="recid" placeholder="">
+        </div>
+    </div>
+    <button id="submit-edit-record-widget" type="submit" class="btn btn-default">Submit</button>
+</form>
+
+{% endblock %}
\ No newline at end of file
diff --git a/invenio/modules/workflows/templates/workflows/hp_index.html b/invenio/modules/workflows/templates/workflows/hp_index.html
index b90c1ac9a..6a7fef3a0 100644
--- a/invenio/modules/workflows/templates/workflows/hp_index.html
+++ b/invenio/modules/workflows/templates/workflows/hp_index.html
@@ -1,65 +1,21 @@
 {% extends "workflows/hp_layout.html" %}
 {% block hpbody %}
 
 	<h1>HoldingPen Overview</h1>
 		<div class="container">
 			<div class="col-md-3">
 				<h4>Main Table</h4>
 				<div><a href="{{url_for('holdingpen.maintable')}}"><button class="btn btn-primary" type="button">Show Table</button></a></div>
 			</div>
 			<div class="col-md-3">
 				<h4>Pending Tasks</h4>
-				{% for task in tasks.iterkeys() %}
-					<div class="task-btns"><a href="{{url_for('holdingpen.maintable')}}"><button class="btn btn-warning" type="button">{{task}}: {{tasks[task][0]}}</button></a></br></div>
+				{% for task, object_count in tasks.iteritems() %}
+					<div class="task-btns"><a href="{{url_for('holdingpen.maintable')}}"><button class="btn btn-warning" type="button">{{task}}: {{object_count}}</button></a></br></div>
 				{% endfor %}
 			</div>
 			<div class="col-md-3">
 				<h4>Assigned to me</h4>
 				<div><a href="{{url_for('holdingpen.maintable')}}"><button class="btn btn-primary" type="button">Show Records</button></a></div>
 			</div>
 		</div>
-		
-
-    <style type="text/css" title="currentStyle">
-      @import "{{ url_for('workflows.static', filename='css/workflows/DT_bootstrap.css') }}";
-    </style>
-
-    <h1>Records in Holding Pen</h1>
-
-    <button id="refresh_button" class="btn btn-primary pull-right">Refresh!</button>
-
-    <div class="container">
-        <div class="row">
-            <table id="example" cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered">
-                <thead>
-                    <tr>
-                        <th>Id</th>
-                        <th>Title</th>
-                        <th>Source</th>
-                        <th>Category</th>
-                        <th>Workflow ID</th>
-                        <th>Owner</th>
-                        <th>Created</th>
-                        <th>Version</th>
-                        <th>Details</th>
-                        <th>Actions</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <tr>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                    </tr>
-                </tbody>
-            </table>
-        </div>
-    </div>
 {% endblock %}
diff --git a/invenio/modules/workflows/templates/workflows/hp_maintable.html b/invenio/modules/workflows/templates/workflows/hp_maintable.html
index 15e5229b0..7ce16eb8a 100644
--- a/invenio/modules/workflows/templates/workflows/hp_maintable.html
+++ b/invenio/modules/workflows/templates/workflows/hp_maintable.html
@@ -1,115 +1,118 @@
 {% extends "workflows/hp_layout.html" %}
 {% import 'workflows/hp_utils.html' as utils %}
 
 {% block header%}
     {{ super() }}
     {% css url_for('static', filename='css/ColVis.css') %}
     {% css url_for('static', filename='css/dataTables.bootstrap.css') %}
+    {% css url_for('workflows.static', filename='css/workflows/style.css'), '20-workflows' %}
 {% endblock header %}
 
 {% js url_for('static', filename='js/jquery.dataTables.min.js'), '30-datatables' %}
 {% js url_for('static', filename='js/ColVis.js'), '30-datatables' %}
+{% js url_for('static', filename='js/bootstrap.js'), '30-datatables' %}
 {% js url_for('static', filename='js/dataTables.bootstrap.js'), '30-datatables' %}
+{% js url_for('static', filename='js/bootstrap-tagsinput.min.js'), '30-datatables' %}
 {% js url_for('workflows.static', filename='js/workflows/hp_maintable.js'), '50-workflows' %}
 {% js url_for('workflows.static', filename='js/workflows/widgets/approval.js'), '50-workflows' %}
 
 {% block javascript %}
     {{ super() }}
 
     <script type="text/javascript">
         $(document).ready(function(){
             url = new Object();
+            // console.log(url);
             url.load_table = "{{ url_for('holdingpen.load_table')|safe }}";
             url.batch_widget = "{{ url_for('holdingpen.batch_widget') }}";
             url.resolve_widget = "{{ url_for('holdingpen.resolve_widget') }}";
             url.delete_single = "{{ url_for('holdingpen.delete_from_db') }}";
             url.refresh = "{{ url_for('holdingpen.refresh') }}";
             url.widget = "{{ url_for('holdingpen.show_widget') }}";
             url.details = "{{ url_for('holdingpen.details')|safe }}";
             url.batch_widget = "{{ url_for('holdingpen.batch_widget') }}";
+            url.preview = "{{ url_for('holdingpen.entry_data_preview') }}";
+            version_showing = "{{version_showing}}";
 
             init_urls(url);
             init_urls_approval(url);
+            oTable = init_datatable(version_showing);
         });
     </script>
 {% endblock javascript %}
 
 {% block hpbody %}
     <div id="alert-message"></div>
 
     <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 class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
+      <div id="bs-example-navbar-collapse-1" class="collapse navbar-collapse">
         <ul class="nav navbar-nav">
-            <li class="active">
-                <a href="#">Home</a>
-            </li>
            <!--  <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" data-toggle="dropdown" href="#">Actions<b class="caret"></b></a>
-                <ul class="dropdown-menu">
-                {% set i = 0 %}
-                {% for task in widget_list.iterkeys() %}
-                    <li><a id="task{{i}}" class="task-btn" tabindex="-1" name="{{task}}">{{task}}: {{widget_list[task][0]}}</a></li>
-                    {% set i = i+1 %}
-                {% endfor %}
-                </ul>
+                <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 widget_list.iteritems() %}
+                            <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" data-toggle="dropdown">Status<b class="caret"></b></a>
+                <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">Halted</a></li>
-                    <li><a id="version-final" class="version-selection" name="Final">Final</a></li>
+                    <li><a id="version-final" class="version-selection" name="Final">Completed</a></li>
                     <li><a id="version-running" class="version-selection" name="Running">Running</a></li>
                 </ul>
             </li>
         </ul>
-        <ul class="nav navbar-nav pull-right">
-          <li><button id="refresh_button" type="button" class="btn btn-default navbar-btn">Refresh!</button></li>    
-        </ul>
       </div>
     </nav>
 
-    <div id="tag-area" class="row">
-    </div>
+    <input id="tagsinput" type="text" data-role="tagsinput" placeholder="Add new tag"/>
+    </br>
 
     <div class="container">
         <div class="row">
-            <table id="example" cellpadding="0" cellspacing="0" border="0" class="table table-bordered">
+            <table id="maintable" cellpadding="0" cellspacing="0" border="0" class="table table-bordered">
                 <thead>
                     <tr>
-                        <th><input id="select-all" type="checkbox"></th>
                         <th>Id</th>
+                        <th><input id="select-all" type="checkbox"></th>
                         <th>Title</th>
                         <th>Source</th>
                         <th>Category</th>
-                        <th>Workflow ID</th>
-                        <th>Owner</th>
                         <th>Created</th>
-                        <th>Version</th>
+                        <th>Status</th>
+                        <th>Type</th>
                         <th>Details</th>
                         <th>Actions</th>
                     </tr>
                 </thead>
                 <tbody>
                     <tr>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
                         <td></td>
-                        <td></td>
                     </tr>
                 </tbody>
             </table>
         </div>
     </div>
 {% endblock %}
\ No newline at end of file
diff --git a/invenio/modules/workflows/templates/workflows/hp_utils.html b/invenio/modules/workflows/templates/workflows/hp_utils.html
index 6807bb7cc..cc72efc4d 100644
--- a/invenio/modules/workflows/templates/workflows/hp_utils.html
+++ b/invenio/modules/workflows/templates/workflows/hp_utils.html
@@ -1,51 +1,68 @@
 {% macro function_display(fun, task_counter, version) -%}
     <!-- {% set comma2 = joiner(",") %} -->
     {% set i = 0 %}
     {% set flag = 0 %}
     {% for w in fun %}
         {% if w is not iterable %}
-            <!-- {{ comma2() }} -->
-            </br>
-            {% if w.__title__ == task_counter and version == 2 %}
-                <b>
-            {% endif %}
-
-            <a href="#infoModal{{i}}" data-toggle="modal">{{ w.__title__ }}</a>
-
-            {% if w.__title__ == task_counter %}
+            {{ function_display_inner(w, task_counter, version, flag) }}
+            {% if w.func_name == task_counter and version == 2 %}
                 {% set flag = 1 %}
-                {% if version == 2 or version == 3  %}
-                    </b><i class="icon-remove"></i>
-                {% else %}
-                    <i class="icon-ok"></i>
-                {% endif %}    
-            {% else %}
-                {% if flag == 0 %}
-                    <i class="icon-ok"></i>
-                {% endif %}
-                
             {% endif %}
-            
-            <div id="infoModal{{i}}" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
-              <div class="modal-header">
-                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
-                <h3 id="myModalLabel">{{ w.__title__ }}</h3>
-              </div>
-              <div class="modal-body">
-                  {% if w.func_closure is defined %}
-                      {% if w.func_closure is iterable %}
-                          {% set comma = joiner(", ") %}
-                          {% for arg in w.func_closure %}
-                              {{ comma() }}
-                              <b>Parameter: {{ arg.cell_contents }}</b>
-                          {% endfor %}
-                          </br>
-                      {% endif %}
-                  {% endif %}
-                {{ w.func_doc }}
-              </div>
-            </div>
-            {% set i = i + 1 %}
+        {% else %}
+            {{ function_display(w, task_counter, version) }}
         {% endif %}
+            <!-- {{ comma2() }} -->
+        {% set i = i + 1 %}
     {% endfor %}
 {%- endmacro %}
+
+{% macro function_display_inner(w, task_counter, version, flag) -%}
+  </br>
+
+  {% if flag == 0 %}
+
+  <button type="button" class="btn btn-default btn-sm" href="#" data-toggle="modal" data-target="#infoModal{{i}}">
+    <span class="glyphicon glyphicon-ok-sign"></span>
+    {% if w.func_name == task_counter and version == 2 %}
+        <strong>{{ w.func_name }}</strong>
+    {% else %}
+        {{ w.func_name }}
+    {% endif %}
+  </button>
+
+  {% else %}
+
+  <button type="button" class="btn btn-default btn-sm" href="#" data-toggle="modal" data-target="#infoModal{{i}}">
+    {{ w.func_name }}
+  </button>
+
+  {% endif %}
+  
+  <div class="modal fade" id="infoModal{{i}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+   <div class="modal-dialog">
+      <div class="modal-content">
+        <div class="modal-header">
+          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+          <h4 class="modal-title" id="myModalLabel">{{ w.func_name }}</h4>
+        </div>
+        <div class="modal-body">
+          {% if w.func_closure is defined %}
+            {% if w.func_closure is iterable %}
+                {% set comma = joiner(", ") %}
+                {% for arg in w.func_closure %}
+                    {{ comma() }}
+                    <b>Parameter: {{ arg.cell_contents }}</b>
+                {% endfor %}
+                </br>
+            {% endif %}
+          {% endif %}
+          {{ w.func_doc }}
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        </div>
+      </div><!-- /.modal-content -->
+    </div><!-- /.modal-dialog -->
+  </div><!-- /.modal -->
+
+{%- endmacro %}
diff --git a/invenio/modules/workflows/templates/workflows/row_formatter.html b/invenio/modules/workflows/templates/workflows/row_formatter.html
index ae64d7c15..5f88f8509 100644
--- a/invenio/modules/workflows/templates/workflows/row_formatter.html
+++ b/invenio/modules/workflows/templates/workflows/row_formatter.html
@@ -1,46 +1,48 @@
-#checkbox$
-<input type="checkbox">
-#id$
-{{record.id}}
-#title$
-{% if record.get_extra_data()['redis_search'].has_key('title') %}{{ record.get_extra_data()['redis_search']['title'] }}
-{% else %}None
-{% endif %}
-#source$
-{% if record.get_extra_data()['redis_search'].has_key('source') %}{{ record.get_extra_data()['redis_search']['source'] }}
-{% else %}None
-{% endif %}
-#category$
-{% if record.get_extra_data()['redis_search'].has_key('category') %}{{ record.get_extra_data()['redis_search']['category'] }}
-{% else %}None
-{% endif %}
-#workflow_id$
-{{record.id_workflow}}
-#owner$
-{% if record.get_extra_data()['owner'] == None %}None{% endif %}
-#pretty_date$
-{{ pretty_date(record.created)}}
-#version$
-{% if record.version == 1 %}<span class="label label-success">Final</span>
-{% elif record.version == 2 %}<span class="label label-warning">Halted</span>
+<td id="id">
+{{object.id}}
+</td>
+<td id="checkbox">
+<input type="checkbox" class="hp-check">
+</td>
+<td id="title">
+{{ record.get('title', {}) }}
+</td>
+<td id="source">
+{{ extra_data.get('source', "No source") }}
+</td>
+<td id="category">
+{{ ", ".join(categories) or "No category" }}
+</td>
+<td id="pretty_date">
+{{ pretty_date(object.created)}}
+</td>
+<td id="version">
+{% if object.version == 1 %}<span class="label label-success">Completed</span>
+{% elif object.version == 2 %}<span class="label label-warning">Halted</span>
 {% else %}<span class="label label-info">Running</span>
 {% endif %}
-#details$
+</td>
+<td id="type">
+{{object.data_type}}
+</td>
+<td id="details">
 {% if widget == None %}
-	<a href="{{url_for('holdingpen.details', bwobject_id=record.id)}}">Details</a>
+    <a href="{{url_for('holdingpen.details', objectid=object.id)}}">Details</a>
 {% else %}
 {% set widget_instance = widget() %}
-	<a href="{{url_for('holdingpen.show_widget', bwobject_id=record.id, widget=widget_instance.__class__.__name__)}}">Details</a>
+    <a href="{{url_for('holdingpen.show_widget', objectid=object.id)}}">Details</a>
 {% endif %}
-#widget$
+</td>
+<td id="widget">
 {% if widget != None %}
-	{% set widget = widget() %}
-	{% if mini_widget != None %}
-		{% set mini_widget = mini_widget() %}
-		{% for field in mini_widget %}
-	    	{{ field }}
-		{% endfor %}
-	{% endif %}
+    {% set widget = widget() %}
+    {% if mini_widget != None %}
+        {% set mini_widget = mini_widget() %}
+        {% for field in mini_widget %}
+            {{ field(objectid=object.id) }}
+        {% endfor %}
+    {% endif %}
 {% else %}
 N/A
-{% endif %}
\ No newline at end of file
+{% endif %}
+</td>
\ No newline at end of file
diff --git a/invenio/modules/workflows/testsuite/test_halt.py b/invenio/modules/workflows/testsuite/test_halt.py
index bb391e187..51c6a5992 100644
--- a/invenio/modules/workflows/testsuite/test_halt.py
+++ b/invenio/modules/workflows/testsuite/test_halt.py
@@ -1,84 +1,83 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
 ## Copyright (C) 2013 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.
 
 """Unit tests for workflows views."""
 
 from __future__ import absolute_import
 
 from invenio.testsuite import InvenioTestCase, make_test_suite, \
     run_test_suite
 import logging
 
 
 class WorkflowTestBranch(InvenioTestCase):
     def test_halt(self):
         from invenio.modules.workflows.loader import workflows
         from invenio.modules.workflows.api import start
-        from invenio.modules.workflows.config import CFG_OBJECT_VERSION, \
-            CFG_WORKFLOW_STATUS
-        from invenio.modules.workflows.models import BibWorkflowObjectLog
+        from invenio.modules.workflows.engine import WorkflowStatus
+        from invenio.modules.workflows.models import (BibWorkflowObjectLog,
+                                                      ObjectVersion)
 
         halt_engine = lambda obj, eng: eng.halt("Test")
 
         class HaltTest(object):
             workflow = [halt_engine]
 
         workflows['halttest'] = HaltTest
 
         data = [{'somekey', 'somevalue'}, ]
         eng = start('halttest', data)
         idx, obj = list(eng.getObjects())[0]
 
-        assert obj.version == CFG_OBJECT_VERSION.HALTED
-        assert eng.status == CFG_WORKFLOW_STATUS.FINISHED
+        assert obj.version == ObjectVersion.HALTED
+        assert eng.status == WorkflowStatus.FINISHED
         assert BibWorkflowObjectLog.get(
             id_object=obj.id, log_type=logging.ERROR).count() == 0
 
     def test_halt_in_branch(self):
         from workflow.patterns import IF_ELSE
         from invenio.modules.workflows.loader import workflows
         from invenio.modules.workflows.api import start
-        from invenio.modules.workflows.config import CFG_OBJECT_VERSION, \
-            CFG_WORKFLOW_STATUS
-        from invenio.modules.workflows.models import BibWorkflowObjectLog
-
+        from invenio.modules.workflows.engine import WorkflowStatus
+        from invenio.modules.workflows.models import (BibWorkflowObjectLog,
+                                                      ObjectVersion)
         always_true = lambda obj, eng: True
         halt_engine = lambda obj, eng: eng.halt("Test")
 
         class BranchTest(object):
             workflow = [
                 IF_ELSE(always_true, [halt_engine], [halt_engine])
             ]
 
         workflows['branchtest'] = BranchTest
 
         data = [{'somekey', 'somevalue'}, ]
         eng = start('branchtest', data)
         idx, obj = list(eng.getObjects())[0]
 
-        assert obj.version == CFG_OBJECT_VERSION.HALTED
-        assert eng.status == CFG_WORKFLOW_STATUS.FINISHED
+        assert obj.version == ObjectVersion.HALTED
+        assert eng.status == WorkflowStatus.FINISHED
         assert BibWorkflowObjectLog.get(
             id_object=obj.id, log_type=logging.ERROR).count() == 0
 
 
 TEST_SUITE = make_test_suite(WorkflowTestBranch)
 
 if __name__ == "__main__":
     run_test_suite(TEST_SUITE)
diff --git a/invenio/modules/workflows/utils.py b/invenio/modules/workflows/utils.py
index f593bed8d..05405b3f5 100644
--- a/invenio/modules/workflows/utils.py
+++ b/invenio/modules/workflows/utils.py
@@ -1,280 +1,279 @@
 ## -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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.
 
 from __future__ import print_function
 
 import re
 import redis
 import traceback
 
 from six import iteritems
 
 from invenio.ext.logging import register_exception
 
 from .errors import WorkflowDefinitionError
 
 
 REGEXP_RECORD = re.compile("<record.*?>(.*?)</record>", re.DOTALL)
 
 
 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 invenio.modules.workflows.models import BibWorkflowObject
 
         if self.id is not None:
             return BibWorkflowObject.query.filter(BibWorkflowObject.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__}
 
-
     def __str__(self):
         return "BibWorkflowObject(%s)" % (str(self.id),)
 
 
 class WorkflowsTaskResult(object):
     """
     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 get_workflow_definition(name):
     """ Tries to load the given workflow from the system. """
     from .loader import workflows
 
     try:
         return workflows[name]
     except Exception as e:
         raise WorkflowDefinitionError("Error with workflow '%s': %s\n%s" %
                                       (name, str(e), traceback.format_exc()),
                                       workflow_name=name)
 
 
 def determineDataType(data):
     # If data is a dictionary and contains type key,
     # we can directly derive the data_type
     if isinstance(data, dict):
         if 'type' in data:
             data_type = data['type']
         else:
             data_type = 'dict'
     else:
 
         # If data is not a dictionary, we try to guess MIME type
         # by using magic library
         try:
             from magic import Magic
 
             mime_checker = Magic(mime=True)
             data_type = mime_checker.from_buffer(data)  # noqa
         except:
             register_exception(stream="warning", prefix=
             "BibWorkflowObject.determineDataType:" +
             " Impossible to resolve data type.")
             data_type = ""
     return data_type
 
 
 ## TODO special thanks to http://code.activestate.com/recipes/440514-dictproperty-properties-for-dictionary-attributes/
 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):
             try:
                 return self._fget(self._obj, key)
             except TypeError:
                 print("can't read item")
 
         def __setitem__(self, key, value):
             try:
                 self._fset(self._obj, key, value)
             except TypeError:
                 print("can't set item %s: %s" % (str(key), str(value),))
 
         def __delitem__(self, key):
             try:
                 self._fdel(self._obj, key)
             except TypeError:
                 print("can't delete item")
 
     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):
     if iSortCol_0 == 0:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.id, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.id, reverse=False)
     elif iSortCol_0 == 1:
         pass
         # if sSortDir_0 == 'desc':
         #     bwolist.sort(key=lambda x: x.id_user, reverse=True)
         # else:
         #     bwolist.sort(key=lambda x: x.id_user, reverse=False)
     elif iSortCol_0 == 2:
         pass
         # if sSortDir_0 == 'desc':
         #     bwolist.sort(key=lambda x: x.id_user, reverse=True)
         # else:
         #     bwolist.sort(key=lambda x: x.id_user, reverse=False)
     elif iSortCol_0 == 3:
         pass
         # if sSortDir_0 == 'desc':
         #     bwolist.sort(key=lambda x: x.id_user, reverse=True)
         # else:
         #     bwolist.sort(key=lambda x: x.id_user, reverse=False)
     elif iSortCol_0 == 4:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.id_workflow, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.id_workflow, reverse=False)
     elif iSortCol_0 == 5:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.id_user, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.id_user, reverse=False)
     elif iSortCol_0 == 6:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.created, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.created, reverse=False)
     elif iSortCol_0 == 7:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.version, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.version, reverse=False)
     elif iSortCol_0 == 8:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.version, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.version, reverse=False)
     elif iSortCol_0 == 9:
         if sSortDir_0 == 'desc':
             bwolist.sort(key=lambda x: x.version, reverse=True)
         else:
             bwolist.sort(key=lambda x: x.version, reverse=False)
 
     return bwolist
 
 
 def parse_bwids(bwolist):
     import ast
 
     return list(ast.literal_eval(bwolist))
diff --git a/invenio/modules/workflows/views/holdingpen.py b/invenio/modules/workflows/views/holdingpen.py
index 0a75868f1..8e7f7dc4a 100644
--- a/invenio/modules/workflows/views/holdingpen.py
+++ b/invenio/modules/workflows/views/holdingpen.py
@@ -1,502 +1,535 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
-## Copyright (C) 2013 CERN.
+## 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 web interface"""
 
-from __future__ import print_function
+import re
 
-from flask import render_template, Blueprint, redirect, url_for, flash, request, current_app, jsonify
+from flask import (render_template, Blueprint,
+                   request, current_app,
+                   jsonify, 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 ..models import BibWorkflowObject, Workflow
-from ..loader import widgets
 from invenio.base.decorators import templated, wash_arguments
-from invenio.modules.formatter.engine import format_record
 from invenio.base.i18n import _
-from flask.ext.breadcrumbs import default_breadcrumb_root, register_breadcrumb
-from flask.ext.menu import register_menu
 from invenio.utils.date import pretty_date
+
+from ..models import BibWorkflowObject, Workflow, ObjectVersion
+from ..loader import widgets
 from ..utils import (get_workflow_definition,
                      sort_bwolist)
 from ..api import continue_oid_delayed, start
-from ..config import CFG_OBJECT_VERSION
 
 
 blueprint = Blueprint('holdingpen', __name__, url_prefix="/admin/holdingpen",
                       template_folder='../templates',
                       static_folder='../static')
 
 default_breadcrumb_root(blueprint, '.holdingpen')
 
+REG_TD = re.compile("<td id=\"(.+?)\">(.+?)</td>", re.DOTALL)
+
 
 @blueprint.route('/', methods=['GET', 'POST'])
 @blueprint.route('/index', methods=['GET', 'POST'])
 @login_required
 @register_menu(blueprint, 'main.admin.holdingpen', _('Holdingpen'))
 @register_breadcrumb(blueprint, '.', _('Holdingpen'))
 @templated('workflows/hp_index.html')
 def index():
     """
     Displays main interface of Holdingpen.
     Acts as a hub for catalogers (may be removed)
     """
-    from ..containers import bwolist
-
-    # FIXME: need to autodiscover widgets properly
-    widget_list = {}
-    for widget in widgets:
-        widget_list[widget] = [0, []]
+    from ..containers import create_hp_containers
+    bwolist = create_hp_containers()
 
-    for bwo in bwolist:
-        print bwo.get_extra_data()['widget']
-        if ('widget' in bwo.get_extra_data()) and \
-           (bwo.get_extra_data()['widget'] is not None) \
-                and (bwo.version == CFG_OBJECT_VERSION.HALTED):
-            widget_list[bwo.get_extra_data()['widget']][1].append(bwo)
-    for key in widget_list:
-        widget_list[key][0] = len(widget_list[key][1])
+    widget_list = get_widget_list(bwolist)
 
     return dict(tasks=widget_list)
 
 
 @blueprint.route('/maintable', methods=['GET', 'POST'])
 @register_breadcrumb(blueprint, '.records', _('Records'))
 @login_required
 @templated('workflows/hp_maintable.html')
 def maintable():
     """
     Displays main table interface of Holdingpen.
     """
-    from ..containers import bwolist
+    from ..containers import create_hp_containers
+    bwolist = create_hp_containers()
 
-    # FIXME: need to autodiscover widgets properly
-    widget_list = {}
-    for widget in widgets:
-        import IPython
-        # IPython.embed()
-        print widget
-        widget_list[widgets[widget].__title__] = [0, []]
+    widget_list = get_widget_list(bwolist)
 
-    for bwo in bwolist:
-        if ('widget' in bwo.get_extra_data()) and \
-           (bwo.get_extra_data()['widget'] is not None) \
-                and (bwo.version != CFG_OBJECT_VERSION.FINAL):
-            widget = bwo.get_extra_data()['widget']
-            widget_list[widgets[widget].__title__][1].append(bwo)
-    for key in widget_list:
-        widget_list[key][0] = len(widget_list[key][1])
+    try:
+        version_showing = current_app.config['VERSION_SHOWING']
+    except KeyError:
+        version_showing = ObjectVersion.HALTED
 
-    return dict(bwolist=bwolist, widget_list=widget_list)
+    return dict(bwolist=bwolist, widget_list=widget_list,
+                version_showing=version_showing)
 
 
 @blueprint.route('/refresh', methods=['GET', 'POST'])
 @login_required
 def refresh():
     """
     Reloads the bibworkflow_containers file,
     thus rebuilding the BWObject list.
     """
     # FIXME: Temp hack until redis is hooked up
     try:
-        version_showing=current_app.config['VERSION_SHOWING']
+        version_showing = session['VERSION_SHOWING']
         load_table(version_showing)
     except:
         pass
         # import invenio.modules.workflows.containers
         # reload(invenio.modules.workflows.containers)
     return 'Records Refreshed'
 
 
 @blueprint.route('/batch_widget', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'bwolist': (unicode, "")})
 def batch_widget(bwolist):
     """
     Renders widget accepting single or multiple records.
     """
     from ..utils import parse_bwids
     bwolist = parse_bwids(bwolist)
 
     try:
         bwolist = map(int, bwolist)
     except ValueError:
-        print('Error in IDs')
+        # Bad ID, we just pass for now
+        pass
 
     objlist = []
-    workflow_list = []
     workflow_func_list = []
     w_metadata_list = []
     info_list = []
     widgetlist = []
     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_extra_data()['widget'] not in widgetlist:
-            widgetlist.append(bwobject.get_extra_data()['widget'])
+            widgetlist.append(bwobject.get_widget())
 
     widget_form = widgets[widgetlist[0]]
 
     result = widget_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('/load_table', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'version_showing': (unicode, "default")})
 @templated('workflows/hp_maintable.html')
 def load_table(version_showing):
     """
     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.
     """
-    from ..containers import bwolist
-
-    try:
-        version_showing = request.get_json()
-        VERSION_SHOWING = []
-
-        if version_showing['final'] == True:
-            VERSION_SHOWING.append(CFG_OBJECT_VERSION.FINAL)
-        if version_showing['halted'] == True:
-            VERSION_SHOWING.append(CFG_OBJECT_VERSION.HALTED)
-        if version_showing['running'] == True:
-            VERSION_SHOWING.append(CFG_OBJECT_VERSION.RUNNING)
-        print 'NEW STUFF'
+    from ..containers import create_hp_containers
+    VERSION_SHOWING = []
+    req = request.get_json()
+
+    if req:
+        if req.get('final', None):
+            VERSION_SHOWING.append(ObjectVersion.FINAL)
+        if req.get('halted', None):
+            VERSION_SHOWING.append(ObjectVersion.HALTED)
+        if req.get('running', None):
+            VERSION_SHOWING.append(ObjectVersion.RUNNING)
         current_app.config['VERSION_SHOWING'] = VERSION_SHOWING
-        rebuild_containers = True
-    except:
-        print 'OLD STUFFS'
-        version_showing = request.get_json()
+    else:
         try:
             VERSION_SHOWING = current_app.config['VERSION_SHOWING']
-            rebuild_containers = True
         except:
-            VERSION_SHOWING = [CFG_OBJECT_VERSION.HALTED]
-            rebuild_containers = False
+            VERSION_SHOWING = [ObjectVersion.HALTED]
 
     # sSearch will be used for searching later
-    a_search = request.args.get('sSearch')
+    a_search = request.args.get('sSearch', None)
 
     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 = current_app.config['iSortCol_0']
-        s_sortdir_0 = current_app.config['sSortDir_0']
-        i_display_start = current_app.config['iDisplayStart']
-        i_display_length = current_app.config['iDisplayLength']
-        sEcho = current_app.config['sEcho'] + 1
-
-    if a_search or rebuild_containers:
-        # FIXME: Temp measure until Redis is hooked up
-        from ..containers import create_hp_containers
-        print 'rebuilding containers'
-        print 'with version:', VERSION_SHOWING
-        bwolist = create_hp_containers(sSearch=a_search, version_showing=VERSION_SHOWING)
+        i_sortcol_0 = current_app.config.get('iSortCol_0', 0)
+        s_sortdir_0 = current_app.config.get('sSortDir_0', None)
+        i_display_start = current_app.config.get('iDisplayStart', 0)
+        i_display_length = current_app.config.get('iDisplayLength', 10)
+        sEcho = current_app.config.get('sEcho', 0) + 1
+
+    bwolist = create_hp_containers(sSearch=a_search,
+                                   version_showing=VERSION_SHOWING)
 
     if 'iSortCol_0' in current_app.config:
         i_sortcol_0 = int(i_sortcol_0)
         if i_sortcol_0 != current_app.config['iSortCol_0'] \
            or s_sortdir_0 != current_app.config['sSortDir_0']:
             bwolist = sort_bwolist(bwolist, i_sortcol_0, s_sortdir_0)
 
     current_app.config['iDisplayStart'] = i_display_start
     current_app.config['iDisplayLength'] = i_display_length
     current_app.config['iSortCol_0'] = i_sortcol_0
     current_app.config['sSortDir_0'] = s_sortdir_0
     current_app.config['sEcho'] = sEcho
 
     table_data = {
         "aaData": []
     }
 
-    table_data['iTotalRecords'] = len(bwolist)
-    table_data['iTotalDisplayRecords'] = len(bwolist)
-    #This will be simplified once Redis is utilized.
-    
-    rendered_rows = []
+    try:
+        table_data['iTotalRecords'] = len(bwolist)
+        table_data['iTotalDisplayRecords'] = len(bwolist)
+    except:
+        bwolist = create_hp_containers(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]:
         try:
-            widgetname = widgets[bwo.get_extra_data()['widget']].__title__
+            # FIXME: Will be used in near future
+            # widgetname = widgets[bwo.get_extra_data()['widget']].__title__
             widget = widgets[bwo.get_extra_data()['widget']]
         except KeyError:
-            widgetname = None
+            # widgetname = None
             widget = None
 
         # if widget != None and bwo.version in VERSION_SHOWING:
         records_showing += 1
 
         mini_widget = getattr(widget, "mini_widget", None)
-        row = render_template('workflows/row_formatter.html', record=bwo,
-                               widget=widget, mini_widget=mini_widget,
-                               pretty_date=pretty_date)
+        record = bwo.get_data()
+        if not isinstance(record, dict):
+            record = {}
+        extra_data = bwo.get_extra_data()
+        category_list = record.get('subject_term', [])
+        if isinstance(category_list, dict):
+            category_list = [category_list]
+        categories = ["%s (%s)" % (subject['term'], subject['scheme'])
+                      for subject in category_list]
+        row = render_template('workflows/row_formatter.html',
+                              object=bwo,
+                              record=record,
+                              extra_data=extra_data,
+                              categories=categories,
+                              widget=widget,
+                              mini_widget=mini_widget,
+                              pretty_date=pretty_date)
 
-        list1 = [r.split('$') for r in row.split('#')]
         d = {}
-        list1.pop(0)
-        for key, value in list1:
-            d[key] = value
+        for key, value in REG_TD.findall(row):
+            d[key] = value.strip()
 
         table_data['aaData'].append(
-            [d['checkbox'],
-             d['id'],
+            [d['id'],
+             d['checkbox'],
              d['title'],
              d['source'],
              d['category'],
-             d['workflow_id'],
-             d['owner'],
              d['pretty_date'],
              d['version'],
+             d['type'],
              d['details'],
              d['widget']
-            ])
+             ]
+        )
 
     table_data['sEcho'] = sEcho
     table_data['iTotalRecords'] = len(bwolist)
     table_data['iTotalDisplayRecords'] = len(bwolist)
+    return jsonify(table_data)
 
-    print 'LOAD TABLE RETURNING THAT MANY RECORDS:', len(bwolist)
-    return table_data
+
+@blueprint.route('/get_version_showing', methods=['GET', 'POST'])
+@login_required
+def get_version_showing():
+    """
+    Returns current version showing, saved in current_app.config
+    """
+    try:
+        return current_app.config['VERSION_SHOWING']
+    except KeyError:
+        return None
 
 
-@blueprint.route('/details', methods=['GET', 'POST'])
-@register_breadcrumb(blueprint, '.details', "Record Details")
+@blueprint.route('/details/<objectid>', methods=['GET', 'POST'])
+@register_breadcrumb(blueprint, '.details', _("Record Details"))
 @login_required
-@wash_arguments({'bwobject_id': (int, 0)})
-def details(bwobject_id):
+def details(objectid):
     """
     Displays info about the object, and presents the data
     of all available versions of the object. (Initial, Error, Final)
     """
-    bwobject = BibWorkflowObject.query.get(bwobject_id)
+    of = "hd"
+    bwobject = BibWorkflowObject.query.filter(
+        BibWorkflowObject.id == objectid).first_or_404()
 
     extracted_data = extract_data(bwobject)
 
-    # FIXME: need to determine right format
-    recformat = "hd"
+    try:
+        edit_record_widget = widgets['edit_record_widget']()
+    except KeyError:
+        # Could not load edit_record_widget
+        edit_record_widget = []
 
     return render_template('workflows/hp_details.html',
                            bwobject=bwobject,
                            bwparent=extracted_data['bwparent'],
                            info=extracted_data['info'],
                            log=extracted_data['logtext'],
-                           data_preview=bwobject.get_formatted_data(recformat),
+                           data_preview=bwobject.get_formatted_data(of),
                            workflow_func=extracted_data['workflow_func'],
-                           workflow=extracted_data['w_metadata'])
+                           workflow=extracted_data['w_metadata'],
+                           edit_record_widget=edit_record_widget)
 
 
 @blueprint.route('/restart_record', methods=['GET', 'POST'])
 @login_required
-@wash_arguments({'bwobject_id': (int, 0)})
-def restart_record(bwobject_id, start_point='continue_next'):
+@wash_arguments({'objectid': (int, 0)})
+def restart_record(objectid, start_point='continue_next'):
     """
     Restarts the initial object in its workflow
     """
-    bwobject = BibWorkflowObject.query.get(bwobject_id)
+    bwobject = BibWorkflowObject.query.get(objectid)
 
     workflow = Workflow.query.filter(
         Workflow.uuid == bwobject.id_workflow).first()
 
     start(workflow.name, [bwobject.get_data()])
     return 'Record Restarted'
 
 
 @blueprint.route('/continue_record', methods=['GET', 'POST'])
 @login_required
-@wash_arguments({'bwobject_id': (int, 0)})
-def continue_record(bwobject_id):
+@wash_arguments({'objectid': (int, 0)})
+def continue_record(objectid):
     """
     Restarts the initial object in its workflow
     """
-    continue_oid_delayed(oid=bwobject_id, start_point='continue_next')
+    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({'bwobject_id': (int, 0)})
-def restart_record_prev(bwobject_id):
+@wash_arguments({'objectid': (int, 0)})
+def restart_record_prev(objectid):
     """
     Restarts the initial object in its workflow from the current task
     """
-    continue_oid_delayed(oid=bwobject_id, start_point="restart_task")
+    continue_oid_delayed(oid=objectid, start_point="restart_task")
     return 'Record restarted current task'
 
 
 @blueprint.route('/delete_from_db', methods=['GET', 'POST'])
 @login_required
-@wash_arguments({'bwobject_id': (int, 0)})
-def delete_from_db(bwobject_id):
+@wash_arguments({'objectid': (int, 0)})
+def delete_from_db(objectid):
     """
     Deletes all available versions of the object from the db
     """
-    # FIXME: Temp hack until redis is hooked up
-    # import invenio.modules.workflows.containers
-    _delete_from_db(bwobject_id)
-    # reload invenio.modules.workflows.containers
+    BibWorkflowObject.delete(bwobject_id)
     return 'Record Deleted'
 
 
-def _delete_from_db(bwobject_id):
-    from invenio.ext.sqlalchemy import db
-    # delete every BibWorkflowObject version from the db
-    # TODO: THIS NEEDS FIXING
-    print bwobject_id
-    BibWorkflowObject.query.filter(BibWorkflowObject.id == bwobject_id).delete()
-    db.session.commit()
-
-
 @blueprint.route('/delete_multi', methods=['GET', 'POST'])
 @login_required
 @wash_arguments({'bwolist': (unicode, "")})
 def delete_multi(bwolist):
     from ..utils import parse_bwids
     bwolist = parse_bwids(bwolist)
-    print 'bwolist:', bwolist
-    for bwobject_id in bwolist:
-        print 'bwobject_id:', bwobject_id
-        _delete_from_db(bwobject_id)
+    for objectid in bwolist:
+        delete_from_db(objectid)
     return 'Records Deleted'
 
 
-@blueprint.route('/widget', methods=['GET', 'POST'])
-@register_breadcrumb(blueprint, '.widget', "Widget")
+@blueprint.route('/action/<objectid>', methods=['GET', 'POST'])
+@register_breadcrumb(blueprint, '.widget', _("Widget"))
 @login_required
-@wash_arguments({'bwobject_id': (int, 0),
-                 'widget': (unicode, 'default')})
-def show_widget(bwobject_id, widget):
+def show_widget(objectid):
     """
     Renders the widget assigned to a specific record
     """
-    bwobject = BibWorkflowObject.query.get(bwobject_id)
+    bwobject = BibWorkflowObject.query.filter(
+        BibWorkflowObject.id == objectid).first_or_404()
+
+    widget = bwobject.get_widget()
+    # FIXME: add case here if no widget
     widget_form = widgets[widget]
     extracted_data = extract_data(bwobject)
     result = widget_form().render([bwobject],
                                   [extracted_data['bwparent']],
                                   [extracted_data['info']],
                                   [extracted_data['logtext']],
                                   [extracted_data['w_metadata']],
                                   [extracted_data['workflow_func']])
     url, parameters = result
 
     return render_template(url, **parameters)
 
 
-@blueprint.route('/resolve_widget', methods=['POST'])
+@blueprint.route('/resolve', methods=['GET', 'POST'])
 @login_required
-@wash_arguments({'bwobject_id': (unicode, '0'),
-                                 'widget': (unicode, 'default')})
-def resolve_widget(bwobject_id, widget):
+@wash_arguments({'objectid': (unicode, '-1'),
+                 'widget': (unicode, 'default')})
+def resolve_widget(objectid, widget):
     """
     Resolves the action taken in a widget.
     Calls the run_widget function of the specific widget.
     """
     widget_form = widgets[widget]
-    widget_form().run_widget(bwobject_id, request)
+    widget_form().run_widget(objectid, request)
     return "Done"
 
 
+@blueprint.route('/resolve_edit', methods=['GET', 'POST'])
+@login_required
+@wash_arguments({'objectid': (unicode, '0'),
+                 'form': (unicode, '')})
+def resolve_edit(objectid, form):
+    """
+    Performs the changes to the record made in the edit record widget.
+    """
+    if request:
+        edit_record(request.form)
+    return 'Record Edited'
+
+
 @blueprint.route('/entry_data_preview', methods=['GET', 'POST'])
 @login_required
-@wash_arguments({'oid': (unicode, '0'),
-                 'recformat': (unicode, None)})
-def entry_data_preview(oid, recformat):
+@wash_arguments({'objectid': (unicode, '0'),
+                 'of': (unicode, None)})
+def entry_data_preview(objectid, of):
     """
     Presents the data in a human readble form or in xml code
     """
     from flask import Markup
     from pprint import pformat
-    
-    bwobject = BibWorkflowObject.query.get(int(oid))
 
-    formatted_data = bwobject.get_formatted_data(recformat)
+    bwobject = BibWorkflowObject.query.get(int(objectid))
+
+    formatted_data = bwobject.get_formatted_data(of)
     if isinstance(formatted_data, dict):
         formatted_data = pformat(formatted_data)
-    if recformat and recformat in ("xm", "xml", "marcxml"):
+    if of and of in ("xm", "xml", "marcxml"):
         data = Markup.escape(formatted_data)
     else:
         data = formatted_data
     return jsonify(data=data)
 
 
 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['widget'] = bwobject.get_extra_data()['widget']
     return info
 
 
 def extract_data(bwobject):
     """
     Extracts metadata for BibWorkflowObject needed for rendering
     the Record's details and widget 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']['widget'] = bwobject.get_extra_data()['widget']
     except (KeyError, AttributeError):
         pass
 
     extracted_data['w_metadata'] = \
         Workflow.query.filter(Workflow.uuid == bwobject.id_workflow).first()
 
     extracted_data['workflow_func'] = \
         get_workflow_definition(extracted_data['w_metadata'].name).workflow
 
     return extracted_data
+
+
+def edit_record(form):
+    """
+    Will call the edit record widget resolve function
+    """
+    for key in form.iterkeys():
+        # print '%s: %s' % (key, form[key])
+        pass
+
+
+def get_widget_list(object_list):
+    """
+    Returns a dicts of widget names mapped to
+    the number of halted objects associated with that widget.
+    """
+    widget_dict = {}
+    for bwo in object_list:
+        widget = bwo.get_widget()
+        if widget is not None and bwo.version == ObjectVersion.HALTED:
+            widget_count = widget_dict.setdefault(widget, 0)
+            widget_count += 1
+    return widget_dict
diff --git a/invenio/modules/workflows/widgets/approval_widget.py b/invenio/modules/workflows/widgets/approval_widget.py
index 020f122a8..4c8d00ba6 100644
--- a/invenio/modules/workflows/widgets/approval_widget.py
+++ b/invenio/modules/workflows/widgets/approval_widget.py
@@ -1,77 +1,78 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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.
 
 from ..hp_field_widgets import (bootstrap_accept, bootstrap_accept_mini,
                                 bootstrap_reject, bootstrap_reject_mini)
 
 from wtforms import SubmitField, Form
+from invenio.base.i18n import _
+
 
 __all__ = ['approval_widget']
 
 
 class approval_widget(Form):
-    reject = SubmitField(label='Reject', widget=bootstrap_reject)
-    accept = SubmitField(label='Accept', widget=bootstrap_accept)
+    reject = SubmitField(label=_('Reject'), widget=bootstrap_reject)
+    accept = SubmitField(label=_('Accept'), widget=bootstrap_accept)
 
     class mini_widget(Form):
-        reject = SubmitField(label='Reject', widget=bootstrap_reject_mini)
-        accept = SubmitField(label='Accept', widget=bootstrap_accept_mini)
+        reject = SubmitField(label=_('Reject'), widget=bootstrap_reject_mini)
+        accept = SubmitField(label=_('Accept'), widget=bootstrap_accept_mini)
 
     def render(self, bwobject_list, bwparent_list, info_list,
                logtext_list, w_metadata_list,
                workflow_func_list, *args, **kwargs):
         data_preview_list = []
         # setting up approval widget
         for bwo in bwobject_list:
             data_preview_list.append(bwo.get_formatted_data())
 
         return ('workflows/hp_approval_widget.html',
                 {'bwobject_list': bwobject_list,
                  'bwparent_list': bwparent_list,
                  'widget': approval_widget(),
                  'data_preview_list': data_preview_list,
                  'obj_number': len(bwobject_list),
                  'info_list': info_list,
                  'logtext_list': logtext_list,
                  'w_metadata_list': w_metadata_list,
                  'workflow_func_list': workflow_func_list})
 
-    def run_widget(self, bwobject_id, request):
+    def run_widget(self, objectid, request):
         """
         Resolves the action taken in the approval widget
         """
-        from flask import request, flash, redirect, url_for
+        from flask import request, flash
         from ..api import continue_oid_delayed
-        from ..views.holdingpen import _delete_from_db
         from ..models import BibWorkflowObject
 
-        bwobject = BibWorkflowObject.query.get(bwobject_id)
+        bwobject = BibWorkflowObject.query.get(objectid)
 
         if request.form['decision'] == 'Accept':
             bwobject.remove_widget()
-            continue_oid_delayed(bwobject_id)
+            continue_oid_delayed(objectid)
             flash('Record Accepted')
-            
+
         elif request.form['decision'] == 'Reject':
-            _delete_from_db(bwobject_id)
+            BibWorkflowObject.delete(objectid)
             flash('Record Rejected')
 
 approval_widget.__title__ = 'Approve Record'
 
 widget = approval_widget()
diff --git a/invenio/modules/workflows/widgets/bibmatch_widget.py b/invenio/modules/workflows/widgets/bibmatch_widget.py
index 6158bcb3f..c47a31dfe 100644
--- a/invenio/modules/workflows/widgets/bibmatch_widget.py
+++ b/invenio/modules/workflows/widgets/bibmatch_widget.py
@@ -1,59 +1,54 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
-## Copyright (C) 2012, 2013 CERN.
+## 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.
 
+from invenio.base.i18n import _
 from ..hp_field_widgets import bootstrap_accept
 from wtforms import SubmitField, Form
 __all__ = ['bibmatch_widget']
 
 
 class bibmatch_widget(Form):
-    accept = SubmitField(label='Accept', widget=bootstrap_accept)
+    accept = SubmitField(label=_('Accept'), widget=bootstrap_accept)
 
     def render(self, bwobject_list, *args, **kwargs):
-        from ..models import BibWorkflowObject
-        from ..views.holdingpen import _entry_data_preview
+        # FIXME: Currently not working
 
         # setting up bibmatch widget
         bwobject = bwobject_list[0]
+        results = bwobject.get_extra_data()['_tasks_results']
 
-        try:
-            matches = bwobject.get_extra_data()['tasks_results']['match_record']
-        except:
-            pass
-
+        matches = []
         match_preview = []
-        # adding dummy matches
-        match_preview.append(BibWorkflowObject.query.filter(
-            BibWorkflowObject.id == bwobject.id).first())
-        match_preview.append(BibWorkflowObject.query.filter(
-            BibWorkflowObject.id == bwobject.id).first())
+        for res in results:
+            if res.name == "matcher":
+                matches.append(res.result)
 
-        data_preview = _entry_data_preview(bwobject.get_data())
+        data_preview = None
 
         return ('workflows/hp_bibmatch_widget.html',
                 {'bwobject': bwobject,
                  'widget': bibmatch_widget(),
                  'match_preview': match_preview,
                  'matches': matches,
                  'data_preview': data_preview})
 
 
 bibmatch_widget.__title__ = 'Bibmatch Widget'
 
 widget = bibmatch_widget()
diff --git a/invenio/modules/workflows/widgets/edit_record_widget.py b/invenio/modules/workflows/widgets/edit_record_widget.py
new file mode 100644
index 000000000..e4dbed0a2
--- /dev/null
+++ b/invenio/modules/workflows/widgets/edit_record_widget.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+##
+## This file is part of Invenio.
+## Copyright (C) 2012, 2013 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.
+
+from wtforms import TextField, Form, SubmitField, BooleanField
+from ..hp_field_widgets import bootstrap_submit
+from flask import render_template
+
+__all__ = ['edit_record_widget']
+
+
+class edit_record_widget(Form):
+    recid = TextField(label='Rec ID')
+    core = BooleanField(label='Core')
+    field_code = TextField(label='Field Code')
+    type_code = TextField(label='Type Code')
+    submit = SubmitField(label="Submit", widget=bootstrap_submit)
+
+    def render(self, *args, **kwargs):
+        return render_template('workflows/hp_edit_record_widget.html')
+
+
+edit_record_widget.__title__ = 'Edit Record'
+
+widget = edit_record_widget()
diff --git a/invenio/modules/workflows/worker_engine.py b/invenio/modules/workflows/worker_engine.py
index fe29ffee6..43fc99476 100644
--- a/invenio/modules/workflows/worker_engine.py
+++ b/invenio/modules/workflows/worker_engine.py
@@ -1,185 +1,189 @@
 # -*- coding: utf-8 -*-
 ## This file is part of Invenio.
 ## Copyright (C) 2012, 2013 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.
 
 from invenio.ext.sqlalchemy import db
 from .client import run_workflow, continue_execution
 from .engine import BibWorkflowEngine
-from .models import BibWorkflowObject, Workflow
-from .config import CFG_OBJECT_VERSION
-
-
-class InvenioBibWorkflowValueError(Exception):
-    pass
+from .models import BibWorkflowObject, Workflow, ObjectVersion
+from .errors import WorkflowObjectVersionError
 
 
 def run_worker(wname, data, **kwargs):
     """
     Runs workflow with given name and given data.
     Data can be specified as list of objects or
     single id of WfeObject/BibWorkflowObjects.
     """
     wfe = BibWorkflowEngine(wname, **kwargs)
     wfe.save()
     objects = prepare_objects(data, wfe)
     run_workflow(wfe=wfe, data=objects, **kwargs)
 
     return wfe
 
 
 def restart_worker(wid, **kwargs):
     """
     Restarts workflow with given id (wid) and given data. If data are not
     specified then it will load all initial data for workflow.
 
     Data can be specified as list of objects
     or single id of WfeObject/BibWorkflowObjects.
     """
     data = BibWorkflowObject.query.filter(BibWorkflowObject.id_workflow == wid,
                                           BibWorkflowObject.version ==
-                                          CFG_OBJECT_VERSION.INITIAL).all()
+                                          ObjectVersion.INITIAL).all()
 
     workflow = Workflow.query.filter(Workflow.uuid == wid).first()
 
     wfe = BibWorkflowEngine(workflow.name, **kwargs)
     wfe.save()
 
     objects = prepare_objects(data, wfe)
     run_workflow(wfe=wfe, data=objects, **kwargs)
 
     return wfe
 
 
 def continue_worker(oid, restart_point="continue_next", **kwargs):
     """
     Restarts workflow with given id (wid) at given point.
 
     restart_point can be 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
     """
     data = [BibWorkflowObject.query.filter(BibWorkflowObject.id ==
                                            oid).first()]
+    #data[0].version = ObjectVersion.RUNNING
+    #data[0].save()
 
     workflow = Workflow.query.filter(Workflow.uuid ==
                                      data[0].id_workflow).first()
     wfe = BibWorkflowEngine(workflow.name, uuid=None, id_user=0,
                             workflow_object=workflow, **kwargs)
     wfe.save()
 
     continue_execution(wfe, data, restart_point, **kwargs)
     return wfe
 
 
 def prepare_objects(data, workflow_object):
     objects = []
+    data_type = workflow_object.get_default_data_type()
     for obj in data:
         if isinstance(obj, BibWorkflowObject):
             if obj.id:
-                obj.log.debug("Object found for process")
+                obj.log.info("Object found for process")
                 objects.append(_prepare_objects_helper(obj, workflow_object))
             else:
+                obj.log.info("Object not found for process")
                 objects.append(obj)
         else:
             # First we create an initial object for each data item
             new_initial = \
                 BibWorkflowObject(id_workflow=workflow_object.uuid,
-                                  version=CFG_OBJECT_VERSION.INITIAL
-                                  )
+                                  version=ObjectVersion.INITIAL,
+                                  data_type=data_type)
             new_initial.set_data(obj)
             new_initial._update_db()
 
             # Then we create another object to actually work on
             current_obj = BibWorkflowObject(id_workflow=workflow_object.uuid,
-                                            version=CFG_OBJECT_VERSION.RUNNING,
-                                            id_parent=new_initial.id)
+                                            version=ObjectVersion.RUNNING,
+                                            id_parent=new_initial.id,
+                                            data_type=data_type)
             current_obj.set_data(obj)
             objects.append(current_obj)
     return objects
 
+
 def _prepare_objects_helper(obj, workflow_object):
     assert obj
-    if obj.version == CFG_OBJECT_VERSION.INITIAL:
-        obj.log.debug("State: Initial")
+    if obj.version == ObjectVersion.INITIAL:
+        obj.log.info("State: Initial")
         new_id = obj._create_version_obj(id_workflow=workflow_object.uuid,
-                                         version=CFG_OBJECT_VERSION.RUNNING,
+                                         version=ObjectVersion.RUNNING,
                                          id_parent=obj.id,
                                          no_update=True)
         return BibWorkflowObject.query.filter(BibWorkflowObject.id ==
                                               new_id).first()
-    elif obj.version in (CFG_OBJECT_VERSION.HALTED, CFG_OBJECT_VERSION.FINAL):
-        obj.log.debug("State: Halted or Final")
+    elif obj.version in (ObjectVersion.HALTED, ObjectVersion.FINAL):
+        obj.log.info("State: Halted or Final")
         # creating INITIAL object
         # for FINAL version: maybe it should set
         # id_parent to the previous final object
         new_initial = obj._create_version_obj(id_workflow=workflow_object.uuid,
-                                              version=CFG_OBJECT_VERSION.INITIAL,
+                                              version=ObjectVersion.INITIAL,
                                               no_update=True)
         new_id = obj._create_version_obj(id_workflow=workflow_object.uuid,
-                                         version=CFG_OBJECT_VERSION.RUNNING,
+                                         version=ObjectVersion.RUNNING,
                                          id_parent=new_initial,
                                          no_update=True)
         return BibWorkflowObject.query.filter(BibWorkflowObject.id ==
                                               new_id).first()
-    elif obj.version == CFG_OBJECT_VERSION.RUNNING:
+    elif obj.version == ObjectVersion.RUNNING:
         # object shuld be deleted restart from INITIAL
-        obj.log.debug("State: Running")
+        obj.log.info("State: Running")
 
         if obj.id_workflow is not None:
             obj.log.info("""WARNING! You want to restart from temporary object.
 We can't guarantee that data object is not corrupted.
 Workflow will start from associated INITIAL object
 and RUNNING object will be deleted.""")
 
             parent_obj = BibWorkflowObject.query.filter(
                 BibWorkflowObject.id == obj.id_parent).first()
             new_initial = parent_obj._create_version_obj(
                 id_workflow=workflow_object.uuid,
-                version=CFG_OBJECT_VERSION.INITIAL,
+                version=ObjectVersion.INITIAL,
                 no_update=True)
             new_id = parent_obj._create_version_obj(
                 id_workflow=workflow_object.uuid,
-                version=CFG_OBJECT_VERSION.RUNNING,
+                version=ObjectVersion.RUNNING,
                 id_parent=new_initial,
                 no_update=True)
             db.session.delete(obj)
 
             return BibWorkflowObject.query.filter(BibWorkflowObject.id ==
                                                   new_id).first()
         else:
-            obj.log.info("""You are running workflow on a object created manualy
+            obj.log.info("""You are running workflow on a object created manually
 outside of the workflow. Workflow will execute on THIS object (it will change
 its state and/or data) but it would also create INITIAL version of the object to
  keep its original state.""")
 
             # We assume that there is no parent object, so we create a new
             # INITIAL object, which will become a parent.
             new_parent = obj._create_version_obj(
                 id_workflow=workflow_object.uuid,
-                version=CFG_OBJECT_VERSION.INITIAL,
+                version=ObjectVersion.INITIAL,
                 no_update=True)
             # We add an id_workflow to our object
             obj.id_workflow = workflow_object.uuid
             obj.id_parent = new_parent
             obj._update_db()
 
             return obj
     else:
-        raise InvenioBibWorkflowValueError("Object version is unknown: %s" %
-                                           (obj.version,))
+        raise WorkflowObjectVersionError("Object version is unknown: %s" %
+                                         (obj.version,),
+                                         obj_version=obj.version,
+                                         id_object=obj.id)
diff --git a/invenio/modules/workflows/workflows/full_doc_process.py b/invenio/modules/workflows/workflows/full_doc_process.py
index f11c1576d..7f594fa2b 100644
--- a/invenio/modules/workflows/workflows/full_doc_process.py
+++ b/invenio/modules/workflows/workflows/full_doc_process.py
@@ -1,59 +1,57 @@
+# -*- coding: utf-8 -*-
 ## This file is part of Invenio.
-## Copyright (C) 2012 CERN.
+## 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.
 
 from ..tasks.marcxml_tasks import (convert_record_with_repository,
                                    plot_extract,
                                    convert_record_to_bibfield,
                                    fulltext_download,
                                    refextract,
                                    author_list,
                                    upload_step,
                                    quick_match_record,
                                    inspire_filter_custom,
                                    bibclassify
                                    )
 
 from ..tasks.workflows_tasks import (log_info)
 
 from ..tasks.logic_tasks import (workflow_if,
                                  workflow_else
                                  )
-from ..models import DATA_TYPES
-
 from invenio.config import CFG_PREFIX
 
 
 class full_doc_process(object):
-    object_type = DATA_TYPES.RECORD
+    object_type = "record"
     workflow = [convert_record_with_repository("oaiarXiv2inspire_nofilter.xsl"), convert_record_to_bibfield,
-                inspire_filter_category(category_widgeted=["gr-qc"], category_accepted=['*'], widget="approval_widget"),
                 workflow_if(quick_match_record, True),
                 [
                     plot_extract(["latex"]),
                     fulltext_download,
                     inspire_filter_custom(fields=["report_number", "arxiv_category"], custom_accepted=["*"],
-                                          widget="approval_widget"),
+                                          custom_refused="gr-qc", widget="approval_widget"),
                     bibclassify(taxonomy=CFG_PREFIX + "/etc/bibclassify/HEP.rdf",
                                 output_mode="dict", match_mode="partial"),
                     refextract, author_list,
                     upload_step,
                 ],
                 workflow_else,
                 [
                     log_info("Record already into database"),
                 ],
                 ]
diff --git a/invenio/modules/workflows/workflows/generic_harvesting_workflow.py b/invenio/modules/workflows/workflows/generic_harvesting_workflow.py
index 27181307d..84497dbcd 100644
--- a/invenio/modules/workflows/workflows/generic_harvesting_workflow.py
+++ b/invenio/modules/workflows/workflows/generic_harvesting_workflow.py
@@ -1,67 +1,66 @@
+# -*- coding: utf-8 -*-
 ## This file is part of Invenio.
-## Copyright (C) 2012 CERN.
+## 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 t
 ## 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.
 
 """Implements an example of a typical ingestion workflow for MARCXML records"""
 
 from ..tasks.marcxml_tasks import (get_repositories_list,
                                    init_harvesting,
                                    harvest_records,
                                    get_files_list,
                                    get_eng_uuid_harvested,
                                    get_records_from_file
                                    )
 
 from ..tasks.workflows_tasks import (start_workflow,
                                      wait_for_workflows_to_complete,
                                      workflows_reviews,
                                      get_nb_workflow_created
                                      )
 
 from ..tasks.logic_tasks import (foreach,
                                  end_for
                                  )
 
 from ..tasks.bibsched_tasks import write_something_bibsched
 
 from invenio.base.config import CFG_TMPSHAREDDIR
 
-from ..models import DATA_TYPES
-
 
 class generic_harvesting_workflow(object):
-    object_type = DATA_TYPES.HARVEST
+    object_type = "harvest"
     workflow = [init_harvesting,
                 foreach(get_repositories_list(['arxivb']), "repository"),
                 [
                     harvest_records,
                     foreach(get_files_list(CFG_TMPSHAREDDIR, get_eng_uuid_harvested)),
                     [
                         foreach(get_records_from_file()),
                         [
                             start_workflow("full_doc_process", None),
                             write_something_bibsched(["Workflow started : ", get_nb_workflow_created, " "]),
                         ],
                         end_for
                     ],
                     end_for
                 ],
                 end_for,
                 wait_for_workflows_to_complete,
                 write_something_bibsched("the end"),
-                workflows_reviews
+                workflows_reviews()
     ]