diff --git a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_parseSearchString.xml b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_parseSearchString.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0876b7d095e1f482fb5de5e5a0a57b0616c4bc9b
--- /dev/null
+++ b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_parseSearchString.xml
@@ -0,0 +1,270 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_body</string> </key>
+            <value> <string encoding="cdata"><![CDATA[
+
+"""\n
+Make SQLCatalog parse given search string and generate an Abstract Syntax Tree.\n
+Then, walk this tree and categorize criterion by type (and their alias, see code).\n
+"""\n
+from DateTime import DateTime\n
+\n
+def render_filetype_list(filetype_list):\n
+  return [\'%%.%s\' % (x, ) for x in filetype_list]\n
+\n
+def render_state_list(state_list):\n
+  # Note: also used to render type list\n
+  result = []\n
+  append = result.append\n
+  for state in state_list:\n
+    if state != \'all\':\n
+      append(state)\n
+  return result\n
+\n
+def render_date_range(date_range_list):\n
+  result = []\n
+  append = result.append\n
+  now = DateTime()\n
+  for date_range in date_range_list:\n
+    # XXX: original version used a regex, but we can\'t import\n
+    # "re" module here, so fallback on hand-crafted parsing.\n
+    # Original regex: \'(\\d)([wmy]).*\'\n
+    # State meaning:\n
+    #   0: we expect only decimals\n
+    #   1: we expect one of \'w\', \'m\', or \'y\'\n
+    state = 0\n
+    duration_char_list = []\n
+    multiplicator = None\n
+    for char in date_range:\n
+      if state == 0:\n
+        if \'0\' <= char <= \'9\':\n
+          duration_char_list.append(char)\n
+        else:\n
+          state = 1\n
+      if state == 1:\n
+        if len(duration_char_list):\n
+          if char == \'w\':\n
+            multiplicator = 7\n
+          elif char == \'m\':\n
+            multiplicator = 30\n
+          elif char == \'y\':\n
+            multiplicator = 365\n
+        break\n
+    if multiplicator is not None:\n
+      duration = int(\'\'.join(duration_char_list))\n
+      append(now - duration * multiplicator)\n
+  return result\n
+\n
+criterion_alias_dict = {\n
+  \'state\':            (\'simulation_state\', render_state_list),\n
+  \'type\':             (\'portal_type\',      render_state_list),\n
+  \'filetype\':         (\'source_reference\', render_filetype_list),\n
+  \'file\':             (\'source_reference\', None),\n
+  \'created\':          (\'creation_from\',    render_date_range),\n
+  \'simulation_state\': (True, None),\n
+  \'language\':         (True, None),\n
+  \'version\':          (True, None),\n
+  \'reference\':        (True, None),\n
+  \'portal_type\':      (True, None),\n
+  \'source_reference\': (True, None),\n
+  \'creation_from\':    (True, None),\n
+  \'searchabletext\':   (True, None),\n
+}\n
+\n
+DEFAULT_CRITERION_ALIAS = \'searchabletext\'\n
+\n
+def resolveCriterion(criterion_alias, criterion_value_list):\n
+  initial_criterion_alias = criterion_alias\n
+  # XXX: should be a set\n
+  seen_alias_dict = {} # Protection against endless loops\n
+  while True:\n
+    next_alias, value_list_renderer = criterion_alias_dict.get(criterion_alias, (DEFAULT_CRITERION_ALIAS, None))\n
+    if value_list_renderer is not None:\n
+      criterion_value_list = value_list_renderer(criterion_value_list)\n
+    if next_alias is True:\n
+      break\n
+    seen_alias_dict[criterion_alias] = None\n
+    if next_alias in seen_alias_dict:\n
+      raise Exeption, \'Endless alias loop detected: lookup of %r reached alias %r twice\' % (initial_criterion_alias, next_alias)\n
+    criterion_alias = next_alias\n
+  return criterion_alias, criterion_value_list\n
+\n
+def recurseSyntaxNode(node, criterion=DEFAULT_CRITERION_ALIAS):\n
+  if node.isColumn():\n
+    result = recurseSyntaxNode(node.getSubNode(), criterion=node.getColumnName())\n
+  else:\n
+    result = {}\n
+    if node.isLeaf():\n
+      result[criterion] = [node.getValue()]\n
+    else:\n
+      for subnode in node.getNodeList():\n
+        for criterion, value_list in recurseSyntaxNode(subnode, criterion=criterion).items():\n
+          result.setdefault(criterion, []).extend(value_list)\n
+  return result\n
+\n
+def acceptAllColumns(column):\n
+  return True\n
+\n
+node = context.getPortalObject().portal_catalog.getSQLCatalog().parseSearchText(searchstring, search_key=\'FullTextKey\', is_valid=acceptAllColumns)\n
+result =  {}\n
+if node is None:\n
+  result[\'searchabletext\'] = searchstring\n
+else:\n
+  for criterion, value_list in recurseSyntaxNode(node).items():\n
+    criterion, value_list = resolveCriterion(criterion, value_list)\n
+    result.setdefault(criterion, []).extend(value_list)\n
+  filtered_result = {}\n
+  for criterion, value_list in result.items():\n
+    if len(value_list) > 0:\n
+      filtered_result[criterion] = value_list\n
+  result = filtered_result\n
+  for criterion, value_list in result.items():\n
+    # XXX: yuck\n
+    if criterion == \'searchabletext\':\n
+      result[\'searchabletext\'] = \' \'.join(value_list)\n
+    if len(value_list) == 1:\n
+      result[criterion] = value_list[0]\n
+  if \'searchabletext\' not in result:\n
+    result[\'searchabletext\'] = \'\'\n
+return result\n
+
+
+]]></string> </value>
+        </item>
+        <item>
+            <key> <string>_code</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>searchstring</string> </value>
+        </item>
+        <item>
+            <key> <string>errors</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>func_code</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>co_argcount</string> </key>
+                        <value> <int>1</int> </value>
+                    </item>
+                    <item>
+                        <key> <string>co_varnames</string> </key>
+                        <value>
+                          <tuple>
+                            <string>searchstring</string>
+                            <string>DateTime</string>
+                            <string>render_filetype_list</string>
+                            <string>render_state_list</string>
+                            <string>render_date_range</string>
+                            <string>None</string>
+                            <string>True</string>
+                            <string>criterion_alias_dict</string>
+                            <string>DEFAULT_CRITERION_ALIAS</string>
+                            <string>resolveCriterion</string>
+                            <string>recurseSyntaxNode</string>
+                            <string>acceptAllColumns</string>
+                            <string>_getattr_</string>
+                            <string>context</string>
+                            <string>node</string>
+                            <string>result</string>
+                            <string>_write_</string>
+                            <string>_getiter_</string>
+                            <string>criterion</string>
+                            <string>value_list</string>
+                            <string>filtered_result</string>
+                            <string>len</string>
+                            <string>_getitem_</string>
+                          </tuple>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>func_defaults</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Base_parseSearchString</string> </value>
+        </item>
+        <item>
+            <key> <string>warnings</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_showFoundText.xml b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_showFoundText.xml
index 9729ca3b8146335f09c43382828b164e7ab4553f..969de4f43182d2091284615ea37b07b326458add 100644
--- a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_showFoundText.xml
+++ b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_showFoundText.xml
@@ -62,23 +62,58 @@
   words in the text itself.\n
 """\n
 \n
+is_gadget_mode = context.REQUEST.get(\'is_gadget_mode\', 0)\n
+\n
+if is_gadget_mode:\n
+  # in gadget mode less space is available thus show less text\n
+  max_text_length = 100\n
+  max_lines = 1\n
+\n
+def getRandomDocumentTextExcerpt(document_text):\n
+  # try to get somewhat arbitrary choice of searchable attrs\n
+  if isinstance(document_text, str) and document_text!=\'\':\n
+    document_text = document_text.decode(\'utf-8\', \'ignore\')\n
+    start = min(len(document_text) - 300, 200)\n
+    return \'... %s ...\' %document_text[start:start + max_text_length]\n
+  else:\n
+    return \'\'\n
+\n
+# get search words from listbox selection\n
+argument_names = (\'advanced_search_text\', \n
+                  \'your_search_text\',\n
+                  \'title\',\n
+                  \'reference\',\n
+                  \'searchabletext\', \n
+                  \'searchabletext_any\',\n
+                  \'searchabletext_all\', \n
+                  \'searchabletext_phrase\',)\n
+\n
+if document_text is None:\n
+  document_text = context.getSearchableText()\n
+\n
 if selection is not None:\n
   params = selection.getParams()\n
 else:\n
   params = context.portal_selections.getSelectionParamsFor(\'search_result_selection\')\n
-search_words = params.get(\'your_search_text\')\n
 \n
-if search_words is None:\n
-  return \'\'\n
-else:\n
+params = [params.get(name, \'\') for name in argument_names]\n
+# flatten value if it is list\n
+params = [(hasattr(param, \'sort\') and \' \'.join(param) or param) for param in params]\n
+search_string = \' \'.join(params).strip()\n
 \n
-  if document_text is None:\n
-    document_text = context.getSearchableText()\n
+if search_string != \'\':\n
+  search_argument_list = context.Base_parseSearchString(search_string)\n
+  search_string = search_argument_list.get(\'searchabletext\', \'\')\n
 \n
+if search_string == \'\':\n
+  # the searched words are empty (e.g. because we used only parameters \n
+  # without pure searchable text)\n
+  return getRandomDocumentTextExcerpt(document_text)\n
+else:\n
   found_text_fragments = context.Base_getExcerptText(\n
                            context, \\\n
                            document_text, \\\n
-                           search_words, \\\n
+                           search_string, \\\n
                            tags = (\'<em>\', \'</em>\'), \\\n
                            trail = 5, \\\n
                            maxlines = max_lines)\n
@@ -131,11 +166,21 @@ else:\n
                             <string>selection</string>
                             <string>max_lines</string>
                             <string>max_text_length</string>
-                            <string>None</string>
                             <string>_getattr_</string>
-                            <string>params</string>
                             <string>context</string>
-                            <string>search_words</string>
+                            <string>is_gadget_mode</string>
+                            <string>getRandomDocumentTextExcerpt</string>
+                            <string>argument_names</string>
+                            <string>None</string>
+                            <string>params</string>
+                            <string>append</string>
+                            <string>$append0</string>
+                            <string>_getiter_</string>
+                            <string>name</string>
+                            <string>param</string>
+                            <string>hasattr</string>
+                            <string>search_string</string>
+                            <string>search_argument_list</string>
                             <string>found_text_fragments</string>
                             <string>map</string>
                             <string>str</string>
diff --git a/product/ERP5/bootstrap/erp5_core/bt/revision b/product/ERP5/bootstrap/erp5_core/bt/revision
index 872362fa15d58b62629786cae412c8e6f08a1760..7ff9fa9bd870374d4773866c2746abb552fa7cf5 100644
--- a/product/ERP5/bootstrap/erp5_core/bt/revision
+++ b/product/ERP5/bootstrap/erp5_core/bt/revision
@@ -1 +1 @@
-1226
\ No newline at end of file
+1227
\ No newline at end of file