diff --git a/process/JditoFilter_lib/process.js b/process/JditoFilter_lib/process.js
index 369edee61bfbe69d51b524dd446a892fb06eea6d..588480d799366f7596832df69ac842bc4bb76bad 100644
--- a/process/JditoFilter_lib/process.js
+++ b/process/JditoFilter_lib/process.js
@@ -4,35 +4,41 @@ import("Sql_lib");
 import("Util_lib");
 import("system.datetime");
 
+//@TODO: add support for permissions to the lib
+
 /**
  * object for filtering records
  * 
- * @param {Array} pColumns the column names
- * @param {Object} pFilter the filter object
- * @param {Object} pCustomCheckFns
- * @param {Object} pCheckFnThisArg
+ * @param {Object} [pFilter] the filter object
+ * @param {Array} [pFieldOrder] the fields
+ */
+function JditoFilter (pFilter, pFieldOrder) 
+{
+    this._fieldInfos = {};
+    this.fieldOrder(pFieldOrder);
+    this._filter = null;
+    this.filter(pFilter);
+    this._ignoreCase = JditoFilterUtils.isUserIgnoreCase();
+    this._lookupFields = [];
+}
+
+/**
+ * Sets the filter of the object
  * 
- * @private
+ * @param {Object} pFilter the filter object that should be used (e.g. vars.get("$local.filter"))
+ * @return {JditoFilter} current object
  */
-function JditoFilter (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg) 
+JditoFilter.prototype.filter = function (pFilter)
 {
-    var columnMap = {};
-    for (let i = 0, l = pColumns.length; i < l; i++)
+    if (pFilter)
     {
-        let col = pColumns[i];
-        if (col)
-            columnMap[col] = {
-                index : i,
-                checkFn : (pCustomCheckFns ? pCustomCheckFns[col] : null)
-            };
+        if (!Utils.isObject(pFilter))
+            throw new TypeError("JditoFilter: Wrong type for the filter, expected 'object' but got '" + (typeof pFilter) + "'");
+        this._filter = "filter" in pFilter ? pFilter.filter : pFilter;
+        if (this._filter && this._filter.childs.length !== 0)
+            _removeEmptyGroups(this._filter.childs);
     }
-    this.columnMap = columnMap;
-    
-    if (pFilter && pFilter.childs.length !== 0)
-        _removeEmptyGroups(pFilter.childs);
-    
-    this.filter = pFilter;
-    this.checkFnThisArg = pCheckFnThisArg || null;
+    return this;
     
     function _removeEmptyGroups (pCurrentArray)
     {
@@ -49,6 +55,104 @@ function JditoFilter (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg)
     }
 }
 
