diff --git a/local/alpha/config/vufind/searchspecs.yaml b/local/alpha/config/vufind/searchspecs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..498d584b19e72b391ed788ed137285df3a5880f6
--- /dev/null
+++ b/local/alpha/config/vufind/searchspecs.yaml
@@ -0,0 +1,739 @@
+---
+# Listing of search types and their component parts and weights.
+#
+# Format is:
+#  searchType:
+#    # CustomMunge is an optional section to define custom pre-processing of
+#    #     user input.  See below for details of munge actions.
+#    CustomMunge:
+#      MungeName1:
+#        - [action1, actionParams]
+#        - [action2, actionParams]
+#        - [action3, actionParams]
+#      MungeName2:
+#        - [action1, actionParams]
+#    # DismaxFields is optional and defines the fields sent to the Dismax handler
+#    #     when we are able to use it.  QueryFields will be used for advanced
+#    #     searches that Dismax cannot support.  QueryFields is always used if no
+#    #     DismaxFields section is defined.
+#    DismaxFields:
+#      - field1^boost
+#      - field2^boost
+#      - field3^boost
+#    # DismaxParams is optional and allows you to override default Dismax settings
+#    #     (i.e. mm / bf) on a search-by-search basis. Enclose the parameter values
+#    #     in quotes for proper behavior. If you want global default values for these
+#    #     settings, you can edit the appropriate search handler in
+#    #     solr/biblio/conf/solrconfig.xml.
+#    DismaxParams:
+#      - [param1_name, param1_value]
+#      - [param2_name, param2_value]
+#      - [param3_name, param3_value]
+#    # This optional setting may be used to specify which Dismax handler to use. By
+#    #     default, VuFind provides two options: dismax (for the old, standard
+#    #     Dismax) and edismax (for Extended Dismax). You can also configure your own
+#    #     in solrconfig.xml, but VuFind relies on the name "edismax" to identify an
+#    #     Extended Dismax handler. If you omit this setting, the default value from
+#    #     the default_dismax_handler setting in the [Index] section of config.ini
+#    #     will be used.
+#    DismaxHandler: dismax|edismax
+#    # QueryFields define the fields we are searching when not using Dismax; VuFind
+#    #     detects queries that will not work with Dismax and switches to QueryFields
+#    #     as needed.
+#    QueryFields:
+#      SolrField:
+#        - [howToMungeSearchstring, weight]
+#        - [differentMunge, weight]
+#      DifferentSolrField:
+#        - [howToMunge, weight]
+#    # The optional FilterQuery section allows you to AND a static query to the
+#    #     dynamic query generated using the QueryFields; see JournalTitle below
+#    #     for an example.  This is applied whether we use DismaxFields or
+#    #     QueryFields.
+#    FilterQuery: (optional Lucene filter query)
+#    ExactSettings:
+#      DismaxFields: ...
+#      QueryFields: ...
+#    # All the same settings as above, but for exact searches, i.e. search terms
+#    #     enclosed in quotes. Allows different fields or weights for exact
+#    #     searches. See below for commented-out examples.
+#
+# ...etc.
+#
+#-----------------------------------------------------------------------------------
+#
+# Within the QueryFields area, fields are OR'd together, unless they're in an
+# anonymous array with a numeric instead of alphanumeric key, in which case the
+# first element is a two-value array that tells us what the type (AND or OR) and
+# weight of the whole group should be.
+#
+# So, given:
+#
+# test:
+#   QueryFields:
+#     A:
+#       - [onephrase, 500]
+#       - [and, 200]
+#     B:
+#       - [and, 100]
+#       - [or, 50]
+#     # Start an anonymous array to group; first element indicates AND grouping
+#     #     and a weight of 50
+#     0:
+#       0:
+#         - AND
+#         - 50
+#       C:
+#         - [onephrase, 200]
+#       D:
+#         - [onephrase, 300]
+#       # Note the "not" attached to the field name as a minus, and the use of ~
+#       #     to mean null ("no special weight")
+#       -E:
+#         - [or, ~]
+#     D:
+#       - [or, 100]
+#
+#  ...and the search string
+#
+#      test "one two"
+#
+#  ...we'd get
+#
+#   (A:"test one two"^500 OR
+#    A:(test AND "one two")^ 200 OR
+#    B:(test AND "one two")^100 OR
+#    B:(test OR "one two")^50
+#    (
+#      C:("test one two")^200 AND
+#      D:"test one two"^300 AND
+#      -E:(test OR "one two")
+#    )^50 OR
+#    D:(test OR "one two")^100
+#   )
+#
+#-----------------------------------------------------------------------------------
+#
+# Munge types are based on the original Solr.php code, and consist of:
+#
+# onephrase: eliminate all quotes and do it as a single phrase. 
+#   testing "one two"
+#    ...becomes ("testing one two")
+#
+# and: AND the terms together
+#  testing "one two"
+#   ...becomes (testing AND "one two")
+#
+# or: OR the terms together
+#  testing "one two"
+#   ...becomes (testing OR "one two")
+#
+# identity: Use the search as-is
+#  testing "one two"
+#   ...becomes (testing "one two")
+#
+# Additional Munge types can be defined in the CustomMunge section.  Each array
+# entry under CustomMunge defines a new named munge type.  Each array entry under
+# the name of the munge type specifies a string manipulation operation.  Operations
+# will be applied in the order listed, and different operations take different
+# numbers of parameters.
+#
+# Munge operations:
+#
+# [append, text] - Append text to the end of the user's search string
+# [lowercase] - Convert string to lowercase
+# [preg_replace, pattern, replacement] - Perform a regular expression replace
+#     using the preg_replace() PHP function.  If you use backreferences in your
+#     replacement phrase, be sure to escape dollar signs (i.e. \$1, not $1).
+# [uppercase] - Convert string to uppercase
+#
+# See the CallNumber search below for an example of custom munging in action.
+#-----------------------------------------------------------------------------------
+
+# These searches use Dismax when possible:
+Author:
+  DismaxParams:
+    - [bf , ord(publishDateSort)^10]
+  DismaxFields:
+    - author^400
+    - author2^300
+    - author_id^100
+    - author_ref^150
+    - author_corp^200
+    - author_corp2^200
+    - author_corp_ref^150
+    - author_orig^200
+    - author2_orig^200
+    - author_corp_orig^200
+    - author_corp2_orig^200
+  QueryFields:
+    - author:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author2:
+      - [onephrase, 100]
+      - [and, 50]
+      - [or, ~]
+    - author_ref:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp2:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp_ref:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author2_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp2_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_id:
+      - [onephrase, 450]
+      - [and, 300]
+      - [or, 200]
+
+ISN:
+#  DismaxFields:
+#    - isbn
+#    - issn
+#    - ismn
+  QueryFields:
+    - issn:
+      - [and, 100]
+      - [or, ~]
+    - isbn:
+      - [and, 100]
+      - [or, ~]
+    - ismn:
+      - [and, 100]
+      - [or, ~]
+
+Signatur:
+  DismaxParams:
+    - [mm, 0]
+  DismaxFields:
+    - callnumber_ISIL
+  QueryFields:
+    - callnumber_ISIL:
+      - [or, ~]
+  #    - [and, 100]
+  #    - [or, ~]
+
+Barcode:
+  DismaxParams:
+    - [mm, 0]
+  DismaxFields:
+    - barcode_ISIL
+  QueryFields:
+    - barcode_ISIL:
+      #- [and, 100]
+      - [or, ~]
+
+Subject:
+  DismaxFields:
+    - topic_unstemmed^150
+    - topic^100
+    - topic_id^100
+    - topic_ref^100
+    #- geographic^50
+    #- genre^50
+    #- era
+  QueryFields:
+    - topic_unstemmed:
+      - [onephrase, 350]
+      - [and, 150]
+      - [or, ~]
+    - topic:
+      - [onephrase, 300]
+      - [and, 100]
+      - [or, ~]
+    - topic_ref:
+      - [onephrase, 100]
+      - [and, 50]
+      - [or, ~]
+    - topic_id:
+      - [onephrase, 100]
+      - [and, 50]
+      - [or, ~]
+    #- geographic:
+    #  - [onephrase, 300]
+    #  - [and, 100]
+    #  - [or, ~]
+    #- genre:
+    #  - [onephrase, 300]
+    #  - [and, 100]
+    #  - [or, ~]
+    #- era:
+    #  - [and, 100]
+    #  - [or, ~]
+#  ExactSettings:
+#    DismaxFields:
+#      - topic_unstemmed^150
+#    QueryFields:
+#      - topic_unstemmed:
+#        - [onephrase, 350]
+#        - [and, 150]
+#        - [or, ~]
+
+# This field definition is a compromise that supports both journal-level and
+# article-level data.  The disadvantage is that hits in article titles will
+# be mixed in.  If you are building a purely article-oriented index, you should
+# customize this to remove all of the title_* fields and focus entirely on the
+# container_title field.
+JournalTitle:
+  DismaxFields:
+    - title_short^500
+    - title_full_unstemmed^450
+    - title_full^400
+    - title^300
+    - title_alt^200
+    - title_new^100
+    - title_old
+    - series^100
+    - series2
+  QueryFields:
+    - title_short:
+      - [onephrase, 500]
+    - title_full_unstemmed:
+      - [onephrase, 450]
+      - [and, 400]
+    - title_full:
+      - [onephrase, 400]
+    - title:
+      - [onephrase, 300]
+      - [and, 250]
+    - title_alt:
+      - [and, 200]
+    - title_new:
+      - [and, 100]
+    - title_old:
+      - [and, ~]  
+    - series:
+      - [onephrase, 100]
+      - [and, 50]
+    - series2:
+      - [onephrase, 50]
+      - [and , ~]
+  FilterQuery: "format:Journal"
+#  ExactSettings:
+#    DismaxFields:
+#      - title_full_unstemmed^450
+#    QueryFields:
+#      - title_full_unstemmed:
+#        - [onephrase, 450]
+#        - [and, 400]
+#    FilterQuery: "format:Journal OR format:Article"
+
+Title:
+  DismaxParams:
+    - [mm, 3]
+    - [bf , ord(publishDateSort)^10]
+  DismaxFields:
+#    - title_sub^200
+#    - title_short^300
+    - title_full_unstemmed^150
+    - title_full^100
+    - title^900
+    - title_alt^200
+    - title_new^100
+    - title_old
+    - title_orig^400
+    - series^100
+    - series2
+    - series_orig^100
+  QueryFields:
+    - title_short:
+      - [onephrase, 500]
+    - title_full_unstemmed:
+      - [onephrase, 150]
+      - [and, 100]
+    - title_full:
+      - [onephrase, 100]
+    - title:
+      - [onephrase, 300]
+      - [and, 250]
+    - title_alt:
+      - [and, 200]
+    - title_new:
+      - [and, 100]
+    - title_old:
+      - [and, ~]
+    - title_orig:
+      - [onephrase, 500]
+      - [and, 200]
+    - series:
+      - [onephrase, 100]
+      - [and, 50]
+    - series2:
+      - [onephrase, 50]
+      - [and , ~]
+    - series_orig:
+      - [onephrase, 100]
+      - [and, 50]
+#  ExactSettings:
+#    DismaxFields:
+#      - title_full_unstemmed^450
+#    QueryFields:
+#      - title_full_unstemmed:
+#        - [onephrase, 450]
+#        - [and, 400]
+
+Series:
+  DismaxFields:
+    - series^100
+    - series2
+    - series_orig^100
+  QueryFields:
+    - series:
+      - [onephrase, 500]
+      - [and, 200]
+      - [or, 100]
+    - series2:
+      - [onephrase, 50]
+      - [and, 50]
+      - [or, ~]
+    - series_orig:
+      - [onephrase, 500]
+      - [and, 200]
+      - [or, 100]
+
+Series2:
+  DismaxFields:
+    - series2
+  QueryFields:
+    - series2:
+      - [onephrase, 200]
+      - [and, 50]
+
+AllFields:
+  DismaxParams:
+    - [mm, 3]
+    - [bf , ord(publishDateSort)^10]
+    - [bf , "if(exists(query({!v='source_id:0'})),10,1)^1000"]
+#    - [bf, "if(exists(query({!v='access_facet:Local*'})),10,1)^1000"]
+  DismaxFields:
+    - title_short^1000
+    - title_full_unstemmed^1000
+    - title_full^400
+    - title^500
+    - title_alt^200
+    - title_new^100
+    - title_orig^500
+    - series^50
+    - series2^30
+    - series_orig^50
+    - author^500
+    - author_corp^300
+    - author2^400
+    - author_corp2^100
+    - author_ref^500
+    - author_corp_ref^500
+    - author_orig^300
+    - author2_orig^300
+    - author_corp_orig^300
+    - author_corp2_orig^100
+    - topic_ref^10
+    - contents^10
+    - topic_unstemmed^15
+    - topic^10
+    - geographic^10
+    - genre^10
+    - rvk_label
+    - allfields_unstemmed^10
+    - allfields
+    - fulltext
+    - isbn
+    - issn
+    - ismn
+
+  QueryFields:
+    0:
+      0:
+        - OR
+        - 50
+      title_short:
+        - [onephrase, 1000]
+      title_full_unstemmed:
+        - [onephrase, 1000]
+        - [and, 500]
+      title_full:
+        - [onephrase, 400]
+      title:
+        - [onephrase, 300]
+        - [and, 250]
+      title_alt:
+        - [and, 200]
+      title_new:
+        - [and, 100]
+      title_orig:
+        - [onephrase, 500]
+        - [and, 400]
+    series:
+      - [onephrase, 300]
+      - [and, 100]
+    series2:
+      - [and, 30]
+    series_orig:
+      - [onephrase, 200]
+      - [and, 100]
+    author:
+      - [onephrase, 500]
+      - [and, 250]
+    author_ref:
+      - [onephrase, 250]
+      - [and, 250]
+      - [or, 250]
+    author_corp_ref:
+      - [onephrase, 250]
+      - [and, 250]
+      - [or, 250]
+    author_orig:
+      - [onephrase, 500]
+      - [and, 250]
+    author2_orig:
+      - [and, 50]
+    author_corp_orig:
+      - [onephrase, 500]
+      - [and, 400]
+    author_corp2_orig:
+      - [and, 50]
+    author_corp:
+      - [onephrase, 500]
+      - [and, 400]
+    author2:
+      - [and, 50]
+    author_corp2:
+      - [and, 50]
+    contents:
+      - [and, 10]
+    topic_unstemmed:
+      - [onephrase, 55]
+      - [and, 50]
+    topic:
+      - [onephrase, 50]
+    topic_ref:
+      - [onephrase, 10]
+      - [and, 5]
+      - [or, 5]
+    topic_id:
+      - [onephrase, 50]
+      - [and, 25]
+    allfields_unstemmed:
+      - [or, 10]
+    allfields:
+      - [or, ~]
+    fulltext:
+      - [or, ~]
+    rvk_label:
+      - [onephrase, 500]
+      - [and, 250]
+      - [or, 250]
+    isbn:
+      - [onephrase, 500]
+    issn:
+      - [onephrase, 500]
+    ismn:
+      - [onephrase, 500]
+    imprint:
+      - [onephrase, 500]
+      
+#  ExactSettings:
+#    DismaxFields:
+#      - title_full_unstemmed^600
+#      - topic_unstemmed^550
+#      - allfields_unstemmed^10
+#      - fulltext_unstemmed^10
+#      - isbn
+#      - issn
+#    QueryFields:
+#      title_full_unstemmed:
+#        - [onephrase, 600]
+#        - [and, 500]
+#      topic_unstemmed:
+#        - [onephrase, 550]
+#        - [and, 500]
+#      allfields_unstemmed:
+#        - [or, 10]
+#      fulltext_unstemmed:
+#        - [or, 10]
+#      isbn:
+#        - [onephrase, ~]
+#      issn:
+#        - [onephrase, ~]
+
+# These are advanced searches that never use Dismax:
+id:
+  QueryFields:
+    - id:
+      - [onephrase, ~]
+
+# Fields for exact matches originating from alphabetic browse
+ids:
+  QueryFields:
+    - id:
+      - [or, ~]
+
+TopicBrowse:
+  QueryFields:
+    - topic_browse:
+      - [onephrase, ~]
+
+AuthorBrowse:
+  QueryFields:
+    - author_browse:
+      - [onephrase, ~]
+
+TitleBrowse:
+  QueryFields:
+    - title_full:
+      - [onephrase, ~]
+
+DeweyBrowse:
+  QueryFields:
+    - dewey-raw:
+      - [onephrase, ~]
+
+LccBrowse:
+  QueryFields:
+    - callnumber-a:
+      - [onephrase, ~]
+
+
+
+# CallNumber:
+  # We use two similar munges here -- one for exact matches, which will get
+  # a very high boost factor, and one for left-anchored wildcard searches,
+  # which will return a larger number of hits at a lower boost.
+  #CustomMunge:
+    #callnumber_exact:
+      #- [uppercase]
+      # Strip whitespace and quotes:
+      #- [preg_replace, '/[ "]/', ""]
+      # Escape colons (unescape first to avoid double-escapes):
+      #- [preg_replace, "/(\\\:)/", ':']
+      #- [preg_replace, '/:/', '\:']
+      # Strip pre-existing trailing asterisks:
+      #- [preg_replace, "/\*+$/", ""]
+    #callnumber_fuzzy:
+      #- [uppercase]
+      # Strip whitespace and quotes:
+      #- [preg_replace, '/[ "]/', ""]
+      # Escape colons (unescape first to avoid double-escapes):
+      #- [preg_replace, "/(\\\:)/", ':']
+      #- [preg_replace, '/:/', '\:']
+      # Strip pre-existing trailing asterisks, then add a new one:
+      #- [preg_replace, "/\*+$/", ""]
+      #- [append, "*"]
+  QueryFields:
+    callnumber-search:
+      - [callnumber_exact, 1000]
+      - [callnumber_fuzzy, ~]
+    dewey-search:
+      - [callnumber_exact, 1000]
+      - [callnumber_fuzzy, ~]
+
+publisher:
+  DismaxFields:
+    - publisher^100
+  QueryFields:
+    - publisher:
+      - [and, 100]
+      - [or, ~]
+
+year:
+  DismaxFields:
+    - publishDate^100
+  QueryFields:
+    - publishDate:
+      - [and, 100]
+      - [or, ~]
+
+language:
+  QueryFields:
+    - language:
+      - [and, ~]
+
+toc:
+  DismaxFields:
+    - contents^100
+  QueryFields:
+    - contents:
+      - [and, 100]
+      - [or, ~]
+
+topic:
+  QueryFields:
+    - topic:
+      - [and, 50]
+    - topic_facet:
+      - [and, ~]
+
+geographic:
+  QueryFields:
+    - geographic:
+      - [and, 50]
+    - geographic_facet:
+      - [and ~]
+
+genre:
+  QueryFields:
+    - genre:
+      - [and, 50]
+    - genre_facet:
+      - [and, ~]
+
+era:
+  QueryFields:
+    - era:
+      - [and, ~]
+
+oclc_num:
+  CustomMunge:
+    oclc_num:
+      - [preg_replace, "/[^0-9]/", ""]
+      # trim leading zeroes:
+      - [preg_replace, "/^0*/", ""]
+  QueryFields:
+    - oclc_num:
+      - [oclc_num, ~]
+      
+rvk:
+  DismaxFields:
+    - rvk_facet^100
+  QueryFields:
+    - rvk_facet:
+      - [and, 50]
+      - [or, 50]
+      
+rvk_path:
+  QueryFields:
+    - rvk_path:
+      - [onephrase, ~]
+
+multipart:
+  DismaxFields:
+    - multipart_link^100
+  QueryFields:
+    - multipart_link:
+      - [and, 50]
+      - [or, 50]  
diff --git a/local/config/vufind/FincILS.ini b/local/config/vufind/FincILS.ini
index 97cc44775e7f960081e56db570caed0d9142ed49..54c5658be2c405813eb79cb6a65c2a75c6e8e9cc 100644
--- a/local/config/vufind/FincILS.ini
+++ b/local/config/vufind/FincILS.ini
@@ -44,7 +44,6 @@
 
 ; DE-Gla 1
 ;baseUrl            = http://139.18.19.238:9080/daiatheca/daia/
-;ilsIdentifier      = "record_id"
 ;daiaIdPrefix       = "DE-Gla1:ppn:"
 ;ilsIdentifier      = "record_id"
 ;multiQuery         = true
diff --git a/local/config/vufind/HierarchyDefault.ini b/local/config/vufind/HierarchyDefault.ini
index e2b00196c47af1f367622eea42a6321af43a98b4..3c0a202431083521cedf451212a3839cfd6027f8 100644
--- a/local/config/vufind/HierarchyDefault.ini
+++ b/local/config/vufind/HierarchyDefault.ini
@@ -4,7 +4,7 @@
 ;     All  - any record with is_hierarchy set
 ;     Top  - any record where is_hierarchy = hierarchy_top
 ;     None - never link to the collection module
-link_type = "Top"
+link_type = "None"
 
 [HierarchyTree]
 ; Are hierarchy trees visible? -- true or false (default false)
diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini
index 5eb66cc7d53c87887828be085f00fbb7cafb0f79..a82829020628cf1d8dbd75389a43bb4eaf965917 100644
--- a/local/config/vufind/config.ini
+++ b/local/config/vufind/config.ini
@@ -1212,9 +1212,9 @@ HMACkey = mySuperSecretValue
 ; field of the Solr index.
 driver = Default
 ; Should we display hierarchy trees? (default = false)
-;showTree = true
+showTree = true
 ; "Search within trees" can be disabled here if set to "false" (default = true)
-search = true
+search = false
 ; You can limit the number of search results highlighted when searching the tree;
 ; a limit is recommended if you have large trees, as otherwise large numbers of
 ; results can cause performance problems.  If treeSearchLimit is -1 or not set,
@@ -1318,22 +1318,38 @@ max_tag_length = 64
 ;isil[] = "DE-15-292"
 ;bik = "952000-4"
 
-; This section contains all site related customization for finc
-;[CustomSite]
-; Combine more formats to one css class. If false first format entry will taken
-; to display icon symbol
-;combinedIcons   = false
-;namespace      = ubl
-
 ; This section contains all index related customizations for finc
-;[CustomIndex]
-; Special settings to control single instances of libaries within one vufind
-; installation.
-;indexExtension  = "de15" ; for solr index of hmt
+[CustomIndex]
+; The indexExtension allows to select library specific index fields (e.g.
+; barcode_{indexExtension}, callnumber_{indexExtension}, format_{indexExtension}
+; etc.).
+;indexExtension  = "de15"
+
 ; take general format field of Solr index. If false it takes the format fields
 ; with index extension defined above.
 ;generalFormats  = true ;for ubl & htwk it should be true
 
+; This mapping allows access to library specific Marc fields identified by the
+; library namespace (defined in localMarcFieldOfLibraryNamespace)
+localMarcFieldOfLibraryMapping[] = "ubl:969"
+localMarcFieldOfLibraryMapping[] = "hmt:970"
+localMarcFieldOfLibraryMapping[] = "che:971"
+localMarcFieldOfLibraryMapping[] = "tuf:972"
+localMarcFieldOfLibraryMapping[] = "htw:973"
+localMarcFieldOfLibraryMapping[] = "htwk:974"
+localMarcFieldOfLibraryMapping[] = "zwi:975"
+localMarcFieldOfLibraryMapping[] = "zit:976"
+localMarcFieldOfLibraryMapping[] = "hfm:977"
+localMarcFieldOfLibraryMapping[] = "hfbk:978"
+localMarcFieldOfLibraryMapping[] = "hgb:979"
+localMarcFieldOfLibraryMapping[] = "skd:983"
+localMarcFieldOfLibraryMapping[] = "slub:984"
+localMarcFieldOfLibraryMapping[] = "bas:985"
+
+; Namespace to select the correct library specific Marc field from the
+; localMarcFieldOfLibraryMapping
+;localMarcFieldOfLibraryNamespace = "ubl"
+
 ; This section configures the form for patrdon driven acquisition suggestions.
 ;[Acquisition]
 ; Email address to receive the acquisition suggestions