+/**
+ * Sets the filter of the object
+ * 
+ * @param {String} pFilter the filter object that should be used as JSON string
+ * @return {JditoFilter} current object
+ */
+JditoFilter.prototype.filterJSON = function (pFilter)
+{
+    return this.filter(JSON.parse(pFilter));
+}
+
+/**
+ * Sets the order of the columns
+ * 
+ * @param {Array} pFields array containing the field names in the right order
+ * @return {JditoFilter} current object
+ */
+JditoFilter.prototype.fieldOrder = function (pFields)
+{
+    for (let i = 0, l = pFields.length; i < l; i++)
+    {
+        let fieldName = pFields[i];
+        if (fieldName)
+        {
+            //remove .value if present
+            if (fieldName.endsWith(".value"))
+                fieldName = fieldName.slice(0, -6);
+            this._fieldInfos[fieldName] = {
+                index: i
+            };
+        }
+    }
+    return this;
+}
+
+/**
+ * Sets a custom check-function for the given field. This can be used to handle the value of the field differently, making more complex
+ * filters possible.
+ * 
+ * @param {String} pFieldName column the function should be used for
+ * @param {Function} pCheckFn custom check function, it will be called with these arguments: (rowValue, filterValue, operator), and it should
+ *                            return true if the row meets the filter-condition and false if it doesn't
+ * @param {Object} [pThisArg] this-value for the check-function
+ * @return {JditoFilter} current object
+ */
+JditoFilter.prototype.addSpecialCheckFn = function (pFieldName, pCheckFn, pThisArg)
+{
+    if (!this._fieldInfos[pFieldName])
+        this._fieldInfos[pFieldName] = {};
+    
+    this._fieldInfos[pFieldName].checkFn = pCheckFn;
+    this._fieldInfos[pFieldName].thisArg = pThisArg || null;
+    
+    return this;
+}
+
+/**
+ * Sets the fields that should be used for lookup filter
+ * 
+ * @param {Array} pFields the fields
+ * @return {JditoFilter} current object
+ */
+JditoFilter.prototype.lookupFilterFields = function (pFields)
+{
+    this._lookupFields = pFields;
+    var lookupFilterFn = function (pRecordValue, pFilterValue, pOperator, pRow)
+    {
+        if (pOperator == "CONTAINS")
+        {
+            var filterValues = pFilterValue.split(" ").filter(function (val) {return val.trim();});
+            return filterValues.every(function (filterValue)
+            {
+                return this._lookupFields.some(function (fieldName)
+                {
+                    var fieldIndex = this._fieldInfos[fieldName].index;
+                    return (new RegExp(filterValue, "i")).test(pRow[fieldIndex]);
+                }, this);
+            }, this);
+        }
+        return false;
+    }
+    this.addSpecialCheckFn("$$$LOOKUPFIELD$$$", lookupFilterFn, this);
+    return this;
+}
+
+/**
+ * Changes whether the condition should be case-insensitive for text
+ * 
+ * @param {boolean} [pIgnoreCase=true] if it should be case-insensitive
+ * @return {JditoFilter} current object
+ */
+JditoFilter.prototype.ignoreCase = function (pIgnoreCase)
+{
+    //"", 0 , false -> false, everything else is considered true
+    this._ignoreCase = pIgnoreCase != false;
+    return this;
+}
+
 /**
  * tests the given row if it matches the filter
  * 
@@ -58,12 +162,12 @@ function JditoFilter (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg)
  */
 JditoFilter.prototype.checkRecord = function (pRow)
 {
-    if (!this.filter || this.filter.childs.length === 0)
+    if (!this._filter || this._filter.childs.length === 0)
         return true;
     
     var regexFlags = JditoFilterUtils.isUserIgnoreCase() ? "i" : undefined;
     
-    return _testRecord.call(this, this.filter);
+    return _testRecord.call(this, this._filter);
     
     /**
      * recursive function to test the row against the condition
@@ -72,9 +176,10 @@ JditoFilter.prototype.checkRecord = function (pRow)
     {
         if (pCondition.type == "row")
         {
-            let value = pRow[this.columnMap[pCondition.name].index];
-            let testFn = this.columnMap[pCondition.name].checkFn || _testValue;
-            return testFn.call(this.checkFnThisArg, value, (pCondition.key || pCondition.value), pCondition.operator, pRow);
+            let columnInfo = this._fieldInfos[pCondition.name];
+            let value = "index" in columnInfo ? pRow[columnInfo.index] : null;
+            let testFn = columnInfo.checkFn || _testValue;
+            return testFn.call(columnInfo.thisArg, value, (pCondition.key || pCondition.value), pCondition.operator, pRow);
         }
         else if (pCondition.type == "group")
         {
@@ -125,6 +230,12 @@ JditoFilter.prototype.checkRecord = function (pRow)
     }
 }
 
+/**
+ * Filters the given records by the criteria defined by the filter object.
+ * 
+ * @param {Array} pRecords 2d-array containing the records
+ * @return {Array the filtered records
+ */
 JditoFilter.prototype.filterRecords = function (pRecords)
 {
     return pRecords.filter(this.checkRecord, this);
@@ -178,7 +289,16 @@ JditoFilterUtils.filterRecords = function (pColumns, pRecords, pFilter, pCustomC
     if (!pFilter)
         return pRecords;
     
-    return new JditoFilter(pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg).filterRecords(pRecords);
+    var filterObj = new JditoFilter(pFilter, pColumns);
+    
+    if (pCustomCheckFns)
+    {
+        for (let fieldName in pCustomCheckFns)
+        {
+            filterObj.addSpecialCheckFn(fieldName, pCustomCheckFns[fieldName], pCheckFnThisArg);
+        }
+    }
+    return filterObj.filterRecords(pRecords);
 }
 
 /**
@@ -263,7 +383,7 @@ function FilterSqlTranslator (pFilter, pTable)
 /**
  * Sets the filter of the object
  * 
- * @param {Object} pFilter the filter object that should be used
+ * @param {Object} pFilter the filter object that should be used (e.g. vars.get("$local.filter"))
  * @return {FilterSqlTranslator} current object
  */
 FilterSqlTranslator.prototype.filter = function (pFilter)
@@ -272,7 +392,7 @@ FilterSqlTranslator.prototype.filter = function (pFilter)
     {
         if (!Utils.isObject(pFilter))
             throw new TypeError("FilterSqlTranslator: Wrong type for the filter, expected 'object' but got '" + (typeof pFilter) + "'");
-        this._filter = pFilter.filter || pFilter;
+        this._filter = "filter" in pFilter ? pFilter.filter : pFilter;
     }
     return this;
 }