diff --git a/local/config/vufind/searchspecs.yaml b/local/config/vufind/searchspecs.yaml
index 52fd75dd3abb411fe66adf7216baf21d0a1bf530..498d584b19e72b391ed788ed137285df3a5880f6 100644
--- a/local/config/vufind/searchspecs.yaml
+++ b/local/config/vufind/searchspecs.yaml
@@ -155,11 +155,12 @@ Author:
   DismaxParams:
     - [bf , ord(publishDateSort)^10]
   DismaxFields:
-    - author^200
-    - author2^200
+    - author^400
+    - author2^300
     - author_id^100
     - author_ref^150
     - author_corp^200
+    - author_corp2^200
     - author_corp_ref^150
     - author_orig^200
     - author2_orig^200
@@ -182,6 +183,10 @@ Author:
       - [onephrase, 350]
       - [and, 200]
       - [or, 100]
+    - author_corp2:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
     - author_corp_ref:
       - [onephrase, 350]
       - [and, 200]
@@ -227,9 +232,9 @@ Signatur:
   DismaxParams:
     - [mm, 0]
   DismaxFields:
-    - signatur
+    - callnumber_ISIL
   QueryFields:
-    - signatur:
+    - callnumber_ISIL:
       - [or, ~]
   #    - [and, 100]
   #    - [or, ~]
@@ -238,9 +243,9 @@ Barcode:
   DismaxParams:
     - [mm, 0]
   DismaxFields:
-    - barcode
+    - barcode_ISIL
   QueryFields:
-    - barcode:
+    - barcode_ISIL:
       #- [and, 100]
       - [or, ~]
 
@@ -263,12 +268,12 @@ Subject:
       - [and, 100]
       - [or, ~]
     - topic_ref:
-      - [onephrase, 300]
-      - [and, 100]
+      - [onephrase, 100]
+      - [and, 50]
       - [or, ~]
     - topic_id:
-      - [onephrase, 300]
-      - [and, 100]
+      - [onephrase, 100]
+      - [and, 50]
       - [or, ~]
     #- geographic:
     #  - [onephrase, 300]
@@ -341,6 +346,7 @@ JournalTitle:
 
 Title:
   DismaxParams:
+    - [mm, 3]
     - [bf , ord(publishDateSort)^10]
   DismaxFields:
 #    - title_sub^200
@@ -423,9 +429,11 @@ AllFields:
   DismaxParams:
     - [mm, 3]
     - [bf , ord(publishDateSort)^10]
+    - [bf , "if(exists(query({!v='source_id:0'})),10,1)^1000"]
+#    - [bf, "if(exists(query({!v='access_facet:Local*'})),10,1)^1000"]
   DismaxFields:
-    - title_short^750
-    - title_full_unstemmed^600
+    - title_short^1000
+    - title_full_unstemmed^1000
     - title_full^400
     - title^500
     - title_alt^200
@@ -434,24 +442,22 @@ AllFields:
     - series^50
     - series2^30
     - series_orig^50
-    - author^300
-    - author_id^100
+    - author^500
     - author_corp^300
-    - author2^300
+    - author2^400
     - author_corp2^100
-    - author_fuller^150
     - author_ref^500
     - author_corp_ref^500
     - author_orig^300
     - author2_orig^300
     - author_corp_orig^300
     - author_corp2_orig^100
-    - topic_ref^500
+    - topic_ref^10
     - contents^10
-    - topic_unstemmed^550
-    - topic^500
-    - geographic^300
-    - genre^300
+    - topic_unstemmed^15
+    - topic^10
+    - geographic^10
+    - genre^10
     - rvk_label
     - allfields_unstemmed^10
     - allfields
@@ -459,16 +465,16 @@ AllFields:
     - isbn
     - issn
     - ismn
-    - rsn
+
   QueryFields:
     0:
       0:
         - OR
         - 50
       title_short:
-        - [onephrase, 750]
+        - [onephrase, 1000]
       title_full_unstemmed:
-        - [onephrase, 600]
+        - [onephrase, 1000]
         - [and, 500]
       title_full:
         - [onephrase, 400]
@@ -493,15 +499,12 @@ AllFields:
     author:
       - [onephrase, 500]
       - [and, 250]
-    author_id:
-      - [onephrase, 50]
-      - [and, 25]
     author_ref:
-      - [onephrase, 500]
+      - [onephrase, 250]
       - [and, 250]
       - [or, 250]
     author_corp_ref:
-      - [onephrase, 500]
+      - [onephrase, 250]
       - [and, 250]
       - [or, 250]
     author_orig:
@@ -524,14 +527,14 @@ AllFields:
     contents:
       - [and, 10]
     topic_unstemmed:
-      - [onephrase, 550]
-      - [and, 500]
+      - [onephrase, 55]
+      - [and, 50]
     topic:
-      - [onephrase, 500]
+      - [onephrase, 50]
     topic_ref:
-      - [onephrase, 500]
-      - [and, 250]
-      - [or, 250]
+      - [onephrase, 10]
+      - [and, 5]
+      - [or, 5]
     topic_id:
       - [onephrase, 50]
       - [and, 25]
@@ -541,12 +544,19 @@ AllFields:
       - [or, ~]
     fulltext:
       - [or, ~]
+    rvk_label:
+      - [onephrase, 500]
+      - [and, 250]
+      - [or, 250]
     isbn:
       - [onephrase, 500]
     issn:
       - [onephrase, 500]
     ismn:
       - [onephrase, 500]
+    imprint:
+      - [onephrase, 500]
+      
 #  ExactSettings:
 #    DismaxFields:
 #      - title_full_unstemmed^600
diff --git a/local/dev/config/vufind/searchspecs.yaml.sample b/local/dev/config/vufind/searchspecs.yaml.sample
new file mode 100644
index 0000000000000000000000000000000000000000..498d584b19e72b391ed788ed137285df3a5880f6
--- /dev/null
+++ b/local/dev/config/vufind/searchspecs.yaml.sample
@@ -0,0 +1,739 @@
+---
+# Listing of search types and their component parts and weights.
+#
+# Format is:
+#  searchType:
+#    # CustomMunge is an optional section to define custom pre-processing of
+#    #     user input.  See below for details of munge actions.
+#    CustomMunge:
+#      MungeName1:
+#        - [action1, actionParams]
+#        - [action2, actionParams]
+#        - [action3, actionParams]
+#      MungeName2:
+#        - [action1, actionParams]
+#    # DismaxFields is optional and defines the fields sent to the Dismax handler
+#    #     when we are able to use it.  QueryFields will be used for advanced
+#    #     searches that Dismax cannot support.  QueryFields is always used if no
+#    #     DismaxFields section is defined.
+#    DismaxFields:
+#      - field1^boost
+#      - field2^boost
+#      - field3^boost
+#    # DismaxParams is optional and allows you to override default Dismax settings
+#    #     (i.e. mm / bf) on a search-by-search basis. Enclose the parameter values
+#    #     in quotes for proper behavior. If you want global default values for these
+#    #     settings, you can edit the appropriate search handler in
+#    #     solr/biblio/conf/solrconfig.xml.
+#    DismaxParams:
+#      - [param1_name, param1_value]
+#      - [param2_name, param2_value]
+#      - [param3_name, param3_value]
+#    # This optional setting may be used to specify which Dismax handler to use. By
+#    #     default, VuFind provides two options: dismax (for the old, standard
+#    #     Dismax) and edismax (for Extended Dismax). You can also configure your own
+#    #     in solrconfig.xml, but VuFind relies on the name "edismax" to identify an
+#    #     Extended Dismax handler. If you omit this setting, the default value from
+#    #     the default_dismax_handler setting in the [Index] section of config.ini
+#    #     will be used.
+#    DismaxHandler: dismax|edismax
+#    # QueryFields define the fields we are searching when not using Dismax; VuFind
+#    #     detects queries that will not work with Dismax and switches to QueryFields
+#    #     as needed.
+#    QueryFields:
+#      SolrField:
+#        - [howToMungeSearchstring, weight]
+#        - [differentMunge, weight]
+#      DifferentSolrField:
+#        - [howToMunge, weight]
+#    # The optional FilterQuery section allows you to AND a static query to the
+#    #     dynamic query generated using the QueryFields; see JournalTitle below
+#    #     for an example.  This is applied whether we use DismaxFields or
+#    #     QueryFields.
+#    FilterQuery: (optional Lucene filter query)
+#    ExactSettings:
+#      DismaxFields: ...
+#      QueryFields: ...
+#    # All the same settings as above, but for exact searches, i.e. search terms
+#    #     enclosed in quotes. Allows different fields or weights for exact
+#    #     searches. See below for commented-out examples.
+#
+# ...etc.
+#
+#-----------------------------------------------------------------------------------
+#
+# Within the QueryFields area, fields are OR'd together, unless they're in an
+# anonymous array with a numeric instead of alphanumeric key, in which case the
+# first element is a two-value array that tells us what the type (AND or OR) and
+# weight of the whole group should be.
+#
+# So, given:
+#
+# test:
+#   QueryFields:
+#     A:
+#       - [onephrase, 500]
+#       - [and, 200]
+#     B:
+#       - [and, 100]
+#       - [or, 50]
+#     # Start an anonymous array to group; first element indicates AND grouping
+#     #     and a weight of 50
+#     0:
+#       0:
+#         - AND
+#         - 50
+#       C:
+#         - [onephrase, 200]
+#       D:
+#         - [onephrase, 300]
+#       # Note the "not" attached to the field name as a minus, and the use of ~
+#       #     to mean null ("no special weight")
+#       -E:
+#         - [or, ~]
+#     D:
+#       - [or, 100]
+#
+#  ...and the search string
+#
+#      test "one two"
+#
+#  ...we'd get
+#
+#   (A:"test one two"^500 OR
+#    A:(test AND "one two")^ 200 OR
+#    B:(test AND "one two")^100 OR
+#    B:(test OR "one two")^50
+#    (
+#      C:("test one two")^200 AND
+#      D:"test one two"^300 AND
+#      -E:(test OR "one two")
+#    )^50 OR
+#    D:(test OR "one two")^100
+#   )
+#
+#-----------------------------------------------------------------------------------
+#
+# Munge types are based on the original Solr.php code, and consist of:
+#
+# onephrase: eliminate all quotes and do it as a single phrase. 
+#   testing "one two"
+#    ...becomes ("testing one two")
+#
+# and: AND the terms together
+#  testing "one two"
+#   ...becomes (testing AND "one two")
+#
+# or: OR the terms together
+#  testing "one two"
+#   ...becomes (testing OR "one two")
+#
+# identity: Use the search as-is
+#  testing "one two"
+#   ...becomes (testing "one two")
+#
+# Additional Munge types can be defined in the CustomMunge section.  Each array
+# entry under CustomMunge defines a new named munge type.  Each array entry under
+# the name of the munge type specifies a string manipulation operation.  Operations
+# will be applied in the order listed, and different operations take different
+# numbers of parameters.
+#
+# Munge operations:
+#
+# [append, text] - Append text to the end of the user's search string
+# [lowercase] - Convert string to lowercase
+# [preg_replace, pattern, replacement] - Perform a regular expression replace
+#     using the preg_replace() PHP function.  If you use backreferences in your
+#     replacement phrase, be sure to escape dollar signs (i.e. \$1, not $1).
+# [uppercase] - Convert string to uppercase
+#
+# See the CallNumber search below for an example of custom munging in action.
+#-----------------------------------------------------------------------------------
+
+# These searches use Dismax when possible:
+Author:
+  DismaxParams:
+    - [bf , ord(publishDateSort)^10]
+  DismaxFields:
+    - author^400
+    - author2^300
+    - author_id^100
+    - author_ref^150
+    - author_corp^200
+    - author_corp2^200
+    - author_corp_ref^150
+    - author_orig^200
+    - author2_orig^200
+    - author_corp_orig^200
+    - author_corp2_orig^200
+  QueryFields:
+    - author:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author2:
+      - [onephrase, 100]
+      - [and, 50]
+      - [or, ~]
+    - author_ref:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp2:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp_ref:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author2_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_corp2_orig:
+      - [onephrase, 350]
+      - [and, 200]
+      - [or, 100]
+    - author_id:
+      - [onephrase, 450]
+      - [and, 300]
+      - [or, 200]
+
+ISN:
+#  DismaxFields:
+#    - isbn
+#    - issn
+#    - ismn
+  QueryFields:
+    - issn:
+      - [and, 100]
+      - [or, ~]
+    - isbn:
+      - [and, 100]
+      - [or, ~]
+    - ismn:
+      - [and, 100]
+      - [or, ~]
+
+Signatur:
+  DismaxParams:
+    - [mm, 0]
+  DismaxFields:
+    - callnumber_ISIL
+  QueryFields:
+    - callnumber_ISIL:
+      - [or, ~]
+  #    - [and, 100]
+  #    - [or, ~]
+
+Barcode:
+  DismaxParams:
+    - [mm, 0]
+  DismaxFields:
+    - barcode_ISIL
+  QueryFields:
+    - barcode_ISIL:
+      #- [and, 100]
+      - [or, ~]
+
+Subject:
+  DismaxFields:
+    - topic_unstemmed^150
+    - topic^100
+    - topic_id^100
+    - topic_ref^100
+    #- geographic^50
+    #- genre^50
+    #- era
+  QueryFields:
+    - topic_unstemmed:
+      - [onephrase, 350]
+      - [and, 150]
+      - [or, ~]
+    - topic:
+      - [onephrase, 300]
+      - [and, 100]
+      - [or, ~]
+    - topic_ref:
+      - [onephrase, 100]
+      - [and, 50]
+      - [or, ~]
+    - topic_id:
+      - [onephrase, 100]
+      - [and, 50]
+      - [or, ~]
+    #- geographic:
+    #  - [onephrase, 300]
+    #  - [and, 100]
+    #  - [or, ~]
+    #- genre:
+    #  - [onephrase, 300]
+    #  - [and, 100]
+    #  - [or, ~]
+    #- era:
+    #  - [and, 100]
+    #  - [or, ~]
+#  ExactSettings:
+#    DismaxFields:
+#      - topic_unstemmed^150
+#    QueryFields:
+#      - topic_unstemmed:
+#        - [onephrase, 350]
+#        - [and, 150]
+#        - [or, ~]
+
+# This field definition is a compromise that supports both journal-level and
+# article-level data.  The disadvantage is that hits in article titles will
+# be mixed in.  If you are building a purely article-oriented index, you should
+# customize this to remove all of the title_* fields and focus entirely on the
+# container_title field.
+JournalTitle:
+  DismaxFields:
+    - title_short^500
+    - title_full_unstemmed^450
+    - title_full^400
+    - title^300
+    - title_alt^200
+    - title_new^100
+    - title_old
+    - series^100
+    - series2
+  QueryFields:
+    - title_short:
+      - [onephrase, 500]
+    - title_full_unstemmed:
+      - [onephrase, 450]
+      - [and, 400]
+    - title_full:
+      - [onephrase, 400]
+    - title:
+      - [onephrase, 300]
+      - [and, 250]
+    - title_alt:
+      - [and, 200]
+    - title_new:
+      - [and, 100]
+    - title_old:
+      - [and, ~]  
+    - series:
+      - [onephrase, 100]
+      - [and, 50]
+    - series2:
+      - [onephrase, 50]
+      - [and , ~]
+  FilterQuery: "format:Journal"
+#  ExactSettings:
+#    DismaxFields:
+#      - title_full_unstemmed^450
+#    QueryFields:
+#      - title_full_unstemmed:
+#        - [onephrase, 450]
+#        - [and, 400]
+#    FilterQuery: "format:Journal OR format:Article"
+
+Title:
+  DismaxParams:
+    - [mm, 3]
+    - [bf , ord(publishDateSort)^10]
+  DismaxFields:
+#    - title_sub^200
+#    - title_short^300
+    - title_full_unstemmed^150
+    - title_full^100
+    - title^900
+    - title_alt^200
+    - title_new^100
+    - title_old
+    - title_orig^400
+    - series^100
+    - series2
+    - series_orig^100
+  QueryFields:
+    - title_short:
+      - [onephrase, 500]
+    - title_full_unstemmed:
+      - [onephrase, 150]
+      - [and, 100]
+    - title_full:
+      - [onephrase, 100]
+    - title:
+      - [onephrase, 300]
+      - [and, 250]
+    - title_alt:
+      - [and, 200]
+    - title_new:
+      - [and, 100]
+    - title_old:
+      - [and, ~]
+    - title_orig:
+      - [onephrase, 500]
+      - [and, 200]
+    - series:
+      - [onephrase, 100]
+      - [and, 50]
+    - series2:
+      - [onephrase, 50]
+      - [and , ~]
+    - series_orig:
+      - [onephrase, 100]
+      - [and, 50]
+#  ExactSettings:
+#    DismaxFields:
+#      - title_full_unstemmed^450
+#    QueryFields:
+#      - title_full_unstemmed:
+#        - [onephrase, 450]
+#        - [and, 400]
+
+Series:
+  DismaxFields:
+    - series^100
+    - series2
+    - series_orig^100
+  QueryFields:
+    - series:
+      - [onephrase, 500]
+      - [and, 200]
+      - [or, 100]
+    - series2:
+      - [onephrase, 50]
+      - [and, 50]
+      - [or, ~]
+    - series_orig:
+      - [onephrase, 500]
+      - [and, 200]
+      - [or, 100]
+
+Series2:
+  DismaxFields:
+    - series2
+  QueryFields:
+    - series2:
+      - [onephrase, 200]
+      - [and, 50]
+
+AllFields:
+  DismaxParams:
+    - [mm, 3]
+    - [bf , ord(publishDateSort)^10]
+    - [bf , "if(exists(query({!v='source_id:0'})),10,1)^1000"]
+#    - [bf, "if(exists(query({!v='access_facet:Local*'})),10,1)^1000"]
+  DismaxFields:
+    - title_short^1000
+    - title_full_unstemmed^1000
+    - title_full^400
+    - title^500
+    - title_alt^200
+    - title_new^100
+    - title_orig^500
+    - series^50
+    - series2^30
+    - series_orig^50
+    - author^500
+    - author_corp^300
+    - author2^400
+    - author_corp2^100
+    - author_ref^500
+    - author_corp_ref^500
+    - author_orig^300
+    - author2_orig^300
+    - author_corp_orig^300
+    - author_corp2_orig^100
+    - topic_ref^10
+    - contents^10
+    - topic_unstemmed^15
+    - topic^10
+    - geographic^10
+    - genre^10
+    - rvk_label
+    - allfields_unstemmed^10
+    - allfields
+    - fulltext
+    - isbn
+    - issn
+    - ismn
+
+  QueryFields:
+    0:
+      0:
+        - OR
+        - 50
+      title_short:
+        - [onephrase, 1000]
+      title_full_unstemmed:
+        - [onephrase, 1000]
+        - [and, 500]
+      title_full:
+        - [onephrase, 400]
+      title:
+        - [onephrase, 300]
+        - [and, 250]
+      title_alt:
+        - [and, 200]
+      title_new:
+        - [and, 100]
+      title_orig:
+        - [onephrase, 500]
+        - [and, 400]
+    series:
+      - [onephrase, 300]
+      - [and, 100]
+    series2:
+      - [and, 30]
+    series_orig:
+      - [onephrase, 200]
+      - [and, 100]
+    author:
+      - [onephrase, 500]
+      - [and, 250]
+    author_ref:
+      - [onephrase, 250]
+      - [and, 250]
+      - [or, 250]
+    author_corp_ref:
+      - [onephrase, 250]
+      - [and, 250]
+      - [or, 250]
+    author_orig:
+      - [onephrase, 500]
+      - [and, 250]
+    author2_orig:
+      - [and, 50]
+    author_corp_orig:
+      - [onephrase, 500]
+      - [and, 400]
+    author_corp2_orig:
+      - [and, 50]
+    author_corp:
+      - [onephrase, 500]
+      - [and, 400]
+    author2:
+      - [and, 50]
+    author_corp2:
+      - [and, 50]
+    contents:
+      - [and, 10]
+    topic_unstemmed:
+      - [onephrase, 55]
+      - [and, 50]
+    topic:
+      - [onephrase, 50]
+    topic_ref:
+      - [onephrase, 10]
+      - [and, 5]
+      - [or, 5]
+    topic_id:
+      - [onephrase, 50]
+      - [and, 25]
+    allfields_unstemmed:
+      - [or, 10]
+    allfields:
+      - [or, ~]
+    fulltext:
+      - [or, ~]
+    rvk_label:
+      - [onephrase, 500]
+      - [and, 250]
+      - [or, 250]
+    isbn:
+      - [onephrase, 500]
+    issn:
+      - [onephrase, 500]
+    ismn:
+      - [onephrase, 500]
+    imprint:
+      - [onephrase, 500]
+      
+#  ExactSettings:
+#    DismaxFields:
+#      - title_full_unstemmed^600
+#      - topic_unstemmed^550
+#      - allfields_unstemmed^10
+#      - fulltext_unstemmed^10
+#      - isbn
+#      - issn
+#    QueryFields:
+#      title_full_unstemmed:
+#        - [onephrase, 600]
+#        - [and, 500]
+#      topic_unstemmed:
+#        - [onephrase, 550]
+#        - [and, 500]
+#      allfields_unstemmed:
+#        - [or, 10]
+#      fulltext_unstemmed:
+#        - [or, 10]
+#      isbn:
+#        - [onephrase, ~]
+#      issn:
+#        - [onephrase, ~]
+
+# These are advanced searches that never use Dismax:
+id:
+  QueryFields:
+    - id:
+      - [onephrase, ~]
+
+# Fields for exact matches originating from alphabetic browse
+ids:
+  QueryFields:
+    - id:
+      - [or, ~]
+
+TopicBrowse:
+  QueryFields:
+    - topic_browse:
+      - [onephrase, ~]
+
+AuthorBrowse:
+  QueryFields:
+    - author_browse:
+      - [onephrase, ~]
+
+TitleBrowse:
+  QueryFields:
+    - title_full:
+      - [onephrase, ~]
+
+DeweyBrowse:
+  QueryFields:
+    - dewey-raw:
+      - [onephrase, ~]
+
+LccBrowse:
+  QueryFields:
+    - callnumber-a:
+      - [onephrase, ~]
+
+
+
+# CallNumber:
+  # We use two similar munges here -- one for exact matches, which will get
+  # a very high boost factor, and one for left-anchored wildcard searches,
+  # which will return a larger number of hits at a lower boost.
+  #CustomMunge:
+    #callnumber_exact:
+      #- [uppercase]
+      # Strip whitespace and quotes:
+      #- [preg_replace, '/[ "]/', ""]
+      # Escape colons (unescape first to avoid double-escapes):
+      #- [preg_replace, "/(\\\:)/", ':']
+      #- [preg_replace, '/:/', '\:']
+      # Strip pre-existing trailing asterisks:
+      #- [preg_replace, "/\*+$/", ""]
+    #callnumber_fuzzy:
+      #- [uppercase]
+      # Strip whitespace and quotes:
+      #- [preg_replace, '/[ "]/', ""]
+      # Escape colons (unescape first to avoid double-escapes):
+      #- [preg_replace, "/(\\\:)/", ':']
+      #- [preg_replace, '/:/', '\:']
+      # Strip pre-existing trailing asterisks, then add a new one:
+      #- [preg_replace, "/\*+$/", ""]
+      #- [append, "*"]
+  QueryFields:
+    callnumber-search:
+      - [callnumber_exact, 1000]
+      - [callnumber_fuzzy, ~]
+    dewey-search:
+      - [callnumber_exact, 1000]
+      - [callnumber_fuzzy, ~]
+
+publisher:
+  DismaxFields:
+    - publisher^100
+  QueryFields:
+    - publisher:
+      - [and, 100]
+      - [or, ~]
+
+year:
+  DismaxFields:
+    - publishDate^100
+  QueryFields:
+    - publishDate:
+      - [and, 100]
+      - [or, ~]
+
+language:
+  QueryFields:
+    - language:
+      - [and, ~]
+
+toc:
+  DismaxFields:
+    - contents^100
+  QueryFields:
+    - contents:
+      - [and, 100]
+      - [or, ~]
+
+topic:
+  QueryFields:
+    - topic:
+      - [and, 50]
+    - topic_facet:
+      - [and, ~]
+
+geographic:
+  QueryFields:
+    - geographic:
+      - [and, 50]
+    - geographic_facet:
+      - [and ~]
+
+genre:
+  QueryFields:
+    - genre:
+      - [and, 50]
+    - genre_facet:
+      - [and, ~]
+
+era:
+  QueryFields:
+    - era:
+      - [and, ~]
+
+oclc_num:
+  CustomMunge:
+    oclc_num:
+      - [preg_replace, "/[^0-9]/", ""]
+      # trim leading zeroes:
+      - [preg_replace, "/^0*/", ""]
+  QueryFields:
+    - oclc_num:
+      - [oclc_num, ~]
+      
+rvk:
+  DismaxFields:
+    - rvk_facet^100
+  QueryFields:
+    - rvk_facet:
+      - [and, 50]
+      - [or, 50]
+      
+rvk_path:
+  QueryFields:
+    - rvk_path:
+      - [onephrase, ~]
+
+multipart:
+  DismaxFields:
+    - multipart_link^100
+  QueryFields:
+    - multipart_link:
+      - [and, 50]
+      - [or, 50]  
diff --git a/local/languages/de.ini b/local/languages/de.ini
index 3efd85b389af925eef3a3289f53526793e0a5ffe..3881f0e818b832a676d9fe69bdbfbdd7c78a9a40 100644
--- a/local/languages/de.ini
+++ b/local/languages/de.ini
@@ -252,7 +252,6 @@ Close = "Schließen"
 Code = Fehlercode
 Collection mode = ""
 Comment = "Kommentar"
-Comments = Lesermeinungen
 combined search (OR) = "Kombinierte Suche (OR)"
 Confirm = Bestätigen
 Confirm with your password = "Bestätigen Sie mit Ihrem Passwort"
diff --git a/module/finc/config/module.config.php b/module/finc/config/module.config.php
index 80cd4926de58e8bc18b75a4794107085dcab48a4..178586187b7814c13843e7e407c1d345348c345a 100644
--- a/module/finc/config/module.config.php
+++ b/module/finc/config/module.config.php
@@ -17,6 +17,7 @@ $config = [
             'ils_driver' => [
                 'factories' => [
                     'fincils' => 'finc\ILS\Driver\Factory::getFincILS',
+                    'daia' => 'finc\ILS\Driver\Factory::getDAIA',
                     'paia' => 'finc\ILS\Driver\Factory::getPAIA',
                 ],
             ],
diff --git a/module/finc/src/finc/ILS/Driver/DAIA.php b/module/finc/src/finc/ILS/Driver/DAIA.php
new file mode 100644
index 0000000000000000000000000000000000000000..30bf450ded0b0490c72ff382db211ba89f43ad6b
--- /dev/null
+++ b/module/finc/src/finc/ILS/Driver/DAIA.php
@@ -0,0 +1,283 @@
+<?php
+/**
+ * ILS Driver for VuFind to query availability information via DAIA.
+ *
+ * Based on the proof-of-concept-driver by Till Kinstler, GBV.
+ * Relaunch of the daia driver developed by Oliver Goldschmidt.
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Jochen Lienhard 2014.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  ILS_Drivers
+ * @author   Jochen Lienhard <lienhard@ub.uni-freiburg.de>
+ * @author   Oliver Goldschmidt <o.goldschmidt@tu-harburg.de>
+ * @author   André Lahmann <lahmann@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:building_an_ils_driver Wiki
+ */
+namespace finc\ILS\Driver;
+
+/**
+ * ILS Driver for VuFind to query availability information via DAIA.
+ *
+ * @category VuFind2
+ * @package  ILS_Drivers
+ * @author   Jochen Lienhard <lienhard@ub.uni-freiburg.de>
+ * @author   Oliver Goldschmidt <o.goldschmidt@tu-harburg.de>
+ * @author   André Lahmann <lahmann@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:building_an_ils_driver Wiki
+ */
+class DAIA extends \VuFind\ILS\Driver\DAIA
+{
+
+    /**
+     * Parse an array with DAIA status information.
+     *
+     * @param string $id        Record id for the DAIA array.
+     * @param array  $daiaArray Array with raw DAIA status information.
+     *
+     * @return array            Array with VuFind compatible status information.
+     */
+    protected function parseDaiaArray($id, $daiaArray)
+    {
+        $doc_id = null;
+        $doc_href = null;
+        if (array_key_exists('id', $daiaArray)) {
+            $doc_id = $daiaArray['id'];
+        }
+        if (array_key_exists('href', $daiaArray)) {
+            // url of the document (not needed for VuFind)
+            $doc_href = $daiaArray['href'];
+        }
+        if (array_key_exists('message', $daiaArray)) {
+            // log messages for debugging
+            $this->logMessages($daiaArray['message'], 'document');
+        }
+        // if one or more items exist, iterate and build result-item
+        if (array_key_exists('item', $daiaArray)) {
+            $number = 0;
+            foreach ($daiaArray['item'] as $item) {
+                $result_item = [];
+                $result_item['id'] = $id;
+                $result_item['item_id'] = $item['id'];
+                // custom DAIA field used in getHoldLink()
+                $result_item['ilslink']
+                    = (isset($item['href']) ? $item['href'] : $doc_href);
+                // count items
+                $number++;
+                $result_item['number'] = $this->getItemNumber($item, $number);
+                // set default value for barcode
+                $result_item['barcode'] = $this->getItemBarcode($item);
+                // set default value for reserve
+                $result_item['reserve'] = $this->getItemReserveStatus($item);
+                // get callnumber
+                $result_item['callnumber'] = $this->getItemCallnumber($item);
+                // get location
+                $result_item['location'] = $this->getItemLocation($item);
+                // get location link
+                $result_item['locationhref'] = $this->getItemLocationLink($item);
+                // get location
+                $result_item['storage'] = $this->getItemStorage($item);
+                // status and availability will be calculated in own function
+                $result_item = $this->getItemStatus($item) + $result_item;
+                // add result_item to the result array
+                $result[] = $result_item;
+            } // end iteration on item
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns an array with status information for provided item.
+     *
+     * @param array $item Array with DAIA item data
+     *
+     * @return array
+     */
+    protected function getItemStatus($item)
+    {
+        $availability = false;
+        $status = ''; // status cannot be null as this will crash the translator
+        $duedate = null;
+        $availableLink = '';
+        $queue = '';
+        $notes = [];
+        if (array_key_exists('available', $item)) {
+            // check if item is loanable or presentation
+            foreach ($item['available'] as $available) {
+                // attribute service can be set once or not
+                if (isset($available['service'])
+                    && in_array(
+                        $available['service'],
+                        ['loan', 'presentation', 'openaccess']
+                    )
+                ) {
+                    // set item available if service is loan, presentation or
+                    // openaccess
+                    $availability = true;
+                    if ($available['service'] == 'loan'
+                        && isset($available['service']['href'])
+                    ) {
+                        // save the link to the ils if we have a href for loan
+                        // service
+                        $availableLink = $available['service']['href'];
+                    }
+                }
+
+                // use limitation element for status string
+                if (isset($available['limitation'])) {
+                    $notes = array_merge($notes, $this->getItemLimitation($available['limitation']));
+                }
+
+                // log messages for debugging
+                if (isset($available['message'])) {
+                    $this->logMessages($available['message'], 'item->available');
+                }
+            }
+        }
+        if (array_key_exists('unavailable', $item)) {
+            foreach ($item['unavailable'] as $unavailable) {
+                // attribute service can be set once or not
+                if (isset($unavailable['service'])
+                    && in_array(
+                        $unavailable['service'],
+                        ['loan', 'presentation', 'openaccess']
+                    )
+                ) {
+                    if ($unavailable['service'] == 'loan'
+                        && isset($unavailable['service']['href'])
+                    ) {
+                        //save the link to the ils if we have a href for loan service
+                    }
+
+                    // use limitation element for status string
+                    if (isset($unavailable['limitation'])) {
+                        $notes = array_merge($notes, $this
+                            ->getItemLimitation($unavailable['limitation']));
+                    }
+                }
+                // attribute expected is mandatory for unavailable element
+                if (isset($unavailable['expected'])) {
+                    try {
+                        $duedate = $this->dateConverter
+                            ->convertToDisplayDate(
+                                'Y-m-d', $unavailable['expected']
+                            );
+                    } catch (\Exception $e) {
+                        $this->debug('Date conversion failed: ' . $e->getMessage());
+                        $duedate = null;
+                    }
+                }
+
+                // attribute queue can be set
+                if (isset($unavailable['queue'])) {
+                    $queue = $unavailable['queue'];
+                }
+
+                // log messages for debugging
+                if (isset($unavailable['message'])) {
+                    $this->logMessages($unavailable['message'], 'item->unavailable');
+                }
+            }
+        }
+
+        /*'availability' => '0',
+        'status' => '',  // string - needs to be computed from availability info
+        'duedate' => '', // if checked_out else null
+        'returnDate' => '', // false if not recently returned(?)
+        'requests_placed' => '', // total number of placed holds
+        'is_holdable' => false, // place holding possible?*/
+
+        if (!empty($availableLink)) {
+            $return['ilslink'] = $availableLink;
+        }
+
+        $return['notes']           = $notes;
+        $return['status']          = $status;
+        $return['availability']    = $availability;
+        $return['duedate']         = $duedate;
+        $return['requests_placed'] = $queue;
+
+        return $return;
+    }
+
+    /**
+     * Returns the evaluated value of the provided limitation element
+     *
+     * @param array $limitations Array with DAIA limitation data
+     *
+     * @return array
+     */
+    protected function getItemLimitation($limitations)
+    {
+        $itemLimitation = [];
+        foreach ($limitations as $limitation) {
+            // return the first limitation with content set
+            if (isset($limitation['content'])) {
+                $itemLimitation[] = $limitation['content'];
+            }
+        }
+        return $itemLimitation;
+    }
+
+    /**
+     * Returns the value for "location" in VuFind getStatus/getHolding array
+     *
+     * @param array $item Array with DAIA item data
+     *
+     * @return string
+     */
+    protected function getItemLocation($item)
+    {
+        $location = '';
+
+        if (isset($item['department'])
+            && isset($item['department']['content'])
+        ) {
+            $location .= (empty($location)
+                ? $item['department']['content']
+                : ' - ' . $item['department']['content']);
+        }
+
+        return (empty($location) ? 'Unknown' : $location);
+    }
+
+    /**
+     * Returns the value for "location" in VuFind getStatus/getHolding array
+     *
+     * @param array $item Array with DAIA item data
+     *
+     * @return string
+     */
+    protected function getItemStorage($item)
+    {
+        $storage = '';
+
+        if (isset($item['storage'])
+            && isset($item['storage']['content'])
+        ) {
+            $storage .= (empty($storage)
+                ? $item['storage']['content']
+                : ' - ' . $item['storage']['content']);
+        }
+
+        return (empty($storage) ? 'Unknown' : $storage);
+    }
+}
diff --git a/module/finc/src/finc/ILS/Driver/FincILS.php b/module/finc/src/finc/ILS/Driver/FincILS.php
index 6d762837a0cffda3f4af1bfa8987a8ad786f45d2..7a3cdb66a60b9a5c21b4479cd4d4b8d5c5695dc1 100644
--- a/module/finc/src/finc/ILS/Driver/FincILS.php
+++ b/module/finc/src/finc/ILS/Driver/FincILS.php
@@ -233,7 +233,7 @@ class FincILS extends PAIA implements LoggerAwareInterface
 
             // if we already have a session with access_token and patron id, try to get
             // patron info with session data
-            if (isset($this->session->expires) && microtime() < $this->session->expires) {
+            if (isset($this->session->expires) && $this->session->expires > time()) {
                 try {
                     return $enrichUserDetails(
                         $this->paiaGetUserDetails(($this->session->patron === 'root' ? $username : $this->session->patron)),
@@ -304,9 +304,9 @@ class FincILS extends PAIA implements LoggerAwareInterface
                             case 'regex' :
                                 // check regex filters
                                 $regexCounter = 0;
-                                foreach ($filterValue as $regexKey => $regexValue) {
-                                    if (!(isset($doc[$regexKey])
-                                        && preg_match($regexValue, $doc[$regexKey]))
+                                foreach ($filterValue as $regexField => $regexPattern) {
+                                    if (isset($doc[$regexField])
+                                        && preg_match($regexPattern, $doc[$regexField]) === 1
                                     ) {
                                         $regexCounter++;
                                     }
@@ -341,6 +341,69 @@ class FincILS extends PAIA implements LoggerAwareInterface
         return [];
     }
 
+    /**
+     * PAIA helper function to allow customization of mapping from PAIA response to
+     * VuFind ILS-method return values.
+     *
+     * @param array  $items   Array of PAIA items to be mapped
+     * @param string $mapping String identifying a custom mapping-method
+     *
+     * @return array
+     */
+    protected function mapPaiaItems($items, $mapping)
+    {
+        return $this->postprocessPaiaItems(
+            parent::mapPaiaItems($items, $mapping)
+        );
+    }
+
+    /**
+     * Helper function to postprocess the PAIA items for display in catalog (e.g. retrieve
+     * fincid etc.).
+     *
+     * @param array $items Array of PAIA items to be postprocessed
+     *
+     * @return mixed
+     */
+    protected function postprocessPaiaItems($items)
+    {
+        // regex pattern for item_id (e.g. UBL:barcode:0008911555)
+        $idPattern = '/^([]A-Za-z0-9_\-]*):(%s):(.*)$/';
+
+        // item_id identifier - Solr field mapping
+        $identifier = [
+            'barcode' => 'barcode' .
+                (isset($this->mainConfig->CustomIndex->indexExtension)
+                    ? '_'.$this->mainConfig->CustomIndex->indexExtension : ''),
+            'fincid'  => 'id',
+            'ppn'     => 'record_id'
+        ];
+
+        // try item_id with defined regex pattern and identifiers and use Solr to
+        // retrieve fincid on match
+        $ilsIdentifier = function ($itemId) use ($identifier, $idPattern) {
+            foreach ($identifier as $key => $value) {
+                $matches = [];
+                if (preg_match(sprintf($idPattern, $key), $itemId, $matches)) {
+                    return $this->_getFincId($matches[3], $value);
+                }
+            }
+        };
+
+        // iterate trough given items
+        foreach ($items as &$item) {
+            if (isset($item['id']) && empty($item['id']) && !empty($item['item_id'])) {
+                $ilsId = $ilsIdentifier($item['item_id']);
+                if ($ilsId != null) {
+                    $item['id'] = $ilsId;
+                    $item['source'] = 'Solr';
+                }
+            }
+        }
+
+        return $items;
+    }
+
     /**
      * Get the Record-Object from the RecordDriver.
      *
@@ -435,12 +498,18 @@ class FincILS extends PAIA implements LoggerAwareInterface
     /**
      * Get the identifier for the record which will be used for ILS interaction
      *
-     * @param string $id Document to look up.
+     * @param string $id            Document to look up.
+     * @param string $ilsIdentifier Identifier to override config settings.
      *
      * @return string $ilsRecordId
      */
-    private function _getILSRecordId($id)
+    private function _getILSRecordId($id, $ilsIdentifier = null)
     {
+        // override ilsIdentifier set in ILS driver config
+        if ($ilsIdentifier != null) {
+            $this->ilsIdentifier = $ilsIdentifier;
+        }
+
         //get the ILS-specific recordId
         if ($this->ilsIdentifier != "default") {
 
@@ -488,17 +557,18 @@ class FincILS extends PAIA implements LoggerAwareInterface
     /**
      * Get the identifiers for multiple records
      *
-     * @param array $ids Documents to look up.
+     * @param array  $ids           Documents to look up.
+     * @param string $ilsIdentifier Identifier to override config settings.
      *
      * @return array $ilsRecordIds
      */
-    private function _getILSRecordIds($ids)
+    private function _getILSRecordIds($ids, $ilsIdentifier = null)
     {
         $ilsRecordIds = [];
 
         if (is_array($ids)) {
             foreach ($ids as $id) {
-                $ilsRecordIds[] = $this->_getILSRecordId($id);
+                $ilsRecordIds[] = $this->_getILSRecordId($id, $ilsIdentifier);
             }
 
             return $ilsRecordIds;
@@ -510,12 +580,18 @@ class FincILS extends PAIA implements LoggerAwareInterface
     /**
      * Get the finc id of the record with the given ilsIdentifier value
      *
-     * @param string $ilsId Document to look up.
+     * @param string $ilsId         Document to look up.
+     * @param string $ilsIdentifier Identifier to override config settings.
      *
      * @return string $fincId if ilsIdentifier is configured, otherwise $ilsId
      */
-    private function _getFincId($ilsId)
+    private function _getFincId($ilsId, $ilsIdentifier = null)
     {
+        // override ilsIdentifier set in ILS driver config
+        if ($ilsIdentifier != null) {
+            $this->ilsIdentifier = $ilsIdentifier;
+        }
+
         if ($this->ilsIdentifier != "default") {
             // different ilsIdentifier is configured, retrieve fincid
             try {
diff --git a/module/finc/src/finc/ILS/Driver/PAIA.php b/module/finc/src/finc/ILS/Driver/PAIA.php
index 2cde98d7e2a29a7689d3c9027f2ca264060a3017..29b4aafe98db67f28b944542e3cca72b7acd2ef4 100644
--- a/module/finc/src/finc/ILS/Driver/PAIA.php
+++ b/module/finc/src/finc/ILS/Driver/PAIA.php
@@ -51,7 +51,7 @@ use VuFind\Exception\ILS as ILSException,
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://vufind.org/wiki/building_an_ils_driver Wiki
  */
-class PAIA extends \VuFind\ILS\Driver\DAIA implements
+class PAIA extends DAIA implements
     HttpServiceAwareInterface, LoggerAwareInterface
 {
     use \VuFindHttp\HttpServiceAwareTrait;
@@ -608,9 +608,7 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
 
         // if we already have a session with access_token and patron id, try to get
         // patron info with session data
-        if (isset($this->session->expires)
-            && microtime() < $this->session->expires
-        ) {
+        if (isset($this->session->expires) && $this->session->expires > time()) {
             try {
                 return $enrichUserDetails(
                     $this->paiaGetUserDetails($this->session->patron),
@@ -962,6 +960,9 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
             // about (0..1) textual description of the document
             $result['title'] = (isset($doc['about']) ? $doc['about'] : null);
 
+            // label (0..1) call number, shelf mark or similar item label
+            $result['callnumber'] = (isset($doc['label']) ? $doc['label'] : null); // PAIA custom field
+
             if (in_array($doc['status'], [1, 2])) {
                 // status == 1 => starttime: when the document was reserved
                 // status == 2 => starttime: when the document was ordered
@@ -978,6 +979,7 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
                 $result['available'] = true;
             }
 
+            // Optional VuFind fields
             /*
             $result['reqnum'] = null;
             $result['volume'] =  null;
@@ -988,9 +990,6 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
             $result['upc'] = null;
             */
 
-            //'message'        => $loans_response['doc'][$i]['label'],
-            //'callnumber'     => $loans_response['doc'][$i]['label'],
-
             $results[] = $result;
 
         }
@@ -1033,9 +1032,6 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
             // about (0..1) textual description of the document
             $result['title'] = (isset($doc['about']) ? $doc['about'] : null);
 
-            // label (0..1) call number, shelf mark or similar item label
-            $result['barcode'] = (isset($doc['label']) ? $doc['label'] : null);
-
             // queue (0..1) number of waiting requests for the document or item
             $result['request'] = (isset($doc['queue']) ? $doc['queue'] : null);
 
@@ -1067,7 +1063,12 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
 
             // storageid (0..1) location URI
 
+            // label (0..1) call number, shelf mark or similar item label
+            $result['callnumber'] = (isset($doc['label']) ? $doc['label'] : null); // PAIA custom field
+
+            // Optional VuFind fields
             /*
+            $result['barcode'] = null;
             $result['dueStatus'] = null;
             $result['renewLimit'] = "1";
             $result['volume'] = null;
@@ -1292,8 +1293,8 @@ class PAIA extends \VuFind\ILS\Driver\DAIA implements
                 = isset($responseArray['scope'])
                     ? explode(' ', $responseArray['scope']) : null;
             $this->session->expires
-                = isset($responseArray['expires'])
-                    ? (microtime() + ($responseArray['expires']*1000)) : null;
+                = isset($responseArray['expires_in'])
+                    ? (time() + ($responseArray['expires_in'])) : null;
 
             return true;
         }
diff --git a/module/finc/src/finc/RecordDriver/SolrDefault.php b/module/finc/src/finc/RecordDriver/SolrDefault.php
index f619e72812bdc8e46ba0d0f03c92309c23f16b8d..ce4b3bbd46c7f33a7faa28009313b85ec46962c1 100644
--- a/module/finc/src/finc/RecordDriver/SolrDefault.php
+++ b/module/finc/src/finc/RecordDriver/SolrDefault.php
@@ -52,4 +52,33 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault implements
 {
     use \VuFind\Log\LoggerAwareTrait;
     use SolrDefaultFincTrait;
+
+    /**
+     * Index extension used for dynamic fields
+     *
+     * @var string
+     */
+    protected $indexExtension = '';
+
+    /**
+     * Constructor
+     *
+     * @param \Zend\Config\Config $mainConfig     VuFind main configuration (omit for
+     * built-in defaults)
+     * @param \Zend\Config\Config $recordConfig   Record-specific configuration file
+     * (omit to use $mainConfig as $recordConfig)
+     * @param \Zend\Config\Config $searchSettings Search-specific configuration file
+     */
+    public function __construct($mainConfig = null, $recordConfig = null,
+                                $searchSettings = null
+    )
+    {
+        parent::__construct($mainConfig, $recordConfig, $searchSettings);
+
+        if (isset($this->mainConfig->CustomIndex->indexExtension)) {
+            $this->indexExtension = $this->mainConfig->CustomIndex->indexExtension;
+        } else {
+            $this->debug('Index extension for custom index not set!');
+        }
+    }
 }
diff --git a/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php b/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php
index 0ec2e010c52d06a3f9b346350d31ffd1685166bf..2e27f68e0f28b284c103e5e742d891fed3b7760d 100644
--- a/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php
+++ b/module/finc/src/finc/RecordDriver/SolrDefaultFincTrait.php
@@ -50,6 +50,18 @@ use VuFindSearch\ParamBag;
 trait SolrDefaultFincTrait
 {
 
+    /**
+     * Get all call numbers associated with the record (empty string if none).
+     *
+     * @return array
+     */
+    public function getCallNumbers()
+    {
+        return isset($this->fields['callnumber_' . $this->indexExtension])
+            ? $this->fields['callnumber_' . $this->indexExtension]
+            : parent::getCallNumbers();
+    }
+
     /**
      * Return the custom index field local_heading if indexExtension is set.
      * If indexExtension is set local_heading_{indexExtension} is returned,
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcFinc.php b/module/finc/src/finc/RecordDriver/SolrMarcFinc.php
index 593d00a7f4a9dcf4d35599560c68b97d3ab2037f..13422d421147c490f817cc71441036e800facb8c 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcFinc.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcFinc.php
@@ -77,6 +77,7 @@ class SolrMarcFinc extends SolrMarc
     {
         parent::__construct($mainConfig, $recordConfig, $searchSettings);
 
+        // get the isil set in InstitutionInfo in config.ini
         if (isset($mainConfig->InstitutionInfo->isil)
             && count($mainConfig->InstitutionInfo->isil) > 0
         ) {
@@ -85,26 +86,5 @@ class SolrMarcFinc extends SolrMarc
             $this->debug('InstitutionInfo setting: isil is missing.');
         }
 
-        if (isset($this->mainConfig->CustomSite->namespace)) {
-            // map for marc fields
-            $map = [
-                'che' => '971',
-                'hgb' => '979',
-                'hfbk' => '978',
-                'hfm' => '977',
-                'hmt' => '970',
-                'htw' => '973',
-                'htwk' => '974',
-                'tuf' => '972',
-                'ubl' => '969',
-                'zit' => '976',
-                'zwi' => '975',
-            ];
-            $this->localMarcFieldOfLibrary
-                = isset($map[$this->mainConfig->CustomSite->namespace]) ?
-                $map[$this->mainConfig->CustomSite->namespace] : null;
-        } else {
-            $this->debug('Namespace setting for localMarcField is missing.');
-        }
     }
 }
\ No newline at end of file
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
index 381e4f21ec63a187914f952ac09dbbc97ad4924e..282ae50c007957d21bf5f4e14ed7d01df18057d2 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
@@ -168,6 +168,7 @@ trait SolrMarcFincTrait
      *
      * @return array   Return fields.
      * @access public
+     * @deprecated (https://intern.finc.info/issues/6324)
      * @link   https://intern.finc.info/issues/2639
      */
     public function getLocalCallnumber()
@@ -198,6 +199,7 @@ trait SolrMarcFincTrait
      *
      * @return array
      * @access protected
+     * @deprecated (https://intern.finc.info/issues/6324)
      */
     protected function getLocalCallnumbersByLibrary()
     {
@@ -237,7 +239,7 @@ trait SolrMarcFincTrait
     protected function getLocalGivenCallnumber()
     {
         $retval = [];
-        $arrSignatur = $this->getFieldArray($this->localMarcFieldOfLibrary, ['i']);
+        $arrSignatur = $this->getFieldArray($this->getLocalMarcFieldOfLibrary(), ['i']);
 
         foreach ($arrSignatur as $signatur) {
             foreach ($this->isil as $code) {
@@ -425,8 +427,8 @@ trait SolrMarcFincTrait
      */
     protected function getLocalAccessNumber()
     {
-        if (null != $this->localMarcFieldOfLibrary) {
-            return $this->getFieldArray($this->localMarcFieldOfLibrary, ['o']);
+        if (null != $this->getLocalMarcFieldOfLibrary()) {
+            return $this->getFieldArray($this->getLocalMarcFieldOfLibrary(), ['o']);
         }
         return [];
     }
@@ -483,8 +485,8 @@ trait SolrMarcFincTrait
      */
     public function getLocalFormat()
     {
-        if (null != $this->localMarcFieldOfLibrary) {
-            if (count($localformat = $this->getFieldArray($this->localMarcFieldOfLibrary, ['c'])) > 0) {
+        if (null != $this->getLocalMarcFieldOfLibrary()) {
+            if (count($localformat = $this->getFieldArray($this->getLocalMarcFieldOfLibrary(), ['c'])) > 0) {
                 foreach ($localformat as &$line) {
                     if ($line != "") {
                         $line = trim('local_format_' . strtolower($line));
@@ -497,6 +499,39 @@ trait SolrMarcFincTrait
         return [];
     }
 
+    /**
+     * Returns lazily the library specific Marc field configured by CustomIndex
+     * settings in config.ini
+     *
+     * @return mixed
+     * @link https://intern.finc.info/issues/7063
+     */
+    protected function getLocalMarcFieldOfLibrary()
+    {
+        // return the library specific Marc field if its already set
+        if ($this->localMarcFieldOfLibrary != null) {
+            return $this->localMarcFieldOfLibrary;
+        }
+
+        // get the library specific Marc field configured by CustomIndex settings in
+        // config.ini
+        if (isset($this->mainConfig->CustomIndex->localMarcFieldOfLibraryNamespace)) {
+            $namespace = $this->mainConfig->CustomIndex->localMarcFieldOfLibraryNamespace;
+            if (isset($this->mainConfig->CustomIndex->localMarcFieldOfLibraryMapping)) {
+                foreach ($this->mainConfig->CustomIndex->localMarcFieldOfLibraryMapping as $mappingValue) {
+                    list ($ns, $fn) = explode(':', $mappingValue);
+                    if (trim($ns) == trim($namespace)) {
+                        $this->localMarcFieldOfLibrary = $fn;
+                        break;
+                    }
+                }
+            }
+        } else {
+            $this->debug('Namespace setting for localMarcField is missing.');
+        }
+        return $this->localMarcFieldOfLibrary;
+    }
+
     /**
      * Return a local notice via an consortial defined field with subfield $k.
      * Marc field depends on library e.g. 970 for HMT or 972 for TUBAF.
@@ -507,8 +542,8 @@ trait SolrMarcFincTrait
      */
     protected function getLocalNotice()
     {
-        if (null != $this->localMarcFieldOfLibrary) {
-            return $this->getFieldArray($this->localMarcFieldOfLibrary, ['k']);
+        if (null != $this->getLocalMarcFieldOfLibrary()) {
+            return $this->getFieldArray($this->getLocalMarcFieldOfLibrary(), ['k']);
         }
         return [];
     }
@@ -667,8 +702,8 @@ trait SolrMarcFincTrait
      */
     protected function getPurchaseInformation()
     {
-        if (null != $this->localMarcFieldOfLibrary) {
-            if ($this->getFirstFieldValue($this->localMarcFieldOfLibrary, ['m']) == 'e') {
+        if (null != $this->getLocalMarcFieldOfLibrary()) {
+            if ($this->getFirstFieldValue($this->getLocalMarcFieldOfLibrary(), ['m']) == 'e') {
                 return true;
             }
         }
@@ -700,9 +735,9 @@ trait SolrMarcFincTrait
     protected function getUDKs()
     {
         $array = [];
-        if (null != $this->localMarcFieldOfLibrary) {
+        if (null != $this->getLocalMarcFieldOfLibrary()) {
 
-            $udk = $this->getMarcRecord()->getFields($this->localMarcFieldOfLibrary);
+            $udk = $this->getMarcRecord()->getFields($this->getLocalMarcFieldOfLibrary());
             // if not return void value
             if (!$udk) {
                 return $array;
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcRemoteFinc.php b/module/finc/src/finc/RecordDriver/SolrMarcRemoteFinc.php
index ce8fe5b4f26cd4e768af0af4ee81e5e71a8e0ef6..7cd6d44a6ad325740998c552ec6a5160baac5bb5 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcRemoteFinc.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcRemoteFinc.php
@@ -86,27 +86,5 @@ class SolrMarcRemoteFinc extends SolrMarcRemote
         } else {
             $this->debug('InstitutionInfo setting: isil is missing.');
         }
-
-        if (isset($this->mainConfig->CustomSite->namespace)) {
-            // map for marc fields
-            $map = [
-                'che' => '971',
-                'hgb' => '979',
-                'hfbk' => '978',
-                'hfm' => '977',
-                'hmt' => '970',
-                'htw' => '973',
-                'htwk' => '974',
-                'tuf' => '972',
-                'ubl' => '969',
-                'zit' => '976',
-                'zwi' => '975',
-            ];
-            $this->localMarcFieldOfLibrary
-                = isset($map[$this->mainConfig->CustomSite->namespace]) ?
-                    $map[$this->mainConfig->CustomSite->namespace] : null;
-        } else {
-            $this->debug('Namespace setting for localMarcField is missing.');
-        }
     }
 }
diff --git a/themes/finc/scss/default.scss b/themes/finc/scss/default.scss
index 56772ee60a7f74d2b6ec2aeeb5aba6edfcfde3c8..e9d557ae0261ad4c3b18aa2030a473e9017d9221 100644
--- a/themes/finc/scss/default.scss
+++ b/themes/finc/scss/default.scss
@@ -45,10 +45,33 @@
 }
 
 // RECORD VIEW
+// TABS
+// Table width
+.tabs-content table {
+  width:100%;
+}
+// Holdings
+// Insert line break before Vormerken buttons
+.holdings-tab {
+  line-height: 1.75rem;
+  td {
+    vertical-align: top;
+  }
+  td span:after {
+    content: "\a ";
+    white-space: pre;
+  }
+  // remove excessive bottom margins above order buttons
+  ul {margin-bottom: 0}
+  .button {
+    margin-top: .5rem;
+  }
+}
 // Internformat
 .pace-car th {min-width: 10%}
 
-// Footer
+
+// FOOTER
 .powered-by {
   img {
     height: 1.75em;
diff --git a/themes/finc/templates/RecordDriver/SolrAI/core.phtml b/themes/finc/templates/RecordDriver/SolrAI/core.phtml
index c8f694fe552b3ac064eeeb0bd9f2f596bcc92da4..333ade8e09afb7091e41c904531076e342eef2cf 100644
--- a/themes/finc/templates/RecordDriver/SolrAI/core.phtml
+++ b/themes/finc/templates/RecordDriver/SolrAI/core.phtml
@@ -137,11 +137,10 @@ if($loggedin = $this->auth()->isLoggedIn()) {
         <tr>
           <th><?=$this->transEsc('In')?>: </th>
             <td>
-              <? $issns = $aidatain['issns']; if (!empty($issns)): ?>
+              <? $jtitle = $aidatain['jtitle']; $issns = $aidatain['issns']; if (!empty($issns)): ?>
                 <a href="<?=$this->record($this->driver)->getLinkISN($issns)?>">
-                  <? $jtitle = $aidatain['jtitle'];
-                  if (!empty($jtitle)): ?><?=$this->escapeHtml($jtitle)?><? endif; ?>
-                </a><? endif; ?><? $volume = $aidatain['volume']; if (!empty($volume)): ?>, <?=$this->escapeHtml($volume) ?><? endif; ?><? $date = $aidatain['date']; if (!empty($date)): ?><? if (empty($volume)): ?>, <? endif; ?>(<?=$this->escapeHtml($date) ?>)<? endif; ?><? $issue = $aidatain['issue']; if (!empty($issue)): ?>, <?=$this->escapeHtml($issue) ?><? endif; ?><? $pages = $aidatain['pages']; if (!empty($pages)): ?>, <?=$this->transEsc('p.')?> <?=$this->escapeHtml($pages) ?><? endif; ?>
+                <? if (!empty($jtitle)): ?><?=$this->escapeHtml($jtitle)?><? endif; ?>
+                </a><? elseif (!empty($jtitle)): ?><?=$this->escapeHtml($jtitle)?><? endif; ?><? $volume = $aidatain['volume']; if (!empty($volume)): ?><? if (empty($jtitle)): ?>, <? endif; ?><?=$this->escapeHtml($volume) ?><? endif; ?><? $date = $aidatain['date']; if (!empty($date)): ?><? if (empty($volume)): ?>, <? endif; ?>(<?=$this->escapeHtml($date) ?>)<? endif; ?><? $issue = $aidatain['issue']; if (!empty($issue)): ?>, <?=$this->escapeHtml($issue) ?><? endif; ?><? $pages = $aidatain['pages']; if (!empty($pages)): ?>, <?=$this->transEsc('p.')?> <?=$this->escapeHtml($pages) ?><? endif; ?>
               </td>
           </tr>
       <? endif; ?>
diff --git a/themes/finc/templates/RecordTab/holdingsils.phtml b/themes/finc/templates/RecordTab/holdingsils.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..2fbb8267d4a842b750cffc23781d6beaee33a49d
--- /dev/null
+++ b/themes/finc/templates/RecordTab/holdingsils.phtml
@@ -0,0 +1,168 @@
+<!-- recordTab - HOLDINGSILS.phtml -->
+<?
+    // Set up convenience variables:
+    $account = $this->auth()->getManager();
+    $user = $account->isLoggedIn();
+    $holdings = $this->driver->getRealTimeHoldings();
+    $openUrl = $this->openUrl($this->driver, 'holdings');
+    $openUrlActive = $openUrl->isActive();
+    // Account for replace_other_urls setting
+    $urls = $this->record($this->driver)->getLinkDetails($openUrlActive);
+    $offlineMode = $this->ils()->getOfflineMode();
+    // Set page title.
+    $this->headTitle($this->translate('Holdings') . ': ' . $this->driver->getBreadcrumb());
+?>
+
+<?=$this->context($this)->renderInContext('librarycards/selectcard.phtml', array('user' => $this->auth()->isLoggedIn())); ?>
+
+<? if ($offlineMode == "ils-offline"): ?>
+  <div data-alert class="alert-box warning" tabindex="0" aria-live="assertive" role="dialogalert">
+    <h2><?=$this->transEsc('ils_offline_title')?></h2>
+    <p><strong><?=$this->transEsc('ils_offline_status')?></strong></p>
+    <p><?=$this->transEsc('ils_offline_holdings_message')?></p>
+    <? $supportEmail = $this->escapeHtmlAttr($this->systemEmail()); ?>
+    <p><a href="mailto:<?=$supportEmail?>"><?=$supportEmail?></a></p>
+  </div>
+<? endif; ?>
+<? if (($this->ils()->getHoldsMode() == 'driver' && !empty($holdings)) || $this->ils()->getTitleHoldsMode() == 'driver'): ?>
+  <? if ($account->loginEnabled() && $offlineMode != 'ils-offline'): ?>
+    <? if (!$user): ?>
+      <div data-alert class="alert-box info" tabindex="0" aria-live="assertive" role="dialogalert">
+        <a href="<?=$this->recordLink()->getTabUrl($this->driver, 'Holdings')?>?login=true&amp;catalogLogin=true"><?=$this->transEsc("Login")?></a> <?=$this->transEsc("hold_login")?>
+      </div>
+    <? elseif (!$user->cat_username): ?>
+      <div data-alert class="alert-box info" tabindex="0" aria-live="assertive" role="dialogalert">
+        <?=$this->translate("hold_profile_html", array('%%url%%' => $this->recordLink()->getTabUrl($this->driver, 'Holdings') . '?catalogLogin=true'))?>
+      </div>
+    <? endif; ?>
+  <? endif; ?>
+<? endif; ?>
+<? $holdingTitleHold = $this->driver->tryMethod('getRealTimeTitleHold'); if (!empty($holdingTitleHold)): ?>
+    <a class="placehold modal-link button small" title="<?=$this->transEsc('request_place_text')?>" href="<?=$this->recordLink()->getRequestUrl($holdingTitleHold)?>"><i class="fa fa-flag"></i>&nbsp;<?=$this->transEsc('title_hold_place')?></a>
+<? endif; ?>
+<? if (!empty($urls) || $openUrlActive): ?>
+  <h3><?=$this->transEsc("Internet")?></h3>
+  <? if (!empty($urls)): ?>
+    <? foreach ($urls as $current): ?>
+      <a href="<?=$this->escapeHtmlAttr($this->proxyUrl($current['url']))?>"><?=$this->escapeHtml($current['desc'])?></a><br/>
+    <? endforeach; ?>
+  <? endif; ?>
+  <? if ($openUrlActive): ?><?=$openUrl->renderTemplate()?><? endif; ?>
+<? endif; ?>
+<? foreach ($holdings as $holding): ?>
+  <h3>
+    <? $locationText = $this->transEsc('location_' . $holding['location'], array(), $holding['location']); ?>
+    <? if (isset($holding['locationhref']) && $holding['locationhref']): ?>
+      <a href="<?=$holding['locationhref']?>" target="_blank"><?=$locationText?></a>
+    <? else: ?>
+      <?=$locationText?>
+    <? endif; ?>
+  </h3>
+<table class="table" summary="<?=$this->transEsc('Holdings details from')?> <?=$this->transEsc($holding['location'])?>">
+  <tr>
+    <th><?=$this->transEsc("Availability")?></th>
+    <th><?=$this->transEsc("Details")?></th>
+  </tr>
+  <? foreach ($holding['items'] as $row): ?>
+    <? $check = (isset($row['check']) && $row['check']); ?>
+    <? $checkStorageRetrievalRequest = (isset($row['checkStorageRetrievalRequest']) && $row['checkStorageRetrievalRequest']); ?>
+    <? $checkILLRequest = (isset($row['checkILLRequest']) && $row['checkILLRequest']); ?>
+    <? if (isset($row['barcode']) && $row['barcode'] != ""): ?>
+    <tr vocab="http://schema.org/" typeof="Offer">
+      <td>
+        <? if ($row['availability']): ?>
+        <? /* Begin Available Items (Holds) */ ?>
+        <span class="label success"><?=$this->transEsc("Available")?><link property="availability" href="http://schema.org/InStock" /></span>
+        <? else: ?>
+        <? /* Begin Unavailable Items (Recalls) */ ?>
+        <span class="label alert"><?=empty($row['status'])?$this->transEsc("Unavailable"):$this->transEsc($row['status'])?><link property="availability" href="http://schema.org/OutOfStock" /></span>
+        <? endif; ?>
+      </td>
+      <td>
+        <? if ($row['reserve'] == "Y"): ?>
+          <link property="availability" href="http://schema.org/InStoreOnly" />
+          <?=$this->transEsc("On Reserve - Ask at Circulation Desk")?><br />
+        <? endif; ?>
+        <? if (isset($row['use_unknown_message']) && $row['use_unknown_message']): ?>
+          <span class="label secondary"><?=$this->transEsc("status_unknown_message")?></span>
+        <? else: ?>
+          <? if (isset($row['callnumber'])): ?>
+            <span class="callnumber"><?=$this->transEsc("Call Number")?>: <?=$row['callnumber']?></span>
+          <? endif; ?>
+          <? if (isset($row['storage']) && $row['storage'] != 'Unknown'): ?>
+            <span class="storage"><?=$this->transEsc("Location")?>: <?=$row['storage']?></span>
+          <? endif; ?>
+          <? if ($row['availability']): ?>
+            <? /* Begin Available Items (Holds) */ ?>
+            <? if (isset($row['notes'])): ?>
+              <span class="notes"><?=$this->transEsc("Notes")?>:</span>
+              <ul class="notes">
+                <? foreach ($row['notes'] as $note): ?>
+                  <li><?=$note?></li>
+                <? endforeach; ?>
+              </ul>
+            <? endif; ?>
+            <? if (isset($row['link']) && $row['link']): ?>
+                <a class="<?=$check ? 'checkRequest ' : ''?>inlineblock modal-link placehold hide-for-print" href="<?=$this->recordLink()->getRequestUrl($row['link'])?>" title="<?=$this->transEsc($check ? "Check Hold" : "Place a Hold")?>"><i class="fa fa-flag"></i>&nbsp;<?=$this->transEsc($check ? "Check Hold" : "Place a Hold")?></a>
+            <? endif; ?>
+            <? if (isset($row['storageRetrievalRequestLink']) && $row['storageRetrievalRequestLink']): ?>
+                <a class="<?=$checkStorageRetrievalRequest ? 'checkStorageRetrievalRequest ' : ''?>modal-link placeStorageRetrievalRequest" href="<?=$this->recordLink()->getRequestUrl($row['storageRetrievalRequestLink'])?>" title="<?=$this->transEsc($checkStorageRetrievalRequest ? "storage_retrieval_request_check_text" : "storage_retrieval_request_place_text")?>"><i class="fa fa-flag"></i>&nbsp;<?=$this->transEsc($checkStorageRetrievalRequest ? "storage_retrieval_request_check_text" : "storage_retrieval_request_place_text")?></a>
+            <? endif; ?>
+            <? if (isset($row['ILLRequestLink']) && $row['ILLRequestLink']): ?>
+                <a class="<?=$checkILLRequest ? 'checkILLRequest ' : ''?>inlineblock modal-link placeILLRequest" href="<?=$this->recordLink()->getRequestUrl($row['ILLRequestLink'])?>"  title="<?=$this->transEsc($checkILLRequest ? "ill_request_check_text" : "ill_request_place_text")?>"><i class="fa fa-flag"></i>&nbsp;<?=$this->transEsc($checkILLRequest ? "ill_request_check_text" : "ill_request_place_text")?></a>
+            <? endif; ?>
+          <? else: ?>
+            <? /* Begin Unavailable Items (Recalls) */ ?>
+              <span class="label alert"><?=empty($row['status'])?$this->transEsc("Unavailable"):$this->transEsc($row['status'])?><link property="availability" href="http://schema.org/OutOfStock" /></span>
+            <? if (isset($row['returnDate']) && $row['returnDate']): ?>&ndash; <span class="small"><?=$this->escapeHtml($row['returnDate'])?></span><? endif; ?>
+            <? if (isset($row['duedate']) && $row['duedate']): ?>
+              &ndash; <span class="small"><?=$this->transEsc("Due")?>: <?=$this->escapeHtml($row['duedate'])?></span>
+            <? endif; ?>
+            <? if (isset($row['requests_placed']) && $row['requests_placed'] > 0): ?>
+              <span><?=$this->transEsc("Requests")?>: <?=$this->escapeHtml($row['requests_placed'])?></span>
+            <? endif; ?>
+            <? if (isset($row['link']) && $row['link']): ?>
+                <a class="<?=$check ? 'checkRequest' : ''?> modal-link inlineblock placehold hide-for-print" href="<?=$this->recordLink()->getRequestUrl($row['link'])?>"><i class="fa fa-flag"></i>&nbsp;<?=$this->transEsc($check ? "Check Recall" : "Recall This")?></a>
+            <? endif; ?>
+          <? endif; ?>
+        <? endif; ?>
+        <? /* Embed item structured data: library, barcode, call number */ ?>
+        <? if ($row['location']): ?>
+          <meta property="seller" content="<?=$this->escapeHtmlAttr($row['location'])?>" />
+        <? endif; ?>
+        <? if ($row['barcode']): ?>
+          <meta property="serialNumber" content="<?=$this->escapeHtmlAttr($row['barcode'])?>" />
+        <? endif; ?>
+        <? if ($row['callnumber']): ?>
+          <meta property="sku" content="<?=$this->escapeHtmlAttr($row['callnumber'])?>" />
+        <? endif; ?>
+        <? /* Declare that the item is to be borrowed, not for sale */ ?>
+          <link property="businessFunction" href="http://purl.org/goodrelations/v1#LeaseOut" />
+          <link property="itemOffered" href="#record" />
+      </td>
+    </tr>
+    <? endif; ?>
+  <? endforeach; ?>
+  <? if (!empty($holding['purchase_history'])): ?>
+    <tr>
+      <th><?=$this->transEsc("Most Recent Received Issues")?>:</th>
+      <td>
+        <? foreach ($holding['purchase_history'] as $current): ?>
+          <?=$this->escapeHtml($current['issue'])?><br/>
+        <? endforeach; ?>
+      </td>
+    </tr>
+  <? endif; ?>
+</table>
+<? endforeach; ?>
+
+<? $history = $this->driver->getRealTimeHistory(); ?>
+<? if (is_array($history) && !empty($history)): ?>
+<h3><?=$this->transEsc("Most Recent Received Issues")?></h3>
+<table class="table">
+  <? foreach ($history as $row): ?>
+    <tr><td><?=$this->escapeHtml($row['issue'])?></td></tr>
+  <? endforeach; ?>
+</table>
+<? endif; ?>
+<!-- recordTab - HOLDINGSILS.phtml end -->
\ No newline at end of file
diff --git a/themes/finc/templates/record/view.phtml b/themes/finc/templates/record/view.phtml
index 13e1d1a98ca0541ace1c7eb1fcac3822a9227d7b..e631a70fe9e35b839b107c5f08aac53f23e9bfc5 100644
--- a/themes/finc/templates/record/view.phtml
+++ b/themes/finc/templates/record/view.phtml
@@ -81,7 +81,7 @@
 
       <div class="tabs-content" id="record-tabs">
         <? if (!$this->ajaxTabs || !isset($activeTabObj) || !$activeTabObj->supportsAjax()): ?>
-          <div class="content active" id="<?=$this->activeTab?>-tab">
+          <div class="content active <?=$this->activeTab?>-tab">
           <?=isset($activeTabObj) ? $this->record($this->driver)->getTab($activeTabObj) : ''?>
           </div>
         <? endif; ?>
diff --git a/themes/foundation5/templates/record/view.phtml b/themes/foundation5/templates/record/view.phtml
index db711cfe888075ecb686866e8627c6865547e171..41dbd12e18357ebfba5dec9cb27b5883ff34afa3 100644
--- a/themes/foundation5/templates/record/view.phtml
+++ b/themes/foundation5/templates/record/view.phtml
@@ -81,7 +81,7 @@ $this->layout()->title = $this->driver->getShortTitle();
 
       <div class="tabs-content" id="record-tabs">
           <? if (!$this->ajaxTabs || !isset($activeTabObj) || !$activeTabObj->supportsAjax()): ?>
-            <div class="content active" id="<?=$this->activeTab?>-tab">
+            <div class="content active <?=$this->activeTab?>-tab">
             <?=isset($activeTabObj) ? $this->record($this->driver)->getTab($activeTabObj) : ''?>
             </div>
           <? endif; ?>