JBAS-1832 Migrate 3.2 SQL to sqitch
authorBill Erickson <berickxx@gmail.com>
Wed, 12 Sep 2018 14:50:35 +0000 (10:50 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 21 Mar 2019 19:46:23 +0000 (15:46 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
KCLS/sql/schema/deploy/2.12-3.2-db-upgrade-data.sql [new file with mode: 0644]
KCLS/sql/schema/deploy/2.12-3.2-db-upgrade-schema.sql [new file with mode: 0644]
KCLS/sql/schema/revert/2.12-3.2-db-upgrade-data.sql [new file with mode: 0644]
KCLS/sql/schema/revert/2.12-3.2-db-upgrade-schema.sql [new file with mode: 0644]
KCLS/sql/schema/sqitch.plan
kcls-2.12-3.2-db-upgrade-data.sql [deleted file]
kcls-2.12-3.2-db-upgrade.sql [deleted file]

diff --git a/KCLS/sql/schema/deploy/2.12-3.2-db-upgrade-data.sql b/KCLS/sql/schema/deploy/2.12-3.2-db-upgrade-data.sql
new file mode 100644 (file)
index 0000000..a3df7e0
--- /dev/null
@@ -0,0 +1,123 @@
+-- Deploy kcls-evergreen:2.12-3.2-db-upgrade-data to pg
+-- requires: 2.12-3.2-db-upgrade-schema
+
+\set ON_ERROR_STOP on
+
+SET STATEMENT_TIMEOUT = 0;
+
+----------------------------------------------------------------------------
+-- POST UPGRADE DATA UPDATES.
+----------------------------------------------------------------------------
+
+-- TODO: EXTERNAL BIB FULL RE-INGEST
+
+-- TODO: run all in transaction for testing -- remove transactions later.
+
+BEGIN;
+
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON biblio.peer_bib_copy_map;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON biblio.record_entry;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON asset.copy;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON asset.call_number;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON asset.copy_location;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON serial.unit;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON config.copy_status;
+DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON actor.org_unit;
+
+SELECT CLOCK_TIMESTAMP(), 'Updating copy visibility attr cache';
+
+-- no insert wrapper required
+-- Upgrade the data!
+INSERT INTO asset.copy_vis_attr_cache (target_copy, record, vis_attr_vector)
+    SELECT  cp.id,
+            cn.record,
+            asset.calculate_copy_visibility_attribute_set(cp.id)
+      FROM  asset.copy cp
+            JOIN asset.call_number cn ON (cp.call_number = cn.id);
+
+CREATE TRIGGER z_opac_vis_mat_view_tgr BEFORE INSERT OR UPDATE 
+    ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR DELETE 
+    ON biblio.peer_bib_copy_map FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER UPDATE 
+    ON asset.call_number FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_del_tgr BEFORE DELETE 
+    ON asset.copy FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_del_tgr BEFORE DELETE 
+    ON serial.unit FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE 
+    ON asset.copy FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE 
+    ON serial.unit FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+
+SELECT CLOCK_TIMESTAMP(), 'Making copy alert types active';
+
+UPDATE config.copy_alert_type
+SET active = TRUE
+WHERE id IN (4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+
+
+-- Update keyword indexes for existing patrons
+SELECT CLOCK_TIMESTAMP(), 'Updating patron name keyword vector';
+
+UPDATE actor.usr SET name_kw_tsvector = 
+    TO_TSVECTOR(
+        COALESCE(prefix, '') || ' ' || 
+        COALESCE(first_given_name, '') || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(first_given_name), '') || ' ' || 
+        COALESCE(second_given_name, '') || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(second_given_name), '') || ' ' || 
+        COALESCE(family_name, '') || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(family_name), '') || ' ' || 
+        COALESCE(suffix, '')
+    );
+
+-- Authority record re-ingest
+
+SELECT CLOCK_TIMESTAMP(), 'Reingesting authority records';
+
+-- add the flag ingest.disable_authority_full_rec if it does not exist
+INSERT INTO config.internal_flag (name, enabled)
+SELECT 'ingest.disable_authority_full_rec', FALSE
+WHERE NOT EXISTS (SELECT 1 FROM config.internal_flag 
+WHERE name = 'ingest.disable_authority_full_rec');
+
+CREATE TEMPORARY TABLE internal_flag_state AS
+    SELECT name, enabled
+    FROM config.internal_flag
+    WHERE name in (
+        'ingest.reingest.force_on_same_marc',
+        'ingest.disable_authority_auto_update',
+        'ingest.disable_authority_full_rec'
+    );
+
+UPDATE config.internal_flag
+SET enabled = TRUE
+WHERE name in (
+    'ingest.reingest.force_on_same_marc',
+    'ingest.disable_authority_auto_update',
+    'ingest.disable_authority_full_rec'
+);
+
+ALTER TABLE authority.record_entry DISABLE TRIGGER a_marcxml_is_well_formed;
+ALTER TABLE authority.record_entry DISABLE TRIGGER b_maintain_901;
+ALTER TABLE authority.record_entry DISABLE TRIGGER c_maintain_control_numbers;
+ALTER TABLE authority.record_entry DISABLE TRIGGER map_thesaurus_to_control_set;
+
+UPDATE authority.record_entry SET id = id WHERE NOT DELETED;
+
+ALTER TABLE authority.record_entry ENABLE TRIGGER a_marcxml_is_well_formed;
+ALTER TABLE authority.record_entry ENABLE TRIGGER b_maintain_901;
+ALTER TABLE authority.record_entry ENABLE TRIGGER c_maintain_control_numbers;
+ALTER TABLE authority.record_entry ENABLE TRIGGER map_thesaurus_to_control_set;
+
+-- and restore
+UPDATE config.internal_flag a
+SET enabled = b.enabled
+FROM internal_flag_state b
+WHERE a.name = b.name;
+
+
+--COMMIT;
+ROLLBACK;
+
diff --git a/KCLS/sql/schema/deploy/2.12-3.2-db-upgrade-schema.sql b/KCLS/sql/schema/deploy/2.12-3.2-db-upgrade-schema.sql
new file mode 100644 (file)
index 0000000..1a83ec9
--- /dev/null
@@ -0,0 +1,21493 @@
+-- Deploy kcls-evergreen:2.12-3.2-db-upgrade-schema to pg
+-- requires: ecard-notice-validator
+
+BEGIN;
+
+--Upgrade Script for 2.12.6 to 3.0.0
+--\set eg_version '''3.0.0'''
+\set ON_ERROR_STOP on
+
+SET STATEMENT_TIMEOUT = 0;
+
+-- VERSION 1032 
+
+CREATE OR REPLACE VIEW action.all_circulation_combined_types AS 
+ SELECT acirc.id AS id,
+    acirc.xact_start,
+    acirc.circ_lib,
+    acirc.circ_staff,
+    acirc.create_time,
+    ac_acirc.circ_modifier AS item_type,
+    'regular_circ'::text AS circ_type
+   FROM action.circulation acirc,
+    asset.copy ac_acirc
+  WHERE acirc.target_copy = ac_acirc.id
+UNION ALL
+ SELECT ancc.id::BIGINT AS id,
+    ancc.circ_time AS xact_start,
+    ancc.circ_lib,
+    ancc.staff AS circ_staff,
+    ancc.circ_time AS create_time,
+    cnct_ancc.name AS item_type,
+    'non-cat_circ'::text AS circ_type
+   FROM action.non_cataloged_circulation ancc,
+    config.non_cataloged_type cnct_ancc
+  WHERE ancc.item_type = cnct_ancc.id
+UNION ALL
+ SELECT aihu.id::BIGINT AS id,
+    aihu.use_time AS xact_start,
+    aihu.org_unit AS circ_lib,
+    aihu.staff AS circ_staff,
+    aihu.use_time AS create_time,
+    ac_aihu.circ_modifier AS item_type,
+    'in-house_use'::text AS circ_type
+   FROM action.in_house_use aihu,
+    asset.copy ac_aihu
+  WHERE aihu.item = ac_aihu.id
+UNION ALL
+ SELECT ancihu.id::BIGINT AS id,
+    ancihu.use_time AS xact_start,
+    ancihu.org_unit AS circ_lib,
+    ancihu.staff AS circ_staff,
+    ancihu.use_time AS create_time,
+    cnct_ancihu.name AS item_type,
+    'non-cat_circ'::text AS circ_type
+   FROM action.non_cat_in_house_use ancihu,
+    config.non_cataloged_type cnct_ancihu
+  WHERE ancihu.item_type = cnct_ancihu.id
+UNION ALL
+ SELECT aacirc.id AS id,
+    aacirc.xact_start,
+    aacirc.circ_lib,
+    aacirc.circ_staff,
+    aacirc.create_time,
+    ac_aacirc.circ_modifier AS item_type,
+    'aged_circ'::text AS circ_type
+   FROM action.aged_circulation aacirc,
+    asset.copy ac_aacirc
+  WHERE aacirc.target_copy = ac_aacirc.id;
+
+
+-- VERSION 1034
+
+ALTER TABLE config.hold_matrix_matchpoint
+    ADD COLUMN description TEXT;
+
+ALTER TABLE config.circ_matrix_matchpoint
+    ADD COLUMN description TEXT;
+
+-- VERSION 1035
+
+-- Per Lp bug 1684984, the config.internal_flag,
+-- ingest.disable_metabib_field_entry, was made obsolete by the
+-- addition of the ingest.skip_browse_indexing,
+-- ingest.skip_search_indexing, and ingest.skip_facet_indexing flags.
+-- Since it is not used in the database, we delete it.
+DELETE FROM config.internal_flag
+WHERE name = 'ingest.disable_metabib_field_entry';
+
+-- VERSION 1036
+
+CREATE OR REPLACE FUNCTION config.update_hard_due_dates () RETURNS INT AS $func$
+DECLARE
+    temp_value  config.hard_due_date_values%ROWTYPE;
+    updated     INT := 0;
+BEGIN
+    FOR temp_value IN
+      SELECT  DISTINCT ON (hard_due_date) *
+        FROM  config.hard_due_date_values
+        WHERE active_date <= NOW() -- We've passed (or are at) the rollover time
+        ORDER BY hard_due_date, active_date DESC -- Latest (nearest to us) active time
+   LOOP
+        UPDATE  config.hard_due_date
+          SET   ceiling_date = temp_value.ceiling_date
+          WHERE id = temp_value.hard_due_date
+                AND ceiling_date <> temp_value.ceiling_date -- Time is equal if we've already updated the chdd
+                AND temp_value.ceiling_date >= NOW(); -- Don't update ceiling dates to the past
+
+        IF FOUND THEN
+            updated := updated + 1;
+        END IF;
+    END LOOP;
+
+    RETURN updated;
+END;
+$func$ LANGUAGE plpgsql;
+
+
+-- VERSION 1041
+
+--delete all instances from permission.grp_perm_map first
+DELETE FROM permission.grp_perm_map where perm in 
+(select id from permission.perm_list where code='SET_CIRC_MISSING');
+
+--delete all instances from permission.usr_perm_map too
+DELETE FROM permission.usr_perm_map where perm in
+(select id from permission.perm_list where code='SET_CIRC_MISSING');
+
+--delete from permission.perm_list
+DELETE FROM permission.perm_list where code='SET_CIRC_MISSING';
+
+
+-- VERSION 1042
+
+ALTER TABLE asset.copy_location
+          ADD COLUMN url TEXT;
+
+-- SELECT evergreen.upgrade_deps_block_check('1043', :eg_version);
+
+-- SELECT evergreen.upgrade_deps_block_check('1044', :eg_version);
+
+-- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1045', :eg_version); -- csharp/berick/gmcharlt
+
+ALTER TABLE action.transit_copy
+       ADD COLUMN cancel_time TIMESTAMPTZ;
+
+-- change "abort" to "cancel" in stock perm descriptions
+UPDATE permission.perm_list 
+       SET description = 'Allow a user to cancel a copy transit if the user is at the transit destination or source' 
+       WHERE code = 'ABORT_TRANSIT'
+       AND description = 'Allow a user to abort a copy transit if the user is at the transit destination or source';
+UPDATE permission.perm_list 
+       SET description = 'Allow a user to cancel a copy transit if the user is not at the transit source or dest' 
+       WHERE code = 'ABORT_REMOTE_TRANSIT'
+       AND description = 'Allow a user to abort a copy transit if the user is not at the transit source or dest';
+UPDATE permission.perm_list 
+       SET description = 'Allows a user to cancel a transit on a copy with status of LOST' 
+       WHERE code = 'ABORT_TRANSIT_ON_LOST'
+       AND description = 'Allows a user to abort a transit on a copy with status of LOST';
+UPDATE permission.perm_list 
+       SET description = 'Allows a user to cancel a transit on a copy with status of MISSING' 
+       WHERE code = 'ABORT_TRANSIT_ON_MISSING'
+       AND description = 'Allows a user to abort a transit on a copy with status of MISSING';
+
+-- SELECT evergreen.upgrade_deps_block_check('1046', :eg_version); -- phasefx/berick/gmcharlt
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
+INSERT into config.org_unit_setting_type (
+     name
+    ,grp
+    ,label
+    ,description
+    ,datatype
+) VALUES ( ----------------------------------------
+     'webstaff.format.dates'
+    ,'gui'
+    ,oils_i18n_gettext(
+         'webstaff.format.dates'
+        ,'Format Dates with this pattern'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.format.dates'
+        ,'Format Dates with this pattern (examples: "yyyy-MM-dd" for "2010-04-26", "MMM d, yyyy" for "Apr 26, 2010").  This will be used in areas where a date without a timestamp is sufficient, like Date of Birth.'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.format.date_and_time'
+    ,'gui'
+    ,oils_i18n_gettext(
+         'webstaff.format.date_and_time'
+        ,'Format Date+Time with this pattern'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.format.date_and_time'
+        ,'Format Date+Time with this pattern (examples: "yy-MM-dd h:m:s.SSS a" for "16-04-05 2:07:20.666 PM", "yyyy-dd-MMM HH:mm" for "2016-05-Apr 14:07").  This will be used in areas of the client where a date with a timestamp is needed, like Checkout, Due Date, or Record Created.'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+);
+END IF; END $INSERT$;
+
+UPDATE
+    config.org_unit_setting_type
+SET
+    label = 'Deprecated: ' || label -- FIXME: Is this okay?
+WHERE
+    name IN ('format.date','format.time')
+;
+
+-- SELECT evergreen.upgrade_deps_block_check('1047', :eg_version); -- gmcharlt/stompro
+
+CREATE TABLE config.copy_tag_type (
+    code            TEXT NOT NULL PRIMARY KEY,
+    label           TEXT NOT NULL,
+    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED
+);
+
+CREATE INDEX config_copy_tag_type_owner_idx
+    ON config.copy_tag_type (owner);
+
+CREATE TABLE asset.copy_tag (
+    id              SERIAL PRIMARY KEY,
+    tag_type        TEXT REFERENCES config.copy_tag_type (code)
+                    ON UPDATE CASCADE ON DELETE CASCADE,
+    label           TEXT NOT NULL,
+    value           TEXT NOT NULL,
+    index_vector    tsvector NOT NULL,
+    staff_note      TEXT,
+    pub             BOOLEAN DEFAULT TRUE,
+    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id)
+);
+
+CREATE INDEX asset_copy_tag_label_idx
+    ON asset.copy_tag (label);
+CREATE INDEX asset_copy_tag_label_lower_idx
+    ON asset.copy_tag (evergreen.lowercase(label));
+CREATE INDEX asset_copy_tag_index_vector_idx
+    ON asset.copy_tag
+    USING GIN(index_vector);
+CREATE INDEX asset_copy_tag_tag_type_idx
+    ON asset.copy_tag (tag_type);
+CREATE INDEX asset_copy_tag_owner_idx
+    ON asset.copy_tag (owner);
+
+CREATE OR REPLACE FUNCTION asset.set_copy_tag_value () RETURNS TRIGGER AS $$
+BEGIN
+    IF NEW.value IS NULL THEN
+        NEW.value = NEW.label;        
+    END IF;
+
+    RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+-- name of following trigger chosen to ensure it runs first
+CREATE TRIGGER asset_copy_tag_do_value
+    BEFORE INSERT OR UPDATE ON asset.copy_tag
+    FOR EACH ROW EXECUTE PROCEDURE asset.set_copy_tag_value();
+CREATE TRIGGER asset_copy_tag_fti_trigger
+    BEFORE UPDATE OR INSERT ON asset.copy_tag
+    FOR EACH ROW EXECUTE PROCEDURE oils_tsearch2('default');
+
+CREATE TABLE asset.copy_tag_copy_map (
+    id              BIGSERIAL PRIMARY KEY,
+    copy            BIGINT REFERENCES asset.copy (id)
+                    ON UPDATE CASCADE ON DELETE CASCADE,
+    tag             INTEGER REFERENCES asset.copy_tag (id)
+                    ON UPDATE CASCADE ON DELETE CASCADE
+);
+
+CREATE INDEX asset_copy_tag_copy_map_copy_idx
+    ON asset.copy_tag_copy_map (copy);
+CREATE INDEX asset_copy_tag_copy_map_tag_idx
+    ON asset.copy_tag_copy_map (tag);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
+
+INSERT INTO config.copy_tag_type (code, label, owner) VALUES ('bookplate', 'Digital Bookplate', 1);
+
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+ ( 590, 'ADMIN_COPY_TAG_TYPES', oils_i18n_gettext( 590,
+    'Administer copy tag types', 'ppl', 'description' )),
+ ( 591, 'ADMIN_COPY_TAG', oils_i18n_gettext( 591,
+    'Administer copy tag', 'ppl', 'description' ))
+;
+
+INSERT INTO config.org_unit_setting_type
+    (name, label, description, grp, datatype)
+VALUES (
+    'opac.search.enable_bookplate_search',
+    oils_i18n_gettext(
+        'opac.search.enable_bookplate_search',
+        'Enable Digital Bookplate Search',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.search.enable_bookplate_search',
+        'If enabled, adds a "Digital Bookplate" option to the query type selectors in the public catalog for search on copy tags.',   
+        'coust',
+        'description'
+    ),
+    'opac',
+    'bool'
+);
+
+-- SELECT evergreen.upgrade_deps_block_check('1048', :eg_version);
+
+INSERT into config.org_unit_setting_type (
+     name
+    ,grp
+    ,label
+    ,description
+    ,datatype
+) VALUES ( ----------------------------------------
+     'webstaff.cat.label.font.family'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.font.family'
+        ,'Item Print Label Font Family'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.font.family'
+        ,'Set the preferred font family for item print labels. You can specify a list of CSS fonts, separated by commas, in order of preference; the system will use the first font it finds with a matching name. For example, "Arial, Helvetica, serif"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.font.size'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.font.size'
+        ,'Item Print Label Font Size'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.font.size'
+        ,'Set the default font size for item print labels. Please include a unit of measurement that is valid CSS. For example, "12pt" or "16px" or "1em"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.font.weight'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.font.weight'
+        ,'Item Print Label Font Weight'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.font.weight'
+        ,'Set the default font weight for item print labels. Please use the CSS specification for values for font-weight.  For example, "normal", "bold", "bolder", or "lighter"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.left_label.left_margin'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.left_label.left_margin'
+        ,'Item Print Label - Left Margin for Left Label'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.left_label.left_margin'
+        ,'Set the default left margin for the leftmost item print Label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.right_label.left_margin'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.right_label.left_margin'
+        ,'Item Print Label - Left Margin for Right Label'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.right_label.left_margin'
+        ,'Set the default left margin for the rightmost item print label (or in other words, the desired space between the two labels). Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.left_label.height'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.left_label.height'
+        ,'Item Print Label - Height for Left Label'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.left_label.height'
+        ,'Set the default height for the leftmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.left_label.width'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.left_label.width'
+        ,'Item Print Label - Width for Left Label'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.left_label.width'
+        ,'Set the default width for the leftmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.right_label.height'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.right_label.height'
+        ,'Item Print Label - Height for Right Label'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.right_label.height'
+        ,'Set the default height for the rightmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), ( ----------------------------------------
+     'webstaff.cat.label.right_label.width'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.right_label.width'
+        ,'Item Print Label - Width for Right Label'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.right_label.width'
+        ,'Set the default width for the rightmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), (
+     'webstaff.cat.label.inline_css'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.inline_css'
+        ,'Item Print Label - Inline CSS'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.inline_css'
+        ,'This setting allows you to inject arbitrary CSS into the item print label template.  For example, ".printlabel { text-transform: uppercase; }"'
+        ,'coust'
+        ,'description'
+    )
+    ,'string'
+), (
+     'webstaff.cat.label.call_number_wrap_filter_height'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.call_number_wrap_filter_height'
+        ,'Item Print Label - Call Number Wrap Filter Height'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.call_number_wrap_filter_height'
+        ,'This setting is used to set the default height (in number of lines) to use for call number wrapping in the left print label.'
+        ,'coust'
+        ,'description'
+    )
+    ,'integer'
+), (
+     'webstaff.cat.label.call_number_wrap_filter_width'
+    ,'cat'
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.call_number_wrap_filter_width'
+        ,'Item Print Label - Call Number Wrap Filter Width'
+        ,'coust'
+        ,'label'
+    )
+    ,oils_i18n_gettext(
+         'webstaff.cat.label.call_number_wrap_filter_width'
+        ,'This setting is used to set the default width (in number of characters) to use for call number wrapping in the left print label.'
+        ,'coust'
+        ,'description'
+    )
+    ,'integer'
+
+
+);
+
+END IF; END $INSERT$;
+
+-- SELECT evergreen.upgrade_deps_block_check('1049', :eg_version); -- mmorgan/stompro/gmcharlt
+
+SELECT CLOCK_TIMESTAMP(), 
+    'Setting invalid age_protect and circ_as_type entries to NULL';
+
+UPDATE asset.copy_template act
+SET age_protect = NULL
+FROM actor.org_unit aou
+WHERE aou.id=act.owning_lib
+   AND act.age_protect NOT IN
+   (
+   SELECT id FROM config.rule_age_hold_protect
+   )
+RETURNING act.id "Template ID", act.name "Template Name",
+          aou.shortname "Owning Lib",
+          'Age Protection value reset to null.' "Description";
+
+UPDATE asset.copy_template act
+SET circ_as_type = NULL
+FROM actor.org_unit aou
+WHERE aou.id=act.owning_lib
+   AND act.circ_as_type NOT IN
+   (
+   SELECT code FROM config.item_type_map
+   )
+RETURNING act.id "Template ID", act.name "Template Name",
+          aou.shortname "Owning Lib",
+          'Circ as Type value reset to null.' as "Description";
+
+\echo -----------End Serial Template Fix----------------
+
+-- SELECT evergreen.upgrade_deps_block_check('1050', :eg_version); -- mmorgan/cesardv/gmcharlt
+
+CREATE OR REPLACE FUNCTION permission.usr_perms ( INT ) RETURNS SETOF permission.usr_perm_map AS $$
+    SELECT     DISTINCT ON (usr,perm) *
+         FROM  (
+                       (SELECT * FROM permission.usr_perm_map WHERE usr = $1)
+            UNION ALL
+                       (SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
+                         FROM  permission.grp_perm_map p
+                         WHERE p.grp IN (
+      SELECT   (permission.grp_ancestors(
+      (SELECT profile FROM actor.usr WHERE id = $1)
+                                       )).id
+                               )
+                       )
+            UNION ALL
+                       (SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
+                         FROM  permission.grp_perm_map p
+                         WHERE p.grp IN (SELECT (permission.grp_ancestors(m.grp)).id FROM permission.usr_grp_map m WHERE usr = $1))
+               ) AS x
+         ORDER BY 2, 3, 4 ASC, 5 DESC ;
+$$ LANGUAGE SQL STABLE ROWS 10;
+
+-- SELECT evergreen.upgrade_deps_block_check('1051', :eg_version);
+
+CREATE OR REPLACE VIEW action.all_circulation_slim AS
+    SELECT
+        id,
+        usr,
+        xact_start,
+        xact_finish,
+        unrecovered,
+        target_copy,
+        circ_lib,
+        circ_staff,
+        checkin_staff,
+        checkin_lib,
+        renewal_remaining,
+        grace_period,
+        due_date,
+        stop_fines_time,
+        checkin_time,
+        create_time,
+        duration,
+        fine_interval,
+        recurring_fine,
+        max_fine,
+        phone_renewal,
+        desk_renewal,
+        opac_renewal,
+        duration_rule,
+        recurring_fine_rule,
+        max_fine_rule,
+        stop_fines,
+        workstation,
+        checkin_workstation,
+        copy_location,
+        checkin_scan_time,
+        parent_circ
+    FROM action.circulation
+UNION ALL
+    SELECT
+        id,
+        NULL AS usr,
+        xact_start,
+        xact_finish,
+        unrecovered,
+        target_copy,
+        circ_lib,
+        circ_staff,
+        checkin_staff,
+        checkin_lib,
+        renewal_remaining,
+        grace_period,
+        due_date,
+        stop_fines_time,
+        checkin_time,
+        create_time,
+        duration,
+        fine_interval,
+        recurring_fine,
+        max_fine,
+        phone_renewal,
+        desk_renewal,
+        opac_renewal,
+        duration_rule,
+        recurring_fine_rule,
+        max_fine_rule,
+        stop_fines,
+        workstation,
+        checkin_workstation,
+        copy_location,
+        checkin_scan_time,
+        parent_circ
+    FROM action.aged_circulation
+;
+
+DROP FUNCTION action.summarize_all_circ_chain(INTEGER);
+DROP FUNCTION action.all_circ_chain(INTEGER);
+
+CREATE OR REPLACE FUNCTION action.all_circ_chain (ctx_circ_id INTEGER) 
+    RETURNS SETOF action.all_circulation_slim AS $$
+DECLARE
+    tmp_circ action.all_circulation_slim%ROWTYPE;
+    circ_0 action.all_circulation_slim%ROWTYPE;
+BEGIN
+
+    SELECT INTO tmp_circ * FROM action.all_circulation_slim WHERE id = ctx_circ_id;
+
+    IF tmp_circ IS NULL THEN
+        RETURN NEXT tmp_circ;
+    END IF;
+    circ_0 := tmp_circ;
+
+    -- find the front of the chain
+    WHILE TRUE LOOP
+        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
+            WHERE id = tmp_circ.parent_circ;
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        circ_0 := tmp_circ;
+    END LOOP;
+
+    -- now send the circs to the caller, oldest to newest
+    tmp_circ := circ_0;
+    WHILE TRUE LOOP
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        RETURN NEXT tmp_circ;
+        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
+            WHERE parent_circ = tmp_circ.id;
+    END LOOP;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION action.summarize_all_circ_chain 
+    (ctx_circ_id INTEGER) RETURNS action.circ_chain_summary AS $$
+
+DECLARE
+
+    -- first circ in the chain
+    circ_0 action.all_circulation_slim%ROWTYPE;
+
+    -- last circ in the chain
+    circ_n action.all_circulation_slim%ROWTYPE;
+
+    -- circ chain under construction
+    chain action.circ_chain_summary;
+    tmp_circ action.all_circulation_slim%ROWTYPE;
+
+BEGIN
+    
+    chain.num_circs := 0;
+    FOR tmp_circ IN SELECT * FROM action.all_circ_chain(ctx_circ_id) LOOP
+
+        IF chain.num_circs = 0 THEN
+            circ_0 := tmp_circ;
+        END IF;
+
+        chain.num_circs := chain.num_circs + 1;
+        circ_n := tmp_circ;
+    END LOOP;
+
+    chain.start_time := circ_0.xact_start;
+    chain.last_stop_fines := circ_n.stop_fines;
+    chain.last_stop_fines_time := circ_n.stop_fines_time;
+    chain.last_checkin_time := circ_n.checkin_time;
+    chain.last_checkin_scan_time := circ_n.checkin_scan_time;
+    SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
+    SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
+
+    IF chain.num_circs > 1 THEN
+        chain.last_renewal_time := circ_n.xact_start;
+        SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
+    END IF;
+
+    RETURN chain;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION rating.percent_time_circulating(badge_id INT)
+    RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
+DECLARE
+    badge   rating.badge_with_orgs%ROWTYPE;
+BEGIN
+
+    SELECT * INTO badge FROM rating.badge_with_orgs WHERE id = badge_id;
+
+    PERFORM rating.precalc_bibs_by_copy(badge_id);
+
+    DELETE FROM precalc_copy_filter_bib_list WHERE id NOT IN (
+        SELECT id FROM precalc_filter_bib_list
+            INTERSECT
+        SELECT id FROM precalc_bibs_by_copy_list
+    );
+
+    ANALYZE precalc_copy_filter_bib_list;
+
+    RETURN QUERY
+     SELECT bib,
+            SUM(COALESCE(circ_time,0))::NUMERIC / SUM(age)::NUMERIC
+      FROM  (SELECT cn.record AS bib,
+                    cp.id,
+                    EXTRACT( EPOCH FROM AGE(cp.active_date) ) + 1 AS age,
+                    SUM(  -- time copy spent circulating
+                        EXTRACT(
+                            EPOCH FROM
+                            AGE(
+                                COALESCE(circ.checkin_time, circ.stop_fines_time, NOW()),
+                                circ.xact_start
+                            )
+                        )
+                    )::NUMERIC AS circ_time
+              FROM  asset.copy cp
+                    JOIN precalc_copy_filter_bib_list c ON (cp.id = c.copy)
+                    JOIN asset.call_number cn ON (cn.id = cp.call_number)
+                    LEFT JOIN action.all_circulation_slim circ ON (
+                        circ.target_copy = cp.id
+                        AND stop_fines NOT IN (
+                            'LOST',
+                            'LONGOVERDUE',
+                            'CLAIMSRETURNED',
+                            'LONGOVERDUE'
+                        )
+                        AND NOT (
+                            checkin_time IS NULL AND
+                            stop_fines = 'MAXFINES'
+                        )
+                    )
+              WHERE cn.owning_lib = ANY (badge.orgs)
+                    AND cp.active_date IS NOT NULL
+                    -- Next line requires that copies with no circs (circ.id IS NULL) also not be deleted
+                    AND ((circ.id IS NULL AND NOT cp.deleted) OR circ.id IS NOT NULL)
+              GROUP BY 1,2,3
+            ) x
+      GROUP BY 1;
+END;
+$f$ LANGUAGE PLPGSQL STRICT;
+
+-- SELECT evergreen.upgrade_deps_block_check('1052', :eg_version);
+
+CREATE OR REPLACE FUNCTION rating.inhouse_over_time(badge_id INT)
+    RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
+DECLARE
+    badge   rating.badge_with_orgs%ROWTYPE;
+    iage    INT     := 1;
+    iint    INT     := NULL;
+    iscale  NUMERIC := NULL;
+BEGIN
+
+    SELECT * INTO badge FROM rating.badge_with_orgs WHERE id = badge_id;
+
+    IF badge.horizon_age IS NULL THEN
+        RAISE EXCEPTION 'Badge "%" with id % requires a horizon age but has none.',
+            badge.name,
+            badge.id;
+    END IF;
+
+    PERFORM rating.precalc_bibs_by_copy(badge_id);
+
+    DELETE FROM precalc_copy_filter_bib_list WHERE id NOT IN (
+        SELECT id FROM precalc_filter_bib_list
+            INTERSECT
+        SELECT id FROM precalc_bibs_by_copy_list
+    );
+
+    ANALYZE precalc_copy_filter_bib_list;
+
+    iint := EXTRACT(EPOCH FROM badge.importance_interval);
+    IF badge.importance_age IS NOT NULL THEN
+        iage := (EXTRACT(EPOCH FROM badge.importance_age) / iint)::INT;
+    END IF;
+
+    -- if iscale is smaller than 1, scaling slope will be shallow ... BEWARE!
+    iscale := COALESCE(badge.importance_scale, 1.0);
+
+    RETURN QUERY
+     SELECT bib,
+            SUM( uses * GREATEST( iscale * (iage - cage), 1.0 ))
+      FROM (
+         SELECT cn.record AS bib,
+                (1 + EXTRACT(EPOCH FROM AGE(u.use_time)) / iint)::INT AS cage,
+                COUNT(u.id)::INT AS uses
+          FROM  action.in_house_use u
+                JOIN precalc_copy_filter_bib_list cf ON (u.item = cf.copy)
+                JOIN asset.copy cp ON (cp.id = u.item)
+                JOIN asset.call_number cn ON (cn.id = cp.call_number)
+          WHERE u.use_time >= NOW() - badge.horizon_age
+                AND cn.owning_lib = ANY (badge.orgs)
+          GROUP BY 1, 2
+      ) x
+      GROUP BY 1;
+END;
+$f$ LANGUAGE PLPGSQL STRICT;
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+INSERT INTO rating.popularity_parameter (id, name, func, require_horizon,require_percentile) VALUES
+    (18,'In-House Use Over Time', 'rating.inhouse_over_time', TRUE, TRUE);
+END IF; END $INSERT$;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1053', :eg_version);
+
+CREATE OR REPLACE FUNCTION rating.org_unit_count(badge_id INT)
+    RETURNS TABLE (record INT, value NUMERIC) AS $f$
+DECLARE
+    badge   rating.badge_with_orgs%ROWTYPE;
+BEGIN
+
+    SELECT * INTO badge FROM rating.badge_with_orgs WHERE id = badge_id;
+
+    PERFORM rating.precalc_bibs_by_copy(badge_id);
+
+    DELETE FROM precalc_copy_filter_bib_list WHERE id NOT IN (
+        SELECT id FROM precalc_filter_bib_list
+            INTERSECT
+        SELECT id FROM precalc_bibs_by_copy_list
+    );
+    ANALYZE precalc_copy_filter_bib_list;
+
+    -- Use circ rather than owning lib here as that means "on the shelf at..."
+    RETURN QUERY
+     SELECT f.id::INT AS bib,
+            COUNT(DISTINCT cp.circ_lib)::NUMERIC
+     FROM asset.copy cp
+          JOIN precalc_copy_filter_bib_list f ON (cp.id = f.copy)
+     WHERE cp.circ_lib = ANY (badge.orgs) GROUP BY 1;
+
+END;
+$f$ LANGUAGE PLPGSQL STRICT;
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+INSERT INTO rating.popularity_parameter (id, name, func, require_percentile) VALUES
+    (17,'Circulation Library Count', 'rating.org_unit_count', TRUE);
+
+-- SELECT evergreen.upgrade_deps_block_check('1054', :eg_version);
+
+INSERT into config.org_unit_setting_type
+( name, grp, label, description, datatype ) VALUES
+
+( 'lib.timezone', 'lib',
+    oils_i18n_gettext('lib.timezone',
+        'Library time zone',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.timezone',
+        'Define the time zone in which a library physically resides',
+        'coust', 'description'),
+    'string');
+END IF; END $INSERT$;
+
+ALTER TABLE actor.org_unit_closed ADD COLUMN full_day BOOLEAN DEFAULT FALSE;
+ALTER TABLE actor.org_unit_closed ADD COLUMN multi_day BOOLEAN DEFAULT FALSE;
+
+UPDATE actor.org_unit_closed SET multi_day = TRUE
+  WHERE close_start::DATE <> close_end::DATE;
+
+UPDATE actor.org_unit_closed SET full_day = TRUE
+  WHERE close_start::DATE = close_end::DATE
+        AND SUBSTRING(close_start::time::text FROM 1 FOR 8) = '00:00:00'
+        AND SUBSTRING(close_end::time::text FROM 1 FOR 8) = '23:59:59';
+
+CREATE OR REPLACE FUNCTION action.push_circ_due_time () RETURNS TRIGGER AS $$
+DECLARE
+    proper_tz TEXT := COALESCE(
+        oils_json_to_text((
+            SELECT value
+              FROM  actor.org_unit_ancestor_setting('lib.timezone',NEW.circ_lib)
+              LIMIT 1
+        )),
+        CURRENT_SETTING('timezone')
+    );
+BEGIN
+
+    IF (EXTRACT(EPOCH FROM NEW.duration)::INT % EXTRACT(EPOCH FROM '1 day'::INTERVAL)::INT) = 0 -- day-granular duration
+        AND SUBSTRING((NEW.due_date AT TIME ZONE proper_tz)::TIME::TEXT FROM 1 FOR 8) <> '23:59:59' THEN -- has not yet been pushed
+        NEW.due_date = ((NEW.due_date AT TIME ZONE proper_tz)::DATE + '1 day'::INTERVAL - '1 second'::INTERVAL) || ' ' || proper_tz;
+    END IF;
+
+    RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+-- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1056', :eg_version); -- miker/gmcharlt
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+INSERT INTO permission.perm_list (id,code,description) VALUES (592,'CONTAINER_BATCH_UPDATE','Allow batch update via buckets');
+
+INSERT INTO container.user_bucket_type (code,label) SELECT code,label FROM container.copy_bucket_type where code = 'staff_client';
+END IF; END $INSERT$;                                                          
+
+
+CREATE TABLE action.fieldset_group (
+    id              SERIAL  PRIMARY KEY,
+    name            TEXT        NOT NULL,
+    create_time     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+    complete_time   TIMESTAMPTZ,
+    container       INT,        -- Points to a container of some type ...
+    container_type  TEXT,       -- One of 'biblio_record_entry', 'user', 'call_number', 'copy'
+    can_rollback    BOOL        DEFAULT TRUE,
+    rollback_group  INT         REFERENCES action.fieldset_group (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    rollback_time   TIMESTAMPTZ,
+    creator         INT         NOT NULL REFERENCES actor.usr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    owning_lib      INT         NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
+);
+
+ALTER TABLE action.fieldset ADD COLUMN fieldset_group INT REFERENCES action.fieldset_group (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE action.fieldset ADD COLUMN error_msg TEXT;
+ALTER TABLE container.biblio_record_entry_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE container.user_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE container.call_number_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE container.copy_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+UPDATE query.stored_query SET id = id + 1000 WHERE id < 1000;
+UPDATE query.from_relation SET id = id + 1000 WHERE id < 1000;
+UPDATE query.expression SET id = id + 1000 WHERE id < 1000;
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+PERFORM SETVAL('query.stored_query_id_seq', 1, FALSE);
+PERFORM SETVAL('query.from_relation_id_seq', 1, FALSE);
+PERFORM SETVAL('query.expression_id_seq', 1, FALSE);
+
+INSERT INTO query.bind_variable (name,type,description,label)
+    SELECT  'bucket','number','ID of the bucket to pull items from','Bucket ID'
+      WHERE NOT EXISTS (SELECT 1 FROM query.bind_variable WHERE name = 'bucket');
+
+-- Assumes completely empty 'query' schema
+INSERT INTO query.stored_query (type, use_distinct) VALUES ('SELECT', TRUE); -- 1
+
+INSERT INTO query.from_relation (type, table_name, class_name, table_alias) VALUES ('RELATION', 'container.user_bucket_item', 'cubi', 'cubi'); -- 1
+UPDATE query.stored_query SET from_clause = 1;
+
+INSERT INTO query.expr_xcol (table_alias, column_name) VALUES ('cubi', 'target_user'); -- 1
+INSERT INTO query.select_item (stored_query,seq_no,expression) VALUES (1,1,1);
+
+INSERT INTO query.expr_xcol (table_alias, column_name) VALUES ('cubi', 'bucket'); -- 2
+INSERT INTO query.expr_xbind (bind_variable) VALUES ('bucket'); -- 3
+
+INSERT INTO query.expr_xop (left_operand, operator, right_operand) VALUES (2, '=', 3); -- 4
+UPDATE query.stored_query SET where_clause = 4;
+
+PERFORM SETVAL('query.stored_query_id_seq', 1000, TRUE) FROM query.stored_query;
+PERFORM SETVAL('query.from_relation_id_seq', 1000, TRUE) FROM query.from_relation;
+PERFORM SETVAL('query.expression_id_seq', 10000, TRUE) FROM query.expression;
+
+END IF; END $INSERT$;                                                          
+
+CREATE OR REPLACE FUNCTION action.apply_fieldset(
+    fieldset_id IN INT,        -- id from action.fieldset
+    table_name  IN TEXT,       -- table to be updated
+    pkey_name   IN TEXT,       -- name of primary key column in that table
+    query       IN TEXT        -- query constructed by qstore (for query-based
+                               --    fieldsets only; otherwise null
+)
+RETURNS TEXT AS $$
+DECLARE
+    statement TEXT;
+    where_clause TEXT;
+    fs_status TEXT;
+    fs_pkey_value TEXT;
+    fs_query TEXT;
+    sep CHAR;
+    status_code TEXT;
+    msg TEXT;
+    fs_id INT;
+    fsg_id INT;
+    update_count INT;
+    cv RECORD;
+    fs_obj action.fieldset%ROWTYPE;
+    fs_group action.fieldset_group%ROWTYPE;
+    rb_row RECORD;
+BEGIN
+    -- Sanity checks
+    IF fieldset_id IS NULL THEN
+        RETURN 'Fieldset ID parameter is NULL';
+    END IF;
+    IF table_name IS NULL THEN
+        RETURN 'Table name parameter is NULL';
+    END IF;
+    IF pkey_name IS NULL THEN
+        RETURN 'Primary key name parameter is NULL';
+    END IF;
+
+    SELECT
+        status,
+        quote_literal( pkey_value )
+    INTO
+        fs_status,
+        fs_pkey_value
+    FROM
+        action.fieldset
+    WHERE
+        id = fieldset_id;
+
+    --
+    -- Build the WHERE clause.  This differs according to whether it's a
+    -- single-row fieldset or a query-based fieldset.
+    --
+    IF query IS NULL        AND fs_pkey_value IS NULL THEN
+        RETURN 'Incomplete fieldset: neither a primary key nor a query available';
+    ELSIF query IS NOT NULL AND fs_pkey_value IS NULL THEN
+        fs_query := rtrim( query, ';' );
+        where_clause := 'WHERE ' || pkey_name || ' IN ( '
+                     || fs_query || ' )';
+    ELSIF query IS NULL     AND fs_pkey_value IS NOT NULL THEN
+        where_clause := 'WHERE ' || pkey_name || ' = ';
+        IF pkey_name = 'id' THEN
+            where_clause := where_clause || fs_pkey_value;
+        ELSIF pkey_name = 'code' THEN
+            where_clause := where_clause || quote_literal(fs_pkey_value);
+        ELSE
+            RETURN 'Only know how to handle "id" and "code" pkeys currently, received ' || pkey_name;
+        END IF;
+    ELSE  -- both are not null
+        RETURN 'Ambiguous fieldset: both a primary key and a query provided';
+    END IF;
+
+    IF fs_status IS NULL THEN
+        RETURN 'No fieldset found for id = ' || fieldset_id;
+    ELSIF fs_status = 'APPLIED' THEN
+        RETURN 'Fieldset ' || fieldset_id || ' has already been applied';
+    END IF;
+
+    SELECT * INTO fs_obj FROM action.fieldset WHERE id = fieldset_id;
+    SELECT * INTO fs_group FROM action.fieldset_group WHERE id = fs_obj.fieldset_group;
+
+    IF fs_group.can_rollback THEN
+        -- This is part of a non-rollback group.  We need to record the current values for future rollback.
+
+        INSERT INTO action.fieldset_group (can_rollback, name, creator, owning_lib, container, container_type)
+            VALUES (FALSE, 'ROLLBACK: '|| fs_group.name, fs_group.creator, fs_group.owning_lib, fs_group.container, fs_group.container_type);
+
+        fsg_id := CURRVAL('action.fieldset_group_id_seq');
+
+        FOR rb_row IN EXECUTE 'SELECT * FROM ' || table_name || ' ' || where_clause LOOP
+            IF pkey_name = 'id' THEN
+                fs_pkey_value := rb_row.id;
+            ELSIF pkey_name = 'code' THEN
+                fs_pkey_value := rb_row.code;
+            ELSE
+                RETURN 'Only know how to handle "id" and "code" pkeys currently, received ' || pkey_name;
+            END IF;
+            INSERT INTO action.fieldset (fieldset_group,owner,owning_lib,status,classname,name,pkey_value)
+                VALUES (fsg_id, fs_obj.owner, fs_obj.owning_lib, 'PENDING', fs_obj.classname, fs_obj.name || ' ROLLBACK FOR ' || fs_pkey_value, fs_pkey_value);
+
+            fs_id := CURRVAL('action.fieldset_id_seq');
+            sep := '';
+            FOR cv IN
+                SELECT  DISTINCT col
+                FROM    action.fieldset_col_val
+                WHERE   fieldset = fieldset_id
+            LOOP
+                EXECUTE 'INSERT INTO action.fieldset_col_val (fieldset, col, val) ' || 
+                    'SELECT '|| fs_id || ', '||quote_literal(cv.col)||', '||cv.col||' FROM '||table_name||' WHERE '||pkey_name||' = '||fs_pkey_value;
+            END LOOP;
+        END LOOP;
+    END IF;
+
+    statement := 'UPDATE ' || table_name || ' SET';
+
+    sep := '';
+    FOR cv IN
+        SELECT  col,
+                val
+        FROM    action.fieldset_col_val
+        WHERE   fieldset = fieldset_id
+    LOOP
+        statement := statement || sep || ' ' || cv.col
+                     || ' = ' || coalesce( quote_literal( cv.val ), 'NULL' );
+        sep := ',';
+    END LOOP;
+
+    IF sep = '' THEN
+        RETURN 'Fieldset ' || fieldset_id || ' has no column values defined';
+    END IF;
+    statement := statement || ' ' || where_clause;
+
+    --
+    -- Execute the update
+    --
+    BEGIN
+        EXECUTE statement;
+        GET DIAGNOSTICS update_count = ROW_COUNT;
+
+        IF update_count = 0 THEN
+            RAISE data_exception;
+        END IF;
+
+        IF fsg_id IS NOT NULL THEN
+            UPDATE action.fieldset_group SET rollback_group = fsg_id WHERE id = fs_group.id;
+        END IF;
+
+        IF fs_group.id IS NOT NULL THEN
+            UPDATE action.fieldset_group SET complete_time = now() WHERE id = fs_group.id;
+        END IF;
+
+        UPDATE action.fieldset SET status = 'APPLIED', applied_time = now() WHERE id = fieldset_id;
+
+    EXCEPTION WHEN data_exception THEN
+        msg := 'No eligible rows found for fieldset ' || fieldset_id;
+        UPDATE action.fieldset SET status = 'ERROR', applied_time = now() WHERE id = fieldset_id;
+        RETURN msg;
+
+    END;
+
+    RETURN msg;
+
+EXCEPTION WHEN OTHERS THEN
+    msg := 'Unable to apply fieldset ' || fieldset_id || ': ' || sqlerrm;
+    UPDATE action.fieldset SET status = 'ERROR', applied_time = now() WHERE id = fieldset_id;
+    RETURN msg;
+
+END;
+$$ LANGUAGE plpgsql;
+
+-- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1057', :eg_version); -- miker/gmcharlt/kmlussier
+
+-- Thist change drops a needless join and saves 10-15% in time cost
+CREATE OR REPLACE FUNCTION search.facets_for_record_set(ignore_facet_classes text[], hits bigint[]) RETURNS TABLE(id integer, value text, count bigint)
+AS $f$
+    SELECT id, value, count
+      FROM (
+        SELECT  mfae.field AS id,
+                mfae.value,
+                COUNT(DISTINCT mfae.source),
+                row_number() OVER (
+                    PARTITION BY mfae.field ORDER BY COUNT(DISTINCT mfae.source) DESC
+                ) AS rownum
+          FROM  metabib.facet_entry mfae
+                JOIN config.metabib_field cmf ON (cmf.id = mfae.field)
+          WHERE mfae.source = ANY ($2)
+                AND cmf.facet_field
+                AND cmf.field_class NOT IN (SELECT * FROM unnest($1))
+          GROUP by 1, 2
+      ) all_facets
+      WHERE rownum <= (
+        SELECT COALESCE(
+            (SELECT value::INT FROM config.global_flag WHERE name = 'search.max_facets_per_field' AND enabled),
+            1000
+        )
+      );
+$f$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.metabib_virtual_record_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit HSTORE DEFAULT NULL, soffset HSTORE DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL ) RETURNS XML AS $F$
+DECLARE
+    layout          unapi.bre_output_layout%ROWTYPE;
+    transform       config.xml_transform%ROWTYPE;
+    item_format     TEXT;
+    tmp_xml         TEXT;
+    xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
+    ouid            INT;
+    element_list    TEXT[];
+BEGIN
+
+    IF org = '-' OR org IS NULL THEN
+        SELECT shortname INTO org FROM evergreen.org_top();
+    END IF;
+
+    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
+    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
+
+    IF layout.name IS NULL THEN
+        RETURN NULL::XML;
+    END IF;
+
+    SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
+    xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
+
+    -- Gather the bib xml
+    SELECT XMLAGG( unapi.mmr(i, format, '', includes, org, depth, slimit, soffset, include_xmlns)) INTO tmp_xml FROM UNNEST( id_list ) i;
+
+    IF layout.title_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
+    END IF;
+
+    IF layout.description_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
+    END IF;
+
+    IF layout.creator_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
+    END IF;
+
+    IF layout.update_ts_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
+    END IF;
+
+    IF unapi_url IS NOT NULL THEN
+        EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
+    END IF;
+
+    IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
+
+    element_list := regexp_split_to_array(layout.feed_top,E'\\.');
+    FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
+        EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
+    END LOOP;
+
+    RETURN tmp_xml::XML;
+END;
+$F$ LANGUAGE PLPGSQL STABLE;
+
+CREATE TABLE asset.copy_vis_attr_cache (
+    id              BIGSERIAL   PRIMARY KEY,
+    record          BIGINT      NOT NULL, -- No FKEYs, managed by user triggers.
+    target_copy     BIGINT      NOT NULL,
+    vis_attr_vector INT[]
+);
+CREATE INDEX copy_vis_attr_cache_record_idx ON asset.copy_vis_attr_cache (record);
+CREATE INDEX copy_vis_attr_cache_copy_idx ON asset.copy_vis_attr_cache (target_copy);
+
+ALTER TABLE biblio.record_entry ADD COLUMN vis_attr_vector INT[];
+
+CREATE OR REPLACE FUNCTION search.calculate_visibility_attribute ( value INT, attr TEXT ) RETURNS INT AS $f$
+SELECT  ((CASE $2
+
+            WHEN 'luri_org'         THEN 0 -- "b" attr
+            WHEN 'bib_source'       THEN 1 -- "b" attr
+
+            WHEN 'copy_flags'       THEN 0 -- "c" attr
+            WHEN 'owning_lib'       THEN 1 -- "c" attr
+            WHEN 'circ_lib'         THEN 2 -- "c" attr
+            WHEN 'status'           THEN 3 -- "c" attr
+            WHEN 'location'         THEN 4 -- "c" attr
+            WHEN 'location_group'   THEN 5 -- "c" attr
+
+        END) << 28 ) | $1;
+
+/* copy_flags bit positions, LSB-first:
+
+ 0: asset.copy.opac_visible
+
+
+   When adding flags, you must update asset.all_visible_flags()
+
+   Because bib and copy values are stored separately, we can reuse
+   shifts, saving us some space. We could probably take back a bit
+   too, but I'm not sure its worth squeezing that last one out. We'd
+   be left with just 2 slots for copy attrs, rather than 10.
+*/
+
+$f$ LANGUAGE SQL IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION search.calculate_visibility_attribute_list ( attr TEXT, value INT[] ) RETURNS INT[] AS $f$
+    SELECT ARRAY_AGG(search.calculate_visibility_attribute(x, $1)) FROM UNNEST($2) AS X;
+$f$ LANGUAGE SQL IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION search.calculate_visibility_attribute_test ( attr TEXT, value INT[], negate BOOL DEFAULT FALSE ) RETURNS TEXT AS $f$
+    SELECT  CASE WHEN $3 THEN '!' ELSE '' END || '(' || ARRAY_TO_STRING(search.calculate_visibility_attribute_list($1,$2),'|') || ')';
+$f$ LANGUAGE SQL IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION asset.calculate_copy_visibility_attribute_set ( copy_id BIGINT ) RETURNS INT[] AS $f$
+DECLARE
+    copy_row    asset.copy%ROWTYPE;
+    lgroup_map  asset.copy_location_group_map%ROWTYPE;
+    attr_set    INT[];
+BEGIN
+    SELECT * INTO copy_row FROM asset.copy WHERE id = copy_id;
+
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.opac_visible::INT, 'copy_flags');
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.circ_lib, 'circ_lib');
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.status, 'status');
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.location, 'location');
+
+    SELECT  ARRAY_APPEND(
+                attr_set,
+                search.calculate_visibility_attribute(owning_lib, 'owning_lib')
+            ) INTO attr_set
+      FROM  asset.call_number
+      WHERE id = copy_row.call_number;
+
+    FOR lgroup_map IN SELECT * FROM asset.copy_location_group_map WHERE location = copy_row.location LOOP
+        attr_set := attr_set || search.calculate_visibility_attribute(lgroup_map.lgroup, 'location_group');
+    END LOOP;
+
+    RETURN attr_set;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION biblio.calculate_bib_visibility_attribute_set ( bib_id BIGINT ) RETURNS INT[] AS $f$
+DECLARE
+    bib_row     biblio.record_entry%ROWTYPE;
+    cn_row      asset.call_number%ROWTYPE;
+    attr_set    INT[];
+BEGIN
+    SELECT * INTO bib_row FROM biblio.record_entry WHERE id = bib_id;
+
+    IF bib_row.source IS NOT NULL THEN
+        attr_set := attr_set || search.calculate_visibility_attribute(bib_row.source, 'bib_source');
+    END IF;
+
+    FOR cn_row IN
+        SELECT  cn.*
+          FROM  asset.call_number cn
+                JOIN asset.uri_call_number_map m ON (cn.id = m.call_number)
+                JOIN asset.uri u ON (u.id = m.uri)
+          WHERE cn.record = bib_id
+                AND cn.label = '##URI##'
+                AND u.active
+    LOOP
+        attr_set := attr_set || search.calculate_visibility_attribute(cn_row.owning_lib, 'luri_org');
+    END LOOP;
+
+    RETURN attr_set;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+-- SELECT evergreen.upgrade_deps_block_check('1076', :eg_version); -- miker/gmcharlt
+
+CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
+DECLARE
+    ocn     asset.call_number%ROWTYPE;
+    ncn     asset.call_number%ROWTYPE;
+    cid     BIGINT;
+BEGIN
+
+    IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN -- Only needs ON INSERT OR DELETE, so handle separately
+        IF TG_OP = 'INSERT' THEN
+            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                NEW.peer_record,
+                NEW.target_copy,
+                asset.calculate_copy_visibility_attribute_set(NEW.target_copy)
+            );
+
+            RETURN NEW;
+        ELSIF TG_OP = 'DELETE' THEN
+            DELETE FROM asset.copy_vis_attr_cache
+              WHERE record = NEW.peer_record AND target_copy = NEW.target_copy;
+
+            RETURN OLD;
+        END IF;
+    END IF;
+
+    IF TG_OP = 'INSERT' THEN -- Handles ON INSERT. ON UPDATE is below.
+        IF TG_TABLE_NAME IN ('copy', 'unit') THEN
+            SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
+            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                ncn.record,
+                NEW.id,
+                asset.calculate_copy_visibility_attribute_set(NEW.id)
+            );
+        ELSIF TG_TABLE_NAME = 'record_entry' THEN
+            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
+        END IF;
+
+        RETURN NEW;
+    END IF;
+
+    -- handle items first, since with circulation activity
+    -- their statuses change frequently
+    IF TG_TABLE_NAME IN ('copy', 'unit') THEN -- This handles ON UPDATE OR DELETE. ON INSERT above
+
+        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
+            DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
+            RETURN OLD;
+        END IF;
+
+        SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
+
+        IF OLD.deleted <> NEW.deleted THEN
+            IF NEW.deleted THEN
+                DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
+            ELSE
+                INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                    ncn.record,
+                    NEW.id,
+                    asset.calculate_copy_visibility_attribute_set(NEW.id)
+                );
+            END IF;
+
+            RETURN NEW;
+        ELSIF OLD.call_number  <> NEW.call_number THEN
+            SELECT * INTO ocn FROM asset.call_number cn WHERE id = OLD.call_number;
+
+            IF ncn.record <> ocn.record THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(ncn.record)
+                  WHERE id = ocn.record;
+
+                -- We have to use a record-specific WHERE clause
+                -- to avoid modifying the entries for peer-bib copies.
+                UPDATE  asset.copy_vis_attr_cache
+                  SET   target_copy = NEW.id,
+                        record = ncn.record
+                  WHERE target_copy = OLD.id
+                        AND record = ocn.record;
+            END IF;
+        END IF;
+
+        IF OLD.location     <> NEW.location OR
+           OLD.status       <> NEW.status OR
+           OLD.opac_visible <> NEW.opac_visible OR
+           OLD.circ_lib     <> NEW.circ_lib
+        THEN
+            -- Any of these could change visibility, but
+            -- we'll save some queries and not try to calculate
+            -- the change directly.  We want to update peer-bib
+            -- entries in this case, unlike above.
+            UPDATE  asset.copy_vis_attr_cache
+              SET   target_copy = NEW.id,
+                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(NEW.id)
+              WHERE target_copy = OLD.id;
+
+        END IF;
+
+    ELSIF TG_TABLE_NAME = 'call_number' THEN -- Only ON UPDATE. Copy handler will deal with ON INSERT OR DELETE.
+
+        IF OLD.record <> NEW.record THEN
+            IF NEW.label = '##URI##' THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
+                  WHERE id = OLD.record;
+
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
+                  WHERE id = NEW.record;
+            END IF;
+
+            UPDATE  asset.copy_vis_attr_cache
+              SET   record = NEW.record,
+                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
+              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
+                    AND record = OLD.record;
+
+        ELSIF OLD.owning_lib <> NEW.owning_lib THEN
+            UPDATE  asset.copy_vis_attr_cache
+              SET   vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
+              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
+                    AND record = NEW.record;
+
+            IF NEW.label = '##URI##' THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
+                  WHERE id = OLD.record;
+            END IF;
+        END IF;
+
+    ELSIF TG_TABLE_NAME = 'record_entry' THEN -- Only handles ON UPDATE OR DELETE
+
+        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
+            DELETE FROM asset.copy_vis_attr_cache WHERE record = OLD.id;
+            RETURN OLD;
+        ELSIF OLD.source <> NEW.source THEN
+            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
+        END IF;
+
+    END IF;
+
+    RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+-- Helper functions for use in constructing searches --
+
+CREATE OR REPLACE FUNCTION asset.all_visible_flags () RETURNS TEXT AS $f$
+    SELECT  '(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(1 << x, 'copy_flags')),'&') || ')'
+      FROM  GENERATE_SERIES(0,0) AS x; -- increment as new flags are added.
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.visible_orgs (otype TEXT) RETURNS TEXT AS $f$
+    SELECT  '(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, $1)),'|') || ')'
+      FROM  actor.org_unit
+      WHERE opac_visible;
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.invisible_orgs (otype TEXT) RETURNS TEXT AS $f$
+    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, $1)),'|') || ')'
+      FROM  actor.org_unit
+      WHERE NOT opac_visible;
+$f$ LANGUAGE SQL STABLE;
+
+-- Bib-oriented defaults for search
+CREATE OR REPLACE FUNCTION asset.bib_source_default () RETURNS TEXT AS $f$
+    SELECT  '(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'bib_source')),'|') || ')'
+      FROM  config.bib_source
+      WHERE transcendant;
+$f$ LANGUAGE SQL IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION asset.luri_org_default () RETURNS TEXT AS $f$
+    SELECT  * FROM asset.invisible_orgs('luri_org');
+$f$ LANGUAGE SQL STABLE;
+
+-- Copy-oriented defaults for search
+CREATE OR REPLACE FUNCTION asset.location_group_default () RETURNS TEXT AS $f$
+    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'location_group')),'|') || ')'
+      FROM  asset.copy_location_group
+      WHERE NOT opac_visible;
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.location_default () RETURNS TEXT AS $f$
+    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'location')),'|') || ')'
+      FROM  asset.copy_location
+      WHERE NOT opac_visible;
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.status_default () RETURNS TEXT AS $f$
+    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'status')),'|') || ')'
+      FROM  config.copy_status
+      WHERE NOT opac_visible;
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.owning_lib_default () RETURNS TEXT AS $f$
+    SELECT  * FROM asset.invisible_orgs('owning_lib');
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.circ_lib_default () RETURNS TEXT AS $f$
+    SELECT  * FROM asset.invisible_orgs('circ_lib');
+$f$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION asset.patron_default_visibility_mask () RETURNS TABLE (b_attrs TEXT, c_attrs TEXT)  AS $f$
+DECLARE
+    copy_flags      TEXT; -- "c" attr
+
+    owning_lib      TEXT; -- "c" attr
+    circ_lib        TEXT; -- "c" attr
+    status          TEXT; -- "c" attr
+    location        TEXT; -- "c" attr
+    location_group  TEXT; -- "c" attr
+
+    luri_org        TEXT; -- "b" attr
+    bib_sources     TEXT; -- "b" attr
+BEGIN
+    copy_flags      := asset.all_visible_flags(); -- Will always have at least one
+
+    owning_lib      := NULLIF(asset.owning_lib_default(),'!()');
+    
+    circ_lib        := NULLIF(asset.circ_lib_default(),'!()');
+    status          := NULLIF(asset.status_default(),'!()');
+    location        := NULLIF(asset.location_default(),'!()');
+    location_group  := NULLIF(asset.location_group_default(),'!()');
+
+    luri_org        := NULLIF(asset.luri_org_default(),'!()');
+    bib_sources     := NULLIF(asset.bib_source_default(),'()');
+
+    RETURN QUERY SELECT
+        '('||ARRAY_TO_STRING(
+            ARRAY[luri_org,bib_sources],
+            '|'
+        )||')',
+        '('||ARRAY_TO_STRING(
+            ARRAY[copy_flags,owning_lib,circ_lib,status,location,location_group]::TEXT[],
+            '&'
+        )||')';
+END;
+$f$ LANGUAGE PLPGSQL STABLE ROWS 1;
+
+CREATE OR REPLACE FUNCTION metabib.suggest_browse_entries(raw_query_text text, search_class text, headline_opts text, visibility_org integer, query_limit integer, normalization integer)
+ RETURNS TABLE(value text, field integer, buoyant_and_class_match boolean, field_match boolean, field_weight integer, rank real, buoyant boolean, match text)
+AS $f$
+DECLARE
+    prepared_query_texts    TEXT[];
+    query                   TSQUERY;
+    plain_query             TSQUERY;
+    opac_visibility_join    TEXT;
+    search_class_join       TEXT;
+    r_fields                RECORD;
+BEGIN
+    prepared_query_texts := metabib.autosuggest_prepare_tsquery(raw_query_text);
+
+    query := TO_TSQUERY('keyword', prepared_query_texts[1]);
+    plain_query := TO_TSQUERY('keyword', prepared_query_texts[2]);
+
+    visibility_org := NULLIF(visibility_org,-1);
+    IF visibility_org IS NOT NULL THEN
+        PERFORM FROM actor.org_unit WHERE id = visibility_org AND parent_ou IS NULL;
+        IF FOUND THEN
+            opac_visibility_join := '';
+        ELSE
+            opac_visibility_join := '
+    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = x.source)
+    JOIN vm ON (acvac.vis_attr_vector @@
+            (vm.c_attrs || $$&$$ ||
+                search.calculate_visibility_attribute_test(
+                    $$circ_lib$$,
+                    (SELECT ARRAY_AGG(id) FROM actor.org_unit_descendants($4))
+                )
+            )::query_int
+         )
+';
+        END IF;
+    ELSE
+        opac_visibility_join := '';
+    END IF;
+
+    -- The following determines whether we only provide suggestsons matching
+    -- the user's selected search_class, or whether we show other suggestions
+    -- too. The reason for MIN() is that for search_classes like
+    -- 'title|proper|uniform' you would otherwise get multiple rows.  The
+    -- implication is that if title as a class doesn't have restrict,
+    -- nor does the proper field, but the uniform field does, you're going
+    -- to get 'false' for your overall evaluation of 'should we restrict?'
+    -- To invert that, change from MIN() to MAX().
+
+    SELECT
+        INTO r_fields
+            MIN(cmc.restrict::INT) AS restrict_class,
+            MIN(cmf.restrict::INT) AS restrict_field
+        FROM metabib.search_class_to_registered_components(search_class)
+            AS _registered (field_class TEXT, field INT)
+        JOIN
+            config.metabib_class cmc ON (cmc.name = _registered.field_class)
+        LEFT JOIN
+            config.metabib_field cmf ON (cmf.id = _registered.field);
+
+    -- evaluate 'should we restrict?'
+    IF r_fields.restrict_field::BOOL OR r_fields.restrict_class::BOOL THEN
+        search_class_join := '
+    JOIN
+        metabib.search_class_to_registered_components($2)
+        AS _registered (field_class TEXT, field INT) ON (
+            (_registered.field IS NULL AND
+                _registered.field_class = cmf.field_class) OR
+            (_registered.field = cmf.id)
+        )
+    ';
+    ELSE
+        search_class_join := '
+    LEFT JOIN
+        metabib.search_class_to_registered_components($2)
+        AS _registered (field_class TEXT, field INT) ON (
+            _registered.field_class = cmc.name
+        )
+    ';
+    END IF;
+
+    RETURN QUERY EXECUTE '
+WITH vm AS ( SELECT * FROM asset.patron_default_visibility_mask() ),
+     mbe AS (SELECT * FROM metabib.browse_entry WHERE index_vector @@ $1 LIMIT 10000)
+SELECT  DISTINCT
+        x.value,
+        x.id,
+        x.push,
+        x.restrict,
+        x.weight,
+        x.ts_rank_cd,
+        x.buoyant,
+        TS_HEADLINE(value, $7, $3)
+  FROM  (SELECT DISTINCT
+                mbe.value,
+                cmf.id,
+                cmc.buoyant AND _registered.field_class IS NOT NULL AS push,
+                _registered.field = cmf.id AS restrict,
+                cmf.weight,
+                TS_RANK_CD(mbe.index_vector, $1, $6),
+                cmc.buoyant,
+                mbedm.source
+          FROM  metabib.browse_entry_def_map mbedm
+                JOIN mbe ON (mbe.id = mbedm.entry)
+                JOIN config.metabib_field cmf ON (cmf.id = mbedm.def)
+                JOIN config.metabib_class cmc ON (cmf.field_class = cmc.name)
+                '  || search_class_join || '
+          ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
+          LIMIT 1000) AS x
+        ' || opac_visibility_join || '
+  ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
+  LIMIT $5
+'   -- sic, repeat the order by clause in the outer select too
+    USING
+        query, search_class, headline_opts,
+        visibility_org, query_limit, normalization, plain_query
+        ;
+
+    -- sort order:
+    --  buoyant AND chosen class = match class
+    --  chosen field = match field
+    --  field weight
+    --  rank
+    --  buoyancy
+    --  value itself
+
+END;
+$f$ LANGUAGE plpgsql ROWS 10;
+
+/* COMMENT OUT THE FIRST UPDATE SO WE THERE IS NOT NEED TO PATCH BOTH 
+CREATE OR REPLACE FUNCTION metabib.browse(search_field integer[], browse_term text, context_org integer DEFAULT NULL::integer, context_loc_group integer DEFAULT NULL::integer, staff boolean DEFAULT false, pivot_id bigint DEFAULT NULL::bigint, result_limit integer DEFAULT 10)
+ RETURNS SETOF metabib.flat_browse_entry_appearance
+AS $f$
+DECLARE
+    core_query              TEXT;
+    back_query              TEXT;
+    forward_query           TEXT;
+    pivot_sort_value        TEXT;
+    pivot_sort_fallback     TEXT;
+    context_locations       INT[];
+    browse_superpage_size   INT;
+    results_skipped         INT := 0;
+    back_limit              INT;
+    back_to_pivot           INT;
+    forward_limit           INT;
+    forward_to_pivot        INT;
+BEGIN
+    -- First, find the pivot if we were given a browse term but not a pivot.
+    IF pivot_id IS NULL THEN
+        pivot_id := metabib.browse_pivot(search_field, browse_term);
+    END IF;
+
+    SELECT INTO pivot_sort_value, pivot_sort_fallback
+        sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
+
+    -- Bail if we couldn't find a pivot.
+    IF pivot_sort_value IS NULL THEN
+        RETURN;
+    END IF;
+
+    -- Transform the context_loc_group argument (if any) (logc at the
+    -- TPAC layer) into a form we'll be able to use.
+    IF context_loc_group IS NOT NULL THEN
+        SELECT INTO context_locations ARRAY_AGG(location)
+            FROM asset.copy_location_group_map
+            WHERE lgroup = context_loc_group;
+    END IF;
+
+    -- Get the configured size of browse superpages.
+    SELECT INTO browse_superpage_size COALESCE(value::INT,100)     -- NULL ok
+        FROM config.global_flag
+        WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
+
+    -- First we're going to search backward from the pivot, then we're going
+    -- to search forward.  In each direction, we need two limits.  At the
+    -- lesser of the two limits, we delineate the edge of the result set
+    -- we're going to return.  At the greater of the two limits, we find the
+    -- pivot value that would represent an offset from the current pivot
+    -- at a distance of one "page" in either direction, where a "page" is a
+    -- result set of the size specified in the "result_limit" argument.
+    --
+    -- The two limits in each direction make four derived values in total,
+    -- and we calculate them now.
+    back_limit := CEIL(result_limit::FLOAT / 2);
+    back_to_pivot := result_limit;
+    forward_limit := result_limit / 2;
+    forward_to_pivot := result_limit - 1;
+
+    -- This is the meat of the SQL query that finds browse entries.  We'll
+    -- pass this to a function which uses it with a cursor, so that individual
+    -- rows may be fetched in a loop until some condition is satisfied, without
+    -- waiting for a result set of fixed size to be collected all at once.
+    core_query := '
+SELECT  mbe.id,
+        mbe.value,
+        mbe.sort_value
+  FROM  metabib.browse_entry mbe
+  WHERE (
+            EXISTS ( -- are there any bibs using this mbe via the requested fields?
+                SELECT  1
+                  FROM  metabib.browse_entry_def_map mbedm
+                  WHERE mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ')
+            ) OR EXISTS ( -- are there any authorities using this mbe via the requested fields?
+                SELECT  1
+                  FROM  metabib.browse_entry_simple_heading_map mbeshm
+                        JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+                        JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                            ash.atag = map.authority_field
+                            AND map.metabib_field = ANY(' || quote_literal(search_field) || ')
+                        )
+                  WHERE mbeshm.entry = mbe.id
+            )
+        ) AND ';
+
+    -- This is the variant of the query for browsing backward.
+    back_query := core_query ||
+        ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
+    ' ORDER BY mbe.sort_value DESC, mbe.value DESC LIMIT 1000';
+
+    -- This variant browses forward.
+    forward_query := core_query ||
+        ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
+    ' ORDER BY mbe.sort_value, mbe.value LIMIT 1000';
+
+    -- We now call the function which applies a cursor to the provided
+    -- queries, stopping at the appropriate limits and also giving us
+    -- the next page's pivot.
+    RETURN QUERY
+        SELECT * FROM metabib.staged_browse(
+            back_query, search_field, context_org, context_locations,
+            staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
+        ) UNION
+        SELECT * FROM metabib.staged_browse(
+            forward_query, search_field, context_org, context_locations,
+            staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
+        ) ORDER BY row_number DESC;
+END; $f$ LANGUAGE plpgsql ROWS 10;
+
+CREATE OR REPLACE FUNCTION metabib.staged_browse(query text, fields integer[], context_org integer, context_locations integer[], staff boolean, browse_superpage_size integer, count_up_from_zero boolean, result_limit integer, next_pivot_pos integer)
+ RETURNS SETOF metabib.flat_browse_entry_appearance
+AS $f$
+DECLARE
+    curs                    REFCURSOR;
+    rec                     RECORD;
+    qpfts_query             TEXT;
+    aqpfts_query            TEXT;
+    afields                 INT[];
+    bfields                 INT[];
+    result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
+    results_skipped         INT := 0;
+    row_counter             INT := 0;
+    row_number              INT;
+    slice_start             INT;
+    slice_end               INT;
+    full_end                INT;
+    all_records             BIGINT[];
+    all_brecords             BIGINT[];
+    all_arecords            BIGINT[];
+    superpage_of_records    BIGINT[];
+    superpage_size          INT;
+    c_tests                 TEXT := '';
+    b_tests                 TEXT := '';
+    c_orgs                  INT[];
+BEGIN
+    IF count_up_from_zero THEN
+        row_number := 0;
+    ELSE
+        row_number := -1;
+    END IF;
+
+    IF NOT staff THEN
+        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
+    END IF;
+
+    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+    IF b_tests <> '' THEN b_tests := b_tests || '&'; END IF;
+
+    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
+    
+    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
+               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
+    
+    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
+    IF FOUND THEN
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
+        );
+    ELSE
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
+        );
+    END IF;
+
+    IF context_locations THEN
+        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_locations);
+    END IF;
+
+    OPEN curs NO SCROLL FOR EXECUTE query;
+
+    LOOP
+        FETCH curs INTO rec;
+        IF NOT FOUND THEN
+            IF result_row.pivot_point IS NOT NULL THEN
+                RETURN NEXT result_row;
+            END IF;
+            RETURN;
+        END IF;
+
+        -- Gather aggregate data based on the MBE row we're looking at now, authority axis
+        SELECT INTO all_arecords, result_row.sees, afields
+                ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
+                STRING_AGG(DISTINCT aal.source::TEXT, $$,$$), -- authority record ids
+                ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
+
+          FROM  metabib.browse_entry_simple_heading_map mbeshm
+                JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+                JOIN authority.authority_linking aal ON ( ash.record = aal.source )
+                JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
+                JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                    ash.atag = map.authority_field
+                    AND map.metabib_field = ANY(fields)
+                )
+          WHERE mbeshm.entry = rec.id;
+
+        -- Gather aggregate data based on the MBE row we're looking at now, bib axis
+        SELECT INTO all_brecords, result_row.authorities, bfields
+                ARRAY_AGG(DISTINCT source),
+                STRING_AGG(DISTINCT authority::TEXT, $$,$$),
+                ARRAY_AGG(DISTINCT def)
+          FROM  metabib.browse_entry_def_map
+          WHERE entry = rec.id
+                AND def = ANY(fields);
+
+        SELECT INTO result_row.fields STRING_AGG(DISTINCT x::TEXT, $$,$$) FROM UNNEST(afields || bfields) x;
+
+        result_row.sources := 0;
+        result_row.asources := 0;
+
+        -- Bib-linked vis checking
+        IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
+
+            SELECT  INTO result_row.sources COUNT(DISTINCT b.id)
+              FROM  biblio.record_entry b
+                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+              WHERE b.id = ANY(all_brecords[1:browse_superpage_size])
+                    AND (
+                        acvac.vis_attr_vector @@ c_tests::query_int
+                        OR b.vis_attr_vector @@ b_tests::query_int
+                    );
+
+            result_row.accurate := TRUE;
+
+        END IF;
+
+        -- Authority-linked vis checking
+        IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
+
+            SELECT  INTO result_row.asources COUNT(DISTINCT b.id)
+              FROM  biblio.record_entry b
+                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+              WHERE b.id = ANY(all_arecords[1:browse_superpage_size])
+                    AND (
+                        acvac.vis_attr_vector @@ c_tests::query_int
+                        OR b.vis_attr_vector @@ b_tests::query_int
+                    );
+
+            result_row.aaccurate := TRUE;
+
+        END IF;
+
+        IF result_row.sources > 0 OR result_row.asources > 0 THEN
+
+            -- The function that calls this function needs row_number in order
+            -- to correctly order results from two different runs of this
+            -- functions.
+            result_row.row_number := row_number;
+
+            -- Now, if row_counter is still less than limit, return a row.  If
+            -- not, but it is less than next_pivot_pos, continue on without
+            -- returning actual result rows until we find
+            -- that next pivot, and return it.
+
+            IF row_counter < result_limit THEN
+                result_row.browse_entry := rec.id;
+                result_row.value := rec.value;
+
+                RETURN NEXT result_row;
+            ELSE
+                result_row.browse_entry := NULL;
+                result_row.authorities := NULL;
+                result_row.fields := NULL;
+                result_row.value := NULL;
+                result_row.sources := NULL;
+                result_row.sees := NULL;
+                result_row.accurate := NULL;
+                result_row.aaccurate := NULL;
+                result_row.pivot_point := rec.id;
+
+                IF row_counter >= next_pivot_pos THEN
+                    RETURN NEXT result_row;
+                    RETURN;
+                END IF;
+            END IF;
+
+            IF count_up_from_zero THEN
+                row_number := row_number + 1;
+            ELSE
+                row_number := row_number - 1;
+            END IF;
+
+            -- row_counter is different from row_number.
+            -- It simply counts up from zero so that we know when
+            -- we've reached our limit.
+            row_counter := row_counter + 1;
+        END IF;
+    END LOOP;
+END;
+$f$ LANGUAGE plpgsql ROWS 10;
+*/
+
+CREATE OR REPLACE FUNCTION asset.opac_ou_record_copy_count (org INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
+DECLARE
+    ans RECORD;
+    trans INT;
+BEGIN
+    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
+
+    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
+        RETURN QUERY
+        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
+             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
+             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
+        SELECT  ans.depth,
+                ans.id,
+                COUNT( av.id ),
+                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
+                COUNT( av.id ),
+                trans
+          FROM  mask,
+                available_statuses,
+                org_list,
+                asset.copy_vis_attr_cache av
+                JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
+          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
+          GROUP BY 1,2,6;
+
+        IF NOT FOUND THEN
+            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
+        END IF;
+
+    END LOOP;
+
+    RETURN;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION asset.opac_lasso_record_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
+DECLARE
+    ans RECORD;
+    trans INT;
+BEGIN
+    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
+
+    FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
+        RETURN QUERY
+        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
+             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
+             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
+        SELECT  -1,
+                ans.id,
+                COUNT( av.id ),
+                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
+                COUNT( av.id ),
+                trans
+          FROM  mask,
+                org_list,
+                asset.copy_vis_attr_cache av
+                JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
+          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
+          GROUP BY 1,2,6;
+
+        IF NOT FOUND THEN
+            RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
+        END IF;
+
+    END LOOP;
+
+    RETURN;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION asset.opac_ou_metarecord_copy_count (org INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
+DECLARE
+    ans RECORD;
+    trans INT;
+BEGIN
+    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) JOIN metabib.metarecord_source_map m ON (m.source = b.id) WHERE src.transcendant AND m.metarecord = rid;
+
+    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
+        RETURN QUERY
+        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
+             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
+             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
+        SELECT  ans.depth,
+                ans.id,
+                COUNT( av.id ),
+                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
+                COUNT( av.id ),
+                trans
+          FROM  mask,
+                org_list,
+                available_statuses,
+                asset.copy_vis_attr_cache av
+                JOIN asset.copy cp ON (cp.id = av.target_copy)
+                JOIN metabib.metarecord_source_map m ON (m.metarecord = rid AND m.source = av.record)
+          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
+          GROUP BY 1,2,6;
+
+        IF NOT FOUND THEN
+            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
+        END IF;
+
+    END LOOP;
+
+    RETURN;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION asset.opac_lasso_metarecord_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
+DECLARE
+    ans RECORD;
+    trans INT;
+BEGIN
+    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) JOIN metabib.metarecord_source_map m ON (m.source = b.id) WHERE src.transcendant AND m.metarecord = rid;
+
+    FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
+        RETURN QUERY
+        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
+             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
+             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
+        SELECT  -1,
+                ans.id,
+                COUNT( av.id ),
+                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
+                COUNT( av.id ),
+                trans
+          FROM  mask,
+                org_list,
+                available_statuses,
+                asset.copy_vis_attr_cache av
+                JOIN asset.copy cp ON (cp.id = av.target_copy)
+                JOIN metabib.metarecord_source_map m ON (m.metarecord = rid AND m.source = av.record)
+          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
+          GROUP BY 1,2,6;
+
+        IF NOT FOUND THEN
+            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
+        END IF;
+
+    END LOOP;
+
+    RETURN;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION unapi.mmr_mra (
+    obj_id BIGINT,
+    format TEXT,
+    ename TEXT,
+    includes TEXT[],
+    org TEXT,
+    depth INT DEFAULT NULL,
+    slimit HSTORE DEFAULT NULL,
+    soffset HSTORE DEFAULT NULL,
+    include_xmlns BOOL DEFAULT TRUE,
+    pref_lib INT DEFAULT NULL
+) RETURNS XML AS $F$
+    SELECT  XMLELEMENT(
+        name attributes,
+        XMLATTRIBUTES(
+            CASE WHEN $9 THEN 'http://open-ils.org/spec/indexing/v1' ELSE NULL END AS xmlns,
+            'tag:open-ils.org:U2@mmr/' || $1 AS metarecord
+        ),
+        (SELECT XMLAGG(foo.y)
+          FROM (
+            WITH sourcelist AS (
+                WITH aou AS (SELECT COALESCE(id, (evergreen.org_top()).id) AS id FROM actor.org_unit WHERE shortname = $5 LIMIT 1),
+                     basevm AS (SELECT c_attrs FROM  asset.patron_default_visibility_mask()),
+                     circvm AS (SELECT search.calculate_visibility_attribute_test('circ_lib', ARRAY_AGG(aoud.id)) AS mask
+                                  FROM aou, LATERAL actor.org_unit_descendants(aou.id, $6) aoud)
+                SELECT  source
+                  FROM  aou, circvm, basevm, metabib.metarecord_source_map mmsm
+                  WHERE mmsm.metarecord = $1 AND (
+                    EXISTS (
+                        SELECT  1
+                          FROM  circvm, basevm, asset.copy_vis_attr_cache acvac
+                          WHERE acvac.vis_attr_vector @@ (basevm.c_attrs || '&' || circvm.mask)::query_int
+                                AND acvac.record = mmsm.source
+                    )
+                    OR EXISTS (SELECT 1 FROM evergreen.located_uris(source, aou.id, $10) LIMIT 1)
+                    OR EXISTS (SELECT 1 FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = mmsm.source)
+                )
+            )
+            SELECT  cmra.aid,
+                    XMLELEMENT(
+                        name field,
+                        XMLATTRIBUTES(
+                            cmra.attr AS name,
+                            cmra.value AS "coded-value",
+                            cmra.aid AS "cvmid",
+                            rad.composite,
+                            rad.multi,
+                            rad.filter,
+                            rad.sorter,
+                            cmra.source_list
+                        ),
+                        cmra.value
+                    )
+              FROM  (
+                SELECT DISTINCT aid, attr, value, STRING_AGG(x.id::TEXT, ',') AS source_list
+                  FROM (
+                    SELECT  v.source AS id,
+                            c.id AS aid,
+                            c.ctype AS attr,
+                            c.code AS value
+                      FROM  metabib.record_attr_vector_list v
+                            JOIN config.coded_value_map c ON ( c.id = ANY( v.vlist ) )
+                    ) AS x
+                    JOIN sourcelist ON (x.id = sourcelist.source)
+                    GROUP BY 1, 2, 3
+                ) AS cmra
+                JOIN config.record_attr_definition rad ON (cmra.attr = rad.name)
+                UNION ALL
+            SELECT  umra.aid,
+                    XMLELEMENT(
+                        name field,
+                        XMLATTRIBUTES(
+                            umra.attr AS name,
+                            rad.composite,
+                            rad.multi,
+                            rad.filter,
+                            rad.sorter
+                        ),
+                        umra.value
+                    )
+              FROM  (
+                SELECT DISTINCT aid, attr, value
+                  FROM (
+                    SELECT  v.source AS id,
+                            m.id AS aid,
+                            m.attr AS attr,
+                            m.value AS value
+                      FROM  metabib.record_attr_vector_list v
+                            JOIN metabib.uncontrolled_record_attr_value m ON ( m.id = ANY( v.vlist ) )
+                    ) AS x
+                    JOIN sourcelist ON (x.id = sourcelist.source)
+                ) AS umra
+                JOIN config.record_attr_definition rad ON (umra.attr = rad.name)
+                ORDER BY 1
+
+            )foo(id,y)
+        )
+    )
+$F$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE FUNCTION evergreen.ranked_volumes(
+    bibid BIGINT[],
+    ouid INT,
+    depth INT DEFAULT NULL,
+    slimit HSTORE DEFAULT NULL,
+    soffset HSTORE DEFAULT NULL,
+    pref_lib INT DEFAULT NULL,
+    includes TEXT[] DEFAULT NULL::TEXT[]
+) RETURNS TABLE(id BIGINT, name TEXT, label_sortkey TEXT, rank BIGINT) AS $$
+    WITH RECURSIVE ou_depth AS (
+        SELECT COALESCE(
+            $3,
+            (
+                SELECT depth
+                FROM actor.org_unit_type aout
+                    INNER JOIN actor.org_unit ou ON ou_type = aout.id
+                WHERE ou.id = $2
+            )
+        ) AS depth
+    ), descendant_depth AS (
+        SELECT  ou.id,
+                ou.parent_ou,
+                out.depth
+        FROM  actor.org_unit ou
+                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+                JOIN anscestor_depth ad ON (ad.id = ou.id),
+                ou_depth
+        WHERE ad.depth = ou_depth.depth
+            UNION ALL
+        SELECT  ou.id,
+                ou.parent_ou,
+                out.depth
+        FROM  actor.org_unit ou
+                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+                JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
+    ), anscestor_depth AS (
+        SELECT  ou.id,
+                ou.parent_ou,
+                out.depth
+        FROM  actor.org_unit ou
+                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+        WHERE ou.id = $2
+            UNION ALL
+        SELECT  ou.id,
+                ou.parent_ou,
+                out.depth
+        FROM  actor.org_unit ou
+                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+                JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
+    ), descendants as (
+        SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id)
+    )
+
+    SELECT ua.id, ua.name, ua.label_sortkey, MIN(ua.rank) AS rank FROM (
+        SELECT acn.id, owning_lib.name, acn.label_sortkey,
+            evergreen.rank_cp(acp),
+            RANK() OVER w
+        FROM asset.call_number acn
+            JOIN asset.copy acp ON (acn.id = acp.call_number)
+            JOIN descendants AS aou ON (acp.circ_lib = aou.id)
+            JOIN actor.org_unit AS owning_lib ON (acn.owning_lib = owning_lib.id)
+        WHERE acn.record = ANY ($1)
+            AND acn.deleted IS FALSE
+            AND acp.deleted IS FALSE
+            AND CASE WHEN ('exclude_invisible_acn' = ANY($7)) THEN
+                EXISTS (
+                    WITH basevm AS (SELECT c_attrs FROM  asset.patron_default_visibility_mask()),
+                         circvm AS (SELECT search.calculate_visibility_attribute_test('circ_lib', ARRAY[acp.circ_lib]) AS mask)
+                    SELECT  1
+                      FROM  basevm, circvm, asset.copy_vis_attr_cache acvac
+                      WHERE acvac.vis_attr_vector @@ (basevm.c_attrs || '&' || circvm.mask)::query_int
+                            AND acvac.target_copy = acp.id
+                            AND acvac.record = acn.record
+                ) ELSE TRUE END
+        GROUP BY acn.id, evergreen.rank_cp(acp), owning_lib.name, acn.label_sortkey, aou.id
+        WINDOW w AS (
+            ORDER BY
+                COALESCE(
+                    CASE WHEN aou.id = $2 THEN -20000 END,
+                    CASE WHEN aou.id = $6 THEN -10000 END,
+                    (SELECT distance - 5000
+                        FROM actor.org_unit_descendants_distance($6) as x
+                        WHERE x.id = aou.id AND $6 IN (
+                            SELECT q.id FROM actor.org_unit_descendants($2) as q)),
+                    (SELECT e.distance FROM actor.org_unit_descendants_distance($2) as e WHERE e.id = aou.id),
+                    1000
+                ),
+                evergreen.rank_cp(acp)
+        )
+    ) AS ua
+    GROUP BY ua.id, ua.name, ua.label_sortkey
+    ORDER BY rank, ua.name, ua.label_sortkey
+    LIMIT ($4 -> 'acn')::INT
+    OFFSET ($5 -> 'acn')::INT;
+$$ LANGUAGE SQL STABLE ROWS 10;
+
+
+-- Evergreen DB patch XXXX.schema.action-trigger.event_definition.sms_preminder.sql
+--
+-- New action trigger event definition: 3 Day Courtesy Notice by SMS
+--
+
+-- check whether patch can be applied
+-- SELECT evergreen.upgrade_deps_block_check('1058', :eg_version); -- mccanna/csharp/gmcharlt
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+INSERT INTO action_trigger.event_definition (id, active, owner, name, hook,
+        validator, reactor, delay, max_delay, delay_field, group_field, template)
+    VALUES (54, FALSE, 1,
+        '3 Day Courtesy Notice by SMS',
+        'checkout.due',
+        'CircIsOpen', 'SendSMS', '-3 days', '-2 days', 'due_date', 'usr',
+$$
+[%- USE date -%]
+[%- user = target.0.usr -%]
+[%- homelib = user.home_ou -%]
+[%- sms_number = helpers.get_user_setting(user.id, 'opac.default_sms_notify') -%]
+[%- sms_carrier = helpers.get_user_setting(user.id, 'opac.default_sms_carrier') -%]
+From: [%- helpers.get_org_setting(homelib.id, 'org.bounced_emails') || homelib.email || params.sender_email || default_sender %]
+To: [%- helpers.get_sms_gateway_email(sms_carrier,sms_number) %]
+Subject: Library Materials Due Soon
+
+You have items due soon:
+
+[% FOR circ IN target %]
+[%- copy_details = helpers.get_copy_bib_basics(circ.target_copy.id) -%]
+[% copy_details.title FILTER ucfirst %] by [% copy_details.author FILTER ucfirst %] due on [% date.format(helpers.format_date(circ.due_date), '%m-%d-%Y') %]
+
+[% END %]
+
+$$);
+
+INSERT INTO action_trigger.environment (event_def, path) VALUES
+    (54, 'circ_lib.billing_address'),
+    (54, 'target_copy.call_number'),
+    (54, 'usr'),
+    (54, 'usr.home_ou');
+
+END IF; END $INSERT$;                                                          
+
+
+-- check whether patch can be applied
+-- SELECT evergreen.upgrade_deps_block_check('1059', :eg_version); --Stompro/DPearl/kmlussier
+
+CREATE OR REPLACE VIEW reporter.old_super_simple_record AS
+SELECT  r.id,
+    r.fingerprint,
+    r.quality,
+    r.tcn_source,
+    r.tcn_value,
+    CONCAT_WS(' ', FIRST(title.value),FIRST(title_np.val)) AS title,
+    FIRST(author.value) AS author,
+    STRING_AGG(DISTINCT publisher.value, ', ') AS publisher,
+    STRING_AGG(DISTINCT SUBSTRING(pubdate.value FROM $$\d+$$), ', ') AS pubdate,
+    CASE WHEN ARRAY_AGG( DISTINCT REPLACE(SUBSTRING(isbn.value FROM $$^\S+$$), '-', '') ) = '{NULL}'
+        THEN NULL
+        ELSE ARRAY_AGG( DISTINCT REPLACE(SUBSTRING(isbn.value FROM $$^\S+$$), '-', '') )
+    END AS isbn,
+    CASE WHEN ARRAY_AGG( DISTINCT REGEXP_REPLACE(issn.value, E'^\\S*(\\d{4})[-\\s](\\d{3,4}x?)', E'\\1 \\2') ) = '{NULL}'
+        THEN NULL
+        ELSE ARRAY_AGG( DISTINCT REGEXP_REPLACE(issn.value, E'^\\S*(\\d{4})[-\\s](\\d{3,4}x?)', E'\\1 \\2') )
+    END AS issn
+  FROM  biblio.record_entry r
+    LEFT JOIN metabib.full_rec title ON (r.id = title.record AND title.tag = '245' AND title.subfield = 'a')
+    LEFT JOIN ( -- Grab 245 N and P subfields in the order that they appear.
+      SELECT b.record, string_agg(val, ' ') AS val FROM (
+            SELECT title_np.record, title_np.value AS val
+             FROM metabib.full_rec title_np
+             WHERE
+             title_np.tag = '245'
+                       AND title_np.subfield IN ('p','n')                      
+                       ORDER BY title_np.id
+               ) b
+               GROUP BY 1
+        ) title_np ON (title_np.record=r.id) 
+    LEFT JOIN metabib.full_rec author ON (r.id = author.record AND author.tag IN ('100','110','111') AND author.subfield = 'a')
+    LEFT JOIN metabib.full_rec publisher ON (r.id = publisher.record AND (publisher.tag = '260' OR (publisher.tag = '264' AND publisher.ind2 = '1')) AND publisher.subfield = 'b')
+    LEFT JOIN metabib.full_rec pubdate ON (r.id = pubdate.record AND (pubdate.tag = '260' OR (pubdate.tag = '264' AND pubdate.ind2 = '1')) AND pubdate.subfield = 'c')
+    LEFT JOIN metabib.full_rec isbn ON (r.id = isbn.record AND isbn.tag IN ('024', '020') AND isbn.subfield IN ('a','z'))
+    LEFT JOIN metabib.full_rec issn ON (r.id = issn.record AND issn.tag = '022' AND issn.subfield = 'a')
+  GROUP BY 1,2,3,4,5;
+
+  
+  -- Remove trigger on biblio.record_entry
+  SELECT reporter.disable_materialized_simple_record_trigger();
+  
+  -- Rebuild reporter.materialized_simple_record
+  SELECT reporter.enable_materialized_simple_record_trigger();
+  
+
+-- SELECT evergreen.upgrade_deps_block_check('1060', :eg_version);
+
+DROP VIEW IF EXISTS extend_reporter.copy_count_per_org;
+
+CREATE OR REPLACE VIEW extend_reporter.copy_count_per_org AS
+ SELECT acn.record AS bibid,
+    ac.circ_lib,
+    acn.owning_lib,
+    max(ac.edit_date) AS last_edit_time,
+    min(ac.deleted::integer) AS has_only_deleted_copies,
+    count(
+        CASE
+            WHEN ac.deleted THEN ac.id
+            ELSE NULL::bigint
+        END) AS deleted_count,
+    count(
+        CASE
+            WHEN NOT ac.deleted THEN ac.id
+            ELSE NULL::bigint
+        END) AS visible_count,
+    count(*) AS total_count
+   FROM asset.call_number acn,
+    asset.copy ac
+  WHERE ac.call_number = acn.id
+  GROUP BY acn.record, acn.owning_lib, ac.circ_lib;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1061', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+INSERT INTO config.org_unit_setting_type
+    (name, label, description, grp, datatype)
+VALUES (
+    'ui.staff.max_recent_patrons',
+    oils_i18n_gettext(
+        'ui.staff.max_recent_patrons',
+        'Number of Retrievable Recent Patrons',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.staff.max_recent_patrons',
+        'Number of most recently accessed patrons that can be re-retrieved ' ||
+        'in the staff client.  A value of 0 or less disables the feature. Defaults to 1.',
+        'coust',
+        'description'
+    ),
+    'circ',
+    'integer'
+);
+
+END IF; END $INSERT$;                                                          
+
+-- SELECT evergreen.upgrade_deps_block_check('1062', :eg_version);
+
+CREATE TABLE acq.edi_attr (
+    key     TEXT PRIMARY KEY,
+    label   TEXT NOT NULL UNIQUE
+);
+
+CREATE TABLE acq.edi_attr_set (
+    id      SERIAL  PRIMARY KEY,
+    label   TEXT NOT NULL UNIQUE
+);
+
+CREATE TABLE acq.edi_attr_set_map (
+    id          SERIAL  PRIMARY KEY,
+    attr_set    INTEGER NOT NULL REFERENCES acq.edi_attr_set(id) 
+                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    attr        TEXT NOT NULL REFERENCES acq.edi_attr(key) 
+                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    CONSTRAINT edi_attr_set_map_attr_once UNIQUE (attr_set, attr)
+);
+
+-- An attr_set is not strictly required, since some edi_accounts/vendors 
+-- may not need to apply any attributes.
+ALTER TABLE acq.edi_account 
+    ADD COLUMN attr_set INTEGER REFERENCES acq.edi_attr_set(id),
+    ADD COLUMN use_attrs BOOLEAN NOT NULL DEFAULT FALSE;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1063', :eg_version);
+
+DO $temp$
+DECLARE
+       r RECORD;
+BEGIN
+
+       FOR r IN SELECT t.table_schema AS sname,
+                       t.table_name AS tname,
+                       t.column_name AS colname,
+                       t.constraint_name
+                 FROM  information_schema.referential_constraints ref
+                       JOIN information_schema.key_column_usage t USING (constraint_schema,constraint_name)
+                 WHERE ref.unique_constraint_schema = 'asset'
+                       AND ref.unique_constraint_name = 'copy_pkey'
+       LOOP
+
+               EXECUTE 'ALTER TABLE '||r.sname||'.'||r.tname||' DROP CONSTRAINT '||r.constraint_name||';';
+
+               EXECUTE '
+                       CREATE OR REPLACE FUNCTION evergreen.'||r.sname||'_'||r.tname||'_'||r.colname||'_inh_fkey() RETURNS TRIGGER AS $f$
+                       BEGIN
+                               PERFORM 1 FROM asset.copy WHERE id = NEW.'||r.colname||';
+                               IF NOT FOUND THEN
+                                       RAISE foreign_key_violation USING MESSAGE = FORMAT(
+                                               $$Referenced asset.copy id not found, '||r.colname||':%s$$, NEW.'||r.colname||'
+                                       );
+                               END IF;
+                               RETURN NEW;
+                       END;
+                       $f$ LANGUAGE PLPGSQL VOLATILE COST 50;
+               ';
+
+               EXECUTE '
+                       CREATE CONSTRAINT TRIGGER inherit_'||r.constraint_name||'
+                               AFTER UPDATE OR INSERT OR DELETE ON '||r.sname||'.'||r.tname||'
+                               DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.'||r.sname||'_'||r.tname||'_'||r.colname||'_inh_fkey();
+               ';
+       END LOOP;
+END
+$temp$;
+
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1064', :eg_version);
+
+ALTER TABLE serial.issuance DROP CONSTRAINT IF EXISTS issuance_caption_and_pattern_fkey;
+
+-- Using NOT VALID and VALIDATE CONSTRAINT limits the impact to concurrent work.
+-- For details, see: https://www.postgresql.org/docs/current/static/sql-altertable.html
+
+ALTER TABLE serial.issuance ADD CONSTRAINT issuance_caption_and_pattern_fkey
+    FOREIGN KEY (caption_and_pattern)
+    REFERENCES serial.caption_and_pattern (id)
+    ON DELETE CASCADE
+    DEFERRABLE INITIALLY DEFERRED
+    NOT VALID;
+
+ALTER TABLE serial.issuance VALIDATE CONSTRAINT issuance_caption_and_pattern_fkey;
+
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1065', :eg_version);
+
+CREATE TABLE serial.pattern_template (
+    id            SERIAL PRIMARY KEY,
+    name          TEXT NOT NULL,
+    pattern_code  TEXT NOT NULL,
+    owning_lib    INTEGER REFERENCES actor.org_unit(id) DEFERRABLE INITIALLY DEFERRED,
+    share_depth   INTEGER NOT NULL DEFAULT 0
+);
+CREATE INDEX serial_pattern_template_name_idx ON serial.pattern_template (evergreen.lowercase(name));
+
+CREATE OR REPLACE FUNCTION serial.pattern_templates_visible_to(org_unit INT) RETURNS SETOF serial.pattern_template AS $func$
+BEGIN
+    RETURN QUERY SELECT *
+           FROM serial.pattern_template spt
+           WHERE (
+             SELECT ARRAY_AGG(id)
+             FROM actor.org_unit_descendants(spt.owning_lib, spt.share_depth)
+           ) @@ org_unit::TEXT::QUERY_INT;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1066', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+ ( 593, 'ADMIN_SERIAL_PATTERN_TEMPLATE', oils_i18n_gettext( 593,
+    'Administer serial prediction pattern templates', 'ppl', 'description' ))
+;
+
+INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
+    SELECT
+        pgt.id, perm.id, aout.depth, FALSE
+    FROM
+        permission.grp_tree pgt,
+        permission.perm_list perm,
+        actor.org_unit_type aout
+    WHERE
+        pgt.name = 'Serials' AND
+        aout.name = 'System' AND
+        perm.code IN (
+            'ADMIN_SERIAL_PATTERN_TEMPLATE'
+        );
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1067', :eg_version);
+
+INSERT INTO acq.edi_attr (key, label) VALUES
+    ('INCLUDE_PO_NAME', 
+        oils_i18n_gettext('INCLUDE_PO_NAME', 
+        'Orders Include PO Name', 'aea', 'label')),
+    ('INCLUDE_COPIES', 
+        oils_i18n_gettext('INCLUDE_COPIES', 
+        'Orders Include Copy Data', 'aea', 'label')),
+    ('INCLUDE_FUND', 
+        oils_i18n_gettext('INCLUDE_FUND', 
+        'Orders Include Copy Funds', 'aea', 'label')),
+    ('INCLUDE_CALL_NUMBER', 
+        oils_i18n_gettext('INCLUDE_CALL_NUMBER', 
+        'Orders Include Copy Call Numbers', 'aea', 'label')),
+    ('INCLUDE_ITEM_TYPE', 
+        oils_i18n_gettext('INCLUDE_ITEM_TYPE', 
+        'Orders Include Copy Item Types', 'aea', 'label')),
+    ('INCLUDE_ITEM_BARCODE',
+        oils_i18n_gettext('INCLUDE_ITEM_BARCODE',
+        'Orders Include Copy Barcodes', 'aea', 'label')),
+    ('INCLUDE_LOCATION', 
+        oils_i18n_gettext('INCLUDE_LOCATION', 
+        'Orders Include Copy Locations', 'aea', 'label')),
+    ('INCLUDE_COLLECTION_CODE', 
+        oils_i18n_gettext('INCLUDE_COLLECTION_CODE', 
+        'Orders Include Copy Collection Codes', 'aea', 'label')),
+    ('INCLUDE_OWNING_LIB', 
+        oils_i18n_gettext('INCLUDE_OWNING_LIB', 
+        'Orders Include Copy Owning Library', 'aea', 'label')),
+    ('USE_ID_FOR_OWNING_LIB',
+        oils_i18n_gettext('USE_ID_FOR_OWNING_LIB',
+        'Emit Owning Library ID Rather Than Short Name. Takes effect only if INCLUDE_OWNING_LIB is in use', 'aea', 'label')),
+    ('INCLUDE_QUANTITY', 
+        oils_i18n_gettext('INCLUDE_QUANTITY', 
+        'Orders Include Copy Quantities', 'aea', 'label')),
+    ('INCLUDE_COPY_ID', 
+        oils_i18n_gettext('INCLUDE_COPY_ID', 
+        'Orders Include Copy IDs', 'aea', 'label')),
+    ('BUYER_ID_INCLUDE_VENDCODE', 
+        oils_i18n_gettext('BUYER_ID_INCLUDE_VENDCODE', 
+        'Buyer ID Qualifier Includes Vendcode', 'aea', 'label')),
+    ('BUYER_ID_ONLY_VENDCODE', 
+        oils_i18n_gettext('BUYER_ID_ONLY_VENDCODE', 
+        'Buyer ID Qualifier Only Contains Vendcode', 'aea', 'label')),
+    ('INCLUDE_BIB_EDITION', 
+        oils_i18n_gettext('INCLUDE_BIB_EDITION', 
+        'Order Lineitems Include Edition Info', 'aea', 'label')),
+    ('INCLUDE_BIB_AUTHOR', 
+        oils_i18n_gettext('INCLUDE_BIB_AUTHOR', 
+        'Order Lineitems Include Author Info', 'aea', 'label')),
+    ('INCLUDE_BIB_PAGINATION', 
+        oils_i18n_gettext('INCLUDE_BIB_PAGINATION', 
+        'Order Lineitems Include Pagination Info', 'aea', 'label')),
+    ('COPY_SPEC_CODES', 
+        oils_i18n_gettext('COPY_SPEC_CODES', 
+        'Order Lineitem Notes Include Copy Spec Codes', 'aea', 'label')),
+    ('INCLUDE_EMPTY_IMD_VALUES', 
+        oils_i18n_gettext('INCLUDE_EMPTY_IMD_VALUES',
+        'Lineitem Title, Author, etc. Fields Are Present Even if Empty', 'aea', 'label')),
+    ('INCLUDE_EMPTY_LI_NOTE', 
+        oils_i18n_gettext('INCLUDE_EMPTY_LI_NOTE', 
+        'Order Lineitem Notes Always Present (Even if Empty)', 'aea', 'label')),
+    ('INCLUDE_EMPTY_CALL_NUMBER', 
+        oils_i18n_gettext('INCLUDE_EMPTY_CALL_NUMBER', 
+        'Order Copies Always Include Call Number (Even if Empty)', 'aea', 'label')),
+    ('INCLUDE_EMPTY_ITEM_TYPE', 
+        oils_i18n_gettext('INCLUDE_EMPTY_ITEM_TYPE', 
+        'Order Copies Always Include Item Type (Even if Empty)', 'aea', 'label')),
+    ('INCLUDE_EMPTY_LOCATION', 
+        oils_i18n_gettext('INCLUDE_EMPTY_LOCATION', 
+        'Order Copies Always Include Location (Even if Empty)', 'aea', 'label')),
+    ('INCLUDE_EMPTY_COLLECTION_CODE', 
+        oils_i18n_gettext('INCLUDE_EMPTY_COLLECTION_CODE', 
+        'Order Copies Always Include Collection Code (Even if Empty)', 'aea', 'label')),
+    ('LINEITEM_IDENT_VENDOR_NUMBER',
+        oils_i18n_gettext('LINEITEM_IDENT_VENDOR_NUMBER',
+        'Lineitem Identifier Fields (LIN/PIA) Use Vendor-Encoded ID Value When Available', 'aea', 'label')),
+    ('LINEITEM_REF_ID_ONLY',
+        oils_i18n_gettext('LINEITEM_REF_ID_ONLY',
+        'Lineitem Reference Field (RFF) Uses Lineitem ID Only', 'aea', 'label'))
+
+;
+
+INSERT INTO acq.edi_attr_set (id, label) VALUES (1, 'Ingram Default');
+INSERT INTO acq.edi_attr_set (id, label) VALUES (2, 'Baker & Taylor Default');
+INSERT INTO acq.edi_attr_set (id, label) VALUES (3, 'Brodart Default');
+INSERT INTO acq.edi_attr_set (id, label) VALUES (4, 'Midwest Tape Default');
+INSERT INTO acq.edi_attr_set (id, label) VALUES (5, 'ULS Default');
+INSERT INTO acq.edi_attr_set (id, label) VALUES (6, 'Recorded Books Default');
+INSERT INTO acq.edi_attr_set (id, label) VALUES (7, 'Midwest Library Service');
+
+-- carve out space for mucho defaults
+PERFORM SETVAL('acq.edi_attr_set_id_seq'::TEXT, 1000);
+
+INSERT INTO acq.edi_attr_set_map (attr_set, attr) VALUES
+
+    -- Ingram
+    (1, 'INCLUDE_PO_NAME'),
+    (1, 'INCLUDE_COPIES'),
+    (1, 'INCLUDE_ITEM_TYPE'),
+    (1, 'INCLUDE_COLLECTION_CODE'),
+    (1, 'INCLUDE_OWNING_LIB'),
+    (1, 'INCLUDE_QUANTITY'),
+    (1, 'INCLUDE_BIB_PAGINATION'),
+
+    -- B&T
+    (2, 'INCLUDE_COPIES'),
+    (2, 'INCLUDE_ITEM_TYPE'),
+    (2, 'INCLUDE_COLLECTION_CODE'),
+    (2, 'INCLUDE_CALL_NUMBER'),
+    (2, 'INCLUDE_OWNING_LIB'),
+    (2, 'INCLUDE_QUANTITY'),
+    (2, 'INCLUDE_BIB_PAGINATION'),
+    (2, 'BUYER_ID_INCLUDE_VENDCODE'),
+    (2, 'INCLUDE_EMPTY_LI_NOTE'),
+    (2, 'INCLUDE_EMPTY_CALL_NUMBER'),
+    (2, 'INCLUDE_EMPTY_ITEM_TYPE'),
+    (2, 'INCLUDE_EMPTY_COLLECTION_CODE'),
+    (2, 'INCLUDE_EMPTY_LOCATION'),
+    (2, 'LINEITEM_IDENT_VENDOR_NUMBER'),
+    (2, 'LINEITEM_REF_ID_ONLY'),
+
+    -- Brodart
+    (3, 'INCLUDE_COPIES'),
+    (3, 'INCLUDE_FUND'),
+    (3, 'INCLUDE_ITEM_TYPE'),
+    (3, 'INCLUDE_COLLECTION_CODE'),
+    (3, 'INCLUDE_OWNING_LIB'),
+    (3, 'INCLUDE_QUANTITY'),
+    (3, 'INCLUDE_BIB_PAGINATION'),
+    (3, 'COPY_SPEC_CODES'),
+
+    -- Midwest
+    (4, 'INCLUDE_COPIES'),
+    (4, 'INCLUDE_FUND'),
+    (4, 'INCLUDE_OWNING_LIB'),
+    (4, 'INCLUDE_QUANTITY'),
+    (4, 'INCLUDE_BIB_PAGINATION'),
+
+    -- ULS
+    (5, 'INCLUDE_COPIES'),
+    (5, 'INCLUDE_ITEM_TYPE'),
+    (5, 'INCLUDE_COLLECTION_CODE'),
+    (5, 'INCLUDE_OWNING_LIB'),
+    (5, 'INCLUDE_QUANTITY'),
+    (5, 'INCLUDE_BIB_AUTHOR'),
+    (5, 'INCLUDE_BIB_EDITION'),
+    (5, 'INCLUDE_EMPTY_LI_NOTE'),
+
+    -- Recorded Books
+    (6, 'INCLUDE_COPIES'),
+    (6, 'INCLUDE_ITEM_TYPE'),
+    (6, 'INCLUDE_COLLECTION_CODE'),
+    (6, 'INCLUDE_OWNING_LIB'),
+    (6, 'INCLUDE_QUANTITY'),
+    (6, 'INCLUDE_BIB_PAGINATION'),
+
+    -- Midwest Library Service
+    (7, 'INCLUDE_BIB_AUTHOR'),
+    (7, 'INCLUDE_BIB_EDITION'),
+    (7, 'BUYER_ID_ONLY_VENDCODE'),
+    (7, 'INCLUDE_EMPTY_IMD_VALUES')
+;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1068', :eg_version); --miker/gmcharlt/kmlussier
+
+INSERT INTO config.xml_transform (name,namespace_uri,prefix,xslt) VALUES ('mads21','http://www.loc.gov/mads/v2','mads21',$XSLT$<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:mads="http://www.loc.gov/mads/v2"
+       xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
+       <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+       <xsl:strip-space elements="*"/>
+
+       <xsl:variable name="ascii">
+               <xsl:text> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
+       </xsl:variable>
+
+       <xsl:variable name="latin1">
+               <xsl:text> ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
+       </xsl:variable>
+       <!-- Characters that usually don't need to be escaped -->
+       <xsl:variable name="safe">
+               <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
+       </xsl:variable>
+
+       <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
+
+
+       <xsl:template name="datafield">
+               <xsl:param name="tag"/>
+               <xsl:param name="ind1">
+                       <xsl:text> </xsl:text>
+               </xsl:param>
+               <xsl:param name="ind2">
+                       <xsl:text> </xsl:text>
+               </xsl:param>
+               <xsl:param name="subfields"/>
+               <xsl:element name="marc:datafield">
+                       <xsl:attribute name="tag">
+                               <xsl:value-of select="$tag"/>
+                       </xsl:attribute>
+                       <xsl:attribute name="ind1">
+                               <xsl:value-of select="$ind1"/>
+                       </xsl:attribute>
+                       <xsl:attribute name="ind2">
+                               <xsl:value-of select="$ind2"/>
+                       </xsl:attribute>
+                       <xsl:copy-of select="$subfields"/>
+               </xsl:element>
+       </xsl:template>
+
+       <xsl:template name="subfieldSelect">
+               <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
+               <xsl:param name="delimeter">
+                       <xsl:text> </xsl:text>
+               </xsl:param>
+               <xsl:variable name="str">
+                       <xsl:for-each select="marc:subfield">
+                               <xsl:if test="contains($codes, @code)">
+                                       <xsl:value-of select="text()"/>
+                                       <xsl:value-of select="$delimeter"/>
+                               </xsl:if>
+                       </xsl:for-each>
+               </xsl:variable>
+               <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
+       </xsl:template>
+
+       <xsl:template name="buildSpaces">
+               <xsl:param name="spaces"/>
+               <xsl:param name="char">
+                       <xsl:text> </xsl:text>
+               </xsl:param>
+               <xsl:if test="$spaces>0">
+                       <xsl:value-of select="$char"/>
+                       <xsl:call-template name="buildSpaces">
+                               <xsl:with-param name="spaces" select="$spaces - 1"/>
+                               <xsl:with-param name="char" select="$char"/>
+                       </xsl:call-template>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="chopPunctuation">
+               <xsl:param name="chopString"/>
+               <xsl:param name="punctuation">
+                       <xsl:text>.:,;/ </xsl:text>
+               </xsl:param>
+               <xsl:variable name="length" select="string-length($chopString)"/>
+               <xsl:choose>
+                       <xsl:when test="$length=0"/>
+                       <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+                                       <xsl:with-param name="punctuation" select="$punctuation"/>
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:when test="not($chopString)"/>
+                       <xsl:otherwise>
+                               <xsl:value-of select="$chopString"/>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <xsl:template name="chopPunctuationFront">
+               <xsl:param name="chopString"/>
+               <xsl:variable name="length" select="string-length($chopString)"/>
+               <xsl:choose>
+                       <xsl:when test="$length=0"/>
+                       <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
+                               <xsl:call-template name="chopPunctuationFront">
+                                       <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
+                                       />
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:when test="not($chopString)"/>
+                       <xsl:otherwise>
+                               <xsl:value-of select="$chopString"/>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <xsl:template name="chopPunctuationBack">
+               <xsl:param name="chopString"/>
+               <xsl:param name="punctuation">
+                       <xsl:text>.:,;/] </xsl:text>
+               </xsl:param>
+               <xsl:variable name="length" select="string-length($chopString)"/>
+               <xsl:choose>
+                       <xsl:when test="$length=0"/>
+                       <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+                                       <xsl:with-param name="punctuation" select="$punctuation"/>
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:when test="not($chopString)"/>
+                       <xsl:otherwise>
+                               <xsl:value-of select="$chopString"/>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
+       <xsl:template name="url-encode">
+
+               <xsl:param name="str"/>
+
+               <xsl:if test="$str">
+                       <xsl:variable name="first-char" select="substring($str,1,1)"/>
+                       <xsl:choose>
+                               <xsl:when test="contains($safe,$first-char)">
+                                       <xsl:value-of select="$first-char"/>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:variable name="codepoint">
+                                               <xsl:choose>
+                                                       <xsl:when test="contains($ascii,$first-char)">
+                                                               <xsl:value-of
+                                                                       select="string-length(substring-before($ascii,$first-char)) + 32"
+                                                               />
+                                                       </xsl:when>
+                                                       <xsl:when test="contains($latin1,$first-char)">
+                                                               <xsl:value-of
+                                                                       select="string-length(substring-before($latin1,$first-char)) + 160"/>
+                                                               <!-- was 160 -->
+                                                       </xsl:when>
+                                                       <xsl:otherwise>
+                                                               <xsl:message terminate="no">Warning: string contains a character
+                                                                       that is out of range! Substituting "?".</xsl:message>
+                                                               <xsl:text>63</xsl:text>
+                                                       </xsl:otherwise>
+                                               </xsl:choose>
+                                       </xsl:variable>
+                                       <xsl:variable name="hex-digit1"
+                                               select="substring($hex,floor($codepoint div 16) + 1,1)"/>
+                                       <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
+                                       <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
+                                       <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
+                               </xsl:otherwise>
+                       </xsl:choose>
+                       <xsl:if test="string-length($str) &gt; 1">
+                               <xsl:call-template name="url-encode">
+                                       <xsl:with-param name="str" select="substring($str,2)"/>
+                               </xsl:call-template>
+                       </xsl:if>
+               </xsl:if>
+       </xsl:template>
+
+
+<!--
+2.14    Fixed bug in mads:geographic attributes syntax                                      ws   05/04/2016            
+2.13   fixed repeating <geographic>                                                                                                            tmee 01/31/2014
+2.12   added $2 authority for <classification>                                                                                         tmee 09/18/2012
+2.11   added delimiters between <classification> subfields                                                                     tmee 09/18/2012
+2.10   fixed type="other" and type="otherType" for mads:related                                                        tmee 09/16/2011
+2.09   fixed professionTerm and genreTerm empty tag error                                                                      tmee 09/16/2011
+2.08   fixed marc:subfield @code='i' matching error                                                                            tmee 09/16/2011
+2.07   fixed 555 duplication error                                                                                                                     tmee 08/10/2011 
+2.06   fixed topic subfield error                                                                                                                      tmee 08/10/2011 
+2.05   fixed title subfield error                                                                                                                      tmee 06/20/2011 
+2.04   fixed geographicSubdivision mapping for authority element                                                       tmee 06/16/2011
+2.03   added classification for 053, 055, 060, 065, 070, 080, 082, 083, 086, 087                       tmee 06/03/2011         
+2.02   added descriptionStandard for 008/10                                                                                            tmee 04/27/2011
+2.01   added extensions for 046, 336, 370, 374, 375, 376                                                                       tmee 04/08/2011
+2.00   redefined imported MODS elements in version 1.0 to MADS elements in version 2.0         tmee 02/08/2011
+1.08   added 372 subfields $a $s $t for <fieldOfActivity>                                                                      tmee 06/24/2010
+1.07   removed role/roleTerm 100, 110, 111, 400, 410, 411, 500, 510, 511, 700, 710, 711        tmee 06/24/2010
+1.06   added strip-space                                                                                                                                       tmee 06/24/2010
+1.05   added subfield $a for 130, 430, 530                                                                                                     tmee 06/21/2010
+1.04   fixed 550 z omission                                                                                                                            ntra 08/11/2008
+1.03   removed duplication of 550 $a text                                                                                                      tmee 11/01/2006
+1.02   fixed namespace references between mads and mods                                                                        ntra 10/06/2006
+1.01   revised                                                                                                                                                         rgue/jrad 11/29/05
+1.00   adapted from MARC21Slim2MODS3.xsl                                                                                                       ntra 07/06/05
+-->
+
+       <!-- authority attribute defaults to 'naf' if not set using this authority parameter, for <authority> descriptors: name, titleInfo, geographic -->
+       <xsl:param name="authority"/>
+       <xsl:variable name="auth">
+               <xsl:choose>
+                       <xsl:when test="$authority">
+                               <xsl:value-of select="$authority"/>
+                       </xsl:when>
+                       <xsl:otherwise>naf</xsl:otherwise>
+               </xsl:choose>
+       </xsl:variable>
+       <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
+       <xsl:variable name="controlField008-06"
+               select="substring(descendant-or-self::marc:controlfield[@tag=008],7,1)"/>
+       <xsl:variable name="controlField008-11"
+               select="substring(descendant-or-self::marc:controlfield[@tag=008],12,1)"/>
+       <xsl:variable name="controlField008-14"
+               select="substring(descendant-or-self::marc:controlfield[@tag=008],15,1)"/>
+       <xsl:template match="/">
+               <xsl:choose>
+                       <xsl:when test="descendant-or-self::marc:collection">
+                               <mads:madsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                       xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/v2/mads-2-0.xsd">
+                                       <xsl:for-each select="descendant-or-self::marc:collection/marc:record">
+                                               <mads:mads version="2.0">
+                                                       <xsl:call-template name="marcRecord"/>
+                                               </mads:mads>
+                                       </xsl:for-each>
+                               </mads:madsCollection>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <mads:mads version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                       xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/mads-2-0.xsd">
+                                       <xsl:for-each select="descendant-or-self::marc:record">
+                                               <xsl:call-template name="marcRecord"/>
+                                       </xsl:for-each>
+                               </mads:mads>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <xsl:template name="marcRecord">
+               <mads:authority>
+                       <!-- 2.04 -->
+                       <xsl:choose>
+                               <xsl:when test="$controlField008-06='d'">
+                                       <xsl:attribute name="geographicSubdivision">
+                                               <xsl:text>direct</xsl:text>
+                                       </xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="$controlField008-06='i'">
+                                       <xsl:attribute name="geographicSubdivision">
+                                               <xsl:text>indirect</xsl:text>
+                                       </xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="$controlField008-06='n'">
+                                       <xsl:attribute name="geographicSubdivision">
+                                               <xsl:text>not applicable</xsl:text>
+                                       </xsl:attribute>
+                               </xsl:when>
+                       </xsl:choose>
+                       
+                       <xsl:apply-templates select="marc:datafield[100 &lt;= @tag  and @tag &lt; 200]"/>               
+               </mads:authority>
+
+               <!-- related -->
+               <xsl:apply-templates
+                       select="marc:datafield[500 &lt;= @tag and @tag &lt;= 585]|marc:datafield[700 &lt;= @tag and @tag &lt;= 785]"/>
+
+               <!-- variant -->
+               <xsl:apply-templates select="marc:datafield[400 &lt;= @tag and @tag &lt;= 485]"/>
+
+               <!-- notes -->
+               <xsl:apply-templates select="marc:datafield[667 &lt;= @tag and @tag &lt;= 688]"/>
+
+               <!-- url -->
+               <xsl:apply-templates select="marc:datafield[@tag=856]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=010]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=024]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=372]"/>
+               
+               <!-- classification -->
+               <xsl:apply-templates select="marc:datafield[@tag=053]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=055]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=060]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=065]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=070]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=080]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=082]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=083]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=086]"/>
+               <xsl:apply-templates select="marc:datafield[@tag=087]"/>
+
+               <!-- affiliation-->
+               <xsl:for-each select="marc:datafield[@tag=373]">
+                       <mads:affiliation>
+                               <mads:position>
+                                       <xsl:value-of select="marc:subfield[@code='a']"/>
+                               </mads:position>
+                               <mads:dateValid point="start">
+                                       <xsl:value-of select="marc:subfield[@code='s']"/>
+                               </mads:dateValid>
+                               <mads:dateValid point="end">
+                                       <xsl:value-of select="marc:subfield[@code='t']"/>
+                               </mads:dateValid>
+                       </mads:affiliation>
+               </xsl:for-each>
+               <xsl:for-each select="marc:datafield[@tag=371]">
+                       <mads:affiliation>
+                               <mads:address>
+                                       <mads:street>
+                                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                                       </mads:street>
+                                       <mads:city>
+                                               <xsl:value-of select="marc:subfield[@code='b']"/>
+                                       </mads:city>
+                                       <mads:state>
+                                               <xsl:value-of select="marc:subfield[@code='c']"/>
+                                       </mads:state>
+                                       <mads:country>
+                                               <xsl:value-of select="marc:subfield[@code='d']"/>
+                                       </mads:country>
+                                       <mads:postcode>
+                                               <xsl:value-of select="marc:subfield[@code='e']"/>
+                                       </mads:postcode>
+                               </mads:address>
+                               <mads:email>
+                                       <xsl:value-of select="marc:subfield[@code='m']"/>
+                               </mads:email>
+                       </mads:affiliation>
+               </xsl:for-each>
+
+               <!-- extension-->
+               <xsl:for-each select="marc:datafield[@tag=336]">
+                       <mads:extension>
+                               <mads:contentType>
+                                       <mads:contentType type="text">
+                                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                                       </mads:contentType>
+                                       <mads:contentType type="code">
+                                               <xsl:value-of select="marc:subfield[@code='b']"/>
+                                       </mads:contentType>
+                               </mads:contentType>
+                       </mads:extension>
+               </xsl:for-each>
+
+               <xsl:for-each select="marc:datafield[@tag=374]">
+                       <mads:extension>
+                               <mads:profession>
+                                       <xsl:choose>
+                                               <xsl:when test="marc:subfield[@code='a']">
+                                                       <mads:professionTerm>
+                                                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                                                       </mads:professionTerm>
+                                               </xsl:when>
+                                               <xsl:when test="marc:subfield[@code='s']">
+                                                       <mads:dateValid point="start">
+                                                               <xsl:value-of select="marc:subfield[@code='s']"/>
+                                                       </mads:dateValid>
+                                               </xsl:when>
+                                               <xsl:when test="marc:subfield[@code='t']">
+                                                       <mads:dateValid point="end">
+                                                               <xsl:value-of select="marc:subfield[@code='t']"/>
+                                                       </mads:dateValid>
+                                               </xsl:when>
+                                       </xsl:choose>
+                               </mads:profession>
+                       </mads:extension>
+               </xsl:for-each>
+               
+               <xsl:for-each select="marc:datafield[@tag=375]">
+                       <mads:extension>
+                               <mads:gender>
+                                       <xsl:choose>
+                                               <xsl:when test="marc:subfield[@code='a']">
+                                                       <mads:genderTerm>
+                                                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                                                       </mads:genderTerm>
+                                               </xsl:when>
+                                               <xsl:when test="marc:subfield[@code='s']">
+                                                       <mads:dateValid point="start">
+                                                               <xsl:value-of select="marc:subfield[@code='s']"/>
+                                                       </mads:dateValid>
+                                               </xsl:when>
+                                               <xsl:when test="marc:subfield[@code='t']">
+                                                       <mads:dateValid point="end">
+                                                               <xsl:value-of select="marc:subfield[@code='t']"/>
+                                                       </mads:dateValid>
+                                               </xsl:when>
+                                       </xsl:choose>
+                               </mads:gender>
+                       </mads:extension>
+               </xsl:for-each>
+
+               <xsl:for-each select="marc:datafield[@tag=376]">
+                       <mads:extension>
+                               <mads:familyInformation>
+                                       <mads:typeOfFamily>
+                                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                                       </mads:typeOfFamily>
+                                       <mads:nameOfProminentMember>
+                                               <xsl:value-of select="marc:subfield[@code='b']"/>
+                                       </mads:nameOfProminentMember>
+                                       <mads:hereditaryTitle>
+                                               <xsl:value-of select="marc:subfield[@code='c']"/>
+                                       </mads:hereditaryTitle>
+                                       <mads:dateValid point="start">
+                                               <xsl:value-of select="marc:subfield[@code='s']"/>
+                                       </mads:dateValid>
+                                       <mads:dateValid point="end">
+                                               <xsl:value-of select="marc:subfield[@code='t']"/>
+                                       </mads:dateValid>
+                               </mads:familyInformation>
+                       </mads:extension>
+               </xsl:for-each>
+
+               <mads:recordInfo>
+                       <mads:recordOrigin>Converted from MARCXML to MADS version 2.0 (Revision 2.13)</mads:recordOrigin>
+                       <!-- <xsl:apply-templates select="marc:datafield[@tag=024]"/> -->
+
+                       <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='a']"/>
+                       <xsl:apply-templates select="marc:controlfield[@tag=005]"/>
+                       <xsl:apply-templates select="marc:controlfield[@tag=001]"/>
+                       <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='b']"/>
+                       <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='e']"/>
+                       <xsl:for-each select="marc:controlfield[@tag=008]">
+                               <xsl:if test="substring(.,11,1)='a'">
+                                       <mads:descriptionStandard>
+                                               <xsl:text>earlier rules</xsl:text>
+                                       </mads:descriptionStandard>
+                               </xsl:if>
+                               <xsl:if test="substring(.,11,1)='b'">
+                                       <mads:descriptionStandard>
+                                               <xsl:text>aacr1</xsl:text>
+                                       </mads:descriptionStandard>
+                               </xsl:if>
+                               <xsl:if test="substring(.,11,1)='c'">
+                                       <mads:descriptionStandard>
+                                               <xsl:text>aacr2</xsl:text>
+                                       </mads:descriptionStandard>
+                               </xsl:if>
+                               <xsl:if test="substring(.,11,1)='d'">
+                                       <mads:descriptionStandard>
+                                               <xsl:text>aacr2 compatible</xsl:text>
+                                       </mads:descriptionStandard>
+                               </xsl:if>
+                               <xsl:if test="substring(.,11,1)='z'">
+                                       <mads:descriptionStandard>
+                                               <xsl:text>other rules</xsl:text>
+                                       </mads:descriptionStandard>
+                               </xsl:if>
+                       </xsl:for-each>
+               </mads:recordInfo>
+       </xsl:template>
+
+       <!-- start of secondary templates -->
+
+       <!-- ======== xlink ======== -->
+
+       <!-- <xsl:template name="uri"> 
+    <xsl:for-each select="marc:subfield[@code='0']">
+      <xsl:attribute name="xlink:href">
+       <xsl:value-of select="."/>
+      </xsl:attribute>
+    </xsl:for-each>
+     </xsl:template> 
+   -->
+       <xsl:template match="marc:subfield[@code='i']">
+               <xsl:attribute name="otherType">
+                       <xsl:value-of select="."/>
+               </xsl:attribute>
+       </xsl:template>
+
+       <!-- No role/roleTerm mapped in MADS 06/24/2010
+       <xsl:template name="role">
+               <xsl:for-each select="marc:subfield[@code='e']">
+                       <mads:role>
+                               <mads:roleTerm type="text">
+                                       <xsl:value-of select="."/>
+                               </mads:roleTerm>
+                       </mads:role>
+               </xsl:for-each>
+       </xsl:template>
+-->
+
+       <xsl:template name="part">
+               <xsl:variable name="partNumber">
+                       <xsl:call-template name="specialSubfieldSelect">
+                               <xsl:with-param name="axis">n</xsl:with-param>
+                               <xsl:with-param name="anyCodes">n</xsl:with-param>
+                               <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+                       </xsl:call-template>
+               </xsl:variable>
+               <xsl:variable name="partName">
+                       <xsl:call-template name="specialSubfieldSelect">
+                               <xsl:with-param name="axis">p</xsl:with-param>
+                               <xsl:with-param name="anyCodes">p</xsl:with-param>
+                               <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+                       </xsl:call-template>
+               </xsl:variable>
+               <xsl:if test="string-length(normalize-space($partNumber))">
+                       <mads:partNumber>
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString" select="$partNumber"/>
+                               </xsl:call-template>
+                       </mads:partNumber>
+               </xsl:if>
+               <xsl:if test="string-length(normalize-space($partName))">
+                       <mads:partName>
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString" select="$partName"/>
+                               </xsl:call-template>
+                       </mads:partName>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="nameABCDN">
+               <xsl:for-each select="marc:subfield[@code='a']">
+                       <mads:namePart>
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString" select="."/>
+                               </xsl:call-template>
+                       </mads:namePart>
+               </xsl:for-each>
+               <xsl:for-each select="marc:subfield[@code='b']">
+                       <mads:namePart>
+                               <xsl:value-of select="."/>
+                       </mads:namePart>
+               </xsl:for-each>
+               <xsl:if
+                       test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
+                       <mads:namePart>
+                               <xsl:call-template name="subfieldSelect">
+                                       <xsl:with-param name="codes">cdn</xsl:with-param>
+                               </xsl:call-template>
+                       </mads:namePart>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="nameABCDQ">
+               <mads:namePart>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:call-template name="subfieldSelect">
+                                               <xsl:with-param name="codes">aq</xsl:with-param>
+                                       </xsl:call-template>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:namePart>
+               <xsl:call-template name="termsOfAddress"/>
+               <xsl:call-template name="nameDate"/>
+       </xsl:template>
+
+       <xsl:template name="nameACDENQ">
+               <mads:namePart>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">acdenq</xsl:with-param>
+                       </xsl:call-template>
+               </mads:namePart>
+       </xsl:template>
+
+       <xsl:template name="nameDate">
+               <xsl:for-each select="marc:subfield[@code='d']">
+                       <mads:namePart type="date">
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString" select="."/>
+                               </xsl:call-template>
+                       </mads:namePart>
+               </xsl:for-each>
+       </xsl:template>
+
+       <xsl:template name="specialSubfieldSelect">
+               <xsl:param name="anyCodes"/>
+               <xsl:param name="axis"/>
+               <xsl:param name="beforeCodes"/>
+               <xsl:param name="afterCodes"/>
+               <xsl:variable name="str">
+                       <xsl:for-each select="marc:subfield">
+                               <xsl:if
+                                       test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
+                                       <xsl:value-of select="text()"/>
+                                       <xsl:text> </xsl:text>
+                               </xsl:if>
+                       </xsl:for-each>
+               </xsl:variable>
+               <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+       </xsl:template>
+
+       <xsl:template name="termsOfAddress">
+               <xsl:if test="marc:subfield[@code='b' or @code='c']">
+                       <mads:namePart type="termsOfAddress">
+                               <xsl:call-template name="chopPunctuation">
+                                       <xsl:with-param name="chopString">
+                                               <xsl:call-template name="subfieldSelect">
+                                                       <xsl:with-param name="codes">bc</xsl:with-param>
+                                               </xsl:call-template>
+                                       </xsl:with-param>
+                               </xsl:call-template>
+                       </mads:namePart>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="displayLabel">
+               <xsl:if test="marc:subfield[@code='z']">
+                       <xsl:attribute name="displayLabel">
+                               <xsl:value-of select="marc:subfield[@code='z']"/>
+                       </xsl:attribute>
+               </xsl:if>
+               <xsl:if test="marc:subfield[@code='3']">
+                       <xsl:attribute name="displayLabel">
+                               <xsl:value-of select="marc:subfield[@code='3']"/>
+                       </xsl:attribute>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="isInvalid">
+               <xsl:if test="@code='z'">
+                       <xsl:attribute name="invalid">yes</xsl:attribute>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="sub2Attribute">
+               <!-- 024 -->
+               <xsl:if test="../marc:subfield[@code='2']">
+                       <xsl:attribute name="type">
+                               <xsl:value-of select="../marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template match="marc:controlfield[@tag=001]">
+               <mads:recordIdentifier>
+                       <xsl:if test="../marc:controlfield[@tag=003]">
+                               <xsl:attribute name="source">
+                                       <xsl:value-of select="../marc:controlfield[@tag=003]"/>
+                               </xsl:attribute>
+                       </xsl:if>
+                       <xsl:value-of select="."/>
+               </mads:recordIdentifier>
+       </xsl:template>
+
+       <xsl:template match="marc:controlfield[@tag=005]">
+               <mads:recordChangeDate encoding="iso8601">
+                       <xsl:value-of select="."/>
+               </mads:recordChangeDate>
+       </xsl:template>
+
+       <xsl:template match="marc:controlfield[@tag=008]">
+               <mads:recordCreationDate encoding="marc">
+                       <xsl:value-of select="substring(.,1,6)"/>
+               </mads:recordCreationDate>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=010]">
+               <xsl:for-each select="marc:subfield">
+                       <mads:identifier type="lccn">
+                               <xsl:call-template name="isInvalid"/>
+                               <xsl:value-of select="."/>
+                       </mads:identifier>
+               </xsl:for-each>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=024]">
+               <xsl:for-each select="marc:subfield[not(@code=2)]">
+                       <mads:identifier>
+                               <xsl:call-template name="isInvalid"/>
+                               <xsl:call-template name="sub2Attribute"/>
+                               <xsl:value-of select="."/>
+                       </mads:identifier>
+               </xsl:for-each>
+       </xsl:template>
+
+       <!-- ========== 372 ========== -->
+       <xsl:template match="marc:datafield[@tag=372]">
+               <mads:fieldOfActivity>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">a</xsl:with-param>
+                       </xsl:call-template>
+                       <xsl:text>-</xsl:text>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">st</xsl:with-param>
+                       </xsl:call-template>
+               </mads:fieldOfActivity>
+       </xsl:template>
+
+
+       <!-- ========== 040 ========== -->
+       <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='a']">
+               <mads:recordContentSource authority="marcorg">
+                       <xsl:value-of select="."/>
+               </mads:recordContentSource>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='b']">
+               <mads:languageOfCataloging>
+                       <mads:languageTerm authority="iso639-2b" type="code">
+                               <xsl:value-of select="."/>
+                       </mads:languageTerm>
+               </mads:languageOfCataloging>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='e']">
+               <mads:descriptionStandard>
+                       <xsl:value-of select="."/>
+               </mads:descriptionStandard>
+       </xsl:template>
+       
+       <!-- ========== classification 2.03 ========== -->
+       
+       <xsl:template match="marc:datafield[@tag=053]">
+               <mads:classification>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       
+       <xsl:template match="marc:datafield[@tag=055]">
+               <mads:classification>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       
+       <xsl:template match="marc:datafield[@tag=060]">
+               <mads:classification>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=065]">
+               <mads:classification>
+                       <xsl:attribute name="authority">
+                               <xsl:value-of select="marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=070]">
+               <mads:classification>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=080]">
+               <mads:classification>
+                       <xsl:attribute name="authority">
+                               <xsl:value-of select="marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=082]">
+               <mads:classification>
+                       <xsl:attribute name="authority">
+                               <xsl:value-of select="marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=083]">
+               <mads:classification>
+                       <xsl:attribute name="authority">
+                               <xsl:value-of select="marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=086]">
+               <mads:classification>
+                       <xsl:attribute name="authority">
+                               <xsl:value-of select="marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=087]">
+               <mads:classification>
+                       <xsl:attribute name="authority">
+                               <xsl:value-of select="marc:subfield[@code='2']"/>
+                       </xsl:attribute>
+                       <xsl:call-template name="subfieldSelect">
+                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+                               <xsl:with-param name="delimeter">-</xsl:with-param>
+                       </xsl:call-template>
+               </mads:classification>
+       </xsl:template>
+       
+
+       <!-- ========== names  ========== -->
+       <xsl:template match="marc:datafield[@tag=100]">
+               <mads:name type="personal">
+                       <xsl:call-template name="setAuthority"/>
+                       <xsl:call-template name="nameABCDQ"/>
+               </mads:name>
+               <xsl:apply-templates select="*[marc:subfield[not(contains('abcdeq',@code))]]"/>
+               <xsl:call-template name="title"/>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=110]">
+               <mads:name type="corporate">
+                       <xsl:call-template name="setAuthority"/>
+                       <xsl:call-template name="nameABCDN"/>
+               </mads:name>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=111]">
+               <mads:name type="conference">
+                       <xsl:call-template name="setAuthority"/>
+                       <xsl:call-template name="nameACDENQ"/>
+               </mads:name>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=400]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <mads:name type="personal">
+                               <xsl:call-template name="nameABCDQ"/>
+                       </mads:name>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+                       <xsl:call-template name="title"/>
+               </mads:variant>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=410]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <mads:name type="corporate">
+                               <xsl:call-template name="nameABCDN"/>
+                       </mads:name>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:variant>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=411]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <mads:name type="conference">
+                               <xsl:call-template name="nameACDENQ"/>
+                       </mads:name>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:variant>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=500]|marc:datafield[@tag=700]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <!-- <xsl:call-template name="uri"/> -->
+                       <mads:name type="personal">
+                               <xsl:call-template name="setAuthority"/>
+                               <xsl:call-template name="nameABCDQ"/>
+                       </mads:name>
+                       <xsl:call-template name="title"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=510]|marc:datafield[@tag=710]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <!-- <xsl:call-template name="uri"/> -->
+                       <mads:name type="corporate">
+                               <xsl:call-template name="setAuthority"/>
+                               <xsl:call-template name="nameABCDN"/>
+                       </mads:name>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=511]|marc:datafield[@tag=711]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <!-- <xsl:call-template name="uri"/> -->
+                       <mads:name type="conference">
+                               <xsl:call-template name="setAuthority"/>
+                               <xsl:call-template name="nameACDENQ"/>
+                       </mads:name>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+
+       <!-- ========== titles  ========== -->
+       <xsl:template match="marc:datafield[@tag=130]">
+               <xsl:call-template name="uniform-title"/>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=430]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <xsl:call-template name="uniform-title"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:variant>
+       </xsl:template>
+
+       <xsl:template match="marc:datafield[@tag=530]|marc:datafield[@tag=730]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:call-template name="uniform-title"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+
+       <xsl:template name="title">
+               <xsl:variable name="hasTitle">
+                       <xsl:for-each select="marc:subfield">
+                               <xsl:if test="(contains('tfghklmors',@code) )">
+                                       <xsl:value-of select="@code"/>
+                               </xsl:if>
+                       </xsl:for-each>
+               </xsl:variable>
+               <xsl:if test="string-length($hasTitle) &gt; 0 ">
+                       <mads:titleInfo>
+                               <xsl:call-template name="setAuthority"/>
+                               <mads:title>
+                                       <xsl:variable name="str">
+                                               <xsl:for-each select="marc:subfield">
+                                                       <xsl:if test="(contains('atfghklmors',@code) )">
+                                                               <xsl:value-of select="text()"/>
+                                                               <xsl:text> </xsl:text>
+                                                       </xsl:if>
+                                               </xsl:for-each>
+                                       </xsl:variable>
+                                       <xsl:call-template name="chopPunctuation">
+                                               <xsl:with-param name="chopString">
+                                                       <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                                               </xsl:with-param>
+                                       </xsl:call-template>
+                               </mads:title>
+                               <xsl:call-template name="part"/>
+                               <!-- <xsl:call-template name="uri"/> -->
+                       </mads:titleInfo>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="uniform-title">
+               <xsl:variable name="hasTitle">
+                       <xsl:for-each select="marc:subfield">
+                               <xsl:if test="(contains('atfghklmors',@code) )">
+                                       <xsl:value-of select="@code"/>
+                               </xsl:if>
+                       </xsl:for-each>
+               </xsl:variable>
+               <xsl:if test="string-length($hasTitle) &gt; 0 ">
+                       <mads:titleInfo>
+                               <xsl:call-template name="setAuthority"/>
+                               <mads:title>
+                                       <xsl:variable name="str">
+                                               <xsl:for-each select="marc:subfield">
+                                                       <xsl:if test="(contains('adfghklmors',@code) )">
+                                                               <xsl:value-of select="text()"/>
+                                                               <xsl:text> </xsl:text>
+                                                       </xsl:if>
+                                               </xsl:for-each>
+                                       </xsl:variable>
+                                       <xsl:call-template name="chopPunctuation">
+                                               <xsl:with-param name="chopString">
+                                                       <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                                               </xsl:with-param>
+                                       </xsl:call-template>
+                               </mads:title>
+                               <xsl:call-template name="part"/>
+                               <!-- <xsl:call-template name="uri"/> -->
+                       </mads:titleInfo>
+               </xsl:if>
+       </xsl:template>
+
+
+       <!-- ========== topics  ========== -->
+       <xsl:template match="marc:subfield[@code='x']">
+               <mads:topic>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:value-of select="."/>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:topic>
+       </xsl:template>
+       
+       <!-- 2.06 fix -->
+       <xsl:template
+               match="marc:datafield[@tag=150][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=180][marc:subfield[@code='x']]">
+               <xsl:call-template name="topic"/>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=450][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=480][marc:subfield[@code='x']]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <xsl:call-template name="topic"/>
+               </mads:variant>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=550 or @tag=750][marc:subfield[@code='a' or @code='b']]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <!-- <xsl:call-template name="uri"/> -->
+                       <xsl:call-template name="topic"/>
+                       <xsl:apply-templates select="marc:subfield[@code='z']"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template name="topic">
+               <mads:topic>
+                       <xsl:call-template name="setAuthority"/>
+                       <!-- tmee2006 dedupe 550a
+                       <xsl:if test="@tag=550 or @tag=750">
+                               <xsl:call-template name="subfieldSelect">
+                                       <xsl:with-param name="codes">ab</xsl:with-param>
+                               </xsl:call-template>
+                       </xsl:if>       
+                       -->
+                       <xsl:choose>
+                               <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
+                                       <xsl:call-template name="chopPunctuation">
+                                               <xsl:with-param name="chopString">
+                                                       <xsl:apply-templates select="marc:subfield[@code='x']"/>
+                                               </xsl:with-param>
+                                       </xsl:call-template>
+                               </xsl:when>
+                       </xsl:choose>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:choose>
+                                               <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
+                                                       <xsl:apply-templates select="marc:subfield[@code='x']"/>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:call-template name="subfieldSelect">
+                                                               <xsl:with-param name="codes">ab</xsl:with-param>
+                                                       </xsl:call-template>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:topic>
+       </xsl:template>
+
+       <!-- ========= temporals  ========== -->
+       <xsl:template match="marc:subfield[@code='y']">
+               <mads:temporal>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:value-of select="."/>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:temporal>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=148][marc:subfield[@code='a']]|marc:datafield[@tag=182 ][marc:subfield[@code='y']]">
+               <xsl:call-template name="temporal"/>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=448][marc:subfield[@code='a']]|marc:datafield[@tag=482][marc:subfield[@code='y']]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <xsl:call-template name="temporal"/>
+               </mads:variant>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=548 or @tag=748][marc:subfield[@code='a']]|marc:datafield[@tag=582 or @tag=782][marc:subfield[@code='y']]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <!-- <xsl:call-template name="uri"/> -->
+                       <xsl:call-template name="temporal"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template name="temporal">
+               <mads:temporal>
+                       <xsl:call-template name="setAuthority"/>
+                       <xsl:if test="@tag=548 or @tag=748">
+                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                       </xsl:if>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:choose>
+                                               <xsl:when test="@tag=182 or @tag=482 or @tag=582 or @tag=782">
+                                                       <xsl:apply-templates select="marc:subfield[@code='y']"/>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:temporal>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+
+       <!-- ========== genre  ========== -->
+       <xsl:template match="marc:subfield[@code='v']">
+               <mads:genre>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:value-of select="."/>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:genre>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=155][marc:subfield[@code='a']]|marc:datafield[@tag=185][marc:subfield[@code='v']]">
+               <xsl:call-template name="genre"/>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=455][marc:subfield[@code='a']]|marc:datafield[@tag=485 ][marc:subfield[@code='v']]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <xsl:call-template name="genre"/>
+               </mads:variant>
+       </xsl:template>
+       <!--
+       <xsl:template match="marc:datafield[@tag=555]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:call-template name="uri"/>
+                       <xsl:call-template name="genre"/>
+               </mads:related>
+       </xsl:template>
+       -->
+       <xsl:template
+               match="marc:datafield[@tag=555 or @tag=755][marc:subfield[@code='a']]|marc:datafield[@tag=585][marc:subfield[@code='v']]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:call-template name="genre"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template name="genre">
+               <mads:genre>
+                       <xsl:if test="@tag=555">
+                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                       </xsl:if>
+                       <xsl:call-template name="setAuthority"/>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:choose>
+                                               <!-- 2.07 fix -->
+                                               <xsl:when test="@tag='555'"/>
+                                               <xsl:when test="@tag=185 or @tag=485 or @tag=585">
+                                                       <xsl:apply-templates select="marc:subfield[@code='v']"/>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:genre>
+               <xsl:apply-templates/>
+       </xsl:template>
+
+       <!-- ========= geographic  ========== -->
+       <xsl:template match="marc:subfield[@code='z']">
+               <mads:geographic>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:value-of select="."/>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:geographic>
+       </xsl:template>
+       <xsl:template name="geographic">
+               <mads:geographic>
+                       <!-- 2.14 -->
+                       <xsl:call-template name="setAuthority"/>
+                       <!-- 2.13 -->
+                       <xsl:if test="@tag=151 or @tag=551">
+                               <xsl:value-of select="marc:subfield[@code='a']"/>
+                       </xsl:if>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                               <xsl:if test="@tag=181 or @tag=481 or @tag=581">
+                                                               <xsl:apply-templates select="marc:subfield[@code='z']"/>
+                                               </xsl:if>
+                                               <!-- 2.13
+                                                       <xsl:choose>
+                                               <xsl:when test="@tag=181 or @tag=481 or @tag=581">
+                                                       <xsl:apply-templates select="marc:subfield[@code='z']"/>
+                                               </xsl:when>
+                                       
+                                               <xsl:otherwise>
+                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
+                                               </xsl:otherwise>
+                                               </xsl:choose>
+                                               -->
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:geographic>
+               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=151][marc:subfield[@code='a']]|marc:datafield[@tag=181][marc:subfield[@code='z']]">
+               <xsl:call-template name="geographic"/>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=451][marc:subfield[@code='a']]|marc:datafield[@tag=481][marc:subfield[@code='z']]">
+               <mads:variant>
+                       <xsl:call-template name="variantTypeAttribute"/>
+                       <xsl:call-template name="geographic"/>
+               </mads:variant>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=551]|marc:datafield[@tag=581][marc:subfield[@code='z']]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <!-- <xsl:call-template name="uri"/> -->
+                       <xsl:call-template name="geographic"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=580]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template
+               match="marc:datafield[@tag=751][marc:subfield[@code='z']]|marc:datafield[@tag=781][marc:subfield[@code='z']]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:call-template name="geographic"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=755]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:call-template name="genre"/>
+                       <xsl:call-template name="setAuthority"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=780]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+       <xsl:template match="marc:datafield[@tag=785]">
+               <mads:related>
+                       <xsl:call-template name="relatedTypeAttribute"/>
+                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+               </mads:related>
+       </xsl:template>
+
+       <!-- ========== notes  ========== -->
+       <xsl:template match="marc:datafield[667 &lt;= @tag and @tag &lt;= 688]">
+               <mads:note>
+                       <xsl:choose>
+                               <xsl:when test="@tag=667">
+                                       <xsl:attribute name="type">nonpublic</xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="@tag=670">
+                                       <xsl:attribute name="type">source</xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="@tag=675">
+                                       <xsl:attribute name="type">notFound</xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="@tag=678">
+                                       <xsl:attribute name="type">history</xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="@tag=681">
+                                       <xsl:attribute name="type">subject example</xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="@tag=682">
+                                       <xsl:attribute name="type">deleted heading information</xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="@tag=688">
+                                       <xsl:attribute name="type">application history</xsl:attribute>
+                               </xsl:when>
+                       </xsl:choose>
+                       <xsl:call-template name="chopPunctuation">
+                               <xsl:with-param name="chopString">
+                                       <xsl:choose>
+                                               <xsl:when test="@tag=667 or @tag=675">
+                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
+                                               </xsl:when>
+                                               <xsl:when test="@tag=670 or @tag=678">
+                                                       <xsl:call-template name="subfieldSelect">
+                                                               <xsl:with-param name="codes">ab</xsl:with-param>
+                                                       </xsl:call-template>
+                                               </xsl:when>
+                                               <xsl:when test="680 &lt;= @tag and @tag &lt;=688">
+                                                       <xsl:call-template name="subfieldSelect">
+                                                               <xsl:with-param name="codes">ai</xsl:with-param>
+                                                       </xsl:call-template>
+                                               </xsl:when>
+                                       </xsl:choose>
+                               </xsl:with-param>
+                       </xsl:call-template>
+               </mads:note>
+       </xsl:template>
+
+       <!-- ========== url  ========== -->
+       <xsl:template match="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+               <mads:url>
+                       <xsl:if test="marc:subfield[@code='z' or @code='3']">
+                               <xsl:attribute name="displayLabel">
+                                       <xsl:call-template name="subfieldSelect">
+                                               <xsl:with-param name="codes">z3</xsl:with-param>
+                                       </xsl:call-template>
+                               </xsl:attribute>
+                       </xsl:if>
+                       <xsl:value-of select="marc:subfield[@code='u']"/>
+               </mads:url>
+       </xsl:template>
+
+       <xsl:template name="relatedTypeAttribute">
+               <xsl:choose>
+                       <xsl:when
+                               test="@tag=500 or @tag=510 or @tag=511 or @tag=548 or @tag=550 or @tag=551 or @tag=555 or @tag=580 or @tag=581 or @tag=582 or @tag=585">
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='a'">
+                                       <xsl:attribute name="type">earlier</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='b'">
+                                       <xsl:attribute name="type">later</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='t'">
+                                       <xsl:attribute name="type">parentOrg</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='g'">
+                                       <xsl:attribute name="type">broader</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='h'">
+                                       <xsl:attribute name="type">narrower</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='r'">
+                                       <xsl:attribute name="type">other</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="contains('fin|', substring(marc:subfield[@code='w'],1,1))">
+                                       <xsl:attribute name="type">other</xsl:attribute>
+                               </xsl:if>
+                       </xsl:when>
+                       <xsl:when test="@tag=530 or @tag=730">
+                               <xsl:attribute name="type">other</xsl:attribute>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <!-- 7xx -->
+                               <xsl:attribute name="type">equivalent</xsl:attribute>
+                       </xsl:otherwise>
+               </xsl:choose>
+               <xsl:apply-templates select="marc:subfield[@code='i']"/>
+       </xsl:template>
+       
+
+
+       <xsl:template name="variantTypeAttribute">
+               <xsl:choose>
+                       <xsl:when
+                               test="@tag=400 or @tag=410 or @tag=411 or @tag=451 or @tag=455 or @tag=480 or @tag=481 or @tag=482 or @tag=485">
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='d'">
+                                       <xsl:attribute name="type">acronym</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='n'">
+                                       <xsl:attribute name="type">other</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="contains('fit', substring(marc:subfield[@code='w'],1,1))">
+                                       <xsl:attribute name="type">other</xsl:attribute>
+                               </xsl:if>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <!-- 430  -->
+                               <xsl:attribute name="type">other</xsl:attribute>
+                       </xsl:otherwise>
+               </xsl:choose>
+               <xsl:apply-templates select="marc:subfield[@code='i']"/>
+       </xsl:template>
+
+       <xsl:template name="setAuthority">
+               <xsl:choose>
+                       <!-- can be called from the datafield or subfield level, so "..//@tag" means
+                       the tag can be at the subfield's parent level or at the datafields own level -->
+
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='a'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>naf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lcsh</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='k'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lacnaf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='a' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lcsh</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='k' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">cash</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='a'">
+                               <xsl:attribute name="authority">naf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">lcsh</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='a'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lacnaf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>cash</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='b'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lcshcl</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='c'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>nlmnaf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='d'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>nalnaf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='r'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>aat</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='s'">
+                               <xsl:attribute name="authority">sears</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='v'">
+                               <xsl:attribute name="authority">rvm</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='z'">
+                               <xsl:attribute name="authority">
+                                       <xsl:value-of
+                                               select="../marc:datafield[ancestor-or-self::marc:datafield/@tag=040]/marc:subfield[@code='f']"
+                                       />
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='a'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>naf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lcsh</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='k' ">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lacnaf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lcsh</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>lcsh</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='c' ">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>mesh</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='d' ">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>nal</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='k' ">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>cash</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='a'">
+                               <xsl:attribute name="authority">
+                                       <xsl:text>naf</xsl:text>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">lcsh</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='a'">
+                               <xsl:attribute name="authority">lacnaf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='b'">
+                               <xsl:attribute name="authority">cash</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(..//ancestor-or-self::marc:datafield/@tag=180 or ..//ancestor-or-self::marc:datafield/@tag=181 or ..//ancestor-or-self::marc:datafield/@tag=182 or ..//ancestor-or-self::marc:datafield/@tag=185) and $controlField008-11='a'">
+                               <xsl:attribute name="authority">lcsh</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='0'">
+                               <xsl:attribute name="authority">naf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='5'">
+                               <xsl:attribute name="authority">lacnaf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='0'">
+                               <xsl:attribute name="authority">lcsh</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='5'">
+                               <xsl:attribute name="authority">cash</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='1'">
+                               <xsl:attribute name="authority">lcshcl</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='2'">
+                               <xsl:attribute name="authority">nlmnaf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='3'">
+                               <xsl:attribute name="authority">nalnaf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='6'">
+                               <xsl:attribute name="authority">rvm</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='7'">
+                               <xsl:attribute name="authority">
+                                       <xsl:value-of select="marc:subfield[@code='2']"/>
+                               </xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='5'">
+                               <xsl:attribute name="authority">lacnaf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='0'">
+                               <xsl:attribute name="authority">naf</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='0'">
+                               <xsl:attribute name="authority">lcsh</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='2'">
+                               <xsl:attribute name="authority">mesh</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='3'">
+                               <xsl:attribute name="authority">nal</xsl:attribute>
+                       </xsl:when>
+                       <xsl:when
+                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='5'">
+                               <xsl:attribute name="authority">cash</xsl:attribute>
+                       </xsl:when>
+               </xsl:choose>
+       </xsl:template>
+       <xsl:template match="*"/>
+</xsl:stylesheet>$XSLT$);
+
+END IF; END $INSERT$;                                                          
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1069', :eg_version); --gmcharlt/kmlussier
+
+-- subset of types listed in https://www.loc.gov/marc/authority/ad1xx3xx.html
+-- for now, ignoring subdivisions
+CREATE TYPE authority.heading_type AS ENUM (
+    'personal_name',
+    'corporate_name',
+    'meeting_name',
+    'uniform_title',
+    'named_event',
+    'chronological_term',
+    'topical_term',
+    'geographic_name',
+    'genre_form_term',
+    'medium_of_performance_term'
+);
+
+CREATE TYPE authority.variant_heading_type AS ENUM (
+    'abbreviation',
+    'acronym',
+    'translation',
+    'expansion',
+    'other',
+    'hidden'
+);
+
+CREATE TYPE authority.related_heading_type AS ENUM (
+    'earlier',
+    'later',
+    'parent organization',
+    'broader',
+    'narrower',
+    'equivalent',
+    'other'
+);
+
+CREATE TYPE authority.heading_purpose AS ENUM (
+    'main',
+    'variant',
+    'related'
+);
+
+CREATE TABLE authority.heading_field (
+    id              SERIAL                      PRIMARY KEY,
+    heading_type    authority.heading_type      NOT NULL,
+    heading_purpose authority.heading_purpose   NOT NULL,
+    label           TEXT                        NOT NULL,
+    format          TEXT                        NOT NULL REFERENCES config.xml_transform (name) DEFAULT 'mads21',
+    heading_xpath   TEXT                        NOT NULL,
+    component_xpath TEXT                        NOT NULL,
+    type_xpath      TEXT                        NULL, -- to extract related or variant type
+    thesaurus_xpath TEXT                        NULL,
+    thesaurus_override_xpath TEXT               NULL,
+    joiner          TEXT                        NULL
+);
+
+CREATE TABLE authority.heading_field_norm_map (
+        id      SERIAL  PRIMARY KEY,
+        field   INT     NOT NULL REFERENCES authority.heading_field (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+        norm    INT     NOT NULL REFERENCES config.index_normalizer (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+        params  TEXT,
+        pos     INT     NOT NULL DEFAULT 0
+);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+INSERT INTO authority.heading_field(heading_type, heading_purpose, label, heading_xpath, component_xpath, type_xpath, thesaurus_xpath, thesaurus_override_xpath) VALUES
+ ( 'topical_term', 'main',    'Main Topical Term',    '/mads21:mads/mads21:authority', '//mads21:topic', NULL, '/mads21:mads/mads21:authority/mads21:topic[1]/@authority', NULL )
+,( 'topical_term', 'variant', 'Variant Topical Term', '/mads21:mads/mads21:variant',   '//mads21:topic', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:topic[1]/@authority', '//mads21:topic[1]/@authority')
+,( 'topical_term', 'related', 'Related Topical Term', '/mads21:mads/mads21:related',   '//mads21:topic', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:topic[1]/@authority', '//mads21:topic[1]/@authority')
+,( 'personal_name', 'main', 'Main Personal Name',     '/mads21:mads/mads21:authority', '//mads21:name[@type="personal"]', NULL, NULL, NULL )
+,( 'personal_name', 'variant', 'Variant Personal Name',     '/mads21:mads/mads21:variant', '//mads21:name[@type="personal"]', NULL, NULL, NULL )
+,( 'personal_name', 'related', 'Related Personal Name',     '/mads21:mads/mads21:related', '//mads21:name[@type="personal"]', '/mads21:related/@type', NULL, NULL )
+,( 'corporate_name', 'main', 'Main Corporate name',     '/mads21:mads/mads21:authority', '//mads21:name[@type="corporate"]', NULL, NULL, NULL )
+,( 'corporate_name', 'variant', 'Variant Corporate Name',     '/mads21:mads/mads21:variant', '//mads21:name[@type="corporate"]', NULL, NULL, NULL )
+,( 'corporate_name', 'related', 'Related Corporate Name',     '/mads21:mads/mads21:related', '//mads21:name[@type="corporate"]', '/mads21:related/@type', NULL, NULL )
+,( 'meeting_name', 'main', 'Main Meeting name',     '/mads21:mads/mads21:authority', '//mads21:name[@type="conference"]', NULL, NULL, NULL )
+,( 'meeting_name', 'variant', 'Variant Meeting Name',     '/mads21:mads/mads21:variant', '//mads21:name[@type="conference"]', NULL, NULL, NULL )
+,( 'meeting_name', 'related', 'Related Meeting Name',     '/mads21:mads/mads21:related', '//mads21:name[@type="meeting"]', '/mads21:related/@type', NULL, NULL )
+,( 'geographic_name', 'main',    'Main Geographic Term',    '/mads21:mads/mads21:authority', '//mads21:geographic', NULL, '/mads21:mads/mads21:authority/mads21:geographic[1]/@authority', NULL )
+,( 'geographic_name', 'variant', 'Variant Geographic Term', '/mads21:mads/mads21:variant',   '//mads21:geographic', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:geographic[1]/@authority', '//mads21:geographic[1]/@authority')
+,( 'geographic_name', 'related', 'Related Geographic Term', '/mads21:mads/mads21:related',   '//mads21:geographic', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:geographic[1]/@authority', '//mads21:geographic[1]/@authority')
+,( 'genre_form_term', 'main',    'Main Genre/Form Term',    '/mads21:mads/mads21:authority', '//mads21:genre', NULL, '/mads21:mads/mads21:authority/mads21:genre[1]/@authority', NULL )
+,( 'genre_form_term', 'variant', 'Variant Genre/Form Term', '/mads21:mads/mads21:variant',   '//mads21:genre', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:genre[1]/@authority', '//mads21:genre[1]/@authority')
+,( 'genre_form_term', 'related', 'Related Genre/Form Term', '/mads21:mads/mads21:related',   '//mads21:genre', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:genre[1]/@authority', '//mads21:genre[1]/@authority')
+,( 'chronological_term', 'main',    'Main Chronological Term',    '/mads21:mads/mads21:authority', '//mads21:temporal', NULL, '/mads21:mads/mads21:authority/mads21:temporal[1]/@authority', NULL )
+,( 'chronological_term', 'variant', 'Variant Chronological Term', '/mads21:mads/mads21:variant',   '//mads21:temporal', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:temporal[1]/@authority', '//mads21:temporal[1]/@authority')
+,( 'chronological_term', 'related', 'Related Chronological Term', '/mads21:mads/mads21:related',   '//mads21:temporal', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:temporal[1]/@authority', '//mads21:temporal[1]/@authority')
+,( 'uniform_title', 'main',    'Main Uniform Title',    '/mads21:mads/mads21:authority', '//mads21:title', NULL, '/mads21:mads/mads21:authority/mads21:title[1]/@authority', NULL )
+,( 'uniform_title', 'variant', 'Variant Uniform Title', '/mads21:mads/mads21:variant',   '//mads21:title', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:title[1]/@authority', '//mads21:title[1]/@authority')
+,( 'uniform_title', 'related', 'Related Uniform Title', '/mads21:mads/mads21:related',   '//mads21:title', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:title[1]/@authority', '//mads21:title[1]/@authority')
+;
+
+-- NACO normalize all the things
+INSERT INTO authority.heading_field_norm_map (field, norm, pos)
+SELECT id, 1, 0
+FROM authority.heading_field;
+
+END IF; END $INSERT$;                                                          
+
+CREATE TYPE authority.heading AS (
+    field               INT,
+    type                authority.heading_type,
+    purpose             authority.heading_purpose,
+    variant_type        authority.variant_heading_type,
+    related_type        authority.related_heading_type,
+    thesaurus           TEXT,
+    heading             TEXT,
+    normalized_heading  TEXT
+);
+
+CREATE OR REPLACE FUNCTION authority.extract_headings(marc TEXT, restrict INT[] DEFAULT NULL) RETURNS SETOF authority.heading AS $func$
+DECLARE
+    idx         authority.heading_field%ROWTYPE;
+    xfrm        config.xml_transform%ROWTYPE;
+    prev_xfrm   TEXT;
+    transformed_xml TEXT;
+    heading_node    TEXT;
+    heading_node_list   TEXT[];
+    component_node    TEXT;
+    component_node_list   TEXT[];
+    raw_text    TEXT;
+    normalized_text    TEXT;
+    normalizer  RECORD;
+    curr_text   TEXT;
+    joiner      TEXT;
+    type_value  TEXT;
+    base_thesaurus TEXT := NULL;
+    output_row  authority.heading;
+BEGIN
+
+    -- Loop over the indexing entries
+    FOR idx IN SELECT * FROM authority.heading_field WHERE restrict IS NULL OR id = ANY (restrict) ORDER BY format LOOP
+
+        output_row.field   := idx.id;
+        output_row.type    := idx.heading_type;
+        output_row.purpose := idx.heading_purpose;
+
+        joiner := COALESCE(idx.joiner, ' ');
+
+        SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
+
+        -- See if we can skip the XSLT ... it's expensive
+        IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+            -- Can't skip the transform
+            IF xfrm.xslt <> '---' THEN
+                transformed_xml := oils_xslt_process(marc, xfrm.xslt);
+            ELSE
+                transformed_xml := marc;
+            END IF;
+
+            prev_xfrm := xfrm.name;
+        END IF;
+
+        IF idx.thesaurus_xpath IS NOT NULL THEN
+            base_thesaurus := ARRAY_TO_STRING(oils_xpath(idx.thesaurus_xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
+        END IF;
+
+        heading_node_list := oils_xpath( idx.heading_xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+
+        FOR heading_node IN SELECT x FROM unnest(heading_node_list) AS x LOOP
+
+            CONTINUE WHEN heading_node !~ E'^\\s*<';
+
+            output_row.variant_type := NULL;
+            output_row.related_type := NULL;
+            output_row.thesaurus    := NULL;
+            output_row.heading      := NULL;
+
+            IF idx.heading_purpose = 'variant' AND idx.type_xpath IS NOT NULL THEN
+                type_value := ARRAY_TO_STRING(oils_xpath(idx.type_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
+                BEGIN
+                    output_row.variant_type := type_value;
+                EXCEPTION WHEN invalid_text_representation THEN
+                    RAISE NOTICE 'Do not recognize variant heading type %', type_value;
+                END;
+            END IF;
+            IF idx.heading_purpose = 'related' AND idx.type_xpath IS NOT NULL THEN
+                type_value := ARRAY_TO_STRING(oils_xpath(idx.type_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
+                BEGIN
+                    output_row.related_type := type_value;
+                EXCEPTION WHEN invalid_text_representation THEN
+                    RAISE NOTICE 'Do not recognize related heading type %', type_value;
+                END;
+            END IF;
+            IF idx.thesaurus_override_xpath IS NOT NULL THEN
+                output_row.thesaurus := ARRAY_TO_STRING(oils_xpath(idx.thesaurus_override_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
+            END IF;
+            IF output_row.thesaurus IS NULL THEN
+                output_row.thesaurus := base_thesaurus;
+            END IF;
+
+            raw_text := NULL;
+
+            -- now iterate over components of heading
+            component_node_list := oils_xpath( idx.component_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+            FOR component_node IN SELECT x FROM unnest(component_node_list) AS x LOOP
+            -- XXX much of this should be moved into oils_xpath_string...
+                curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
+                    oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
+                        REGEXP_REPLACE( component_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
+                    ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
+                    joiner
+                );
+
+                CONTINUE WHEN curr_text IS NULL OR curr_text = '';
+
+                IF raw_text IS NOT NULL THEN
+                    raw_text := raw_text || joiner;
+                END IF;
+
+                raw_text := COALESCE(raw_text,'') || curr_text;
+            END LOOP;
+
+            IF raw_text IS NOT NULL THEN
+                output_row.heading := raw_text;
+                normalized_text := raw_text;
+
+                FOR normalizer IN
+                    SELECT  n.func AS func,
+                            n.param_count AS param_count,
+                            m.params AS params
+                    FROM  config.index_normalizer n
+                            JOIN authority.heading_field_norm_map m ON (m.norm = n.id)
+                    WHERE m.field = idx.id
+                    ORDER BY m.pos LOOP
+            
+                        EXECUTE 'SELECT ' || normalizer.func || '(' ||
+                            quote_literal( normalized_text ) ||
+                            CASE
+                                WHEN normalizer.param_count > 0
+                                    THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
+                                    ELSE ''
+                                END ||
+                            ')' INTO normalized_text;
+            
+                END LOOP;
+            
+                output_row.normalized_heading := normalized_text;
+            
+                RETURN NEXT output_row;
+            END IF;
+        END LOOP;
+
+    END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION authority.extract_headings(rid BIGINT, restrict INT[] DEFAULT NULL) RETURNS SETOF authority.heading AS $func$
+DECLARE
+    auth        authority.record_entry%ROWTYPE;
+    output_row  authority.heading;
+BEGIN
+    -- Get the record
+    SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
+
+    RETURN QUERY SELECT * FROM authority.extract_headings(auth.marc, restrict);
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
+DECLARE
+    res             authority.simple_heading%ROWTYPE;
+    acsaf           authority.control_set_authority_field%ROWTYPE;
+    heading_row     authority.heading%ROWTYPE;
+    tag_used        TEXT;
+    nfi_used        TEXT;
+    sf              TEXT;
+    cset            INT;
+    heading_text    TEXT;
+    joiner_text     TEXT;
+    sort_text       TEXT;
+    tmp_text        TEXT;
+    tmp_xml         TEXT;
+    first_sf        BOOL;
+    auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT; 
+BEGIN
+
+    SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
+
+    IF cset IS NULL THEN
+        SELECT  control_set INTO cset
+          FROM  authority.control_set_authority_field
+          WHERE tag IN ( SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
+          LIMIT 1;
+    END IF;
+
+    res.record := auth_id;
+    res.thesaurus := authority.extract_thesaurus(marcxml);
+
+    FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
+        res.atag := acsaf.id;
+
+        IF acsaf.heading_field IS NULL THEN
+            tag_used := acsaf.tag;
+            nfi_used := acsaf.nfi;
+            joiner_text := COALESCE(acsaf.joiner, ' ');
+    
+            FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)::TEXT[]) LOOP
+    
+                heading_text := COALESCE(
+                    oils_xpath_string('./*[contains("'||acsaf.display_sf_list||'",@code)]', tmp_xml, joiner_text),
+                    ''
+                );
+    
+                IF nfi_used IS NOT NULL THEN
+    
+                    sort_text := SUBSTRING(
+                        heading_text FROM
+                        COALESCE(
+                            NULLIF(
+                                REGEXP_REPLACE(
+                                    oils_xpath_string('./@ind'||nfi_used, tmp_xml::TEXT),
+                                    $$\D+$$,
+                                    '',
+                                    'g'
+                                ),
+                                ''
+                            )::INT,
+                            0
+                        ) + 1
+                    );
+    
+                ELSE
+                    sort_text := heading_text;
+                END IF;
+    
+                IF heading_text IS NOT NULL AND heading_text <> '' THEN
+                    res.value := heading_text;
+                    res.sort_value := public.naco_normalize(sort_text);
+                    res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
+                    RETURN NEXT res;
+                END IF;
+    
+            END LOOP;
+        ELSE
+            FOR heading_row IN SELECT * FROM authority.extract_headings(marcxml, ARRAY[acsaf.heading_field]) LOOP
+                res.value := heading_row.heading;
+                res.sort_value := heading_row.normalized_heading;
+                res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
+                RETURN NEXT res;
+            END LOOP;
+        END IF;
+    END LOOP;
+
+    RETURN;
+END;
+$func$ LANGUAGE PLPGSQL STABLE STRICT;
+
+ALTER TABLE authority.control_set_authority_field ADD COLUMN heading_field INTEGER REFERENCES authority.heading_field(id);
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '100'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'personal_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '400'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'personal_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '500'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'personal_name';
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '110'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'corporate_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '410'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'corporate_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '510'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'corporate_name';
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '111'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'meeting_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '411'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'meeting_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '511'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'meeting_name';
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '130'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'uniform_title';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '430'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'uniform_title';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '530'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'uniform_title';
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '150'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'topical_term';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '450'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'topical_term';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '550'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'topical_term';
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '151'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'geographic_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '451'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'geographic_name';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '551'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'geographic_name';
+
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '155'
+AND control_set = 1
+AND ahf.heading_purpose = 'main'
+AND ahf.heading_type = 'genre_form_term';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '455'
+AND control_set = 1
+AND ahf.heading_purpose = 'variant'
+AND ahf.heading_type = 'genre_form_term';
+UPDATE authority.control_set_authority_field acsaf
+SET heading_field = ahf.id
+FROM authority.heading_field ahf
+WHERE tag = '555'
+AND control_set = 1
+AND ahf.heading_purpose = 'related'
+AND ahf.heading_type = 'genre_form_term';
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1070', :eg_version); --miker/gmcharlt/kmlussier
+
+CREATE TRIGGER thes_code_tracking_trigger
+    AFTER UPDATE ON authority.thesaurus
+    FOR EACH ROW EXECUTE PROCEDURE oils_i18n_code_tracking('at');
+
+ALTER TABLE authority.thesaurus ADD COLUMN short_code TEXT, ADD COLUMN uri TEXT;
+
+DELETE FROM authority.thesaurus WHERE control_set = 1 AND code NOT IN ('n',' ','|');
+UPDATE authority.thesaurus SET short_code = code;
+
+CREATE TEMP TABLE thesauri (code text, uri text, name text, xlate hstore);
+COPY thesauri (code, uri, name, xlate) FROM STDIN;
+migfg  http://id.loc.gov/vocabulary/genreFormSchemes/migfg     Moving image genre-form guide   
+reveal http://id.loc.gov/vocabulary/genreFormSchemes/reveal    REVEAL: fiction indexing and genre headings     
+dct    http://id.loc.gov/vocabulary/genreFormSchemes/dct       Dublin Core list of resource types      
+gmgpc  http://id.loc.gov/vocabulary/genreFormSchemes/gmgpc     Thesaurus for graphic materials: TGM II, Genre and physical characteristic terms        
+rbgenr http://id.loc.gov/vocabulary/genreFormSchemes/rbgenr    Genre terms: a thesaurus for use in rare book and special collections cataloguing       
+sgp    http://id.loc.gov/vocabulary/genreFormSchemes/sgp       Svenska genrebeteckningar fr periodika  "sv"=>"Svenska genrebeteckningar fr periodika"
+estc   http://id.loc.gov/vocabulary/genreFormSchemes/estc      Eighteenth century short title catalogue, the cataloguing rules. New ed.        
+ftamc  http://id.loc.gov/vocabulary/genreFormSchemes/ftamc     Form terms for archival and manuscripts control 
+alett  http://id.loc.gov/vocabulary/genreFormSchemes/alett     An alphabetical list of English text types      
+gtlm   http://id.loc.gov/vocabulary/genreFormSchemes/gtlm      Genre terms for law materials: a thesaurus      
+rbprov http://id.loc.gov/vocabulary/genreFormSchemes/rbprov    Provenance evidence: a thesaurus for use in rare book and special collections cataloging        
+rbbin  http://id.loc.gov/vocabulary/genreFormSchemes/rbbin     Binding terms: a thesaurus for use in rare book and special collections cataloguing     
+fbg    http://id.loc.gov/vocabulary/genreFormSchemes/fbg       Films by genre /dd>     
+isbdmedia      http://id.loc.gov/vocabulary/genreFormSchemes/isbdmedia ISBD Area 0 [media]     
+marccategory   http://id.loc.gov/vocabulary/genreFormSchemes/marccategory      MARC form category term list    
+gnd-music      http://id.loc.gov/vocabulary/genreFormSchemes/gnd-music Gemeinsame Normdatei: Musikalische Ausgabeform  
+proysen        http://id.loc.gov/vocabulary/genreFormSchemes/proysen   Prøysen: emneord for Prøysen-bibliografien        
+rdacarrier     http://id.loc.gov/vocabulary/genreFormSchemes/rdacarrier        Term and code list for RDA carrier types        
+gnd    http://id.loc.gov/vocabulary/genreFormSchemes/gnd       Gemeinsame Normdatei    
+cjh    http://id.loc.gov/vocabulary/genreFormSchemes/cjh       Center for Jewish History thesaurus     
+rbpri  http://id.loc.gov/vocabulary/genreFormSchemes/rbpri     Printing & publishing evidence: a thesaurus for use in rare book and special collections cataloging     
+fgtpcm http://id.loc.gov/vocabulary/genreFormSchemes/fgtpcm    Form/genre terms for printed cartoon material   
+rbpub  http://id.loc.gov/vocabulary/genreFormSchemes/rbpub     Printing and publishing evidence: a thesaurus for use in rare book and special collections cataloging   
+gmd    http://id.loc.gov/vocabulary/genreFormSchemes/gmd       Anglo-American Cataloguing Rules general material designation   
+rbpap  http://id.loc.gov/vocabulary/genreFormSchemes/rbpap     Paper terms: a thesaurus for use in rare book and special collections cataloging        
+rdamedia       http://id.loc.gov/vocabulary/genreFormSchemes/rdamedia  Term and code list for RDA media types  
+marcsmd        http://id.loc.gov/vocabulary/genreFormSchemes/marcsmd   MARC specific material form term list   
+saogf  http://id.loc.gov/vocabulary/genreFormSchemes/saogf     Svenska Ã¤mnesord - Genre/Form        "sv"=>"Svenska Ã¤mnesord - Genre/Form"
+lcgft  http://id.loc.gov/vocabulary/genreFormSchemes/lcgft     Library of Congress genre/form terms for library and archival materials 
+muzeukv        http://id.loc.gov/vocabulary/genreFormSchemes/muzeukv   MuzeVideo UK DVD and UMD film genre classification      
+mim    http://id.loc.gov/vocabulary/genreFormSchemes/mim       Moving image materials: genre terms     
+nmc    http://id.loc.gov/vocabulary/genreFormSchemes/nmc       Revised nomenclature for museum cataloging: a revised and expanded version of Robert C. Chenhall's system for classifying man-made objects      
+gnd-content    http://id.loc.gov/vocabulary/genreFormSchemes/gnd-content       Gemeinsame Normdatei: Beschreibung des Inhalts  
+bgtchm http://id.loc.gov/vocabulary/genreFormSchemes/bgtchm    Basic genre terms for cultural heritage materials       
+gsafd  http://id.loc.gov/vocabulary/genreFormSchemes/gsafd     Guidelines on subject access to individual works of fiction, drama, etc 
+marcform       http://id.loc.gov/vocabulary/genreFormSchemes/marcform  MARC form of item term list     
+marcgt http://id.loc.gov/vocabulary/genreFormSchemes/marcgt    MARC genre terms        
+barngf http://id.loc.gov/vocabulary/genreFormSchemes/barngf    Svenska Ã¤mnesord för barn - Genre/Form    "sv"=>"Svenska Ã¤mnesord för barn - Genre/Form"
+ngl    http://id.loc.gov/vocabulary/genreFormSchemes/ngl       Newspaper genre list    
+rvmgf  http://id.loc.gov/vocabulary/genreFormSchemes/rvmgf     Thésaurus des descripteurs de genre/forme de l'Université Laval   "fr"=>"Thésaurus des descripteurs de genre/forme de l'Université Laval"
+tgfbne http://id.loc.gov/vocabulary/genreFormSchemes/tgfbne    Términos de género/forma de la Biblioteca Nacional de España   
+nbdbgf http://id.loc.gov/vocabulary/genreFormSchemes/nbdbgf    NBD Biblion Genres Fictie       
+rbtyp  http://id.loc.gov/vocabulary/genreFormSchemes/rbtyp     Type evidence: a thesaurus for use in rare book and special collections cataloging      
+radfg  http://id.loc.gov/vocabulary/genreFormSchemes/radfg     Radio form / genre terms guide  
+gnd-carrier    http://id.loc.gov/vocabulary/genreFormSchemes/gnd-carrier       Gemeinsame Normdatei: Datenträgertyp 
+gatbeg http://id.loc.gov/vocabulary/genreFormSchemes/gatbeg    Gattungsbegriffe        "de"=>"Gattungsbegriffe"
+rdacontent     http://id.loc.gov/vocabulary/genreFormSchemes/rdacontent        Term and code list for RDA content types        
+isbdcontent    http://id.loc.gov/vocabulary/genreFormSchemes/isbdcontent       ISBD Area 0 [content]   
+nimafc http://id.loc.gov/vocabulary/genreFormSchemes/nimafc    NIMA form codes 
+amg    http://id.loc.gov/vocabulary/genreFormSchemes/amg       Audiovisual material glossary   
+local  http://id.loc.gov/vocabulary/subjectSchemes/local       Locally assigned term   
+taika  http://id.loc.gov/vocabulary/subjectSchemes/taika       Taideteollisuuden asiasanasto   "fi"=>"Taideteollisuuden asiasanasto"
+nasat  http://id.loc.gov/vocabulary/subjectSchemes/nasat       NASA thesaurus  
+rswkaf http://id.loc.gov/vocabulary/subjectSchemes/rswkaf      Alternativform zum Hauptschlagwort      "de"=>"Alternativform zum Hauptschlagwort"
+jhpk   http://id.loc.gov/vocabulary/subjectSchemes/jhpk        JÄ\99zyk haseÅ\82 przedmiotowych KABA   "pl"=>"JÄ\99zyk haseÅ\82 przedmiotowych KABA"
+asrcrfcd       http://id.loc.gov/vocabulary/subjectSchemes/asrcrfcd    Australian Standard Research Classification: Research Fields, Courses and Disciplines (RFCD) classification     
+bt     http://id.loc.gov/vocabulary/subjectSchemes/bt  Bioethics thesaurus     
+lcstt  http://id.loc.gov/vocabulary/subjectSchemes/lcstt       List of Chinese subject terms   
+netc   http://id.loc.gov/vocabulary/subjectSchemes/netc        National Emergency Training Center Thesaurus (NETC)     
+aat    http://id.loc.gov/vocabulary/subjectSchemes/aat Art & architecture thesaurus    
+bet    http://id.loc.gov/vocabulary/subjectSchemes/bet British education thesaurus     
+ncjt   http://id.loc.gov/vocabulary/subjectSchemes/ncjt        National criminal justice thesaurus     
+samisk http://id.loc.gov/vocabulary/subjectSchemes/samisk      Sami bibliography       "no"=>"Sámi bibliografia = Samisk bibliografi (Norge)"
+tips   http://id.loc.gov/vocabulary/subjectSchemes/tips        Tesauro ISOC de psicología   "es"=>"Tesauro ISOC de psicología"
+ukslc  http://id.loc.gov/vocabulary/subjectSchemes/ukslc       UK Standard Library Categories  
+tekord http://id.loc.gov/vocabulary/subjectSchemes/tekord      TEK-ord : UBiTs emneordliste for arkitektur, realfag, og teknolog       "no"=>"TEK-ord : UBiTs emneordliste for arkitektur, realfag, og teknolog"
+umitrist       http://id.loc.gov/vocabulary/subjectSchemes/umitrist    University of Michigan Transportation Research Institute structured thesaurus   
+wgst   http://id.loc.gov/vocabulary/subjectSchemes/wgst        Washington GILS Subject Tree    
+rasuqam        http://id.loc.gov/vocabulary/subjectSchemes/rasuqam     Répertoire d'autorités-sujet de l'UQAM    "fr"=>"Répertoire d'autorités-sujet de l'UQAM"
+ntids  http://id.loc.gov/vocabulary/subjectSchemes/ntids       Norske tidsskrifter 1700-1820: emneord  "no"=>"Norske tidsskrifter 1700-1820: emneord"
+kaa    http://id.loc.gov/vocabulary/subjectSchemes/kaa Kasvatusalan asiasanasto        "fi"=>"Kasvatusalan asiasanasto"
+yso    http://id.loc.gov/vocabulary/subjectSchemes/yso YSO - Yleinen suomalainen ontologia     "fi"=>"YSO - Yleinen suomalainen ontologia"
+gcipmedia      http://id.loc.gov/vocabulary/subjectSchemes/gcipmedia   GAMECIP - Computer Game Media Formats (GAMECIP (Game Metadata and Citation Project))    
+inspect        http://id.loc.gov/vocabulary/subjectSchemes/inspect     INSPEC thesaurus        
+ordnok http://id.loc.gov/vocabulary/subjectSchemes/ordnok      Ordnokkelen: tesaurus for kulturminnevern       "no"=>"Ordnokkelen: tesaurus for kulturminnevern"
+helecon        http://id.loc.gov/vocabulary/subjectSchemes/helecon     Asiasanasto HELECON-tietikantoihin      "fi"=>"Asiasanasto HELECON-tietikantoihin"
+dltlt  http://id.loc.gov/vocabulary/subjectSchemes/dltlt       Cuddon, J. A. A dictionary of literary terms and literary theory        
+csapa  http://id.loc.gov/vocabulary/subjectSchemes/csapa       "Controlled vocabulary" in Pollution abstracts  
+gtt    http://id.loc.gov/vocabulary/subjectSchemes/gtt GOO-trefwoorden thesaurus       "nl"=>"GOO-trefwoorden thesaurus"
+iescs  http://id.loc.gov/vocabulary/subjectSchemes/iescs       International energy subject categories and scope       
+itrt   http://id.loc.gov/vocabulary/subjectSchemes/itrt        International Thesaurus of Refugee Terminology  
+sanb   http://id.loc.gov/vocabulary/subjectSchemes/sanb        South African national bibliography authority file      
+blmlsh http://id.loc.gov/vocabulary/subjectSchemes/blmlsh      British Library - Map library subject headings  
+bhb    http://id.loc.gov/vocabulary/subjectSchemes/bhb Bibliography of the Hebrew Book 
+csh    http://id.loc.gov/vocabulary/subjectSchemes/csh Kapsner, Oliver Leonard. Catholic subject headings      
+fire   http://id.loc.gov/vocabulary/subjectSchemes/fire        FireTalk, IFSI thesaurus        
+jlabsh http://id.loc.gov/vocabulary/subjectSchemes/jlabsh      Basic subject headings  "ja"=>"Kihon kenmei hyômokuhyô"
+udc    http://id.loc.gov/vocabulary/subjectSchemes/udc Universal decimal classification        
+lcshac http://id.loc.gov/vocabulary/subjectSchemes/lcshac      Children's subject headings in Library of Congress subject headings: supplementary vocabularies 
+geonet http://id.loc.gov/vocabulary/subjectSchemes/geonet      NGA GEOnet Names Server (GNS)   
+humord http://id.loc.gov/vocabulary/subjectSchemes/humord      HUMORD  "no"=>"HUMORD"
+no-ubo-mr      http://id.loc.gov/vocabulary/subjectSchemes/no-ubo-mr   Menneskerettighets-tesaurus     "no"=>"Menneskerettighets-tesaurus"
+sgce   http://id.loc.gov/vocabulary/subjectSchemes/sgce        COBISS.SI General List of subject headings (English subject headings)   "sl"=>"SploÅ¡ni geslovnik COBISS.SI"
+kdm    http://id.loc.gov/vocabulary/subjectSchemes/kdm Khung dê muc hê thông thông tin khoa hoc và ky thuât quôc gia      "vi"=>"Khung dê muc hê thông thông tin khoa hoc và ky thuât quôc gia"
+thesoz http://id.loc.gov/vocabulary/subjectSchemes/thesoz      Thesaurus for the Social Sciences       
+asth   http://id.loc.gov/vocabulary/subjectSchemes/asth        Astronomy thesaurus     
+muzeukc        http://id.loc.gov/vocabulary/subjectSchemes/muzeukc     MuzeMusic UK classical music classification     
+norbok http://id.loc.gov/vocabulary/subjectSchemes/norbok      Norbok: emneord i Norsk bokfortegnelse  "no"=>"Norbok: emneord i Norsk bokfortegnelse"
+masa   http://id.loc.gov/vocabulary/subjectSchemes/masa        Museoalan asiasanasto   "fi"=>"Museoalan asiasanasto"
+conorsi        http://id.loc.gov/vocabulary/subjectSchemes/conorsi     CONOR.SI (name authority file) (Maribor, Slovenia: Institut informacijskih znanosti (IZUM))     
+eurovocen      http://id.loc.gov/vocabulary/subjectSchemes/eurovocen   Eurovoc thesaurus (English)     
+kto    http://id.loc.gov/vocabulary/subjectSchemes/kto KTO - Kielitieteen ontologia    "fi"=>"KTO - Kielitieteen ontologia"
+muzvukci       http://id.loc.gov/vocabulary/subjectSchemes/muzvukci    MuzeVideo UK contributor index  
+kaunokki       http://id.loc.gov/vocabulary/subjectSchemes/kaunokki    Kaunokki: kaunokirjallisuuden asiasanasto       "fi"=>"Kaunokki: kaunokirjallisuuden asiasanasto"
+maotao http://id.loc.gov/vocabulary/subjectSchemes/maotao      MAO/TAO - Ontologi för museibranschen och Konstindustriella ontologin        "fi"=>"MAO/TAO - Ontologi för museibranschen och Konstindustriella ontologin"
+psychit        http://id.loc.gov/vocabulary/subjectSchemes/psychit     Thesaurus of psychological index terms. 
+tlsh   http://id.loc.gov/vocabulary/subjectSchemes/tlsh        Subject heading authority list  
+csalsct        http://id.loc.gov/vocabulary/subjectSchemes/csalsct     CSA life sciences collection thesaurus  
+ciesiniv       http://id.loc.gov/vocabulary/subjectSchemes/ciesiniv    CIESIN indexing vocabulary      
+ebfem  http://id.loc.gov/vocabulary/subjectSchemes/ebfem       Encabezamientos bilingües de la Fundación Educativa Ana G. Mendez 
+mero   http://id.loc.gov/vocabulary/subjectSchemes/mero        MERO - Merenkulkualan ontologia "fi"=>"MERO - Merenkulkualan ontologia"
+mmm    http://id.loc.gov/vocabulary/subjectSchemes/mmm "Subject key" in Marxism and the mass media     
+pascal http://id.loc.gov/vocabulary/subjectSchemes/pascal      PASCAL database classification scheme   "fr"=>"Base de donneés PASCAL: plan de classement"
+chirosh        http://id.loc.gov/vocabulary/subjectSchemes/chirosh     Chiropractic Subject Headings   
+cilla  http://id.loc.gov/vocabulary/subjectSchemes/cilla       Cilla: specialtesaurus för musik     "fi"=>"Cilla: specialtesaurus för musik"
+aiatsisl       http://id.loc.gov/vocabulary/subjectSchemes/aiatsisl    AIATSIS language thesaurus      
+nskps  http://id.loc.gov/vocabulary/subjectSchemes/nskps       PriruÄ\8dnik za izradu predmetnog kataloga u Nacionalnoj i sveuÄ\8diliÅ¡noj knjiÄ\8dnici u Zagrebu    "hr"=>"PriruÄ\8dnik za izradu predmetnog kataloga u Nacionalnoj i sveuÄ\8diliÅ¡noj knjiÄ\8dnici u Zagrebu"
+lctgm  http://id.loc.gov/vocabulary/subjectSchemes/lctgm       Thesaurus for graphic materials: TGM I, Subject terms   
+muso   http://id.loc.gov/vocabulary/subjectSchemes/muso        MUSO - Ontologi för musik    "fi"=>"MUSO - Ontologi för musik"
+blcpss http://id.loc.gov/vocabulary/subjectSchemes/blcpss      COMPASS subject authority system        
+fast   http://id.loc.gov/vocabulary/subjectSchemes/fast        Faceted application of subject terminology      
+bisacmt        http://id.loc.gov/vocabulary/subjectSchemes/bisacmt     BISAC Merchandising Themes      
+lapponica      http://id.loc.gov/vocabulary/subjectSchemes/lapponica   Lapponica       "fi"=>"Lapponica"
+juho   http://id.loc.gov/vocabulary/subjectSchemes/juho        JUHO - Julkishallinnon ontologia        "fi"=>"JUHO - Julkishallinnon ontologia"
+idas   http://id.loc.gov/vocabulary/subjectSchemes/idas        ID-Archivschlüssel   "de"=>"ID-Archivschlüssel"
+tbjvp  http://id.loc.gov/vocabulary/subjectSchemes/tbjvp       Tesauro de la Biblioteca Dr. Jorge Villalobos Padilla, S.J.     "es"=>"Tesauro de la Biblioteca Dr. Jorge Villalobos Padilla, S.J."
+test   http://id.loc.gov/vocabulary/subjectSchemes/test        Thesaurus of engineering and scientific terms   
+finmesh        http://id.loc.gov/vocabulary/subjectSchemes/finmesh     FinMeSH "fi"=>"FinMeSH"
+kssbar http://id.loc.gov/vocabulary/subjectSchemes/kssbar      Klassifikationssystem for svenska bibliotek. Ã\84mnesordregister. Alfabetisk del        "sv"=>"Klassifikationssystem for svenska bibliotek. Ã\84mnesordregister. Alfabetisk del"
+kupu   http://id.loc.gov/vocabulary/subjectSchemes/kupu        Maori Wordnet   "mi"=>"He puna kupu"
+rpe    http://id.loc.gov/vocabulary/subjectSchemes/rpe Rubricator on economics "ru"=>"Rubrikator po ekonomike"
+dit    http://id.loc.gov/vocabulary/subjectSchemes/dit Defense intelligence thesaurus  
+she    http://id.loc.gov/vocabulary/subjectSchemes/she SHE: subject headings for engineering   
+idszbzna       http://id.loc.gov/vocabulary/subjectSchemes/idszbzna    Thesaurus IDS Nebis Zentralbibliothek Zürich, Nordamerika-Bibliothek "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Nordamerika-Bibliothek"
+msc    http://id.loc.gov/vocabulary/subjectSchemes/msc Mathematical subject classification     
+muzeukn        http://id.loc.gov/vocabulary/subjectSchemes/muzeukn     MuzeMusic UK non-classical music classification 
+ipsp   http://id.loc.gov/vocabulary/subjectSchemes/ipsp        Defense intelligence production schedule.       
+sthus  http://id.loc.gov/vocabulary/subjectSchemes/sthus       Subject Taxonomy of the History of U.S. Foreign Relations       
+poliscit       http://id.loc.gov/vocabulary/subjectSchemes/poliscit    Political science thesaurus II  
+qtglit http://id.loc.gov/vocabulary/subjectSchemes/qtglit      A queer thesaurus : an international thesaurus of gay and lesbian index terms   
+unbist http://id.loc.gov/vocabulary/subjectSchemes/unbist      UNBIS thesaurus 
+gcipplatform   http://id.loc.gov/vocabulary/subjectSchemes/gcipplatform        GAMECIP - Computer Game Platforms (GAMECIP (Game Metadata and Citation Project))        
+puho   http://id.loc.gov/vocabulary/subjectSchemes/puho        PUHO - Puolustushallinnon ontologia     "fi"=>"PUHO - Puolustushallinnon ontologia"
+thub   http://id.loc.gov/vocabulary/subjectSchemes/thub        Thesaurus de la Universitat de Barcelona        "ca"=>"Thesaurus de la Universitat de Barcelona"
+ndlsh  http://id.loc.gov/vocabulary/subjectSchemes/ndlsh       National Diet Library list of subject headings  "ja"=>"Koktsu Kokkai Toshokan kenmei hyômokuhyô"
+czenas http://id.loc.gov/vocabulary/subjectSchemes/czenas      CZENAS thesaurus: a list of subject terms used in the National Library of the Czech Republic    "cs"=>"Soubor vÄ\95cných autorit Národní knihovny Ä\8cR"
+idszbzzh       http://id.loc.gov/vocabulary/subjectSchemes/idszbzzh    Thesaurus IDS Nebis Zentralbibliothek Zürich, Handschriftenabteilung "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Handschriftenabteilung"
+unbisn http://id.loc.gov/vocabulary/subjectSchemes/unbisn      UNBIS name authority list (New York, NY: Dag Hammarskjld Library, United Nations; : Chadwyck-Healey)    
+rswk   http://id.loc.gov/vocabulary/subjectSchemes/rswk        Regeln für den Schlagwortkatalog     "de"=>"Regeln für den Schlagwortkatalog"
+larpcal        http://id.loc.gov/vocabulary/subjectSchemes/larpcal     Lista de assuntos referente ao programa de cadastramento automatizado de livros da USP  "pt"=>"Lista de assuntos referente ao programa de cadastramento automatizado de livros da USP"
+biccbmc        http://id.loc.gov/vocabulary/subjectSchemes/biccbmc     BIC Children's Books Marketing Classifications  
+kulo   http://id.loc.gov/vocabulary/subjectSchemes/kulo        KULO - Kulttuurien tutkimuksen ontologia        "fi"=>"KULO - Kulttuurien tutkimuksen ontologia"
+popinte        http://id.loc.gov/vocabulary/subjectSchemes/popinte     POPIN thesaurus: population multilingual thesaurus      
+tisa   http://id.loc.gov/vocabulary/subjectSchemes/tisa        Villagrá Rubio, Angel. Tesauro ISOC de sociología autores "es"=>"Villagrá Rubio, Angel. Tesauro ISOC de sociología autores"
+atg    http://id.loc.gov/vocabulary/subjectSchemes/atg Agricultural thesaurus and glossary     
+eflch  http://id.loc.gov/vocabulary/subjectSchemes/eflch       E4Libraries Category Headings   
+maaq   http://id.loc.gov/vocabulary/subjectSchemes/maaq        Madâkhil al-asmâ' al-'arabîyah al-qadîmah   "ar"=>"Madâkhil al-asmâ' al-'arabîyah al-qadîmah"
+rvmgd  http://id.loc.gov/vocabulary/subjectSchemes/rvmgd       Thésaurus des descripteurs de groupes démographiques de l'Université Laval     "fr"=>"Thésaurus des descripteurs de groupes démographiques de l'Université Laval"
+csahssa        http://id.loc.gov/vocabulary/subjectSchemes/csahssa     "Controlled vocabulary" in Health and safety science abstracts  
+sigle  http://id.loc.gov/vocabulary/subjectSchemes/sigle       SIGLE manual, Part 2, Subject category list     
+blnpn  http://id.loc.gov/vocabulary/subjectSchemes/blnpn       British Library newspaper place names   
+asrctoa        http://id.loc.gov/vocabulary/subjectSchemes/asrctoa     Australian Standard Research Classification: Type of Activity (TOA) classification      
+lcdgt  http://id.loc.gov/vocabulary/subjectSchemes/lcdgt       Library of Congress demographic group term and code List        
+bokbas http://id.loc.gov/vocabulary/subjectSchemes/bokbas      Bokbasen        "no"=>"Bokbasen"
+gnis   http://id.loc.gov/vocabulary/subjectSchemes/gnis        Geographic Names Information System (GNIS)      
+nbiemnfag      http://id.loc.gov/vocabulary/subjectSchemes/nbiemnfag   NBIs emneordsliste for faglitteratur    "no"=>"NBIs emneordsliste for faglitteratur"
+nlgaf  http://id.loc.gov/vocabulary/subjectSchemes/nlgaf       Archeio KathierÅ\8dmenÅ\8dn EpikephalidÅ\8dn    "el"=>"Archeio KathierÅ\8dmenÅ\8dn EpikephalidÅ\8dn"
+bhashe http://id.loc.gov/vocabulary/subjectSchemes/bhashe      BHA, Bibliography of the history of art, subject headings/English       
+tsht   http://id.loc.gov/vocabulary/subjectSchemes/tsht        Thesaurus of subject headings for television    
+scbi   http://id.loc.gov/vocabulary/subjectSchemes/scbi        Soggettario per i cataloghi delle biblioteche italiane  "it"=>"Soggettario per i cataloghi delle biblioteche italiane"
+valo   http://id.loc.gov/vocabulary/subjectSchemes/valo        VALO - Fotografiska ontologin   "fi"=>"VALO - Fotografiska ontologin"
+wpicsh http://id.loc.gov/vocabulary/subjectSchemes/wpicsh      WPIC Library thesaurus of subject headings      
+aktp   http://id.loc.gov/vocabulary/subjectSchemes/aktp        AlphavÄ\93tikos Katalogos ThematikÅ\8dn PerigrapheÅ\8dn "el"=>"AlphavÄ\93tikos Katalogos ThematikÅ\8dn PerigrapheÅ\8dn"
+stw    http://id.loc.gov/vocabulary/subjectSchemes/stw STW Thesaurus for Economics     "de"=>"Standard-Thesaurus Wirtschaft"
+mesh   http://id.loc.gov/vocabulary/subjectSchemes/mesh        Medical subject headings        
+ica    http://id.loc.gov/vocabulary/subjectSchemes/ica Index of Christian art  
+emnmus http://id.loc.gov/vocabulary/subjectSchemes/emnmus      Emneord for musikkdokument i EDB-kataloger      "no"=>"Emneord for musikkdokument i EDB-kataloger"
+sao    http://id.loc.gov/vocabulary/subjectSchemes/sao Svenska Ã¤mnesord     "sv"=>"Svenska Ã¤mnesord"
+sgc    http://id.loc.gov/vocabulary/subjectSchemes/sgc COBISS.SI General List of subject headings (Slovenian subject headings) "sl"=>"SploÅ¡ni geslovnik COBISS.SI"
+bib1814        http://id.loc.gov/vocabulary/subjectSchemes/bib1814     1814-bibliografi: emneord for 1814-bibliografi  "no"=>"1814-bibliografi: emneord for 1814-bibliografi"
+bjornson       http://id.loc.gov/vocabulary/subjectSchemes/bjornson    Bjornson: emneord for Bjornsonbibliografien     "no"=>"Bjornson: emneord for Bjornsonbibliografien"
+liito  http://id.loc.gov/vocabulary/subjectSchemes/liito       LIITO - Liiketoimintaontologia  "fi"=>"LIITO - Liiketoimintaontologia"
+apaist http://id.loc.gov/vocabulary/subjectSchemes/apaist      APAIS thesaurus: a list of subject terms used in the Australian Public Affairs Information Service      
+itglit http://id.loc.gov/vocabulary/subjectSchemes/itglit      International thesaurus of gay and lesbian index terms (Chicago?: Thesaurus Committee, Gay and Lesbian Task Force, American Library Association)        
+ntcsd  http://id.loc.gov/vocabulary/subjectSchemes/ntcsd       "National Translations Center secondary descriptors" in National Translation Center primary subject classification and secondary descriptor     
+scisshl        http://id.loc.gov/vocabulary/subjectSchemes/scisshl     SCIS subject headings   
+opms   http://id.loc.gov/vocabulary/subjectSchemes/opms        Opetusministeriön asiasanasto        "fi"=>"Opetusministeriön asiasanasto"
+ttka   http://id.loc.gov/vocabulary/subjectSchemes/ttka        Teologisen tiedekunnan kirjaston asiasanasto    "fi"=>"Teologisen tiedekunnan kirjaston asiasanasto"
+watrest        http://id.loc.gov/vocabulary/subjectSchemes/watrest     Thesaurus of water resources terms: a collection of water resources and related terms for use in indexing technical information 
+ysa    http://id.loc.gov/vocabulary/subjectSchemes/ysa Yleinen suomalainen asiasanasto "fi"=>"Yleinen suomalainen asiasanasto"
+kitu   http://id.loc.gov/vocabulary/subjectSchemes/kitu        Kirjallisuudentutkimuksen asiasanasto   "fi"=>"Kirjallisuudentutkimuksen asiasanasto"
+sk     http://id.loc.gov/vocabulary/subjectSchemes/sk  'Zhong guo gu ji shan ban shu zong mu' fen lei biao     "zh"=>"'Zhong guo gu ji shan ban shu zong mu' fen lei biao"
+aiatsisp       http://id.loc.gov/vocabulary/subjectSchemes/aiatsisp    AIATSIS place thesaurus 
+ram    http://id.loc.gov/vocabulary/subjectSchemes/ram RAMEAU: répertoire d'authorité de matières encyclopédique unifié "fr"=>"RAMEAU: répertoire d'authorité de matières encyclopédique unifié"
+aedoml http://id.loc.gov/vocabulary/subjectSchemes/aedoml      Listado de encabezamientos de materia de música      "es"=>"Listado de encabezamientos de materia de música"
+ated   http://id.loc.gov/vocabulary/subjectSchemes/ated        Australian Thesaurus of Education Descriptors (ATED)    
+cabt   http://id.loc.gov/vocabulary/subjectSchemes/cabt        CAB thesaurus (Slough [England]: Commonwealth Agricultural Bureaux)     
+kassu  http://id.loc.gov/vocabulary/subjectSchemes/kassu       Kassu - Kasvien suomenkieliset nimet    "fi"=>"Kassu - Kasvien suomenkieliset nimet"
+nbdbt  http://id.loc.gov/vocabulary/subjectSchemes/nbdbt       NBD Biblion Trefwoordenthesaurus        "nl"=>"NBD Biblion Trefwoordenthesaurus"
+jhpb   http://id.loc.gov/vocabulary/subjectSchemes/jhpb        JÄ\99zyk haseÅ\82 przedmiotowych Biblioteki Narodowej   "pl"=>"JÄ\99zyk haseÅ\82 przedmiotowych Biblioteki Narodowej"
+bidex  http://id.loc.gov/vocabulary/subjectSchemes/bidex       Bilindex: a bilingual Spanish-English subject heading list      
+ccsa   http://id.loc.gov/vocabulary/subjectSchemes/ccsa        Catalogue collectif suisse des affiches "fr"=>"Catalogue collectif suisse des affiches"
+noraf  http://id.loc.gov/vocabulary/subjectSchemes/noraf       Norwegian Authority File        
+kito   http://id.loc.gov/vocabulary/subjectSchemes/kito        KITO - Kirjallisuudentutkimuksen ontologia      "fi"=>"KITO - Kirjallisuudentutkimuksen ontologia"
+tho    http://id.loc.gov/vocabulary/subjectSchemes/tho Thesauros HellÄ\93nikÅ\8dn Oron "el"=>"Thesauros HellÄ\93nikÅ\8dn Oron"
+pmont  http://id.loc.gov/vocabulary/subjectSchemes/pmont       Powerhouse Museum Object Name Thesaurus 
+ssg    http://id.loc.gov/vocabulary/subjectSchemes/ssg SploÅ¡ni slovenski geslovnik  "sl"=>"SploÅ¡ni slovenski geslovnik"
+huc    http://id.loc.gov/vocabulary/subjectSchemes/huc U.S. Geological Survey water-supply paper 2294: hydrologic basins unit codes    
+isis   http://id.loc.gov/vocabulary/subjectSchemes/isis        "Classification scheme" in Isis 
+ibsen  http://id.loc.gov/vocabulary/subjectSchemes/ibsen       Ibsen: emneord for Den internasjonale Ibsen-bibliografien       "no"=>"Ibsen: emneord for Den internasjonale Ibsen-bibliografien"
+lacnaf http://id.loc.gov/vocabulary/subjectSchemes/lacnaf      Library and Archives Canada name authority file 
+swemesh        http://id.loc.gov/vocabulary/subjectSchemes/swemesh     Swedish MeSH    "sv"=>"Svenska MeSH"
+hamsun http://id.loc.gov/vocabulary/subjectSchemes/hamsun      Hamsun: emneord for Hamsunbibliografien "no"=>"Hamsun: emneord for Hamsunbibliografien"
+qrma   http://id.loc.gov/vocabulary/subjectSchemes/qrma        List of Arabic subject headings "ar"=>"Qâ'imat ru'ûs al-mawdûât al-'Arabîyah"
+qrmak  http://id.loc.gov/vocabulary/subjectSchemes/qrmak       Qâ'imat ru'ûs al-mawdû'ât al-'Arabîyah al-qiyâsîyah al-maktabât wa-marâkaz al-ma'lûmât wa-qawâid al-bayânât   "ar"=>"Qâ'imat ru'ûs al-mawdû'ât al-'Arabîyah al-qiyâsîyah al-maktabât wa-marâkaz al-ma'lûmât wa-qawâid al-bayânât"
+ceeus  http://id.loc.gov/vocabulary/subjectSchemes/ceeus       Counties and equivalent entities of the United States its possessions, and associated areas     
+taxhs  http://id.loc.gov/vocabulary/subjectSchemes/taxhs       A taxonomy or human services: a conceptual framework with standardized terminology and definitions for the field        
+noram  http://id.loc.gov/vocabulary/subjectSchemes/noram       Noram: emneord for Norsk-amerikansk samling     "no"=>"Noram: emneord for Norsk-amerikansk samling"
+eurovocfr      http://id.loc.gov/vocabulary/subjectSchemes/eurovocfr   Eurovoc thesaurus (French)      
+jurivoc        http://id.loc.gov/vocabulary/subjectSchemes/jurivoc     JURIVOC 
+agrifors       http://id.loc.gov/vocabulary/subjectSchemes/agrifors    AGRIFOREST-sanasto      "fi"=>"AGRIFOREST-sanasto"
+noubojur       http://id.loc.gov/vocabulary/subjectSchemes/noubojur    Thesaurus of Law        "no"=>"Thesaurus of Law"
+pha    http://id.loc.gov/vocabulary/subjectSchemes/pha Puolostushallinnon asiasanasto  "fi"=>"Puolostushallinnon asiasanasto"
+ddcrit http://id.loc.gov/vocabulary/subjectSchemes/ddcrit      DDC retrieval and indexing terminology; posting terms with hierarchy and KWOC   
+mar    http://id.loc.gov/vocabulary/subjectSchemes/mar Merenkulun asiasanasto  "fi"=>"Merenkulun asiasanasto"
+sbt    http://id.loc.gov/vocabulary/subjectSchemes/sbt Soggettario Sistema Bibliotecario Ticinese      "it"=>"Soggettario Sistema Bibliotecario Ticinese"
+nzggn  http://id.loc.gov/vocabulary/subjectSchemes/nzggn       New Zealand gazetteer of official geographic names (New Zealand Geographic Board Ngā Pou Taunaha o Aotearoa (NZGB))    
+kta    http://id.loc.gov/vocabulary/subjectSchemes/kta Kielitieteen asiasanasto        "fi"=>"Kielitieteen asiasanasto"
+snt    http://id.loc.gov/vocabulary/subjectSchemes/snt Sexual nomenclature : a thesaurus       
+francis        http://id.loc.gov/vocabulary/subjectSchemes/francis     FRANCIS database classification scheme  "fr"=>"Base de donneés FRANCIS: plan de classement"
+eurovocsl      http://id.loc.gov/vocabulary/subjectSchemes/eurovocsl   Eurovoc thesaurus       "sl"=>"Eurovoc thesaurus"
+idszbzes       http://id.loc.gov/vocabulary/subjectSchemes/idszbzes    Thesaurus IDS Nebis Bibliothek Englisches Seminar der Universität Zürich  "de"=>"Thesaurus IDS Nebis Bibliothek Englisches Seminar der Universität Zürich"
+nlmnaf http://id.loc.gov/vocabulary/subjectSchemes/nlmnaf      National Library of Medicine name authority file        
+rugeo  http://id.loc.gov/vocabulary/subjectSchemes/rugeo       Natsional'nyi normativnyi fail geograficheskikh nazvanii Rossiiskoi Federatsii  "ru"=>"Natsional'nyi normativnyi fail geograficheskikh nazvanii Rossiiskoi Federatsii"
+sipri  http://id.loc.gov/vocabulary/subjectSchemes/sipri       SIPRI library thesaurus 
+kkts   http://id.loc.gov/vocabulary/subjectSchemes/kkts        Katalogos KathierÅ\8dmenÅ\8dn TypÅ\8dn Syllogikou Katalogou Demosion Vivliothekon       "el"=>"Katalogos KathierÅ\8dmenÅ\8dn TypÅ\8dn Syllogikou Katalogou Demosion Vivliothekon"
+tucua  http://id.loc.gov/vocabulary/subjectSchemes/tucua       Thesaurus for use in college and university archives    
+pmbok  http://id.loc.gov/vocabulary/subjectSchemes/pmbok       Guide to the project management body of knowledge (PMBOK Guide) 
+agrovoc        http://id.loc.gov/vocabulary/subjectSchemes/agrovoc     AGROVOC multilingual agricultural thesaurus     
+nal    http://id.loc.gov/vocabulary/subjectSchemes/nal National Agricultural Library subject headings  
+lnmmbr http://id.loc.gov/vocabulary/subjectSchemes/lnmmbr      Lietuvos nacionalines Martyno Mazvydo bibliotekos rubrikynas    "lt"=>"Lietuvos nacionalines Martyno Mazvydo bibliotekos rubrikynas"
+vmj    http://id.loc.gov/vocabulary/subjectSchemes/vmj Vedettes-matière jeunesse    "fr"=>"Vedettes-matière jeunesse"
+ddcut  http://id.loc.gov/vocabulary/subjectSchemes/ddcut       Dewey Decimal Classification user terms 
+eks    http://id.loc.gov/vocabulary/subjectSchemes/eks Eduskunnan kirjaston asiasanasto        "fi"=>"Eduskunnan kirjaston asiasanasto"
+wot    http://id.loc.gov/vocabulary/subjectSchemes/wot A Women's thesaurus     
+noubomn        http://id.loc.gov/vocabulary/subjectSchemes/noubomn     University of Oslo Library Thesaurus of Science "no"=>"University of Oslo Library Thesaurus of Science"
+idszbzzg       http://id.loc.gov/vocabulary/subjectSchemes/idszbzzg    Thesaurus IDS Nebis Zentralbibliothek Zürich, Graphische Sammlung    "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Graphische Sammlung"
+precis http://id.loc.gov/vocabulary/subjectSchemes/precis      PRECIS: a manual of concept analysis and subject indexing       
+cstud  http://id.loc.gov/vocabulary/subjectSchemes/cstud       Classificatieschema's Bibliotheek TU Delft      "nl"=>"Classificatieschema's Bibliotheek TU Delft"
+nlgkk  http://id.loc.gov/vocabulary/subjectSchemes/nlgkk       Katalogos kathierÅ\8dmenÅ\8dn onomatÅ\8dn physikÅ\8dn prosÅ\8d\8dn    "el"=>"Katalogos kathierÅ\8dmenÅ\8dn onomatÅ\8dn physikÅ\8dn prosÅ\8d\8dn"
+pmt    http://id.loc.gov/vocabulary/subjectSchemes/pmt Project management terminology. Newtown Square, PA: Project Management Institute        
+ericd  http://id.loc.gov/vocabulary/subjectSchemes/ericd       Thesaurus of ERIC descriptors   
+rvm    http://id.loc.gov/vocabulary/subjectSchemes/rvm Répertoire de vedettes-matière    "fr"=>"Répertoire de vedettes-matière"
+sfit   http://id.loc.gov/vocabulary/subjectSchemes/sfit        Svenska filminstitutets tesaurus        "sv"=>"Svenska filminstitutets tesaurus"
+trtsa  http://id.loc.gov/vocabulary/subjectSchemes/trtsa       Teatterin ja tanssin asiasanasto        "fi"=>"Teatterin ja tanssin asiasanasto"
+ulan   http://id.loc.gov/vocabulary/subjectSchemes/ulan        Union list of artist names      
+unescot        http://id.loc.gov/vocabulary/subjectSchemes/unescot     UNESCO thesaurus        "fr"=>"Thésaurus de l'UNESCO","es"=>"Tesauro de la UNESCO"
+koko   http://id.loc.gov/vocabulary/subjectSchemes/koko        KOKO-ontologia  "fi"=>"KOKO-ontologia"
+msh    http://id.loc.gov/vocabulary/subjectSchemes/msh Trimboli, T., and Martyn S. Marianist subject headings  
+trt    http://id.loc.gov/vocabulary/subjectSchemes/trt Transportation resource thesaurus       
+agrovocf       http://id.loc.gov/vocabulary/subjectSchemes/agrovocf    AGROVOC thésaurus agricole multilingue       "fr"=>"AGROVOC thésaurus agricole multilingue"
+aucsh  http://id.loc.gov/vocabulary/subjectSchemes/aucsh       Arabic Union Catalog Subject Headings   "ar"=>"Qâ'imat ru'ûs mawdû'ât al-fahras al-'Arabîyah al-mowahad"
+ddcri  http://id.loc.gov/vocabulary/subjectSchemes/ddcri       Dewey Decimal Classification Relative Index     
+est    http://id.loc.gov/vocabulary/subjectSchemes/est International energy: subject thesaurus (: International Energy Agency, Energy Technology Data Exchange)        
+lua    http://id.loc.gov/vocabulary/subjectSchemes/lua Liikunnan ja urheilun asiasanasto       "fi"=>"Liikunnan ja urheilun asiasanasto"
+mipfesd        http://id.loc.gov/vocabulary/subjectSchemes/mipfesd     Macrothesaurus for information processing in the field of economic and social development       
+rurkp  http://id.loc.gov/vocabulary/subjectSchemes/rurkp       Predmetnye rubriki Rossiiskoi knizhnoi palaty   "ru"=>"Predmetnye rubriki Rossiiskoi knizhnoi palaty"
+albt   http://id.loc.gov/vocabulary/subjectSchemes/albt        Arbetslivsbibliotekets tesaurus "sv"=>"Arbetslivsbibliotekets tesaurus"
+fmesh  http://id.loc.gov/vocabulary/subjectSchemes/fmesh       Liste systématique et liste permutée des descripteurs français MeSH    "fr"=>"Liste systématique et liste permutée des descripteurs français MeSH"
+bicssc http://id.loc.gov/vocabulary/subjectSchemes/bicssc      BIC standard subject categories 
+cctf   http://id.loc.gov/vocabulary/subjectSchemes/cctf        Carto-Canadiana thésaurus - Français      "fr"=>"Carto-Canadiana thésaurus - Français"
+reo    http://id.loc.gov/vocabulary/subjectSchemes/reo Māori Subject Headings thesaurus       "mi"=>"Ngā Åªpoko Tukutuku"
+icpsr  http://id.loc.gov/vocabulary/subjectSchemes/icpsr       ICPSR controlled vocabulary system      
+kao    http://id.loc.gov/vocabulary/subjectSchemes/kao KVINNSAM Ã¤mnesordsregister   "sv"=>"KVINNSAM Ã¤mnesordsregister"
+asrcseo        http://id.loc.gov/vocabulary/subjectSchemes/asrcseo     Australian Standard Research Classification: Socio-Economic Objective (SEO) classification      
+georeft        http://id.loc.gov/vocabulary/subjectSchemes/georeft     GeoRef thesaurus        
+cct    http://id.loc.gov/vocabulary/subjectSchemes/cct Chinese Classified Thesaurus    "zh"=>"Zhong guo fen lei zhu ti ci biao"
+dcs    http://id.loc.gov/vocabulary/subjectSchemes/dcs Health Sciences Descriptors     "es"=>"Descriptores en Ciencias de la Salud","pt"=>"Descritores em Ciências da Saúde"
+musa   http://id.loc.gov/vocabulary/subjectSchemes/musa        Musiikin asiasanasto: erikoissanasto    "fi"=>"Musiikin asiasanasto: erikoissanasto"
+ntissc http://id.loc.gov/vocabulary/subjectSchemes/ntissc      NTIS subject categories 
+idszbz http://id.loc.gov/vocabulary/subjectSchemes/idszbz      Thesaurus IDS Nebis Zentralbibliothek Zürich "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich"
+tlka   http://id.loc.gov/vocabulary/subjectSchemes/tlka        Investigació, Procés Tècnicn kirjaston asiasanasto     "fi"=>"Investigació, Procés Tècnicn kirjaston asiasanasto"
+usaidt http://id.loc.gov/vocabulary/subjectSchemes/usaidt      USAID thesaurus: Keywords used to index documents included in the USAID Development Experience System.  
+embne  http://id.loc.gov/vocabulary/subjectSchemes/embne       Encabezamientos de Materia de la Biblioteca Nacional de España       "es"=>"Encabezamientos de Materia de la Biblioteca Nacional de España"
+vcaadu http://id.loc.gov/vocabulary/subjectSchemes/vcaadu      Vocabulario controlado de arquitectura, arte, diseño y urbanismo     "es"=>"Vocabulario controlado de arquitectura, arte, diseño y urbanismo"
+ntcpsc http://id.loc.gov/vocabulary/subjectSchemes/ntcpsc      "National Translations Center primary subject classification" in National Translations Center primary subject classification and secondary descriptors  
+quiding        http://id.loc.gov/vocabulary/subjectSchemes/quiding     Quiding, Nils Herman. Svenskt allmänt författningsregister för tiden frÃ¥n Ã¥r 1522 till och med Ã¥r 1862        "sv"=>"Quiding, Nils Herman. Svenskt allmänt författningsregister för tiden frÃ¥n Ã¥r 1522 till och med Ã¥r 1862"
+allars http://id.loc.gov/vocabulary/subjectSchemes/allars      Allärs: allmän tesaurus pä svenska     "fi"=>"Allärs: allmän tesaurus pä svenska"
+ogst   http://id.loc.gov/vocabulary/subjectSchemes/ogst        Oregon GILS Subject Tree (Oregon: Oregon State Library and Oregon Information Resource Management Division (IRMD))      
+bella  http://id.loc.gov/vocabulary/subjectSchemes/bella       Bella: specialtesaurus för skönlitteratur "fi"=>"Bella: specialtesaurus för skönlitteratur"
+bibalex        http://id.loc.gov/vocabulary/subjectSchemes/bibalex     Bibliotheca Alexandrina name and subject authority file 
+pepp   http://id.loc.gov/vocabulary/subjectSchemes/pepp        The Princeton encyclopedia of poetry and poetics        
+hkcan  http://id.loc.gov/vocabulary/subjectSchemes/hkcan       Hong Kong Chinese Authority File (Name) - HKCAN 
+dissao http://id.loc.gov/vocabulary/subjectSchemes/dissao      "Dissertation abstracts online" in Search tools: the guide to UNI/Data Courier Online   
+ltcsh  http://id.loc.gov/vocabulary/subjectSchemes/ltcsh       Land Tenure Center Library list of subject headings     
+mpirdes        http://id.loc.gov/vocabulary/subjectSchemes/mpirdes     Macrothesaurus para el procesamiento de la información relativa al desarrollo económico y social  "es"=>"Macrothesaurus para el procesamiento de la información relativa al desarrollo económico y social"
+asft   http://id.loc.gov/vocabulary/subjectSchemes/asft        Aquatic sciences and fisheries thesaurus        
+naf    http://id.loc.gov/vocabulary/subjectSchemes/naf NACO authority file     
+nimacsc        http://id.loc.gov/vocabulary/subjectSchemes/nimacsc     NIMA cartographic subject categories    
+khib   http://id.loc.gov/vocabulary/subjectSchemes/khib        Emneord, KHiB Biblioteket       "no"=>"Emneord, KHiB Biblioteket"
+cdcng  http://id.loc.gov/vocabulary/subjectSchemes/cdcng       Catalogage des documents cartographiques: forme et structure des vedettes noms géographiques - NF Z 44-081   "fr"=>"Catalogage des documents cartographiques: forme et structure des vedettes noms géographiques - NF Z 44-081"
+afset  http://id.loc.gov/vocabulary/subjectSchemes/afset       American Folklore Society Ethnographic Thesaurus        
+erfemn http://id.loc.gov/vocabulary/subjectSchemes/erfemn      Erfaringskompetanses emneord    "no"=>"Erfaringskompetanses emneord"
+sbiao  http://id.loc.gov/vocabulary/subjectSchemes/sbiao       Svenska barnboksinstitutets Ã¤mnesordslista   "sv"=>"Svenska barnboksinstitutets Ã¤mnesordslista"
+socio  http://id.loc.gov/vocabulary/subjectSchemes/socio       Sociological Abstracts Thesaurus        
+bisacrt        http://id.loc.gov/vocabulary/subjectSchemes/bisacrt     BISAC Regional Themes   
+eum    http://id.loc.gov/vocabulary/subjectSchemes/eum Eesti uldine märksonastik    "et"=>"Eesti uldine märksonastik"
+kula   http://id.loc.gov/vocabulary/subjectSchemes/kula        Kulttuurien tutkimuksen asiasanasto     "fi"=>"Kulttuurien tutkimuksen asiasanasto"
+odlt   http://id.loc.gov/vocabulary/subjectSchemes/odlt        Baldick, C. The Oxford dictionary of literary terms     
+rerovoc        http://id.loc.gov/vocabulary/subjectSchemes/rerovoc     Indexation matiéres RERO autoritès        "fr"=>"Indexation matiéres RERO autoritès"
+tsr    http://id.loc.gov/vocabulary/subjectSchemes/tsr TSR-ontologia   "fi"=>"TSR-ontologia"
+czmesh http://id.loc.gov/vocabulary/subjectSchemes/czmesh      Czech MeSH      "cs"=>"Czech MeSH"
+dltt   http://id.loc.gov/vocabulary/subjectSchemes/dltt        Quinn, E. A dictionary of literary and thematic terms   
+idsbb  http://id.loc.gov/vocabulary/subjectSchemes/idsbb       Thesaurus IDS Basel Bern        "de"=>"Thesaurus IDS Basel Bern"
+inist  http://id.loc.gov/vocabulary/subjectSchemes/inist       INIS: thesaurus 
+idszbzzk       http://id.loc.gov/vocabulary/subjectSchemes/idszbzzk    Thesaurus IDS Nebis Zentralbibliothek Zürich, Kartensammlung "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Kartensammlung"
+tesa   http://id.loc.gov/vocabulary/subjectSchemes/tesa        Tesauro Agrícola     "es"=>"Tesauro Agrícola"
+liv    http://id.loc.gov/vocabulary/subjectSchemes/liv Legislative indexing vocabulary 
+collett        http://id.loc.gov/vocabulary/subjectSchemes/collett     Collett-bibliografi: litteratur av og om Camilla Collett        "no"=>"Collett-bibliografi: litteratur av og om Camilla Collett"
+nsbncf http://id.loc.gov/vocabulary/subjectSchemes/nsbncf      Nuovo Soggettario       "it"=>"Nuovo Soggettario"
+ipat   http://id.loc.gov/vocabulary/subjectSchemes/ipat        IPA thesaurus and frequency list        
+skon   http://id.loc.gov/vocabulary/subjectSchemes/skon        Att indexera skönlitteratur: Ã\84mnesordslista, vuxenlitteratur      "sv"=>"Att indexera skönlitteratur: Ã\84mnesordslista, vuxenlitteratur"
+renib  http://id.loc.gov/vocabulary/subjectSchemes/renib       Renib   "es"=>"Renib"
+hrvmesh        http://id.loc.gov/vocabulary/subjectSchemes/hrvmesh     Croatian MeSH / Hrvatski MeSH   "no"=>"Croatian MeSH / Hrvatski MeSH"
+swd    http://id.loc.gov/vocabulary/subjectSchemes/swd Schlagwortnormdatei     "de"=>"Schlagwortnormdatei"
+aass   http://id.loc.gov/vocabulary/subjectSchemes/aass        "Asian American Studies Library subject headings" in A Guide for establishing Asian American core collections   
+cht    http://id.loc.gov/vocabulary/subjectSchemes/cht Chicano thesaurus for indexing Chicano materials in Chicano periodical index    
+galestne       http://id.loc.gov/vocabulary/subjectSchemes/galestne    Gale Group subject thesaurus and named entity vocabulary        
+nlgsh  http://id.loc.gov/vocabulary/subjectSchemes/nlgsh       Katalogos HellÄ\93nikÅ\8dn thematikÅ\8dn epikephalidÅ\8dn       "el"=>"Katalogos HellÄ\93nikÅ\8dn thematikÅ\8dn epikephalidÅ\8dn"
+hoidokki       http://id.loc.gov/vocabulary/subjectSchemes/hoidokki    Hoitotieteellinen asiasanasto   
+vffyl  http://id.loc.gov/vocabulary/subjectSchemes/vffyl       Vocabulario de la Biblioteca Central de la FFyL "es"=>"Vocabulario de la Biblioteca Central de la FFyL"
+kubikat        http://id.loc.gov/vocabulary/subjectSchemes/kubikat     kubikat "de"=>"kubikat"
+waqaf  http://id.loc.gov/vocabulary/subjectSchemes/waqaf       Maknas Uloom Al Waqaf   "ar"=>"Maknas Uloom Al Waqaf"
+hapi   http://id.loc.gov/vocabulary/subjectSchemes/hapi        HAPI thesaurus and name authority, 1970-2000    
+drama  http://id.loc.gov/vocabulary/subjectSchemes/drama       Drama: specialtesaurus för teater och dans   
+sosa   http://id.loc.gov/vocabulary/subjectSchemes/sosa        Sociaalialan asiasanasto        "fi"=>"Sociaalialan asiasanasto"
+ilpt   http://id.loc.gov/vocabulary/subjectSchemes/ilpt        Index to legal periodicals: thesaurus   
+nicem  http://id.loc.gov/vocabulary/subjectSchemes/nicem       NICEM subject headings and classification system        
+qlsp   http://id.loc.gov/vocabulary/subjectSchemes/qlsp        Queens Library Spanish language subject headings        
+eet    http://id.loc.gov/vocabulary/subjectSchemes/eet European education thesaurus    
+nalnaf http://id.loc.gov/vocabulary/subjectSchemes/nalnaf      National Agricultural Library name authority file       
+eclas  http://id.loc.gov/vocabulary/subjectSchemes/eclas       ECLAS thesaurus 
+agrovocs       http://id.loc.gov/vocabulary/subjectSchemes/agrovocs    AGROVOC tesauro agrícola multilingée      "es"=>"AGROVOC tesauro agrícola multilingée"
+shbe   http://id.loc.gov/vocabulary/subjectSchemes/shbe        Subject headings in business and economics      "sv"=>"Subject headings in business and economics"
+barn   http://id.loc.gov/vocabulary/subjectSchemes/barn        Svenska Ã¤mnesord för barn "sv"=>"Svenska Ã¤mnesord för barn"
+bhammf http://id.loc.gov/vocabulary/subjectSchemes/bhammf      BHA, Bibliographie d'histoire de l'art, mots-matière/français     "fr"=>"BHA, Bibliographie d'histoire de l'art, mots-matière/français"
+gccst  http://id.loc.gov/vocabulary/subjectSchemes/gccst       Government of Canada core subject thesaurus (Gatineau : Library and Archives Canada)    
+fnhl   http://id.loc.gov/vocabulary/subjectSchemes/fnhl        First Nations House of Learning Subject Headings        
+kauno  http://id.loc.gov/vocabulary/subjectSchemes/kauno       KAUNO - Kaunokki-ontologin      "fi"=>"KAUNO - Kaunokki-ontologin"
+dtict  http://id.loc.gov/vocabulary/subjectSchemes/dtict       Defense Technical Information Center thesaurus  
+mech   http://id.loc.gov/vocabulary/subjectSchemes/mech        Iskanje po zbirki MECH  "sl"=>"Iskanje po zbirki MECH"
+jupo   http://id.loc.gov/vocabulary/subjectSchemes/jupo        JUPO - Julkisen hallinnon palveluontologia      "fi"=>"JUPO - Julkisen hallinnon palveluontologia"
+ktpt   http://id.loc.gov/vocabulary/subjectSchemes/ktpt        Kirjasto- ja tietopalvelualan tesaurus  "fi"=>"Kirjasto- ja tietopalvelualan tesaurus"
+aiatsiss       http://id.loc.gov/vocabulary/subjectSchemes/aiatsiss    AIATSIS subject Thesaurus       
+lcac   http://id.loc.gov/vocabulary/subjectSchemes/lcac        Library of Congress Annotated Children's Cataloging Program subject headings    
+lemac  http://id.loc.gov/vocabulary/subjectSchemes/lemac       Llista d'encapçalaments de matèria en català   "ca"=>"Llista d'encapçalaments de matèria en català"
+lemb   http://id.loc.gov/vocabulary/subjectSchemes/lemb        Lista de encabezamientos de materia para bibliotecas    "es"=>"Lista de encabezamientos de materia para bibliotecas"
+henn   http://id.loc.gov/vocabulary/subjectSchemes/henn        Hennepin County Library cumulative authority list       
+mtirdes        http://id.loc.gov/vocabulary/subjectSchemes/mtirdes     Macrothésaurus pour le traitement de l'information relative au développement Ã©conomique et social      "fr"=>"Macrothésaurus pour le traitement de l'information relative au développement Ã©conomique et social"
+cash   http://id.loc.gov/vocabulary/subjectSchemes/cash        Canadian subject headings       
+nznb   http://id.loc.gov/vocabulary/subjectSchemes/nznb        New Zealand national bibliographic      
+prvt   http://id.loc.gov/vocabulary/subjectSchemes/prvt        Patent- och registreringsverkets tesaurus       "sv"=>"Patent- och registreringsverkets tesaurus"
+scgdst http://id.loc.gov/vocabulary/subjectSchemes/scgdst      Subject categorization guide for defense science and technology 
+gem    http://id.loc.gov/vocabulary/subjectSchemes/gem GEM controlled vocabularies     
+lcsh   http://id.loc.gov/vocabulary/subjectSchemes/lcsh        Library of Congress subject headings    
+rero   http://id.loc.gov/vocabulary/subjectSchemes/rero        Indexation matires RERO "fr"=>"Indexation matires RERO"
+peri   http://id.loc.gov/vocabulary/subjectSchemes/peri        Perinnetieteiden asiasanasto    "fi"=>"Perinnetieteiden asiasanasto"
+shsples        http://id.loc.gov/vocabulary/subjectSchemes/shsples     Encabezamientos de materia para bibliotecas escolares y públicas     "es"=>"Encabezamientos de materia para bibliotecas escolares y públicas"
+slem   http://id.loc.gov/vocabulary/subjectSchemes/slem        Sears: lista de encabezamientos de materia      "es"=>"Sears: lista de encabezamientos de materia"
+afo    http://id.loc.gov/vocabulary/subjectSchemes/afo AFO - Viikin kampuskirjaston ontologia  "fi"=>"AFO - Viikin kampuskirjaston ontologia"
+gst    http://id.loc.gov/vocabulary/subjectSchemes/gst Gay studies thesaurus: a controlled vocabulary for indexing and accessing materials of relevance to gay culture, history, politics and psychology       
+hlasstg        http://id.loc.gov/vocabulary/subjectSchemes/hlasstg     HLAS subject term glossary      
+iest   http://id.loc.gov/vocabulary/subjectSchemes/iest        International energy: subject thesaurus 
+pkk    http://id.loc.gov/vocabulary/subjectSchemes/pkk Predmetnik za katoliÅ¡ke knjižnice "sl"=>"Predmetnik za katoliÅ¡ke knjižnice"
+atla   http://id.loc.gov/vocabulary/subjectSchemes/atla        Religion indexes: thesaurus     
+scot   http://id.loc.gov/vocabulary/subjectSchemes/scot        Schools Online Thesaurus (ScOT) 
+smda   http://id.loc.gov/vocabulary/subjectSchemes/smda        Smithsonian National Air and Space Museum Directory of Airplanes        
+solstad        http://id.loc.gov/vocabulary/subjectSchemes/solstad     Solstad: emneord for Solstadbibliografien       "no"=>"Solstad: emneord for Solstadbibliografien"
+abne   http://id.loc.gov/vocabulary/subjectSchemes/abne        Autoridades de la Biblioteca Nacional de España      "es"=>"Autoridades de la Biblioteca Nacional de España"
+spines http://id.loc.gov/vocabulary/subjectSchemes/spines      Tesauro SPINES: un vocabulario controlado y estructurado para el tratamiento de información sobre ciencia y tecnología para el desarrollo "es"=>"Tesauro SPINES: un vocabulario controlado y estructurado para el tratamiento de información sobre ciencia y tecnología para el desarrollo"
+ktta   http://id.loc.gov/vocabulary/subjectSchemes/ktta        Käsi - ja taideteollisuuden asiasanasto      "fi"=>"Käsi - ja taideteollisuuden asiasanasto"
+ccte   http://id.loc.gov/vocabulary/subjectSchemes/ccte        Carto-Canadiana thesaurus - English     
+pmcsg  http://id.loc.gov/vocabulary/subjectSchemes/pmcsg       Combined standards glossary     
+bisacsh        http://id.loc.gov/vocabulary/subjectSchemes/bisacsh     BISAC Subject Headings  
+fssh   http://id.loc.gov/vocabulary/subjectSchemes/fssh        FamilySearch Subject Headings (FamilySearch)    
+tasmas http://id.loc.gov/vocabulary/subjectSchemes/tasmas      Tesaurus de Asuntos Sociales del Ministerio de Asuntos Sociales de España    "es"=>"Tesaurus de Asuntos Sociales del Ministerio de Asuntos Sociales de España"
+tero   http://id.loc.gov/vocabulary/subjectSchemes/tero        TERO - Terveyden ja hyvinvoinnin ontologia      "fi"=>"TERO - Terveyden ja hyvinvoinnin ontologia"
+rma    http://id.loc.gov/vocabulary/subjectSchemes/rma Ru'us al-mawdu'at al-'Arabiyah  "ar"=>"Ru'us al-mawdu'at al-'Arabiyah"
+tgn    http://id.loc.gov/vocabulary/subjectSchemes/tgn Getty thesaurus of geographic names     
+tha    http://id.loc.gov/vocabulary/subjectSchemes/tha Barcala de Moyano, Graciela G., Cristina Voena. Tesauro de Historia Argentina   "es"=>"Barcala de Moyano, Graciela G., Cristina Voena. Tesauro de Historia Argentina"
+ttll   http://id.loc.gov/vocabulary/subjectSchemes/ttll        Roggau, Zunilda. Tell. Tesauro de lengua y literatura   "es"=>"Roggau, Zunilda. Tell. Tesauro de lengua y literatura"
+sears  http://id.loc.gov/vocabulary/subjectSchemes/sears       Sears list of subject headings  
+csht   http://id.loc.gov/vocabulary/subjectSchemes/csht        Chinese subject headings        
+\.
+
+-- ' ...blah
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
+INSERT INTO authority.thesaurus (code, uri, name, control_set)
+  SELECT code, uri, name, 1 FROM thesauri;
+END IF; END $INSERT$;                                                          
+
+
+UPDATE authority.thesaurus SET short_code = 'a' WHERE code = 'lcsh';
+UPDATE authority.thesaurus SET short_code = 'b' WHERE code = 'lcshac';
+UPDATE authority.thesaurus SET short_code = 'c' WHERE code = 'mesh';
+UPDATE authority.thesaurus SET short_code = 'd' WHERE code = 'nal';
+UPDATE authority.thesaurus SET short_code = 'k' WHERE code = 'cash';
+UPDATE authority.thesaurus SET short_code = 'r' WHERE code = 'aat';
+UPDATE authority.thesaurus SET short_code = 's' WHERE code = 'sears';
+UPDATE authority.thesaurus SET short_code = 'v' WHERE code = 'rvm';
+
+UPDATE  authority.thesaurus
+  SET   short_code = 'z'
+  WHERE short_code IS NULL
+        AND control_set = 1;
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+INSERT INTO config.i18n_core (fq_field, identity_value, translation, string )
+  SELECT  'at.name', t.code, xlate->key, xlate->value
+    FROM  thesauri t
+          JOIN LATERAL each(t.xlate) AS xlate ON TRUE
+    WHERE NOT EXISTS
+            (SELECT id
+              FROM  config.i18n_core
+              WHERE fq_field = 'at.name'
+                    AND identity_value = t.code
+                    AND translation = xlate->key)
+          AND t.xlate IS NOT NULL
+          AND t.name <> (xlate->value);
+END IF; END $INSERT$;                                                          
+
+
+CREATE OR REPLACE FUNCTION authority.extract_thesaurus( marcxml TEXT ) RETURNS TEXT AS $func$
+DECLARE
+    thes_code TEXT;
+BEGIN
+    thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
+    IF thes_code IS NULL THEN
+        thes_code := '|';
+    ELSIF thes_code = 'z' THEN
+        thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), 'z' );
+    ELSE
+        SELECT code INTO thes_code FROM authority.thesaurus WHERE short_code = thes_code;
+        IF NOT FOUND THEN
+            thes_code := '|'; -- default
+        END IF;
+    END IF;
+    RETURN thes_code;
+END;
+$func$ LANGUAGE PLPGSQL STABLE STRICT;
+
+CREATE OR REPLACE FUNCTION authority.map_thesaurus_to_control_set () RETURNS TRIGGER AS $func$
+BEGIN
+    IF NEW.control_set IS NULL THEN
+        SELECT control_set INTO NEW.control_set
+        FROM authority.thesaurus
+        WHERE code = authority.extract_thesaurus(NEW.marc);
+    END IF;
+
+    RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION authority.reingest_authority_rec_descriptor( auth_id BIGINT ) RETURNS VOID AS $func$
+BEGIN
+    DELETE FROM authority.rec_descriptor WHERE record = auth_id;
+    INSERT INTO authority.rec_descriptor (record, record_status, encoding_level, thesaurus)
+        SELECT  auth_id,
+                vandelay.marc21_extract_fixed_field(marc,'RecStat'),
+                vandelay.marc21_extract_fixed_field(marc,'ELvl'),
+                authority.extract_thesaurus(marc)
+          FROM  authority.record_entry
+          WHERE id = auth_id;
+    RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1071', :eg_version); --gmcharlt/kmlussier
+
+CREATE OR REPLACE FUNCTION metabib.staged_browse(query text, fields integer[], context_org integer, context_locations integer[], staff boolean, browse_superpage_size integer, count_up_from_zero boolean, result_limit integer, next_pivot_pos integer)
+ RETURNS SETOF metabib.flat_browse_entry_appearance
+AS $f$
+DECLARE
+    curs                    REFCURSOR;
+    rec                     RECORD;
+    qpfts_query             TEXT;
+    aqpfts_query            TEXT;
+    afields                 INT[];
+    bfields                 INT[];
+    result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
+    results_skipped         INT := 0;
+    row_counter             INT := 0;
+    row_number              INT;
+    slice_start             INT;
+    slice_end               INT;
+    full_end                INT;
+    all_records             BIGINT[];
+    all_brecords             BIGINT[];
+    all_arecords            BIGINT[];
+    superpage_of_records    BIGINT[];
+    superpage_size          INT;
+    c_tests                 TEXT := '';
+    b_tests                 TEXT := '';
+    c_orgs                  INT[];
+    unauthorized_entry      RECORD;
+BEGIN
+    IF count_up_from_zero THEN
+        row_number := 0;
+    ELSE
+        row_number := -1;
+    END IF;
+
+    IF NOT staff THEN
+        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
+    END IF;
+
+    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+    IF b_tests <> '' THEN b_tests := b_tests || '&'; END IF;
+
+    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
+
+    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
+               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
+
+    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
+    IF FOUND THEN
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
+        );
+    ELSE
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
+        );
+    END IF;
+
+    IF context_locations THEN
+        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_locations);
+    END IF;
+
+    OPEN curs NO SCROLL FOR EXECUTE query;
+
+    LOOP
+        FETCH curs INTO rec;
+        IF NOT FOUND THEN
+            IF result_row.pivot_point IS NOT NULL THEN
+                RETURN NEXT result_row;
+            END IF;
+            RETURN;
+        END IF;
+
+        --Is unauthorized?
+        SELECT INTO unauthorized_entry *
+        FROM metabib.browse_entry_simple_heading_map mbeshm
+        INNER JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+        INNER JOIN authority.control_set_authority_field acsaf ON ( acsaf.id = ash.atag )
+        JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
+        WHERE mbeshm.entry = rec.id
+        AND   ahf.heading_purpose = 'variant';
+
+        -- Gather aggregate data based on the MBE row we're looking at now, authority axis
+        IF (unauthorized_entry.record IS NOT NULL) THEN
+            --unauthorized term belongs to an auth linked to a bib?
+            SELECT INTO all_arecords, result_row.sees, afields
+                    ARRAY_AGG(DISTINCT abl.bib),
+                    STRING_AGG(DISTINCT abl.authority::TEXT, $$,$$),
+                    ARRAY_AGG(DISTINCT map.metabib_field)
+            FROM authority.bib_linking abl
+            INNER JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                    map.authority_field = unauthorized_entry.atag
+                    AND map.metabib_field = ANY(fields)
+            )
+            WHERE abl.authority = unauthorized_entry.record;
+        ELSE
+            --do usual procedure
+            SELECT INTO all_arecords, result_row.sees, afields
+                    ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
+                    STRING_AGG(DISTINCT aal.source::TEXT, $$,$$), -- authority record ids
+                    ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
+
+            FROM  metabib.browse_entry_simple_heading_map mbeshm
+                    JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+                    JOIN authority.authority_linking aal ON ( ash.record = aal.source )
+                    JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
+                    JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                        ash.atag = map.authority_field
+                        AND map.metabib_field = ANY(fields)
+                    )
+                    JOIN authority.control_set_authority_field acsaf ON (
+                        map.authority_field = acsaf.id
+                    )
+                    JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
+              WHERE mbeshm.entry = rec.id
+              AND   ahf.heading_purpose = 'variant';
+
+        END IF;
+
+        -- Gather aggregate data based on the MBE row we're looking at now, bib axis
+        SELECT INTO all_brecords, result_row.authorities, bfields
+                ARRAY_AGG(DISTINCT source),
+                STRING_AGG(DISTINCT authority::TEXT, $$,$$),
+                ARRAY_AGG(DISTINCT def)
+          FROM  metabib.browse_entry_def_map
+          WHERE entry = rec.id
+                AND def = ANY(fields);
+
+        SELECT INTO result_row.fields STRING_AGG(DISTINCT x::TEXT, $$,$$) FROM UNNEST(afields || bfields) x;
+
+        result_row.sources := 0;
+        result_row.asources := 0;
+
+        -- Bib-linked vis checking
+        IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
+
+            SELECT  INTO result_row.sources COUNT(DISTINCT b.id)
+              FROM  biblio.record_entry b
+                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+              WHERE b.id = ANY(all_brecords[1:browse_superpage_size])
+                    AND (
+                        acvac.vis_attr_vector @@ c_tests::query_int
+                        OR b.vis_attr_vector @@ b_tests::query_int
+                    );
+
+            result_row.accurate := TRUE;
+
+        END IF;
+
+        -- Authority-linked vis checking
+        IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
+
+            SELECT  INTO result_row.asources COUNT(DISTINCT b.id)
+              FROM  biblio.record_entry b
+                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+              WHERE b.id = ANY(all_arecords[1:browse_superpage_size])
+                    AND (
+                        acvac.vis_attr_vector @@ c_tests::query_int
+                        OR b.vis_attr_vector @@ b_tests::query_int
+                    );
+
+            result_row.aaccurate := TRUE;
+
+        END IF;
+
+        IF result_row.sources > 0 OR result_row.asources > 0 THEN
+
+            -- The function that calls this function needs row_number in order
+            -- to correctly order results from two different runs of this
+            -- functions.
+            result_row.row_number := row_number;
+
+            -- Now, if row_counter is still less than limit, return a row.  If
+            -- not, but it is less than next_pivot_pos, continue on without
+            -- returning actual result rows until we find
+            -- that next pivot, and return it.
+
+            IF row_counter < result_limit THEN
+                result_row.browse_entry := rec.id;
+                result_row.value := rec.value;
+
+                RETURN NEXT result_row;
+            ELSE
+                result_row.browse_entry := NULL;
+                result_row.authorities := NULL;
+                result_row.fields := NULL;
+                result_row.value := NULL;
+                result_row.sources := NULL;
+                result_row.sees := NULL;
+                result_row.accurate := NULL;
+                result_row.aaccurate := NULL;
+                result_row.pivot_point := rec.id;
+
+                IF row_counter >= next_pivot_pos THEN
+                    RETURN NEXT result_row;
+                    RETURN;
+                END IF;
+            END IF;
+
+            IF count_up_from_zero THEN
+                row_number := row_number + 1;
+            ELSE
+                row_number := row_number - 1;
+            END IF;
+
+            -- row_counter is different from row_number.
+            -- It simply counts up from zero so that we know when
+            -- we've reached our limit.
+            row_counter := row_counter + 1;
+        END IF;
+    END LOOP;
+END;
+$f$ LANGUAGE plpgsql ROWS 10;
+
+CREATE OR REPLACE FUNCTION metabib.browse(search_field integer[], browse_term text, context_org integer DEFAULT NULL::integer, context_loc_group integer DEFAULT NULL::integer, staff boolean DEFAULT false, pivot_id bigint DEFAULT NULL::bigint, result_limit integer DEFAULT 10)
+ RETURNS SETOF metabib.flat_browse_entry_appearance
+AS $f$
+DECLARE
+    core_query              TEXT;
+    back_query              TEXT;
+    forward_query           TEXT;
+    pivot_sort_value        TEXT;
+    pivot_sort_fallback     TEXT;
+    context_locations       INT[];
+    browse_superpage_size   INT;
+    results_skipped         INT := 0;
+    back_limit              INT;
+    back_to_pivot           INT;
+    forward_limit           INT;
+    forward_to_pivot        INT;
+BEGIN
+    -- First, find the pivot if we were given a browse term but not a pivot.
+    IF pivot_id IS NULL THEN
+        pivot_id := metabib.browse_pivot(search_field, browse_term);
+    END IF;
+
+    SELECT INTO pivot_sort_value, pivot_sort_fallback
+        sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
+
+    -- Bail if we couldn't find a pivot.
+    IF pivot_sort_value IS NULL THEN
+        RETURN;
+    END IF;
+
+    -- Transform the context_loc_group argument (if any) (logc at the
+    -- TPAC layer) into a form we'll be able to use.
+    IF context_loc_group IS NOT NULL THEN
+        SELECT INTO context_locations ARRAY_AGG(location)
+            FROM asset.copy_location_group_map
+            WHERE lgroup = context_loc_group;
+    END IF;
+
+    -- Get the configured size of browse superpages.
+    SELECT INTO browse_superpage_size COALESCE(value::INT,100)     -- NULL ok
+        FROM config.global_flag
+        WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
+
+    -- First we're going to search backward from the pivot, then we're going
+    -- to search forward.  In each direction, we need two limits.  At the
+    -- lesser of the two limits, we delineate the edge of the result set
+    -- we're going to return.  At the greater of the two limits, we find the
+    -- pivot value that would represent an offset from the current pivot
+    -- at a distance of one "page" in either direction, where a "page" is a
+    -- result set of the size specified in the "result_limit" argument.
+    --
+    -- The two limits in each direction make four derived values in total,
+    -- and we calculate them now.
+    back_limit := CEIL(result_limit::FLOAT / 2);
+    back_to_pivot := result_limit;
+    forward_limit := result_limit / 2;
+    forward_to_pivot := result_limit - 1;
+
+    -- This is the meat of the SQL query that finds browse entries.  We'll
+    -- pass this to a function which uses it with a cursor, so that individual
+    -- rows may be fetched in a loop until some condition is satisfied, without
+    -- waiting for a result set of fixed size to be collected all at once.
+    core_query := '
+SELECT  mbe.id,
+        mbe.value,
+        mbe.sort_value
+  FROM  metabib.browse_entry mbe
+  WHERE (
+            EXISTS ( -- are there any bibs using this mbe via the requested fields?
+                SELECT  1
+                  FROM  metabib.browse_entry_def_map mbedm
+                  WHERE mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ')
+            ) OR EXISTS ( -- are there any authorities using this mbe via the requested fields?
+                SELECT  1
+                  FROM  metabib.browse_entry_simple_heading_map mbeshm
+                        JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+                        JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                            ash.atag = map.authority_field
+                            AND map.metabib_field = ANY(' || quote_literal(search_field) || ')
+                        )
+                        JOIN authority.control_set_authority_field acsaf ON (
+                            map.authority_field = acsaf.id
+                        )
+                        JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
+                  WHERE mbeshm.entry = mbe.id
+                    AND ahf.heading_purpose IN (' || $$'variant'$$ || ')
+                    -- and authority that variant is coming from is linked to a bib
+                    AND EXISTS (
+                        SELECT  1
+                        FROM  metabib.browse_entry_def_map mbedm2
+                        WHERE mbedm2.authority = ash.record AND mbedm2.def = ANY(' || quote_literal(search_field) || ')
+                    )
+            )
+        ) AND ';
+
+    -- This is the variant of the query for browsing backward.
+    back_query := core_query ||
+        ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
+    ' ORDER BY mbe.sort_value DESC, mbe.value DESC LIMIT 1000';
+
+    -- This variant browses forward.
+    forward_query := core_query ||
+        ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
+    ' ORDER BY mbe.sort_value, mbe.value LIMIT 1000';
+
+    -- We now call the function which applies a cursor to the provided
+    -- queries, stopping at the appropriate limits and also giving us
+    -- the next page's pivot.
+    RETURN QUERY
+        SELECT * FROM metabib.staged_browse(
+            back_query, search_field, context_org, context_locations,
+            staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
+        ) UNION
+        SELECT * FROM metabib.staged_browse(
+            forward_query, search_field, context_org, context_locations,
+            staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
+        ) ORDER BY row_number DESC;
+
+END;
+$f$ LANGUAGE plpgsql ROWS 10;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1072', :eg_version); --gmcharlt/kmlussier
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
+
+INSERT INTO config.global_flag (name, label, enabled) VALUES (
+    'opac.show_related_headings_in_browse',
+    oils_i18n_gettext(
+        'opac.show_related_headings_in_browse',
+        'Display related headings (see-also) in browse',
+        'cgf',
+        'label'
+    ),
+    TRUE
+);
+
+END IF; END $INSERT$;                                                          
+
+-- SELECT evergreen.upgrade_deps_block_check('1073', :eg_version);
+
+ALTER TABLE config.metabib_field 
+    ADD COLUMN display_xpath TEXT, 
+    ADD COLUMN display_field BOOL NOT NULL DEFAULT FALSE;
+
+CREATE TABLE config.display_field_map (
+    name    TEXT   PRIMARY KEY,
+    field   INTEGER REFERENCES config.metabib_field (id),
+    multi   BOOLEAN DEFAULT FALSE
+);
+
+CREATE TABLE metabib.display_entry (
+    id      BIGSERIAL  PRIMARY KEY,
+    source  BIGINT     NOT NULL REFERENCES biblio.record_entry (id),
+    field   INT        NOT NULL REFERENCES config.metabib_field (id),
+    value   TEXT       NOT NULL
+);
+
+CREATE INDEX metabib_display_entry_field_idx ON metabib.display_entry (field);
+CREATE INDEX metabib_display_entry_source_idx ON metabib.display_entry (source);
+
+-- one row per display entry fleshed with field info
+CREATE VIEW metabib.flat_display_entry AS
+    SELECT
+        mde.source,
+        cdfm.name,
+        cdfm.multi,
+        cmf.label,
+        cmf.id AS field,
+        mde.value
+    FROM metabib.display_entry mde
+    JOIN config.metabib_field cmf ON (cmf.id = mde.field)
+    JOIN config.display_field_map cdfm ON (cdfm.field = mde.field)
+;
+
+-- like flat_display_entry except values are compressed 
+-- into one row per display_field_map and JSON-ified.
+CREATE VIEW metabib.compressed_display_entry AS
+    SELECT 
+        source,
+        name,
+        multi,
+        label,
+        field,
+        CASE WHEN multi THEN
+            TO_JSON(ARRAY_AGG(value))
+        ELSE
+            TO_JSON(MIN(value))
+        END AS value
+    FROM metabib.flat_display_entry
+    GROUP BY 1, 2, 3, 4, 5
+;
+
+-- TODO: expand to encompass all well-known fields
+CREATE VIEW metabib.wide_display_entry AS
+    SELECT 
+        bre.id AS source,
+        COALESCE(mcde_title.value, 'null') AS title,
+        COALESCE(mcde_author.value, 'null') AS author,
+        COALESCE(mcde_subject.value, 'null') AS subject,
+        COALESCE(mcde_creators.value, 'null') AS creators,
+        COALESCE(mcde_isbn.value, 'null') AS isbn
+    -- ensure one row per bre regardless of any display fields
+    FROM biblio.record_entry bre 
+    LEFT JOIN metabib.compressed_display_entry mcde_title 
+        ON (bre.id = mcde_title.source AND mcde_title.name = 'title')
+    LEFT JOIN metabib.compressed_display_entry mcde_author 
+        ON (bre.id = mcde_author.source AND mcde_author.name = 'author')
+    LEFT JOIN metabib.compressed_display_entry mcde_subject 
+        ON (bre.id = mcde_subject.source AND mcde_subject.name = 'subject')
+    LEFT JOIN metabib.compressed_display_entry mcde_creators 
+        ON (bre.id = mcde_creators.source AND mcde_creators.name = 'creators')
+    LEFT JOIN metabib.compressed_display_entry mcde_isbn 
+        ON (bre.id = mcde_isbn.source AND mcde_isbn.name = 'isbn')
+;
+
+
+CREATE OR REPLACE FUNCTION metabib.display_field_normalize_trigger () 
+    RETURNS TRIGGER AS $$
+DECLARE
+    normalizer  RECORD;
+    display_field_text  TEXT;
+BEGIN
+    display_field_text := NEW.value;
+
+    FOR normalizer IN
+        SELECT  n.func AS func,
+                n.param_count AS param_count,
+                m.params AS params
+          FROM  config.index_normalizer n
+                JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
+          WHERE m.field = NEW.field AND m.pos < 0
+          ORDER BY m.pos LOOP
+
+            EXECUTE 'SELECT ' || normalizer.func || '(' ||
+                quote_literal( display_field_text ) ||
+                CASE
+                    WHEN normalizer.param_count > 0
+                        THEN ',' || REPLACE(REPLACE(BTRIM(
+                            normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
+                        ELSE ''
+                    END ||
+                ')' INTO display_field_text;
+
+    END LOOP;
+
+    NEW.value = display_field_text;
+
+    RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TRIGGER display_field_normalize_tgr
+       BEFORE UPDATE OR INSERT ON metabib.display_entry
+       FOR EACH ROW EXECUTE PROCEDURE metabib.display_field_normalize_trigger();
+
+CREATE OR REPLACE FUNCTION evergreen.display_field_force_nfc() 
+    RETURNS TRIGGER AS $$
+BEGIN
+    NEW.value := force_unicode_normal_form(NEW.value,'NFC');
+    RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TRIGGER display_field_force_nfc_tgr
+       BEFORE UPDATE OR INSERT ON metabib.display_entry
+       FOR EACH ROW EXECUTE PROCEDURE evergreen.display_field_force_nfc();
+
+ALTER TYPE metabib.field_entry_template ADD ATTRIBUTE display_field BOOL;
+
+DROP FUNCTION metabib.reingest_metabib_field_entries(BIGINT, BOOL, BOOL, BOOL);
+DROP FUNCTION biblio.extract_metabib_field_entry(BIGINT);
+DROP FUNCTION biblio.extract_metabib_field_entry(BIGINT, TEXT);
+
+CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry (
+    rid BIGINT,
+    default_joiner TEXT,
+    field_types TEXT[],
+    only_fields INT[]
+) RETURNS SETOF metabib.field_entry_template AS $func$
+DECLARE
+    bib     biblio.record_entry%ROWTYPE;
+    idx     config.metabib_field%ROWTYPE;
+    xfrm        config.xml_transform%ROWTYPE;
+    prev_xfrm   TEXT;
+    transformed_xml TEXT;
+    xml_node    TEXT;
+    xml_node_list   TEXT[];
+    facet_text  TEXT;
+    display_text TEXT;
+    browse_text TEXT;
+    sort_value  TEXT;
+    raw_text    TEXT;
+    curr_text   TEXT;
+    joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
+    authority_text TEXT;
+    authority_link BIGINT;
+    output_row  metabib.field_entry_template%ROWTYPE;
+    process_idx BOOL;
+BEGIN
+
+    -- Start out with no field-use bools set
+    output_row.browse_field = FALSE;
+    output_row.facet_field = FALSE;
+    output_row.display_field = FALSE;
+    output_row.search_field = FALSE;
+
+    -- Get the record
+    SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
+
+    -- Loop over the indexing entries
+    FOR idx IN SELECT * FROM config.metabib_field WHERE id = ANY (only_fields) ORDER BY format LOOP
+
+        process_idx := FALSE;
+        IF idx.display_field AND 'display' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        IF idx.browse_field AND 'browse' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        IF idx.search_field AND 'search' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        IF idx.facet_field AND 'facet' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        CONTINUE WHEN process_idx = FALSE;
+
+        joiner := COALESCE(idx.joiner, default_joiner);
+
+        SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
+
+        -- See if we can skip the XSLT ... it's expensive
+        IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+            -- Can't skip the transform
+            IF xfrm.xslt <> '---' THEN
+                transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
+            ELSE
+                transformed_xml := bib.marc;
+            END IF;
+
+            prev_xfrm := xfrm.name;
+        END IF;
+
+        xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+
+        raw_text := NULL;
+        FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
+            CONTINUE WHEN xml_node !~ E'^\\s*<';
+
+            -- XXX much of this should be moved into oils_xpath_string...
+            curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
+                oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
+                    REGEXP_REPLACE( xml_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
+                ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
+                joiner
+            );
+
+            CONTINUE WHEN curr_text IS NULL OR curr_text = '';
+
+            IF raw_text IS NOT NULL THEN
+                raw_text := raw_text || joiner;
+            END IF;
+
+            raw_text := COALESCE(raw_text,'') || curr_text;
+
+            -- autosuggest/metabib.browse_entry
+            IF idx.browse_field THEN
+
+                IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
+                    browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+                ELSE
+                    browse_text := curr_text;
+                END IF;
+
+                IF idx.browse_sort_xpath IS NOT NULL AND
+                    idx.browse_sort_xpath <> '' THEN
+
+                    sort_value := oils_xpath_string(
+                        idx.browse_sort_xpath, xml_node, joiner,
+                        ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
+                    );
+                ELSE
+                    sort_value := browse_text;
+                END IF;
+
+                output_row.field_class = idx.field_class;
+                output_row.field = idx.id;
+                output_row.source = rid;
+                output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
+
+                -- output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
+                -- outer regexp_replace keeps all '.' expect the last one.
+                -- inner regexp_replace removes all connecting whitespace and replaces it with a single space
+                output_row.value = BTRIM(REGEXP_REPLACE(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'), E'\\.$', '', 'g'));
+                -- /KCLS 
+
+                output_row.sort_value :=
+                    public.naco_normalize(sort_value);
+
+                output_row.authority := NULL;
+
+                IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
+                    authority_text := oils_xpath_string(
+                        idx.authority_xpath, xml_node, joiner,
+                        ARRAY[
+                            ARRAY[xfrm.prefix, xfrm.namespace_uri],
+                            ARRAY['xlink','http://www.w3.org/1999/xlink']
+                        ]
+                    );
+
+                    IF authority_text ~ '^\d+$' THEN
+                        authority_link := authority_text::BIGINT;
+                        PERFORM * FROM authority.record_entry WHERE id = authority_link;
+                        IF FOUND THEN
+                            output_row.authority := authority_link;
+                        END IF;
+                    END IF;
+
+                END IF;
+
+                output_row.browse_field = TRUE;
+                -- Returning browse rows with search_field = true for search+browse
+                -- configs allows us to retain granularity of being able to search
+                -- browse fields with "starts with" type operators (for example, for
+                -- titles of songs in music albums)
+                IF idx.search_field THEN
+                    output_row.search_field = TRUE;
+                END IF;
+                RETURN NEXT output_row;
+                output_row.browse_field = FALSE;
+                output_row.search_field = FALSE;
+                output_row.sort_value := NULL;
+            END IF;
+
+            -- insert raw node text for faceting
+            IF idx.facet_field THEN
+
+                IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
+                    facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+                ELSE
+                    facet_text := curr_text;
+                END IF;
+
+                output_row.field_class = idx.field_class;
+                output_row.field = -1 * idx.id;
+                output_row.source = rid;
+                output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
+
+                output_row.facet_field = TRUE;
+                RETURN NEXT output_row;
+                output_row.facet_field = FALSE;
+            END IF;
+
+            -- insert raw node text for display
+            IF idx.display_field THEN
+
+                IF idx.display_xpath IS NOT NULL AND idx.display_xpath <> '' THEN
+                    display_text := oils_xpath_string( idx.display_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+                ELSE
+                    display_text := curr_text;
+                END IF;
+
+                output_row.field_class = idx.field_class;
+                output_row.field = -1 * idx.id;
+                output_row.source = rid;
+                output_row.value = BTRIM(REGEXP_REPLACE(display_text, E'\\s+', ' ', 'g'));
+
+                output_row.display_field = TRUE;
+                RETURN NEXT output_row;
+                output_row.display_field = FALSE;
+            END IF;
+
+        END LOOP;
+
+        CONTINUE WHEN raw_text IS NULL OR raw_text = '';
+
+        -- insert combined node text for searching
+        IF idx.search_field THEN
+            output_row.field_class = idx.field_class;
+            -- KCLS
+            -- TODO: move these mods into configs / search normalizers
+            IF idx.field_class = 'identifier' AND idx.name = 'bibcn' THEN
+                output_row.field_class = 'call_number';
+                output_row.browse_field = TRUE;
+                output_row.sort_value = public.naco_normalize_keep_decimal(raw_text,'');
+                output_row.value = raw_text;
+            ELSE
+                output_row.field_class = idx.field_class;
+                output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
+            END IF;
+            -- /KCLS
+            output_row.field = idx.id;
+            output_row.source = rid;
+            -- KCLS -- value is set above
+            -- output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
+            -- /KCLS
+
+            output_row.search_field = TRUE;
+            RETURN NEXT output_row;
+            output_row.search_field = FALSE;
+        END IF;
+
+    END LOOP;
+
+END;
+
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries( 
+    bib_id BIGINT,
+    skip_facet BOOL DEFAULT FALSE, 
+    skip_display BOOL DEFAULT FALSE,
+    skip_browse BOOL DEFAULT FALSE, 
+    skip_search BOOL DEFAULT FALSE,
+    only_fields INT[] DEFAULT '{}'::INT[]
+) RETURNS VOID AS $func$
+DECLARE
+    fclass          RECORD;
+    ind_data        metabib.field_entry_template%ROWTYPE;
+    mbe_row         metabib.browse_entry%ROWTYPE;
+    mbe_id          BIGINT;
+    b_skip_facet    BOOL;
+    b_skip_display    BOOL;
+    b_skip_browse   BOOL;
+    b_skip_search   BOOL;
+    value_prepped   TEXT;
+    field_list      INT[] := only_fields;
+    field_types     TEXT[] := '{}'::TEXT[];
+BEGIN
+
+    IF field_list = '{}'::INT[] THEN
+        SELECT ARRAY_AGG(id) INTO field_list FROM config.metabib_field;
+    END IF;
+
+    SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
+    SELECT COALESCE(NULLIF(skip_display, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_display_indexing' AND enabled)) INTO b_skip_display;
+    SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
+    SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
+
+    IF NOT b_skip_facet THEN field_types := field_types || '{facet}'; END IF;
+    IF NOT b_skip_display THEN field_types := field_types || '{display}'; END IF;
+    IF NOT b_skip_browse THEN field_types := field_types || '{browse}'; END IF;
+    IF NOT b_skip_search THEN field_types := field_types || '{search}'; END IF;
+
+    PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
+    IF NOT FOUND THEN
+        IF NOT b_skip_search THEN
+            FOR fclass IN SELECT * FROM config.metabib_class LOOP
+                -- RAISE NOTICE 'Emptying out %', fclass.name;
+                EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
+            END LOOP;
+        END IF;
+        IF NOT b_skip_facet THEN
+            DELETE FROM metabib.facet_entry WHERE source = bib_id;
+        END IF;
+        IF NOT b_skip_display THEN
+            DELETE FROM metabib.display_entry WHERE source = bib_id;
+        END IF;
+        IF NOT b_skip_browse THEN
+            DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
+        END IF;
+    END IF;
+
+    FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id, ' ', field_types, field_list ) LOOP
+
+       -- don't store what has been normalized away
+        CONTINUE WHEN ind_data.value IS NULL;
+
+        IF ind_data.field < 0 THEN
+            ind_data.field = -1 * ind_data.field;
+        END IF;
+
+        IF ind_data.facet_field AND NOT b_skip_facet THEN
+            INSERT INTO metabib.facet_entry (field, source, value)
+                VALUES (ind_data.field, ind_data.source, ind_data.value);
+        END IF;
+
+        IF ind_data.display_field AND NOT b_skip_display THEN
+            INSERT INTO metabib.display_entry (field, source, value)
+                VALUES (ind_data.field, ind_data.source, ind_data.value);
+        END IF;
+
+
+        IF ind_data.browse_field AND NOT b_skip_browse THEN
+            -- A caveat about this SELECT: this should take care of replacing
+            -- old mbe rows when data changes, but not if normalization (by
+            -- which I mean specifically the output of
+            -- evergreen.oils_tsearch2()) changes.  It may or may not be
+            -- expensive to add a comparison of index_vector to index_vector
+            -- to the WHERE clause below.
+
+            CONTINUE WHEN ind_data.sort_value IS NULL;
+
+            value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
+            SELECT INTO mbe_row * FROM metabib.browse_entry
+                WHERE value = value_prepped AND sort_value = ind_data.sort_value;
+
+            IF FOUND THEN
+                mbe_id := mbe_row.id;
+            ELSE
+                INSERT INTO metabib.browse_entry
+                    ( value, sort_value ) VALUES
+                    ( value_prepped, ind_data.sort_value );
+
+                mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
+            END IF;
+
+            INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
+                VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
+        END IF;
+
+        IF ind_data.search_field AND NOT b_skip_search THEN
+            -- Avoid inserting duplicate rows
+            EXECUTE 'SELECT 1 FROM metabib.' || ind_data.field_class ||
+                '_field_entry WHERE field = $1 AND source = $2 AND value = $3'
+                INTO mbe_id USING ind_data.field, ind_data.source, ind_data.value;
+                -- RAISE NOTICE 'Search for an already matching row returned %', mbe_id;
+            IF mbe_id IS NULL THEN
+                EXECUTE $$
+                INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
+                    VALUES ($$ ||
+                        quote_literal(ind_data.field) || $$, $$ ||
+                        quote_literal(ind_data.source) || $$, $$ ||
+                        quote_literal(ind_data.value) ||
+                    $$);$$;
+            END IF;
+        END IF;
+
+    END LOOP;
+
+    IF NOT b_skip_search THEN
+        PERFORM metabib.update_combined_index_vectors(bib_id);
+    END IF;
+
+    RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+-- AFTER UPDATE OR INSERT trigger for biblio.record_entry
+CREATE OR REPLACE FUNCTION biblio.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
+DECLARE
+    tmp_bool BOOL;
+BEGIN
+
+    IF NEW.deleted THEN -- If this bib is deleted
+
+        PERFORM * FROM config.internal_flag WHERE
+            name = 'ingest.metarecord_mapping.preserve_on_delete' AND enabled;
+
+        tmp_bool := FOUND; -- Just in case this is changed by some other statement
+
+        PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint, TRUE, tmp_bool );
+
+        IF NOT tmp_bool THEN
+            -- One needs to keep these around to support searches
+            -- with the #deleted modifier, so one should turn on the named
+            -- internal flag for that functionality.
+            DELETE FROM metabib.record_attr_vector_list WHERE source = NEW.id;
+        END IF;
+
+        DELETE FROM authority.bib_linking WHERE bib = NEW.id; -- Avoid updating fields in bibs that are no longer visible
+        DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = NEW.id; -- Separate any multi-homed items
+        -- DELETE FROM metabib.browse_entry_def_map WHERE source = NEW.id; -- Don't auto-suggest deleted bibs
+        -- KCLS
+        -- DELETE FROM metabib.browse_entry_def_map WHERE source = NEW.id; -- Don't auto-suggest deleted bibs
+        DELETE FROM metabib.browse_author_entry_def_map WHERE source = NEW.id;
+        DELETE FROM metabib.browse_series_entry_def_map WHERE source = NEW.id;
+        DELETE FROM metabib.browse_subject_entry_def_map WHERE source = NEW.id;
+        DELETE FROM metabib.browse_title_entry_def_map WHERE source = NEW.id;
+        DELETE FROM metabib.browse_call_number_entry_def_map WHERE source = NEW.id;
+        -- /KCLS
+        RETURN NEW; -- and we're done
+    END IF;
+
+    IF TG_OP = 'UPDATE' THEN -- re-ingest?
+        PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
+
+        IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
+            RETURN NEW;
+        END IF;
+    END IF;
+
+    -- Record authority linking
+    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_linking' AND enabled;
+    IF NOT FOUND THEN
+        PERFORM biblio.map_authority_linking( NEW.id, NEW.marc );
+    END IF;
+
+    -- Flatten and insert the mfr data
+    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_full_rec' AND enabled;
+    IF NOT FOUND THEN
+        PERFORM metabib.reingest_metabib_full_rec(NEW.id);
+
+        -- Now we pull out attribute data, which is dependent on the mfr for all but XPath-based fields
+        PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_rec_descriptor' AND enabled;
+        IF NOT FOUND THEN
+            PERFORM metabib.reingest_record_attributes(NEW.id, NULL, NEW.marc, TG_OP = 'INSERT' OR OLD.deleted);
+        END IF;
+    END IF;
+
+    -- Gather and insert the field entry data
+    PERFORM metabib.reingest_metabib_field_entries(NEW.id);
+
+    -- Located URI magic
+    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_located_uri' AND enabled;
+    IF NOT FOUND THEN PERFORM biblio.extract_located_uris( NEW.id, NEW.marc, NEW.editor ); END IF;
+
+    -- (re)map metarecord-bib linking
+    IF TG_OP = 'INSERT' THEN -- if not deleted and performing an insert, check for the flag
+        PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_insert' AND enabled;
+        IF NOT FOUND THEN
+            PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
+        END IF;
+    ELSE -- we're doing an update, and we're not deleted, remap
+        PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_update' AND enabled;
+        IF NOT FOUND THEN
+            PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
+        END IF;
+    END IF;
+
+    RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1074', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
+
+INSERT INTO config.internal_flag (name, enabled) 
+    VALUES ('ingest.skip_display_indexing', FALSE);
+
+-- Adds seed data to replace (for now) values from the 'mvr' class
+
+UPDATE config.metabib_field SET display_field = TRUE WHERE id IN (6, 8, 16, 18);
+
+INSERT INTO config.metabib_field ( id, field_class, name, label,
+    format, xpath, display_field, display_xpath ) VALUES
+    (37, 'author', 'creator', oils_i18n_gettext(37, 'All Creators', 'cmf', 'label'),
+     'mods32', $$//mods32:mods/mods32:name[mods32:role/mods32:roleTerm[text()='creator']]$$, 
+     TRUE, $$//*[local-name()='namePart']$$ ); -- /* to fool vim */;
+
+-- 'author' field
+UPDATE config.metabib_field SET display_xpath = 
+    $$//*[local-name()='namePart']$$ -- /* to fool vim */
+    WHERE id = 8;
+
+INSERT INTO config.display_field_map (name, field, multi) VALUES
+    ('title', 6, FALSE),
+    ('author', 8, FALSE),
+    ('creators', 37, TRUE),
+    ('subject', 16, TRUE),
+    ('isbn', 18, TRUE)
+;
+END IF; END $INSERT$;                                                          
+
+
+-- SELECT evergreen.upgrade_deps_block_check('1075', :eg_version);
+
+CREATE OR REPLACE FUNCTION evergreen.vandelay_import_item_imported_as_inh_fkey() RETURNS TRIGGER AS $f$
+BEGIN   
+        IF NEW.imported_as IS NULL THEN
+                RETURN NEW;
+        END IF;
+        PERFORM 1 FROM asset.copy WHERE id = NEW.imported_as;
+        IF NOT FOUND THEN
+                RAISE foreign_key_violation USING MESSAGE = FORMAT(
+                        $$Referenced asset.copy id not found, imported_as:%s$$, NEW.imported_as
+                );
+        END IF;
+        RETURN NEW;
+END;
+$f$ LANGUAGE PLPGSQL VOLATILE COST 50;
+
+-- SELECT evergreen.upgrade_deps_block_check('1077', :eg_version); -- csharp/gmcharlt
+
+-- if the "public" version of this function exists, drop it to prevent confusion/trouble
+
+-- drop triggers that depend on this first
+DROP TRIGGER IF EXISTS c_maintain_control_numbers ON biblio.record_entry;
+DROP TRIGGER IF EXISTS c_maintain_control_numbers ON serial.record_entry;
+DROP TRIGGER IF EXISTS c_maintain_control_numbers ON authority.record_entry;
+
+DROP FUNCTION IF EXISTS public.maintain_control_numbers();
+
+-- create the function within the "evergreen" schema
+
+CREATE OR REPLACE FUNCTION evergreen.maintain_control_numbers() RETURNS TRIGGER AS $func$
+use strict;
+use MARC::Record;
+use MARC::File::XML (BinaryEncoding => 'UTF-8');
+use MARC::Charset;
+use Encode;
+use Unicode::Normalize;
+
+MARC::Charset->assume_unicode(1);
+
+my $record = MARC::Record->new_from_xml($_TD->{new}{marc});
+my $schema = $_TD->{table_schema};
+my $rec_id = $_TD->{new}{id};
+
+# Short-circuit if maintaining control numbers per MARC21 spec is not enabled
+my $enable = spi_exec_query("SELECT enabled FROM config.global_flag WHERE name = 'cat.maintain_control_numbers'");
+if (!($enable->{processed}) or $enable->{rows}[0]->{enabled} eq 'f') {
+    return;
+}
+
+# Get the control number identifier from an OU setting based on $_TD->{new}{owner}
+my $ou_cni = 'EVRGRN';
+
+my $owner;
+if ($schema eq 'serial') {
+    $owner = $_TD->{new}{owning_lib};
+} else {
+    # are.owner and bre.owner can be null, so fall back to the consortial setting
+    $owner = $_TD->{new}{owner} || 1;
+}
+
+my $ous_rv = spi_exec_query("SELECT value FROM actor.org_unit_ancestor_setting('cat.marc_control_number_identifier', $owner)");
+if ($ous_rv->{processed}) {
+    $ou_cni = $ous_rv->{rows}[0]->{value};
+    $ou_cni =~ s/"//g; # Stupid VIM syntax highlighting"
+} else {
+    # Fall back to the shortname of the OU if there was no OU setting
+    $ous_rv = spi_exec_query("SELECT shortname FROM actor.org_unit WHERE id = $owner");
+    if ($ous_rv->{processed}) {
+        $ou_cni = $ous_rv->{rows}[0]->{shortname};
+    }
+}
+
+my ($create, $munge) = (0, 0);
+
+my @scns = $record->field('035');
+
+foreach my $id_field ('001', '003') {
+    my $spec_value;
+    my @controls = $record->field($id_field);
+
+    if ($id_field eq '001') {
+        $spec_value = $rec_id;
+    } else {
+        $spec_value = $ou_cni;
+    }
+
+    # Create the 001/003 if none exist
+    if (scalar(@controls) == 1) {
+        # Only one field; check to see if we need to munge it
+        unless (grep $_->data() eq $spec_value, @controls) {
+            $munge = 1;
+        }
+    } else {
+        # Delete the other fields, as with more than 1 001/003 we do not know which 003/001 to match
+        foreach my $control (@controls) {
+            $record->delete_field($control);
+        }
+        $record->insert_fields_ordered(MARC::Field->new($id_field, $spec_value));
+        $create = 1;
+    }
+}
+
+my $cn = $record->field('001')->data();
+# Special handling of OCLC numbers, often found in records that lack 003
+if ($cn =~ /^o(c[nm]|n)\d/) {
+    $cn =~ s/^o(c[nm]|n)0*(\d+)/$2/;
+    $record->field('003')->data('OCoLC');
+    $create = 0;
+}
+
+# Now, if we need to munge the 001, we will first push the existing 001/003
+# into the 035; but if the record did not have one (and one only) 001 and 003
+# to begin with, skip this process
+if ($munge and not $create) {
+
+    my $scn = "(" . $record->field('003')->data() . ")" . $cn;
+
+    # Do not create duplicate 035 fields
+    unless (grep $_->subfield('a') eq $scn, @scns) {
+        $record->insert_fields_ordered(MARC::Field->new('035', '', '', 'a' => $scn));
+    }
+}
+
+# Set the 001/003 and update the MARC
+if ($create or $munge) {
+    $record->field('001')->data($rec_id);
+    $record->field('003')->data($ou_cni);
+
+    my $xml = $record->as_xml_record();
+    $xml =~ s/\n//sgo;
+    $xml =~ s/^<\?xml.+\?\s*>//go;
+    $xml =~ s/>\s+</></go;
+    $xml =~ s/\p{Cc}//go;
+
+    # Embed a version of OpenILS::Application::AppUtils->entityize()
+    # to avoid having to set PERL5LIB for PostgreSQL as well
+
+    $xml = NFC($xml);
+
+    # Convert raw ampersands to entities
+    $xml =~ s/&(?!\S+;)/&amp;/gso;
+
+    # Convert Unicode characters to entities
+    $xml =~ s/([\x{0080}-\x{fffd}])/sprintf('&#x%X;',ord($1))/sgoe;
+
+    $xml =~ s/[\x00-\x1f]//go;
+    $_TD->{new}{marc} = $xml;
+
+    return "MODIFY";
+}
+
+return;
+$func$ LANGUAGE PLPERLU;
+
+-- re-create the triggers
+CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON serial.record_entry FOR EACH ROW EXECUTE PROCEDURE evergreen.maintain_control_numbers();
+CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON authority.record_entry FOR EACH ROW EXECUTE PROCEDURE evergreen.maintain_control_numbers();
+CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE evergreen.maintain_control_numbers();
+
+-- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.1', :eg_version);
+-- PERFORM evergreen.upgrade_deps_block_check('1078', :eg_version); -- csharp/bshum/gmcharlt
+
+/* KCLS ALREADY HAS 
+DO $INSERT$
+BEGIN
+    IF evergreen.insert_on_deploy() THEN
+INSERT INTO config.billing_type (id, name, owner)
+    SELECT 7, 'Damaged Item', 1
+    WHERE NOT EXISTS (SELECT 1 FROM config.billing_type WHERE name = 'Damaged Item');
+
+INSERT INTO config.billing_type (id, name, owner)
+    SELECT 8, 'Damaged Item Processing Fee', 1
+    WHERE NOT EXISTS (SELECT 1 FROM config.billing_type WHERE name = 'Damaged Item Processing Fee');
+
+INSERT INTO config.billing_type (id, name, owner)
+    SELECT 9, 'Notification Fee', 1
+    WHERE NOT EXISTS (SELECT 1 FROM config.billing_type WHERE name = 'Notification Fee');
+    END IF;
+END $INSERT$;
+*/
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.2', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1079', :eg_version); -- rhamby/cesardv/gmcharlt
+-- KCLS ALREADY HAS - FUNC UPDATE WON'T HURT, MIGHT HELP
+
+CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
+DECLARE
+    moved_objects INT := 0;
+    source_cn     asset.call_number%ROWTYPE;
+    target_cn     asset.call_number%ROWTYPE;
+    metarec       metabib.metarecord%ROWTYPE;
+    hold          action.hold_request%ROWTYPE;
+    ser_rec       serial.record_entry%ROWTYPE;
+    ser_sub       serial.subscription%ROWTYPE;
+    acq_lineitem  acq.lineitem%ROWTYPE;
+    acq_request   acq.user_request%ROWTYPE;
+    booking       booking.resource_type%ROWTYPE;
+    source_part   biblio.monograph_part%ROWTYPE;
+    target_part   biblio.monograph_part%ROWTYPE;
+    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
+    uri_count     INT := 0;
+    counter       INT := 0;
+    uri_datafield TEXT;
+    uri_text      TEXT := '';
+BEGIN
+
+    -- move any 856 entries on records that have at least one MARC-mapped URI entry
+    SELECT  INTO uri_count COUNT(*)
+      FROM  asset.uri_call_number_map m
+            JOIN asset.call_number cn ON (m.call_number = cn.id)
+      WHERE cn.record = source_record;
+
+    IF uri_count > 0 THEN
+        
+        -- This returns more nodes than you might expect:
+        -- 7 instead of 1 for an 856 with $u $y $9
+        SELECT  COUNT(*) INTO counter
+          FROM  oils_xpath_table(
+                    'id',
+                    'marc',
+                    'biblio.record_entry',
+                    '//*[@tag="856"]',
+                    'id=' || source_record
+                ) as t(i int,c text);
+    
+        FOR i IN 1 .. counter LOOP
+            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
+                       ' tag="856"' ||
+                       ' ind1="' || FIRST(ind1) || '"'  ||
+                       ' ind2="' || FIRST(ind2) || '">' ||
+                        STRING_AGG(
+                            '<subfield code="' || subfield || '">' ||
+                            regexp_replace(
+                                regexp_replace(
+                                    regexp_replace(data,'&','&amp;','g'),
+                                    '>', '&gt;', 'g'
+                                ),
+                                '<', '&lt;', 'g'
+                            ) || '</subfield>', ''
+                        ) || '</datafield>' INTO uri_datafield
+              FROM  oils_xpath_table(
+                        'id',
+                        'marc',
+                        'biblio.record_entry',
+                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
+                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
+                        'id=' || source_record
+                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
+
+            -- As most of the results will be NULL, protect against NULLifying
+            -- the valid content that we do generate
+            uri_text := uri_text || COALESCE(uri_datafield, '');
+        END LOOP;
+
+        IF uri_text <> '' THEN
+            UPDATE  biblio.record_entry
+              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
+              WHERE id = target_record;
+        END IF;
+
+    END IF;
+
+       -- Find and move metarecords to the target record
+       SELECT  INTO metarec *
+         FROM  metabib.metarecord
+         WHERE master_record = source_record;
+
+       IF FOUND THEN
+               UPDATE  metabib.metarecord
+                 SET   master_record = target_record,
+                       mods = NULL
+                 WHERE id = metarec.id;
+
+               moved_objects := moved_objects + 1;
+       END IF;
+
+       -- Find call numbers attached to the source ...
+       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
+
+               SELECT  INTO target_cn *
+                 FROM  asset.call_number
+                 WHERE label = source_cn.label
+            AND prefix = source_cn.prefix
+            AND suffix = source_cn.suffix
+                       AND owning_lib = source_cn.owning_lib
+                       AND record = target_record
+                       AND NOT deleted;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copies to that, and ...
+                       UPDATE  asset.copy
+                         SET   call_number = target_cn.id
+                         WHERE call_number = source_cn.id;
+
+                       -- ... move V holds to the move-target call number
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_cn.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+        
+            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the call number to the target record
+                       UPDATE  asset.call_number
+                         SET   record = target_record
+                         WHERE id = source_cn.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find T holds targeting the source record ...
+       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
+
+               -- ... and move them to the target record
+               UPDATE  action.hold_request
+                 SET   target = target_record
+                 WHERE id = hold.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial records targeting the source record ...
+       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.record_entry
+                 SET   record = target_record
+                 WHERE id = ser_rec.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial subscriptions targeting the source record ...
+       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.subscription
+                 SET   record_entry = target_record
+                 WHERE id = ser_sub.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find booking resource types targeting the source record ...
+       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  booking.resource_type
+                 SET   record = target_record
+                 WHERE id = booking.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq lineitems targeting the source record ...
+       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.lineitem
+                 SET   eg_bib_id = target_record
+                 WHERE id = acq_lineitem.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq user purchase requests targeting the source record ...
+       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.user_request
+                 SET   eg_bib = target_record
+                 WHERE id = acq_request.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find parts attached to the source ...
+       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
+
+               SELECT  INTO target_part *
+                 FROM  biblio.monograph_part
+                 WHERE label = source_part.label
+                       AND record = target_record;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copy-part maps to that, and ...
+                       UPDATE  asset.copy_part_map
+                         SET   part = target_part.id
+                         WHERE part = source_part.id;
+
+                       -- ... move P holds to the move-target part
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_part.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the part to the target record
+                       UPDATE  biblio.monograph_part
+                         SET   record = target_record
+                         WHERE id = source_part.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find multi_home items attached to the source ...
+       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  biblio.peer_bib_copy_map
+                 SET   peer_record = target_record
+                 WHERE id = multi_home.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- And delete mappings where the item's home bib was merged with the peer bib
+       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
+               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
+               FROM asset.copy WHERE id = target_copy
+       );
+
+    -- Finally, "delete" the source record
+    DELETE FROM biblio.record_entry WHERE id = source_record;
+
+       -- That's all, folks!
+       RETURN moved_objects;
+END;
+$func$ LANGUAGE plpgsql;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1080', :eg_version); -- miker/jboyer/gmcharlt
+
+CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
+DECLARE
+    ocn     asset.call_number%ROWTYPE;
+    ncn     asset.call_number%ROWTYPE;
+    cid     BIGINT;
+BEGIN
+
+    IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN -- Only needs ON INSERT OR DELETE, so handle separately
+        IF TG_OP = 'INSERT' THEN
+            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                NEW.peer_record,
+                NEW.target_copy,
+                asset.calculate_copy_visibility_attribute_set(NEW.target_copy)
+            );
+
+            RETURN NEW;
+        ELSIF TG_OP = 'DELETE' THEN
+            DELETE FROM asset.copy_vis_attr_cache
+              WHERE record = OLD.peer_record AND target_copy = OLD.target_copy;
+
+            RETURN OLD;
+        END IF;
+    END IF;
+
+    IF TG_OP = 'INSERT' THEN -- Handles ON INSERT. ON UPDATE is below.
+        IF TG_TABLE_NAME IN ('copy', 'unit') THEN
+            SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
+            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                ncn.record,
+                NEW.id,
+                asset.calculate_copy_visibility_attribute_set(NEW.id)
+            );
+        ELSIF TG_TABLE_NAME = 'record_entry' THEN
+            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
+        END IF;
+
+        RETURN NEW;
+    END IF;
+
+    -- handle items first, since with circulation activity
+    -- their statuses change frequently
+    IF TG_TABLE_NAME IN ('copy', 'unit') THEN -- This handles ON UPDATE OR DELETE. ON INSERT above
+
+        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
+            DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
+            RETURN OLD;
+        END IF;
+
+        SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
+
+        IF OLD.deleted <> NEW.deleted THEN
+            IF NEW.deleted THEN
+                DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
+            ELSE
+                INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                    ncn.record,
+                    NEW.id,
+                    asset.calculate_copy_visibility_attribute_set(NEW.id)
+                );
+            END IF;
+
+            RETURN NEW;
+        ELSIF OLD.call_number  <> NEW.call_number THEN
+            SELECT * INTO ocn FROM asset.call_number cn WHERE id = OLD.call_number;
+
+            IF ncn.record <> ocn.record THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(ncn.record)
+                  WHERE id = ocn.record;
+
+                -- We have to use a record-specific WHERE clause
+                -- to avoid modifying the entries for peer-bib copies.
+                UPDATE  asset.copy_vis_attr_cache
+                  SET   target_copy = NEW.id,
+                        record = ncn.record
+                  WHERE target_copy = OLD.id
+                        AND record = ocn.record;
+            END IF;
+        END IF;
+
+        IF OLD.location     <> NEW.location OR
+           OLD.status       <> NEW.status OR
+           OLD.opac_visible <> NEW.opac_visible OR
+           OLD.circ_lib     <> NEW.circ_lib
+        THEN
+            -- Any of these could change visibility, but
+            -- we'll save some queries and not try to calculate
+            -- the change directly.  We want to update peer-bib
+            -- entries in this case, unlike above.
+            UPDATE  asset.copy_vis_attr_cache
+              SET   target_copy = NEW.id,
+                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(NEW.id)
+              WHERE target_copy = OLD.id;
+
+        END IF;
+
+    ELSIF TG_TABLE_NAME = 'call_number' THEN -- Only ON UPDATE. Copy handler will deal with ON INSERT OR DELETE.
+
+        IF OLD.record <> NEW.record THEN
+            IF NEW.label = '##URI##' THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
+                  WHERE id = OLD.record;
+
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
+                  WHERE id = NEW.record;
+            END IF;
+
+            UPDATE  asset.copy_vis_attr_cache
+              SET   record = NEW.record,
+                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
+              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
+                    AND record = OLD.record;
+
+        ELSIF OLD.owning_lib <> NEW.owning_lib THEN
+            UPDATE  asset.copy_vis_attr_cache
+              SET   vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
+              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
+                    AND record = NEW.record;
+
+            IF NEW.label = '##URI##' THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
+                  WHERE id = OLD.record;
+            END IF;
+        END IF;
+
+    ELSIF TG_TABLE_NAME = 'record_entry' THEN -- Only handles ON UPDATE OR DELETE
+
+        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
+            DELETE FROM asset.copy_vis_attr_cache WHERE record = OLD.id;
+            RETURN OLD;
+        ELSIF OLD.source <> NEW.source THEN
+            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
+        END IF;
+
+    END IF;
+
+    RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1081', :eg_version); -- jboyer/gmcharlt
+
+DROP TRIGGER IF EXISTS inherit_copy_bucket_item_target_copy_fkey ON container.copy_bucket_item;
+DROP TRIGGER IF EXISTS inherit_import_item_imported_as_fkey ON vandelay.import_item;
+DROP TRIGGER IF EXISTS inherit_asset_copy_note_copy_fkey ON asset.copy_note;
+DROP TRIGGER IF EXISTS inherit_asset_copy_tag_copy_map_copy_fkey ON asset.copy_tag_copy_map;
+
+CREATE CONSTRAINT TRIGGER inherit_copy_bucket_item_target_copy_fkey
+  AFTER UPDATE OR INSERT ON container.copy_bucket_item
+  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.container_copy_bucket_item_target_copy_inh_fkey();
+CREATE CONSTRAINT TRIGGER inherit_import_item_imported_as_fkey
+  AFTER UPDATE OR INSERT ON vandelay.import_item
+  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.vandelay_import_item_imported_as_inh_fkey();
+CREATE CONSTRAINT TRIGGER inherit_asset_copy_note_copy_fkey
+  AFTER UPDATE OR INSERT ON asset.copy_note
+  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_note_owning_copy_inh_fkey();
+CREATE CONSTRAINT TRIGGER inherit_asset_copy_tag_copy_map_copy_fkey
+  AFTER UPDATE OR INSERT ON asset.copy_tag_copy_map
+  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_tag_copy_map_copy_inh_fkey();
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1082', :eg_version); -- jboyer/gmcharlt
+
+DELETE FROM asset.copy_vis_attr_cache WHERE target_copy IN (SELECT id FROM asset.copy WHERE deleted);
+
+-- Evergreen DB patch XXXX.schema.qualify_unaccent_refs.sql
+--
+-- LP#1671150 Fix unaccent() function call in evergreen.unaccent_and_squash()
+--
+
+
+-- check whether patch can be applied
+--SELECT evergreen.upgrade_deps_block_check('1083', :eg_version);
+
+/* KCLS ALREADY HAS
+CREATE OR REPLACE FUNCTION evergreen.unaccent_and_squash ( IN arg text) RETURNS text
+    IMMUTABLE STRICT AS $$
+        BEGIN
+        RETURN evergreen.lowercase(public.unaccent('public.unaccent', regexp_replace(arg, '[\s[:punct:]]','','g')));
+        END;
+$$ LANGUAGE PLPGSQL;
+
+-- Drop indexes if present, so that we can re-create them
+DROP INDEX IF EXISTS actor.actor_usr_first_given_name_unaccent_idx;
+DROP INDEX IF EXISTS actor.actor_usr_second_given_name_unaccent_idx;
+DROP INDEX IF EXISTS actor.actor_usr_family_name_unaccent_idx; 
+DROP INDEX IF EXISTS actor.actor_usr_usrname_unaccent_idx; 
+
+-- Create (or re-create) indexes -- they may be missing if pg_restore failed to create
+-- them due to the previously unqualified call to unaccent()
+CREATE INDEX actor_usr_first_given_name_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(first_given_name));
+CREATE INDEX actor_usr_second_given_name_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(second_given_name));
+CREATE INDEX actor_usr_family_name_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(family_name));
+CREATE INDEX actor_usr_usrname_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(usrname));
+*/
+
+--SELECT evergreen.upgrade_deps_block_check('1084', :eg_version);
+DO $INSERT$
+BEGIN
+    IF evergreen.insert_on_deploy() THEN
+INSERT INTO config.usr_setting_type (name, label, description, datatype)
+  VALUES ('webstaff.cat.copy.templates', 'Web Client Copy Editor Templates', 
+    'Web Client Copy Editor Templates', 'object');
+    END IF;
+END $INSERT$;
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.3', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1085', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.calculate_copy_visibility_attribute_set ( copy_id BIGINT ) RETURNS INT[] AS $f$
+DECLARE
+    copy_row    asset.copy%ROWTYPE;
+    lgroup_map  asset.copy_location_group_map%ROWTYPE;
+    attr_set    INT[] := '{}'::INT[];
+BEGIN
+    SELECT * INTO copy_row FROM asset.copy WHERE id = copy_id;
+
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.opac_visible::INT, 'copy_flags');
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.circ_lib, 'circ_lib');
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.status, 'status');
+    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.location, 'location');
+
+    SELECT  ARRAY_APPEND(
+                attr_set,
+                search.calculate_visibility_attribute(owning_lib, 'owning_lib')
+            ) INTO attr_set
+      FROM  asset.call_number
+      WHERE id = copy_row.call_number;
+
+    FOR lgroup_map IN SELECT * FROM asset.copy_location_group_map WHERE location = copy_row.location LOOP
+        attr_set := attr_set || search.calculate_visibility_attribute(lgroup_map.lgroup, 'location_group');
+    END LOOP;
+
+    RETURN attr_set;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+DROP FUNCTION IF EXISTS biblio.calculate_bib_visibility_attribute_set ( BIGINT );
+CREATE OR REPLACE FUNCTION biblio.calculate_bib_visibility_attribute_set ( bib_id BIGINT, new_source INT DEFAULT NULL, force_source BOOL DEFAULT FALSE ) RETURNS INT[] AS $f$
+DECLARE
+    bib_row     biblio.record_entry%ROWTYPE;
+    cn_row      asset.call_number%ROWTYPE;
+    attr_set    INT[] := '{}'::INT[];
+BEGIN
+    SELECT * INTO bib_row FROM biblio.record_entry WHERE id = bib_id;
+
+    IF force_source THEN
+        IF new_source IS NOT NULL THEN
+            attr_set := attr_set || search.calculate_visibility_attribute(new_source, 'bib_source');
+        END IF;
+    ELSIF bib_row.source IS NOT NULL THEN
+        attr_set := attr_set || search.calculate_visibility_attribute(bib_row.source, 'bib_source');
+    END IF;
+
+    FOR cn_row IN
+        SELECT  *
+          FROM  asset.call_number
+          WHERE record = bib_id
+                AND label = '##URI##'
+                AND NOT deleted
+    LOOP
+        attr_set := attr_set || search.calculate_visibility_attribute(cn_row.owning_lib, 'luri_org');
+    END LOOP;
+
+    RETURN attr_set;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
+DECLARE
+    ocn     asset.call_number%ROWTYPE;
+    ncn     asset.call_number%ROWTYPE;
+    cid     BIGINT;
+    dobib   BOOL;
+BEGIN
+
+    SELECT enabled = FALSE INTO dobib FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc';
+
+    IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN -- Only needs ON INSERT OR DELETE, so handle separately
+        IF TG_OP = 'INSERT' THEN
+            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                NEW.peer_record,
+                NEW.target_copy,
+                asset.calculate_copy_visibility_attribute_set(NEW.target_copy)
+            );
+
+            RETURN NEW;
+        ELSIF TG_OP = 'DELETE' THEN
+            DELETE FROM asset.copy_vis_attr_cache
+              WHERE record = OLD.peer_record AND target_copy = OLD.target_copy;
+
+            RETURN OLD;
+        END IF;
+    END IF;
+
+    IF TG_OP = 'INSERT' THEN -- Handles ON INSERT. ON UPDATE is below.
+        IF TG_TABLE_NAME IN ('copy', 'unit') THEN
+            SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
+            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                ncn.record,
+                NEW.id,
+                asset.calculate_copy_visibility_attribute_set(NEW.id)
+            );
+        ELSIF TG_TABLE_NAME = 'record_entry' THEN
+            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id, NEW.source, TRUE);
+        ELSIF TG_TABLE_NAME = 'call_number' AND NEW.label = '##URI##' AND dobib THEN -- New located URI
+            UPDATE  biblio.record_entry
+              SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
+              WHERE id = NEW.record;
+
+        END IF;
+
+        RETURN NEW;
+    END IF;
+
+    -- handle items first, since with circulation activity
+    -- their statuses change frequently
+    IF TG_TABLE_NAME IN ('copy', 'unit') THEN -- This handles ON UPDATE OR DELETE. ON INSERT above
+
+        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
+            DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
+            RETURN OLD;
+        END IF;
+
+        SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
+
+        IF OLD.deleted <> NEW.deleted THEN
+            IF NEW.deleted THEN
+                DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
+            ELSE
+                INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
+                    ncn.record,
+                    NEW.id,
+                    asset.calculate_copy_visibility_attribute_set(NEW.id)
+                );
+            END IF;
+
+            RETURN NEW;
+        ELSIF OLD.location   <> NEW.location OR
+            OLD.status       <> NEW.status OR
+            OLD.opac_visible <> NEW.opac_visible OR
+            OLD.circ_lib     <> NEW.circ_lib OR
+            OLD.call_number  <> NEW.call_number
+        THEN
+            IF OLD.call_number  <> NEW.call_number THEN -- Special check since it's more expensive than the next branch
+                SELECT * INTO ocn FROM asset.call_number cn WHERE id = OLD.call_number;
+
+                IF ncn.record <> ocn.record THEN
+                    -- We have to use a record-specific WHERE clause
+                    -- to avoid modifying the entries for peer-bib copies.
+                    UPDATE  asset.copy_vis_attr_cache
+                      SET   target_copy = NEW.id,
+                            record = ncn.record
+                      WHERE target_copy = OLD.id
+                            AND record = ocn.record;
+
+                END IF;
+            ELSE
+                -- Any of these could change visibility, but
+                -- we'll save some queries and not try to calculate
+                -- the change directly.  We want to update peer-bib
+                -- entries in this case, unlike above.
+                UPDATE  asset.copy_vis_attr_cache
+                  SET   target_copy = NEW.id,
+                        vis_attr_vector = asset.calculate_copy_visibility_attribute_set(NEW.id)
+                  WHERE target_copy = OLD.id;
+            END IF;
+        END IF;
+
+    ELSIF TG_TABLE_NAME = 'call_number' THEN
+
+        IF TG_OP = 'DELETE' AND OLD.label = '##URI##' AND dobib THEN -- really deleted located URI, if the delete protection rule is disabled...
+            UPDATE  biblio.record_entry
+              SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
+              WHERE id = OLD.record;
+            RETURN OLD;
+        END IF;
+
+        IF OLD.label = '##URI##' AND dobib THEN -- Located URI
+            IF OLD.deleted <> NEW.deleted OR OLD.record <> NEW.record OR OLD.owning_lib <> NEW.owning_lib THEN
+                UPDATE  biblio.record_entry
+                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
+                  WHERE id = NEW.record;
+
+                IF OLD.record <> NEW.record THEN -- maybe on merge?
+                    UPDATE  biblio.record_entry
+                      SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
+                      WHERE id = OLD.record;
+                END IF;
+            END IF;
+
+        ELSIF OLD.record <> NEW.record OR OLD.owning_lib <> NEW.owning_lib THEN
+            UPDATE  asset.copy_vis_attr_cache
+              SET   record = NEW.record,
+                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
+              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
+                    AND record = OLD.record;
+
+        END IF;
+
+    ELSIF TG_TABLE_NAME = 'record_entry' AND OLD.source IS DISTINCT FROM NEW.source THEN -- Only handles ON UPDATE, INSERT above
+        NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id, NEW.source, TRUE);
+    END IF;
+
+    RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+/* created again later in the data file
+DROP TRIGGER IF EXISTS z_opac_vis_mat_view_tgr ON asset.call_number;
+DROP TRIGGER IF EXISTS z_opac_vis_mat_view_tgr ON biblio.record_entry;
+CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE OR DELETE ON asset.call_number FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+CREATE TRIGGER z_opac_vis_mat_view_tgr BEFORE INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+*/
+
+--SELECT evergreen.upgrade_deps_block_check('1086', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.location_group_default () RETURNS TEXT AS $f$
+    SELECT '!()'::TEXT; -- For now, as there's no way to cause a location group to hide all copies.
+/*
+    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'location_group')),'|') || ')'
+      FROM  asset.copy_location_group
+      WHERE NOT opac_visible;
+*/
+$f$ LANGUAGE SQL IMMUTABLE;
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1087', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.patron_default_visibility_mask () RETURNS TABLE (b_attrs TEXT, c_attrs TEXT)  AS $f$
+DECLARE
+    copy_flags      TEXT; -- "c" attr
+
+    owning_lib      TEXT; -- "c" attr
+    circ_lib        TEXT; -- "c" attr
+    status          TEXT; -- "c" attr
+    location        TEXT; -- "c" attr
+    location_group  TEXT; -- "c" attr
+
+    luri_org        TEXT; -- "b" attr
+    bib_sources     TEXT; -- "b" attr
+
+    bib_tests       TEXT := '';
+BEGIN
+    copy_flags      := asset.all_visible_flags(); -- Will always have at least one
+
+    owning_lib      := NULLIF(asset.owning_lib_default(),'!()');
+
+    circ_lib        := NULLIF(asset.circ_lib_default(),'!()');
+    status          := NULLIF(asset.status_default(),'!()');
+    location        := NULLIF(asset.location_default(),'!()');
+    location_group  := NULLIF(asset.location_group_default(),'!()');
+
+    -- LURIs will be handled at the perl layer directly
+    -- luri_org        := NULLIF(asset.luri_org_default(),'!()');
+    bib_sources     := NULLIF(asset.bib_source_default(),'()');
+
+
+    IF luri_org IS NOT NULL AND bib_sources IS NOT NULL THEN
+        bib_tests := '('||ARRAY_TO_STRING( ARRAY[luri_org,bib_sources], '|')||')&('||luri_org||')&';
+    ELSIF luri_org IS NOT NULL THEN
+        bib_tests := luri_org || '&';
+    ELSIF bib_sources IS NOT NULL THEN
+        bib_tests := bib_sources || '|';
+    END IF;
+
+    RETURN QUERY SELECT bib_tests,
+        '('||ARRAY_TO_STRING(
+            ARRAY[copy_flags,owning_lib,circ_lib,status,location,location_group]::TEXT[],
+            '&'
+        )||')';
+END;
+$f$ LANGUAGE PLPGSQL STABLE ROWS 1;
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.4', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1088', :eg_version);
+
+CREATE OR REPLACE FUNCTION metabib.staged_browse(query text, fields integer[], context_org integer, context_locations integer[], staff boolean, browse_superpage_size integer, count_up_from_zero boolean, result_limit integer, next_pivot_pos integer)
+ RETURNS SETOF metabib.flat_browse_entry_appearance
+AS $f$
+DECLARE
+    curs                    REFCURSOR;
+    rec                     RECORD;
+    qpfts_query             TEXT;
+    aqpfts_query            TEXT;
+    afields                 INT[];
+    bfields                 INT[];
+    result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
+    results_skipped         INT := 0;
+    row_counter             INT := 0;
+    row_number              INT;
+    slice_start             INT;
+    slice_end               INT;
+    full_end                INT;
+    all_records             BIGINT[];
+    all_brecords             BIGINT[];
+    all_arecords            BIGINT[];
+    superpage_of_records    BIGINT[];
+    superpage_size          INT;
+    c_tests                 TEXT := '';
+    b_tests                 TEXT := '';
+    c_orgs                  INT[];
+    unauthorized_entry      RECORD;
+BEGIN
+    IF count_up_from_zero THEN
+        row_number := 0;
+    ELSE
+        row_number := -1;
+    END IF;
+
+    IF NOT staff THEN
+        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
+    END IF;
+
+    -- b_tests supplies its own query_int operator, c_tests does not
+    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+
+    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
+
+    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
+               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
+
+    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
+    IF FOUND THEN
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
+        );
+    ELSE
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
+        );
+    END IF;
+
+    IF context_locations THEN
+        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_locations);
+    END IF;
+
+    OPEN curs NO SCROLL FOR EXECUTE query;
+
+    LOOP
+        FETCH curs INTO rec;
+        IF NOT FOUND THEN
+            IF result_row.pivot_point IS NOT NULL THEN
+                RETURN NEXT result_row;
+            END IF;
+            RETURN;
+        END IF;
+
+        --Is unauthorized?
+        SELECT INTO unauthorized_entry *
+        FROM metabib.browse_entry_simple_heading_map mbeshm
+        INNER JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+        INNER JOIN authority.control_set_authority_field acsaf ON ( acsaf.id = ash.atag )
+        JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
+        WHERE mbeshm.entry = rec.id
+        AND   ahf.heading_purpose = 'variant';
+
+        -- Gather aggregate data based on the MBE row we're looking at now, authority axis
+        IF (unauthorized_entry.record IS NOT NULL) THEN
+            --unauthorized term belongs to an auth linked to a bib?
+            SELECT INTO all_arecords, result_row.sees, afields
+                    ARRAY_AGG(DISTINCT abl.bib),
+                    STRING_AGG(DISTINCT abl.authority::TEXT, $$,$$),
+                    ARRAY_AGG(DISTINCT map.metabib_field)
+            FROM authority.bib_linking abl
+            INNER JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                    map.authority_field = unauthorized_entry.atag
+                    AND map.metabib_field = ANY(fields)
+            )
+            WHERE abl.authority = unauthorized_entry.record;
+        ELSE
+            --do usual procedure
+            SELECT INTO all_arecords, result_row.sees, afields
+                    ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
+                    STRING_AGG(DISTINCT aal.source::TEXT, $$,$$), -- authority record ids
+                    ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
+
+            FROM  metabib.browse_entry_simple_heading_map mbeshm
+                    JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
+                    JOIN authority.authority_linking aal ON ( ash.record = aal.source )
+                    JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
+                    JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
+                        ash.atag = map.authority_field
+                        AND map.metabib_field = ANY(fields)
+                    )
+                    JOIN authority.control_set_authority_field acsaf ON (
+                        map.authority_field = acsaf.id
+                    )
+                    JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
+              WHERE mbeshm.entry = rec.id
+              AND   ahf.heading_purpose = 'variant';
+
+        END IF;
+
+        -- Gather aggregate data based on the MBE row we're looking at now, bib axis
+        SELECT INTO all_brecords, result_row.authorities, bfields
+                ARRAY_AGG(DISTINCT source),
+                STRING_AGG(DISTINCT authority::TEXT, $$,$$),
+                ARRAY_AGG(DISTINCT def)
+          FROM  metabib.browse_entry_def_map
+          WHERE entry = rec.id
+                AND def = ANY(fields);
+
+        SELECT INTO result_row.fields STRING_AGG(DISTINCT x::TEXT, $$,$$) FROM UNNEST(afields || bfields) x;
+
+        result_row.sources := 0;
+        result_row.asources := 0;
+
+        -- Bib-linked vis checking
+        IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
+
+            SELECT  INTO result_row.sources COUNT(DISTINCT b.id)
+              FROM  biblio.record_entry b
+                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+              WHERE b.id = ANY(all_brecords[1:browse_superpage_size])
+                    AND (
+                        acvac.vis_attr_vector @@ c_tests::query_int
+                        OR b.vis_attr_vector @@ b_tests::query_int
+                    );
+
+            result_row.accurate := TRUE;
+
+        END IF;
+
+        -- Authority-linked vis checking
+        IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
+
+            SELECT  INTO result_row.asources COUNT(DISTINCT b.id)
+              FROM  biblio.record_entry b
+                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+              WHERE b.id = ANY(all_arecords[1:browse_superpage_size])
+                    AND (
+                        acvac.vis_attr_vector @@ c_tests::query_int
+                        OR b.vis_attr_vector @@ b_tests::query_int
+                    );
+
+            result_row.aaccurate := TRUE;
+
+        END IF;
+
+        IF result_row.sources > 0 OR result_row.asources > 0 THEN
+
+            -- The function that calls this function needs row_number in order
+            -- to correctly order results from two different runs of this
+            -- functions.
+            result_row.row_number := row_number;
+
+            -- Now, if row_counter is still less than limit, return a row.  If
+            -- not, but it is less than next_pivot_pos, continue on without
+            -- returning actual result rows until we find
+            -- that next pivot, and return it.
+
+            IF row_counter < result_limit THEN
+                result_row.browse_entry := rec.id;
+                result_row.value := rec.value;
+
+                RETURN NEXT result_row;
+            ELSE
+                result_row.browse_entry := NULL;
+                result_row.authorities := NULL;
+                result_row.fields := NULL;
+                result_row.value := NULL;
+                result_row.sources := NULL;
+                result_row.sees := NULL;
+                result_row.accurate := NULL;
+                result_row.aaccurate := NULL;
+                result_row.pivot_point := rec.id;
+
+                IF row_counter >= next_pivot_pos THEN
+                    RETURN NEXT result_row;
+                    RETURN;
+                END IF;
+            END IF;
+
+            IF count_up_from_zero THEN
+                row_number := row_number + 1;
+            ELSE
+                row_number := row_number - 1;
+            END IF;
+
+            -- row_counter is different from row_number.
+            -- It simply counts up from zero so that we know when
+            -- we've reached our limit.
+            row_counter := row_counter + 1;
+        END IF;
+    END LOOP;
+END;
+$f$ LANGUAGE plpgsql ROWS 10;
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.6', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1107', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
+DECLARE
+    moved_objects INT := 0;
+    source_cn     asset.call_number%ROWTYPE;
+    target_cn     asset.call_number%ROWTYPE;
+    metarec       metabib.metarecord%ROWTYPE;
+    hold          action.hold_request%ROWTYPE;
+    ser_rec       serial.record_entry%ROWTYPE;
+    ser_sub       serial.subscription%ROWTYPE;
+    acq_lineitem  acq.lineitem%ROWTYPE;
+    acq_request   acq.user_request%ROWTYPE;
+    booking       booking.resource_type%ROWTYPE;
+    source_part   biblio.monograph_part%ROWTYPE;
+    target_part   biblio.monograph_part%ROWTYPE;
+    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
+    uri_count     INT := 0;
+    counter       INT := 0;
+    uri_datafield TEXT;
+    uri_text      TEXT := '';
+BEGIN
+
+    -- move any 856 entries on records that have at least one MARC-mapped URI entry
+    SELECT  INTO uri_count COUNT(*)
+      FROM  asset.uri_call_number_map m
+            JOIN asset.call_number cn ON (m.call_number = cn.id)
+      WHERE cn.record = source_record;
+
+    IF uri_count > 0 THEN
+        
+        -- This returns more nodes than you might expect:
+        -- 7 instead of 1 for an 856 with $u $y $9
+        SELECT  COUNT(*) INTO counter
+          FROM  oils_xpath_table(
+                    'id',
+                    'marc',
+                    'biblio.record_entry',
+                    '//*[@tag="856"]',
+                    'id=' || source_record
+                ) as t(i int,c text);
+    
+        FOR i IN 1 .. counter LOOP
+            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
+                       ' tag="856"' ||
+                       ' ind1="' || FIRST(ind1) || '"'  ||
+                       ' ind2="' || FIRST(ind2) || '">' ||
+                        STRING_AGG(
+                            '<subfield code="' || subfield || '">' ||
+                            regexp_replace(
+                                regexp_replace(
+                                    regexp_replace(data,'&','&amp;','g'),
+                                    '>', '&gt;', 'g'
+                                ),
+                                '<', '&lt;', 'g'
+                            ) || '</subfield>', ''
+                        ) || '</datafield>' INTO uri_datafield
+              FROM  oils_xpath_table(
+                        'id',
+                        'marc',
+                        'biblio.record_entry',
+                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
+                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
+                        'id=' || source_record
+                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
+
+            -- As most of the results will be NULL, protect against NULLifying
+            -- the valid content that we do generate
+            uri_text := uri_text || COALESCE(uri_datafield, '');
+        END LOOP;
+
+        IF uri_text <> '' THEN
+            UPDATE  biblio.record_entry
+              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
+              WHERE id = target_record;
+        END IF;
+
+    END IF;
+
+       -- Find and move metarecords to the target record
+       SELECT  INTO metarec *
+         FROM  metabib.metarecord
+         WHERE master_record = source_record;
+
+       IF FOUND THEN
+               UPDATE  metabib.metarecord
+                 SET   master_record = target_record,
+                       mods = NULL
+                 WHERE id = metarec.id;
+
+               moved_objects := moved_objects + 1;
+       END IF;
+
+       -- Find call numbers attached to the source ...
+       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
+
+               SELECT  INTO target_cn *
+                 FROM  asset.call_number
+                 WHERE label = source_cn.label
+            AND prefix = source_cn.prefix
+            AND suffix = source_cn.suffix
+                       AND owning_lib = source_cn.owning_lib
+                       AND record = target_record
+                       AND NOT deleted;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copies to that, and ...
+                       UPDATE  asset.copy
+                         SET   call_number = target_cn.id
+                         WHERE call_number = source_cn.id;
+
+                       -- ... move V holds to the move-target call number
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_cn.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+        
+            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the call number to the target record
+                       UPDATE  asset.call_number
+                         SET   record = target_record
+                         WHERE id = source_cn.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find T holds targeting the source record ...
+       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
+
+               -- ... and move them to the target record
+               UPDATE  action.hold_request
+                 SET   target = target_record
+                 WHERE id = hold.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial records targeting the source record ...
+       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.record_entry
+                 SET   record = target_record
+                 WHERE id = ser_rec.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial subscriptions targeting the source record ...
+       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.subscription
+                 SET   record_entry = target_record
+                 WHERE id = ser_sub.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find booking resource types targeting the source record ...
+       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  booking.resource_type
+                 SET   record = target_record
+                 WHERE id = booking.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq lineitems targeting the source record ...
+       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.lineitem
+                 SET   eg_bib_id = target_record
+                 WHERE id = acq_lineitem.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq user purchase requests targeting the source record ...
+       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.user_request
+                 SET   eg_bib = target_record
+                 WHERE id = acq_request.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find parts attached to the source ...
+       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
+
+               SELECT  INTO target_part *
+                 FROM  biblio.monograph_part
+                 WHERE label = source_part.label
+                       AND record = target_record;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copy-part maps to that, and ...
+                       UPDATE  asset.copy_part_map
+                         SET   part = target_part.id
+                         WHERE part = source_part.id;
+
+                       -- ... move P holds to the move-target part
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_part.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the part to the target record
+                       UPDATE  biblio.monograph_part
+                         SET   record = target_record
+                         WHERE id = source_part.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find multi_home items attached to the source ...
+       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  biblio.peer_bib_copy_map
+                 SET   peer_record = target_record
+                 WHERE id = multi_home.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- And delete mappings where the item's home bib was merged with the peer bib
+       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
+               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
+               FROM asset.copy WHERE id = target_copy
+       );
+
+    -- replace book bag entries of source_record with target_record
+    UPDATE container.biblio_record_entry_bucket_item
+        SET target_biblio_record_entry = target_record
+        WHERE bucket IN (SELECT id FROM container.biblio_record_entry_bucket WHERE btype = 'bookbag')
+        AND target_biblio_record_entry = source_record;
+
+    -- Finally, "delete" the source record
+    DELETE FROM biblio.record_entry WHERE id = source_record;
+
+       -- That's all, folks!
+       RETURN moved_objects;
+END;
+$func$ LANGUAGE plpgsql;
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.0', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1089', :eg_version);
+
+-- Add the circ.holds.max_duplicate_holds org. unit setting type.
+DO $INSERT$                                                                    
+BEGIN                                                                          
+    IF evergreen.insert_on_deploy() THEN 
+
+INSERT into config.org_unit_setting_type
+( name, grp, label, description, datatype, fm_class )
+VALUES
+( 'circ.holds.max_duplicate_holds', 'holds',
+   oils_i18n_gettext(
+     'circ.holds.max_duplicate_holds',
+     'Maximum number of duplicate holds allowed.',
+     'coust', 'label'),
+   oils_i18n_gettext(
+     'circ.holds.max_duplicate_holds',
+     'Maximum number of duplicate title or metarecord holds allowed per patron.',
+     'coust', 'description'),
+   'integer', null );
+    END IF;                                                                    
+END $INSERT$; 
+
+
+--SELECT evergreen.upgrade_deps_block_check('1090', :eg_version);
+
+/* KCLS ALREAD HAS THIS
+ALTER TABLE biblio.record_entry
+    ADD COLUMN merge_date TIMESTAMP WITH TIME ZONE,
+    ADD COLUMN merged_to BIGINT REFERENCES biblio.record_entry(id);
+*/
+
+CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
+DECLARE
+    moved_objects INT := 0;
+    source_cn     asset.call_number%ROWTYPE;
+    target_cn     asset.call_number%ROWTYPE;
+    metarec       metabib.metarecord%ROWTYPE;
+    hold          action.hold_request%ROWTYPE;
+    ser_rec       serial.record_entry%ROWTYPE;
+    ser_sub       serial.subscription%ROWTYPE;
+    acq_lineitem  acq.lineitem%ROWTYPE;
+    acq_request   acq.user_request%ROWTYPE;
+    booking       booking.resource_type%ROWTYPE;
+    source_part   biblio.monograph_part%ROWTYPE;
+    target_part   biblio.monograph_part%ROWTYPE;
+    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
+    uri_count     INT := 0;
+    counter       INT := 0;
+    uri_datafield TEXT;
+    uri_text      TEXT := '';
+BEGIN
+
+    -- move any 856 entries on records that have at least one MARC-mapped URI entry
+    SELECT  INTO uri_count COUNT(*)
+      FROM  asset.uri_call_number_map m
+            JOIN asset.call_number cn ON (m.call_number = cn.id)
+      WHERE cn.record = source_record;
+
+    IF uri_count > 0 THEN
+        
+        -- This returns more nodes than you might expect:
+        -- 7 instead of 1 for an 856 with $u $y $9
+        SELECT  COUNT(*) INTO counter
+          FROM  oils_xpath_table(
+                    'id',
+                    'marc',
+                    'biblio.record_entry',
+                    '//*[@tag="856"]',
+                    'id=' || source_record
+                ) as t(i int,c text);
+    
+        FOR i IN 1 .. counter LOOP
+            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
+                       ' tag="856"' ||
+                       ' ind1="' || FIRST(ind1) || '"'  ||
+                       ' ind2="' || FIRST(ind2) || '">' ||
+                        STRING_AGG(
+                            '<subfield code="' || subfield || '">' ||
+                            regexp_replace(
+                                regexp_replace(
+                                    regexp_replace(data,'&','&amp;','g'),
+                                    '>', '&gt;', 'g'
+                                ),
+                                '<', '&lt;', 'g'
+                            ) || '</subfield>', ''
+                        ) || '</datafield>' INTO uri_datafield
+              FROM  oils_xpath_table(
+                        'id',
+                        'marc',
+                        'biblio.record_entry',
+                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
+                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
+                        'id=' || source_record
+                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
+
+            -- As most of the results will be NULL, protect against NULLifying
+            -- the valid content that we do generate
+            uri_text := uri_text || COALESCE(uri_datafield, '');
+        END LOOP;
+
+        IF uri_text <> '' THEN
+            UPDATE  biblio.record_entry
+              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
+              WHERE id = target_record;
+        END IF;
+
+    END IF;
+
+       -- Find and move metarecords to the target record
+       SELECT  INTO metarec *
+         FROM  metabib.metarecord
+         WHERE master_record = source_record;
+
+       IF FOUND THEN
+               UPDATE  metabib.metarecord
+                 SET   master_record = target_record,
+                       mods = NULL
+                 WHERE id = metarec.id;
+
+               moved_objects := moved_objects + 1;
+       END IF;
+
+       -- Find call numbers attached to the source ...
+       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
+
+               SELECT  INTO target_cn *
+                 FROM  asset.call_number
+                 WHERE label = source_cn.label
+            AND prefix = source_cn.prefix
+            AND suffix = source_cn.suffix
+                       AND owning_lib = source_cn.owning_lib
+                       AND record = target_record
+                       AND NOT deleted;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copies to that, and ...
+                       UPDATE  asset.copy
+                         SET   call_number = target_cn.id
+                         WHERE call_number = source_cn.id;
+
+                       -- ... move V holds to the move-target call number
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_cn.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+        
+            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the call number to the target record
+                       UPDATE  asset.call_number
+                         SET   record = target_record
+                         WHERE id = source_cn.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find T holds targeting the source record ...
+       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
+
+               -- ... and move them to the target record
+               UPDATE  action.hold_request
+                 SET   target = target_record
+                 WHERE id = hold.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial records targeting the source record ...
+       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.record_entry
+                 SET   record = target_record
+                 WHERE id = ser_rec.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial subscriptions targeting the source record ...
+       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.subscription
+                 SET   record_entry = target_record
+                 WHERE id = ser_sub.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find booking resource types targeting the source record ...
+       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  booking.resource_type
+                 SET   record = target_record
+                 WHERE id = booking.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq lineitems targeting the source record ...
+       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.lineitem
+                 SET   eg_bib_id = target_record
+                 WHERE id = acq_lineitem.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq user purchase requests targeting the source record ...
+       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.user_request
+                 SET   eg_bib = target_record
+                 WHERE id = acq_request.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find parts attached to the source ...
+       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
+
+               SELECT  INTO target_part *
+                 FROM  biblio.monograph_part
+                 WHERE label = source_part.label
+                       AND record = target_record;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copy-part maps to that, and ...
+                       UPDATE  asset.copy_part_map
+                         SET   part = target_part.id
+                         WHERE part = source_part.id;
+
+                       -- ... move P holds to the move-target part
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_part.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the part to the target record
+                       UPDATE  biblio.monograph_part
+                         SET   record = target_record
+                         WHERE id = source_part.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find multi_home items attached to the source ...
+       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  biblio.peer_bib_copy_map
+                 SET   peer_record = target_record
+                 WHERE id = multi_home.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- And delete mappings where the item's home bib was merged with the peer bib
+       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
+               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
+               FROM asset.copy WHERE id = target_copy
+       );
+
+    -- Apply merge tracking
+    UPDATE biblio.record_entry 
+        SET merge_date = NOW() WHERE id = target_record;
+
+    UPDATE biblio.record_entry
+        SET merge_date = NOW(), merged_to = target_record
+        WHERE id = source_record;
+
+    -- Finally, "delete" the source record
+    DELETE FROM biblio.record_entry WHERE id = source_record;
+
+       -- That's all, folks!
+       RETURN moved_objects;
+END;
+$func$ LANGUAGE plpgsql;
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1091', :eg_version);
+
+ALTER TABLE acq.funding_source DROP CONSTRAINT funding_source_code_key;
+ALTER TABLE acq.funding_source ALTER COLUMN code SET NOT NULL;
+ALTER TABLE acq.funding_source ADD CONSTRAINT funding_source_code_once_per_owner UNIQUE (code,owner);
+
+
+--SELECT evergreen.upgrade_deps_block_check('1092', :eg_version);
+
+CREATE OR REPLACE FUNCTION metabib.reingest_record_attributes (rid BIGINT, pattr_list TEXT[] DEFAULT NULL, prmarc TEXT DEFAULT NULL, rdeleted BOOL DEFAULT TRUE) RETURNS VOID AS $func$
+DECLARE
+    transformed_xml TEXT;
+    rmarc           TEXT := prmarc;
+    tmp_val         TEXT;
+    prev_xfrm       TEXT;
+    normalizer      RECORD;
+    xfrm            config.xml_transform%ROWTYPE;
+    attr_vector     INT[] := '{}'::INT[];
+    attr_vector_tmp INT[];
+    attr_list       TEXT[] := pattr_list;
+    attr_value      TEXT[];
+    norm_attr_value TEXT[];
+    tmp_xml         TEXT;
+    tmp_array       TEXT[];
+    attr_def        config.record_attr_definition%ROWTYPE;
+    ccvm_row        config.coded_value_map%ROWTYPE;
+    jump_past       BOOL;
+BEGIN
+
+    IF attr_list IS NULL OR rdeleted THEN -- need to do the full dance on INSERT or undelete
+        SELECT ARRAY_AGG(name) INTO attr_list FROM config.record_attr_definition
+        WHERE (
+            tag IS NOT NULL OR
+            fixed_field IS NOT NULL OR
+            xpath IS NOT NULL OR
+            phys_char_sf IS NOT NULL OR
+            composite
+        ) AND (
+            filter OR sorter
+        );
+    END IF;
+
+    IF rmarc IS NULL THEN
+        SELECT marc INTO rmarc FROM biblio.record_entry WHERE id = rid;
+    END IF;
+
+    FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE NOT composite AND name = ANY( attr_list ) ORDER BY format LOOP
+
+        jump_past := FALSE; -- This gets set when we are non-multi and have found something
+        attr_value := '{}'::TEXT[];
+        norm_attr_value := '{}'::TEXT[];
+        attr_vector_tmp := '{}'::INT[];
+
+        SELECT * INTO ccvm_row FROM config.coded_value_map c WHERE c.ctype = attr_def.name LIMIT 1; 
+
+        IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
+            SELECT  ARRAY_AGG(value) INTO attr_value
+              FROM  (SELECT * FROM metabib.full_rec ORDER BY tag, subfield) AS x
+              WHERE record = rid
+                    AND tag LIKE attr_def.tag
+                    AND CASE
+                        WHEN attr_def.sf_list IS NOT NULL 
+                            THEN POSITION(subfield IN attr_def.sf_list) > 0
+                        ELSE TRUE
+                    END
+              GROUP BY tag
+              ORDER BY tag;
+
+            IF NOT attr_def.multi THEN
+                attr_value := ARRAY[ARRAY_TO_STRING(attr_value, COALESCE(attr_def.joiner,' '))];
+                jump_past := TRUE;
+            END IF;
+        END IF;
+
+        IF NOT jump_past AND attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
+            attr_value := attr_value || vandelay.marc21_extract_fixed_field_list(rmarc, attr_def.fixed_field);
+
+            IF NOT attr_def.multi THEN
+                attr_value := ARRAY[attr_value[1]];
+                jump_past := TRUE;
+            END IF;
+        END IF;
+
+        IF NOT jump_past AND attr_def.xpath IS NOT NULL THEN -- and xpath expression
+
+            SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
+        
+            -- See if we can skip the XSLT ... it's expensive
+            IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+                -- Can't skip the transform
+                IF xfrm.xslt <> '---' THEN
+                    transformed_xml := oils_xslt_process(rmarc,xfrm.xslt);
+                ELSE
+                    transformed_xml := rmarc;
+                END IF;
+    
+                prev_xfrm := xfrm.name;
+            END IF;
+
+            IF xfrm.name IS NULL THEN
+                -- just grab the marcxml (empty) transform
+                SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
+                prev_xfrm := xfrm.name;
+            END IF;
+
+            FOR tmp_xml IN SELECT UNNEST(oils_xpath(attr_def.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]])) LOOP
+                tmp_val := oils_xpath_string(
+                                '//*',
+                                tmp_xml,
+                                COALESCE(attr_def.joiner,' '),
+                                ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
+                            );
+                IF tmp_val IS NOT NULL AND BTRIM(tmp_val) <> '' THEN
+                    attr_value := attr_value || tmp_val;
+                    EXIT WHEN NOT attr_def.multi;
+                END IF;
+            END LOOP;
+        END IF;
+
+        IF NOT jump_past AND attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
+            SELECT  ARRAY_AGG(m.value) INTO tmp_array
+              FROM  vandelay.marc21_physical_characteristics(rmarc) v
+                    LEFT JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
+              WHERE v.subfield = attr_def.phys_char_sf AND (m.value IS NOT NULL AND BTRIM(m.value) <> '')
+                    AND ( ccvm_row.id IS NULL OR ( ccvm_row.id IS NOT NULL AND v.id IS NOT NULL) );
+
+            attr_value := attr_value || tmp_array;
+
+            IF NOT attr_def.multi THEN
+                attr_value := ARRAY[attr_value[1]];
+            END IF;
+
+        END IF;
+
+                -- apply index normalizers to attr_value
+        FOR tmp_val IN SELECT value FROM UNNEST(attr_value) x(value) LOOP
+            FOR normalizer IN
+                SELECT  n.func AS func,
+                        n.param_count AS param_count,
+                        m.params AS params
+                  FROM  config.index_normalizer n
+                        JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
+                  WHERE attr = attr_def.name
+                  ORDER BY m.pos LOOP
+                    EXECUTE 'SELECT ' || normalizer.func || '(' ||
+                    COALESCE( quote_literal( tmp_val ), 'NULL' ) ||
+                        CASE
+                            WHEN normalizer.param_count > 0
+                                THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
+                                ELSE ''
+                            END ||
+                    ')' INTO tmp_val;
+
+            END LOOP;
+            IF tmp_val IS NOT NULL AND tmp_val <> '' THEN
+                -- note that a string that contains only blanks
+                -- is a valid value for some attributes
+                norm_attr_value := norm_attr_value || tmp_val;
+            END IF;
+        END LOOP;
+        
+        IF attr_def.filter THEN
+            -- Create unknown uncontrolled values and find the IDs of the values
+            IF ccvm_row.id IS NULL THEN
+                FOR tmp_val IN SELECT value FROM UNNEST(norm_attr_value) x(value) LOOP
+                    IF tmp_val IS NOT NULL AND BTRIM(tmp_val) <> '' THEN
+                        BEGIN -- use subtransaction to isolate unique constraint violations
+                            INSERT INTO metabib.uncontrolled_record_attr_value ( attr, value ) VALUES ( attr_def.name, tmp_val );
+                        EXCEPTION WHEN unique_violation THEN END;
+                    END IF;
+                END LOOP;
+
+                SELECT ARRAY_AGG(id) INTO attr_vector_tmp FROM metabib.uncontrolled_record_attr_value WHERE attr = attr_def.name AND value = ANY( norm_attr_value );
+            ELSE
+                SELECT ARRAY_AGG(id) INTO attr_vector_tmp FROM config.coded_value_map WHERE ctype = attr_def.name AND code = ANY( norm_attr_value );
+            END IF;
+
+            -- Add the new value to the vector
+            attr_vector := attr_vector || attr_vector_tmp;
+        END IF;
+
+        IF attr_def.sorter THEN
+            DELETE FROM metabib.record_sorter WHERE source = rid AND attr = attr_def.name;
+            IF norm_attr_value[1] IS NOT NULL THEN
+                INSERT INTO metabib.record_sorter (source, attr, value) VALUES (rid, attr_def.name, norm_attr_value[1]);
+            END IF;
+        END IF;
+
+    END LOOP;
+
+/* We may need to rewrite the vlist to contain
+   the intersection of new values for requested
+   attrs and old values for ignored attrs. To
+   do this, we take the old attr vlist and
+   subtract any values that are valid for the
+   requested attrs, and then add back the new
+   set of attr values. */
+
+    IF ARRAY_LENGTH(pattr_list, 1) > 0 THEN 
+        SELECT vlist INTO attr_vector_tmp FROM metabib.record_attr_vector_list WHERE source = rid;
+        SELECT attr_vector_tmp - ARRAY_AGG(id::INT) INTO attr_vector_tmp FROM metabib.full_attr_id_map WHERE attr = ANY (pattr_list);
+        attr_vector := attr_vector || attr_vector_tmp;
+    END IF;
+
+    -- On to composite attributes, now that the record attrs have been pulled.  Processed in name order, so later composite
+    -- attributes can depend on earlier ones.
+    PERFORM metabib.compile_composite_attr_cache_init();
+    FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE composite AND name = ANY( attr_list ) ORDER BY name LOOP
+
+        FOR ccvm_row IN SELECT * FROM config.coded_value_map c WHERE c.ctype = attr_def.name ORDER BY value LOOP
+
+            tmp_val := metabib.compile_composite_attr( ccvm_row.id );
+            CONTINUE WHEN tmp_val IS NULL OR tmp_val = ''; -- nothing to do
+
+            IF attr_def.filter THEN
+                IF attr_vector @@ tmp_val::query_int THEN
+                    attr_vector = attr_vector + intset(ccvm_row.id);
+                    EXIT WHEN NOT attr_def.multi;
+                END IF;
+            END IF;
+
+            IF attr_def.sorter THEN
+                IF attr_vector @@ tmp_val THEN
+                    DELETE FROM metabib.record_sorter WHERE source = rid AND attr = attr_def.name;
+                    INSERT INTO metabib.record_sorter (source, attr, value) VALUES (rid, attr_def.name, ccvm_row.code);
+                END IF;
+            END IF;
+
+        END LOOP;
+
+    END LOOP;
+
+    IF ARRAY_LENGTH(attr_vector, 1) > 0 THEN
+        IF rdeleted THEN -- initial insert OR revivication
+            DELETE FROM metabib.record_attr_vector_list WHERE source = rid;
+            INSERT INTO metabib.record_attr_vector_list (source, vlist) VALUES (rid, attr_vector);
+        ELSE
+            UPDATE metabib.record_attr_vector_list SET vlist = attr_vector WHERE source = rid;
+        END IF;
+    END IF;
+
+END;
+
+$func$ LANGUAGE PLPGSQL;
+
+--SELECT evergreen.upgrade_deps_block_check('1095', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.copy_state (cid BIGINT) RETURNS TEXT AS $$
+DECLARE
+    last_circ_stop     TEXT;
+    the_copy       asset.copy%ROWTYPE;
+BEGIN
+
+    SELECT * INTO the_copy FROM asset.copy WHERE id = cid;
+    IF NOT FOUND THEN RETURN NULL; END IF;
+
+    IF the_copy.status = 3 THEN -- Lost
+        RETURN 'LOST';
+    ELSIF the_copy.status = 4 THEN -- Missing
+        RETURN 'MISSING';
+    ELSIF the_copy.status = 14 THEN -- Damaged
+        RETURN 'DAMAGED';
+    ELSIF the_copy.status = 17 THEN -- Lost and paid
+        RETURN 'LOST_AND_PAID';
+    END IF;
+
+    SELECT stop_fines INTO last_circ_stop
+      FROM  action.circulation
+      WHERE target_copy = cid
+      ORDER BY xact_start DESC LIMIT 1;
+
+    IF FOUND THEN
+        IF last_circ_stop IN (
+            'CLAIMSNEVERCHECKEDOUT',
+            'CLAIMSRETURNED',
+            'LONGOVERDUE'
+        ) THEN
+            RETURN last_circ_stop;
+        END IF;
+    END IF;
+
+    RETURN 'NORMAL';
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TYPE config.copy_alert_type_state AS ENUM (
+    'NORMAL',
+    'LOST',
+    'LOST_AND_PAID',
+    'MISSING',
+    'DAMAGED',
+    'CLAIMSRETURNED',
+    'LONGOVERDUE',
+    'CLAIMSNEVERCHECKEDOUT'
+);
+
+CREATE TYPE config.copy_alert_type_event AS ENUM (
+    'CHECKIN',
+    'CHECKOUT'
+);
+
+CREATE TABLE config.copy_alert_type (
+    id         serial  primary key, -- reserve 1-100 for system
+    scope_org   int not null references actor.org_unit (id) on delete cascade,
+    active      bool    not null default true,
+    name        text    not null unique,
+    state       config.copy_alert_type_state,
+    event       config.copy_alert_type_event,
+    in_renew    bool,
+    invert_location bool    not null default false,
+    at_circ     bool,
+    at_owning   bool,
+    next_status int[]
+);
+SELECT SETVAL('config.copy_alert_type_id_seq'::TEXT, 100);
+
+CREATE OR REPLACE FUNCTION evergreen.asset_copy_alert_copy_inh_fkey() RETURNS TRIGGER AS $f$
+BEGIN
+        PERFORM 1 FROM asset.copy WHERE id = NEW.copy;
+        IF NOT FOUND THEN
+                RAISE foreign_key_violation USING MESSAGE = FORMAT(
+                        $$Referenced asset.copy id not found, copy:%s$$, NEW.copy
+                );
+        END IF;
+        RETURN NEW;
+END;
+$f$ LANGUAGE PLPGSQL VOLATILE COST 50;
+
+CREATE TABLE actor.copy_alert_suppress (
+    id          serial primary key,
+    org         int not null references actor.org_unit (id) on delete cascade,
+    alert_type  int not null references config.copy_alert_type (id) on delete cascade
+);
+
+CREATE TABLE asset.copy_alert (
+    id      bigserial   primary key,
+    alert_type  int     not null references config.copy_alert_type (id) on delete cascade,
+    copy        bigint  not null,
+    temp        bool    not null default false,
+    create_time timestamptz not null default now(),
+    create_staff    bigint  not null references actor.usr (id) on delete set null,
+    note        text,
+    ack_time    timestamptz,
+    ack_staff   bigint references actor.usr (id) on delete set null
+);
+
+CREATE CONSTRAINT TRIGGER inherit_asset_copy_alert_copy_fkey
+        AFTER UPDATE OR INSERT ON asset.copy_alert
+        DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_alert_copy_inh_fkey();
+
+CREATE VIEW asset.active_copy_alert AS
+    SELECT  *
+      FROM  asset.copy_alert
+      WHERE ack_time IS NULL;
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1096', :eg_version);
+
+DO $INSERT$                                                                    
+BEGIN                                                                          
+    IF evergreen.insert_on_deploy() THEN
+
+-- staff-usable alert types with no location awareness
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew)
+VALUES (1, 1, TRUE, 'Normal checkout', 'NORMAL', 'CHECKOUT', FALSE);
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew)
+VALUES (2, 1, TRUE, 'Normal checkin', 'NORMAL', 'CHECKIN', FALSE);
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew)
+VALUES (3, 1, FALSE, 'Normal renewal', 'NORMAL', 'CHECKIN', TRUE);
+
+-- copy alerts upon checkin or renewal of exceptional copy statuses are not active by
+-- default; they're meant to be turned once a site is ready to fully
+-- commit to using the webstaff client for circulation
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (4, 1, FALSE, 'Checkin of lost copy', 'LOST', 'CHECKIN');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (5, 1, FALSE, 'Checkin of missing copy', 'MISSING', 'CHECKIN');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (6, 1, FALSE, 'Checkin of lost-and-paid copy', 'LOST_AND_PAID', 'CHECKIN');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (7, 1, FALSE, 'Checkin of damaged copy', 'DAMAGED', 'CHECKIN');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (8, 1, FALSE, 'Checkin of claims-returned copy', 'CLAIMSRETURNED', 'CHECKIN');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (9, 1, FALSE, 'Checkin of long overdue copy', 'LONGOVERDUE', 'CHECKIN');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (10, 1, FALSE, 'Checkin of claims-never-checked-out copy', 'CLAIMSNEVERCHECKEDOUT', 'CHECKIN');
+
+-- copy alerts upon checkout of exceptional copy statuses are not active by
+-- default; they're meant to be turned once a site is ready to fully
+-- commit to using the webstaff client for circulation
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (11, 1, FALSE, 'Checkout of lost copy', 'LOST', 'CHECKOUT');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (12, 1, FALSE, 'Checkout of missing copy', 'MISSING', 'CHECKOUT');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (13, 1, FALSE, 'Checkout of lost-and-paid copy', 'LOST_AND_PAID', 'CHECKOUT');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (14, 1, FALSE, 'Checkout of damaged copy', 'DAMAGED', 'CHECKOUT');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (15, 1, FALSE, 'Checkout of claims-returned copy', 'CLAIMSRETURNED', 'CHECKOUT');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (16, 1, FALSE, 'Checkout of long overdue copy', 'LONGOVERDUE', 'CHECKOUT');
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
+VALUES (17, 1, FALSE, 'Checkout of claims-never-checked-out copy', 'CLAIMSNEVERCHECKEDOUT', 'CHECKOUT');
+
+-- staff-usable alert types based on location
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_circ)
+VALUES (18, 1, FALSE, 'Normal checkout at circ lib', 'NORMAL', 'CHECKOUT', FALSE, TRUE);
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_circ)
+VALUES (19, 1, FALSE, 'Normal checkin at circ lib', 'NORMAL', 'CHECKIN', FALSE, TRUE);
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_circ)
+VALUES (20, 1, FALSE, 'Normal renewal at circ lib', 'NORMAL', 'CHECKIN', TRUE, TRUE);
+
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_owning)
+VALUES (21, 1, FALSE, 'Normal checkout at owning lib', 'NORMAL', 'CHECKOUT', FALSE, TRUE);
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_owning)
+VALUES (22, 1, FALSE, 'Normal checkin at owning lib', 'NORMAL', 'CHECKIN', FALSE, TRUE);
+INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_owning)
+VALUES (23, 1, FALSE, 'Normal renewal at owning lib', 'NORMAL', 'CHECKIN', TRUE, TRUE);
+
+
+--SELECT evergreen.upgrade_deps_block_check('1097', :eg_version);
+
+INSERT INTO config.org_unit_setting_type
+    (name, grp, label, description, datatype)
+    VALUES
+        ('circ.copy_alerts.forgive_fines_on_lost_checkin',
+         'circ',
+         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_lost_checkin',
+            'Forgive fines when checking out a lost item and copy alert is suppressed?',
+            'coust', 'label'),
+         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_lost_checkin',
+            'Controls whether fines are automatically forgiven when checking out an '||
+            'item that has been marked as lost, and the corresponding copy alert has been '||
+            'suppressed.',
+            'coust', 'description'),
+        'bool');
+
+INSERT INTO config.org_unit_setting_type
+    (name, grp, label, description, datatype)
+    VALUES
+        ('circ.copy_alerts.forgive_fines_on_long_overdue_checkin',
+         'circ',
+         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_long_overdue_checkin',
+            'Forgive fines when checking out a long-overdue item and copy alert is suppressed?',
+            'coust', 'label'),
+         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_lost_checkin',
+            'Controls whether fines are automatically forgiven when checking out an '||
+            'item that has been marked as lost, and the corresponding copy alert has been '||
+            'suppressed.',
+            'coust', 'description'),
+        'bool');
+
+    END IF;                                                                    
+END $INSERT$; 
+
+--SELECT evergreen.upgrade_deps_block_check('1098', :eg_version);
+
+\qecho Copying copy alert messages to normal checkout copy alerts...
+INSERT INTO asset.copy_alert (alert_type, copy, note, create_staff)
+SELECT 1, id, alert_message, 1
+FROM asset.copy
+WHERE alert_message IS NOT NULL
+AND   alert_message <> '';
+
+\qecho Copying copy alert messages to normal checkin copy alerts...
+INSERT INTO asset.copy_alert (alert_type, copy, note, create_staff)
+SELECT 2, id, alert_message, 1
+FROM asset.copy
+WHERE alert_message IS NOT NULL
+AND   alert_message <> '';
+
+\qecho Clearing legacy copy alert field; this may take a while
+UPDATE asset.copy SET alert_message = NULL
+WHERE alert_message IS NOT NULL;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1099', :eg_version);
+-- moved update to data file
+
+--SELECT evergreen.upgrade_deps_block_check('1100', :eg_version);
+
+-- NEW config.metabib_field entries
+
+UPDATE config.metabib_field SET display_xpath = facet_xpath, display_field = TRUE WHERE id = 33;
+
+                                                                               
+DO $INSERT$                                                                    
+BEGIN                                                                          
+   IF evergreen.insert_on_deploy() THEN     
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    38, 'identifier', 'edition', 
+    oils_i18n_gettext(38, 'Edition', 'cmf', 'label'),
+    $$//mods33:mods/mods33:originInfo//mods33:edition[1]$$,
+    TRUE, TRUE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    39, 'keyword', 'physical_description', 
+    oils_i18n_gettext(39, 'Physical Descrption', 'cmf', 'label'),
+    $$(//mods33:mods/mods33:physicalDescription/mods33:form|//mods33:mods/mods33:physicalDescription/mods33:extent|//mods33:mods/mods33:physicalDescription/mods33:reformattingQuality|//mods33:mods/mods33:physicalDescription/mods33:internetMediaType|//mods33:mods/mods33:physicalDescription/mods33:digitalOrigin)$$,
+    TRUE, TRUE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    40, 'identifier', 'publisher', 
+    oils_i18n_gettext(40, 'Publisher', 'cmf', 'label'),
+    $$//mods33:mods/mods33:originInfo//mods33:publisher[1]$$,
+    TRUE, TRUE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    41, 'keyword', 'abstract', 
+    oils_i18n_gettext(41, 'Abstract', 'cmf', 'label'),
+    $$//mods33:mods/mods33:abstract$$,
+    TRUE, TRUE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    42, 'keyword', 'toc', 
+    oils_i18n_gettext(42, 'Table of Contents', 'cmf', 'label'),
+    $$//mods33:tableOfContents$$,
+    TRUE, TRUE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    43, 'identifier', 'type_of_resource', 
+    oils_i18n_gettext(43, 'Type of Resource', 'cmf', 'label'),
+    $$//mods33:mods/mods33:typeOfResource$$,
+    TRUE, FALSE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    44, 'identifier', 'pubdate', 
+    oils_i18n_gettext(44, 'Publication Date', 'cmf', 'label'),
+    $$//mods33:mods/mods33:originInfo//mods33:dateIssued[@encoding="marc"]|//mods33:mods/mods33:originInfo//mods33:dateIssued[1]$$,
+    TRUE, FALSE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, 
+    label, xpath, display_field, search_field, browse_field)
+VALUES (
+    46, 'keyword', 'bibliography', 
+    oils_i18n_gettext(46, 'Bibliography', 'cmf', 'label'),
+    $$//mods33:note[@type='bibliography']$$,
+    TRUE, TRUE, FALSE
+),(
+    47, 'keyword', 'thesis', 
+    oils_i18n_gettext(47, 'Thesis', 'cmf', 'label'),
+    $$//mods33:note[@type='thesis']$$,
+    TRUE, TRUE, FALSE
+),(
+    48, 'keyword', 'production_credits', 
+    oils_i18n_gettext(48, 'Creation/Production Credits', 'cmf', 'label'),
+    $$//mods33:note[@type='creation/production credits']$$,
+    TRUE, TRUE, FALSE
+),(
+    49, 'keyword', 'performers', 
+    oils_i18n_gettext(49, 'Performers', 'cmf', 'label'),
+    $$//mods33:note[@type='performers']$$,
+    TRUE, TRUE, FALSE
+),(
+    50, 'keyword', 'general_note', 
+    oils_i18n_gettext(50, 'General Note', 'cmf', 'label'),
+    $$//mods33:note[not(@type)]$$,
+    TRUE, TRUE, FALSE
+)
+;
+
+INSERT INTO config.metabib_field (id, field_class, name, format,
+    label, xpath, display_xpath, display_field, search_field, browse_field)
+VALUES (
+    51, 'author', 'first_author', 'mods32',
+    oils_i18n_gettext(51, 'Author', 'cmf', 'label'),
+    $$//mods32:mods/mods32:name[mods32:role/mods32:roleTerm[text()='creator']][1]$$,
+    $$//*[local-name()='namePart']$$,
+    TRUE, TRUE, FALSE
+);
+
+INSERT INTO config.metabib_field (id, field_class, name, format,
+    label, xpath, display_xpath, display_field, search_field, browse_field)
+VALUES (
+    52, 'identifier', 'origin_info', 'marcxml',
+    oils_i18n_gettext(52, 'Origin Info', 'cmf', 'label'),
+    $$//*[@tag='260']$$,
+    $$//*[local-name()='subfield' and contains('abc',@code)]$$,
+    TRUE, FALSE, FALSE
+);
+
+
+-- Modify existing config.metabib_field entries
+
+UPDATE config.metabib_field SET display_field = TRUE WHERE id IN (
+    1,  -- seriestitle
+    11, -- subject_geographic 
+    12, -- subject_name
+    13, -- subject_temporal
+    14, -- subject_topic
+    19, -- ISSN
+    20, -- UPC
+    26  -- TCN
+);
+
+-- Map display field names to config.metabib_field entries
+
+INSERT INTO config.display_field_map (name, field, multi) VALUES 
+    ('series_title',         1, TRUE),
+    ('subject_geographic',  11, TRUE),
+    ('subject_name',        12, TRUE),
+    ('subject_temporal',    13, TRUE),
+    ('subject_topic',       14, TRUE),
+    ('issn',                19, TRUE),
+    ('upc',                 20, TRUE),
+    ('tcn',                 26, FALSE),
+    ('edition',             38, FALSE),
+    ('physical_description',39, TRUE),
+    ('genre',               33, TRUE),
+    ('bibliography',        46, TRUE),
+    ('thesis',              47, TRUE),
+    ('performers',          49, TRUE),
+    ('production_credits',  48, TRUE),
+    ('general_note',        50, TRUE),
+    ('publisher',           52, FALSE),
+    ('abstract',            41, FALSE),
+    ('toc',                 42, FALSE),
+    ('type_of_resource',    43, FALSE),
+    ('pubdate',             44, FALSE)
+;
+
+UPDATE config.display_field_map SET field = 51 WHERE name = 'author';
+
+    END IF;                                                                    
+END $INSERT$;
+
+-- Add a column to wide-display-entry per well-known field
+
+DROP VIEW IF EXISTS metabib.wide_display_entry;
+CREATE VIEW metabib.wide_display_entry AS
+    SELECT 
+        bre.id AS source,
+        COALESCE(mcde_title.value, 'null')::TEXT AS title,
+        COALESCE(mcde_author.value, 'null')::TEXT AS author,
+        COALESCE(mcde_subject_geographic.value, 'null')::TEXT AS subject_geographic,
+        COALESCE(mcde_subject_name.value, 'null')::TEXT AS subject_name,
+        COALESCE(mcde_subject_temporal.value, 'null')::TEXT AS subject_temporal,
+        COALESCE(mcde_subject_topic.value, 'null')::TEXT AS subject_topic,
+        COALESCE(mcde_creators.value, 'null')::TEXT AS creators,
+        COALESCE(mcde_isbn.value, 'null')::TEXT AS isbn,
+        COALESCE(mcde_issn.value, 'null')::TEXT AS issn,
+        COALESCE(mcde_upc.value, 'null')::TEXT AS upc,
+        COALESCE(mcde_tcn.value, 'null')::TEXT AS tcn,
+        COALESCE(mcde_edition.value, 'null')::TEXT AS edition,
+        COALESCE(mcde_physical_description.value, 'null')::TEXT AS physical_description,
+        COALESCE(mcde_publisher.value, 'null')::TEXT AS publisher,
+        COALESCE(mcde_series_title.value, 'null')::TEXT AS series_title,
+        COALESCE(mcde_abstract.value, 'null')::TEXT AS abstract,
+        COALESCE(mcde_toc.value, 'null')::TEXT AS toc,
+        COALESCE(mcde_pubdate.value, 'null')::TEXT AS pubdate,
+        COALESCE(mcde_type_of_resource.value, 'null')::TEXT AS type_of_resource
+    FROM biblio.record_entry bre 
+    LEFT JOIN metabib.compressed_display_entry mcde_title 
+        ON (bre.id = mcde_title.source AND mcde_title.name = 'title')
+    LEFT JOIN metabib.compressed_display_entry mcde_author 
+        ON (bre.id = mcde_author.source AND mcde_author.name = 'author')
+    LEFT JOIN metabib.compressed_display_entry mcde_subject 
+        ON (bre.id = mcde_subject.source AND mcde_subject.name = 'subject')
+    LEFT JOIN metabib.compressed_display_entry mcde_subject_geographic 
+        ON (bre.id = mcde_subject_geographic.source 
+            AND mcde_subject_geographic.name = 'subject_geographic')
+    LEFT JOIN metabib.compressed_display_entry mcde_subject_name 
+        ON (bre.id = mcde_subject_name.source 
+            AND mcde_subject_name.name = 'subject_name')
+    LEFT JOIN metabib.compressed_display_entry mcde_subject_temporal 
+        ON (bre.id = mcde_subject_temporal.source 
+            AND mcde_subject_temporal.name = 'subject_temporal')
+    LEFT JOIN metabib.compressed_display_entry mcde_subject_topic 
+        ON (bre.id = mcde_subject_topic.source 
+            AND mcde_subject_topic.name = 'subject_topic')
+    LEFT JOIN metabib.compressed_display_entry mcde_creators 
+        ON (bre.id = mcde_creators.source AND mcde_creators.name = 'creators')
+    LEFT JOIN metabib.compressed_display_entry mcde_isbn 
+        ON (bre.id = mcde_isbn.source AND mcde_isbn.name = 'isbn')
+    LEFT JOIN metabib.compressed_display_entry mcde_issn 
+        ON (bre.id = mcde_issn.source AND mcde_issn.name = 'issn')
+    LEFT JOIN metabib.compressed_display_entry mcde_upc 
+        ON (bre.id = mcde_upc.source AND mcde_upc.name = 'upc')
+    LEFT JOIN metabib.compressed_display_entry mcde_tcn 
+        ON (bre.id = mcde_tcn.source AND mcde_tcn.name = 'tcn')
+    LEFT JOIN metabib.compressed_display_entry mcde_edition 
+        ON (bre.id = mcde_edition.source AND mcde_edition.name = 'edition')
+    LEFT JOIN metabib.compressed_display_entry mcde_physical_description 
+        ON (bre.id = mcde_physical_description.source 
+            AND mcde_physical_description.name = 'physical_description')
+    LEFT JOIN metabib.compressed_display_entry mcde_publisher 
+        ON (bre.id = mcde_publisher.source AND mcde_publisher.name = 'publisher')
+    LEFT JOIN metabib.compressed_display_entry mcde_series_title 
+        ON (bre.id = mcde_series_title.source AND mcde_series_title.name = 'series_title')
+    LEFT JOIN metabib.compressed_display_entry mcde_abstract 
+        ON (bre.id = mcde_abstract.source AND mcde_abstract.name = 'abstract')
+    LEFT JOIN metabib.compressed_display_entry mcde_toc 
+        ON (bre.id = mcde_toc.source AND mcde_toc.name = 'toc')
+    LEFT JOIN metabib.compressed_display_entry mcde_pubdate 
+        ON (bre.id = mcde_pubdate.source AND mcde_pubdate.name = 'pubdate')
+    LEFT JOIN metabib.compressed_display_entry mcde_type_of_resource 
+        ON (bre.id = mcde_type_of_resource.source 
+            AND mcde_type_of_resource.name = 'type_of_resource')
+;
+
+CREATE OR REPLACE VIEW reporter.old_super_simple_record AS
+SELECT  r.id,
+    r.fingerprint,
+    r.quality,
+    r.tcn_source,
+    r.tcn_value,
+    evergreen.oils_json_to_text(d.title) AS title,
+    evergreen.oils_json_to_text(d.author) AS author,
+    evergreen.oils_json_to_text(d.publisher) AS publisher,
+    evergreen.oils_json_to_text(d.pubdate) AS pubdate,
+    CASE WHEN d.isbn = 'null'
+        THEN NULL
+        ELSE (SELECT ARRAY(SELECT json_array_elements_text(d.isbn::JSON)))
+    END AS isbn,
+    CASE WHEN d.issn = 'null'
+        THEN NULL
+        ELSE (SELECT ARRAY(SELECT json_array_elements_text(d.issn::JSON)))
+    END AS issn
+  FROM  biblio.record_entry r
+        JOIN metabib.wide_display_entry d ON (r.id = d.source);
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1101', :eg_version);
+
+ALTER TABLE config.metabib_field ALTER COLUMN xpath DROP NOT NULL;
+
+CREATE TABLE config.metabib_field_virtual_map (
+    id      SERIAL  PRIMARY KEY,
+    real    INT NOT NULL REFERENCES config.metabib_field (id),
+    virtual INT NOT NULL REFERENCES config.metabib_field (id),
+    weight  INT NOT NULL DEFAULT 1
+);
+COMMENT ON TABLE config.metabib_field_virtual_map IS $$
+Maps between real (physically extracted) index definitions
+and virtual (target sync, no required extraction of its own)
+index definitions.
+
+The virtual side may not extract any data of its own, but
+will collect data from all of the real fields.  This reduces
+extraction (ingest) overhead by eliminating duplcated extraction,
+and allows for searching across novel combinations of fields, such
+as names used as either subjects or authors.  By preserving this
+mapping rather than defining duplicate extractions, information
+about the originating, "real" index definitions can be used
+in interesting ways, such as highlighting in search results.
+$$;
+
+CREATE OR REPLACE VIEW metabib.combined_all_field_entry AS
+    SELECT * FROM metabib.combined_title_field_entry
+        UNION ALL
+    SELECT * FROM metabib.combined_author_field_entry
+        UNION ALL
+    SELECT * FROM metabib.combined_subject_field_entry
+        UNION ALL
+    SELECT * FROM metabib.combined_keyword_field_entry
+        UNION ALL
+    SELECT * FROM metabib.combined_identifier_field_entry
+        UNION ALL
+    SELECT * FROM metabib.combined_series_field_entry;
+
+
+CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry (
+    rid BIGINT,
+    default_joiner TEXT,
+    field_types TEXT[],
+    only_fields INT[]
+) RETURNS SETOF metabib.field_entry_template AS $func$
+DECLARE
+    bib     biblio.record_entry%ROWTYPE;
+    idx     config.metabib_field%ROWTYPE;
+    xfrm        config.xml_transform%ROWTYPE;
+    prev_xfrm   TEXT;
+    transformed_xml TEXT;
+    xml_node    TEXT;
+    xml_node_list   TEXT[];
+    facet_text  TEXT;
+    display_text TEXT;
+    browse_text TEXT;
+    sort_value  TEXT;
+    raw_text    TEXT;
+    curr_text   TEXT;
+    joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
+    authority_text TEXT;
+    authority_link BIGINT;
+    output_row  metabib.field_entry_template%ROWTYPE;
+    process_idx BOOL;
+BEGIN
+
+    -- Start out with no field-use bools set
+    output_row.browse_field = FALSE;
+    output_row.facet_field = FALSE;
+    output_row.display_field = FALSE;
+    output_row.search_field = FALSE;
+
+    -- Get the record
+    SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
+
+    -- Loop over the indexing entries
+    FOR idx IN SELECT * FROM config.metabib_field WHERE id = ANY (only_fields) ORDER BY format LOOP
+        CONTINUE WHEN idx.xpath IS NULL OR idx.xpath = ''; -- pure virtual field
+
+        process_idx := FALSE;
+        IF idx.display_field AND 'display' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        IF idx.browse_field AND 'browse' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        IF idx.search_field AND 'search' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        IF idx.facet_field AND 'facet' = ANY (field_types) THEN process_idx = TRUE; END IF;
+        CONTINUE WHEN process_idx = FALSE; -- disabled for all types
+
+        joiner := COALESCE(idx.joiner, default_joiner);
+
+        SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
+
+        -- See if we can skip the XSLT ... it's expensive
+        IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+            -- Can't skip the transform
+            IF xfrm.xslt <> '---' THEN
+                transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
+            ELSE
+                transformed_xml := bib.marc;
+            END IF;
+
+            prev_xfrm := xfrm.name;
+        END IF;
+
+        xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+
+        raw_text := NULL;
+        FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
+            CONTINUE WHEN xml_node !~ E'^\\s*<';
+
+            -- XXX much of this should be moved into oils_xpath_string...
+            curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
+                oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
+                    REGEXP_REPLACE( xml_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
+                ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
+                joiner
+            );
+
+            CONTINUE WHEN curr_text IS NULL OR curr_text = '';
+
+            IF raw_text IS NOT NULL THEN
+                raw_text := raw_text || joiner;
+            END IF;
+
+            raw_text := COALESCE(raw_text,'') || curr_text;
+
+            -- autosuggest/metabib.browse_entry
+            IF idx.browse_field THEN
+
+                IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
+                    browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+                ELSE
+                    browse_text := curr_text;
+                END IF;
+
+                IF idx.browse_sort_xpath IS NOT NULL AND
+                    idx.browse_sort_xpath <> '' THEN
+
+                    sort_value := oils_xpath_string(
+                        idx.browse_sort_xpath, xml_node, joiner,
+                        ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
+                    );
+                ELSE
+                    sort_value := browse_text;
+                END IF;
+
+                output_row.field_class = idx.field_class;
+                output_row.field = idx.id;
+                output_row.source = rid;
+                output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
+                output_row.sort_value :=
+                    public.naco_normalize(sort_value);
+
+                output_row.authority := NULL;
+
+                IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
+                    authority_text := oils_xpath_string(
+                        idx.authority_xpath, xml_node, joiner,
+                        ARRAY[
+                            ARRAY[xfrm.prefix, xfrm.namespace_uri],
+                            ARRAY['xlink','http://www.w3.org/1999/xlink']
+                        ]
+                    );
+
+                    IF authority_text ~ '^\d+$' THEN
+                        authority_link := authority_text::BIGINT;
+                        PERFORM * FROM authority.record_entry WHERE id = authority_link;
+                        IF FOUND THEN
+                            output_row.authority := authority_link;
+                        END IF;
+                    END IF;
+
+                END IF;
+
+                output_row.browse_field = TRUE;
+                -- Returning browse rows with search_field = true for search+browse
+                -- configs allows us to retain granularity of being able to search
+                -- browse fields with "starts with" type operators (for example, for
+                -- titles of songs in music albums)
+                IF idx.search_field THEN
+                    output_row.search_field = TRUE;
+                END IF;
+                RETURN NEXT output_row;
+                output_row.browse_field = FALSE;
+                output_row.search_field = FALSE;
+                output_row.sort_value := NULL;
+            END IF;
+
+            -- insert raw node text for faceting
+            IF idx.facet_field THEN
+
+                IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
+                    facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+                ELSE
+                    facet_text := curr_text;
+                END IF;
+
+                output_row.field_class = idx.field_class;
+                output_row.field = -1 * idx.id;
+                output_row.source = rid;
+                output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
+
+                output_row.facet_field = TRUE;
+                RETURN NEXT output_row;
+                output_row.facet_field = FALSE;
+            END IF;
+
+            -- insert raw node text for display
+            IF idx.display_field THEN
+
+                IF idx.display_xpath IS NOT NULL AND idx.display_xpath <> '' THEN
+                    display_text := oils_xpath_string( idx.display_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
+                ELSE
+                    display_text := curr_text;
+                END IF;
+
+                output_row.field_class = idx.field_class;
+                output_row.field = -1 * idx.id;
+                output_row.source = rid;
+                output_row.value = BTRIM(REGEXP_REPLACE(display_text, E'\\s+', ' ', 'g'));
+
+                output_row.display_field = TRUE;
+                RETURN NEXT output_row;
+                output_row.display_field = FALSE;
+            END IF;
+
+        END LOOP;
+
+        CONTINUE WHEN raw_text IS NULL OR raw_text = '';
+
+        -- insert combined node text for searching
+        IF idx.search_field THEN
+            output_row.field_class = idx.field_class;
+            output_row.field = idx.id;
+            output_row.source = rid;
+            output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
+
+            output_row.search_field = TRUE;
+            RETURN NEXT output_row;
+            output_row.search_field = FALSE;
+        END IF;
+
+    END LOOP;
+
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION metabib.update_combined_index_vectors(bib_id BIGINT) RETURNS VOID AS $func$
+DECLARE
+    rdata       TSVECTOR;
+    vclass      TEXT;
+    vfield      INT;
+    rfields     INT[];
+BEGIN
+    DELETE FROM metabib.combined_keyword_field_entry WHERE record = bib_id;
+    INSERT INTO metabib.combined_keyword_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.keyword_field_entry WHERE source = bib_id GROUP BY field;
+    INSERT INTO metabib.combined_keyword_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.keyword_field_entry WHERE source = bib_id;
+
+    DELETE FROM metabib.combined_title_field_entry WHERE record = bib_id;
+    INSERT INTO metabib.combined_title_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.title_field_entry WHERE source = bib_id GROUP BY field;
+    INSERT INTO metabib.combined_title_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.title_field_entry WHERE source = bib_id;
+
+    DELETE FROM metabib.combined_author_field_entry WHERE record = bib_id;
+    INSERT INTO metabib.combined_author_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.author_field_entry WHERE source = bib_id GROUP BY field;
+    INSERT INTO metabib.combined_author_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.author_field_entry WHERE source = bib_id;
+
+    DELETE FROM metabib.combined_subject_field_entry WHERE record = bib_id;
+    INSERT INTO metabib.combined_subject_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.subject_field_entry WHERE source = bib_id GROUP BY field;
+    INSERT INTO metabib.combined_subject_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.subject_field_entry WHERE source = bib_id;
+
+    DELETE FROM metabib.combined_series_field_entry WHERE record = bib_id;
+    INSERT INTO metabib.combined_series_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.series_field_entry WHERE source = bib_id GROUP BY field;
+    INSERT INTO metabib.combined_series_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.series_field_entry WHERE source = bib_id;
+
+    DELETE FROM metabib.combined_identifier_field_entry WHERE record = bib_id;
+    INSERT INTO metabib.combined_identifier_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.identifier_field_entry WHERE source = bib_id GROUP BY field;
+    INSERT INTO metabib.combined_identifier_field_entry(record, metabib_field, index_vector)
+        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
+        FROM metabib.identifier_field_entry WHERE source = bib_id;
+
+    -- For each virtual def, gather the data from the combined real field
+    -- entries and append it to the virtual combined entry.
+    FOR vfield, rfields IN SELECT virtual, ARRAY_AGG(real)  FROM config.metabib_field_virtual_map GROUP BY virtual LOOP
+        SELECT  field_class INTO vclass
+          FROM  config.metabib_field
+          WHERE id = vfield;
+
+        SELECT  string_agg(index_vector::TEXT,' ')::tsvector INTO rdata
+          FROM  metabib.combined_all_field_entry
+          WHERE record = bib_id
+                AND metabib_field = ANY (rfields);
+
+        BEGIN -- I cannot wait for INSERT ON CONFLICT ... 9.5, though
+            EXECUTE $$
+                INSERT INTO metabib.combined_$$ || vclass || $$_field_entry
+                    (record, metabib_field, index_vector) VALUES ($1, $2, $3)
+            $$ USING bib_id, vfield, rdata;
+        EXCEPTION WHEN unique_violation THEN
+            EXECUTE $$
+                UPDATE  metabib.combined_$$ || vclass || $$_field_entry
+                  SET   index_vector = index_vector || $3
+                  WHERE record = $1
+                        AND metabib_field = $2
+            $$ USING bib_id, vfield, rdata;
+        WHEN OTHERS THEN
+            -- ignore and move on
+        END;
+    END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE VIEW search.best_tsconfig AS
+    SELECT  m.id AS id,
+            COALESCE(f.ts_config, c.ts_config, 'simple') AS ts_config
+      FROM  config.metabib_field m
+            LEFT JOIN config.metabib_class_ts_map c ON (c.field_class = m.field_class AND c.index_weight = 'C')
+            LEFT JOIN config.metabib_field_ts_map f ON (f.metabib_field = m.id AND f.index_weight = 'C');
+
+CREATE TYPE search.highlight_result AS ( id BIGINT, source BIGINT, field INT, value TEXT, highlight TEXT );
+
+CREATE OR REPLACE FUNCTION search.highlight_display_fields_impl(
+    rid         BIGINT,
+    tsq         TEXT,
+    field_list  INT[] DEFAULT '{}'::INT[],
+    css_class   TEXT DEFAULT 'oils_SH',
+    hl_all      BOOL DEFAULT TRUE,
+    minwords    INT DEFAULT 5,
+    maxwords    INT DEFAULT 25,
+    shortwords  INT DEFAULT 0,
+    maxfrags    INT DEFAULT 0,
+    delimiter   TEXT DEFAULT ' ... '
+) RETURNS SETOF search.highlight_result AS $f$
+DECLARE
+    opts            TEXT := '';
+    v_css_class     TEXT := css_class;
+    v_delimiter     TEXT := delimiter;
+    v_field_list    INT[] := field_list;
+    hl_query        TEXT;
+BEGIN
+    IF v_delimiter LIKE $$%'%$$ OR v_delimiter LIKE '%"%' THEN --"
+        v_delimiter := ' ... ';
+    END IF;
+
+    IF NOT hl_all THEN
+        opts := opts || 'MinWords=' || minwords;
+        opts := opts || ', MaxWords=' || maxwords;
+        opts := opts || ', ShortWords=' || shortwords;
+        opts := opts || ', MaxFragments=' || maxfrags;
+        opts := opts || ', FragmentDelimiter="' || delimiter || '"';
+    ELSE
+        opts := opts || 'HighlightAll=TRUE';
+    END IF;
+
+    IF v_css_class LIKE $$%'%$$ OR v_css_class LIKE '%"%' THEN -- "
+        v_css_class := 'oils_SH';
+    END IF;
+
+    opts := opts || $$, StopSel=</b>, StartSel="<b class='$$ || v_css_class; -- "
+
+    IF v_field_list = '{}'::INT[] THEN
+        SELECT ARRAY_AGG(id) INTO v_field_list FROM config.metabib_field WHERE display_field;
+    END IF;
+
+    hl_query := $$
+        SELECT  de.id,
+                de.source,
+                de.field,
+                de.value AS value,
+                ts_headline(
+                    ts_config::REGCONFIG,
+                    evergreen.escape_for_html(de.value),
+                    $$ || quote_literal(tsq) || $$,
+                    $1 || ' ' || mf.field_class || ' ' || mf.name || $xx$'>"$xx$ -- "'
+                ) AS highlight
+          FROM  metabib.display_entry de
+                JOIN config.metabib_field mf ON (mf.id = de.field)
+                JOIN search.best_tsconfig t ON (t.id = de.field)
+          WHERE de.source = $2
+                AND field = ANY ($3)
+          ORDER BY de.id;$$;
+
+    RETURN QUERY EXECUTE hl_query USING opts, rid, v_field_list;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION evergreen.escape_for_html (TEXT) RETURNS TEXT AS $$
+    SELECT  regexp_replace(
+                regexp_replace(
+                    regexp_replace(
+                        $1,
+                        '&',
+                        '&amp;',
+                        'g'
+                    ),
+                    '<',
+                    '&lt;',
+                    'g'
+                ),
+                '>',
+                '&gt;',
+                'g'
+            );
+$$ LANGUAGE SQL IMMUTABLE LEAKPROOF STRICT COST 10;
+
+CREATE OR REPLACE FUNCTION search.highlight_display_fields(
+    rid         BIGINT,
+    tsq_map     TEXT, -- { '(a | b) & c' => '1,2,3,4', ...}
+    css_class   TEXT DEFAULT 'oils_SH',
+    hl_all      BOOL DEFAULT TRUE,
+    minwords    INT DEFAULT 5,
+    maxwords    INT DEFAULT 25,
+    shortwords  INT DEFAULT 0,
+    maxfrags    INT DEFAULT 0,
+    delimiter   TEXT DEFAULT ' ... '
+) RETURNS SETOF search.highlight_result AS $f$
+DECLARE
+    tsq_hstore  HSTORE;
+    tsq         TEXT;
+    fields      TEXT;
+    afields     INT[];
+    seen        INT[];
+BEGIN
+
+    IF (tsq_map ILIKE 'hstore%') THEN
+        EXECUTE 'SELECT ' || tsq_map INTO tsq_hstore;
+    ELSE
+        tsq_hstore := tsq_map::HSTORE;
+    END IF;
+    
+    FOR tsq, fields IN SELECT key, value FROM each(tsq_hstore::HSTORE) LOOP
+        SELECT  ARRAY_AGG(unnest::INT) INTO afields
+          FROM  unnest(regexp_split_to_array(fields,','));
+        seen := seen || afields;
+
+        RETURN QUERY
+            SELECT * FROM search.highlight_display_fields_impl(
+                rid, tsq, afields, css_class, hl_all,minwords,
+                maxwords, shortwords, maxfrags, delimiter
+            );
+    END LOOP;
+
+    RETURN QUERY
+        SELECT  id,
+                source,
+                field,
+                value,
+                value AS highlight
+          FROM  metabib.display_entry
+          WHERE source = rid
+                AND NOT (field = ANY (seen));
+END;
+$f$ LANGUAGE PLPGSQL ROWS 10;
+CREATE OR REPLACE FUNCTION metabib.remap_metarecord_for_bib(
+    bib_id bigint,
+    fp text,
+    bib_is_deleted boolean DEFAULT false,
+    retain_deleted boolean DEFAULT false
+) RETURNS bigint AS $function$
+DECLARE
+    new_mapping     BOOL := TRUE;
+    source_count    INT;
+    old_mr          BIGINT;
+    tmp_mr          metabib.metarecord%ROWTYPE;
+    deleted_mrs     BIGINT[];
+BEGIN
+
+    -- We need to make sure we're not a deleted master record of an MR
+    IF bib_is_deleted THEN
+        IF NOT retain_deleted THEN -- Go away for any MR that we're master of, unless retained
+            DELETE FROM metabib.metarecord_source_map WHERE source = bib_id;
+        END IF;
+
+        FOR old_mr IN SELECT id FROM metabib.metarecord WHERE master_record = bib_id LOOP
+
+            -- Now, are there any more sources on this MR?
+            SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = old_mr;
+
+            IF source_count = 0 AND NOT retain_deleted THEN -- No other records
+                deleted_mrs := ARRAY_APPEND(deleted_mrs, old_mr); -- Just in case...
+                DELETE FROM metabib.metarecord WHERE id = old_mr;
+
+            ELSE -- indeed there are. Update it with a null cache and recalcualated master record
+                UPDATE  metabib.metarecord
+                  SET   mods = NULL,
+                        master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC LIMIT 1)
+                  WHERE id = old_mr;
+            END IF;
+        END LOOP;
+
+    ELSE -- insert or update
+
+        FOR tmp_mr IN SELECT m.* FROM metabib.metarecord m JOIN metabib.metarecord_source_map s ON (s.metarecord = m.id) WHERE s.source = bib_id LOOP
+
+            -- Find the first fingerprint-matching
+            IF old_mr IS NULL AND fp = tmp_mr.fingerprint THEN
+                old_mr := tmp_mr.id;
+                new_mapping := FALSE;
+
+            ELSE -- Our fingerprint changed ... maybe remove the old MR
+                DELETE FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id AND source = bib_id; -- remove the old source mapping
+                SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id;
+                IF source_count = 0 THEN -- No other records
+                    deleted_mrs := ARRAY_APPEND(deleted_mrs, tmp_mr.id);
+                    DELETE FROM metabib.metarecord WHERE id = tmp_mr.id;
+                END IF;
+            END IF;
+
+        END LOOP;
+
+        -- we found no suitable, preexisting MR based on old source maps
+        IF old_mr IS NULL THEN
+            SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp; -- is there one for our current fingerprint?
+
+            IF old_mr IS NULL THEN -- nope, create one and grab its id
+                INSERT INTO metabib.metarecord ( fingerprint, master_record ) VALUES ( fp, bib_id );
+                SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp;
+
+            ELSE -- indeed there is. update it with a null cache and recalcualated master record
+                UPDATE  metabib.metarecord
+                  SET   mods = NULL,
+                        master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC LIMIT 1)
+                  WHERE id = old_mr;
+            END IF;
+
+        ELSE -- there was one we already attached to, update its mods cache and master_record
+            UPDATE  metabib.metarecord
+              SET   mods = NULL,
+                    master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC LIMIT 1)
+              WHERE id = old_mr;
+        END IF;
+
+        IF new_mapping THEN
+            INSERT INTO metabib.metarecord_source_map (metarecord, source) VALUES (old_mr, bib_id); -- new source mapping
+        END IF;
+
+    END IF;
+
+    IF ARRAY_UPPER(deleted_mrs,1) > 0 THEN
+        UPDATE action.hold_request SET target = old_mr WHERE target IN ( SELECT unnest(deleted_mrs) ) AND hold_type = 'M'; -- if we had to delete any MRs above, make sure their holds are moved
+    END IF;
+
+    RETURN old_mr;
+
+END;
+$function$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION evergreen.marc_to (marc text, xfrm text) RETURNS TEXT AS $$
+    SELECT evergreen.xml_pretty_print(xslt_process($1,xslt)::XML)::TEXT FROM config.xml_transform WHERE name = $2;
+$$ LANGUAGE SQL;
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1102', :eg_version);
+
+update config.xml_transform set xslt = $XXXX$<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc" version="1.0">
+        <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
+<!--
+Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements
+  with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
+
+Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28 tmee
+
+Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11 tmee
+
+Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>
+      2006/04/08  jrad
+
+Revision 1.10 MODS 3.1 revisions to language and classification elements
+                                (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)
+                                2006/02/06  ggar
+
+Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
+
+Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
+
+Revision 1.7 2004/03/25 08:29 jrad
+
+Revision 1.6 various validation fixes 2004/02/20 ntra
+
+Revision 1.5  2003/10/02 16:18:58  ntra
+MODS2 to MODS3 updates, language unstacking and
+de-duping, chopPunctuation expanded
+
+Revision 1.3  2003/04/03 00:07:19  ntra
+Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
+
+Revision 1.2  2003/03/24 19:37:42  ckeith
+Added Log Comment
+
+-->
+        <xsl:template match="/">
+                <xsl:choose>
+                        <xsl:when test="//marc:collection">
+                                <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
+                                        <xsl:for-each select="//marc:collection/marc:record">
+                                                <mods version="3.2">
+                                                        <xsl:call-template name="marcRecord"/>
+                                                </mods>
+                                        </xsl:for-each>
+                                </modsCollection>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
+                                        <xsl:for-each select="//marc:record">
+                                                <xsl:call-template name="marcRecord"/>
+                                        </xsl:for-each>
+                                </mods>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="marcRecord">
+                <xsl:variable name="leader" select="marc:leader"/>
+                <xsl:variable name="leader6" select="substring($leader,7,1)"/>
+                <xsl:variable name="leader7" select="substring($leader,8,1)"/>
+                <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
+                <xsl:variable name="typeOf008">
+                        <xsl:choose>
+                                <xsl:when test="$leader6='a'">
+                                        <xsl:choose>
+                                                <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
+                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
+                                        </xsl:choose>
+                                </xsl:when>
+                                <xsl:when test="$leader6='t'">BK</xsl:when>
+                                <xsl:when test="$leader6='p'">MM</xsl:when>
+                                <xsl:when test="$leader6='m'">CF</xsl:when>
+                                <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
+                                <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
+                                <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:for-each select="marc:datafield[@tag='245']">
+                        <titleInfo>
+                                <xsl:variable name="title">
+                                        <xsl:choose>
+                                                <xsl:when test="marc:subfield[@code='b']">
+                                                        <xsl:call-template name="specialSubfieldSelect">
+                                                                <xsl:with-param name="axis">b</xsl:with-param>
+                                                                <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:when>
+                                                <xsl:otherwise>
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:otherwise>
+                                        </xsl:choose>
+                                </xsl:variable>
+                                <xsl:variable name="titleChop">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="$title"/>
+                                                </xsl:with-param>
+                                                <xsl:with-param name="punctuation">
+                                                    <xsl:text>,;/ </xsl:text>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:variable>
+                                <xsl:choose>
+                                        <xsl:when test="@ind2>0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+                                                </title>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleChop"/>
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:if test="marc:subfield[@code='b']">
+                                        <subTitle>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="axis">b</xsl:with-param>
+                                                                        <xsl:with-param name="anyCodes">b</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">afgk</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </subTitle>
+                                </xsl:if>
+                                <xsl:call-template name="part"></xsl:call-template>
+                        </titleInfo>
+                        <!-- A form of title that ignores non-filing characters; useful
+                                 for not converting "L'Oreal" into "L' Oreal" at index time -->
+                        <titleNonfiling>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="part"></xsl:call-template>
+                        </titleNonfiling>
+                        <!-- hybrid of titleInfo and titleNonfiling which will give us a preformatted string (for punctuation)
+                                 but also keep the nonSort stuff in a separate field (for sorting) -->
+                        <titleBrowse>
+                                <xsl:variable name="titleBrowseChop">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:variable>
+                                <xsl:choose>
+                                        <xsl:when test="@ind2>0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleBrowseChop,1,@ind2)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleBrowseChop,@ind2+1)"/>
+                                                </title>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleBrowseChop"/>
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:call-template name="part"></xsl:call-template>
+                        </titleBrowse>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='210']">
+                        <titleInfo type="abbreviated">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">a</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="subtitle"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='242']">
+                        <xsl:variable name="titleChop">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <!-- 1/04 removed $h, b -->
+                                                        <xsl:with-param name="codes">a</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:variable>
+                        <titleInfo type="translated">
+                                <!--09/01/04 Added subfield $y-->
+                                <xsl:for-each select="marc:subfield[@code='y']">
+                                        <xsl:attribute name="lang">
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:attribute>
+                                </xsl:for-each>
+                                <title>
+                                        <xsl:value-of select="$titleChop" />
+                                </title>
+                                <!-- 1/04 fix -->
+                                <xsl:call-template name="subtitle"/>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                        <titleInfo type="translated-nfi">
+                                <xsl:for-each select="marc:subfield[@code='y']">
+                                        <xsl:attribute name="lang">
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:attribute>
+                                </xsl:for-each>
+                                <xsl:choose>
+                                        <xsl:when test="@ind2>0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+                                                </title>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleChop" />
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:call-template name="subtitle"/>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='246']">
+                        <titleInfo type="alternative">
+                                <xsl:for-each select="marc:subfield[@code='i']">
+                                        <xsl:attribute name="displayLabel">
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:attribute>
+                                </xsl:for-each>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <!-- 1/04 removed $h, $b -->
+                                                                <xsl:with-param name="codes">af</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="subtitle"/>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
+                        <xsl:variable name="nfi">
+                                <xsl:choose>
+                                        <xsl:when test="@tag='240'">
+                                                <xsl:value-of select="@ind2"/>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <xsl:value-of select="@ind1"/>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </xsl:variable>
+                        <xsl:variable name="titleChop">
+                                <xsl:call-template name="uri" />
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield">
+                                                <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
+                                                        <xsl:value-of select="text()"/>
+                                                        <xsl:text> </xsl:text>
+                                                </xsl:if>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:variable>
+                        <titleInfo type="uniform">
+                                <title>
+                                        <xsl:value-of select="$titleChop"/>
+                                </title>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                        <titleInfo type="uniform-nfi">
+                                <xsl:choose>
+                                        <xsl:when test="$nfi>0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleChop,1,$nfi)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleChop,$nfi+1)"/>
+                                                </title>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleChop"/>
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
+                        <xsl:variable name="titleChop">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">ah</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:variable>
+                        <titleInfo type="alternative">
+                                <title>
+                                        <xsl:value-of select="$titleChop" />
+                                </title>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                        <titleInfo type="alternative-nfi">
+                                <xsl:choose>
+                                        <xsl:when test="@ind1>0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleChop,1,@ind1)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleChop,@ind1+1)"/>
+                                                </title>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleChop" />
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='100']">
+                        <name type="personal">
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="nameABCDQ"/>
+                                <xsl:call-template name="affiliation"/>
+                                <role>
+                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+                                </role>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='110']">
+                        <name type="corporate">
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="nameABCDN"/>
+                                <role>
+                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+                                </role>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='111']">
+                        <name type="conference">
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="nameACDEQ"/>
+                                <role>
+                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+                                </role>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
+                        <name type="personal">
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="nameABCDQ"/>
+                                <xsl:call-template name="affiliation"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
+                        <name type="corporate">
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="nameABCDN"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
+                        <name type="conference">
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="nameACDEQ"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
+                        <name>
+                                <xsl:if test="@ind1=1">
+                                        <xsl:attribute name="type">
+                                                <xsl:text>personal</xsl:text>
+                                        </xsl:attribute>
+                                </xsl:if>
+                                <namePart>
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </namePart>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <typeOfResource>
+                        <xsl:if test="$leader7='c'">
+                                <xsl:attribute name="collection">yes</xsl:attribute>
+                        </xsl:if>
+                        <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
+                                <xsl:attribute name="manuscript">yes</xsl:attribute>
+                        </xsl:if>
+                        <xsl:choose>
+                                <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
+                                <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
+                                <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
+                                <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
+                                <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
+                                <xsl:when test="$leader6='k'">still image</xsl:when>
+                                <xsl:when test="$leader6='g'">moving image</xsl:when>
+                                <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
+                                <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
+                                <xsl:when test="$leader6='p'">mixed material</xsl:when>
+                        </xsl:choose>
+                </typeOfResource>
+                <xsl:if test="substring($controlField008,26,1)='d'">
+                        <genre authority="marc">globe</genre>
+                </xsl:if>
+                <xsl:if test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
+                        <genre authority="marc">remote sensing image</genre>
+                </xsl:if>
+                <xsl:if test="$typeOf008='MP'">
+                        <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
+                                        <genre authority="marc">map</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
+                                        <genre authority="marc">atlas</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='SE'">
+                        <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-21='d'">
+                                        <genre authority="marc">database</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='l'">
+                                        <genre authority="marc">loose-leaf</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='m'">
+                                        <genre authority="marc">series</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='n'">
+                                        <genre authority="marc">newspaper</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='p'">
+                                        <genre authority="marc">periodical</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='w'">
+                                        <genre authority="marc">web site</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
+                        <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="contains($controlField008-24,'a')">
+                                        <genre authority="marc">abstract or summary</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'b')">
+                                        <genre authority="marc">bibliography</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'c')">
+                                        <genre authority="marc">catalog</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'d')">
+                                        <genre authority="marc">dictionary</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'e')">
+                                        <genre authority="marc">encyclopedia</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'f')">
+                                        <genre authority="marc">handbook</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'g')">
+                                        <genre authority="marc">legal article</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'i')">
+                                        <genre authority="marc">index</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'k')">
+                                        <genre authority="marc">discography</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'l')">
+                                        <genre authority="marc">legislation</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'m')">
+                                        <genre authority="marc">theses</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'n')">
+                                        <genre authority="marc">survey of literature</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'o')">
+                                        <genre authority="marc">review</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'p')">
+                                        <genre authority="marc">programmed text</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'q')">
+                                        <genre authority="marc">filmography</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'r')">
+                                        <genre authority="marc">directory</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'s')">
+                                        <genre authority="marc">statistics</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'t')">
+                                        <genre authority="marc">technical report</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'v')">
+                                        <genre authority="marc">legal case and case notes</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'w')">
+                                        <genre authority="marc">law report or digest</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'z')">
+                                        <genre authority="marc">treaty</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-29='1'">
+                                        <genre authority="marc">conference publication</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='CF'">
+                        <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-26='a'">
+                                        <genre authority="marc">numeric data</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-26='e'">
+                                        <genre authority="marc">database</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-26='f'">
+                                        <genre authority="marc">font</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-26='g'">
+                                        <genre authority="marc">game</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='BK'">
+                        <xsl:if test="substring($controlField008,25,1)='j'">
+                                <genre authority="marc">patent</genre>
+                        </xsl:if>
+                        <xsl:if test="substring($controlField008,31,1)='1'">
+                                <genre authority="marc">festschrift</genre>
+                        </xsl:if>
+                        <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"></xsl:variable>
+                        <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
+                                <genre authority="marc">biography</genre>
+                        </xsl:if>
+                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-33='e'">
+                                        <genre authority="marc">essay</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='d'">
+                                        <genre authority="marc">drama</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='c'">
+                                        <genre authority="marc">comic strip</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='l'">
+                                        <genre authority="marc">fiction</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='h'">
+                                        <genre authority="marc">humor, satire</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='i'">
+                                        <genre authority="marc">letter</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='f'">
+                                        <genre authority="marc">novel</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='j'">
+                                        <genre authority="marc">short story</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='s'">
+                                        <genre authority="marc">speech</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='MU'">
+                        <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"></xsl:variable>
+                        <xsl:if test="contains($controlField008-30-31,'b')">
+                                <genre authority="marc">biography</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'c')">
+                                <genre authority="marc">conference publication</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'d')">
+                                <genre authority="marc">drama</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'e')">
+                                <genre authority="marc">essay</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'f')">
+                                <genre authority="marc">fiction</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'o')">
+                                <genre authority="marc">folktale</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'h')">
+                                <genre authority="marc">history</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'k')">
+                                <genre authority="marc">humor, satire</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'m')">
+                                <genre authority="marc">memoir</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'p')">
+                                <genre authority="marc">poetry</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'r')">
+                                <genre authority="marc">rehearsal</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'g')">
+                                <genre authority="marc">reporting</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'s')">
+                                <genre authority="marc">sound</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'l')">
+                                <genre authority="marc">speech</genre>
+                        </xsl:if>
+                </xsl:if>
+                <xsl:if test="$typeOf008='VM'">
+                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-33='a'">
+                                        <genre authority="marc">art original</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='b'">
+                                        <genre authority="marc">kit</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='c'">
+                                        <genre authority="marc">art reproduction</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='d'">
+                                        <genre authority="marc">diorama</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='f'">
+                                        <genre authority="marc">filmstrip</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='g'">
+                                        <genre authority="marc">legal article</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='i'">
+                                        <genre authority="marc">picture</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='k'">
+                                        <genre authority="marc">graphic</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='l'">
+                                        <genre authority="marc">technical drawing</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='m'">
+                                        <genre authority="marc">motion picture</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='n'">
+                                        <genre authority="marc">chart</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='o'">
+                                        <genre authority="marc">flash card</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='p'">
+                                        <genre authority="marc">microscope slide</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
+                                        <genre authority="marc">model</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='r'">
+                                        <genre authority="marc">realia</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='s'">
+                                        <genre authority="marc">slide</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='t'">
+                                        <genre authority="marc">transparency</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='v'">
+                                        <genre authority="marc">videorecording</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='w'">
+                                        <genre authority="marc">toy</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=655]">
+                        <genre authority="marc">
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"/>
+                                </xsl:attribute>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abvxyz</xsl:with-param>
+                                        <xsl:with-param name="delimeter">-</xsl:with-param>
+                                </xsl:call-template>
+                        </genre>
+                </xsl:for-each>
+                <originInfo>
+                        <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"></xsl:variable>
+                        <xsl:if test="translate($MARCpublicationCode,'|','')">
+                                <place>
+                                        <placeTerm>
+                                                <xsl:attribute name="type">code</xsl:attribute>
+                                                <xsl:attribute name="authority">marccountry</xsl:attribute>
+                                                <xsl:value-of select="$MARCpublicationCode"/>
+                                        </placeTerm>
+                                </place>
+                        </xsl:if>
+                        <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
+                                <place>
+                                        <placeTerm>
+                                                <xsl:attribute name="type">code</xsl:attribute>
+                                                <xsl:attribute name="authority">iso3166</xsl:attribute>
+                                                <xsl:value-of select="."/>
+                                        </placeTerm>
+                                </place>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
+                                <place>
+                                        <placeTerm>
+                                                <xsl:attribute name="type">text</xsl:attribute>
+                                                <xsl:call-template name="chopPunctuationFront">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="chopPunctuation">
+                                                                        <xsl:with-param name="chopString" select="."/>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </placeTerm>
+                                </place>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
+                                <dateValid point="start">
+                                        <xsl:value-of select="."/>
+                                </dateValid>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
+                                <dateValid point="end">
+                                        <xsl:value-of select="."/>
+                                </dateValid>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
+                                <dateModified>
+                                        <xsl:value-of select="."/>
+                                </dateModified>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
+                                <xsl:choose>
+                                        <xsl:when test="@code='b'">
+                                                <publisher>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                                <xsl:with-param name="punctuation">
+                                                                        <xsl:text>:,;/ </xsl:text>
+                                                                </xsl:with-param>
+                                                        </xsl:call-template>
+                                                </publisher>
+                                        </xsl:when>
+                                        <xsl:when test="@code='c'">
+                                                <dateIssued>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </dateIssued>
+                                        </xsl:when>
+                                        <xsl:when test="@code='g'">
+                                                <dateCreated>
+                                                        <xsl:value-of select="."/>
+                                                </dateCreated>
+                                        </xsl:when>
+                                </xsl:choose>
+                        </xsl:for-each>
+                        <xsl:variable name="dataField260c">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"></xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:variable>
+                        <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"></xsl:variable>
+                        <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"></xsl:variable>
+                        <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"></xsl:variable>
+                        <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
+                                <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
+                                        <dateIssued encoding="marc">
+                                                <xsl:value-of select="$controlField008-7-10"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+                                <xsl:if test="$controlField008-7-10">
+                                        <dateIssued encoding="marc" point="start">
+                                                <xsl:value-of select="$controlField008-7-10"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+                                <xsl:if test="$controlField008-11-14">
+                                        <dateIssued encoding="marc" point="end">
+                                                <xsl:value-of select="$controlField008-11-14"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='q'">
+                                <xsl:if test="$controlField008-7-10">
+                                        <dateIssued encoding="marc" point="start" qualifier="questionable">
+                                                <xsl:value-of select="$controlField008-7-10"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='q'">
+                                <xsl:if test="$controlField008-11-14">
+                                        <dateIssued encoding="marc" point="end" qualifier="questionable">
+                                                <xsl:value-of select="$controlField008-11-14"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='t'">
+                                <xsl:if test="$controlField008-11-14">
+                                        <copyrightDate encoding="marc">
+                                                <xsl:value-of select="$controlField008-11-14"/>
+                                        </copyrightDate>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
+                                <dateCaptured encoding="iso8601">
+                                        <xsl:value-of select="."/>
+                                </dateCaptured>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
+                                <dateCaptured encoding="iso8601" point="start">
+                                        <xsl:value-of select="."/>
+                                </dateCaptured>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
+                                <dateCaptured encoding="iso8601" point="end">
+                                        <xsl:value-of select="."/>
+                                </dateCaptured>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
+                                <edition>
+                                        <xsl:value-of select="."/>
+                                </edition>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:leader">
+                                <issuance>
+                                        <xsl:choose>
+                                                <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
+                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
+                                        </xsl:choose>
+                                </issuance>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
+                                <frequency>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">ab</xsl:with-param>
+                                        </xsl:call-template>
+                                </frequency>
+                        </xsl:for-each>
+                </originInfo>
+                <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"></xsl:variable>
+                <xsl:if test="$controlField008-35-37">
+                        <language>
+                                <languageTerm authority="iso639-2b" type="code">
+                                        <xsl:value-of select="substring($controlField008,36,3)"/>
+                                </languageTerm>
+                        </language>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=041]">
+                        <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
+                                <xsl:variable name="langCodes" select="."/>
+                                <xsl:choose>
+                                        <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
+                                                <!-- not stacked but could be repeated -->
+                                                <xsl:call-template name="rfcLanguages">
+                                                        <xsl:with-param name="nodeNum">
+                                                                <xsl:value-of select="1"/>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="usedLanguages">
+                                                                <xsl:text></xsl:text>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="controlField008-35-37">
+                                                                <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <!-- iso -->
+                                                <xsl:variable name="allLanguages">
+                                                        <xsl:copy-of select="$langCodes"></xsl:copy-of>
+                                                </xsl:variable>
+                                                <xsl:variable name="currentLanguage">
+                                                        <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
+                                                </xsl:variable>
+                                                <xsl:call-template name="isoLanguage">
+                                                        <xsl:with-param name="currentLanguage">
+                                                                <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="remainingLanguages">
+                                                                <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"></xsl:value-of>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="usedLanguages">
+                                                                <xsl:if test="$controlField008-35-37">
+                                                                        <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
+                                                                </xsl:if>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </xsl:for-each>
+                </xsl:for-each>
+                <xsl:variable name="physicalDescription">
+                        <!--3.2 change tmee 007/11 -->
+                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
+                                <digitalOrigin>reformatted digital</digitalOrigin>
+                        </xsl:if>
+                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
+                                <digitalOrigin>digitized microfilm</digitalOrigin>
+                        </xsl:if>
+                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
+                                <digitalOrigin>digitized other analog</digitalOrigin>
+                        </xsl:if>
+                        <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"></xsl:variable>
+                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
+                        <xsl:variable name="check008-23">
+                                <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
+                                        <xsl:value-of select="true()"></xsl:value-of>
+                                </xsl:if>
+                        </xsl:variable>
+                        <xsl:variable name="check008-29">
+                                <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
+                                        <xsl:value-of select="true()"></xsl:value-of>
+                                </xsl:if>
+                        </xsl:variable>
+                        <xsl:choose>
+                                <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
+                                        <form authority="marcform">braille</form>
+                                </xsl:when>
+                                <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
+                                        <form authority="marcform">print</form>
+                                </xsl:when>
+                                <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
+                                        <form authority="marcform">electronic</form>
+                                </xsl:when>
+                                <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
+                                        <form authority="marcform">microfiche</form>
+                                </xsl:when>
+                                <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
+                                        <form authority="marcform">microfilm</form>
+                                </xsl:when>
+                        </xsl:choose>
+                        <!-- 1/04 fix -->
+                        <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
+                                <form>
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </form>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
+                                <xsl:choose>
+                                        <xsl:when test="substring(text(),14,1)='a'">
+                                                <reformattingQuality>access</reformattingQuality>
+                                        </xsl:when>
+                                        <xsl:when test="substring(text(),14,1)='p'">
+                                                <reformattingQuality>preservation</reformattingQuality>
+                                        </xsl:when>
+                                        <xsl:when test="substring(text(),14,1)='r'">
+                                                <reformattingQuality>replacement</reformattingQuality>
+                                        </xsl:when>
+                                </xsl:choose>
+                        </xsl:for-each>
+                        <!--3.2 change tmee 007/01 -->
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
+                                <form authority="smd">chip cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
+                                <form authority="smd">computer optical disc cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
+                                <form authority="smd">magnetic disc</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
+                                <form authority="smd">magneto-optical disc</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
+                                <form authority="smd">optical disc</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
+                                <form authority="smd">remote</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
+                                <form authority="smd">tape cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
+                                <form authority="smd">tape cassette</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
+                                <form authority="smd">tape reel</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
+                                <form authority="smd">celestial globe</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
+                                <form authority="smd">earth moon globe</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
+                                <form authority="smd">planetary or lunar globe</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
+                                <form authority="smd">terrestrial globe</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
+                                <form authority="smd">kit</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
+                                <form authority="smd">atlas</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
+                                <form authority="smd">diagram</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
+                                <form authority="smd">map</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
+                                <form authority="smd">model</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
+                                <form authority="smd">profile</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
+                                <form authority="smd">remote-sensing image</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
+                                <form authority="smd">section</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
+                                <form authority="smd">view</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
+                                <form authority="smd">aperture card</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
+                                <form authority="smd">microfiche</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
+                                <form authority="smd">microfiche cassette</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
+                                <form authority="smd">microfilm cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
+                                <form authority="smd">microfilm cassette</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
+                                <form authority="smd">microfilm reel</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
+                                <form authority="smd">microopaque</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
+                                <form authority="smd">film cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
+                                <form authority="smd">film cassette</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
+                                <form authority="smd">film reel</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
+                                <form authority="smd">chart</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
+                                <form authority="smd">collage</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
+                                <form authority="smd">drawing</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
+                                <form authority="smd">flash card</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
+                                <form authority="smd">painting</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
+                                <form authority="smd">photomechanical print</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
+                                <form authority="smd">photonegative</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
+                                <form authority="smd">photoprint</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
+                                <form authority="smd">picture</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
+                                <form authority="smd">print</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
+                                <form authority="smd">technical drawing</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
+                                <form authority="smd">notated music</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
+                                <form authority="smd">filmslip</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
+                                <form authority="smd">filmstrip cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
+                                <form authority="smd">filmstrip roll</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
+                                <form authority="smd">other filmstrip type</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
+                                <form authority="smd">slide</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
+                                <form authority="smd">transparency</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
+                                <form authority="smd">remote-sensing image</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
+                                <form authority="smd">cylinder</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
+                                <form authority="smd">roll</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
+                                <form authority="smd">sound cartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
+                                <form authority="smd">sound cassette</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
+                                <form authority="smd">sound disc</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
+                                <form authority="smd">sound-tape reel</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
+                                <form authority="smd">sound-track film</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
+                                <form authority="smd">wire recording</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
+                                <form authority="smd">braille</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
+                                <form authority="smd">combination</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
+                                <form authority="smd">moon</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
+                                <form authority="smd">tactile, with no writing system</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
+                                <form authority="smd">braille</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
+                                <form authority="smd">large print</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
+                                <form authority="smd">regular print</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
+                                <form authority="smd">text in looseleaf binder</form>
+                        </xsl:if>
+
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
+                                <form authority="smd">videocartridge</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
+                                <form authority="smd">videocassette</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
+                                <form authority="smd">videodisc</form>
+                        </xsl:if>
+                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
+                                <form authority="smd">videoreel</form>
+                        </xsl:if>
+
+                        <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
+                                <internetMediaType>
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </internetMediaType>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=300]">
+                                <extent>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abce</xsl:with-param>
+                                        </xsl:call-template>
+                                </extent>
+                        </xsl:for-each>
+                </xsl:variable>
+                <xsl:if test="string-length(normalize-space($physicalDescription))">
+                        <physicalDescription>
+                                <xsl:copy-of select="$physicalDescription"></xsl:copy-of>
+                        </physicalDescription>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=520]">
+                        <abstract>
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </abstract>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=505]">
+                        <tableOfContents>
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">agrt</xsl:with-param>
+                                </xsl:call-template>
+                        </tableOfContents>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=521]">
+                        <targetAudience>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </targetAudience>
+                </xsl:for-each>
+                <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
+                        <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"></xsl:variable>
+                        <xsl:choose>
+                                <!-- 01/04 fix -->
+                                <xsl:when test="$controlField008-22='d'">
+                                        <targetAudience authority="marctarget">adolescent</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='e'">
+                                        <targetAudience authority="marctarget">adult</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='g'">
+                                        <targetAudience authority="marctarget">general</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
+                                        <targetAudience authority="marctarget">juvenile</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='a'">
+                                        <targetAudience authority="marctarget">preschool</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='f'">
+                                        <targetAudience authority="marctarget">specialized</targetAudience>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
+                        <note type="statement of responsibility">
+                                <xsl:value-of select="."></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=500]">
+                        <note>
+                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                                <xsl:call-template name="uri"></xsl:call-template>
+                        </note>
+                </xsl:for-each>
+
+                <!--3.2 change tmee additional note fields-->
+
+                <xsl:for-each select="marc:datafield[@tag=502]">
+                        <note type="thesis">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=504]">
+                        <note type="bibliography">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=508]">
+                        <note type="creation/production credits">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=506]">
+                        <note type="restrictions">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=510]">
+                        <note  type="citation/reference">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+
+                <xsl:for-each select="marc:datafield[@tag=511]">
+                        <note type="performers">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=518]">
+                        <note type="venue">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=530]">
+                        <note  type="additional physical form">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=533]">
+                        <note  type="reproduction">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=534]">
+                        <note  type="original version">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=538]">
+                        <note  type="system details">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=583]">
+                        <note type="action">
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+
+
+
+
+
+                <xsl:for-each select="marc:datafield[@tag=501 or @tag=507 or  @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
+                        <note>
+                                <xsl:call-template name="uri"></xsl:call-template>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
+                        <subject>
+                                <cartographics>
+                                        <coordinates>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">defg</xsl:with-param>
+                                                </xsl:call-template>
+                                        </coordinates>
+                                </cartographics>
+                        </subject>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=043]">
+                        <subject>
+                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
+                                        <geographicCode>
+                                                <xsl:attribute name="authority">
+                                                        <xsl:if test="@code='a'">
+                                                                <xsl:text>marcgac</xsl:text>
+                                                        </xsl:if>
+                                                        <xsl:if test="@code='b'">
+                                                                <xsl:value-of select="following-sibling::marc:subfield[@code=2]"></xsl:value-of>
+                                                        </xsl:if>
+                                                        <xsl:if test="@code='c'">
+                                                                <xsl:text>iso3166</xsl:text>
+                                                        </xsl:if>
+                                                </xsl:attribute>
+                                                <xsl:value-of select="self::marc:subfield"></xsl:value-of>
+                                        </geographicCode>
+                                </xsl:for-each>
+                        </subject>
+                </xsl:for-each>
+                <!-- tmee 2006/11/27 -->
+                <xsl:for-each select="marc:datafield[@tag=255]">
+                        <subject>
+                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
+                                <cartographics>
+                                        <xsl:if test="@code='a'">
+                                                <scale>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </scale>
+                                        </xsl:if>
+                                        <xsl:if test="@code='b'">
+                                                <projection>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </projection>
+                                        </xsl:if>
+                                        <xsl:if test="@code='c'">
+                                                <coordinates>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </coordinates>
+                                        </xsl:if>
+                                </cartographics>
+                                </xsl:for-each>
+                        </subject>
+                </xsl:for-each>
+
+                <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"></xsl:apply-templates>
+                <xsl:apply-templates select="marc:datafield[@tag=656]"></xsl:apply-templates>
+                <xsl:for-each select="marc:datafield[@tag=752]">
+                        <subject>
+                                <hierarchicalGeographic>
+                                        <xsl:for-each select="marc:subfield[@code='a']">
+                                                <country>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                                        </xsl:call-template>
+                                                </country>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='b']">
+                                                <state>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                                        </xsl:call-template>
+                                                </state>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='c']">
+                                                <county>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                                        </xsl:call-template>
+                                                </county>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='d']">
+                                                <city>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                                        </xsl:call-template>
+                                                </city>
+                                        </xsl:for-each>
+                                </hierarchicalGeographic>
+                        </subject>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
+                        <subject>
+                                <xsl:choose>
+                                        <xsl:when test="@ind1=2">
+                                                <temporal encoding="iso8601" point="start">
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString">
+                                                                        <xsl:value-of select="marc:subfield[@code='b'][1]"></xsl:value-of>
+                                                                </xsl:with-param>
+                                                        </xsl:call-template>
+                                                </temporal>
+                                                <temporal encoding="iso8601" point="end">
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString">
+                                                                        <xsl:value-of select="marc:subfield[@code='b'][2]"></xsl:value-of>
+                                                                </xsl:with-param>
+                                                        </xsl:call-template>
+                                                </temporal>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <xsl:for-each select="marc:subfield[@code='b']">
+                                                        <temporal encoding="iso8601">
+                                                                <xsl:call-template name="chopPunctuation">
+                                                                        <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </temporal>
+                                                </xsl:for-each>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </subject>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=050]">
+                        <xsl:for-each select="marc:subfield[@code='b']">
+                                <classification authority="lcc">
+                                        <xsl:if test="../marc:subfield[@code='3']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"></xsl:value-of>
+                                        <xsl:text> </xsl:text>
+                                        <xsl:value-of select="text()"></xsl:value-of>
+                                </classification>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
+                                <classification authority="lcc">
+                                        <xsl:if test="../marc:subfield[@code='3']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="text()"></xsl:value-of>
+                                </classification>
+                        </xsl:for-each>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=082]">
+                        <classification authority="ddc">
+                                <xsl:if test="marc:subfield[@code='2']">
+                                        <xsl:attribute name="edition">
+                                                <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
+                                        </xsl:attribute>
+                                </xsl:if>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=080]">
+                        <classification authority="udc">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abx</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=060]">
+                        <classification authority="nlm">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
+                        <classification authority="sudocs">
+                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
+                        <classification authority="candoc">
+                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=086]">
+                        <classification>
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
+                                </xsl:attribute>
+                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=084]">
+                        <classification>
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
+                                </xsl:attribute>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=440]">
+                        <relatedItem type="series">
+                                <xsl:variable name="titleChop">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">av</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:variable>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:value-of select="$titleChop" />
+                                        </title>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                                <titleInfo type="nfi">
+                                        <xsl:choose>
+                                                <xsl:when test="@ind2>0">
+                                                        <nonSort>
+                                                                <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+                                                        </nonSort>
+                                                        <title>
+                                                                <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+                                                        </title>
+                                                        <xsl:call-template name="part"/>
+                                                </xsl:when>
+                                                <xsl:otherwise>
+                                                        <title>
+                                                                <xsl:value-of select="$titleChop" />
+                                                        </title>
+                                                </xsl:otherwise>
+                                        </xsl:choose>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">av</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=510]">
+                        <relatedItem type="isReferencedBy">
+                                <note>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abcx3</xsl:with-param>
+                                        </xsl:call-template>
+                                </note>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=534]">
+                        <relatedItem type="original">
+                                <xsl:call-template name="relatedTitle"></xsl:call-template>
+                                <xsl:call-template name="relatedName"></xsl:call-template>
+                                <xsl:if test="marc:subfield[@code='b' or @code='c']">
+                                        <originInfo>
+                                                <xsl:for-each select="marc:subfield[@code='c']">
+                                                        <publisher>
+                                                                <xsl:value-of select="."></xsl:value-of>
+                                                        </publisher>
+                                                </xsl:for-each>
+                                                <xsl:for-each select="marc:subfield[@code='b']">
+                                                        <edition>
+                                                                <xsl:value-of select="."></xsl:value-of>
+                                                        </edition>
+                                                </xsl:for-each>
+                                        </originInfo>
+                                </xsl:if>
+                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
+                                <xsl:for-each select="marc:subfield[@code='z']">
+                                        <identifier type="isbn">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </identifier>
+                                </xsl:for-each>
+                                <xsl:call-template name="relatedNote"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                                <name type="personal">
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="termsOfAddress"></xsl:call-template>
+                                        <xsl:call-template name="nameDate"></xsl:call-template>
+                                        <xsl:call-template name="role"></xsl:call-template>
+                                </name>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
+                                </titleInfo>
+                                <name type="corporate">
+                                        <xsl:for-each select="marc:subfield[@code='a']">
+                                                <namePart>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='b']">
+                                                <namePart>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <xsl:variable name="tempNamePart">
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:variable>
+                                        <xsl:if test="normalize-space($tempNamePart)">
+                                                <namePart>
+                                                        <xsl:value-of select="$tempNamePart"></xsl:value-of>
+                                                </namePart>
+                                        </xsl:if>
+                                        <xsl:call-template name="role"></xsl:call-template>
+                                </name>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
+                                </titleInfo>
+                                <name type="conference">
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                </name>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
+                                <xsl:variable name="titleChop">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:variable>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:value-of select="$titleChop" />
+                                        </title>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                                <titleInfo type="nfi">
+                                        <xsl:choose>
+                                                <xsl:when test="@ind1>0">
+                                                        <nonSort>
+                                                                <xsl:value-of select="substring($titleChop,1,@ind1)"/>
+                                                        </nonSort>
+                                                        <title>
+                                                                <xsl:value-of select="substring($titleChop,@ind1+1)"/>
+                                                        </title>
+                                                </xsl:when>
+                                                <xsl:otherwise>
+                                                        <title>
+                                                                <xsl:value-of select="$titleChop" />
+                                                        </title>
+                                                </xsl:otherwise>
+                                        </xsl:choose>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
+                        <relatedItem type="series">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
+                        <relatedItem>
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=775]">
+                        <relatedItem type="otherVersion">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
+                        <relatedItem type="constituent">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
+                        <relatedItem type="host">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=776]">
+                        <relatedItem type="otherFormat">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=780]">
+                        <relatedItem type="preceding">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=785]">
+                        <relatedItem type="succeeding">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=786]">
+                        <relatedItem type="original">
+                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=800]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"></xsl:call-template>
+                                </titleInfo>
+                                <name type="personal">
+                                        <namePart>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="termsOfAddress"></xsl:call-template>
+                                        <xsl:call-template name="nameDate"></xsl:call-template>
+                                        <xsl:call-template name="role"></xsl:call-template>
+                                </name>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=810]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
+                                </titleInfo>
+                                <name type="corporate">
+                                        <xsl:for-each select="marc:subfield[@code='a']">
+                                                <namePart>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='b']">
+                                                <namePart>
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="role"></xsl:call-template>
+                                </name>
+                                <xsl:call-template name="relatedForm"></xsl:call-template>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=811]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </titleInfo>
+                                <name type="conference">
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="role"/>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='830']">
+                        <relatedItem type="series">
+                                <xsl:variable name="titleChop">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:variable>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:value-of select="$titleChop" />
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <titleInfo type="nfi">
+                                        <xsl:choose>
+                                                <xsl:when test="@ind2>0">
+                                                        <nonSort>
+                                                                <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+                                                        </nonSort>
+                                                        <title>
+                                                                <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+                                                        </title>
+                                                </xsl:when>
+                                                <xsl:otherwise>
+                                                        <title>
+                                                                <xsl:value-of select="$titleChop" />
+                                                        </title>
+                                                </xsl:otherwise>
+                                        </xsl:choose>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
+                        <relatedItem>
+                                <internetMediaType>
+                                        <xsl:value-of select="."/>
+                                </internetMediaType>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='020']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">isbn</xsl:with-param>
+                        </xsl:call-template>
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <identifier type="isbn">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">isrc</xsl:with-param>
+                        </xsl:call-template>
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <identifier type="isrc">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">ismn</xsl:with-param>
+                        </xsl:call-template>
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <identifier type="ismn">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">sici</xsl:with-param>
+                        </xsl:call-template>
+                        <identifier type="sici">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='022']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">issn</xsl:with-param>
+                        </xsl:call-template>
+                        <identifier type="issn">
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='010']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">lccn</xsl:with-param>
+                        </xsl:call-template>
+                        <identifier type="lccn">
+                                <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='028']">
+                        <identifier>
+                                <xsl:attribute name="type">
+                                        <xsl:choose>
+                                                <xsl:when test="@ind1='0'">issue number</xsl:when>
+                                                <xsl:when test="@ind1='1'">matrix number</xsl:when>
+                                                <xsl:when test="@ind1='2'">music plate</xsl:when>
+                                                <xsl:when test="@ind1='3'">music publisher</xsl:when>
+                                                <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
+                                        </xsl:choose>
+                                </xsl:attribute>
+                                <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 028 -->
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">
+                                                <xsl:choose>
+                                                        <xsl:when test="@ind1='0'">ba</xsl:when>
+                                                        <xsl:otherwise>ab</xsl:otherwise>
+                                                </xsl:choose>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='037']">
+                        <identifier type="stock number">
+                                <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 037 -->
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
+                        <identifier>
+                                <xsl:attribute name="type">
+                                        <xsl:choose>
+                                                <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
+                                                <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
+                                                <xsl:otherwise>uri</xsl:otherwise>
+                                        </xsl:choose>
+                                </xsl:attribute>
+                                <xsl:choose>
+                                        <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
+                                                <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </identifier>
+                        <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
+                                <identifier type="hdl">
+                                        <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">y3z</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
+                        <identifier type="upc">
+                                <xsl:call-template name="isInvalid"/>
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </identifier>
+                </xsl:for-each>
+                <!-- 1/04 fix added $y -->
+                <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+                        <location>
+                                <url>
+                                        <xsl:if test="marc:subfield[@code='y' or @code='3']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">y3</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:if test="marc:subfield[@code='z' ]">
+                                                <xsl:attribute name="note">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">z</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
+
+                                </url>
+                        </location>
+                </xsl:for-each>
+
+                        <!-- 3.2 change tmee 856z  -->
+
+
+                <xsl:for-each select="marc:datafield[@tag=852]">
+                        <location>
+                                <physicalLocation>
+                                        <xsl:call-template name="displayLabel"></xsl:call-template>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abje</xsl:with-param>
+                                        </xsl:call-template>
+                                </physicalLocation>
+                        </location>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=506]">
+                        <accessCondition type="restrictionOnAccess">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abcd35</xsl:with-param>
+                                </xsl:call-template>
+                        </accessCondition>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=540]">
+                        <accessCondition type="useAndReproduction">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abcde35</xsl:with-param>
+                                </xsl:call-template>
+                        </accessCondition>
+                </xsl:for-each>
+                <recordInfo>
+                        <xsl:for-each select="marc:datafield[@tag=040]">
+                                <recordContentSource authority="marcorg">
+                                        <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                                </recordContentSource>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=008]">
+                                <recordCreationDate encoding="marc">
+                                        <xsl:value-of select="substring(.,1,6)"></xsl:value-of>
+                                </recordCreationDate>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=005]">
+                                <recordChangeDate encoding="iso8601">
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </recordChangeDate>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=001]">
+                                <recordIdentifier>
+                                        <xsl:if test="../marc:controlfield[@tag=003]">
+                                                <xsl:attribute name="source">
+                                                        <xsl:value-of select="../marc:controlfield[@tag=003]"></xsl:value-of>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </recordIdentifier>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
+                                <languageOfCataloging>
+                                        <languageTerm authority="iso639-2b" type="code">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </languageTerm>
+                                </languageOfCataloging>
+                        </xsl:for-each>
+                </recordInfo>
+        </xsl:template>
+        <xsl:template name="displayForm">
+                <xsl:for-each select="marc:subfield[@code='c']">
+                        <displayForm>
+                                <xsl:value-of select="."></xsl:value-of>
+                        </displayForm>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="affiliation">
+                <xsl:for-each select="marc:subfield[@code='u']">
+                        <affiliation>
+                                <xsl:value-of select="."></xsl:value-of>
+                        </affiliation>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="uri">
+                <xsl:for-each select="marc:subfield[@code='u']">
+                        <xsl:attribute name="xlink:href">
+                                <xsl:value-of select="."></xsl:value-of>
+                        </xsl:attribute>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='0']">
+                        <xsl:choose>
+                                <xsl:when test="contains(text(), ')')">
+                                        <xsl:attribute name="xlink:href">
+                                                <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
+                                        </xsl:attribute>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:attribute name="xlink:href">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </xsl:attribute>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="role">
+                <xsl:for-each select="marc:subfield[@code='e']">
+                        <role>
+                                <roleTerm type="text">
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </roleTerm>
+                        </role>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='4']">
+                        <role>
+                                <roleTerm authority="marcrelator" type="code">
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </roleTerm>
+                        </role>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="part">
+                <xsl:variable name="partNumber">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">n</xsl:with-param>
+                                <xsl:with-param name="anyCodes">n</xsl:with-param>
+                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:variable name="partName">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">p</xsl:with-param>
+                                <xsl:with-param name="anyCodes">p</xsl:with-param>
+                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:if test="string-length(normalize-space($partNumber))">
+                        <partNumber>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="$partNumber"></xsl:with-param>
+                                </xsl:call-template>
+                        </partNumber>
+                </xsl:if>
+                <xsl:if test="string-length(normalize-space($partName))">
+                        <partName>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="$partName"></xsl:with-param>
+                                </xsl:call-template>
+                        </partName>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedPart">
+                <xsl:if test="@tag=773">
+                        <xsl:for-each select="marc:subfield[@code='g']">
+                                <part>
+                                        <text>
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </text>
+                                </part>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:subfield[@code='q']">
+                                <part>
+                                        <xsl:call-template name="parsePart"></xsl:call-template>
+                                </part>
+                        </xsl:for-each>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedPartNumName">
+                <xsl:variable name="partNumber">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">g</xsl:with-param>
+                                <xsl:with-param name="anyCodes">g</xsl:with-param>
+                                <xsl:with-param name="afterCodes">pst</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:variable name="partName">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">p</xsl:with-param>
+                                <xsl:with-param name="anyCodes">p</xsl:with-param>
+                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:if test="string-length(normalize-space($partNumber))">
+                        <partNumber>
+                                <xsl:value-of select="$partNumber"></xsl:value-of>
+                        </partNumber>
+                </xsl:if>
+                <xsl:if test="string-length(normalize-space($partName))">
+                        <partName>
+                                <xsl:value-of select="$partName"></xsl:value-of>
+                        </partName>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedName">
+                <xsl:for-each select="marc:subfield[@code='a']">
+                        <name>
+                                <namePart>
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </namePart>
+                        </name>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedForm">
+                <xsl:for-each select="marc:subfield[@code='h']">
+                        <physicalDescription>
+                                <form>
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </form>
+                        </physicalDescription>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedExtent">
+                <xsl:for-each select="marc:subfield[@code='h']">
+                        <physicalDescription>
+                                <extent>
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </extent>
+                        </physicalDescription>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedNote">
+                <xsl:for-each select="marc:subfield[@code='n']">
+                        <note>
+                                <xsl:value-of select="."></xsl:value-of>
+                        </note>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedSubject">
+                <xsl:for-each select="marc:subfield[@code='j']">
+                        <subject>
+                                <temporal encoding="iso8601">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                        </xsl:call-template>
+                                </temporal>
+                        </subject>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedIdentifierISSN">
+                <xsl:for-each select="marc:subfield[@code='x']">
+                        <identifier type="issn">
+                                <xsl:value-of select="."></xsl:value-of>
+                        </identifier>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedIdentifierLocal">
+                <xsl:for-each select="marc:subfield[@code='w']">
+                        <identifier type="local">
+                                <xsl:value-of select="."></xsl:value-of>
+                        </identifier>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedIdentifier">
+                <xsl:for-each select="marc:subfield[@code='o']">
+                        <identifier>
+                                <xsl:value-of select="."></xsl:value-of>
+                        </identifier>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedItem76X-78X">
+                <xsl:call-template name="displayLabel"></xsl:call-template>
+                <xsl:call-template name="relatedTitle76X-78X"></xsl:call-template>
+                <xsl:call-template name="relatedName"></xsl:call-template>
+                <xsl:call-template name="relatedOriginInfo"></xsl:call-template>
+                <xsl:call-template name="relatedLanguage"></xsl:call-template>
+                <xsl:call-template name="relatedExtent"></xsl:call-template>
+                <xsl:call-template name="relatedNote"></xsl:call-template>
+                <xsl:call-template name="relatedSubject"></xsl:call-template>
+                <xsl:call-template name="relatedIdentifier"></xsl:call-template>
+                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
+                <xsl:call-template name="relatedIdentifierLocal"></xsl:call-template>
+                <xsl:call-template name="relatedPart"></xsl:call-template>
+        </xsl:template>
+        <xsl:template name="subjectGeographicZ">
+                <geographic>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                        </xsl:call-template>
+                </geographic>
+        </xsl:template>
+        <xsl:template name="subjectTemporalY">
+                <temporal>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                        </xsl:call-template>
+                </temporal>
+        </xsl:template>
+        <xsl:template name="subjectTopic">
+                <topic>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                        </xsl:call-template>
+                </topic>
+        </xsl:template>
+        <!-- 3.2 change tmee 6xx $v genre -->
+        <xsl:template name="subjectGenre">
+                <genre>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                        </xsl:call-template>
+                </genre>
+        </xsl:template>
+
+        <xsl:template name="nameABCDN">
+                <xsl:for-each select="marc:subfield[@code='a']">
+                        <namePart>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='b']">
+                        <namePart>
+                                <xsl:value-of select="."></xsl:value-of>
+                        </namePart>
+                </xsl:for-each>
+                <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
+                        <namePart>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">cdn</xsl:with-param>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="nameABCDQ">
+                <namePart>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString">
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">aq</xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:with-param>
+                                <xsl:with-param name="punctuation">
+                                        <xsl:text>:,;/ </xsl:text>
+                                </xsl:with-param>
+                        </xsl:call-template>
+                </namePart>
+                <xsl:call-template name="termsOfAddress"></xsl:call-template>
+                <xsl:call-template name="nameDate"></xsl:call-template>
+        </xsl:template>
+        <xsl:template name="nameACDEQ">
+                <namePart>
+                        <xsl:call-template name="subfieldSelect">
+                                <xsl:with-param name="codes">acdeq</xsl:with-param>
+                        </xsl:call-template>
+                </namePart>
+        </xsl:template>
+        <xsl:template name="constituentOrRelatedType">
+                <xsl:if test="@ind2=2">
+                        <xsl:attribute name="type">constituent</xsl:attribute>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedTitle">
+                <xsl:for-each select="marc:subfield[@code='t']">
+                        <titleInfo>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                        </titleInfo>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedTitle76X-78X">
+                <xsl:for-each select="marc:subfield[@code='t']">
+                        <titleInfo>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
+                                </xsl:if>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='p']">
+                        <titleInfo type="abbreviated">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
+                                </xsl:if>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='s']">
+                        <titleInfo type="uniform">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
+                                </xsl:if>
+                        </titleInfo>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedOriginInfo">
+                <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
+                        <originInfo>
+                                <xsl:if test="@tag=775">
+                                        <xsl:for-each select="marc:subfield[@code='f']">
+                                                <place>
+                                                        <placeTerm>
+                                                                <xsl:attribute name="type">code</xsl:attribute>
+                                                                <xsl:attribute name="authority">marcgac</xsl:attribute>
+                                                                <xsl:value-of select="."></xsl:value-of>
+                                                        </placeTerm>
+                                                </place>
+                                        </xsl:for-each>
+                                </xsl:if>
+                                <xsl:for-each select="marc:subfield[@code='d']">
+                                        <publisher>
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </publisher>
+                                </xsl:for-each>
+                                <xsl:for-each select="marc:subfield[@code='b']">
+                                        <edition>
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </edition>
+                                </xsl:for-each>
+                        </originInfo>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedLanguage">
+                <xsl:for-each select="marc:subfield[@code='e']">
+                        <xsl:call-template name="getLanguage">
+                                <xsl:with-param name="langString">
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </xsl:with-param>
+                        </xsl:call-template>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="nameDate">
+                <xsl:for-each select="marc:subfield[@code='d']">
+                        <namePart type="date">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="subjectAuthority">
+                <xsl:if test="@ind2!=4">
+                        <xsl:if test="@ind2!=' '">
+                                <xsl:if test="@ind2!=8">
+                                        <xsl:if test="@ind2!=9">
+                                                <xsl:attribute name="authority">
+                                                        <xsl:choose>
+                                                                <xsl:when test="@ind2=0">lcsh</xsl:when>
+                                                                <xsl:when test="@ind2=1">lcshac</xsl:when>
+                                                                <xsl:when test="@ind2=2">mesh</xsl:when>
+                                                                <!-- 1/04 fix -->
+                                                                <xsl:when test="@ind2=3">nal</xsl:when>
+                                                                <xsl:when test="@ind2=5">csh</xsl:when>
+                                                                <xsl:when test="@ind2=6">rvm</xsl:when>
+                                                                <xsl:when test="@ind2=7">
+                                                                        <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
+                                                                </xsl:when>
+                                                        </xsl:choose>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                </xsl:if>
+                        </xsl:if>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="subjectAnyOrder">
+                <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
+                        <xsl:choose>
+                                <xsl:when test="@code='v'">
+                                        <xsl:call-template name="subjectGenre"></xsl:call-template>
+                                </xsl:when>
+                                <xsl:when test="@code='x'">
+                                        <xsl:call-template name="subjectTopic"></xsl:call-template>
+                                </xsl:when>
+                                <xsl:when test="@code='y'">
+                                        <xsl:call-template name="subjectTemporalY"></xsl:call-template>
+                                </xsl:when>
+                                <xsl:when test="@code='z'">
+                                        <xsl:call-template name="subjectGeographicZ"></xsl:call-template>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="specialSubfieldSelect">
+                <xsl:param name="anyCodes"></xsl:param>
+                <xsl:param name="axis"></xsl:param>
+                <xsl:param name="beforeCodes"></xsl:param>
+                <xsl:param name="afterCodes"></xsl:param>
+                <xsl:variable name="str">
+                        <xsl:for-each select="marc:subfield">
+                                <xsl:if test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
+                                        <xsl:value-of select="text()"></xsl:value-of>
+                                        <xsl:text> </xsl:text>
+                                </xsl:if>
+                        </xsl:for-each>
+                </xsl:variable>
+                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
+        </xsl:template>
+
+        <!-- 3.2 change tmee 6xx $v genre -->
+        <xsl:template match="marc:datafield[@tag=600]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
+                        <name type="personal">
+                                <xsl:call-template name="uri" />
+                                <namePart>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">aq</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </namePart>
+                                <xsl:call-template name="termsOfAddress"></xsl:call-template>
+                                <xsl:call-template name="nameDate"></xsl:call-template>
+                                <xsl:call-template name="affiliation"></xsl:call-template>
+                                <xsl:call-template name="role"></xsl:call-template>
+                        </name>
+                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=610]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
+                        <name type="corporate">
+                                <xsl:call-template name="uri" />
+                                <xsl:for-each select="marc:subfield[@code='a']">
+                                        <namePart>
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </namePart>
+                                </xsl:for-each>
+                                <xsl:for-each select="marc:subfield[@code='b']">
+                                        <namePart>
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </namePart>
+                                </xsl:for-each>
+                                <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
+                                        <namePart>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">cdnp</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                </xsl:if>
+                                <xsl:call-template name="role"></xsl:call-template>
+                        </name>
+                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=611]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
+                        <name type="conference">
+                                <xsl:call-template name="uri" />
+                                <namePart>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
+                                        </xsl:call-template>
+                                </namePart>
+                                <xsl:for-each select="marc:subfield[@code='4']">
+                                        <role>
+                                                <roleTerm authority="marcrelator" type="code">
+                                                        <xsl:value-of select="."></xsl:value-of>
+                                                </roleTerm>
+                                        </role>
+                                </xsl:for-each>
+                        </name>
+                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=630]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
+                        <xsl:variable name="titleChop">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">adfhklor</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:variable>
+                        <titleInfo>
+                                <title>
+                                        <xsl:value-of select="$titleChop" />
+                                </title>
+                                <xsl:call-template name="part"></xsl:call-template>
+                        </titleInfo>
+                        <titleInfo type="nfi">
+                                <xsl:choose>
+                                        <xsl:when test="@ind1>0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleChop,1,@ind1)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleChop,@ind1+1)"/>
+                                                </title>
+                                                <xsl:call-template name="part"/>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleChop" />
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:call-template name="part"></xsl:call-template>
+                        </titleInfo>
+                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=650]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
+                        <topic>
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">abcd</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </topic>
+                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=651]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
+                        <xsl:for-each select="marc:subfield[@code='a']">
+                                <geographic>
+                                        <xsl:call-template name="uri" />
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
+                                        </xsl:call-template>
+                                </geographic>
+                        </xsl:for-each>
+                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=653]">
+                <subject>
+                        <xsl:for-each select="marc:subfield[@code='a']">
+                                <topic>
+                                        <xsl:call-template name="uri" />
+                                        <xsl:value-of select="."></xsl:value-of>
+                                </topic>
+                        </xsl:for-each>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=656]">
+                <subject>
+                        <xsl:if test="marc:subfield[@code=2]">
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code=2]"></xsl:value-of>
+                                </xsl:attribute>
+                        </xsl:if>
+                        <occupation>
+                                <xsl:call-template name="uri" />
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </occupation>
+                </subject>
+        </xsl:template>
+        <xsl:template name="termsOfAddress">
+                <xsl:if test="marc:subfield[@code='b' or @code='c']">
+                        <namePart type="termsOfAddress">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">bc</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="displayLabel">
+                <xsl:if test="marc:subfield[@code='i']">
+                        <xsl:attribute name="displayLabel">
+                                <xsl:value-of select="marc:subfield[@code='i']"></xsl:value-of>
+                        </xsl:attribute>
+                </xsl:if>
+                <xsl:if test="marc:subfield[@code='3']">
+                        <xsl:attribute name="displayLabel">
+                                <xsl:value-of select="marc:subfield[@code='3']"></xsl:value-of>
+                        </xsl:attribute>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="isInvalid">
+                <xsl:param name="type"/>
+                <xsl:if test="marc:subfield[@code='z'] or marc:subfield[@code='y']">
+                        <identifier>
+                                <xsl:attribute name="type">
+                                        <xsl:value-of select="$type"/>
+                                </xsl:attribute>
+                                <xsl:attribute name="invalid">
+                                        <xsl:text>yes</xsl:text>
+                                </xsl:attribute>
+                                <xsl:if test="marc:subfield[@code='z']">
+                                        <xsl:value-of select="marc:subfield[@code='z']"/>
+                                </xsl:if>
+                                <xsl:if test="marc:subfield[@code='y']">
+                                        <xsl:value-of select="marc:subfield[@code='y']"/>
+                                </xsl:if>
+                        </identifier>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="subtitle">
+                <xsl:if test="marc:subfield[@code='b']">
+                        <subTitle>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:value-of select="marc:subfield[@code='b']"/>
+                                                <!--<xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">b</xsl:with-param>
+                                                </xsl:call-template>-->
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </subTitle>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="script">
+                <xsl:param name="scriptCode"></xsl:param>
+                <xsl:attribute name="script">
+                        <xsl:choose>
+                                <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
+                                <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
+                                <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
+                                <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
+                                <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
+                                <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
+                        </xsl:choose>
+                </xsl:attribute>
+        </xsl:template>
+        <xsl:template name="parsePart">
+                <!-- assumes 773$q= 1:2:3<4
+                     with up to 3 levels and one optional start page
+                -->
+                <xsl:variable name="level1">
+                        <xsl:choose>
+                                <xsl:when test="contains(text(),':')">
+                                        <!-- 1:2 -->
+                                        <xsl:value-of select="substring-before(text(),':')"></xsl:value-of>
+                                </xsl:when>
+                                <xsl:when test="not(contains(text(),':'))">
+                                        <!-- 1 or 1<3 -->
+                                        <xsl:if test="contains(text(),'&lt;')">
+                                                <!-- 1<3 -->
+                                                <xsl:value-of select="substring-before(text(),'&lt;')"></xsl:value-of>
+                                        </xsl:if>
+                                        <xsl:if test="not(contains(text(),'&lt;'))">
+                                                <!-- 1 -->
+                                                <xsl:value-of select="text()"></xsl:value-of>
+                                        </xsl:if>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="sici2">
+                        <xsl:choose>
+                                <xsl:when test="starts-with(substring-after(text(),$level1),':')">
+                                        <xsl:value-of select="substring(substring-after(text(),$level1),2)"></xsl:value-of>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="substring-after(text(),$level1)"></xsl:value-of>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="level2">
+                        <xsl:choose>
+                                <xsl:when test="contains($sici2,':')">
+                                        <!--  2:3<4  -->
+                                        <xsl:value-of select="substring-before($sici2,':')"></xsl:value-of>
+                                </xsl:when>
+                                <xsl:when test="contains($sici2,'&lt;')">
+                                        <!-- 1: 2<4 -->
+                                        <xsl:value-of select="substring-before($sici2,'&lt;')"></xsl:value-of>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="$sici2"></xsl:value-of>
+                                        <!-- 1:2 -->
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="sici3">
+                        <xsl:choose>
+                                <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
+                                        <xsl:value-of select="substring(substring-after($sici2,$level2),2)"></xsl:value-of>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="substring-after($sici2,$level2)"></xsl:value-of>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="level3">
+                        <xsl:choose>
+                                <xsl:when test="contains($sici3,'&lt;')">
+                                        <!-- 2<4 -->
+                                        <xsl:value-of select="substring-before($sici3,'&lt;')"></xsl:value-of>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="$sici3"></xsl:value-of>
+                                        <!-- 3 -->
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="page">
+                        <xsl:if test="contains(text(),'&lt;')">
+                                <xsl:value-of select="substring-after(text(),'&lt;')"></xsl:value-of>
+                        </xsl:if>
+                </xsl:variable>
+                <xsl:if test="$level1">
+                        <detail level="1">
+                                <number>
+                                        <xsl:value-of select="$level1"></xsl:value-of>
+                                </number>
+                        </detail>
+                </xsl:if>
+                <xsl:if test="$level2">
+                        <detail level="2">
+                                <number>
+                                        <xsl:value-of select="$level2"></xsl:value-of>
+                                </number>
+                        </detail>
+                </xsl:if>
+                <xsl:if test="$level3">
+                        <detail level="3">
+                                <number>
+                                        <xsl:value-of select="$level3"></xsl:value-of>
+                                </number>
+                        </detail>
+                </xsl:if>
+                <xsl:if test="$page">
+                        <extent unit="page">
+                                <start>
+                                        <xsl:value-of select="$page"></xsl:value-of>
+                                </start>
+                        </extent>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="getLanguage">
+                <xsl:param name="langString"></xsl:param>
+                <xsl:param name="controlField008-35-37"></xsl:param>
+                <xsl:variable name="length" select="string-length($langString)"></xsl:variable>
+                <xsl:choose>
+                        <xsl:when test="$length=0"></xsl:when>
+                        <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
+                                <xsl:call-template name="getLanguage">
+                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
+                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <language>
+                                        <languageTerm authority="iso639-2b" type="code">
+                                                <xsl:value-of select="substring($langString,1,3)"></xsl:value-of>
+                                        </languageTerm>
+                                </language>
+                                <xsl:call-template name="getLanguage">
+                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
+                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="isoLanguage">
+                <xsl:param name="currentLanguage"></xsl:param>
+                <xsl:param name="usedLanguages"></xsl:param>
+                <xsl:param name="remainingLanguages"></xsl:param>
+                <xsl:choose>
+                        <xsl:when test="string-length($currentLanguage)=0"></xsl:when>
+                        <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
+                                <language>
+                                        <xsl:if test="@code!='a'">
+                                                <xsl:attribute name="objectPart">
+                                                        <xsl:choose>
+                                                                <xsl:when test="@code='b'">summary or subtitle</xsl:when>
+                                                                <xsl:when test="@code='d'">sung or spoken text</xsl:when>
+                                                                <xsl:when test="@code='e'">libretto</xsl:when>
+                                                                <xsl:when test="@code='f'">table of contents</xsl:when>
+                                                                <xsl:when test="@code='g'">accompanying material</xsl:when>
+                                                                <xsl:when test="@code='h'">translation</xsl:when>
+                                                        </xsl:choose>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <languageTerm authority="iso639-2b" type="code">
+                                                <xsl:value-of select="$currentLanguage"></xsl:value-of>
+                                        </languageTerm>
+                                </language>
+                                <xsl:call-template name="isoLanguage">
+                                        <xsl:with-param name="currentLanguage">
+                                                <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="usedLanguages">
+                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="remainingLanguages">
+                                                <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <xsl:call-template name="isoLanguage">
+                                        <xsl:with-param name="currentLanguage">
+                                                <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="usedLanguages">
+                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="remainingLanguages">
+                                                <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="chopBrackets">
+                <xsl:param name="chopString"></xsl:param>
+                <xsl:variable name="string">
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="$chopString"></xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:if test="substring($string, 1,1)='['">
+                        <xsl:value-of select="substring($string,2, string-length($string)-2)"></xsl:value-of>
+                </xsl:if>
+                <xsl:if test="substring($string, 1,1)!='['">
+                        <xsl:value-of select="$string"></xsl:value-of>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="rfcLanguages">
+                <xsl:param name="nodeNum"></xsl:param>
+                <xsl:param name="usedLanguages"></xsl:param>
+                <xsl:param name="controlField008-35-37"></xsl:param>
+                <xsl:variable name="currentLanguage" select="."></xsl:variable>
+                <xsl:choose>
+                        <xsl:when test="not($currentLanguage)"></xsl:when>
+                        <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
+                                <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
+                                        <language>
+                                                <xsl:if test="@code!='a'">
+                                                        <xsl:attribute name="objectPart">
+                                                                <xsl:choose>
+                                                                        <xsl:when test="@code='b'">summary or subtitle</xsl:when>
+                                                                        <xsl:when test="@code='d'">sung or spoken text</xsl:when>
+                                                                        <xsl:when test="@code='e'">libretto</xsl:when>
+                                                                        <xsl:when test="@code='f'">table of contents</xsl:when>
+                                                                        <xsl:when test="@code='g'">accompanying material</xsl:when>
+                                                                        <xsl:when test="@code='h'">translation</xsl:when>
+                                                                </xsl:choose>
+                                                        </xsl:attribute>
+                                                </xsl:if>
+                                                <languageTerm authority="rfc3066" type="code">
+                                                        <xsl:value-of select="$currentLanguage"/>
+                                                </languageTerm>
+                                        </language>
+                                </xsl:if>
+                        </xsl:when>
+                        <xsl:otherwise>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="datafield">
+                <xsl:param name="tag"/>
+                <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
+                <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
+                <xsl:param name="subfields"/>
+                <xsl:element name="marc:datafield">
+                        <xsl:attribute name="tag">
+                                <xsl:value-of select="$tag"/>
+                        </xsl:attribute>
+                        <xsl:attribute name="ind1">
+                                <xsl:value-of select="$ind1"/>
+                        </xsl:attribute>
+                        <xsl:attribute name="ind2">
+                                <xsl:value-of select="$ind2"/>
+                        </xsl:attribute>
+                        <xsl:copy-of select="$subfields"/>
+                </xsl:element>
+        </xsl:template>
+
+        <xsl:template name="subfieldSelect">
+                <xsl:param name="codes"/>
+                <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
+                <xsl:variable name="str">
+                        <xsl:for-each select="marc:subfield">
+                                <xsl:if test="contains($codes, @code)">
+                                        <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
+                                </xsl:if>
+                        </xsl:for-each>
+                </xsl:variable>
+                <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
+        </xsl:template>
+
+        <xsl:template name="buildSpaces">
+                <xsl:param name="spaces"/>
+                <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
+                <xsl:if test="$spaces>0">
+                        <xsl:value-of select="$char"/>
+                        <xsl:call-template name="buildSpaces">
+                                <xsl:with-param name="spaces" select="$spaces - 1"/>
+                                <xsl:with-param name="char" select="$char"/>
+                        </xsl:call-template>
+                </xsl:if>
+        </xsl:template>
+
+        <xsl:template name="chopPunctuation">
+                <xsl:param name="chopString"/>
+                <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
+                <xsl:variable name="length" select="string-length($chopString)"/>
+                <xsl:choose>
+                        <xsl:when test="$length=0"/>
+                        <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+                                        <xsl:with-param name="punctuation" select="$punctuation"/>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:when test="not($chopString)"/>
+                        <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+
+        <xsl:template name="chopPunctuationFront">
+                <xsl:param name="chopString"/>
+                <xsl:variable name="length" select="string-length($chopString)"/>
+                <xsl:choose>
+                        <xsl:when test="$length=0"/>
+                        <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
+                                <xsl:call-template name="chopPunctuationFront">
+                                        <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:when test="not($chopString)"/>
+                        <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+</xsl:stylesheet>$XXXX$ where name = $$mods32$$;
+
+update config.xml_transform set xslt = $XXXX$<xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim"
+        xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+        exclude-result-prefixes="xlink marc" version="1.0">
+        <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
+
+        <xsl:variable name="ascii">
+                <xsl:text> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
+        </xsl:variable>
+
+        <xsl:variable name="latin1">
+                <xsl:text> ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
+        </xsl:variable>
+        <!-- Characters that usually don't need to be escaped -->
+        <xsl:variable name="safe">
+                <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
+        </xsl:variable>
+
+        <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
+
+    <!-- Evergreen specific: revert Revision 1.23, so we can have those authority xlink attributes back. -->
+
+        <!--MARC21slim2MODS3-3.xsl
+Revision 1.27 - Mapped 648 to <subject> 2009/03/13 tmee
+Revision 1.26 - Added subfield $s mapping for 130/240/730  2008/10/16 tmee
+Revision 1.25 - Mapped 040e to <descriptiveStandard> and Leader/18 to <descriptive standard>aacr2  2008/09/18 tmee
+Revision 1.24 - Mapped 852 subfields $h, $i, $j, $k, $l, $m, $t to <shelfLocation> and 852 subfield $u to <physicalLocation> with @xlink 2008/09/17 tmee
+Revision 1.23 - Commented out xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711 as these are currently unactionable  2008/09/17  tmee
+Revision 1.22 - Mapped 022 subfield $l to type "issn-l" subfield $m to output identifier element with corresponding @type and @invalid eq 'yes'2008/09/17  tmee
+Revision 1.21 - Mapped 856 ind2=1 or ind2=2 to <relatedItem><location><url>  2008/07/03  tmee
+Revision 1.20 - Added genre w/@auth="contents of 2" and type= "musical composition"  2008/07/01  tmee
+Revision 1.19 - Added genre offprint for 008/24+ BK code 2  2008/07/01  tmee
+Revision 1.18 - Added xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711  2008/06/26  tmee
+Revision 1.17 - Added mapping of 662 2008/05/14 tmee
+Revision 1.16 - Changed @authority from "marc" to "marcgt" for 007 and 008 codes mapped to a term in <genre> 2007/07/10  tmee
+Revision 1.15 - For field 630, moved call to part template outside title element  2007/07/10  tmee
+Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
+Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28  tmee
+Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11  tmee
+Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>  2006/04/08  jrad
+Revision 1.10 - MODS 3.1 revisions to language and classification elements  (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)  2006/02/06  ggar
+Revision 1.9 - Subfield $y was added to field 242 2004/09/02 10:57 jrad
+Revision 1.8 - Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
+Revision 1.7 - 2004/03/25 08:29 jrad
+Revision 1.6 - Various validation fixes 2004/02/20 ntra
+Revision 1.5 - MODS2 to MODS3 updates, language unstacking and de-duping, chopPunctuation expanded  2003/10/02 16:18:58  ntra
+Revision 1.3 - Additional Changes not related to MODS Version 2.0 by ntra
+Revision 1.2 - Added Log Comment  2003/03/24 19:37:42  ckeith
+-->
+        <xsl:template match="/">
+                <xsl:choose>
+                        <xsl:when test="//marc:collection">
+                                <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                        xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
+                                        <xsl:for-each select="//marc:collection/marc:record">
+                                                <mods version="3.3">
+                                                        <xsl:call-template name="marcRecord"/>
+                                                </mods>
+                                        </xsl:for-each>
+                                </modsCollection>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
+                                        xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
+                                        <xsl:for-each select="//marc:record">
+                                                <xsl:call-template name="marcRecord"/>
+                                        </xsl:for-each>
+                                </mods>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="marcRecord">
+                <xsl:variable name="leader" select="marc:leader"/>
+                <xsl:variable name="leader6" select="substring($leader,7,1)"/>
+                <xsl:variable name="leader7" select="substring($leader,8,1)"/>
+                <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
+                <xsl:variable name="typeOf008">
+                        <xsl:choose>
+                                <xsl:when test="$leader6='a'">
+                                        <xsl:choose>
+                                                <xsl:when
+                                                        test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
+                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
+                                        </xsl:choose>
+                                </xsl:when>
+                                <xsl:when test="$leader6='t'">BK</xsl:when>
+                                <xsl:when test="$leader6='p'">MM</xsl:when>
+                                <xsl:when test="$leader6='m'">CF</xsl:when>
+                                <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
+                                <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
+                                <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'"
+                                >MU</xsl:when>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:for-each select="marc:datafield[@tag='245']">
+                        <titleInfo>
+                                <xsl:variable name="title">
+                                        <xsl:choose>
+                                                <xsl:when test="marc:subfield[@code='b']">
+                                                        <xsl:call-template name="specialSubfieldSelect">
+                                                                <xsl:with-param name="axis">b</xsl:with-param>
+                                                                <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:when>
+                                                <xsl:otherwise>
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:otherwise>
+                                        </xsl:choose>
+                                </xsl:variable>
+                                <xsl:variable name="titleChop">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="$title"/>
+                                                </xsl:with-param>
+                                                <xsl:with-param name="punctuation">
+                                                    <xsl:text>,;/ </xsl:text>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:variable>
+                                <xsl:choose>
+                                        <xsl:when test="@ind2&gt;0">
+                                                <nonSort>
+                                                        <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+                                                </nonSort>
+                                                <title>
+                                                        <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+                                                </title>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <title>
+                                                        <xsl:value-of select="$titleChop"/>
+                                                </title>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                                <xsl:if test="marc:subfield[@code='b']">
+                                        <subTitle>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="axis">b</xsl:with-param>
+                                                                        <xsl:with-param name="anyCodes">b</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">afgk</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </subTitle>
+                                </xsl:if>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='210']">
+                        <titleInfo type="abbreviated">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">a</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="subtitle"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='242']">
+                        <titleInfo type="translated">
+                                <!--09/01/04 Added subfield $y-->
+                                <xsl:for-each select="marc:subfield[@code='y']">
+                                        <xsl:attribute name="lang">
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:attribute>
+                                </xsl:for-each>
+                                <xsl:for-each select="marc:subfield[@code='i']">
+                                        <xsl:attribute name="displayLabel">
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:attribute>
+                                </xsl:for-each>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <!-- 1/04 removed $h, b -->
+                                                                <xsl:with-param name="codes">a</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <!-- 1/04 fix -->
+                                <xsl:call-template name="subtitle"/>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='246']">
+                        <titleInfo type="alternative">
+                                <xsl:for-each select="marc:subfield[@code='i']">
+                                        <xsl:attribute name="displayLabel">
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:attribute>
+                                </xsl:for-each>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <!-- 1/04 removed $h, $b -->
+                                                                <xsl:with-param name="codes">af</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="subtitle"/>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each
+                        select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
+                        <titleInfo type="uniform">
+                                <title>
+                                                <xsl:call-template name="uri"/>
+
+                                        <xsl:variable name="str">
+                                                <xsl:for-each select="marc:subfield">
+                                                        <xsl:if
+                                                                test="(contains('adfklmors',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
+                                                                <xsl:value-of select="text()"/>
+                                                                <xsl:text> </xsl:text>
+                                                        </xsl:if>
+                                                </xsl:for-each>
+                                        </xsl:variable>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
+                        <titleInfo type="alternative">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">ah</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='100']">
+                        <name type="personal">
+
+                                <xsl:call-template name="uri"/>
+
+                                <xsl:call-template name="nameABCDQ"/>
+                                <xsl:call-template name="affiliation"/>
+                                <role>
+                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+                                </role>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='110']">
+                        <name type="corporate">
+
+                                        <xsl:call-template name="uri"/>
+
+                                <xsl:call-template name="nameABCDN"/>
+                                <role>
+                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+                                </role>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='111']">
+                        <name type="conference">
+
+                                        <xsl:call-template name="uri"/>
+
+                                <xsl:call-template name="nameACDEQ"/>
+                                <role>
+                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+                                </role>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
+                        <name type="personal">
+
+                                        <xsl:call-template name="uri"/>
+
+                                <xsl:call-template name="nameABCDQ"/>
+                                <xsl:call-template name="affiliation"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
+                        <name type="corporate">
+
+                                        <xsl:call-template name="uri"/>
+
+                                <xsl:call-template name="nameABCDN"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
+                        <name type="conference">
+
+                                        <xsl:call-template name="uri"/>
+
+                                <xsl:call-template name="nameACDEQ"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
+                        <name>
+                                <xsl:if test="@ind1=1">
+                                        <xsl:attribute name="type">
+                                                <xsl:text>personal</xsl:text>
+                                        </xsl:attribute>
+                                </xsl:if>
+                                <namePart>
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </namePart>
+                                <xsl:call-template name="role"/>
+                        </name>
+                </xsl:for-each>
+                <typeOfResource>
+                        <xsl:if test="$leader7='c'">
+                                <xsl:attribute name="collection">yes</xsl:attribute>
+                        </xsl:if>
+                        <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
+                                <xsl:attribute name="manuscript">yes</xsl:attribute>
+                        </xsl:if>
+                        <xsl:choose>
+                                <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
+                                <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
+                                <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
+                                <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
+                                <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
+                                <xsl:when test="$leader6='k'">still image</xsl:when>
+                                <xsl:when test="$leader6='g'">moving image</xsl:when>
+                                <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
+                                <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
+                                <xsl:when test="$leader6='p'">mixed material</xsl:when>
+                        </xsl:choose>
+                </typeOfResource>
+                <xsl:if test="substring($controlField008,26,1)='d'">
+                        <genre authority="marcgt">globe</genre>
+                </xsl:if>
+                <xsl:if
+                        test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
+                        <genre authority="marcgt">remote-sensing image</genre>
+                </xsl:if>
+                <xsl:if test="$typeOf008='MP'">
+                        <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"/>
+                        <xsl:choose>
+                                <xsl:when
+                                        test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
+                                        <genre authority="marcgt">map</genre>
+                                </xsl:when>
+                                <xsl:when
+                                        test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
+                                        <genre authority="marcgt">atlas</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='SE'">
+                        <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"/>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-21='d'">
+                                        <genre authority="marcgt">database</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='l'">
+                                        <genre authority="marcgt">loose-leaf</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='m'">
+                                        <genre authority="marcgt">series</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='n'">
+                                        <genre authority="marcgt">newspaper</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='p'">
+                                        <genre authority="marcgt">periodical</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-21='w'">
+                                        <genre authority="marcgt">web site</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
+                        <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"/>
+                        <xsl:choose>
+                                <xsl:when test="contains($controlField008-24,'a')">
+                                        <genre authority="marcgt">abstract or summary</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'b')">
+                                        <genre authority="marcgt">bibliography</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'c')">
+                                        <genre authority="marcgt">catalog</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'d')">
+                                        <genre authority="marcgt">dictionary</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'e')">
+                                        <genre authority="marcgt">encyclopedia</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'f')">
+                                        <genre authority="marcgt">handbook</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'g')">
+                                        <genre authority="marcgt">legal article</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'i')">
+                                        <genre authority="marcgt">index</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'k')">
+                                        <genre authority="marcgt">discography</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'l')">
+                                        <genre authority="marcgt">legislation</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'m')">
+                                        <genre authority="marcgt">theses</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'n')">
+                                        <genre authority="marcgt">survey of literature</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'o')">
+                                        <genre authority="marcgt">review</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'p')">
+                                        <genre authority="marcgt">programmed text</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'q')">
+                                        <genre authority="marcgt">filmography</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'r')">
+                                        <genre authority="marcgt">directory</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'s')">
+                                        <genre authority="marcgt">statistics</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'t')">
+                                        <genre authority="marcgt">technical report</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'v')">
+                                        <genre authority="marcgt">legal case and case notes</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'w')">
+                                        <genre authority="marcgt">law report or digest</genre>
+                                </xsl:when>
+                                <xsl:when test="contains($controlField008-24,'z')">
+                                        <genre authority="marcgt">treaty</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-29='1'">
+                                        <genre authority="marcgt">conference publication</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='CF'">
+                        <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"/>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-26='a'">
+                                        <genre authority="marcgt">numeric data</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-26='e'">
+                                        <genre authority="marcgt">database</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-26='f'">
+                                        <genre authority="marcgt">font</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-26='g'">
+                                        <genre authority="marcgt">game</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='BK'">
+                        <xsl:if test="substring($controlField008,25,1)='j'">
+                                <genre authority="marcgt">patent</genre>
+                        </xsl:if>
+                        <xsl:if test="substring($controlField008,25,1)='2'">
+                                <genre authority="marcgt">offprint</genre>
+                        </xsl:if>
+                        <xsl:if test="substring($controlField008,31,1)='1'">
+                                <genre authority="marcgt">festschrift</genre>
+                        </xsl:if>
+                        <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"/>
+                        <xsl:if
+                                test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
+                                <genre authority="marcgt">biography</genre>
+                        </xsl:if>
+                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-33='e'">
+                                        <genre authority="marcgt">essay</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='d'">
+                                        <genre authority="marcgt">drama</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='c'">
+                                        <genre authority="marcgt">comic strip</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='l'">
+                                        <genre authority="marcgt">fiction</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='h'">
+                                        <genre authority="marcgt">humor, satire</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='i'">
+                                        <genre authority="marcgt">letter</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='f'">
+                                        <genre authority="marcgt">novel</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='j'">
+                                        <genre authority="marcgt">short story</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='s'">
+                                        <genre authority="marcgt">speech</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:if test="$typeOf008='MU'">
+                        <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>
+                        <xsl:if test="contains($controlField008-30-31,'b')">
+                                <genre authority="marcgt">biography</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'c')">
+                                <genre authority="marcgt">conference publication</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'d')">
+                                <genre authority="marcgt">drama</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'e')">
+                                <genre authority="marcgt">essay</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'f')">
+                                <genre authority="marcgt">fiction</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'o')">
+                                <genre authority="marcgt">folktale</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'h')">
+                                <genre authority="marcgt">history</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'k')">
+                                <genre authority="marcgt">humor, satire</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'m')">
+                                <genre authority="marcgt">memoir</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'p')">
+                                <genre authority="marcgt">poetry</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'r')">
+                                <genre authority="marcgt">rehearsal</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'g')">
+                                <genre authority="marcgt">reporting</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'s')">
+                                <genre authority="marcgt">sound</genre>
+                        </xsl:if>
+                        <xsl:if test="contains($controlField008-30-31,'l')">
+                                <genre authority="marcgt">speech</genre>
+                        </xsl:if>
+                </xsl:if>
+                <xsl:if test="$typeOf008='VM'">
+                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
+                        <xsl:choose>
+                                <xsl:when test="$controlField008-33='a'">
+                                        <genre authority="marcgt">art original</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='b'">
+                                        <genre authority="marcgt">kit</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='c'">
+                                        <genre authority="marcgt">art reproduction</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='d'">
+                                        <genre authority="marcgt">diorama</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='f'">
+                                        <genre authority="marcgt">filmstrip</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='g'">
+                                        <genre authority="marcgt">legal article</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='i'">
+                                        <genre authority="marcgt">picture</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='k'">
+                                        <genre authority="marcgt">graphic</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='l'">
+                                        <genre authority="marcgt">technical drawing</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='m'">
+                                        <genre authority="marcgt">motion picture</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='n'">
+                                        <genre authority="marcgt">chart</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='o'">
+                                        <genre authority="marcgt">flash card</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='p'">
+                                        <genre authority="marcgt">microscope slide</genre>
+                                </xsl:when>
+                                <xsl:when
+                                        test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
+                                        <genre authority="marcgt">model</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='r'">
+                                        <genre authority="marcgt">realia</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='s'">
+                                        <genre authority="marcgt">slide</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='t'">
+                                        <genre authority="marcgt">transparency</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='v'">
+                                        <genre authority="marcgt">videorecording</genre>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-33='w'">
+                                        <genre authority="marcgt">toy</genre>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+
+                <!-- 1.20 047 genre tmee-->
+
+                <xsl:for-each select="marc:datafield[@tag=047]">
+                        <genre authority="marcgt">
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"/>
+                                </xsl:attribute>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abcdef</xsl:with-param>
+                                        <xsl:with-param name="delimeter">-</xsl:with-param>
+                                </xsl:call-template>
+                        </genre>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=655]">
+                        <genre authority="marcgt">
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"/>
+                                </xsl:attribute>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abvxyz</xsl:with-param>
+                                        <xsl:with-param name="delimeter">-</xsl:with-param>
+                                </xsl:call-template>
+                        </genre>
+                </xsl:for-each>
+                <originInfo>
+                        <xsl:variable name="MARCpublicationCode"
+                                select="normalize-space(substring($controlField008,16,3))"/>
+                        <xsl:if test="translate($MARCpublicationCode,'|','')">
+                                <place>
+                                        <placeTerm>
+                                                <xsl:attribute name="type">code</xsl:attribute>
+                                                <xsl:attribute name="authority">marccountry</xsl:attribute>
+                                                <xsl:value-of select="$MARCpublicationCode"/>
+                                        </placeTerm>
+                                </place>
+                        </xsl:if>
+                        <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
+                                <place>
+                                        <placeTerm>
+                                                <xsl:attribute name="type">code</xsl:attribute>
+                                                <xsl:attribute name="authority">iso3166</xsl:attribute>
+                                                <xsl:value-of select="."/>
+                                        </placeTerm>
+                                </place>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
+                                <place>
+                                        <placeTerm>
+                                                <xsl:attribute name="type">text</xsl:attribute>
+                                                <xsl:call-template name="chopPunctuationFront">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="chopPunctuation">
+                                                                        <xsl:with-param name="chopString" select="."/>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </placeTerm>
+                                </place>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
+                                <dateValid point="start">
+                                        <xsl:value-of select="."/>
+                                </dateValid>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
+                                <dateValid point="end">
+                                        <xsl:value-of select="."/>
+                                </dateValid>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
+                                <dateModified>
+                                        <xsl:value-of select="."/>
+                                </dateModified>
+                        </xsl:for-each>
+                        <xsl:for-each
+                                select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
+                                <xsl:choose>
+                                        <xsl:when test="@code='b'">
+                                                <publisher>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                                <xsl:with-param name="punctuation">
+                                                                        <xsl:text>:,;/ </xsl:text>
+                                                                </xsl:with-param>
+                                                        </xsl:call-template>
+                                                </publisher>
+                                        </xsl:when>
+                                        <xsl:when test="@code='c'">
+                                                <dateIssued>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </dateIssued>
+                                        </xsl:when>
+                                        <xsl:when test="@code='g'">
+                                                <dateCreated>
+                                                        <xsl:value-of select="."/>
+                                                </dateCreated>
+                                        </xsl:when>
+                                </xsl:choose>
+                        </xsl:for-each>
+                        <xsl:variable name="dataField260c">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString"
+                                                select="marc:datafield[@tag=260]/marc:subfield[@code='c']"/>
+                                </xsl:call-template>
+                        </xsl:variable>
+                        <xsl:variable name="controlField008-7-10"
+                                select="normalize-space(substring($controlField008, 8, 4))"/>
+                        <xsl:variable name="controlField008-11-14"
+                                select="normalize-space(substring($controlField008, 12, 4))"/>
+                        <xsl:variable name="controlField008-6"
+                                select="normalize-space(substring($controlField008, 7, 1))"/>
+                        <xsl:if
+                                test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
+                                <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
+                                        <dateIssued encoding="marc">
+                                                <xsl:value-of select="$controlField008-7-10"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if
+                                test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+                                <xsl:if test="$controlField008-7-10">
+                                        <dateIssued encoding="marc" point="start">
+                                                <xsl:value-of select="$controlField008-7-10"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if
+                                test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+                                <xsl:if test="$controlField008-11-14">
+                                        <dateIssued encoding="marc" point="end">
+                                                <xsl:value-of select="$controlField008-11-14"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='q'">
+                                <xsl:if test="$controlField008-7-10">
+                                        <dateIssued encoding="marc" point="start" qualifier="questionable">
+                                                <xsl:value-of select="$controlField008-7-10"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='q'">
+                                <xsl:if test="$controlField008-11-14">
+                                        <dateIssued encoding="marc" point="end" qualifier="questionable">
+                                                <xsl:value-of select="$controlField008-11-14"/>
+                                        </dateIssued>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:if test="$controlField008-6='t'">
+                                <xsl:if test="$controlField008-11-14">
+                                        <copyrightDate encoding="marc">
+                                                <xsl:value-of select="$controlField008-11-14"/>
+                                        </copyrightDate>
+                                </xsl:if>
+                        </xsl:if>
+                        <xsl:for-each
+                                select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
+                                <dateCaptured encoding="iso8601">
+                                        <xsl:value-of select="."/>
+                                </dateCaptured>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
+                                <dateCaptured encoding="iso8601" point="start">
+                                        <xsl:value-of select="."/>
+                                </dateCaptured>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
+                                <dateCaptured encoding="iso8601" point="end">
+                                        <xsl:value-of select="."/>
+                                </dateCaptured>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
+                                <edition>
+                                        <xsl:value-of select="."/>
+                                </edition>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:leader">
+                                <issuance>
+                                        <xsl:choose>
+                                                <xsl:when
+                                                        test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'"
+                                                        >monographic</xsl:when>
+                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'"
+                                                >continuing</xsl:when>
+                                        </xsl:choose>
+                                </issuance>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
+                                <frequency>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">ab</xsl:with-param>
+                                        </xsl:call-template>
+                                </frequency>
+                        </xsl:for-each>
+                </originInfo>
+                <xsl:variable name="controlField008-35-37"
+                        select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"/>
+                <xsl:if test="$controlField008-35-37">
+                        <language>
+                                <languageTerm authority="iso639-2b" type="code">
+                                        <xsl:value-of select="substring($controlField008,36,3)"/>
+                                </languageTerm>
+                        </language>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=041]">
+                        <xsl:for-each
+                                select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
+                                <xsl:variable name="langCodes" select="."/>
+                                <xsl:choose>
+                                        <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
+                                                <!-- not stacked but could be repeated -->
+                                                <xsl:call-template name="rfcLanguages">
+                                                        <xsl:with-param name="nodeNum">
+                                                                <xsl:value-of select="1"/>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="usedLanguages">
+                                                                <xsl:text/>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="controlField008-35-37">
+                                                                <xsl:value-of select="$controlField008-35-37"/>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <!-- iso -->
+                                                <xsl:variable name="allLanguages">
+                                                        <xsl:copy-of select="$langCodes"/>
+                                                </xsl:variable>
+                                                <xsl:variable name="currentLanguage">
+                                                        <xsl:value-of select="substring($allLanguages,1,3)"/>
+                                                </xsl:variable>
+                                                <xsl:call-template name="isoLanguage">
+                                                        <xsl:with-param name="currentLanguage">
+                                                                <xsl:value-of select="substring($allLanguages,1,3)"/>
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="remainingLanguages">
+                                                                <xsl:value-of
+                                                                        select="substring($allLanguages,4,string-length($allLanguages)-3)"
+                                                                />
+                                                        </xsl:with-param>
+                                                        <xsl:with-param name="usedLanguages">
+                                                                <xsl:if test="$controlField008-35-37">
+                                                                        <xsl:value-of select="$controlField008-35-37"/>
+                                                                </xsl:if>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </xsl:for-each>
+                </xsl:for-each>
+                <xsl:variable name="physicalDescription">
+                        <!--3.2 change tmee 007/11 -->
+                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
+                                <digitalOrigin>reformatted digital</digitalOrigin>
+                        </xsl:if>
+                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
+                                <digitalOrigin>digitized microfilm</digitalOrigin>
+                        </xsl:if>
+                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
+                                <digitalOrigin>digitized other analog</digitalOrigin>
+                        </xsl:if>
+                        <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"/>
+                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
+                        <xsl:variable name="check008-23">
+                                <xsl:if
+                                        test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
+                                        <xsl:value-of select="true()"/>
+                                </xsl:if>
+                        </xsl:variable>
+                        <xsl:variable name="check008-29">
+                                <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
+                                        <xsl:value-of select="true()"/>
+                                </xsl:if>
+                        </xsl:variable>
+                        <xsl:choose>
+                                <xsl:when
+                                        test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
+                                        <form authority="marcform">braille</form>
+                                </xsl:when>
+                                <xsl:when
+                                        test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
+                                        <form authority="marcform">print</form>
+                                </xsl:when>
+                                <xsl:when
+                                        test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
+                                        <form authority="marcform">electronic</form>
+                                </xsl:when>
+                                <xsl:when
+                                        test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
+                                        <form authority="marcform">microfiche</form>
+                                </xsl:when>
+                                <xsl:when
+                                        test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
+                                        <form authority="marcform">microfilm</form>
+                                </xsl:when>
+                        </xsl:choose>
+                        <!-- 1/04 fix -->
+                        <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"
+                                                        />
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"
+                                                        />
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"
+                                                        />
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"
+                                                        />
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"
+                                                        />
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
+                                <form authority="gmd">
+                                        <xsl:call-template name="chopBrackets">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"
+                                                        />
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </form>
+                        </xsl:if>
+                        <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
+                                <form>
+                                        <xsl:value-of select="."/>
+                                </form>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
+                                <xsl:choose>
+                                        <xsl:when test="substring(text(),14,1)='a'">
+                                                <reformattingQuality>access</reformattingQuality>
+                                        </xsl:when>
+                                        <xsl:when test="substring(text(),14,1)='p'">
+                                                <reformattingQuality>preservation</reformattingQuality>
+                                        </xsl:when>
+                                        <xsl:when test="substring(text(),14,1)='r'">
+                                                <reformattingQuality>replacement</reformattingQuality>
+                                        </xsl:when>
+                                </xsl:choose>
+                        </xsl:for-each>
+                        <!--3.2 change tmee 007/01 -->
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
+                                <form authority="smd">chip cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
+                                <form authority="smd">computer optical disc cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
+                                <form authority="smd">magnetic disc</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
+                                <form authority="smd">magneto-optical disc</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
+                                <form authority="smd">optical disc</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
+                                <form authority="smd">remote</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
+                                <form authority="smd">tape cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
+                                <form authority="smd">tape cassette</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
+                                <form authority="smd">tape reel</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
+                                <form authority="smd">celestial globe</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
+                                <form authority="smd">earth moon globe</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
+                                <form authority="smd">planetary or lunar globe</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
+                                <form authority="smd">terrestrial globe</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
+                                <form authority="smd">kit</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
+                                <form authority="smd">atlas</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
+                                <form authority="smd">diagram</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
+                                <form authority="smd">map</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
+                                <form authority="smd">model</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
+                                <form authority="smd">profile</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
+                                <form authority="smd">remote-sensing image</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
+                                <form authority="smd">section</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
+                                <form authority="smd">view</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
+                                <form authority="smd">aperture card</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
+                                <form authority="smd">microfiche</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
+                                <form authority="smd">microfiche cassette</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
+                                <form authority="smd">microfilm cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
+                                <form authority="smd">microfilm cassette</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
+                                <form authority="smd">microfilm reel</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
+                                <form authority="smd">microopaque</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
+                                <form authority="smd">film cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
+                                <form authority="smd">film cassette</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
+                                <form authority="smd">film reel</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
+                                <form authority="smd">chart</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
+                                <form authority="smd">collage</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
+                                <form authority="smd">drawing</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
+                                <form authority="smd">flash card</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
+                                <form authority="smd">painting</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
+                                <form authority="smd">photomechanical print</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
+                                <form authority="smd">photonegative</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
+                                <form authority="smd">photoprint</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
+                                <form authority="smd">picture</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
+                                <form authority="smd">print</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
+                                <form authority="smd">technical drawing</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
+                                <form authority="smd">notated music</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
+                                <form authority="smd">filmslip</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
+                                <form authority="smd">filmstrip cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
+                                <form authority="smd">filmstrip roll</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
+                                <form authority="smd">other filmstrip type</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
+                                <form authority="smd">slide</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
+                                <form authority="smd">transparency</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
+                                <form authority="smd">remote-sensing image</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
+                                <form authority="smd">cylinder</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
+                                <form authority="smd">roll</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
+                                <form authority="smd">sound cartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
+                                <form authority="smd">sound cassette</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
+                                <form authority="smd">sound disc</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
+                                <form authority="smd">sound-tape reel</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
+                                <form authority="smd">sound-track film</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
+                                <form authority="smd">wire recording</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
+                                <form authority="smd">braille</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
+                                <form authority="smd">combination</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
+                                <form authority="smd">moon</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
+                                <form authority="smd">tactile, with no writing system</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
+                                <form authority="smd">braille</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
+                                <form authority="smd">large print</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
+                                <form authority="smd">regular print</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
+                                <form authority="smd">text in looseleaf binder</form>
+                        </xsl:if>
+
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
+                                <form authority="smd">videocartridge</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
+                                <form authority="smd">videocassette</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
+                                <form authority="smd">videodisc</form>
+                        </xsl:if>
+                        <xsl:if
+                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
+                                <form authority="smd">videoreel</form>
+                        </xsl:if>
+
+                        <xsl:for-each
+                                select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)&gt;1]">
+                                <internetMediaType>
+                                        <xsl:value-of select="."/>
+                                </internetMediaType>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=300]">
+                                <extent>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abce</xsl:with-param>
+                                        </xsl:call-template>
+                                </extent>
+                        </xsl:for-each>
+                </xsl:variable>
+                <xsl:if test="string-length(normalize-space($physicalDescription))">
+                        <physicalDescription>
+                                <xsl:copy-of select="$physicalDescription"/>
+                        </physicalDescription>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=520]">
+                        <abstract>
+                                <xsl:call-template name="uri"/>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </abstract>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=505]">
+                        <tableOfContents>
+                                <xsl:call-template name="uri"/>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">agrt</xsl:with-param>
+                                </xsl:call-template>
+                        </tableOfContents>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=521]">
+                        <targetAudience>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </targetAudience>
+                </xsl:for-each>
+                <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
+                        <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"/>
+                        <xsl:choose>
+                                <!-- 01/04 fix -->
+                                <xsl:when test="$controlField008-22='d'">
+                                        <targetAudience authority="marctarget">adolescent</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='e'">
+                                        <targetAudience authority="marctarget">adult</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='g'">
+                                        <targetAudience authority="marctarget">general</targetAudience>
+                                </xsl:when>
+                                <xsl:when
+                                        test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
+                                        <targetAudience authority="marctarget">juvenile</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='a'">
+                                        <targetAudience authority="marctarget">preschool</targetAudience>
+                                </xsl:when>
+                                <xsl:when test="$controlField008-22='f'">
+                                        <targetAudience authority="marctarget">specialized</targetAudience>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:if>
+                <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
+                        <note type="statement of responsibility">
+                                <xsl:value-of select="."/>
+                        </note>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=500]">
+                        <note>
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                                <xsl:call-template name="uri"/>
+                        </note>
+                </xsl:for-each>
+
+                <!--3.2 change tmee additional note fields-->
+
+                <xsl:for-each select="marc:datafield[@tag=502]">
+                        <note type="thesis">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=504]">
+                        <note type="bibliography">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=508]">
+                        <note type="creation/production credits">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=506]">
+                        <note type="restrictions">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=510]">
+                        <note type="citation/reference">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+
+                <xsl:for-each select="marc:datafield[@tag=511]">
+                        <note type="performers">
+                                <xsl:call-template name="uri"/>
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </note>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=518]">
+                        <note type="venue">
+                                <xsl:call-template name="uri"/>
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=530]">
+                        <note type="additional physical form">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=533]">
+                        <note type="reproduction">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=534]">
+                        <note type="original version">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=538]">
+                        <note type="system details">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=583]">
+                        <note type="action">
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+
+                <xsl:for-each
+                        select="marc:datafield[@tag=501 or @tag=507 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
+                        <note>
+                                <xsl:call-template name="uri"/>
+                                <xsl:variable name="str">
+                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+                                                <xsl:value-of select="."/>
+                                                <xsl:text> </xsl:text>
+                                        </xsl:for-each>
+                                </xsl:variable>
+                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+                        </note>
+                </xsl:for-each>
+                <xsl:for-each
+                        select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
+                        <subject>
+                                <cartographics>
+                                        <coordinates>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">defg</xsl:with-param>
+                                                </xsl:call-template>
+                                        </coordinates>
+                                </cartographics>
+                        </subject>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=043]">
+                        <subject>
+                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
+                                        <geographicCode>
+                                                <xsl:attribute name="authority">
+                                                        <xsl:if test="@code='a'">
+                                                                <xsl:text>marcgac</xsl:text>
+                                                        </xsl:if>
+                                                        <xsl:if test="@code='b'">
+                                                                <xsl:value-of select="following-sibling::marc:subfield[@code=2]"/>
+                                                        </xsl:if>
+                                                        <xsl:if test="@code='c'">
+                                                                <xsl:text>iso3166</xsl:text>
+                                                        </xsl:if>
+                                                </xsl:attribute>
+                                                <xsl:value-of select="self::marc:subfield"/>
+                                        </geographicCode>
+                                </xsl:for-each>
+                        </subject>
+                </xsl:for-each>
+                <!-- tmee 2006/11/27 -->
+                <xsl:for-each select="marc:datafield[@tag=255]">
+                        <subject>
+                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
+                                        <cartographics>
+                                                <xsl:if test="@code='a'">
+                                                        <scale>
+                                                                <xsl:value-of select="."/>
+                                                        </scale>
+                                                </xsl:if>
+                                                <xsl:if test="@code='b'">
+                                                        <projection>
+                                                                <xsl:value-of select="."/>
+                                                        </projection>
+                                                </xsl:if>
+                                                <xsl:if test="@code='c'">
+                                                        <coordinates>
+                                                                <xsl:value-of select="."/>
+                                                        </coordinates>
+                                                </xsl:if>
+                                        </cartographics>
+                                </xsl:for-each>
+                        </subject>
+                </xsl:for-each>
+
+                <xsl:apply-templates select="marc:datafield[653 &gt;= @tag and @tag &gt;= 600]"/>
+                <xsl:apply-templates select="marc:datafield[@tag=656]"/>
+                <xsl:for-each select="marc:datafield[@tag=752 or @tag=662]">
+                        <subject>
+                                <hierarchicalGeographic>
+                                        <xsl:for-each select="marc:subfield[@code='a']">
+                                                <country>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </country>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='b']">
+                                                <state>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </state>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='c']">
+                                                <county>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </county>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='d']">
+                                                <city>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </city>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='e']">
+                                                <citySection>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </citySection>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='g']">
+                                                <region>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </region>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='h']">
+                                                <extraterrestrialArea>
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString" select="."/>
+                                                        </xsl:call-template>
+                                                </extraterrestrialArea>
+                                        </xsl:for-each>
+                                </hierarchicalGeographic>
+                        </subject>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
+                        <subject>
+                                <xsl:choose>
+                                        <xsl:when test="@ind1=2">
+                                                <temporal encoding="iso8601" point="start">
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString">
+                                                                        <xsl:value-of select="marc:subfield[@code='b'][1]"/>
+                                                                </xsl:with-param>
+                                                        </xsl:call-template>
+                                                </temporal>
+                                                <temporal encoding="iso8601" point="end">
+                                                        <xsl:call-template name="chopPunctuation">
+                                                                <xsl:with-param name="chopString">
+                                                                        <xsl:value-of select="marc:subfield[@code='b'][2]"/>
+                                                                </xsl:with-param>
+                                                        </xsl:call-template>
+                                                </temporal>
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <xsl:for-each select="marc:subfield[@code='b']">
+                                                        <temporal encoding="iso8601">
+                                                                <xsl:call-template name="chopPunctuation">
+                                                                        <xsl:with-param name="chopString" select="."/>
+                                                                </xsl:call-template>
+                                                        </temporal>
+                                                </xsl:for-each>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </subject>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=050]">
+                        <xsl:for-each select="marc:subfield[@code='b']">
+                                <classification authority="lcc">
+                                        <xsl:if test="../marc:subfield[@code='3']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:value-of select="../marc:subfield[@code='3']"/>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
+                                        <xsl:text> </xsl:text>
+                                        <xsl:value-of select="text()"/>
+                                </classification>
+                        </xsl:for-each>
+                        <xsl:for-each
+                                select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
+                                <classification authority="lcc">
+                                        <xsl:if test="../marc:subfield[@code='3']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:value-of select="../marc:subfield[@code='3']"/>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="text()"/>
+                                </classification>
+                        </xsl:for-each>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=082]">
+                        <classification authority="ddc">
+                                <xsl:if test="marc:subfield[@code='2']">
+                                        <xsl:attribute name="edition">
+                                                <xsl:value-of select="marc:subfield[@code='2']"/>
+                                        </xsl:attribute>
+                                </xsl:if>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=080]">
+                        <classification authority="udc">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abx</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=060]">
+                        <classification authority="nlm">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
+                        <classification authority="sudocs">
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
+                        <classification authority="candoc">
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=086]">
+                        <classification>
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"/>
+                                </xsl:attribute>
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=084]">
+                        <classification>
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code='2']"/>
+                                </xsl:attribute>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </classification>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=440]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">av</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">av</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=510]">
+                        <relatedItem type="isReferencedBy">
+                                <note>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abcx3</xsl:with-param>
+                                        </xsl:call-template>
+                                </note>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=534]">
+                        <relatedItem type="original">
+                                <xsl:call-template name="relatedTitle"/>
+                                <xsl:call-template name="relatedName"/>
+                                <xsl:if test="marc:subfield[@code='b' or @code='c']">
+                                        <originInfo>
+                                                <xsl:for-each select="marc:subfield[@code='c']">
+                                                        <publisher>
+                                                                <xsl:value-of select="."/>
+                                                        </publisher>
+                                                </xsl:for-each>
+                                                <xsl:for-each select="marc:subfield[@code='b']">
+                                                        <edition>
+                                                                <xsl:value-of select="."/>
+                                                        </edition>
+                                                </xsl:for-each>
+                                        </originInfo>
+                                </xsl:if>
+                                <xsl:call-template name="relatedIdentifierISSN"/>
+                                <xsl:for-each select="marc:subfield[@code='z']">
+                                        <identifier type="isbn">
+                                                <xsl:value-of select="."/>
+                                        </identifier>
+                                </xsl:for-each>
+                                <xsl:call-template name="relatedNote"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"/>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <name type="personal">
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="termsOfAddress"/>
+                                        <xsl:call-template name="nameDate"/>
+                                        <xsl:call-template name="role"/>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                                <xsl:call-template name="relatedIdentifierISSN"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"/>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </titleInfo>
+                                <name type="corporate">
+                                        <xsl:for-each select="marc:subfield[@code='a']">
+                                                <namePart>
+                                                        <xsl:value-of select="."/>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='b']">
+                                                <namePart>
+                                                        <xsl:value-of select="."/>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <xsl:variable name="tempNamePart">
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:variable>
+                                        <xsl:if test="normalize-space($tempNamePart)">
+                                                <namePart>
+                                                        <xsl:value-of select="$tempNamePart"/>
+                                                </namePart>
+                                        </xsl:if>
+                                        <xsl:call-template name="role"/>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                                <xsl:call-template name="relatedIdentifierISSN"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"/>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </titleInfo>
+                                <name type="conference">
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                                <xsl:call-template name="relatedIdentifierISSN"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"/>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <xsl:call-template name="relatedForm"/>
+                                <xsl:call-template name="relatedIdentifierISSN"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
+                        <relatedItem>
+                                <xsl:call-template name="constituentOrRelatedType"/>
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
+                        <relatedItem type="series">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each
+                        select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
+                        <relatedItem>
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=775]">
+                        <relatedItem type="otherVersion">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
+                        <relatedItem type="constituent">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
+                        <relatedItem type="host">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=776]">
+                        <relatedItem type="otherFormat">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=780]">
+                        <relatedItem type="preceding">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=785]">
+                        <relatedItem type="succeeding">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=786]">
+                        <relatedItem type="original">
+                                <xsl:call-template name="relatedItem76X-78X"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=800]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <name type="personal">
+                                        <namePart>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="termsOfAddress"/>
+                                        <xsl:call-template name="nameDate"/>
+                                        <xsl:call-template name="role"/>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=810]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </titleInfo>
+                                <name type="corporate">
+                                        <xsl:for-each select="marc:subfield[@code='a']">
+                                                <namePart>
+                                                        <xsl:value-of select="."/>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <xsl:for-each select="marc:subfield[@code='b']">
+                                                <namePart>
+                                                        <xsl:value-of select="."/>
+                                                </namePart>
+                                        </xsl:for-each>
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="role"/>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=811]">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="specialSubfieldSelect">
+                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+                                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </titleInfo>
+                                <name type="conference">
+                                        <namePart>
+                                                <xsl:call-template name="specialSubfieldSelect">
+                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+                                                        <xsl:with-param name="axis">t</xsl:with-param>
+                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                        <xsl:call-template name="role"/>
+                                </name>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='830']">
+                        <relatedItem type="series">
+                                <titleInfo>
+                                        <title>
+                                                <xsl:call-template name="chopPunctuation">
+                                                        <xsl:with-param name="chopString">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:with-param>
+                                                </xsl:call-template>
+                                        </title>
+                                        <xsl:call-template name="part"/>
+                                </titleInfo>
+                                <xsl:call-template name="relatedForm"/>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
+                        <relatedItem>
+                                <internetMediaType>
+                                        <xsl:value-of select="."/>
+                                </internetMediaType>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='020']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">isbn</xsl:with-param>
+                        </xsl:call-template>
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <identifier type="isbn">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">isrc</xsl:with-param>
+                        </xsl:call-template>
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <identifier type="isrc">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">ismn</xsl:with-param>
+                        </xsl:call-template>
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <identifier type="ismn">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">sici</xsl:with-param>
+                        </xsl:call-template>
+                        <identifier type="sici">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='022']">
+                        <xsl:if test="marc:subfield[@code='a']">
+                                <xsl:call-template name="isInvalid">
+                                        <xsl:with-param name="type">issn</xsl:with-param>
+                                </xsl:call-template>
+                                <identifier type="issn">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </identifier>
+                        </xsl:if>
+                        <xsl:if test="marc:subfield[@code='l']">
+                                <xsl:call-template name="isInvalid">
+                                        <xsl:with-param name="type">issn-l</xsl:with-param>
+                                </xsl:call-template>
+                                <identifier type="issn-l">
+                                        <xsl:value-of select="marc:subfield[@code='l']"/>
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+
+
+
+                <xsl:for-each select="marc:datafield[@tag='010']">
+                        <xsl:call-template name="isInvalid">
+                                <xsl:with-param name="type">lccn</xsl:with-param>
+                        </xsl:call-template>
+                        <identifier type="lccn">
+                                <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='028']">
+                        <identifier>
+                                <xsl:attribute name="type">
+                                        <xsl:choose>
+                                                <xsl:when test="@ind1='0'">issue number</xsl:when>
+                                                <xsl:when test="@ind1='1'">matrix number</xsl:when>
+                                                <xsl:when test="@ind1='2'">music plate</xsl:when>
+                                                <xsl:when test="@ind1='3'">music publisher</xsl:when>
+                                                <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
+                                        </xsl:choose>
+                                </xsl:attribute>
+                                <!--<xsl:call-template name="isInvalid"/>-->
+                                <!-- no $z in 028 -->
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">
+                                                <xsl:choose>
+                                                        <xsl:when test="@ind1='0'">ba</xsl:when>
+                                                        <xsl:otherwise>ab</xsl:otherwise>
+                                                </xsl:choose>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='037']">
+                        <identifier type="stock number">
+                                <!--<xsl:call-template name="isInvalid"/>-->
+                                <!-- no $z in 037 -->
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">ab</xsl:with-param>
+                                </xsl:call-template>
+                        </identifier>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
+                        <identifier>
+                                <xsl:attribute name="type">
+                                        <xsl:choose>
+                                                <xsl:when
+                                                        test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')"
+                                                        >doi</xsl:when>
+                                                <xsl:when
+                                                        test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')"
+                                                        >hdl</xsl:when>
+                                                <xsl:otherwise>uri</xsl:otherwise>
+                                        </xsl:choose>
+                                </xsl:attribute>
+                                <xsl:choose>
+                                        <xsl:when
+                                                test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
+                                                <xsl:value-of
+                                                        select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
+                                                />
+                                        </xsl:when>
+                                        <xsl:otherwise>
+                                                <xsl:value-of select="marc:subfield[@code='u']"/>
+                                        </xsl:otherwise>
+                                </xsl:choose>
+                        </identifier>
+                        <xsl:if
+                                test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
+                                <identifier type="hdl">
+                                        <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
+                                                <xsl:attribute name="displayLabel">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">y3z</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of
+                                                select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
+                                        />
+                                </identifier>
+                        </xsl:if>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
+                        <identifier type="upc">
+                                <xsl:call-template name="isInvalid"/>
+                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                        </identifier>
+                </xsl:for-each>
+
+                <!-- 1/04 fix added $y -->
+
+                <!-- 1.21  tmee-->
+                <xsl:for-each select="marc:datafield[@tag=856][@ind2=1][marc:subfield[@code='u']]">
+                        <relatedItem type="otherVersion">
+                                <location>
+                                        <url>
+                                                <xsl:if test="marc:subfield[@code='y' or @code='3']">
+                                                        <xsl:attribute name="displayLabel">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">y3</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:attribute>
+                                                </xsl:if>
+                                                <xsl:if test="marc:subfield[@code='z' ]">
+                                                        <xsl:attribute name="note">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">z</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:attribute>
+                                                </xsl:if>
+                                                <xsl:value-of select="marc:subfield[@code='u']"/>
+                                        </url>
+                                </location>
+                        </relatedItem>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=856][@ind2=2][marc:subfield[@code='u']]">
+                        <relatedItem>
+                                <location>
+                                        <url>
+                                                <xsl:if test="marc:subfield[@code='y' or @code='3']">
+                                                        <xsl:attribute name="displayLabel">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">y3</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:attribute>
+                                                </xsl:if>
+                                                <xsl:if test="marc:subfield[@code='z' ]">
+                                                        <xsl:attribute name="note">
+                                                                <xsl:call-template name="subfieldSelect">
+                                                                        <xsl:with-param name="codes">z</xsl:with-param>
+                                                                </xsl:call-template>
+                                                        </xsl:attribute>
+                                                </xsl:if>
+                                                <xsl:value-of select="marc:subfield[@code='u']"/>
+                                        </url>
+                                </location>
+                        </relatedItem>
+                </xsl:for-each>
+
+                <!-- 3.2 change tmee 856z  -->
+
+                <!-- 1.24  tmee  -->
+                <xsl:for-each select="marc:datafield[@tag=852]">
+                        <location>
+                                <xsl:if test="marc:subfield[@code='a' or @code='b' or @code='e']">
+                                        <physicalLocation>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">abe</xsl:with-param>
+                                                </xsl:call-template>
+                                        </physicalLocation>
+                                </xsl:if>
+
+                                <xsl:if test="marc:subfield[@code='u']">
+                                        <physicalLocation>
+                                                <xsl:call-template name="uri"/>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">u</xsl:with-param>
+                                                </xsl:call-template>
+                                        </physicalLocation>
+                                </xsl:if>
+
+                                <xsl:if
+                                        test="marc:subfield[@code='h' or @code='i' or @code='j' or @code='k' or @code='l' or @code='m' or @code='t']">
+                                        <shelfLocation>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">hijklmt</xsl:with-param>
+                                                </xsl:call-template>
+                                        </shelfLocation>
+                                </xsl:if>
+                        </location>
+                </xsl:for-each>
+
+                <xsl:for-each select="marc:datafield[@tag=506]">
+                        <accessCondition type="restrictionOnAccess">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abcd35</xsl:with-param>
+                                </xsl:call-template>
+                        </accessCondition>
+                </xsl:for-each>
+                <xsl:for-each select="marc:datafield[@tag=540]">
+                        <accessCondition type="useAndReproduction">
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">abcde35</xsl:with-param>
+                                </xsl:call-template>
+                        </accessCondition>
+                </xsl:for-each>
+
+                <recordInfo>
+                        <!-- 1.25  tmee-->
+
+
+                        <xsl:for-each select="marc:leader[substring($leader,19,1)='a']">
+                                <descriptionStandard>aacr2</descriptionStandard>
+                        </xsl:for-each>
+
+                        <xsl:for-each select="marc:datafield[@tag=040]">
+                                <xsl:if test="marc:subfield[@code='e']">
+                                        <descriptionStandard>
+                                                <xsl:value-of select="marc:subfield[@code='e']"/>
+                                        </descriptionStandard>
+                                </xsl:if>
+                                <recordContentSource authority="marcorg">
+                                        <xsl:value-of select="marc:subfield[@code='a']"/>
+                                </recordContentSource>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=008]">
+                                <recordCreationDate encoding="marc">
+                                        <xsl:value-of select="substring(.,1,6)"/>
+                                </recordCreationDate>
+                        </xsl:for-each>
+
+                        <xsl:for-each select="marc:controlfield[@tag=005]">
+                                <recordChangeDate encoding="iso8601">
+                                        <xsl:value-of select="."/>
+                                </recordChangeDate>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:controlfield[@tag=001]">
+                                <recordIdentifier>
+                                        <xsl:if test="../marc:controlfield[@tag=003]">
+                                                <xsl:attribute name="source">
+                                                        <xsl:value-of select="../marc:controlfield[@tag=003]"/>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <xsl:value-of select="."/>
+                                </recordIdentifier>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
+                                <languageOfCataloging>
+                                        <languageTerm authority="iso639-2b" type="code">
+                                                <xsl:value-of select="."/>
+                                        </languageTerm>
+                                </languageOfCataloging>
+                        </xsl:for-each>
+                </recordInfo>
+        </xsl:template>
+        <xsl:template name="displayForm">
+                <xsl:for-each select="marc:subfield[@code='c']">
+                        <displayForm>
+                                <xsl:value-of select="."/>
+                        </displayForm>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="affiliation">
+                <xsl:for-each select="marc:subfield[@code='u']">
+                        <affiliation>
+                                <xsl:value-of select="."/>
+                        </affiliation>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="uri">
+                <xsl:for-each select="marc:subfield[@code='u']">
+                        <xsl:attribute name="xlink:href">
+                                <xsl:value-of select="."/>
+                        </xsl:attribute>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='0']">
+                        <xsl:choose>
+                                <xsl:when test="contains(text(), ')')">
+                                        <xsl:attribute name="xlink:href">
+                                                <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
+                                        </xsl:attribute>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:attribute name="xlink:href">
+                                                <xsl:value-of select="."></xsl:value-of>
+                                        </xsl:attribute>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="role">
+                <xsl:for-each select="marc:subfield[@code='e']">
+                        <role>
+                                <roleTerm type="text">
+                                        <xsl:value-of select="."/>
+                                </roleTerm>
+                        </role>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='4']">
+                        <role>
+                                <roleTerm authority="marcrelator" type="code">
+                                        <xsl:value-of select="."/>
+                                </roleTerm>
+                        </role>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="part">
+                <xsl:variable name="partNumber">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">n</xsl:with-param>
+                                <xsl:with-param name="anyCodes">n</xsl:with-param>
+                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:variable name="partName">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">p</xsl:with-param>
+                                <xsl:with-param name="anyCodes">p</xsl:with-param>
+                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:if test="string-length(normalize-space($partNumber))">
+                        <partNumber>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="$partNumber"/>
+                                </xsl:call-template>
+                        </partNumber>
+                </xsl:if>
+                <xsl:if test="string-length(normalize-space($partName))">
+                        <partName>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="$partName"/>
+                                </xsl:call-template>
+                        </partName>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedPart">
+                <xsl:if test="@tag=773">
+                        <xsl:for-each select="marc:subfield[@code='g']">
+                                <part>
+                                        <text>
+                                                <xsl:value-of select="."/>
+                                        </text>
+                                </part>
+                        </xsl:for-each>
+                        <xsl:for-each select="marc:subfield[@code='q']">
+                                <part>
+                                        <xsl:call-template name="parsePart"/>
+                                </part>
+                        </xsl:for-each>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedPartNumName">
+                <xsl:variable name="partNumber">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">g</xsl:with-param>
+                                <xsl:with-param name="anyCodes">g</xsl:with-param>
+                                <xsl:with-param name="afterCodes">pst</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:variable name="partName">
+                        <xsl:call-template name="specialSubfieldSelect">
+                                <xsl:with-param name="axis">p</xsl:with-param>
+                                <xsl:with-param name="anyCodes">p</xsl:with-param>
+                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:if test="string-length(normalize-space($partNumber))">
+                        <partNumber>
+                                <xsl:value-of select="$partNumber"/>
+                        </partNumber>
+                </xsl:if>
+                <xsl:if test="string-length(normalize-space($partName))">
+                        <partName>
+                                <xsl:value-of select="$partName"/>
+                        </partName>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedName">
+                <xsl:for-each select="marc:subfield[@code='a']">
+                        <name>
+                                <namePart>
+                                        <xsl:value-of select="."/>
+                                </namePart>
+                        </name>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedForm">
+                <xsl:for-each select="marc:subfield[@code='h']">
+                        <physicalDescription>
+                                <form>
+                                        <xsl:value-of select="."/>
+                                </form>
+                        </physicalDescription>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedExtent">
+                <xsl:for-each select="marc:subfield[@code='h']">
+                        <physicalDescription>
+                                <extent>
+                                        <xsl:value-of select="."/>
+                                </extent>
+                        </physicalDescription>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedNote">
+                <xsl:for-each select="marc:subfield[@code='n']">
+                        <note>
+                                <xsl:value-of select="."/>
+                        </note>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedSubject">
+                <xsl:for-each select="marc:subfield[@code='j']">
+                        <subject>
+                                <temporal encoding="iso8601">
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString" select="."/>
+                                        </xsl:call-template>
+                                </temporal>
+                        </subject>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedIdentifierISSN">
+                <xsl:for-each select="marc:subfield[@code='x']">
+                        <identifier type="issn">
+                                <xsl:value-of select="."/>
+                        </identifier>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedIdentifierLocal">
+                <xsl:for-each select="marc:subfield[@code='w']">
+                        <identifier type="local">
+                                <xsl:value-of select="."/>
+                        </identifier>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedIdentifier">
+                <xsl:for-each select="marc:subfield[@code='o']">
+                        <identifier>
+                                <xsl:value-of select="."/>
+                        </identifier>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedItem76X-78X">
+                <xsl:call-template name="displayLabel"/>
+                <xsl:call-template name="relatedTitle76X-78X"/>
+                <xsl:call-template name="relatedName"/>
+                <xsl:call-template name="relatedOriginInfo"/>
+                <xsl:call-template name="relatedLanguage"/>
+                <xsl:call-template name="relatedExtent"/>
+                <xsl:call-template name="relatedNote"/>
+                <xsl:call-template name="relatedSubject"/>
+                <xsl:call-template name="relatedIdentifier"/>
+                <xsl:call-template name="relatedIdentifierISSN"/>
+                <xsl:call-template name="relatedIdentifierLocal"/>
+                <xsl:call-template name="relatedPart"/>
+        </xsl:template>
+        <xsl:template name="subjectGeographicZ">
+                <geographic>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."/>
+                        </xsl:call-template>
+                </geographic>
+        </xsl:template>
+        <xsl:template name="subjectTemporalY">
+                <temporal>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."/>
+                        </xsl:call-template>
+                </temporal>
+        </xsl:template>
+        <xsl:template name="subjectTopic">
+                <topic>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."/>
+                        </xsl:call-template>
+                </topic>
+        </xsl:template>
+        <!-- 3.2 change tmee 6xx $v genre -->
+        <xsl:template name="subjectGenre">
+                <genre>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="."/>
+                        </xsl:call-template>
+                </genre>
+        </xsl:template>
+
+        <xsl:template name="nameABCDN">
+                <xsl:for-each select="marc:subfield[@code='a']">
+                        <namePart>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="."/>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='b']">
+                        <namePart>
+                                <xsl:value-of select="."/>
+                        </namePart>
+                </xsl:for-each>
+                <xsl:if
+                        test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
+                        <namePart>
+                                <xsl:call-template name="subfieldSelect">
+                                        <xsl:with-param name="codes">cdn</xsl:with-param>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="nameABCDQ">
+                <namePart>
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString">
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">aq</xsl:with-param>
+                                        </xsl:call-template>
+                                </xsl:with-param>
+                                <xsl:with-param name="punctuation">
+                                        <xsl:text>:,;/ </xsl:text>
+                                </xsl:with-param>
+                        </xsl:call-template>
+                </namePart>
+                <xsl:call-template name="termsOfAddress"/>
+                <xsl:call-template name="nameDate"/>
+        </xsl:template>
+        <xsl:template name="nameACDEQ">
+                <namePart>
+                        <xsl:call-template name="subfieldSelect">
+                                <xsl:with-param name="codes">acdeq</xsl:with-param>
+                        </xsl:call-template>
+                </namePart>
+        </xsl:template>
+        <xsl:template name="constituentOrRelatedType">
+                <xsl:if test="@ind2=2">
+                        <xsl:attribute name="type">constituent</xsl:attribute>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedTitle">
+                <xsl:for-each select="marc:subfield[@code='t']">
+                        <titleInfo>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."/>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                        </titleInfo>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedTitle76X-78X">
+                <xsl:for-each select="marc:subfield[@code='t']">
+                        <titleInfo>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."/>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </xsl:if>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='p']">
+                        <titleInfo type="abbreviated">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."/>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </xsl:if>
+                        </titleInfo>
+                </xsl:for-each>
+                <xsl:for-each select="marc:subfield[@code='s']">
+                        <titleInfo type="uniform">
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:value-of select="."/>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+                                        <xsl:call-template name="relatedPartNumName"/>
+                                </xsl:if>
+                        </titleInfo>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="relatedOriginInfo">
+                <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
+                        <originInfo>
+                                <xsl:if test="@tag=775">
+                                        <xsl:for-each select="marc:subfield[@code='f']">
+                                                <place>
+                                                        <placeTerm>
+                                                                <xsl:attribute name="type">code</xsl:attribute>
+                                                                <xsl:attribute name="authority">marcgac</xsl:attribute>
+                                                                <xsl:value-of select="."/>
+                                                        </placeTerm>
+                                                </place>
+                                        </xsl:for-each>
+                                </xsl:if>
+                                <xsl:for-each select="marc:subfield[@code='d']">
+                                        <publisher>
+                                                <xsl:value-of select="."/>
+                                        </publisher>
+                                </xsl:for-each>
+                                <xsl:for-each select="marc:subfield[@code='b']">
+                                        <edition>
+                                                <xsl:value-of select="."/>
+                                        </edition>
+                                </xsl:for-each>
+                        </originInfo>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="relatedLanguage">
+                <xsl:for-each select="marc:subfield[@code='e']">
+                        <xsl:call-template name="getLanguage">
+                                <xsl:with-param name="langString">
+                                        <xsl:value-of select="."/>
+                                </xsl:with-param>
+                        </xsl:call-template>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="nameDate">
+                <xsl:for-each select="marc:subfield[@code='d']">
+                        <namePart type="date">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="."/>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="subjectAuthority">
+                <xsl:if test="@ind2!=4">
+                        <xsl:if test="@ind2!=' '">
+                                <xsl:if test="@ind2!=8">
+                                        <xsl:if test="@ind2!=9">
+                                                <xsl:attribute name="authority">
+                                                        <xsl:choose>
+                                                                <xsl:when test="@ind2=0">lcsh</xsl:when>
+                                                                <xsl:when test="@ind2=1">lcshac</xsl:when>
+                                                                <xsl:when test="@ind2=2">mesh</xsl:when>
+                                                                <!-- 1/04 fix -->
+                                                                <xsl:when test="@ind2=3">nal</xsl:when>
+                                                                <xsl:when test="@ind2=5">csh</xsl:when>
+                                                                <xsl:when test="@ind2=6">rvm</xsl:when>
+                                                                <xsl:when test="@ind2=7">
+                                                                        <xsl:value-of select="marc:subfield[@code='2']"/>
+                                                                </xsl:when>
+                                                        </xsl:choose>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                </xsl:if>
+                        </xsl:if>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="subjectAnyOrder">
+                <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
+                        <xsl:choose>
+                                <xsl:when test="@code='v'">
+                                        <xsl:call-template name="subjectGenre"/>
+                                </xsl:when>
+                                <xsl:when test="@code='x'">
+                                        <xsl:call-template name="subjectTopic"/>
+                                </xsl:when>
+                                <xsl:when test="@code='y'">
+                                        <xsl:call-template name="subjectTemporalY"/>
+                                </xsl:when>
+                                <xsl:when test="@code='z'">
+                                        <xsl:call-template name="subjectGeographicZ"/>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:for-each>
+        </xsl:template>
+        <xsl:template name="specialSubfieldSelect">
+                <xsl:param name="anyCodes"/>
+                <xsl:param name="axis"/>
+                <xsl:param name="beforeCodes"/>
+                <xsl:param name="afterCodes"/>
+                <xsl:variable name="str">
+                        <xsl:for-each select="marc:subfield">
+                                <xsl:if
+                                        test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
+                                        <xsl:value-of select="text()"/>
+                                        <xsl:text> </xsl:text>
+                                </xsl:if>
+                        </xsl:for-each>
+                </xsl:variable>
+                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+        </xsl:template>
+
+        <!-- 3.2 change tmee 6xx $v genre -->
+        <xsl:template match="marc:datafield[@tag=600]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"/>
+                        <name type="personal">
+                                <xsl:call-template name="termsOfAddress"/>
+                                <namePart>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">aq</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </namePart>
+                                <xsl:call-template name="nameDate"/>
+                                <xsl:call-template name="affiliation"/>
+                                <xsl:call-template name="role"/>
+                        </name>
+                        <xsl:call-template name="subjectAnyOrder"/>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=610]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"/>
+                        <name type="corporate">
+                                <xsl:for-each select="marc:subfield[@code='a']">
+                                        <namePart>
+                                                <xsl:value-of select="."/>
+                                        </namePart>
+                                </xsl:for-each>
+                                <xsl:for-each select="marc:subfield[@code='b']">
+                                        <namePart>
+                                                <xsl:value-of select="."/>
+                                        </namePart>
+                                </xsl:for-each>
+                                <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
+                                        <namePart>
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">cdnp</xsl:with-param>
+                                                </xsl:call-template>
+                                        </namePart>
+                                </xsl:if>
+                                <xsl:call-template name="role"/>
+                        </name>
+                        <xsl:call-template name="subjectAnyOrder"/>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=611]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"/>
+                        <name type="conference">
+                                <namePart>
+                                        <xsl:call-template name="subfieldSelect">
+                                                <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
+                                        </xsl:call-template>
+                                </namePart>
+                                <xsl:for-each select="marc:subfield[@code='4']">
+                                        <role>
+                                                <roleTerm authority="marcrelator" type="code">
+                                                        <xsl:value-of select="."/>
+                                                </roleTerm>
+                                        </role>
+                                </xsl:for-each>
+                        </name>
+                        <xsl:call-template name="subjectAnyOrder"/>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=630]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"/>
+                        <titleInfo>
+                                <title>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString">
+                                                        <xsl:call-template name="subfieldSelect">
+                                                                <xsl:with-param name="codes">adfhklor</xsl:with-param>
+                                                        </xsl:call-template>
+                                                </xsl:with-param>
+                                        </xsl:call-template>
+                                </title>
+                                <xsl:call-template name="part"/>
+                        </titleInfo>
+                        <xsl:call-template name="subjectAnyOrder"/>
+                </subject>
+        </xsl:template>
+        <!-- 1.27 648 tmee-->
+        <xsl:template match="marc:datafield[@tag=648]">
+                <subject>
+                        <xsl:if test="marc:subfield[@code=2]">
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code=2]"/>
+                                </xsl:attribute>
+                        </xsl:if>
+                        <xsl:call-template name="uri"/>
+
+                        <xsl:call-template name="subjectAuthority"/>
+                        <temporal>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">abcd</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </temporal>
+                        <xsl:call-template name="subjectAnyOrder"/>
+
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=650]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"/>
+                        <topic>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">abcd</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </topic>
+                        <xsl:call-template name="subjectAnyOrder"/>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=651]">
+                <subject>
+                        <xsl:call-template name="subjectAuthority"/>
+                        <xsl:for-each select="marc:subfield[@code='a']">
+                                <geographic>
+                                        <xsl:call-template name="chopPunctuation">
+                                                <xsl:with-param name="chopString" select="."/>
+                                        </xsl:call-template>
+                                </geographic>
+                        </xsl:for-each>
+                        <xsl:call-template name="subjectAnyOrder"/>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=653]">
+                <subject>
+                        <xsl:for-each select="marc:subfield[@code='a']">
+                                <topic>
+                                        <xsl:value-of select="."/>
+                                </topic>
+                        </xsl:for-each>
+                </subject>
+        </xsl:template>
+        <xsl:template match="marc:datafield[@tag=656]">
+                <subject>
+                        <xsl:if test="marc:subfield[@code=2]">
+                                <xsl:attribute name="authority">
+                                        <xsl:value-of select="marc:subfield[@code=2]"/>
+                                </xsl:attribute>
+                        </xsl:if>
+                        <occupation>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:value-of select="marc:subfield[@code='a']"/>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </occupation>
+                </subject>
+        </xsl:template>
+        <xsl:template name="termsOfAddress">
+                <xsl:if test="marc:subfield[@code='b' or @code='c']">
+                        <namePart type="termsOfAddress">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">bc</xsl:with-param>
+                                                </xsl:call-template>
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </namePart>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="displayLabel">
+                <xsl:if test="marc:subfield[@code='i']">
+                        <xsl:attribute name="displayLabel">
+                                <xsl:value-of select="marc:subfield[@code='i']"/>
+                        </xsl:attribute>
+                </xsl:if>
+                <xsl:if test="marc:subfield[@code='3']">
+                        <xsl:attribute name="displayLabel">
+                                <xsl:value-of select="marc:subfield[@code='3']"/>
+                        </xsl:attribute>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="isInvalid">
+                <xsl:param name="type"/>
+                <xsl:if
+                        test="marc:subfield[@code='z'] or marc:subfield[@code='y']  or marc:subfield[@code='m']">
+                        <identifier>
+                                <xsl:attribute name="type">
+                                        <xsl:value-of select="$type"/>
+                                </xsl:attribute>
+                                <xsl:attribute name="invalid">
+                                        <xsl:text>yes</xsl:text>
+                                </xsl:attribute>
+                                <xsl:if test="marc:subfield[@code='z']">
+                                        <xsl:value-of select="marc:subfield[@code='z']"/>
+                                </xsl:if>
+                                <xsl:if test="marc:subfield[@code='y']">
+                                        <xsl:value-of select="marc:subfield[@code='y']"/>
+                                </xsl:if>
+                                <xsl:if test="marc:subfield[@code='m']">
+                                        <xsl:value-of select="marc:subfield[@code='m']"/>
+                                </xsl:if>
+                        </identifier>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="subtitle">
+                <xsl:if test="marc:subfield[@code='b']">
+                        <subTitle>
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString">
+                                                <xsl:value-of select="marc:subfield[@code='b']"/>
+                                                <!--<xsl:call-template name="subfieldSelect">
+                                                        <xsl:with-param name="codes">b</xsl:with-param>
+                                                </xsl:call-template>-->
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </subTitle>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="script">
+                <xsl:param name="scriptCode"/>
+                <xsl:attribute name="script">
+                        <xsl:choose>
+                                <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
+                                <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
+                                <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
+                                <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
+                                <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
+                                <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
+                        </xsl:choose>
+                </xsl:attribute>
+        </xsl:template>
+        <xsl:template name="parsePart">
+                <!-- assumes 773$q= 1:2:3<4
+                     with up to 3 levels and one optional start page
+                -->
+                <xsl:variable name="level1">
+                        <xsl:choose>
+                                <xsl:when test="contains(text(),':')">
+                                        <!-- 1:2 -->
+                                        <xsl:value-of select="substring-before(text(),':')"/>
+                                </xsl:when>
+                                <xsl:when test="not(contains(text(),':'))">
+                                        <!-- 1 or 1<3 -->
+                                        <xsl:if test="contains(text(),'&lt;')">
+                                                <!-- 1<3 -->
+                                                <xsl:value-of select="substring-before(text(),'&lt;')"/>
+                                        </xsl:if>
+                                        <xsl:if test="not(contains(text(),'&lt;'))">
+                                                <!-- 1 -->
+                                                <xsl:value-of select="text()"/>
+                                        </xsl:if>
+                                </xsl:when>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="sici2">
+                        <xsl:choose>
+                                <xsl:when test="starts-with(substring-after(text(),$level1),':')">
+                                        <xsl:value-of select="substring(substring-after(text(),$level1),2)"/>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="substring-after(text(),$level1)"/>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="level2">
+                        <xsl:choose>
+                                <xsl:when test="contains($sici2,':')">
+                                        <!--  2:3<4  -->
+                                        <xsl:value-of select="substring-before($sici2,':')"/>
+                                </xsl:when>
+                                <xsl:when test="contains($sici2,'&lt;')">
+                                        <!-- 1: 2<4 -->
+                                        <xsl:value-of select="substring-before($sici2,'&lt;')"/>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="$sici2"/>
+                                        <!-- 1:2 -->
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="sici3">
+                        <xsl:choose>
+                                <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
+                                        <xsl:value-of select="substring(substring-after($sici2,$level2),2)"/>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="substring-after($sici2,$level2)"/>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="level3">
+                        <xsl:choose>
+                                <xsl:when test="contains($sici3,'&lt;')">
+                                        <!-- 2<4 -->
+                                        <xsl:value-of select="substring-before($sici3,'&lt;')"/>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:value-of select="$sici3"/>
+                                        <!-- 3 -->
+                                </xsl:otherwise>
+                        </xsl:choose>
+                </xsl:variable>
+                <xsl:variable name="page">
+                        <xsl:if test="contains(text(),'&lt;')">
+                                <xsl:value-of select="substring-after(text(),'&lt;')"/>
+                        </xsl:if>
+                </xsl:variable>
+                <xsl:if test="$level1">
+                        <detail level="1">
+                                <number>
+                                        <xsl:value-of select="$level1"/>
+                                </number>
+                        </detail>
+                </xsl:if>
+                <xsl:if test="$level2">
+                        <detail level="2">
+                                <number>
+                                        <xsl:value-of select="$level2"/>
+                                </number>
+                        </detail>
+                </xsl:if>
+                <xsl:if test="$level3">
+                        <detail level="3">
+                                <number>
+                                        <xsl:value-of select="$level3"/>
+                                </number>
+                        </detail>
+                </xsl:if>
+                <xsl:if test="$page">
+                        <extent unit="page">
+                                <start>
+                                        <xsl:value-of select="$page"/>
+                                </start>
+                        </extent>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="getLanguage">
+                <xsl:param name="langString"/>
+                <xsl:param name="controlField008-35-37"/>
+                <xsl:variable name="length" select="string-length($langString)"/>
+                <xsl:choose>
+                        <xsl:when test="$length=0"/>
+                        <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
+                                <xsl:call-template name="getLanguage">
+                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
+                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <language>
+                                        <languageTerm authority="iso639-2b" type="code">
+                                                <xsl:value-of select="substring($langString,1,3)"/>
+                                        </languageTerm>
+                                </language>
+                                <xsl:call-template name="getLanguage">
+                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
+                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
+                                </xsl:call-template>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="isoLanguage">
+                <xsl:param name="currentLanguage"/>
+                <xsl:param name="usedLanguages"/>
+                <xsl:param name="remainingLanguages"/>
+                <xsl:choose>
+                        <xsl:when test="string-length($currentLanguage)=0"/>
+                        <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
+                                <language>
+                                        <xsl:if test="@code!='a'">
+                                                <xsl:attribute name="objectPart">
+                                                        <xsl:choose>
+                                                                <xsl:when test="@code='b'">summary or subtitle</xsl:when>
+                                                                <xsl:when test="@code='d'">sung or spoken text</xsl:when>
+                                                                <xsl:when test="@code='e'">libretto</xsl:when>
+                                                                <xsl:when test="@code='f'">table of contents</xsl:when>
+                                                                <xsl:when test="@code='g'">accompanying material</xsl:when>
+                                                                <xsl:when test="@code='h'">translation</xsl:when>
+                                                        </xsl:choose>
+                                                </xsl:attribute>
+                                        </xsl:if>
+                                        <languageTerm authority="iso639-2b" type="code">
+                                                <xsl:value-of select="$currentLanguage"/>
+                                        </languageTerm>
+                                </language>
+                                <xsl:call-template name="isoLanguage">
+                                        <xsl:with-param name="currentLanguage">
+                                                <xsl:value-of select="substring($remainingLanguages,1,3)"/>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="usedLanguages">
+                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="remainingLanguages">
+                                                <xsl:value-of
+                                                        select="substring($remainingLanguages,4,string-length($remainingLanguages))"
+                                                />
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <xsl:call-template name="isoLanguage">
+                                        <xsl:with-param name="currentLanguage">
+                                                <xsl:value-of select="substring($remainingLanguages,1,3)"/>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="usedLanguages">
+                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+                                        </xsl:with-param>
+                                        <xsl:with-param name="remainingLanguages">
+                                                <xsl:value-of
+                                                        select="substring($remainingLanguages,4,string-length($remainingLanguages))"
+                                                />
+                                        </xsl:with-param>
+                                </xsl:call-template>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <xsl:template name="chopBrackets">
+                <xsl:param name="chopString"/>
+                <xsl:variable name="string">
+                        <xsl:call-template name="chopPunctuation">
+                                <xsl:with-param name="chopString" select="$chopString"/>
+                        </xsl:call-template>
+                </xsl:variable>
+                <xsl:if test="substring($string, 1,1)='['">
+                        <xsl:value-of select="substring($string,2, string-length($string)-2)"/>
+                </xsl:if>
+                <xsl:if test="substring($string, 1,1)!='['">
+                        <xsl:value-of select="$string"/>
+                </xsl:if>
+        </xsl:template>
+        <xsl:template name="rfcLanguages">
+                <xsl:param name="nodeNum"/>
+                <xsl:param name="usedLanguages"/>
+                <xsl:param name="controlField008-35-37"/>
+                <xsl:variable name="currentLanguage" select="."/>
+                <xsl:choose>
+                        <xsl:when test="not($currentLanguage)"/>
+                        <xsl:when
+                                test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
+                                <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
+                                        <language>
+                                                <xsl:if test="@code!='a'">
+                                                        <xsl:attribute name="objectPart">
+                                                                <xsl:choose>
+                                                                        <xsl:when test="@code='b'">summary or subtitle</xsl:when>
+                                                                        <xsl:when test="@code='d'">sung or spoken text</xsl:when>
+                                                                        <xsl:when test="@code='e'">libretto</xsl:when>
+                                                                        <xsl:when test="@code='f'">table of contents</xsl:when>
+                                                                        <xsl:when test="@code='g'">accompanying material</xsl:when>
+                                                                        <xsl:when test="@code='h'">translation</xsl:when>
+                                                                </xsl:choose>
+                                                        </xsl:attribute>
+                                                </xsl:if>
+                                                <languageTerm authority="rfc3066" type="code">
+                                                        <xsl:value-of select="$currentLanguage"/>
+                                                </languageTerm>
+                                        </language>
+                                </xsl:if>
+                        </xsl:when>
+                        <xsl:otherwise> </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+
+    <xsl:template name="datafield">
+                <xsl:param name="tag"/>
+                <xsl:param name="ind1">
+                        <xsl:text> </xsl:text>
+                </xsl:param>
+                <xsl:param name="ind2">
+                        <xsl:text> </xsl:text>
+                </xsl:param>
+                <xsl:param name="subfields"/>
+                <xsl:element name="marc:datafield">
+                        <xsl:attribute name="tag">
+                                <xsl:value-of select="$tag"/>
+                        </xsl:attribute>
+                        <xsl:attribute name="ind1">
+                                <xsl:value-of select="$ind1"/>
+                        </xsl:attribute>
+                        <xsl:attribute name="ind2">
+                                <xsl:value-of select="$ind2"/>
+                        </xsl:attribute>
+                        <xsl:copy-of select="$subfields"/>
+                </xsl:element>
+        </xsl:template>
+
+        <xsl:template name="subfieldSelect">
+                <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
+                <xsl:param name="delimeter">
+                        <xsl:text> </xsl:text>
+                </xsl:param>
+                <xsl:variable name="str">
+                        <xsl:for-each select="marc:subfield">
+                                <xsl:if test="contains($codes, @code)">
+                                        <xsl:value-of select="text()"/>
+                                        <xsl:value-of select="$delimeter"/>
+                                </xsl:if>
+                        </xsl:for-each>
+                </xsl:variable>
+                <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
+        </xsl:template>
+
+        <xsl:template name="buildSpaces">
+                <xsl:param name="spaces"/>
+                <xsl:param name="char">
+                        <xsl:text> </xsl:text>
+                </xsl:param>
+                <xsl:if test="$spaces>0">
+                        <xsl:value-of select="$char"/>
+                        <xsl:call-template name="buildSpaces">
+                                <xsl:with-param name="spaces" select="$spaces - 1"/>
+                                <xsl:with-param name="char" select="$char"/>
+                        </xsl:call-template>
+                </xsl:if>
+        </xsl:template>
+
+        <xsl:template name="chopPunctuation">
+                <xsl:param name="chopString"/>
+                <xsl:param name="punctuation">
+                        <xsl:text>.:,;/ </xsl:text>
+                </xsl:param>
+                <xsl:variable name="length" select="string-length($chopString)"/>
+                <xsl:choose>
+                        <xsl:when test="$length=0"/>
+                        <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+                                        <xsl:with-param name="punctuation" select="$punctuation"/>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:when test="not($chopString)"/>
+                        <xsl:otherwise>
+                                <xsl:value-of select="$chopString"/>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+
+        <xsl:template name="chopPunctuationFront">
+                <xsl:param name="chopString"/>
+                <xsl:variable name="length" select="string-length($chopString)"/>
+                <xsl:choose>
+                        <xsl:when test="$length=0"/>
+                        <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
+                                <xsl:call-template name="chopPunctuationFront">
+                                        <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
+                                        />
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:when test="not($chopString)"/>
+                        <xsl:otherwise>
+                                <xsl:value-of select="$chopString"/>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+
+        <xsl:template name="chopPunctuationBack">
+                <xsl:param name="chopString"/>
+                <xsl:param name="punctuation">
+                        <xsl:text>.:,;/] </xsl:text>
+                </xsl:param>
+                <xsl:variable name="length" select="string-length($chopString)"/>
+                <xsl:choose>
+                        <xsl:when test="$length=0"/>
+                        <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+                                <xsl:call-template name="chopPunctuation">
+                                        <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+                                        <xsl:with-param name="punctuation" select="$punctuation"/>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:when test="not($chopString)"/>
+                        <xsl:otherwise>
+                                <xsl:value-of select="$chopString"/>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+
+        <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
+        <xsl:template name="url-encode">
+
+                <xsl:param name="str"/>
+
+                <xsl:if test="$str">
+                        <xsl:variable name="first-char" select="substring($str,1,1)"/>
+                        <xsl:choose>
+                                <xsl:when test="contains($safe,$first-char)">
+                                        <xsl:value-of select="$first-char"/>
+                                </xsl:when>
+                                <xsl:otherwise>
+                                        <xsl:variable name="codepoint">
+                                                <xsl:choose>
+                                                        <xsl:when test="contains($ascii,$first-char)">
+                                                                <xsl:value-of
+                                                                        select="string-length(substring-before($ascii,$first-char)) + 32"
+                                                                />
+                                                        </xsl:when>
+                                                        <xsl:when test="contains($latin1,$first-char)">
+                                                                <xsl:value-of
+                                                                        select="string-length(substring-before($latin1,$first-char)) + 160"/>
+                                                                <!-- was 160 -->
+                                                        </xsl:when>
+                                                        <xsl:otherwise>
+                                                                <xsl:message terminate="no">Warning: string contains a character
+                                                                        that is out of range! Substituting "?".</xsl:message>
+                                                                <xsl:text>63</xsl:text>
+                                                        </xsl:otherwise>
+                                                </xsl:choose>
+                                        </xsl:variable>
+                                        <xsl:variable name="hex-digit1"
+                                                select="substring($hex,floor($codepoint div 16) + 1,1)"/>
+                                        <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
+                                        <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
+                                        <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
+                                </xsl:otherwise>
+                        </xsl:choose>
+                        <xsl:if test="string-length($str) &gt; 1">
+                                <xsl:call-template name="url-encode">
+                                        <xsl:with-param name="str" select="substring($str,2)"/>
+                                </xsl:call-template>
+                        </xsl:if>
+                </xsl:if>
+        </xsl:template>
+</xsl:stylesheet>$XXXX$ where name = $$mods33$$;
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1103', :eg_version);
+
+DO $INSERT$                                                                    
+BEGIN                                                                          
+    IF evergreen.insert_on_deploy() THEN
+
+INSERT INTO config.metabib_field (id, field_class, name, label, browse_field)
+    VALUES (45, 'keyword', 'blob', 'All searchable fields', FALSE);
+
+INSERT INTO config.metabib_field (id, field_class, name, format, weight,
+    label, xpath, display_field, search_field, browse_field, facet_field)
+VALUES (
+    53, 'title', 'maintitle', 'marcxml', 10,
+    oils_i18n_gettext(53, 'Main Title', 'cmf', 'label'),
+    $$//*[@tag='245']/*[@code='a']$$,
+    FALSE, TRUE, FALSE, FALSE
+);
+
+INSERT INTO config.metabib_field_virtual_map (real, virtual)
+    SELECT  id,
+            45
+      FROM  config.metabib_field
+      WHERE search_field
+            AND id NOT IN (15, 45, 38, 40) -- keyword|keyword, self, edition, publisher
+            AND id NOT IN (SELECT real FROM config.metabib_field_virtual_map);
+
+UPDATE config.metabib_field SET xpath=$$//mods32:mods/mods32:subject[not(descendant::mods32:geographicCode)]$$ WHERE id = 16;
+
+UPDATE config.metabib_field_virtual_map SET weight = -1 WHERE real = 39;
+UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 41;
+UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 42;
+UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 46;
+UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 47;
+UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 48;
+UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 50;
+UPDATE config.metabib_field_virtual_map SET weight = 8 WHERE real = 6;
+UPDATE config.metabib_field_virtual_map SET weight = 8 WHERE real = 8;
+UPDATE config.metabib_field_virtual_map SET weight = 8 WHERE real = 16;
+UPDATE config.metabib_field_virtual_map SET weight = 12 WHERE real = 53;
+
+-- Stemming for genre
+INSERT INTO config.metabib_field_ts_map (metabib_field, ts_config)
+    SELECT 33, 'english_nostop' WHERE NOT EXISTS (
+        SELECT 1 FROM config.metabib_field_ts_map WHERE metabib_field = 33 AND ts_config = 'english_nostop'
+    )
+;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1104', :eg_version);
+
+INSERT INTO config.org_unit_setting_type
+( name, grp, label, description, datatype )
+VALUES
+       ('circ.clear_hold_on_checkout',
+        'circ',
+       oils_i18n_gettext('circ.clear_hold_on_checkout',
+               'Clear hold when other patron checks out item',
+               'coust', 'label'),
+        oils_i18n_gettext('circ.clear_hold_on_checkout',
+            'Default to cancel the hold when patron A checks out item on hold for patron B.',
+               'coust', 'description'),
+       'bool');
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1105', :eg_version);
+
+INSERT into config.org_unit_setting_type (name, label, grp, description, datatype) 
+values ('webstaff.circ.itemsout_notice_count_excludes_courtesies','Exclude Courtesy Notices from Patrons Itemsout Notices Count',
+    'circ', 'Exclude Courtesy Notices from Patron Itemsout Notices Count', 'bool');
+
+    END IF;                                                                    
+END $INSERT$;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1106', :eg_version);
+
+ALTER TABLE money.billing
+       ADD COLUMN create_date TIMESTAMP WITH TIME ZONE,
+       ADD COLUMN period_start    TIMESTAMP WITH TIME ZONE,
+       ADD COLUMN period_end  TIMESTAMP WITH TIME ZONE;
+
+--Disable materialized update trigger
+--It takes forever, and doesn't matter yet for what we are doing, as the
+--view definition is unchanged (still using billing_ts)
+ALTER TABLE money.billing DISABLE TRIGGER mat_summary_upd_tgr;
+
+--Limit to btype=1 / 'Overdue Materials'
+--Update day-granular fines first (i.e. 24 hour, 1 day, 2 day, etc., all of which are multiples of 86400 seconds), and simply remove the time portion of timestamp
+UPDATE money.billing mb
+       SET period_start = date_trunc('day', billing_ts), period_end = date_trunc('day', billing_ts) + (ac.fine_interval - '1 second')
+       FROM action.circulation ac
+WHERE mb.xact = ac.id
+       AND mb.btype = 1
+       AND (EXTRACT(EPOCH FROM ac.fine_interval))::integer % 86400 = 0;
+
+--Update fines for non-day intervals
+UPDATE money.billing mb
+       SET period_start = billing_ts - ac.fine_interval + interval '1 sec', period_end = billing_ts
+       FROM action.circulation ac
+WHERE mb.xact = ac.id
+       AND mb.btype = 1
+       AND (EXTRACT(EPOCH FROM ac.fine_interval))::integer % 86400 > 0;
+
+SET CONSTRAINTS ALL IMMEDIATE;
+UPDATE money.billing SET create_date = COALESCE(period_start, billing_ts);
+
+--Re-enable update trigger
+ALTER TABLE money.billing ENABLE TRIGGER mat_summary_upd_tgr;
+
+ALTER TABLE money.billing ALTER COLUMN create_date SET DEFAULT NOW();
+ALTER TABLE money.billing ALTER COLUMN create_date SET NOT NULL;
+
+CREATE INDEX m_b_create_date_idx ON money.billing (create_date);
+CREATE INDEX m_b_period_start_idx ON money.billing (period_start);
+CREATE INDEX m_b_period_end_idx ON money.billing (period_end);
+
+CREATE OR REPLACE FUNCTION money.maintain_billing_ts () RETURNS TRIGGER AS $$
+BEGIN
+       NEW.billing_ts := COALESCE(NEW.period_end, NEW.create_date);
+       RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+CREATE TRIGGER maintain_billing_ts_tgr BEFORE INSERT OR UPDATE ON money.billing FOR EACH ROW EXECUTE PROCEDURE money.maintain_billing_ts();
+
+  
+--SELECT evergreen.upgrade_deps_block_check('1108', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
+DECLARE
+    moved_objects INT := 0;
+    source_cn     asset.call_number%ROWTYPE;
+    target_cn     asset.call_number%ROWTYPE;
+    metarec       metabib.metarecord%ROWTYPE;
+    hold          action.hold_request%ROWTYPE;
+    ser_rec       serial.record_entry%ROWTYPE;
+    ser_sub       serial.subscription%ROWTYPE;
+    acq_lineitem  acq.lineitem%ROWTYPE;
+    acq_request   acq.user_request%ROWTYPE;
+    booking       booking.resource_type%ROWTYPE;
+    source_part   biblio.monograph_part%ROWTYPE;
+    target_part   biblio.monograph_part%ROWTYPE;
+    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
+    uri_count     INT := 0;
+    counter       INT := 0;
+    uri_datafield TEXT;
+    uri_text      TEXT := '';
+BEGIN
+
+    -- move any 856 entries on records that have at least one MARC-mapped URI entry
+    SELECT  INTO uri_count COUNT(*)
+      FROM  asset.uri_call_number_map m
+            JOIN asset.call_number cn ON (m.call_number = cn.id)
+      WHERE cn.record = source_record;
+
+    IF uri_count > 0 THEN
+        
+        -- This returns more nodes than you might expect:
+        -- 7 instead of 1 for an 856 with $u $y $9
+        SELECT  COUNT(*) INTO counter
+          FROM  oils_xpath_table(
+                    'id',
+                    'marc',
+                    'biblio.record_entry',
+                    '//*[@tag="856"]',
+                    'id=' || source_record
+                ) as t(i int,c text);
+    
+        FOR i IN 1 .. counter LOOP
+            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
+                       ' tag="856"' ||
+                       ' ind1="' || FIRST(ind1) || '"'  ||
+                       ' ind2="' || FIRST(ind2) || '">' ||
+                        STRING_AGG(
+                            '<subfield code="' || subfield || '">' ||
+                            regexp_replace(
+                                regexp_replace(
+                                    regexp_replace(data,'&','&amp;','g'),
+                                    '>', '&gt;', 'g'
+                                ),
+                                '<', '&lt;', 'g'
+                            ) || '</subfield>', ''
+                        ) || '</datafield>' INTO uri_datafield
+              FROM  oils_xpath_table(
+                        'id',
+                        'marc',
+                        'biblio.record_entry',
+                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
+                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
+                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
+                        'id=' || source_record
+                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
+
+            -- As most of the results will be NULL, protect against NULLifying
+            -- the valid content that we do generate
+            uri_text := uri_text || COALESCE(uri_datafield, '');
+        END LOOP;
+
+        IF uri_text <> '' THEN
+            UPDATE  biblio.record_entry
+              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
+              WHERE id = target_record;
+        END IF;
+
+    END IF;
+
+       -- Find and move metarecords to the target record
+       SELECT  INTO metarec *
+         FROM  metabib.metarecord
+         WHERE master_record = source_record;
+
+       IF FOUND THEN
+               UPDATE  metabib.metarecord
+                 SET   master_record = target_record,
+                       mods = NULL
+                 WHERE id = metarec.id;
+
+               moved_objects := moved_objects + 1;
+       END IF;
+
+       -- Find call numbers attached to the source ...
+       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
+
+               SELECT  INTO target_cn *
+                 FROM  asset.call_number
+                 WHERE label = source_cn.label
+            AND prefix = source_cn.prefix
+            AND suffix = source_cn.suffix
+                       AND owning_lib = source_cn.owning_lib
+                       AND record = target_record
+                       AND NOT deleted;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copies to that, and ...
+                       UPDATE  asset.copy
+                         SET   call_number = target_cn.id
+                         WHERE call_number = source_cn.id;
+
+                       -- ... move V holds to the move-target call number
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_cn.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+        
+            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the call number to the target record
+                       UPDATE  asset.call_number
+                         SET   record = target_record
+                         WHERE id = source_cn.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find T holds targeting the source record ...
+       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
+
+               -- ... and move them to the target record
+               UPDATE  action.hold_request
+                 SET   target = target_record
+                 WHERE id = hold.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial records targeting the source record ...
+       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.record_entry
+                 SET   record = target_record
+                 WHERE id = ser_rec.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find serial subscriptions targeting the source record ...
+       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  serial.subscription
+                 SET   record_entry = target_record
+                 WHERE id = ser_sub.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find booking resource types targeting the source record ...
+       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  booking.resource_type
+                 SET   record = target_record
+                 WHERE id = booking.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq lineitems targeting the source record ...
+       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.lineitem
+                 SET   eg_bib_id = target_record
+                 WHERE id = acq_lineitem.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find acq user purchase requests targeting the source record ...
+       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  acq.user_request
+                 SET   eg_bib = target_record
+                 WHERE id = acq_request.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find parts attached to the source ...
+       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
+
+               SELECT  INTO target_part *
+                 FROM  biblio.monograph_part
+                 WHERE label = source_part.label
+                       AND record = target_record;
+
+               -- ... and if there's a conflicting one on the target ...
+               IF FOUND THEN
+
+                       -- ... move the copy-part maps to that, and ...
+                       UPDATE  asset.copy_part_map
+                         SET   part = target_part.id
+                         WHERE part = source_part.id;
+
+                       -- ... move P holds to the move-target part
+                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
+               
+                               UPDATE  action.hold_request
+                                 SET   target = target_part.id
+                                 WHERE id = hold.id;
+               
+                               moved_objects := moved_objects + 1;
+                       END LOOP;
+
+               -- ... if not ...
+               ELSE
+                       -- ... just move the part to the target record
+                       UPDATE  biblio.monograph_part
+                         SET   record = target_record
+                         WHERE id = source_part.id;
+               END IF;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- Find multi_home items attached to the source ...
+       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
+               -- ... and move them to the target record
+               UPDATE  biblio.peer_bib_copy_map
+                 SET   peer_record = target_record
+                 WHERE id = multi_home.id;
+
+               moved_objects := moved_objects + 1;
+       END LOOP;
+
+       -- And delete mappings where the item's home bib was merged with the peer bib
+       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
+               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
+               FROM asset.copy WHERE id = target_copy
+       );
+
+    -- Apply merge tracking
+    UPDATE biblio.record_entry 
+        SET merge_date = NOW() WHERE id = target_record;
+
+    UPDATE biblio.record_entry
+        SET merge_date = NOW(), merged_to = target_record
+        WHERE id = source_record;
+
+    -- replace book bag entries of source_record with target_record
+    UPDATE container.biblio_record_entry_bucket_item
+        SET target_biblio_record_entry = target_record
+        WHERE bucket IN (SELECT id FROM container.biblio_record_entry_bucket WHERE btype = 'bookbag')
+        AND target_biblio_record_entry = source_record;
+
+    -- Finally, "delete" the source record
+    DELETE FROM biblio.record_entry WHERE id = source_record;
+
+       -- That's all, folks!
+       RETURN moved_objects;
+END;
+$func$ LANGUAGE plpgsql;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1109', :eg_version);
+
+DO $INSERT$                                                                    
+BEGIN                                                                          
+    IF evergreen.insert_on_deploy() THEN 
+INSERT into config.org_unit_setting_type (name, label, grp, description, datatype)
+values ('circ.staff_placed_holds_fallback_to_ws_ou','Workstation OU fallback for staff-placed holds',
+        'circ', 'For staff-placed holds, in the absence of a patron preferred pickup location, fall back to using the staff workstation OU (rather than patron home OU)', 'bool');
+    END IF;                                                                    
+END $INSERT$;     
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.2', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1110', :eg_version);
+
+DROP FUNCTION IF EXISTS unapi.biblio_record_entry_feed (BIGINT[], TEXT, TEXT[], TEXT, INT, HSTORE, HSTORE,
+                                                        BOOL, TEXT, TEXT, TEXT, TEXT, TEXT, XML);
+DROP FUNCTION IF EXISTS unapi.metabib_virtual_record_feed (BIGINT[], TEXT, TEXT[], TEXT, INT, HSTORE, HSTORE,
+                                                           BOOL, TEXT, TEXT, TEXT, TEXT, TEXT, XML);
+
+CREATE OR REPLACE FUNCTION unapi.biblio_record_entry_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit HSTORE DEFAULT NULL, soffset HSTORE DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL, pref_lib INT DEFAULT NULL ) RETURNS XML AS $F$
+DECLARE
+    layout          unapi.bre_output_layout%ROWTYPE;
+    transform       config.xml_transform%ROWTYPE;
+    item_format     TEXT;
+    tmp_xml         TEXT;
+    xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
+    ouid            INT;
+    element_list    TEXT[];
+BEGIN
+
+    IF org = '-' OR org IS NULL THEN
+        SELECT shortname INTO org FROM evergreen.org_top();
+    END IF;
+
+    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
+    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
+
+    IF layout.name IS NULL THEN
+        RETURN NULL::XML;
+    END IF;
+
+    SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
+    xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
+
+    -- Gather the bib xml
+    SELECT XMLAGG( unapi.bre(i, format, '', includes, org, depth, slimit, soffset, include_xmlns, pref_lib)) INTO tmp_xml FROM UNNEST( id_list ) i;
+
+    IF layout.title_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
+    END IF;
+
+    IF layout.description_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
+    END IF;
+
+    IF layout.creator_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
+    END IF;
+
+    IF layout.update_ts_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
+    END IF;
+
+    IF unapi_url IS NOT NULL THEN
+        EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
+    END IF;
+
+    IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
+
+    element_list := regexp_split_to_array(layout.feed_top,E'\\.');
+    FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
+        EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
+    END LOOP;
+
+    RETURN tmp_xml::XML;
+END;
+$F$ LANGUAGE PLPGSQL STABLE;
+
+CREATE OR REPLACE FUNCTION unapi.metabib_virtual_record_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit HSTORE DEFAULT NULL, soffset HSTORE DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL, pref_lib INT DEFAULT NULL ) RETURNS XML AS $F$
+DECLARE
+    layout          unapi.bre_output_layout%ROWTYPE;
+    transform       config.xml_transform%ROWTYPE;
+    item_format     TEXT;
+    tmp_xml         TEXT;
+    xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
+    ouid            INT;
+    element_list    TEXT[];
+BEGIN
+
+    IF org = '-' OR org IS NULL THEN
+        SELECT shortname INTO org FROM evergreen.org_top();
+    END IF;
+
+    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
+    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
+
+    IF layout.name IS NULL THEN
+        RETURN NULL::XML;
+    END IF;
+
+    SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
+    xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
+
+    -- Gather the bib xml
+    SELECT XMLAGG( unapi.mmr(i, format, '', includes, org, depth, slimit, soffset, include_xmlns, pref_lib)) INTO tmp_xml FROM UNNEST( id_list ) i;
+
+    IF layout.title_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
+    END IF;
+
+    IF layout.description_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
+    END IF;
+
+    IF layout.creator_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
+    END IF;
+
+    IF layout.update_ts_element IS NOT NULL THEN
+        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
+    END IF;
+
+    IF unapi_url IS NOT NULL THEN
+        EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
+    END IF;
+
+    IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
+
+    element_list := regexp_split_to_array(layout.feed_top,E'\\.');
+    FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
+        EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
+    END LOOP;
+
+    RETURN tmp_xml::XML;
+END;
+$F$ LANGUAGE PLPGSQL STABLE;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1111', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+ ( 594, 'ADMIN_COPY_ALERT_TYPE', oils_i18n_gettext( 594,
+    'Administer copy alert types', 'ppl', 'description' )),
+ ( 595, 'CREATE_COPY_ALERT_TYPE', oils_i18n_gettext( 595,
+    'Create copy alert types', 'ppl', 'description' )),
+ ( 596, 'UPDATE_COPY_ALERT_TYPE', oils_i18n_gettext( 596,
+    'Update copy alert types', 'ppl', 'description' )),
+ ( 597, 'DELETE_COPY_ALERT_TYPE', oils_i18n_gettext( 597,
+    'Delete copy alert types', 'ppl', 'description' )),
+ ( 598, 'ADMIN_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 598,
+    'Administer copy alert suppression', 'ppl', 'description' )),
+ ( 599, 'CREATE_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 599,
+    'Create copy alert suppression', 'ppl', 'description' )),
+ ( 600, 'UPDATE_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 600,
+    'Update copy alert suppression', 'ppl', 'description' )),
+ ( 601, 'DELETE_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 601,
+    'Delete copy alert suppression', 'ppl', 'description' )),
+ ( 602, 'ADMIN_COPY_ALERT', oils_i18n_gettext( 602,
+    'Administer copy alerts', 'ppl', 'description' )),
+ ( 603, 'CREATE_COPY_ALERT', oils_i18n_gettext( 603,
+    'Create copy alerts', 'ppl', 'description' )),
+ ( 604, 'VIEW_COPY_ALERT', oils_i18n_gettext( 604,
+    'View copy alerts', 'ppl', 'description' )),
+ ( 605, 'UPDATE_COPY_ALERT', oils_i18n_gettext( 605,
+    'Update copy alerts', 'ppl', 'description' )),
+ ( 606, 'DELETE_COPY_ALERT', oils_i18n_gettext( 606,
+    'Delete copy alerts', 'ppl', 'description' ))
+;
+END IF; END $INSERT$;
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.3', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1112', :eg_version);
+
+-- Add an index to action.usr_circ_history (source_circ) to speed up aging circs and purging accounts
+
+/* KCLS already has this one.
+CREATE INDEX action_usr_circ_history_source_circ_idx 
+  ON action.usr_circ_history
+  USING btree
+  (source_circ);
+  */
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.4', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1113', :eg_version); 
+
+CREATE OR REPLACE FUNCTION acq.rollover_funds_by_org_tree(
+    old_year INTEGER,
+    user_id INTEGER,
+    org_unit_id INTEGER,
+    encumb_only BOOL DEFAULT FALSE,
+    include_desc BOOL DEFAULT TRUE
+) RETURNS VOID AS $$
+DECLARE
+--
+new_fund    INT;
+new_year    INT := old_year + 1;
+org_found   BOOL;
+perm_ous    BOOL;
+xfer_amount NUMERIC := 0;
+roll_fund   RECORD;
+deb         RECORD;
+detail      RECORD;
+roll_distrib_forms BOOL;
+--
+BEGIN
+    --
+    -- Sanity checks
+    --
+    IF old_year IS NULL THEN
+        RAISE EXCEPTION 'Input year argument is NULL';
+    ELSIF old_year NOT BETWEEN 2008 and 2200 THEN
+        RAISE EXCEPTION 'Input year is out of range';
+    END IF;
+    --
+    IF user_id IS NULL THEN
+        RAISE EXCEPTION 'Input user id argument is NULL';
+    END IF;
+    --
+    IF org_unit_id IS NULL THEN
+        RAISE EXCEPTION 'Org unit id argument is NULL';
+    ELSE
+        --
+        -- Validate the org unit
+        --
+        SELECT TRUE
+        INTO org_found
+        FROM actor.org_unit
+        WHERE id = org_unit_id;
+        --
+        IF org_found IS NULL THEN
+            RAISE EXCEPTION 'Org unit id % is invalid', org_unit_id;
+        ELSIF encumb_only THEN
+            SELECT INTO perm_ous value::BOOL FROM
+            actor.org_unit_ancestor_setting(
+                'acq.fund.allow_rollover_without_money', org_unit_id
+            );
+            IF NOT FOUND OR NOT perm_ous THEN
+                RAISE EXCEPTION 'Encumbrance-only rollover not permitted at org %', org_unit_id;
+            END IF;
+        END IF;
+    END IF;
+    --
+    -- Loop over the propagable funds to identify the details
+    -- from the old fund plus the id of the new one, if it exists.
+    --
+    FOR roll_fund in
+    SELECT
+        oldf.id AS old_fund,
+        oldf.org,
+        oldf.name,
+        oldf.currency_type,
+        oldf.code,
+        oldf.rollover,
+        newf.id AS new_fund_id
+    FROM
+        acq.fund AS oldf
+        LEFT JOIN acq.fund AS newf
+            ON ( oldf.code = newf.code AND oldf.org = newf.org )
+    WHERE
+            oldf.year = old_year
+        AND oldf.propagate
+        AND newf.year = new_year
+        AND ( ( include_desc AND oldf.org IN ( SELECT id FROM actor.org_unit_descendants( org_unit_id ) ) )
+                OR (NOT include_desc AND oldf.org = org_unit_id ) )
+    LOOP
+        --RAISE NOTICE 'Processing fund %', roll_fund.old_fund;
+        --
+        IF roll_fund.new_fund_id IS NULL THEN
+            --
+            -- The old fund hasn't been propagated yet.  Propagate it now.
+            --
+            INSERT INTO acq.fund (
+                org,
+                name,
+                year,
+                currency_type,
+                code,
+                rollover,
+                propagate,
+                balance_warning_percent,
+                balance_stop_percent
+            ) VALUES (
+                roll_fund.org,
+                roll_fund.name,
+                new_year,
+                roll_fund.currency_type,
+                roll_fund.code,
+                true,
+                true,
+                roll_fund.balance_warning_percent,
+                roll_fund.balance_stop_percent
+            )
+            RETURNING id INTO new_fund;
+
+                PERFORM acq.copy_fund_tags(roll_fund.id,new_fund);
+
+        ELSE
+            new_fund = roll_fund.new_fund_id;
+        END IF;
+        --
+        -- Determine the amount to transfer
+        --
+        SELECT amount
+        INTO xfer_amount
+        FROM acq.fund_spent_balance
+        WHERE fund = roll_fund.old_fund;
+        --
+        IF xfer_amount <> 0 THEN
+            IF NOT encumb_only AND roll_fund.rollover THEN
+                --
+                -- Transfer balance from old fund to new
+                --
+                --RAISE NOTICE 'Transferring % from fund % to %', xfer_amount, roll_fund.old_fund, new_fund;
+                --
+                PERFORM acq.transfer_fund(
+                    roll_fund.old_fund,
+                    xfer_amount,
+                    new_fund,
+                    xfer_amount,
+                    user_id,
+                    'Rollover'
+                );
+            ELSE
+                --
+                -- Transfer balance from old fund to the void
+                --
+                -- RAISE NOTICE 'Transferring % from fund % to the void', xfer_amount, roll_fund.old_fund;
+                --
+                PERFORM acq.transfer_fund(
+                    roll_fund.old_fund,
+                    xfer_amount,
+                    NULL,
+                    NULL,
+                    user_id,
+                    'Rollover into the void'
+                );
+            END IF;
+        END IF;
+        --
+        IF roll_fund.rollover THEN
+            --
+            -- Move any lineitems from the old fund to the new one
+            -- where the associated debit is an encumbrance.
+            --
+            -- Any other tables tying expenditure details to funds should
+            -- receive similar treatment.  At this writing there are none.
+            --
+            UPDATE acq.lineitem_detail
+            SET fund = new_fund
+            WHERE
+                fund = roll_fund.old_fund -- this condition may be redundant
+                AND fund_debit in
+                (
+                    SELECT id
+                    FROM acq.fund_debit
+                    WHERE
+                        fund = roll_fund.old_fund
+                        AND encumbrance
+                );
+            --
+            -- Move encumbrance debits from the old fund to the new fund
+            --
+            UPDATE acq.fund_debit
+            SET fund = new_fund
+            wHERE
+                fund = roll_fund.old_fund
+                AND encumbrance;
+        END IF;
+
+        -- Rollover distribution formulae funds
+        SELECT INTO roll_distrib_forms value::BOOL FROM
+            actor.org_unit_ancestor_setting(
+                'acq.fund.rollover_distrib_forms', org_unit_id
+            );
+
+        IF roll_distrib_forms THEN
+            UPDATE acq.distribution_formula_entry 
+                SET fund = roll_fund.new_fund_id
+                WHERE fund = roll_fund.old_fund;
+        END IF;
+
+        --
+        -- Mark old fund as inactive, now that we've closed it
+        --
+        UPDATE acq.fund
+        SET active = FALSE
+        WHERE id = roll_fund.old_fund;
+    END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1114', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.copy_state (cid BIGINT) RETURNS TEXT AS $$
+DECLARE
+    last_circ_stop      TEXT;
+    the_copy        asset.copy%ROWTYPE;
+BEGIN
+
+    SELECT * INTO the_copy FROM asset.copy WHERE id = cid;
+    IF NOT FOUND THEN RETURN NULL; END IF;
+
+    IF the_copy.status = 3 THEN -- Lost
+        RETURN 'LOST';
+    ELSIF the_copy.status = 4 THEN -- Missing
+        RETURN 'MISSING';
+    ELSIF the_copy.status = 14 THEN -- Damaged
+        RETURN 'DAMAGED';
+    ELSIF the_copy.status = 17 THEN -- Lost and paid
+        RETURN 'LOST_AND_PAID';
+    END IF;
+
+    SELECT stop_fines INTO last_circ_stop
+      FROM  action.circulation
+      WHERE target_copy = cid AND checkin_time IS NULL
+      ORDER BY xact_start DESC LIMIT 1;
+
+    IF FOUND THEN
+        IF last_circ_stop IN (
+            'CLAIMSNEVERCHECKEDOUT',
+            'CLAIMSRETURNED',
+            'LONGOVERDUE'
+        ) THEN
+            RETURN last_circ_stop;
+        END IF;
+    END IF;
+
+    RETURN 'NORMAL';
+END;
+$$ LANGUAGE PLPGSQL;
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.5', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1119', :eg_version);
+
+CREATE OR REPLACE FUNCTION asset.staff_ou_record_copy_count(org integer, rid bigint)
+ RETURNS TABLE(depth integer, org_unit integer, visible bigint, available bigint, unshadow bigint, transcendant integer)
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+    ans RECORD;
+    trans INT;
+BEGIN
+    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
+
+    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
+        RETURN QUERY
+        WITH available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
+            cp AS(
+                SELECT  cp.id,
+                        (cp.status = ANY (available_statuses.ids))::INT as available,
+                        (cl.opac_visible AND cp.opac_visible)::INT as opac_visible
+                  FROM
+                        available_statuses,
+                        actor.org_unit_descendants(ans.id) d
+                        JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
+                        JOIN asset.copy_location cl ON (cp.location = cl.id AND NOT cl.deleted)
+                        JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
+            ),
+            peer AS (
+                SELECT  cp.id,
+                        (cp.status = ANY  (available_statuses.ids))::INT as available,
+                        (cl.opac_visible AND cp.opac_visible)::INT as opac_visible
+                FROM
+                        available_statuses,
+                        actor.org_unit_descendants(ans.id) d
+                        JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
+                        JOIN asset.copy_location cl ON (cp.location = cl.id AND NOT cl.deleted)
+                        JOIN biblio.peer_bib_copy_map bp ON (bp.peer_record = rid AND bp.target_copy = cp.id)
+            )
+        SELECT ans.depth, ans.id, count(id), sum(x.available::int), sum(x.opac_visible::int), trans
+        FROM ((select * from cp) union (select * from peer)) x
+        GROUP BY 1,2,6;
+
+        IF NOT FOUND THEN
+            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
+        END IF;
+
+    END LOOP;
+    RETURN;
+END;
+$function$;
+
+CREATE OR REPLACE FUNCTION asset.opac_ou_record_copy_count(org integer, rid bigint)
+ RETURNS TABLE(depth integer, org_unit integer, visible bigint, available bigint, unshadow bigint, transcendant integer)
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+    ans RECORD;
+    trans INT;
+BEGIN
+    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
+
+    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
+        RETURN QUERY
+        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
+             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
+             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
+        SELECT  ans.depth,
+                ans.id,
+                COUNT( av.id ),
+                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
+                COUNT( av.id ),
+                trans
+          FROM  mask,
+                available_statuses,
+                org_list,
+                asset.copy_vis_attr_cache av
+                JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
+                JOIN asset.call_number cn ON (cp.call_number = cn.id AND not cn.deleted)
+          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
+          GROUP BY 1,2,6;
+
+        IF NOT FOUND THEN
+            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
+        END IF;
+
+    END LOOP;
+
+    RETURN;
+END;
+$function$;
+
+
+--INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.2-beta1', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('1115', :eg_version);
+
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+INSERT INTO permission.perm_list (id,code,description) VALUES ( 607, 'EMERGENCY_CLOSING', 'Create and manage Emergency Closings');
+
+INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('checkout.due.emergency_closing','aecc','Circulation due date was adjusted by the Emergency Closing handler');
+INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('hold.shelf_expire.emergency_closing','aech','Hold shelf expire time was adjusted by the Emergency Closing handler');
+INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('booking.due.emergency_closing','aecr','Booking reservation return date was adjusted by the Emergency Closing handler');
+END IF; END $INSERT$;
+
+CREATE TABLE action.emergency_closing (
+    id                  SERIAL      PRIMARY KEY,
+    creator             INT         NOT NULL REFERENCES actor.usr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    create_time         TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+    process_start_time  TIMESTAMPTZ,
+    process_end_time    TIMESTAMPTZ,
+    last_update_time    TIMESTAMPTZ
+);
+
+ALTER TABLE actor.org_unit_closed
+    ADD COLUMN emergency_closing INT
+        REFERENCES action.emergency_closing (id) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED;
+
+CREATE TABLE action.emergency_closing_circulation (
+    id                  BIGSERIAL   PRIMARY KEY,
+    emergency_closing   INT         NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    circulation         INT         NOT NULL REFERENCES action.circulation (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    original_due_date   TIMESTAMPTZ,
+    process_time        TIMESTAMPTZ
+);
+CREATE INDEX emergency_closing_circulation_emergency_closing_idx ON action.emergency_closing_circulation (emergency_closing);
+CREATE INDEX emergency_closing_circulation_circulation_idx ON action.emergency_closing_circulation (circulation);
+
+CREATE TABLE action.emergency_closing_reservation (
+    id                  BIGSERIAL   PRIMARY KEY,
+    emergency_closing   INT         NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    reservation         INT         NOT NULL REFERENCES booking.reservation (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    original_end_time   TIMESTAMPTZ,
+    process_time        TIMESTAMPTZ
+);
+CREATE INDEX emergency_closing_reservation_emergency_closing_idx ON action.emergency_closing_reservation (emergency_closing);
+CREATE INDEX emergency_closing_reservation_reservation_idx ON action.emergency_closing_reservation (reservation);
+
+CREATE TABLE action.emergency_closing_hold (
+    id                  BIGSERIAL   PRIMARY KEY,
+    emergency_closing   INT         NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    hold                INT         NOT NULL REFERENCES action.hold_request (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    original_shelf_expire_time   TIMESTAMPTZ,
+    process_time        TIMESTAMPTZ
+);
+CREATE INDEX emergency_closing_hold_emergency_closing_idx ON action.emergency_closing_hold (emergency_closing);
+CREATE INDEX emergency_closing_hold_hold_idx ON action.emergency_closing_hold (hold);
+
+CREATE OR REPLACE VIEW action.emergency_closing_status AS
+    SELECT  e.*,
+            COALESCE(c.count, 0) AS circulations,
+            COALESCE(c.completed, 0) AS circulations_complete,
+            COALESCE(b.count, 0) AS reservations,
+            COALESCE(b.completed, 0) AS reservations_complete,
+            COALESCE(h.count, 0) AS holds,
+            COALESCE(h.completed, 0) AS holds_complete
+      FROM  action.emergency_closing e
+            LEFT JOIN (SELECT emergency_closing, count(*) count, SUM((process_time IS NOT NULL)::INT) completed FROM action.emergency_closing_circulation GROUP BY 1) c ON (c.emergency_closing = e.id)
+            LEFT JOIN (SELECT emergency_closing, count(*) count, SUM((process_time IS NOT NULL)::INT) completed FROM action.emergency_closing_reservation GROUP BY 1) b ON (b.emergency_closing = e.id)
+            LEFT JOIN (SELECT emergency_closing, count(*) count, SUM((process_time IS NOT NULL)::INT) completed FROM action.emergency_closing_hold GROUP BY 1) h ON (h.emergency_closing = e.id)
+;
+
+CREATE OR REPLACE FUNCTION evergreen.find_next_open_time ( circ_lib INT, initial TIMESTAMPTZ, hourly BOOL DEFAULT FALSE, initial_time TIME DEFAULT NULL, dow_count INT DEFAULT 0 )
+    RETURNS TIMESTAMPTZ AS $$
+DECLARE
+    day_number      INT;
+    plus_days       INT;
+    final_time      TEXT;
+    time_adjusted   BOOL;
+    hoo_open        TIME WITHOUT TIME ZONE;
+    hoo_close       TIME WITHOUT TIME ZONE;
+    adjacent        actor.org_unit_closed%ROWTYPE;
+    breakout        INT := 0;
+BEGIN
+
+    IF dow_count > 6 THEN
+        RETURN initial;
+    END IF;
+
+    IF initial_time IS NULL THEN
+        initial_time := initial::TIME;
+    END IF;
+
+    final_time := (initial + '1 second'::INTERVAL)::TEXT;
+    LOOP
+        breakout := breakout + 1;
+
+        time_adjusted := FALSE;
+
+        IF dow_count > 0 THEN -- we're recursing, so check for HOO closing
+            day_number := EXTRACT(ISODOW FROM final_time::TIMESTAMPTZ) - 1;
+            plus_days := 0;
+            FOR i IN 1..7 LOOP
+                EXECUTE 'SELECT dow_' || day_number || '_open, dow_' || day_number || '_close FROM actor.hours_of_operation WHERE id = $1'
+                    INTO hoo_open, hoo_close
+                    USING circ_lib;
+
+                -- RAISE NOTICE 'initial time: %; dow: %; close: %',initial_time,day_number,hoo_close;
+
+                IF hoo_close = '00:00:00' THEN -- bah ... I guess we'll check the next day
+                    day_number := (day_number + 1) % 7;
+                    plus_days := plus_days + 1;
+                    time_adjusted := TRUE;
+                    CONTINUE;
+                END IF;
+
+                IF hoo_close IS NULL THEN -- no hours of operation ... assume no closing?
+                    hoo_close := '23:59:59';
+                END IF;
+
+                EXIT;
+            END LOOP;
+
+            final_time := DATE(final_time::TIMESTAMPTZ + (plus_days || ' days')::INTERVAL)::TEXT;
+            IF hoo_close <> '00:00:00' AND hourly THEN -- Not a day-granular circ
+                final_time := final_time||' '|| hoo_close;
+            ELSE
+                final_time := final_time||' 23:59:59';
+            END IF;
+        END IF;
+
+        -- Loop through other closings
+        LOOP 
+            SELECT * INTO adjacent FROM actor.org_unit_closed WHERE org_unit = circ_lib AND final_time::TIMESTAMPTZ between close_start AND close_end;
+            EXIT WHEN adjacent.id IS NULL;
+            time_adjusted := TRUE;
+            -- RAISE NOTICE 'recursing for closings with final_time: %',final_time;
+            final_time := evergreen.find_next_open_time(circ_lib, adjacent.close_end::TIMESTAMPTZ, hourly, initial_time, dow_count + 1)::TEXT;
+        END LOOP;
+
+        EXIT WHEN breakout > 100;
+        EXIT WHEN NOT time_adjusted;
+
+    END LOOP;
+
+    RETURN final_time;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TYPE action.emergency_closing_stage_1_count AS (circulations INT, reservations INT, holds INT);
+CREATE OR REPLACE FUNCTION action.emergency_closing_stage_1 ( e_closing INT )
+    RETURNS SETOF action.emergency_closing_stage_1_count AS $$
+DECLARE
+    tmp     INT;
+    touched action.emergency_closing_stage_1_count%ROWTYPE;
+BEGIN
+    -- First, gather circs
+    INSERT INTO action.emergency_closing_circulation (emergency_closing, circulation)
+        SELECT  e_closing,
+                circ.id
+          FROM  actor.org_unit_closed closing
+                JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
+                JOIN action.circulation circ ON (
+                    circ.circ_lib = closing.org_unit
+                    AND circ.due_date BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+                    AND circ.xact_finish IS NULL
+                )
+          WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_circulation t WHERE t.emergency_closing = e_closing AND t.circulation = circ.id);
+
+    GET DIAGNOSTICS tmp = ROW_COUNT;
+    touched.circulations := tmp;
+
+    INSERT INTO action.emergency_closing_reservation (emergency_closing, reservation)
+        SELECT  e_closing,
+                res.id
+          FROM  actor.org_unit_closed closing
+                JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
+                JOIN booking.reservation res ON (
+                    res.pickup_lib = closing.org_unit
+                    AND res.end_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+                )
+          WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_reservation t WHERE t.emergency_closing = e_closing AND t.reservation = res.id);
+
+    GET DIAGNOSTICS tmp = ROW_COUNT;
+    touched.reservations := tmp;
+
+    INSERT INTO action.emergency_closing_hold (emergency_closing, hold)
+        SELECT  e_closing,
+                hold.id
+          FROM  actor.org_unit_closed closing
+                JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
+                JOIN action.hold_request hold ON (
+                    pickup_lib = closing.org_unit
+                    AND hold.shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+                    AND hold.fulfillment_time IS NULL
+                    AND hold.cancel_time IS NULL
+                )
+          WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_hold t WHERE t.emergency_closing = e_closing AND t.hold = hold.id);
+
+    GET DIAGNOSTICS tmp = ROW_COUNT;
+    touched.holds := tmp;
+
+    UPDATE  action.emergency_closing
+      SET   process_start_time = NOW(),
+            last_update_time = NOW()
+      WHERE id = e_closing;
+
+    RETURN NEXT touched;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_hold ( hold_closing_entry INT )
+    RETURNS BOOL AS $$
+DECLARE
+    hold        action.hold_request%ROWTYPE;
+    e_closing   action.emergency_closing%ROWTYPE;
+    e_c_hold    action.emergency_closing_hold%ROWTYPE;
+    closing     actor.org_unit_closed%ROWTYPE;
+    day_number  INT;
+    hoo_close   TIME WITHOUT TIME ZONE;
+    plus_days   INT;
+BEGIN
+    -- Gather objects involved
+    SELECT  * INTO e_c_hold
+      FROM  action.emergency_closing_hold
+      WHERE id = hold_closing_entry;
+
+    IF e_c_hold.process_time IS NOT NULL THEN
+        -- Already processed ... moving on
+        RETURN FALSE;
+    END IF;
+
+    SELECT  * INTO e_closing
+      FROM  action.emergency_closing
+      WHERE id = e_c_hold.emergency_closing;
+
+    IF e_closing.process_start_time IS NULL THEN
+        -- Huh... that's odd. And wrong.
+        RETURN FALSE;
+    END IF;
+
+    SELECT  * INTO closing
+      FROM  actor.org_unit_closed
+      WHERE emergency_closing = e_closing.id;
+
+    SELECT  * INTO hold
+      FROM  action.hold_request h
+      WHERE id = e_c_hold.hold;
+
+    -- Record the processing
+    UPDATE  action.emergency_closing_hold
+      SET   original_shelf_expire_time = hold.shelf_expire_time,
+            process_time = NOW()
+      WHERE id = hold_closing_entry;
+
+    UPDATE  action.emergency_closing
+      SET   last_update_time = NOW()
+      WHERE id = e_closing.id;
+
+    UPDATE  action.hold_request
+      SET   shelf_expire_time = evergreen.find_next_open_time(closing.org_unit, hold.shelf_expire_time, TRUE)
+      WHERE id = hold.id;
+
+    RETURN TRUE;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_circ ( circ_closing_entry INT )
+    RETURNS BOOL AS $$
+DECLARE
+    circ            action.circulation%ROWTYPE;
+    e_closing       action.emergency_closing%ROWTYPE;
+    e_c_circ        action.emergency_closing_circulation%ROWTYPE;
+    closing         actor.org_unit_closed%ROWTYPE;
+    adjacent        actor.org_unit_closed%ROWTYPE;
+    bill            money.billing%ROWTYPE;
+    last_bill       money.billing%ROWTYPE;
+    day_number      INT;
+    hoo_close       TIME WITHOUT TIME ZONE;
+    plus_days       INT;
+    avoid_negative  BOOL;
+    extend_grace    BOOL;
+    new_due_date    TEXT;
+BEGIN
+    -- Gather objects involved
+    SELECT  * INTO e_c_circ
+      FROM  action.emergency_closing_circulation
+      WHERE id = circ_closing_entry;
+
+    IF e_c_circ.process_time IS NOT NULL THEN
+        -- Already processed ... moving on
+        RETURN FALSE;
+    END IF;
+
+    SELECT  * INTO e_closing
+      FROM  action.emergency_closing
+      WHERE id = e_c_circ.emergency_closing;
+
+    IF e_closing.process_start_time IS NULL THEN
+        -- Huh... that's odd. And wrong.
+        RETURN FALSE;
+    END IF;
+
+    SELECT  * INTO closing
+      FROM  actor.org_unit_closed
+      WHERE emergency_closing = e_closing.id;
+
+    SELECT  * INTO circ
+      FROM  action.circulation
+      WHERE id = e_c_circ.circulation;
+
+    -- Record the processing
+    UPDATE  action.emergency_closing_circulation
+      SET   original_due_date = circ.due_date,
+            process_time = NOW()
+      WHERE id = circ_closing_entry;
+
+    UPDATE  action.emergency_closing
+      SET   last_update_time = NOW()
+      WHERE id = e_closing.id;
+
+    SELECT value::BOOL INTO avoid_negative FROM actor.org_unit_ancestor_setting('bill.prohibit_negative_balance_on_overdues', circ.circ_lib);
+    SELECT value::BOOL INTO extend_grace FROM actor.org_unit_ancestor_setting('circ.grace.extend', circ.circ_lib);
+
+    new_due_date := evergreen.find_next_open_time( closing.org_unit, circ.due_date, EXTRACT(EPOCH FROM circ.duration)::INT % 86400 > 0 )::TEXT;
+    UPDATE action.circulation SET due_date = new_due_date::TIMESTAMPTZ WHERE id = circ.id;
+
+    -- Now, see if we need to get rid of some fines
+    SELECT  * INTO last_bill
+      FROM  money.billing b
+      WHERE b.xact = circ.id
+            AND NOT b.voided
+            AND b.btype = 1
+      ORDER BY billing_ts DESC
+      LIMIT 1;
+
+    FOR bill IN
+        SELECT  *
+          FROM  money.billing b
+          WHERE b.xact = circ.id
+                AND b.btype = 1
+                AND NOT b.voided
+                AND (
+                    b.billing_ts BETWEEN closing.close_start AND new_due_date::TIMESTAMPTZ
+                    OR (extend_grace AND last_bill.billing_ts <= new_due_date::TIMESTAMPTZ + circ.grace_period)
+                )
+                AND NOT EXISTS (SELECT 1 FROM money.account_adjustment a WHERE a.billing = b.id)
+          ORDER BY billing_ts
+    LOOP
+        IF avoid_negative THEN
+            PERFORM FROM money.materialized_billable_xact_summary WHERE id = circ.id AND balanced_owd < bill.amount;
+            EXIT WHEN FOUND; -- We can't go negative, and voiding this bill would do that...
+        END IF;
+
+        UPDATE  money.billing
+          SET   voided = TRUE,
+                void_time = NOW(),
+                note = COALESCE(note,'') || ' :: Voided by emergency closing handler'
+          WHERE id = bill.id;
+    END LOOP;
+    
+    RETURN TRUE;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_reservation ( res_closing_entry INT )
+    RETURNS BOOL AS $$
+DECLARE
+    res             booking.reservation%ROWTYPE;
+    e_closing       action.emergency_closing%ROWTYPE;
+    e_c_res         action.emergency_closing_reservation%ROWTYPE;
+    closing         actor.org_unit_closed%ROWTYPE;
+    adjacent        actor.org_unit_closed%ROWTYPE;
+    bill            money.billing%ROWTYPE;
+    day_number      INT;
+    hoo_close       TIME WITHOUT TIME ZONE;
+    plus_days       INT;
+    avoid_negative  BOOL;
+    new_due_date    TEXT;
+BEGIN
+    -- Gather objects involved
+    SELECT  * INTO e_c_res
+      FROM  action.emergency_closing_reservation
+      WHERE id = res_closing_entry;
+
+    IF e_c_res.process_time IS NOT NULL THEN
+        -- Already processed ... moving on
+        RETURN FALSE;
+    END IF;
+
+    SELECT  * INTO e_closing
+      FROM  action.emergency_closing
+      WHERE id = e_c_res.emergency_closing;
+
+    IF e_closing.process_start_time IS NULL THEN
+        -- Huh... that's odd. And wrong.
+        RETURN FALSE;
+    END IF;
+
+    SELECT  * INTO closing
+      FROM  actor.org_unit_closed
+      WHERE emergency_closing = e_closing.id;
+
+    SELECT  * INTO res
+      FROM  booking.reservation
+      WHERE id = e_c_res.reservation;
+
+    IF res.pickup_lib IS NULL THEN -- Need to be far enough along to have a pickup lib
+        RETURN FALSE;
+    END IF;
+
+    -- Record the processing
+    UPDATE  action.emergency_closing_reservation
+      SET   original_end_time = res.end_time,
+            process_time = NOW()
+      WHERE id = res_closing_entry;
+
+    UPDATE  action.emergency_closing
+      SET   last_update_time = NOW()
+      WHERE id = e_closing.id;
+
+    SELECT value::BOOL INTO avoid_negative FROM actor.org_unit_ancestor_setting('bill.prohibit_negative_balance_on_overdues', res.pickup_lib);
+
+    new_due_date := evergreen.find_next_open_time( closing.org_unit, res.end_time, EXTRACT(EPOCH FROM res.booking_interval)::INT % 86400 > 0 )::TEXT;
+    UPDATE booking.reservation SET end_time = new_due_date::TIMESTAMPTZ WHERE id = res.id;
+
+    -- Now, see if we need to get rid of some fines
+    FOR bill IN
+        SELECT  *
+          FROM  money.billing b
+          WHERE b.xact = res.id
+                AND b.btype = 1
+                AND NOT b.voided
+                AND b.billing_ts BETWEEN closing.close_start AND new_due_date::TIMESTAMPTZ
+                AND NOT EXISTS (SELECT 1 FROM money.account_adjustment a WHERE a.billing = b.id)
+    LOOP
+        IF avoid_negative THEN
+            PERFORM FROM money.materialized_billable_xact_summary WHERE id = res.id AND balanced_owd < bill.amount;
+            EXIT WHEN FOUND; -- We can't go negative, and voiding this bill would do that...
+        END IF;
+
+        UPDATE  money.billing
+          SET   voided = TRUE,
+                void_time = NOW(),
+                note = COALESCE(note,'') || ' :: Voided by emergency closing handler'
+          WHERE id = bill.id;
+    END LOOP;
+    
+    RETURN TRUE;
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+
+CREATE TYPE actor.cascade_setting_summary AS (
+    name TEXT,
+    value JSON,
+    has_org_setting BOOLEAN,
+    has_user_setting BOOLEAN,
+    has_workstation_setting BOOLEAN
+);
+
+--SELECT evergreen.upgrade_deps_block_check('1116', :eg_version);
+
+CREATE TABLE config.workstation_setting_type (
+    name            TEXT    PRIMARY KEY,
+    label           TEXT    UNIQUE NOT NULL,
+    grp             TEXT    REFERENCES config.settings_group (name),
+    description     TEXT,
+    datatype        TEXT    NOT NULL DEFAULT 'string',
+    fm_class        TEXT,
+    --
+    -- define valid datatypes
+    --
+    CONSTRAINT cwst_valid_datatype CHECK ( datatype IN
+    ( 'bool', 'integer', 'float', 'currency', 'interval',
+      'date', 'string', 'object', 'array', 'link' ) ),
+    --
+    -- fm_class is meaningful only for 'link' datatype
+    --
+    CONSTRAINT cwst_no_empty_link CHECK
+    ( ( datatype =  'link' AND fm_class IS NOT NULL ) OR
+      ( datatype <> 'link' AND fm_class IS NULL ) )
+);
+
+CREATE TABLE actor.workstation_setting (
+    id          SERIAL PRIMARY KEY,
+    workstation INT    NOT NULL REFERENCES actor.workstation (id) 
+                       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    name        TEXT   NOT NULL REFERENCES config.workstation_setting_type (name) 
+                       ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    value       JSON   NOT NULL
+);
+
+
+CREATE INDEX actor_workstation_setting_workstation_idx 
+    ON actor.workstation_setting (workstation);
+
+CREATE OR REPLACE FUNCTION config.setting_is_user_or_ws()
+RETURNS TRIGGER AS $FUNC$
+BEGIN
+
+    IF TG_TABLE_NAME = 'usr_setting_type' THEN
+        PERFORM TRUE FROM config.workstation_setting_type cwst
+            WHERE cwst.name = NEW.name;
+        IF NOT FOUND THEN
+            RETURN NULL;
+        END IF;
+    END IF;
+
+    IF TG_TABLE_NAME = 'workstation_setting_type' THEN
+        PERFORM TRUE FROM config.usr_setting_type cust
+            WHERE cust.name = NEW.name;
+        IF NOT FOUND THEN
+            RETURN NULL;
+        END IF;
+    END IF;
+
+    RAISE EXCEPTION 
+        '% Cannot be used as both a user setting and a workstation setting.', 
+        NEW.name;
+END;
+$FUNC$ LANGUAGE PLPGSQL STABLE;
+
+CREATE CONSTRAINT TRIGGER check_setting_is_usr_or_ws
+  AFTER INSERT OR UPDATE ON config.usr_setting_type
+  FOR EACH ROW EXECUTE PROCEDURE config.setting_is_user_or_ws();
+
+CREATE CONSTRAINT TRIGGER check_setting_is_usr_or_ws
+  AFTER INSERT OR UPDATE ON config.workstation_setting_type
+  FOR EACH ROW EXECUTE PROCEDURE config.setting_is_user_or_ws();
+
+CREATE OR REPLACE FUNCTION actor.get_cascade_setting(
+    setting_name TEXT, org_id INT, user_id INT, workstation_id INT) 
+    RETURNS actor.cascade_setting_summary AS
+$FUNC$
+DECLARE
+    setting_value JSON;
+    summary actor.cascade_setting_summary;
+    org_setting_type config.org_unit_setting_type%ROWTYPE;
+BEGIN
+
+    summary.name := setting_name;
+
+    -- Collect the org setting type status first in case we exit early.
+    -- The existance of an org setting type is not considered
+    -- privileged information.
+    SELECT INTO org_setting_type * 
+        FROM config.org_unit_setting_type WHERE name = setting_name;
+    IF FOUND THEN
+        summary.has_org_setting := TRUE;
+    ELSE
+        summary.has_org_setting := FALSE;
+    END IF;
+
+    -- User and workstation settings have the same priority.
+    -- Start with user settings since that's the simplest code path.
+    -- The workstation_id is ignored if no user_id is provided.
+    IF user_id IS NOT NULL THEN
+
+        SELECT INTO summary.value value FROM actor.usr_setting
+            WHERE usr = user_id AND name = setting_name;
+
+        IF FOUND THEN
+            -- if we have a value, we have a setting type
+            summary.has_user_setting := TRUE;
+
+            IF workstation_id IS NOT NULL THEN
+                -- Only inform the caller about the workstation
+                -- setting type disposition when a workstation id is
+                -- provided.  Otherwise, it's NULL to indicate UNKNOWN.
+                summary.has_workstation_setting := FALSE;
+            END IF;
+
+            RETURN summary;
+        END IF;
+
+        -- no user setting value, but a setting type may exist
+        SELECT INTO summary.has_user_setting EXISTS (
+            SELECT TRUE FROM config.usr_setting_type 
+            WHERE name = setting_name
+        );
+
+        IF workstation_id IS NOT NULL THEN 
+
+            IF NOT summary.has_user_setting THEN
+                -- A workstation setting type may only exist when a user
+                -- setting type does not.
+
+                SELECT INTO summary.value value 
+                    FROM actor.workstation_setting         
+                    WHERE workstation = workstation_id AND name = setting_name;
+
+                IF FOUND THEN
+                    -- if we have a value, we have a setting type
+                    summary.has_workstation_setting := TRUE;
+                    RETURN summary;
+                END IF;
+
+                -- no value, but a setting type may exist
+                SELECT INTO summary.has_workstation_setting EXISTS (
+                    SELECT TRUE FROM config.workstation_setting_type 
+                    WHERE name = setting_name
+                );
+            END IF;
+
+            -- Finally make use of the workstation to determine the org
+            -- unit if none is provided.
+            IF org_id IS NULL AND summary.has_org_setting THEN
+                SELECT INTO org_id owning_lib 
+                    FROM actor.workstation WHERE id = workstation_id;
+            END IF;
+        END IF;
+    END IF;
+
+    -- Some org unit settings are protected by a view permission.
+    -- First see if we have any data that needs protecting, then 
+    -- check the permission if needed.
+
+    IF NOT summary.has_org_setting THEN
+        RETURN summary;
+    END IF;
+
+    -- avoid putting the value into the summary until we confirm
+    -- the value should be visible to the caller.
+    SELECT INTO setting_value value 
+        FROM actor.org_unit_ancestor_setting(setting_name, org_id);
+
+    IF NOT FOUND THEN
+        -- No value found -- perm check is irrelevant.
+        RETURN summary;
+    END IF;
+
+    IF org_setting_type.view_perm IS NOT NULL THEN
+
+        IF user_id IS NULL THEN
+            RAISE NOTICE 'Perm check required but no user_id provided';
+            RETURN summary;
+        END IF;
+
+        IF NOT permission.usr_has_perm(
+            user_id, (SELECT code FROM permission.perm_list 
+                WHERE id = org_setting_type.view_perm), org_id) 
+        THEN
+            RAISE NOTICE 'Perm check failed for user % on %',
+                user_id, org_setting_type.view_perm;
+            RETURN summary;
+        END IF;
+    END IF;
+
+    -- Perm check succeeded or was not necessary.
+    summary.value := setting_value;
+    RETURN summary;
+END;
+$FUNC$ LANGUAGE PLPGSQL;
+
+
+CREATE OR REPLACE FUNCTION actor.get_cascade_setting_batch(
+    setting_names TEXT[], org_id INT, user_id INT, workstation_id INT) 
+    RETURNS SETOF actor.cascade_setting_summary AS
+$FUNC$
+-- Returns a row per setting matching the setting name order.  If no 
+-- value is applied, NULL is returned to retain name-response ordering.
+DECLARE
+    setting_name TEXT;
+    summary actor.cascade_setting_summary;
+BEGIN
+    FOREACH setting_name IN ARRAY setting_names LOOP
+        SELECT INTO summary * FROM actor.get_cascade_setting(
+            setting_Name, org_id, user_id, workstation_id);
+        RETURN NEXT summary;
+    END LOOP;
+END;
+$FUNC$ LANGUAGE PLPGSQL;
+
+
+
+
+
+--SELECT evergreen.upgrade_deps_block_check('1117', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+
+INSERT INTO permission.perm_list (id, code, description) VALUES
+ (608, 'APPLY_WORKSTATION_SETTING',
+   oils_i18n_gettext(608, 'APPLY_WORKSTATION_SETTING', 'ppl', 'description'));
+
+INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+    'eg.circ.checkin.no_precat_alert', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.no_precat_alert',
+        'Checkin: Ignore Precataloged Items',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.noop', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.noop',
+        'Checkin: Suppress Holds and Transits',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.void_overdues', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.void_overdues',
+        'Checkin: Amnesty Mode',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.auto_print_holds_transits', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.auto_print_holds_transits',
+        'Checkin: Auto-Print Holds and Transits',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.clear_expired', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.clear_expired',
+        'Checkin: Clear Holds Shelf',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.retarget_holds', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.retarget_holds',
+        'Checkin: Retarget Local Holds',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.retarget_holds_all', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.retarget_holds_all',
+        'Checkin: Retarget All Statuses',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.hold_as_transit', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.hold_as_transit',
+        'Checkin: Capture Local Holds as Transits',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.checkin.manual_float', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.checkin.manual_float',
+        'Checkin: Manual Floating Active',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.patron.summary.collapse', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.patron.summary.collapse',
+        'Collaps Patron Summary Display',
+        'cwst', 'label'
+    )
+), (
+    'circ.bills.receiptonpay', 'circ', 'bool',
+    oils_i18n_gettext(
+        'circ.bills.receiptonpay',
+        'Print Receipt On Payment',
+        'cwst', 'label'
+    )
+), (
+    'circ.renew.strict_barcode', 'circ', 'bool',
+    oils_i18n_gettext(
+        'circ.renew.strict_barcode',
+        'Renew: Strict Barcode',
+        'cwst', 'label'
+    )
+), (
+    'circ.checkin.strict_barcode', 'circ', 'bool',
+    oils_i18n_gettext(
+        'circ.checkin.strict_barcode',
+        'Checkin: Strict Barcode',
+        'cwst', 'label'
+    )
+), (
+    'circ.checkout.strict_barcode', 'circ', 'bool',
+    oils_i18n_gettext(
+        'circ.checkout.strict_barcode',
+        'Checkout: Strict Barcode',
+        'cwst', 'label'
+    )
+), (
+    'cat.holdings_show_copies', 'cat', 'bool',
+    oils_i18n_gettext(
+        'cat.holdings_show_copies',
+        'Holdings View Show Copies',
+        'cwst', 'label'
+    )
+), (
+    'cat.holdings_show_empty', 'cat', 'bool',
+    oils_i18n_gettext(
+        'cat.holdings_show_empty',
+        'Holdings View Show Empty Volumes',
+        'cwst', 'label'
+    )
+), (
+    'cat.holdings_show_empty_org', 'cat', 'bool',
+    oils_i18n_gettext(
+        'cat.holdings_show_empty_org',
+        'Holdings View Show Empty Orgs',
+        'cwst', 'label'
+    )
+), (
+    'cat.holdings_show_vols', 'cat', 'bool',
+    oils_i18n_gettext(
+        'cat.holdings_show_vols',
+        'Holdings View Show Volumes',
+        'cwst', 'label'
+    )
+), (
+    'cat.copy.defaults', 'cat', 'object',
+    oils_i18n_gettext(
+        'cat.copy.defaults',
+        'Copy Edit Default Values',
+        'cwst', 'label'
+    )
+), (
+    'cat.printlabels.default_template', 'cat', 'string',
+    oils_i18n_gettext(
+        'cat.printlabels.default_template',
+        'Print Label Default Template',
+        'cwst', 'label'
+    )
+), (
+    'cat.printlabels.templates', 'cat', 'object',
+    oils_i18n_gettext(
+        'cat.printlabels.templates',
+        'Print Label Templates',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.patron.search.include_inactive', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.patron.search.include_inactive',
+        'Patron Search Include Inactive',
+        'cwst', 'label'
+    )
+), (
+    'eg.circ.patron.search.show_extras', 'circ', 'bool',
+    oils_i18n_gettext(
+        'eg.circ.patron.search.show_extras',
+        'Patron Search Show Extra Search Options',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.checkin.checkin', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.checkin.checkin',
+        'Grid Config: circ.checkin.checkin',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.checkin.capture', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.checkin.capture',
+        'Grid Config: circ.checkin.capture',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.server.config.copy_tag_type', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.server.config.copy_tag_type',
+        'Grid Config: admin.server.config.copy_tag_type',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.server.config.metabib_field_virtual_map.grid', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.server.config.metabib_field_virtual_map.grid',
+        'Grid Config: admin.server.config.metabib_field_virtual_map.grid',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.server.config.metabib_field.grid', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.server.config.metabib_field.grid',
+        'Grid Config: admin.server.config.metabib_field.grid',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.server.config.marc_field', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.server.config.marc_field',
+        'Grid Config: admin.server.config.marc_field',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.server.asset.copy_tag', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.server.asset.copy_tag',
+        'Grid Config: admin.server.asset.copy_tag',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.local.circ.neg_balance_users', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.local.circ.neg_balance_users',
+        'Grid Config: admin.local.circ.neg_balance_users',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.local.rating.badge', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.local.rating.badge',
+        'Grid Config: admin.local.rating.badge',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.workstation.work_log', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.workstation.work_log',
+        'Grid Config: admin.workstation.work_log',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.workstation.patron_log', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.workstation.patron_log',
+        'Grid Config: admin.workstation.patron_log',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.serials.pattern_template', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.admin.serials.pattern_template',
+        'Grid Config: admin.serials.pattern_template',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.serials.copy_templates', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.serials.copy_templates',
+        'Grid Config: serials.copy_templates',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.record_overlay.holdings', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.record_overlay.holdings',
+        'Grid Config: cat.record_overlay.holdings',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.bucket.record.search', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.bucket.record.search',
+        'Grid Config: cat.bucket.record.search',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.bucket.record.view', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.bucket.record.view',
+        'Grid Config: cat.bucket.record.view',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.bucket.record.pending', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.bucket.record.pending',
+        'Grid Config: cat.bucket.record.pending',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.bucket.copy.view', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.bucket.copy.view',
+        'Grid Config: cat.bucket.copy.view',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.bucket.copy.pending', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.bucket.copy.pending',
+        'Grid Config: cat.bucket.copy.pending',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.items', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.items',
+        'Grid Config: cat.items',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.volcopy.copies', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.volcopy.copies',
+        'Grid Config: cat.volcopy.copies',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.volcopy.copies.complete', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.volcopy.copies.complete',
+        'Grid Config: cat.volcopy.copies.complete',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.peer_bibs', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.peer_bibs',
+        'Grid Config: cat.peer_bibs',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.catalog.holds', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.catalog.holds',
+        'Grid Config: cat.catalog.holds',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.holdings', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.holdings',
+        'Grid Config: cat.holdings',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.z3950_results', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.z3950_results',
+        'Grid Config: cat.z3950_results',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.holds.shelf', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.holds.shelf',
+        'Grid Config: circ.holds.shelf',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.holds.pull', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.holds.pull',
+        'Grid Config: circ.holds.pull',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.in_house_use', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.in_house_use',
+        'Grid Config: circ.in_house_use',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.renew', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.renew',
+        'Grid Config: circ.renew',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.transits.list', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.transits.list',
+        'Grid Config: circ.transits.list',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.holds', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.holds',
+        'Grid Config: circ.patron.holds',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.pending_patrons.list', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.pending_patrons.list',
+        'Grid Config: circ.pending_patrons.list',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.items_out.noncat', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.items_out.noncat',
+        'Grid Config: circ.patron.items_out.noncat',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.items_out', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.items_out',
+        'Grid Config: circ.patron.items_out',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.billhistory_payments', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.billhistory_payments',
+        'Grid Config: circ.patron.billhistory_payments',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.user.bucket.view', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.user.bucket.view',
+        'Grid Config: user.bucket.view',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.user.bucket.pending', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.user.bucket.pending',
+        'Grid Config: user.bucket.pending',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.staff_messages', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.staff_messages',
+        'Grid Config: circ.patron.staff_messages',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.archived_messages', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.archived_messages',
+        'Grid Config: circ.patron.archived_messages',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.bills', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.bills',
+        'Grid Config: circ.patron.bills',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.checkout', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.checkout',
+        'Grid Config: circ.patron.checkout',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.serials.mfhd_grid', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.serials.mfhd_grid',
+        'Grid Config: serials.mfhd_grid',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.serials.view_item_grid', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.serials.view_item_grid',
+        'Grid Config: serials.view_item_grid',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.serials.dist_stream_grid', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.serials.dist_stream_grid',
+        'Grid Config: serials.dist_stream_grid',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.circ.patron.search', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.circ.patron.search',
+        'Grid Config: circ.patron.search',
+        'cwst', 'label'
+    )
+), (
+    'eg.cat.record.summary.collapse', 'gui', 'bool',
+    oils_i18n_gettext(
+        'eg.cat.record.summary.collapse',
+        'Collapse Bib Record Summary',
+        'cwst', 'label'
+    )
+), (
+    'cat.marcedit.flateditor', 'gui', 'bool',
+    oils_i18n_gettext(
+        'cat.marcedit.flateditor',
+        'Use Flat MARC Editor',
+        'cwst', 'label'
+    )
+), (
+    'cat.marcedit.stack_subfields', 'gui', 'bool',
+    oils_i18n_gettext(
+        'cat.marcedit.stack_subfields',
+        'MARC Editor Stack Subfields',
+        'cwst', 'label'
+    )
+), (
+    'eg.offline.print_receipt', 'gui', 'bool',
+    oils_i18n_gettext(
+        'eg.offline.print_receipt',
+        'Offline Print Receipt',
+        'cwst', 'label'
+    )
+), (
+    'eg.offline.strict_barcode', 'gui', 'bool',
+    oils_i18n_gettext(
+        'eg.offline.strict_barcode',
+        'Offline Use Strict Barcode',
+        'cwst', 'label'
+    )
+), (
+    'cat.default_bib_marc_template', 'gui', 'string',
+    oils_i18n_gettext(
+        'cat.default_bib_marc_template',
+        'Default MARC Template',
+        'cwst', 'label'
+    )
+), (
+    'eg.audio.disable', 'gui', 'bool',
+    oils_i18n_gettext(
+        'eg.audio.disable',
+        'Disable Staff Client Notification Audio',
+        'cwst', 'label'
+    )
+), (
+    'eg.search.adv_pane', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.search.adv_pane',
+        'Catalog Advanced Search Default Pane',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.bills_current', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.bills_current',
+        'Print Template Context: bills_current',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.bills_current', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.bills_current',
+        'Print Template: bills_current',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.bills_historical', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.bills_historical',
+        'Print Template Context: bills_historical',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.bills_historical', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.bills_historical',
+        'Print Template: bills_historical',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.bill_payment', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.bill_payment',
+        'Print Template Context: bill_payment',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.bill_payment', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.bill_payment',
+        'Print Template: bill_payment',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.checkin', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.checkin',
+        'Print Template Context: checkin',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.checkin', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.checkin',
+        'Print Template: checkin',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.checkout', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.checkout',
+        'Print Template Context: checkout',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.checkout', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.checkout',
+        'Print Template: checkout',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.hold_transit_slip', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.hold_transit_slip',
+        'Print Template Context: hold_transit_slip',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.hold_transit_slip', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.hold_transit_slip',
+        'Print Template: hold_transit_slip',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.hold_shelf_slip', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.hold_shelf_slip',
+        'Print Template Context: hold_shelf_slip',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.hold_shelf_slip', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.hold_shelf_slip',
+        'Print Template: hold_shelf_slip',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.holds_for_bib', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.holds_for_bib',
+        'Print Template Context: holds_for_bib',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.holds_for_bib', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.holds_for_bib',
+        'Print Template: holds_for_bib',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.holds_for_patron', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.holds_for_patron',
+        'Print Template Context: holds_for_patron',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.holds_for_patron', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.holds_for_patron',
+        'Print Template: holds_for_patron',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.hold_pull_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.hold_pull_list',
+        'Print Template Context: hold_pull_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.hold_pull_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.hold_pull_list',
+        'Print Template: hold_pull_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.hold_shelf_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.hold_shelf_list',
+        'Print Template Context: hold_shelf_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.hold_shelf_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.hold_shelf_list',
+        'Print Template: hold_shelf_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.in_house_use_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.in_house_use_list',
+        'Print Template Context: in_house_use_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.in_house_use_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.in_house_use_list',
+        'Print Template: in_house_use_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.item_status', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.item_status',
+        'Print Template Context: item_status',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.item_status', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.item_status',
+        'Print Template: item_status',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.items_out', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.items_out',
+        'Print Template Context: items_out',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.items_out', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.items_out',
+        'Print Template: items_out',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.patron_address', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.patron_address',
+        'Print Template Context: patron_address',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.patron_address', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.patron_address',
+        'Print Template: patron_address',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.patron_data', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.patron_data',
+        'Print Template Context: patron_data',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.patron_data', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.patron_data',
+        'Print Template: patron_data',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.patron_note', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.patron_note',
+        'Print Template Context: patron_note',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.patron_note', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.patron_note',
+        'Print Template: patron_note',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.renew', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.renew',
+        'Print Template Context: renew',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.renew', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.renew',
+        'Print Template: renew',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.transit_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.transit_list',
+        'Print Template Context: transit_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.transit_list', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.transit_list',
+        'Print Template: transit_list',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.transit_slip', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.transit_slip',
+        'Print Template Context: transit_slip',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.transit_slip', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.transit_slip',
+        'Print Template: transit_slip',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.offline_checkout', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.offline_checkout',
+        'Print Template Context: offline_checkout',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.offline_checkout', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.offline_checkout',
+        'Print Template: offline_checkout',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.offline_renew', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.offline_renew',
+        'Print Template Context: offline_renew',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.offline_renew', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.offline_renew',
+        'Print Template: offline_renew',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.offline_checkin', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.offline_checkin',
+        'Print Template Context: offline_checkin',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.offline_checkin', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.offline_checkin',
+        'Print Template: offline_checkin',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template_context.offline_in_house_use', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template_context.offline_in_house_use',
+        'Print Template Context: offline_in_house_use',
+        'cwst', 'label'
+    )
+), (
+    'eg.print.template.offline_in_house_use', 'gui', 'string',
+    oils_i18n_gettext(
+        'eg.print.template.offline_in_house_use',
+        'Print Template: offline_in_house_use',
+        'cwst', 'label'
+    )
+), (
+    'eg.serials.stream_names', 'gui', 'array',
+    oils_i18n_gettext(
+        'eg.serials.stream_names',
+        'Serials Local Stream Names',
+        'cwst', 'label'
+    )
+), (
+    'eg.serials.items.do_print_routing_lists', 'gui', 'bool',
+    oils_i18n_gettext(
+        'eg.serials.items.do_print_routing_lists',
+        'Serials Print Routing Lists',
+        'cwst', 'label'
+    )
+), (
+    'eg.serials.items.receive_and_barcode', 'gui', 'bool',
+    oils_i18n_gettext(
+        'eg.serials.items.receive_and_barcode',
+        'Serials Barcode On Receive',
+        'cwst', 'label'
+    )
+);
+
+
+-- More values with fm_class'es
+INSERT INTO config.workstation_setting_type (name, grp, datatype, fm_class, label)
+VALUES (
+    'eg.search.search_lib', 'gui', 'link', 'aou',
+    oils_i18n_gettext(
+        'eg.search.search_lib',
+        'Staff Catalog Default Search Library',
+        'cwst', 'label'
+    )
+), (
+    'eg.search.pref_lib', 'gui', 'link', 'aou',
+    oils_i18n_gettext(
+        'eg.search.pref_lib',
+        'Staff Catalog Preferred Library',
+        'cwst', 'label'
+    )
+);
+
+
+END IF; END $INSERT$;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1118', :eg_version);
+
+UPDATE action_trigger.event_definition
+SET template =
+$$
+[%- USE date -%]
+[%- SET user = target.0.owner -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- params.sender_email || default_sender %]
+Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
+Subject: Bibliographic Records
+Auto-Submitted: auto-generated
+
+[% FOR cbreb IN target %]
+[% FOR item IN cbreb.items;
+    bre_id = item.target_biblio_record_entry;
+
+    bibxml = helpers.unapi_bre(bre_id, {flesh => '{mra}'});
+    title = '';
+    FOR part IN bibxml.findnodes('//*[@tag="245"]/*[@code="a" or @code="b"]');
+        title = title _ part.textContent;
+    END;
+
+    author = bibxml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
+    item_type = bibxml.findnodes('//*[local-name()="attributes"]/*[local-name()="field"][@name="item_type"]').getAttribute('coded-value');
+    publisher = bibxml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
+    pubdate = bibxml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
+    isbn = bibxml.findnodes('//*[@tag="020"]/*[@code="a"]').textContent;
+    issn = bibxml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
+    upc = bibxml.findnodes('//*[@tag="024"]/*[@code="a"]').textContent;
+%]
+
+[% loop.count %]/[% loop.size %].  Bib ID# [% bre_id %] 
+[% IF isbn %]ISBN: [% isbn _ "\n" %][% END -%]
+[% IF issn %]ISSN: [% issn _ "\n" %][% END -%]
+[% IF upc  %]UPC:  [% upc _ "\n" %] [% END -%]
+Title: [% title %]
+Author: [% author %]
+Publication Info: [% publisher %] [% pubdate %]
+Item Type: [% item_type %]
+
+[% END %]
+[% END %]
+$$
+WHERE hook = 'biblio.format.record_entry.email'
+-- from previous stock definition
+AND MD5(template) = 'ee4e6c1b3049086c570c7a77413d46c1';
+
+UPDATE action_trigger.event_definition
+SET template =
+$$
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <ol>
+    [% FOR cbreb IN target %]
+    [% FOR item IN cbreb.items;
+        bre_id = item.target_biblio_record_entry;
+
+        bibxml = helpers.unapi_bre(bre_id, {flesh => '{mra}'});
+        title = '';
+        FOR part IN bibxml.findnodes('//*[@tag="245"]/*[@code="a" or @code="b"]');
+            title = title _ part.textContent;
+        END;
+
+        author = bibxml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
+        item_type = bibxml.findnodes('//*[local-name()="attributes"]/*[local-name()="field"][@name="item_type"]').getAttribute('coded-value');
+        publisher = bibxml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
+        pubdate = bibxml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
+        isbn = bibxml.findnodes('//*[@tag="020"]/*[@code="a"]').textContent;
+        %]
+
+        <li>
+            Bib ID# [% bre_id %] ISBN: [% isbn %]<br />
+            Title: [% title %]<br />
+            Author: [% author %]<br />
+            Publication Info: [% publisher %] [% pubdate %]<br/>
+            Item Type: [% item_type %]
+        </li>
+    [% END %]
+    [% END %]
+    </ol>
+</div>
+$$
+WHERE hook = 'biblio.format.record_entry.print'
+-- from previous stock definition
+AND MD5(template) = '9ada7ea8417cb23f89d0dc8f15ec68d0';
+
+
+--SELECT evergreen.upgrade_deps_block_check('1120', :eg_version);
+
+--Only insert if the attributes are not already present
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+
+INSERT INTO config.z3950_attr (source, name, label, code, format, truncation)
+SELECT 'oclc','upc','UPC','1007','6','0'
+WHERE NOT EXISTS (SELECT name FROM config.z3950_attr WHERE source = 'oclc' AND name = 'upc');
+
+INSERT INTO config.z3950_attr (source, name, label, code, format, truncation)
+SELECT 'loc','upc','UPC','1007','1','1'
+WHERE NOT EXISTS (SELECT name FROM config.z3950_attr WHERE source = 'loc' AND name = 'upc');
+
+END IF; END $INSERT$;
+
+--SELECT evergreen.upgrade_deps_block_check('1121', :eg_version);
+
+CREATE TABLE permission.grp_tree_display_entry (
+    id      SERIAL PRIMARY KEY,
+    position INTEGER NOT NULL,
+    org     INTEGER NOT NULL REFERENCES actor.org_unit (id)
+            DEFERRABLE INITIALLY DEFERRED,
+    grp     INTEGER NOT NULL REFERENCES permission.grp_tree (id)
+            DEFERRABLE INITIALLY DEFERRED,
+    CONSTRAINT pgtde_once_per_org UNIQUE (org, grp)
+);
+
+ALTER TABLE permission.grp_tree_display_entry
+    ADD COLUMN parent integer REFERENCES permission.grp_tree_display_entry (id)
+            DEFERRABLE INITIALLY DEFERRED;
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+INSERT INTO permission.perm_list (id, code, description)
+VALUES (609, 'MANAGE_CUSTOM_PERM_GRP_TREE', oils_i18n_gettext( 609,
+    'Allows a user to manage custom permission group lists.', 'ppl', 'description' ));
+END IF; END $INSERT$;
+
+--SELECT evergreen.upgrade_deps_block_check('1122', :eg_version);
+
+ALTER TABLE actor.usr 
+    ADD COLUMN pref_prefix TEXT,
+    ADD COLUMN pref_first_given_name TEXT,
+    ADD COLUMN pref_second_given_name TEXT,
+    ADD COLUMN pref_family_name TEXT,
+    ADD COLUMN pref_suffix TEXT,
+    ADD COLUMN name_keywords TEXT,
+    ADD COLUMN name_kw_tsvector TSVECTOR;
+
+ALTER TABLE staging.user_stage
+    ADD COLUMN pref_first_given_name TEXT,
+    ADD COLUMN pref_second_given_name TEXT,
+    ADD COLUMN pref_family_name TEXT;
+
+CREATE INDEX actor_usr_pref_first_given_name_idx 
+    ON actor.usr (evergreen.lowercase(pref_first_given_name));
+CREATE INDEX actor_usr_pref_second_given_name_idx 
+    ON actor.usr (evergreen.lowercase(pref_second_given_name));
+CREATE INDEX actor_usr_pref_family_name_idx 
+    ON actor.usr (evergreen.lowercase(pref_family_name));
+CREATE INDEX actor_usr_pref_first_given_name_unaccent_idx 
+    ON actor.usr (evergreen.unaccent_and_squash(pref_first_given_name));
+CREATE INDEX actor_usr_pref_second_given_name_unaccent_idx 
+    ON actor.usr (evergreen.unaccent_and_squash(pref_second_given_name));
+CREATE INDEX actor_usr_pref_family_name_unaccent_idx 
+   ON actor.usr (evergreen.unaccent_and_squash(pref_family_name));
+
+CREATE OR REPLACE FUNCTION actor.user_ingest_name_keywords() 
+    RETURNS TRIGGER AS $func$
+BEGIN
+    NEW.name_kw_tsvector := TO_TSVECTOR(
+        COALESCE(NEW.prefix, '')                || ' ' || 
+        COALESCE(NEW.first_given_name, '')      || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(NEW.first_given_name), '') || ' ' || 
+        COALESCE(NEW.second_given_name, '')     || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(NEW.second_given_name), '') || ' ' || 
+        COALESCE(NEW.family_name, '')           || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(NEW.family_name), '') || ' ' || 
+        COALESCE(NEW.suffix, '')                || ' ' || 
+        COALESCE(NEW.pref_prefix, '')            || ' ' || 
+        COALESCE(NEW.pref_first_given_name, '')  || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(NEW.pref_first_given_name), '') || ' ' || 
+        COALESCE(NEW.pref_second_given_name, '') || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(NEW.pref_second_given_name), '') || ' ' || 
+        COALESCE(NEW.pref_family_name, '')       || ' ' || 
+        COALESCE(evergreen.unaccent_and_squash(NEW.pref_family_name), '') || ' ' || 
+        COALESCE(NEW.pref_suffix, '')            || ' ' || 
+        COALESCE(NEW.name_keywords, '')
+    );
+    RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+-- Add after the batch upate above to avoid duplicate updates.
+CREATE TRIGGER user_ingest_name_keywords_tgr 
+    BEFORE INSERT OR UPDATE ON actor.usr 
+    FOR EACH ROW EXECUTE PROCEDURE actor.user_ingest_name_keywords();
+
+-- merge pref names from source user to target user, except when
+-- clobbering existing pref names.
+CREATE OR REPLACE FUNCTION actor.usr_merge(src_usr INT, dest_usr INT, 
+    del_addrs BOOLEAN, del_cards BOOLEAN, deactivate_cards BOOLEAN ) 
+    RETURNS VOID AS $$
+DECLARE
+       suffix TEXT;
+       bucket_row RECORD;
+       picklist_row RECORD;
+       queue_row RECORD;
+       folder_row RECORD;
+BEGIN
+
+    -- do some initial cleanup 
+    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
+    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
+    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
+
+    -- actor.*
+    IF del_cards THEN
+        DELETE FROM actor.card where usr = src_usr;
+    ELSE
+        IF deactivate_cards THEN
+            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
+        END IF;
+        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
+    END IF;
+
+
+    IF del_addrs THEN
+        DELETE FROM actor.usr_address WHERE usr = src_usr;
+    ELSE
+        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
+    END IF;
+
+    UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
+    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
+    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
+    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
+
+    -- permission.*
+    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
+
+
+    -- container.*
+       
+       -- For each *_bucket table: transfer every bucket belonging to src_usr
+       -- into the custody of dest_usr.
+       --
+       -- In order to avoid colliding with an existing bucket owned by
+       -- the destination user, append the source user's id (in parenthesese)
+       -- to the name.  If you still get a collision, add successive
+       -- spaces to the name and keep trying until you succeed.
+       --
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.biblio_record_entry_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.biblio_record_entry_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.call_number_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.call_number_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.copy_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.copy_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.user_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.user_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
+
+    -- vandelay.*
+       -- transfer queues the same way we transfer buckets (see above)
+       FOR queue_row in
+               SELECT id, name
+               FROM   vandelay.queue
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  vandelay.queue
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = queue_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    -- money.*
+    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
+    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
+    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
+
+    -- action.*
+    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
+    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
+    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;
+
+    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
+    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
+    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
+
+    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
+    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
+
+    -- acq.*
+    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
+       UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
+
+       -- transfer picklists the same way we transfer buckets (see above)
+       FOR picklist_row in
+               SELECT id, name
+               FROM   acq.picklist
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  acq.picklist
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = picklist_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
+    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
+
+    -- asset.*
+    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
+
+    -- serial.*
+    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
+
+    -- reporter.*
+    -- It's not uncommon to define the reporter schema in a replica 
+    -- DB only, so don't assume these tables exist in the write DB.
+    BEGIN
+       UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+       UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+       UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.template_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.template_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.report_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.report_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.output_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.output_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+
+    -- propagate preferred name values from the source user to the
+    -- destination user, but only when values are not being replaced.
+    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr)
+    UPDATE actor.usr SET 
+        pref_prefix = 
+            COALESCE(pref_prefix, (SELECT pref_prefix FROM susr)),
+        pref_first_given_name = 
+            COALESCE(pref_first_given_name, (SELECT pref_first_given_name FROM susr)),
+        pref_second_given_name = 
+            COALESCE(pref_second_given_name, (SELECT pref_second_given_name FROM susr)),
+        pref_family_name = 
+            COALESCE(pref_family_name, (SELECT pref_family_name FROM susr)),
+        pref_suffix = 
+            COALESCE(pref_suffix, (SELECT pref_suffix FROM susr))
+    WHERE id = dest_usr;
+
+    -- Copy and deduplicate name keywords
+    -- String -> array -> rows -> DISTINCT -> array -> string
+    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr),
+         dusr AS (SELECT * FROM actor.usr WHERE id = dest_usr)
+    UPDATE actor.usr SET name_keywords = (
+        WITH keywords AS (
+            SELECT DISTINCT UNNEST(
+                REGEXP_SPLIT_TO_ARRAY(
+                    COALESCE((SELECT name_keywords FROM susr), '') || ' ' ||
+                    COALESCE((SELECT name_keywords FROM dusr), ''),  E'\\s+'
+                )
+            ) AS parts
+        ) SELECT ARRAY_TO_STRING(ARRAY_AGG(kw.parts), ' ') FROM keywords kw
+    ) WHERE id = dest_usr;
+
+    -- Finally, delete the source user
+    DELETE FROM actor.usr WHERE id = src_usr;
+
+END;
+$$ LANGUAGE plpgsql;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1123', :eg_version);
+
+    ALTER TABLE config.rule_circ_duration
+    ADD column max_auto_renewals INTEGER;
+
+    ALTER TABLE action.circulation
+    ADD column auto_renewal BOOLEAN;
+
+    ALTER TABLE action.circulation
+    ADD column auto_renewal_remaining INTEGER;
+
+    ALTER TABLE action.aged_circulation
+    ADD column auto_renewal BOOLEAN;
+
+    ALTER TABLE action.aged_circulation
+    ADD column auto_renewal_remaining INTEGER;
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+
+    INSERT INTO action_trigger.validator values('CircIsAutoRenewable', 'Checks whether the circulation is able to be autorenewed.');
+    INSERT INTO action_trigger.reactor values('Circ::AutoRenew', 'Auto-Renews a circulation.');
+    INSERT INTO action_trigger.hook(key, core_type, description) values('autorenewal', 'circ', 'Item was auto-renewed to patron.');
+
+    -- AutoRenewer A/T Def: 
+    INSERT INTO action_trigger.event_definition(active, owner, name, hook, validator, reactor, delay, max_delay, delay_field, group_field)
+        values (false, 1, 'Autorenew', 'checkout.due', 'CircIsOpen', 'Circ::AutoRenew', '-23 hours'::interval,'-1 minute'::interval, 'due_date', 'usr');
+
+    -- AutoRenewal outcome Email notifier A/T Def:
+    INSERT INTO action_trigger.event_definition(active, owner, name, hook, validator, reactor, group_field, template)
+        values (false, 1, 'AutorenewNotify', 'autorenewal', 'NOOP_True', 'SendEmail', 'usr', 
+$$
+[%- USE date -%]
+[%- user = target.0.usr -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- params.sender_email || default_sender %]
+Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
+Subject: Items Out Auto-Renewal Notification 
+Auto-Submitted: auto-generated
+
+Dear [% user.family_name %], [% user.first_given_name %]
+An automatic renewal attempt was made for the following items:
+
+[% FOR circ IN target %]
+    [%- SET idx = loop.count - 1; SET udata =  user_data.$idx -%]
+    [%- SET cid = circ.target_copy || udata.copy -%]
+    [%- SET copy_details = helpers.get_copy_bib_basics(cid) -%]
+    Item# [% loop.count %]
+    Title: [% copy_details.title %]
+    Author: [% copy_details.author %]
+    [%- IF udata.is_renewed %]
+    Status: Loan Renewed
+    New Due Date: [% date.format(helpers.format_date(udata.new_due_date), '%Y-%m-%d') %]
+    [%- ELSE %]
+    Status: Not Renewed
+    Reason: [% udata.reason %]
+    Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]
+    [% END %]
+[% END %]
+$$
+    );
+
+    INSERT INTO action_trigger.environment (event_def, path ) VALUES
+    ( currval('action_trigger.event_definition_id_seq'), 'usr' ),
+    ( currval('action_trigger.event_definition_id_seq'), 'circ_lib' );
+
+END IF; END $INSERT$;
+
+
+DROP VIEW action.all_circulation;
+CREATE OR REPLACE VIEW action.all_circulation AS
+    SELECT  id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
+        copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
+        circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
+        stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
+        max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
+        max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ,
+        auto_renewal, auto_renewal_remaining, NULL AS usr
+      FROM  action.aged_circulation
+            UNION ALL
+    SELECT  DISTINCT circ.id,COALESCE(a.post_code,b.post_code) AS usr_post_code, p.home_ou AS usr_home_ou, p.profile AS usr_profile, EXTRACT(YEAR FROM p.dob)::INT AS usr_birth_year,
+        cp.call_number AS copy_call_number, circ.copy_location, cn.owning_lib AS copy_owning_lib, cp.circ_lib AS copy_circ_lib,
+        cn.record AS copy_bib_record, circ.xact_start, circ.xact_finish, circ.target_copy, circ.circ_lib, circ.circ_staff, circ.checkin_staff,
+        circ.checkin_lib, circ.renewal_remaining, circ.grace_period, circ.due_date, circ.stop_fines_time, circ.checkin_time, circ.create_time, circ.duration,
+        circ.fine_interval, circ.recurring_fine, circ.max_fine, circ.phone_renewal, circ.desk_renewal, circ.opac_renewal, circ.duration_rule,
+        circ.recurring_fine_rule, circ.max_fine_rule, circ.stop_fines, circ.workstation, circ.checkin_workstation, circ.checkin_scan_time,
+        circ.parent_circ, circ.auto_renewal, circ.auto_renewal_remaining, circ.usr
+      FROM  action.circulation circ
+        JOIN asset.copy cp ON (circ.target_copy = cp.id)
+        JOIN asset.call_number cn ON (cp.call_number = cn.id)
+        JOIN actor.usr p ON (circ.usr = p.id)
+        LEFT JOIN actor.usr_address a ON (p.mailing_address = a.id)
+        LEFT JOIN actor.usr_address b ON (p.billing_address = b.id);
+
+
+DROP FUNCTION action.summarize_all_circ_chain (INTEGER);
+DROP FUNCTION action.all_circ_chain (INTEGER);
+
+-- rebuild slim circ view
+DROP VIEW action.all_circulation_slim;
+CREATE OR REPLACE VIEW action.all_circulation_slim AS
+    SELECT
+        id,
+        usr,
+        xact_start,
+        xact_finish,
+        unrecovered,
+        target_copy,
+        circ_lib,
+        circ_staff,
+        checkin_staff,
+        checkin_lib,
+        renewal_remaining,
+        grace_period,
+        due_date,
+        stop_fines_time,
+        checkin_time,
+        create_time,
+        duration,
+        fine_interval,
+        recurring_fine,
+        max_fine,
+        phone_renewal,
+        desk_renewal,
+        opac_renewal,
+        duration_rule,
+        recurring_fine_rule,
+        max_fine_rule,
+        stop_fines,
+        workstation,
+        checkin_workstation,
+        copy_location,
+        checkin_scan_time,
+        auto_renewal,
+        auto_renewal_remaining,
+        parent_circ
+    FROM action.circulation
+UNION ALL
+    SELECT
+        id,
+        NULL AS usr,
+        xact_start,
+        xact_finish,
+        unrecovered,
+        target_copy,
+        circ_lib,
+        circ_staff,
+        checkin_staff,
+        checkin_lib,
+        renewal_remaining,
+        grace_period,
+        due_date,
+        stop_fines_time,
+        checkin_time,
+        create_time,
+        duration,
+        fine_interval,
+        recurring_fine,
+        max_fine,
+        phone_renewal,
+        desk_renewal,
+        opac_renewal,
+        duration_rule,
+        recurring_fine_rule,
+        max_fine_rule,
+        stop_fines,
+        workstation,
+        checkin_workstation,
+        copy_location,
+        checkin_scan_time,
+        auto_renewal,
+        auto_renewal_remaining,
+        parent_circ
+    FROM action.aged_circulation
+;
+
+CREATE OR REPLACE FUNCTION action.all_circ_chain (ctx_circ_id INTEGER) 
+    RETURNS SETOF action.all_circulation_slim AS $$
+DECLARE
+    tmp_circ action.all_circulation_slim%ROWTYPE;
+    circ_0 action.all_circulation_slim%ROWTYPE;
+BEGIN
+
+    SELECT INTO tmp_circ * FROM action.all_circulation_slim WHERE id = ctx_circ_id;
+
+    IF tmp_circ IS NULL THEN
+        RETURN NEXT tmp_circ;
+    END IF;
+    circ_0 := tmp_circ;
+
+    -- find the front of the chain
+    WHILE TRUE LOOP
+        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
+            WHERE id = tmp_circ.parent_circ;
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        circ_0 := tmp_circ;
+    END LOOP;
+
+    -- now send the circs to the caller, oldest to newest
+    tmp_circ := circ_0;
+    WHILE TRUE LOOP
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        RETURN NEXT tmp_circ;
+        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
+            WHERE parent_circ = tmp_circ.id;
+    END LOOP;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+-- same as action.summarize_circ_chain, but returns data collected
+-- from action.all_circulation, which may include aged circulations.
+CREATE OR REPLACE FUNCTION action.summarize_all_circ_chain 
+    (ctx_circ_id INTEGER) RETURNS action.circ_chain_summary AS $$
+
+DECLARE
+
+    -- first circ in the chain
+    circ_0 action.all_circulation_slim%ROWTYPE;
+
+    -- last circ in the chain
+    circ_n action.all_circulation_slim%ROWTYPE;
+
+    -- circ chain under construction
+    chain action.circ_chain_summary;
+    tmp_circ action.all_circulation_slim%ROWTYPE;
+
+BEGIN
+    
+    chain.num_circs := 0;
+    FOR tmp_circ IN SELECT * FROM action.all_circ_chain(ctx_circ_id) LOOP
+
+        IF chain.num_circs = 0 THEN
+            circ_0 := tmp_circ;
+        END IF;
+
+        chain.num_circs := chain.num_circs + 1;
+        circ_n := tmp_circ;
+    END LOOP;
+
+    chain.start_time := circ_0.xact_start;
+    chain.last_stop_fines := circ_n.stop_fines;
+    chain.last_stop_fines_time := circ_n.stop_fines_time;
+    chain.last_checkin_time := circ_n.checkin_time;
+    chain.last_checkin_scan_time := circ_n.checkin_scan_time;
+    SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
+    SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
+
+    IF chain.num_circs > 1 THEN
+        chain.last_renewal_time := circ_n.xact_start;
+        SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
+    END IF;
+
+    RETURN chain;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+--SELECT evergreen.upgrade_deps_block_check('1124', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+
+INSERT into config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+    'eg.grid.circ.wide_holds.shelf', 'gui', 'object',
+    oils_i18n_gettext (
+        'eg.grid.circ.wide_holds.shelf',
+        'Grid Config: circ.wide_holds.shelf',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.cat.catalog.wide_holds', 'gui', 'object',
+    oils_i18n_gettext(
+        'eg.grid.cat.catalog.wide_holds',
+        'Grid Config: cat.catalog.wide_holds',
+        'cwst', 'label'
+    )
+);
+
+DELETE from config.workstation_setting_type
+WHERE name = 'eg.grid.cat.catalog.holds' OR name = 'eg.grid.circ.holds.shelf';
+END IF; END $INSERT$;
+
+--SELECT evergreen.upgrade_deps_block_check('1125', :eg_version);
+
+CREATE TABLE asset.latest_inventory (
+    id                          SERIAL                      PRIMARY KEY,
+    inventory_workstation       INTEGER                     REFERENCES actor.workstation (id) DEFERRABLE INITIALLY DEFERRED,
+    inventory_date              TIMESTAMP WITH TIME ZONE    DEFAULT NOW(),
+    copy                        BIGINT                      NOT NULL
+);
+CREATE INDEX latest_inventory_copy_idx ON asset.latest_inventory (copy);
+
+CREATE OR REPLACE FUNCTION evergreen.asset_latest_inventory_copy_inh_fkey() RETURNS TRIGGER AS $f$
+BEGIN
+        PERFORM 1 FROM asset.copy WHERE id = NEW.copy;
+        IF NOT FOUND THEN
+                RAISE foreign_key_violation USING MESSAGE = FORMAT(
+                        $$Referenced asset.copy id not found, copy:%s$$, NEW.copy
+                );
+        END IF;
+        RETURN NEW;
+END;
+$f$ LANGUAGE PLPGSQL VOLATILE COST 50;
+
+CREATE CONSTRAINT TRIGGER inherit_asset_latest_inventory_copy_fkey
+        AFTER UPDATE OR INSERT ON asset.latest_inventory
+        DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_latest_inventory_copy_inh_fkey();
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+INSERT into config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+    'eg.circ.checkin.do_inventory_update', 'circ', 'bool',
+    oils_i18n_gettext (
+             'eg.circ.checkin.do_inventory_update',
+             'Checkin: Update Inventory',
+             'cwst', 'label'
+    )
+);
+END IF; END $INSERT$;
+
+--SELECT evergreen.upgrade_deps_block_check('1126', :eg_version);
+
+CREATE TABLE vandelay.session_tracker (
+    id          BIGSERIAL PRIMARY KEY,
+
+    -- string of characters (e.g. md5) used for linking trackers
+    -- of different actions into a series.  There can be multiple
+    -- session_keys of each action type, creating the opportunity
+    -- to link multiple action trackers into a single session.
+    session_key TEXT NOT NULL,
+
+    -- optional user-supplied name
+    name        TEXT NOT NULL, 
+
+    usr         INTEGER NOT NULL REFERENCES actor.usr(id)
+                DEFERRABLE INITIALLY DEFERRED,
+
+    -- org unit can be derived from WS
+    workstation INTEGER NOT NULL REFERENCES actor.workstation(id)
+                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+
+    -- bib/auth
+    record_type vandelay.bib_queue_queue_type NOT NULL DEFAULT 'bib',
+
+    -- Queue defines the source of the data, it does not necessarily
+    -- mean that an action is being performed against an entire queue.
+    -- E.g. some imports are misc. lists of record IDs, but they always 
+    -- come from one queue.
+    -- No foreign key -- could be auth or bib queue.
+    queue       BIGINT NOT NULL,
+
+    create_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+    update_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+
+    state       TEXT NOT NULL DEFAULT 'active',
+
+    action_type TEXT NOT NULL DEFAULT 'enqueue', -- import
+
+    -- total number of tasks to perform / loosely defined
+    -- could be # of recs to import or # of recs + # of copies 
+    -- depending on the import context
+    total_actions INTEGER NOT NULL DEFAULT 0,
+
+    -- total number of tasked performed so far
+    actions_performed INTEGER NOT NULL DEFAULT 0,
+
+    CONSTRAINT vand_tracker_valid_state 
+        CHECK (state IN ('active','error','complete')),
+
+    CONSTRAINT vand_tracker_valid_action_type
+        CHECK (action_type IN ('upload', 'enqueue', 'import'))
+);
+
+
+CREATE OR REPLACE FUNCTION actor.usr_merge( src_usr INT, dest_usr INT, del_addrs BOOLEAN, del_cards BOOLEAN, deactivate_cards BOOLEAN ) RETURNS VOID AS $$
+DECLARE
+       suffix TEXT;
+       bucket_row RECORD;
+       picklist_row RECORD;
+       queue_row RECORD;
+       folder_row RECORD;
+BEGIN
+
+    -- do some initial cleanup 
+    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
+    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
+    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
+
+    -- actor.*
+    IF del_cards THEN
+        DELETE FROM actor.card where usr = src_usr;
+    ELSE
+        IF deactivate_cards THEN
+            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
+        END IF;
+        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
+    END IF;
+
+
+    IF del_addrs THEN
+        DELETE FROM actor.usr_address WHERE usr = src_usr;
+    ELSE
+        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
+    END IF;
+
+    UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
+    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
+    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
+    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
+
+    -- permission.*
+    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
+
+
+    -- container.*
+       
+       -- For each *_bucket table: transfer every bucket belonging to src_usr
+       -- into the custody of dest_usr.
+       --
+       -- In order to avoid colliding with an existing bucket owned by
+       -- the destination user, append the source user's id (in parenthesese)
+       -- to the name.  If you still get a collision, add successive
+       -- spaces to the name and keep trying until you succeed.
+       --
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.biblio_record_entry_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.biblio_record_entry_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.call_number_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.call_number_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.copy_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.copy_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.user_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.user_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
+
+    -- vandelay.*
+       -- transfer queues the same way we transfer buckets (see above)
+       FOR queue_row in
+               SELECT id, name
+               FROM   vandelay.queue
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  vandelay.queue
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = queue_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    UPDATE vandelay.session_tracker SET usr = dest_usr WHERE usr = src_usr;
+
+    -- money.*
+    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
+    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
+    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
+
+    -- action.*
+    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
+    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
+    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;
+
+    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
+    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
+    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
+
+    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
+    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
+
+    -- acq.*
+    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
+       UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
+
+       -- transfer picklists the same way we transfer buckets (see above)
+       FOR picklist_row in
+               SELECT id, name
+               FROM   acq.picklist
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  acq.picklist
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = picklist_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
+    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
+
+    -- asset.*
+    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
+
+    -- serial.*
+    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
+
+    -- reporter.*
+    -- It's not uncommon to define the reporter schema in a replica 
+    -- DB only, so don't assume these tables exist in the write DB.
+    BEGIN
+       UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+       UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+       UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.template_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.template_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.report_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.report_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.output_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.output_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+
+    -- propagate preferred name values from the source user to the
+    -- destination user, but only when values are not being replaced.
+    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr)
+    UPDATE actor.usr SET 
+        pref_prefix = 
+            COALESCE(pref_prefix, (SELECT pref_prefix FROM susr)),
+        pref_first_given_name = 
+            COALESCE(pref_first_given_name, (SELECT pref_first_given_name FROM susr)),
+        pref_second_given_name = 
+            COALESCE(pref_second_given_name, (SELECT pref_second_given_name FROM susr)),
+        pref_family_name = 
+            COALESCE(pref_family_name, (SELECT pref_family_name FROM susr)),
+        pref_suffix = 
+            COALESCE(pref_suffix, (SELECT pref_suffix FROM susr))
+    WHERE id = dest_usr;
+
+    -- Copy and deduplicate name keywords
+    -- String -> array -> rows -> DISTINCT -> array -> string
+    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr),
+         dusr AS (SELECT * FROM actor.usr WHERE id = dest_usr)
+    UPDATE actor.usr SET name_keywords = (
+        WITH keywords AS (
+            SELECT DISTINCT UNNEST(
+                REGEXP_SPLIT_TO_ARRAY(
+                    COALESCE((SELECT name_keywords FROM susr), '') || ' ' ||
+                    COALESCE((SELECT name_keywords FROM dusr), ''),  E'\\s+'
+                )
+            ) AS parts
+        ) SELECT ARRAY_TO_STRING(ARRAY_AGG(kw.parts), ' ') FROM keywords kw
+    ) WHERE id = dest_usr;
+
+    -- Finally, delete the source user
+    DELETE FROM actor.usr WHERE id = src_usr;
+
+END;
+$$ LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION actor.usr_purge_data(
+       src_usr  IN INTEGER,
+       specified_dest_usr IN INTEGER
+) RETURNS VOID AS $$
+DECLARE
+       suffix TEXT;
+       renamable_row RECORD;
+       dest_usr INTEGER;
+BEGIN
+
+       IF specified_dest_usr IS NULL THEN
+               dest_usr := 1; -- Admin user on stock installs
+       ELSE
+               dest_usr := specified_dest_usr;
+       END IF;
+
+       -- acq.*
+       UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
+       UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
+       UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
+       DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;
+
+       -- Update with a rename to avoid collisions
+       FOR renamable_row in
+               SELECT id, name
+               FROM   acq.picklist
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  acq.picklist
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
+       UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;
+
+       -- action.*
+       DELETE FROM action.circulation WHERE usr = src_usr;
+       UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
+       UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
+       UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
+       UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
+       UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
+       DELETE FROM action.hold_request WHERE usr = src_usr;
+       UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
+       UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
+       DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
+       UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
+       DELETE FROM action.survey_response WHERE usr = src_usr;
+       UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
+       DELETE FROM action.usr_circ_history WHERE usr = src_usr;
+
+       -- actor.*
+       DELETE FROM actor.card WHERE usr = src_usr;
+       DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
+
+       -- The following update is intended to avoid transient violations of a foreign
+       -- key constraint, whereby actor.usr_address references itself.  It may not be
+       -- necessary, but it does no harm.
+       UPDATE actor.usr_address SET replaces = NULL
+               WHERE usr = src_usr AND replaces IS NOT NULL;
+       DELETE FROM actor.usr_address WHERE usr = src_usr;
+       DELETE FROM actor.usr_note WHERE usr = src_usr;
+       UPDATE actor.usr_note SET creator = dest_usr WHERE creator = src_usr;
+       DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
+       UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
+       DELETE FROM actor.usr_setting WHERE usr = src_usr;
+       DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
+       UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
+
+       -- asset.*
+       UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
+
+       -- auditor.*
+       DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
+       DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
+       UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE auditor.asset_call_number_history SET editor  = dest_usr WHERE editor  = src_usr;
+       UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE auditor.asset_copy_history SET editor  = dest_usr WHERE editor  = src_usr;
+       UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE auditor.biblio_record_entry_history SET editor  = dest_usr WHERE editor  = src_usr;
+
+       -- biblio.*
+       UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;
+
+       -- container.*
+       -- Update buckets with a rename to avoid collisions
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.biblio_record_entry_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.biblio_record_entry_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.call_number_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.call_number_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.copy_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.copy_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.user_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.user_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       DELETE FROM container.user_bucket_item WHERE target_user = src_usr;
+
+       -- money.*
+       DELETE FROM money.billable_xact WHERE usr = src_usr;
+       DELETE FROM money.collections_tracker WHERE usr = src_usr;
+       UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;
+
+       -- permission.*
+       DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
+       DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
+       DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
+       DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;
+
+       -- reporter.*
+       -- Update with a rename to avoid collisions
+       BEGIN
+               FOR renamable_row in
+                       SELECT id, name
+                       FROM   reporter.output_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.output_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = renamable_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       BEGIN
+               UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       -- Update with a rename to avoid collisions
+       BEGIN
+               FOR renamable_row in
+                       SELECT id, name
+                       FROM   reporter.report_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.report_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = renamable_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       BEGIN
+               UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       BEGIN
+               UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       -- Update with a rename to avoid collisions
+       BEGIN
+               FOR renamable_row in
+                       SELECT id, name
+                       FROM   reporter.template_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.template_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = renamable_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+       EXCEPTION WHEN undefined_table THEN
+       -- do nothing
+       END;
+
+       -- vandelay.*
+       -- Update with a rename to avoid collisions
+       FOR renamable_row in
+               SELECT id, name
+               FROM   vandelay.queue
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  vandelay.queue
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    UPDATE vandelay.session_tracker SET usr = dest_usr WHERE usr = src_usr;
+
+    -- NULL-ify addresses last so other cleanup (e.g. circ anonymization)
+    -- can access the information before deletion.
+       UPDATE actor.usr SET
+               active = FALSE,
+               card = NULL,
+               mailing_address = NULL,
+               billing_address = NULL
+       WHERE id = src_usr;
+
+END;
+$$ LANGUAGE plpgsql;
+
+
+--SELECT evergreen.upgrade_deps_block_check('1127', :eg_version);
+
+ALTER TABLE acq.user_request ADD COLUMN cancel_time TIMESTAMPTZ;
+ALTER TABLE acq.user_request ADD COLUMN upc TEXT;
+ALTER TABLE action.hold_request ADD COLUMN acq_request INT REFERENCES acq.user_request (id);
+
+UPDATE
+    config.org_unit_setting_type
+SET
+    label = oils_i18n_gettext(
+        'circ.holds.canceled.display_age',
+        'Canceled holds/requests display age',
+        'coust', 'label'),
+    description = oils_i18n_gettext(
+        'circ.holds.canceled.display_age',
+        'Show all canceled entries in patron holds and patron acquisition requests interfaces that were canceled within this amount of time',
+        'coust', 'description')
+WHERE
+    name = 'circ.holds.canceled.display_age'
+;
+
+UPDATE
+    config.org_unit_setting_type
+SET
+    label = oils_i18n_gettext(
+        'circ.holds.canceled.display_count',
+        'Canceled holds/requests display count',
+        'coust', 'label'),
+    description = oils_i18n_gettext(
+        'circ.holds.canceled.display_count',
+        'How many canceled entries to show in patron holds and patron acquisition requests interfaces',
+        'coust', 'description')
+WHERE
+    name = 'circ.holds.canceled.display_count'
+;
+
+
+-- replace existing, unused cancel reason with the new one.
+UPDATE acq.cancel_reason SET org_unit = 1, keep_debits = FALSE, 
+    label = 'Canceled: Fulfilled', 
+    description = 'This acquisition request has been fulfilled.' 
+    WHERE id = 1015;
+
+/*
+INSERT INTO acq.cancel_reason (org_unit, keep_debits, id, label, description)
+    VALUES (
+        1, 'f', 1015,
+        oils_i18n_gettext(1015, 'Canceled: Fulfilled', 'acqcr', 'label'),
+        oils_i18n_gettext(1015, 'This acquisition request has been fulfilled.', 'acqcr', 'description')
+    )
+;
+*/
+
+UPDATE
+    acq.user_request_type
+SET
+    label = oils_i18n_gettext('2', 'Articles', 'aurt', 'label')
+WHERE
+    id = 2
+;
+
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+
+INSERT INTO acq.user_request_type (id,label)
+    SELECT 6, oils_i18n_gettext('6', 'Other', 'aurt', 'label');
+
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+ ( 610, 'CLEAR_PURCHASE_REQUEST', oils_i18n_gettext(610,
+    'Clear Completed User Purchase Requests', 'ppl', 'description'))
+;
+
+END IF; END $INSERT$;
+
+SELECT SETVAL('acq.user_request_type_id_seq'::TEXT, (SELECT MAX(id)+1 FROM acq.user_request_type));
+
+CREATE TABLE acq.user_request_status_type (
+     id  SERIAL  PRIMARY KEY
+    ,label TEXT
+);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+INSERT INTO acq.user_request_status_type (id,label) VALUES
+     (0,oils_i18n_gettext(0,'Error','aurst','label'))
+    ,(1,oils_i18n_gettext(1,'New','aurst','label'))
+    ,(2,oils_i18n_gettext(2,'Pending','aurst','label'))
+    ,(3,oils_i18n_gettext(3,'Ordered, Hold Not Placed','aurst','label'))
+    ,(4,oils_i18n_gettext(4,'Ordered, Hold Placed','aurst','label'))
+    ,(5,oils_i18n_gettext(5,'Received','aurst','label'))
+    ,(6,oils_i18n_gettext(6,'Fulfilled','aurst','label'))
+    ,(7,oils_i18n_gettext(7,'Canceled','aurst','label'))
+;
+
+END IF; END $INSERT$;
+
+SELECT SETVAL('acq.user_request_status_type_id_seq'::TEXT, 100);
+
+-- not used
+DELETE FROM actor.org_unit_setting WHERE name = 'acq.holds.allow_holds_from_purchase_request';
+DELETE FROM config.org_unit_setting_type_log WHERE field_name = 'acq.holds.allow_holds_from_purchase_request';
+DELETE FROM config.org_unit_setting_type WHERE name = 'acq.holds.allow_holds_from_purchase_request';
+
+
+--SELECT evergreen.upgrade_deps_block_check('1128', :eg_version);
+
+-- KCLS already had this
+/*
+DROP VIEW auditor.acq_invoice_lifecycle;
+
+ALTER TABLE acq.invoice
+    ADD COLUMN close_date TIMESTAMPTZ,
+    ADD COLUMN closed_by  INTEGER 
+        REFERENCES actor.usr (id) DEFERRABLE INITIALLY DEFERRED;
+
+-- duplicate steps for auditor table
+ALTER TABLE auditor.acq_invoice_history
+    ADD COLUMN close_date TIMESTAMPTZ,
+    ADD COLUMN closed_by  INTEGER;
+
+UPDATE acq.invoice SET close_date = NOW() WHERE complete;
+UPDATE auditor.acq_invoice_history SET close_date = NOW() WHERE complete;
+
+ALTER TABLE acq.invoice DROP COLUMN complete;
+ALTER TABLE auditor.acq_invoice_history DROP COLUMN complete;
+
+-- this recreates auditor.acq_invoice_lifecycle;
+SELECT auditor.update_auditors();
+*/
+
+CREATE OR REPLACE FUNCTION actor.usr_merge( src_usr INT, dest_usr INT, del_addrs BOOLEAN, del_cards BOOLEAN, deactivate_cards BOOLEAN ) RETURNS VOID AS $$
+DECLARE
+       suffix TEXT;
+       bucket_row RECORD;
+       picklist_row RECORD;
+       queue_row RECORD;
+       folder_row RECORD;
+BEGIN
+
+    -- do some initial cleanup 
+    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
+    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
+    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
+
+    -- actor.*
+    IF del_cards THEN
+        DELETE FROM actor.card where usr = src_usr;
+    ELSE
+        IF deactivate_cards THEN
+            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
+        END IF;
+        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
+    END IF;
+
+
+    IF del_addrs THEN
+        DELETE FROM actor.usr_address WHERE usr = src_usr;
+    ELSE
+        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
+    END IF;
+
+    UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
+    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
+    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
+    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
+
+    -- permission.*
+    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
+
+
+    -- container.*
+       
+       -- For each *_bucket table: transfer every bucket belonging to src_usr
+       -- into the custody of dest_usr.
+       --
+       -- In order to avoid colliding with an existing bucket owned by
+       -- the destination user, append the source user's id (in parenthesese)
+       -- to the name.  If you still get a collision, add successive
+       -- spaces to the name and keep trying until you succeed.
+       --
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.biblio_record_entry_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.biblio_record_entry_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.call_number_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.call_number_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.copy_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.copy_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR bucket_row in
+               SELECT id, name
+               FROM   container.user_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.user_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = bucket_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
+
+    -- vandelay.*
+       -- transfer queues the same way we transfer buckets (see above)
+       FOR queue_row in
+               SELECT id, name
+               FROM   vandelay.queue
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  vandelay.queue
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = queue_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    -- money.*
+    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
+    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
+    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
+    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
+
+    -- action.*
+    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
+    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
+    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;
+
+    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
+    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
+    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
+    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
+
+    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
+    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
+    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
+
+    -- acq.*
+    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
+       UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
+    UPDATE acq.invoice SET closed_by = dest_usr WHERE closed_by = src_usr;
+
+       -- transfer picklists the same way we transfer buckets (see above)
+       FOR picklist_row in
+               SELECT id, name
+               FROM   acq.picklist
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  acq.picklist
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = picklist_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
+    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
+
+    -- asset.*
+    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
+
+    -- serial.*
+    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
+    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
+
+    -- reporter.*
+    -- It's not uncommon to define the reporter schema in a replica 
+    -- DB only, so don't assume these tables exist in the write DB.
+    BEGIN
+       UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+       UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+       UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.template_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.template_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.report_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.report_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+    BEGIN
+               -- transfer folders the same way we transfer buckets (see above)
+               FOR folder_row in
+                       SELECT id, name
+                       FROM   reporter.output_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.output_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = folder_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+    EXCEPTION WHEN undefined_table THEN
+        -- do nothing
+    END;
+
+    -- Finally, delete the source user
+    DELETE FROM actor.usr WHERE id = src_usr;
+
+END;
+$$ LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION actor.usr_purge_data(
+       src_usr  IN INTEGER,
+       specified_dest_usr IN INTEGER
+) RETURNS VOID AS $$
+DECLARE
+       suffix TEXT;
+       renamable_row RECORD;
+       dest_usr INTEGER;
+BEGIN
+
+       IF specified_dest_usr IS NULL THEN
+               dest_usr := 1; -- Admin user on stock installs
+       ELSE
+               dest_usr := specified_dest_usr;
+       END IF;
+
+       -- acq.*
+       UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
+       UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
+       UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
+    UPDATE acq.invoice SET closed_by = dest_usr WHERE closed_by = src_usr;
+       DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;
+
+       -- Update with a rename to avoid collisions
+       FOR renamable_row in
+               SELECT id, name
+               FROM   acq.picklist
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  acq.picklist
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
+       UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;
+
+       -- action.*
+       DELETE FROM action.circulation WHERE usr = src_usr;
+       UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
+       UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
+       UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
+       UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
+       UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
+       DELETE FROM action.hold_request WHERE usr = src_usr;
+       UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
+       UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
+       DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
+       UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
+       DELETE FROM action.survey_response WHERE usr = src_usr;
+       UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
+       DELETE FROM action.usr_circ_history WHERE usr = src_usr;
+
+       -- actor.*
+       DELETE FROM actor.card WHERE usr = src_usr;
+       DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
+
+       -- The following update is intended to avoid transient violations of a foreign
+       -- key constraint, whereby actor.usr_address references itself.  It may not be
+       -- necessary, but it does no harm.
+       UPDATE actor.usr_address SET replaces = NULL
+               WHERE usr = src_usr AND replaces IS NOT NULL;
+       DELETE FROM actor.usr_address WHERE usr = src_usr;
+       DELETE FROM actor.usr_note WHERE usr = src_usr;
+       UPDATE actor.usr_note SET creator = dest_usr WHERE creator = src_usr;
+       DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
+       UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
+       DELETE FROM actor.usr_setting WHERE usr = src_usr;
+       DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
+       UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
+
+       -- asset.*
+       UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
+
+       -- auditor.*
+       DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
+       DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
+       UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE auditor.asset_call_number_history SET editor  = dest_usr WHERE editor  = src_usr;
+       UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE auditor.asset_copy_history SET editor  = dest_usr WHERE editor  = src_usr;
+       UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE auditor.biblio_record_entry_history SET editor  = dest_usr WHERE editor  = src_usr;
+
+       -- biblio.*
+       UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
+       UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
+       UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;
+
+       -- container.*
+       -- Update buckets with a rename to avoid collisions
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.biblio_record_entry_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.biblio_record_entry_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.call_number_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.call_number_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.copy_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.copy_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       FOR renamable_row in
+               SELECT id, name
+               FROM   container.user_bucket
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  container.user_bucket
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+       DELETE FROM container.user_bucket_item WHERE target_user = src_usr;
+
+       -- money.*
+       DELETE FROM money.billable_xact WHERE usr = src_usr;
+       DELETE FROM money.collections_tracker WHERE usr = src_usr;
+       UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;
+
+       -- permission.*
+       DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
+       DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
+       DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
+       DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;
+
+       -- reporter.*
+       -- Update with a rename to avoid collisions
+       BEGIN
+               FOR renamable_row in
+                       SELECT id, name
+                       FROM   reporter.output_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.output_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = renamable_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       BEGIN
+               UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       -- Update with a rename to avoid collisions
+       BEGIN
+               FOR renamable_row in
+                       SELECT id, name
+                       FROM   reporter.report_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.report_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = renamable_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       BEGIN
+               UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       BEGIN
+               UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
+       EXCEPTION WHEN undefined_table THEN
+               -- do nothing
+       END;
+
+       -- Update with a rename to avoid collisions
+       BEGIN
+               FOR renamable_row in
+                       SELECT id, name
+                       FROM   reporter.template_folder
+                       WHERE  owner = src_usr
+               LOOP
+                       suffix := ' (' || src_usr || ')';
+                       LOOP
+                               BEGIN
+                                       UPDATE  reporter.template_folder
+                                       SET     owner = dest_usr, name = name || suffix
+                                       WHERE   id = renamable_row.id;
+                               EXCEPTION WHEN unique_violation THEN
+                                       suffix := suffix || ' ';
+                                       CONTINUE;
+                               END;
+                               EXIT;
+                       END LOOP;
+               END LOOP;
+       EXCEPTION WHEN undefined_table THEN
+       -- do nothing
+       END;
+
+       -- vandelay.*
+       -- Update with a rename to avoid collisions
+       FOR renamable_row in
+               SELECT id, name
+               FROM   vandelay.queue
+               WHERE  owner = src_usr
+       LOOP
+               suffix := ' (' || src_usr || ')';
+               LOOP
+                       BEGIN
+                               UPDATE  vandelay.queue
+                               SET     owner = dest_usr, name = name || suffix
+                               WHERE   id = renamable_row.id;
+                       EXCEPTION WHEN unique_violation THEN
+                               suffix := suffix || ' ';
+                               CONTINUE;
+                       END;
+                       EXIT;
+               END LOOP;
+       END LOOP;
+
+    -- NULL-ify addresses last so other cleanup (e.g. circ anonymization)
+    -- can access the information before deletion.
+       UPDATE actor.usr SET
+               active = FALSE,
+               card = NULL,
+               mailing_address = NULL,
+               billing_address = NULL
+       WHERE id = src_usr;
+
+END;
+$$ LANGUAGE plpgsql;
+
+
+
+
+
+-- UNDO (minus user purge/merge changes)
+/*
+
+DROP VIEW auditor.acq_invoice_lifecycle;
+ALTER TABLE acq.invoice ADD COLUMN complete BOOLEAN NOT NULL DEFAULT FALSE;
+ALTER TABLE auditor.acq_invoice_history 
+    ADD COLUMN complete BOOLEAN NOT NULL DEFAULT FALSE;
+UPDATE acq.invoice SET complete = TRUE where close_date IS NOT NULL;
+UPDATE auditor.acq_invoice_history 
+    SET complete = TRUE where close_date IS NOT NULL;
+SET CONSTRAINTS ALL IMMEDIATE; -- or get pending triggers error.
+ALTER TABLE acq.invoice DROP COLUMN close_date, DROP COLUMN closed_by;
+ALTER TABLE auditor.acq_invoice_history
+    DROP COLUMN close_date, DROP COLUMN closed_by;
+SELECT auditor.update_auditors();
+
+*/
+
+
+--SELECT evergreen.upgrade_deps_block_check('1129', :eg_version);
+
+DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
+
+INSERT into config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+    'eg.grid.admin.acq.cancel_reason', 'gui', 'object',
+    oils_i18n_gettext (
+        'eg.grid.admin.acq.cancel_reason',
+        'Grid Config: admin.acq.cancel_reason',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.claim_event_type', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.claim_event_type',
+        'Grid Config: admin.acq.claim_event_type',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.claim_policy', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.claim_policy',
+        'Grid Config: admin.acq.claim_policy',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.claim_policy_action', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.claim_policy_action',
+        'Grid Config: admin.acq.claim_policy_action',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.claim_type', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.claim_type',
+        'Grid Config: admin.acq.claim_type',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.currency_type', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.currency_type',
+        'Grid Config: admin.acq.currency_type',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.edi_account', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.edi_account',
+        'Grid Config: admin.acq.edi_account',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.edi_message', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.edi_message',
+        'Grid Config: admin.acq.edi_message',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.exchange_rate', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.exchange_rate',
+        'Grid Config: admin.acq.exchange_rate',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.fund_tag', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.fund_tag',
+        'Grid Config: admin.acq.fund_tag',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.invoice_item_type', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.invoice_item_type',
+        'Grid Config: admin.acq.invoice_item_type',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.invoice_payment_method', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.invoice_payment_method',
+        'Grid Config: admin.acq.invoice_payment_method',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.lineitem_alert_text', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.lineitem_alert_text',
+        'Grid Config: admin.acq.lineitem_alert_text',
+        'cwst', 'label'
+    )
+), (
+    'eg.grid.admin.acq.lineitem_marc_attr_definition', 'gui', 'object',
+    oils_i18n_gettext (
+    'eg.grid.admin.acq.lineitem_marc_attr_definition',
+        'Grid Config: admin.acq.lineitem_marc_attr_definition',
+        'cwst', 'label'
+    )
+);
+
+END IF; END $INSERT$;
+
+----------------------------------------------------------------------------
+-- VERSION INSERTS
+----------------------------------------------------------------------------
+
+DO $INSERT$
+BEGIN
+    IF evergreen.insert_on_deploy() THEN
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.0', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1032', '3.0.0'); -- Bmagic/csharp/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1034', '3.0.0');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1035', '3.0.0'); -- dyrcona/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1036', '3.0.0');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1041', '3.0.0'); -- stompro/csharp/gmcharlt
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1042', '3.0.0'); -- mmorgan/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1043', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1044', '3.0.0');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1045', '3.0.0'); -- csharp/berick/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1046', '3.0.0'); -- phasefx/berick/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1047', '3.0.0'); -- gmcharlt/stompro
+PERFORM evergreen.upgrade_deps_block_check('1048', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1049', '3.0.0'); -- mmorgan/stompro/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1050', '3.0.0'); -- mmorgan/cesardv/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1051', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1052', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1053', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1054', '3.0.0');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1056', '3.0.0'); -- miker/gmcharlt
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1057', '3.0.0'); -- miker/gmcharlt/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1076', '3.0.0'); -- miker/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1058', '3.0.0'); -- mccanna/csharp/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1059', '3.0.0'); --Stompro/DPearl/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1060', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1061', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1062', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1063', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1064', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1065', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1066', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1067', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1068', '3.0.0'); --miker/gmcharlt/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1069', '3.0.0'); --gmcharlt/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1070', '3.0.0'); --miker/gmcharlt/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1071', '3.0.0'); --gmcharlt/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1072', '3.0.0'); --gmcharlt/kmlussier
+PERFORM evergreen.upgrade_deps_block_check('1073', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1074', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1075', '3.0.0');
+PERFORM evergreen.upgrade_deps_block_check('1077', '3.0.0'); -- csharp/gmcharlt
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.1', '3.0.0');
+--PERFORM evergreen.upgrade_deps_block_check('1078', '3.0.1'); -- csharp/bshum/gmcharlt
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.2', '3.0.1');
+--PERFORM evergreen.upgrade_deps_block_check('1079', '3.0.2'); -- rhamby/cesardv/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1080', '3.0.2'); -- miker/jboyer/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1081', '3.0.2'); -- jboyer/gmcharlt
+PERFORM evergreen.upgrade_deps_block_check('1082', '3.0.2'); -- jboyer/gmcharlt
+--PERFORM evergreen.upgrade_deps_block_check('1083', '3.0.2');
+PERFORM evergreen.upgrade_deps_block_check('1084', '3.0.2');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.3', '3.0.2');
+PERFORM evergreen.upgrade_deps_block_check('1085', '3.0.3');
+PERFORM evergreen.upgrade_deps_block_check('1086', '3.0.3');
+PERFORM evergreen.upgrade_deps_block_check('1087', '3.0.3');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.4', '3.0.3');
+PERFORM evergreen.upgrade_deps_block_check('1088', '3.0.4');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.5', '3.0.4');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.6', '3.0.5');
+PERFORM evergreen.upgrade_deps_block_check('1107', '3.0.6');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.0', '3.0.6');
+PERFORM evergreen.upgrade_deps_block_check('1089', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1090', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1091', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1092', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1093', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1094', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1095', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1096', '3.1.0');
+
+PERFORM evergreen.upgrade_deps_block_check('1097', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1098', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1099', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1100', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1101', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1102', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1103', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1104', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1105', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1106', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1108', '3.1.0');
+PERFORM evergreen.upgrade_deps_block_check('1109', '3.1.0');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.1', '3.1.0');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.2', '3.1.1');
+PERFORM evergreen.upgrade_deps_block_check('1110', '3.1.2');
+PERFORM evergreen.upgrade_deps_block_check('1111', '3.1.2');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.3', '3.1.2');
+PERFORM evergreen.upgrade_deps_block_check('1112', '3.1.3');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.4', '3.1.3');
+PERFORM evergreen.upgrade_deps_block_check('1113', '3.1.4'); 
+PERFORM evergreen.upgrade_deps_block_check('1114', '3.1.4');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.5', '3.1.4');
+PERFORM evergreen.upgrade_deps_block_check('1119', '3.1.5');
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.2.1', '3.1.5');
+PERFORM evergreen.upgrade_deps_block_check('1115', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1116', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1117', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1118', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1120', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1121', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1122', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1123', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1124', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1125', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1126', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1127', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1128', '3.2.1');
+PERFORM evergreen.upgrade_deps_block_check('1129', '3.2.1');
+    END IF;
+END $INSERT$;
+
+-- COMMIT;
+ROLLBACK;
diff --git a/KCLS/sql/schema/revert/2.12-3.2-db-upgrade-data.sql b/KCLS/sql/schema/revert/2.12-3.2-db-upgrade-data.sql
new file mode 100644 (file)
index 0000000..fe7f507
--- /dev/null
@@ -0,0 +1,5 @@
+-- Revert kcls-evergreen:2.12-3.2-db-upgrade-data from pg
+
+BEGIN;
+
+COMMIT;
diff --git a/KCLS/sql/schema/revert/2.12-3.2-db-upgrade-schema.sql b/KCLS/sql/schema/revert/2.12-3.2-db-upgrade-schema.sql
new file mode 100644 (file)
index 0000000..3f85150
--- /dev/null
@@ -0,0 +1,5 @@
+-- Revert kcls-evergreen:2.12-3.2-db-upgrade-schema from pg
+
+BEGIN;
+
+COMMIT;
index c8143ad..da37222 100644 (file)
@@ -75,3 +75,5 @@ ecard-notice-validator [remove-gender] 2018-07-26T14:33:57Z Bill Erickson,,, <be
 stock-browse-schema [ecard-notice-validator] 2018-08-31T15:22:58Z Bill Erickson,,, <berick@kcls-dev-local> # Recover stock browse data tables, etc.
 stock-browse-headings-report [stock-browse-schema] 2018-10-04T15:56:18Z Bill Erickson,,, <berick@kcls-dev> # New heading report updates for stock browse
 stock-browse-cleanup [stock-browse-schema] 2018-10-03T18:05:49Z Bill Erickson,,, <berick@kcls-dev> # Delete old browse data
+2.12-3.2-db-upgrade-schema [ecard-notice-validator] 2018-09-12T14:46:28Z Bill Erickson,,, <berick@kcls-dev-local> # 2.12 to 3.2 DB update
+2.12-3.2-db-upgrade-data [2.12-3.2-db-upgrade-schema] 2018-09-12T14:46:52Z Bill Erickson,,, <berick@kcls-dev-local> # 2.12 to 3.2 post-update data
diff --git a/kcls-2.12-3.2-db-upgrade-data.sql b/kcls-2.12-3.2-db-upgrade-data.sql
deleted file mode 100644 (file)
index 5a158b8..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-
-----------------------------------------------------------------------------
--- 2.12 -> 3.2 SQL DATA UPDATES
--- No global transaction here.
-----------------------------------------------------------------------------
-
-\set ON_ERROR_STOP on
-
-SET STATEMENT_TIMEOUT = 0;
-
-----------------------------------------------------------------------------
--- POST UPGRADE DATA UPDATES.
-----------------------------------------------------------------------------
-
--- TODO: EXTERNAL BIB FULL RE-INGEST
-
--- TODO: run all in transaction for testing -- remove transactions later.
-
-BEGIN;
-
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON biblio.peer_bib_copy_map;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON biblio.record_entry;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON asset.copy;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON asset.call_number;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON asset.copy_location;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON serial.unit;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON config.copy_status;
-DROP TRIGGER IF EXISTS a_opac_vis_mat_view_tgr ON actor.org_unit;
-
-SELECT CLOCK_TIMESTAMP(), 'Updating copy visibility attr cache';
-
--- no insert wrapper required
--- Upgrade the data!
-INSERT INTO asset.copy_vis_attr_cache (target_copy, record, vis_attr_vector)
-    SELECT  cp.id,
-            cn.record,
-            asset.calculate_copy_visibility_attribute_set(cp.id)
-      FROM  asset.copy cp
-            JOIN asset.call_number cn ON (cp.call_number = cn.id);
-
-CREATE TRIGGER z_opac_vis_mat_view_tgr BEFORE INSERT OR UPDATE 
-    ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR DELETE 
-    ON biblio.peer_bib_copy_map FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER UPDATE 
-    ON asset.call_number FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_del_tgr BEFORE DELETE 
-    ON asset.copy FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_del_tgr BEFORE DELETE 
-    ON serial.unit FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE 
-    ON asset.copy FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE 
-    ON serial.unit FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-
-SELECT CLOCK_TIMESTAMP(), 'Making copy alert types active';
-
-UPDATE config.copy_alert_type
-SET active = TRUE
-WHERE id IN (4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
-
-
--- Update keyword indexes for existing patrons
-SELECT CLOCK_TIMESTAMP(), 'Updating patron name keyword vector';
-
-UPDATE actor.usr SET name_kw_tsvector = 
-    TO_TSVECTOR(
-        COALESCE(prefix, '') || ' ' || 
-        COALESCE(first_given_name, '') || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(first_given_name), '') || ' ' || 
-        COALESCE(second_given_name, '') || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(second_given_name), '') || ' ' || 
-        COALESCE(family_name, '') || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(family_name), '') || ' ' || 
-        COALESCE(suffix, '')
-    );
-
--- Authority record re-ingest
-
-SELECT CLOCK_TIMESTAMP(), 'Reingesting authority records';
-
--- add the flag ingest.disable_authority_full_rec if it does not exist
-INSERT INTO config.internal_flag (name, enabled)
-SELECT 'ingest.disable_authority_full_rec', FALSE
-WHERE NOT EXISTS (SELECT 1 FROM config.internal_flag 
-WHERE name = 'ingest.disable_authority_full_rec');
-
-CREATE TEMPORARY TABLE internal_flag_state AS
-    SELECT name, enabled
-    FROM config.internal_flag
-    WHERE name in (
-        'ingest.reingest.force_on_same_marc',
-        'ingest.disable_authority_auto_update',
-        'ingest.disable_authority_full_rec'
-    );
-
-UPDATE config.internal_flag
-SET enabled = TRUE
-WHERE name in (
-    'ingest.reingest.force_on_same_marc',
-    'ingest.disable_authority_auto_update',
-    'ingest.disable_authority_full_rec'
-);
-
-ALTER TABLE authority.record_entry DISABLE TRIGGER a_marcxml_is_well_formed;
-ALTER TABLE authority.record_entry DISABLE TRIGGER b_maintain_901;
-ALTER TABLE authority.record_entry DISABLE TRIGGER c_maintain_control_numbers;
-ALTER TABLE authority.record_entry DISABLE TRIGGER map_thesaurus_to_control_set;
-
-UPDATE authority.record_entry SET id = id WHERE NOT DELETED;
-
-ALTER TABLE authority.record_entry ENABLE TRIGGER a_marcxml_is_well_formed;
-ALTER TABLE authority.record_entry ENABLE TRIGGER b_maintain_901;
-ALTER TABLE authority.record_entry ENABLE TRIGGER c_maintain_control_numbers;
-ALTER TABLE authority.record_entry ENABLE TRIGGER map_thesaurus_to_control_set;
-
--- and restore
-UPDATE config.internal_flag a
-SET enabled = b.enabled
-FROM internal_flag_state b
-WHERE a.name = b.name;
-
-
-COMMIT;
---ROLLBACK;
-
-
diff --git a/kcls-2.12-3.2-db-upgrade.sql b/kcls-2.12-3.2-db-upgrade.sql
deleted file mode 100644 (file)
index 2b16a8a..0000000
+++ /dev/null
@@ -1,21496 +0,0 @@
-
-BEGIN;
-
-----------------------------------------------------------------------------
--- BEGIN 2.12.6 -> 3.0.0
-----------------------------------------------------------------------------
-
---Upgrade Script for 2.12.6 to 3.0.0
---\set eg_version '''3.0.0'''
-\set ON_ERROR_STOP on
-
-SET STATEMENT_TIMEOUT = 0;
-
--- VERSION 1032 
-
-CREATE OR REPLACE VIEW action.all_circulation_combined_types AS 
- SELECT acirc.id AS id,
-    acirc.xact_start,
-    acirc.circ_lib,
-    acirc.circ_staff,
-    acirc.create_time,
-    ac_acirc.circ_modifier AS item_type,
-    'regular_circ'::text AS circ_type
-   FROM action.circulation acirc,
-    asset.copy ac_acirc
-  WHERE acirc.target_copy = ac_acirc.id
-UNION ALL
- SELECT ancc.id::BIGINT AS id,
-    ancc.circ_time AS xact_start,
-    ancc.circ_lib,
-    ancc.staff AS circ_staff,
-    ancc.circ_time AS create_time,
-    cnct_ancc.name AS item_type,
-    'non-cat_circ'::text AS circ_type
-   FROM action.non_cataloged_circulation ancc,
-    config.non_cataloged_type cnct_ancc
-  WHERE ancc.item_type = cnct_ancc.id
-UNION ALL
- SELECT aihu.id::BIGINT AS id,
-    aihu.use_time AS xact_start,
-    aihu.org_unit AS circ_lib,
-    aihu.staff AS circ_staff,
-    aihu.use_time AS create_time,
-    ac_aihu.circ_modifier AS item_type,
-    'in-house_use'::text AS circ_type
-   FROM action.in_house_use aihu,
-    asset.copy ac_aihu
-  WHERE aihu.item = ac_aihu.id
-UNION ALL
- SELECT ancihu.id::BIGINT AS id,
-    ancihu.use_time AS xact_start,
-    ancihu.org_unit AS circ_lib,
-    ancihu.staff AS circ_staff,
-    ancihu.use_time AS create_time,
-    cnct_ancihu.name AS item_type,
-    'non-cat_circ'::text AS circ_type
-   FROM action.non_cat_in_house_use ancihu,
-    config.non_cataloged_type cnct_ancihu
-  WHERE ancihu.item_type = cnct_ancihu.id
-UNION ALL
- SELECT aacirc.id AS id,
-    aacirc.xact_start,
-    aacirc.circ_lib,
-    aacirc.circ_staff,
-    aacirc.create_time,
-    ac_aacirc.circ_modifier AS item_type,
-    'aged_circ'::text AS circ_type
-   FROM action.aged_circulation aacirc,
-    asset.copy ac_aacirc
-  WHERE aacirc.target_copy = ac_aacirc.id;
-
-
--- VERSION 1034
-
-ALTER TABLE config.hold_matrix_matchpoint
-    ADD COLUMN description TEXT;
-
-ALTER TABLE config.circ_matrix_matchpoint
-    ADD COLUMN description TEXT;
-
--- VERSION 1035
-
--- Per Lp bug 1684984, the config.internal_flag,
--- ingest.disable_metabib_field_entry, was made obsolete by the
--- addition of the ingest.skip_browse_indexing,
--- ingest.skip_search_indexing, and ingest.skip_facet_indexing flags.
--- Since it is not used in the database, we delete it.
-DELETE FROM config.internal_flag
-WHERE name = 'ingest.disable_metabib_field_entry';
-
--- VERSION 1036
-
-CREATE OR REPLACE FUNCTION config.update_hard_due_dates () RETURNS INT AS $func$
-DECLARE
-    temp_value  config.hard_due_date_values%ROWTYPE;
-    updated     INT := 0;
-BEGIN
-    FOR temp_value IN
-      SELECT  DISTINCT ON (hard_due_date) *
-        FROM  config.hard_due_date_values
-        WHERE active_date <= NOW() -- We've passed (or are at) the rollover time
-        ORDER BY hard_due_date, active_date DESC -- Latest (nearest to us) active time
-   LOOP
-        UPDATE  config.hard_due_date
-          SET   ceiling_date = temp_value.ceiling_date
-          WHERE id = temp_value.hard_due_date
-                AND ceiling_date <> temp_value.ceiling_date -- Time is equal if we've already updated the chdd
-                AND temp_value.ceiling_date >= NOW(); -- Don't update ceiling dates to the past
-
-        IF FOUND THEN
-            updated := updated + 1;
-        END IF;
-    END LOOP;
-
-    RETURN updated;
-END;
-$func$ LANGUAGE plpgsql;
-
-
--- VERSION 1041
-
---delete all instances from permission.grp_perm_map first
-DELETE FROM permission.grp_perm_map where perm in 
-(select id from permission.perm_list where code='SET_CIRC_MISSING');
-
---delete all instances from permission.usr_perm_map too
-DELETE FROM permission.usr_perm_map where perm in
-(select id from permission.perm_list where code='SET_CIRC_MISSING');
-
---delete from permission.perm_list
-DELETE FROM permission.perm_list where code='SET_CIRC_MISSING';
-
-
--- VERSION 1042
-
-ALTER TABLE asset.copy_location
-          ADD COLUMN url TEXT;
-
--- SELECT evergreen.upgrade_deps_block_check('1043', :eg_version);
-
--- SELECT evergreen.upgrade_deps_block_check('1044', :eg_version);
-
--- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1045', :eg_version); -- csharp/berick/gmcharlt
-
-ALTER TABLE action.transit_copy
-       ADD COLUMN cancel_time TIMESTAMPTZ;
-
--- change "abort" to "cancel" in stock perm descriptions
-UPDATE permission.perm_list 
-       SET description = 'Allow a user to cancel a copy transit if the user is at the transit destination or source' 
-       WHERE code = 'ABORT_TRANSIT'
-       AND description = 'Allow a user to abort a copy transit if the user is at the transit destination or source';
-UPDATE permission.perm_list 
-       SET description = 'Allow a user to cancel a copy transit if the user is not at the transit source or dest' 
-       WHERE code = 'ABORT_REMOTE_TRANSIT'
-       AND description = 'Allow a user to abort a copy transit if the user is not at the transit source or dest';
-UPDATE permission.perm_list 
-       SET description = 'Allows a user to cancel a transit on a copy with status of LOST' 
-       WHERE code = 'ABORT_TRANSIT_ON_LOST'
-       AND description = 'Allows a user to abort a transit on a copy with status of LOST';
-UPDATE permission.perm_list 
-       SET description = 'Allows a user to cancel a transit on a copy with status of MISSING' 
-       WHERE code = 'ABORT_TRANSIT_ON_MISSING'
-       AND description = 'Allows a user to abort a transit on a copy with status of MISSING';
-
--- SELECT evergreen.upgrade_deps_block_check('1046', :eg_version); -- phasefx/berick/gmcharlt
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
-INSERT into config.org_unit_setting_type (
-     name
-    ,grp
-    ,label
-    ,description
-    ,datatype
-) VALUES ( ----------------------------------------
-     'webstaff.format.dates'
-    ,'gui'
-    ,oils_i18n_gettext(
-         'webstaff.format.dates'
-        ,'Format Dates with this pattern'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.format.dates'
-        ,'Format Dates with this pattern (examples: "yyyy-MM-dd" for "2010-04-26", "MMM d, yyyy" for "Apr 26, 2010").  This will be used in areas where a date without a timestamp is sufficient, like Date of Birth.'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.format.date_and_time'
-    ,'gui'
-    ,oils_i18n_gettext(
-         'webstaff.format.date_and_time'
-        ,'Format Date+Time with this pattern'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.format.date_and_time'
-        ,'Format Date+Time with this pattern (examples: "yy-MM-dd h:m:s.SSS a" for "16-04-05 2:07:20.666 PM", "yyyy-dd-MMM HH:mm" for "2016-05-Apr 14:07").  This will be used in areas of the client where a date with a timestamp is needed, like Checkout, Due Date, or Record Created.'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-);
-END IF; END $INSERT$;
-
-UPDATE
-    config.org_unit_setting_type
-SET
-    label = 'Deprecated: ' || label -- FIXME: Is this okay?
-WHERE
-    name IN ('format.date','format.time')
-;
-
--- SELECT evergreen.upgrade_deps_block_check('1047', :eg_version); -- gmcharlt/stompro
-
-CREATE TABLE config.copy_tag_type (
-    code            TEXT NOT NULL PRIMARY KEY,
-    label           TEXT NOT NULL,
-    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED
-);
-
-CREATE INDEX config_copy_tag_type_owner_idx
-    ON config.copy_tag_type (owner);
-
-CREATE TABLE asset.copy_tag (
-    id              SERIAL PRIMARY KEY,
-    tag_type        TEXT REFERENCES config.copy_tag_type (code)
-                    ON UPDATE CASCADE ON DELETE CASCADE,
-    label           TEXT NOT NULL,
-    value           TEXT NOT NULL,
-    index_vector    tsvector NOT NULL,
-    staff_note      TEXT,
-    pub             BOOLEAN DEFAULT TRUE,
-    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id)
-);
-
-CREATE INDEX asset_copy_tag_label_idx
-    ON asset.copy_tag (label);
-CREATE INDEX asset_copy_tag_label_lower_idx
-    ON asset.copy_tag (evergreen.lowercase(label));
-CREATE INDEX asset_copy_tag_index_vector_idx
-    ON asset.copy_tag
-    USING GIN(index_vector);
-CREATE INDEX asset_copy_tag_tag_type_idx
-    ON asset.copy_tag (tag_type);
-CREATE INDEX asset_copy_tag_owner_idx
-    ON asset.copy_tag (owner);
-
-CREATE OR REPLACE FUNCTION asset.set_copy_tag_value () RETURNS TRIGGER AS $$
-BEGIN
-    IF NEW.value IS NULL THEN
-        NEW.value = NEW.label;        
-    END IF;
-
-    RETURN NEW;
-END;
-$$ LANGUAGE 'plpgsql';
-
--- name of following trigger chosen to ensure it runs first
-CREATE TRIGGER asset_copy_tag_do_value
-    BEFORE INSERT OR UPDATE ON asset.copy_tag
-    FOR EACH ROW EXECUTE PROCEDURE asset.set_copy_tag_value();
-CREATE TRIGGER asset_copy_tag_fti_trigger
-    BEFORE UPDATE OR INSERT ON asset.copy_tag
-    FOR EACH ROW EXECUTE PROCEDURE oils_tsearch2('default');
-
-CREATE TABLE asset.copy_tag_copy_map (
-    id              BIGSERIAL PRIMARY KEY,
-    copy            BIGINT REFERENCES asset.copy (id)
-                    ON UPDATE CASCADE ON DELETE CASCADE,
-    tag             INTEGER REFERENCES asset.copy_tag (id)
-                    ON UPDATE CASCADE ON DELETE CASCADE
-);
-
-CREATE INDEX asset_copy_tag_copy_map_copy_idx
-    ON asset.copy_tag_copy_map (copy);
-CREATE INDEX asset_copy_tag_copy_map_tag_idx
-    ON asset.copy_tag_copy_map (tag);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
-
-INSERT INTO config.copy_tag_type (code, label, owner) VALUES ('bookplate', 'Digital Bookplate', 1);
-
-INSERT INTO permission.perm_list ( id, code, description ) VALUES
- ( 590, 'ADMIN_COPY_TAG_TYPES', oils_i18n_gettext( 590,
-    'Administer copy tag types', 'ppl', 'description' )),
- ( 591, 'ADMIN_COPY_TAG', oils_i18n_gettext( 591,
-    'Administer copy tag', 'ppl', 'description' ))
-;
-
-INSERT INTO config.org_unit_setting_type
-    (name, label, description, grp, datatype)
-VALUES (
-    'opac.search.enable_bookplate_search',
-    oils_i18n_gettext(
-        'opac.search.enable_bookplate_search',
-        'Enable Digital Bookplate Search',
-        'coust',
-        'label'
-    ),
-    oils_i18n_gettext(
-        'opac.search.enable_bookplate_search',
-        'If enabled, adds a "Digital Bookplate" option to the query type selectors in the public catalog for search on copy tags.',   
-        'coust',
-        'description'
-    ),
-    'opac',
-    'bool'
-);
-
--- SELECT evergreen.upgrade_deps_block_check('1048', :eg_version);
-
-INSERT into config.org_unit_setting_type (
-     name
-    ,grp
-    ,label
-    ,description
-    ,datatype
-) VALUES ( ----------------------------------------
-     'webstaff.cat.label.font.family'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.font.family'
-        ,'Item Print Label Font Family'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.font.family'
-        ,'Set the preferred font family for item print labels. You can specify a list of CSS fonts, separated by commas, in order of preference; the system will use the first font it finds with a matching name. For example, "Arial, Helvetica, serif"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.font.size'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.font.size'
-        ,'Item Print Label Font Size'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.font.size'
-        ,'Set the default font size for item print labels. Please include a unit of measurement that is valid CSS. For example, "12pt" or "16px" or "1em"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.font.weight'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.font.weight'
-        ,'Item Print Label Font Weight'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.font.weight'
-        ,'Set the default font weight for item print labels. Please use the CSS specification for values for font-weight.  For example, "normal", "bold", "bolder", or "lighter"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.left_label.left_margin'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.left_label.left_margin'
-        ,'Item Print Label - Left Margin for Left Label'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.left_label.left_margin'
-        ,'Set the default left margin for the leftmost item print Label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.right_label.left_margin'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.right_label.left_margin'
-        ,'Item Print Label - Left Margin for Right Label'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.right_label.left_margin'
-        ,'Set the default left margin for the rightmost item print label (or in other words, the desired space between the two labels). Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.left_label.height'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.left_label.height'
-        ,'Item Print Label - Height for Left Label'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.left_label.height'
-        ,'Set the default height for the leftmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.left_label.width'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.left_label.width'
-        ,'Item Print Label - Width for Left Label'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.left_label.width'
-        ,'Set the default width for the leftmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.right_label.height'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.right_label.height'
-        ,'Item Print Label - Height for Right Label'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.right_label.height'
-        ,'Set the default height for the rightmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), ( ----------------------------------------
-     'webstaff.cat.label.right_label.width'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.right_label.width'
-        ,'Item Print Label - Width for Right Label'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.right_label.width'
-        ,'Set the default width for the rightmost item print label. Please include a unit of measurement that is valid CSS. For example, "1in" or "2.5cm"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), (
-     'webstaff.cat.label.inline_css'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.inline_css'
-        ,'Item Print Label - Inline CSS'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.inline_css'
-        ,'This setting allows you to inject arbitrary CSS into the item print label template.  For example, ".printlabel { text-transform: uppercase; }"'
-        ,'coust'
-        ,'description'
-    )
-    ,'string'
-), (
-     'webstaff.cat.label.call_number_wrap_filter_height'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.call_number_wrap_filter_height'
-        ,'Item Print Label - Call Number Wrap Filter Height'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.call_number_wrap_filter_height'
-        ,'This setting is used to set the default height (in number of lines) to use for call number wrapping in the left print label.'
-        ,'coust'
-        ,'description'
-    )
-    ,'integer'
-), (
-     'webstaff.cat.label.call_number_wrap_filter_width'
-    ,'cat'
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.call_number_wrap_filter_width'
-        ,'Item Print Label - Call Number Wrap Filter Width'
-        ,'coust'
-        ,'label'
-    )
-    ,oils_i18n_gettext(
-         'webstaff.cat.label.call_number_wrap_filter_width'
-        ,'This setting is used to set the default width (in number of characters) to use for call number wrapping in the left print label.'
-        ,'coust'
-        ,'description'
-    )
-    ,'integer'
-
-
-);
-
-END IF; END $INSERT$;
-
--- SELECT evergreen.upgrade_deps_block_check('1049', :eg_version); -- mmorgan/stompro/gmcharlt
-
-SELECT CLOCK_TIMESTAMP(), 
-    'Setting invalid age_protect and circ_as_type entries to NULL';
-
-UPDATE asset.copy_template act
-SET age_protect = NULL
-FROM actor.org_unit aou
-WHERE aou.id=act.owning_lib
-   AND act.age_protect NOT IN
-   (
-   SELECT id FROM config.rule_age_hold_protect
-   )
-RETURNING act.id "Template ID", act.name "Template Name",
-          aou.shortname "Owning Lib",
-          'Age Protection value reset to null.' "Description";
-
-UPDATE asset.copy_template act
-SET circ_as_type = NULL
-FROM actor.org_unit aou
-WHERE aou.id=act.owning_lib
-   AND act.circ_as_type NOT IN
-   (
-   SELECT code FROM config.item_type_map
-   )
-RETURNING act.id "Template ID", act.name "Template Name",
-          aou.shortname "Owning Lib",
-          'Circ as Type value reset to null.' as "Description";
-
-\echo -----------End Serial Template Fix----------------
-
--- SELECT evergreen.upgrade_deps_block_check('1050', :eg_version); -- mmorgan/cesardv/gmcharlt
-
-CREATE OR REPLACE FUNCTION permission.usr_perms ( INT ) RETURNS SETOF permission.usr_perm_map AS $$
-    SELECT     DISTINCT ON (usr,perm) *
-         FROM  (
-                       (SELECT * FROM permission.usr_perm_map WHERE usr = $1)
-            UNION ALL
-                       (SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
-                         FROM  permission.grp_perm_map p
-                         WHERE p.grp IN (
-      SELECT   (permission.grp_ancestors(
-      (SELECT profile FROM actor.usr WHERE id = $1)
-                                       )).id
-                               )
-                       )
-            UNION ALL
-                       (SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
-                         FROM  permission.grp_perm_map p
-                         WHERE p.grp IN (SELECT (permission.grp_ancestors(m.grp)).id FROM permission.usr_grp_map m WHERE usr = $1))
-               ) AS x
-         ORDER BY 2, 3, 4 ASC, 5 DESC ;
-$$ LANGUAGE SQL STABLE ROWS 10;
-
--- SELECT evergreen.upgrade_deps_block_check('1051', :eg_version);
-
-CREATE OR REPLACE VIEW action.all_circulation_slim AS
-    SELECT
-        id,
-        usr,
-        xact_start,
-        xact_finish,
-        unrecovered,
-        target_copy,
-        circ_lib,
-        circ_staff,
-        checkin_staff,
-        checkin_lib,
-        renewal_remaining,
-        grace_period,
-        due_date,
-        stop_fines_time,
-        checkin_time,
-        create_time,
-        duration,
-        fine_interval,
-        recurring_fine,
-        max_fine,
-        phone_renewal,
-        desk_renewal,
-        opac_renewal,
-        duration_rule,
-        recurring_fine_rule,
-        max_fine_rule,
-        stop_fines,
-        workstation,
-        checkin_workstation,
-        copy_location,
-        checkin_scan_time,
-        parent_circ
-    FROM action.circulation
-UNION ALL
-    SELECT
-        id,
-        NULL AS usr,
-        xact_start,
-        xact_finish,
-        unrecovered,
-        target_copy,
-        circ_lib,
-        circ_staff,
-        checkin_staff,
-        checkin_lib,
-        renewal_remaining,
-        grace_period,
-        due_date,
-        stop_fines_time,
-        checkin_time,
-        create_time,
-        duration,
-        fine_interval,
-        recurring_fine,
-        max_fine,
-        phone_renewal,
-        desk_renewal,
-        opac_renewal,
-        duration_rule,
-        recurring_fine_rule,
-        max_fine_rule,
-        stop_fines,
-        workstation,
-        checkin_workstation,
-        copy_location,
-        checkin_scan_time,
-        parent_circ
-    FROM action.aged_circulation
-;
-
-DROP FUNCTION action.summarize_all_circ_chain(INTEGER);
-DROP FUNCTION action.all_circ_chain(INTEGER);
-
-CREATE OR REPLACE FUNCTION action.all_circ_chain (ctx_circ_id INTEGER) 
-    RETURNS SETOF action.all_circulation_slim AS $$
-DECLARE
-    tmp_circ action.all_circulation_slim%ROWTYPE;
-    circ_0 action.all_circulation_slim%ROWTYPE;
-BEGIN
-
-    SELECT INTO tmp_circ * FROM action.all_circulation_slim WHERE id = ctx_circ_id;
-
-    IF tmp_circ IS NULL THEN
-        RETURN NEXT tmp_circ;
-    END IF;
-    circ_0 := tmp_circ;
-
-    -- find the front of the chain
-    WHILE TRUE LOOP
-        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
-            WHERE id = tmp_circ.parent_circ;
-        IF tmp_circ IS NULL THEN
-            EXIT;
-        END IF;
-        circ_0 := tmp_circ;
-    END LOOP;
-
-    -- now send the circs to the caller, oldest to newest
-    tmp_circ := circ_0;
-    WHILE TRUE LOOP
-        IF tmp_circ IS NULL THEN
-            EXIT;
-        END IF;
-        RETURN NEXT tmp_circ;
-        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
-            WHERE parent_circ = tmp_circ.id;
-    END LOOP;
-
-END;
-$$ LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION action.summarize_all_circ_chain 
-    (ctx_circ_id INTEGER) RETURNS action.circ_chain_summary AS $$
-
-DECLARE
-
-    -- first circ in the chain
-    circ_0 action.all_circulation_slim%ROWTYPE;
-
-    -- last circ in the chain
-    circ_n action.all_circulation_slim%ROWTYPE;
-
-    -- circ chain under construction
-    chain action.circ_chain_summary;
-    tmp_circ action.all_circulation_slim%ROWTYPE;
-
-BEGIN
-    
-    chain.num_circs := 0;
-    FOR tmp_circ IN SELECT * FROM action.all_circ_chain(ctx_circ_id) LOOP
-
-        IF chain.num_circs = 0 THEN
-            circ_0 := tmp_circ;
-        END IF;
-
-        chain.num_circs := chain.num_circs + 1;
-        circ_n := tmp_circ;
-    END LOOP;
-
-    chain.start_time := circ_0.xact_start;
-    chain.last_stop_fines := circ_n.stop_fines;
-    chain.last_stop_fines_time := circ_n.stop_fines_time;
-    chain.last_checkin_time := circ_n.checkin_time;
-    chain.last_checkin_scan_time := circ_n.checkin_scan_time;
-    SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
-    SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
-
-    IF chain.num_circs > 1 THEN
-        chain.last_renewal_time := circ_n.xact_start;
-        SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
-    END IF;
-
-    RETURN chain;
-
-END;
-$$ LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION rating.percent_time_circulating(badge_id INT)
-    RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
-DECLARE
-    badge   rating.badge_with_orgs%ROWTYPE;
-BEGIN
-
-    SELECT * INTO badge FROM rating.badge_with_orgs WHERE id = badge_id;
-
-    PERFORM rating.precalc_bibs_by_copy(badge_id);
-
-    DELETE FROM precalc_copy_filter_bib_list WHERE id NOT IN (
-        SELECT id FROM precalc_filter_bib_list
-            INTERSECT
-        SELECT id FROM precalc_bibs_by_copy_list
-    );
-
-    ANALYZE precalc_copy_filter_bib_list;
-
-    RETURN QUERY
-     SELECT bib,
-            SUM(COALESCE(circ_time,0))::NUMERIC / SUM(age)::NUMERIC
-      FROM  (SELECT cn.record AS bib,
-                    cp.id,
-                    EXTRACT( EPOCH FROM AGE(cp.active_date) ) + 1 AS age,
-                    SUM(  -- time copy spent circulating
-                        EXTRACT(
-                            EPOCH FROM
-                            AGE(
-                                COALESCE(circ.checkin_time, circ.stop_fines_time, NOW()),
-                                circ.xact_start
-                            )
-                        )
-                    )::NUMERIC AS circ_time
-              FROM  asset.copy cp
-                    JOIN precalc_copy_filter_bib_list c ON (cp.id = c.copy)
-                    JOIN asset.call_number cn ON (cn.id = cp.call_number)
-                    LEFT JOIN action.all_circulation_slim circ ON (
-                        circ.target_copy = cp.id
-                        AND stop_fines NOT IN (
-                            'LOST',
-                            'LONGOVERDUE',
-                            'CLAIMSRETURNED',
-                            'LONGOVERDUE'
-                        )
-                        AND NOT (
-                            checkin_time IS NULL AND
-                            stop_fines = 'MAXFINES'
-                        )
-                    )
-              WHERE cn.owning_lib = ANY (badge.orgs)
-                    AND cp.active_date IS NOT NULL
-                    -- Next line requires that copies with no circs (circ.id IS NULL) also not be deleted
-                    AND ((circ.id IS NULL AND NOT cp.deleted) OR circ.id IS NOT NULL)
-              GROUP BY 1,2,3
-            ) x
-      GROUP BY 1;
-END;
-$f$ LANGUAGE PLPGSQL STRICT;
-
--- SELECT evergreen.upgrade_deps_block_check('1052', :eg_version);
-
-CREATE OR REPLACE FUNCTION rating.inhouse_over_time(badge_id INT)
-    RETURNS TABLE (record BIGINT, value NUMERIC) AS $f$
-DECLARE
-    badge   rating.badge_with_orgs%ROWTYPE;
-    iage    INT     := 1;
-    iint    INT     := NULL;
-    iscale  NUMERIC := NULL;
-BEGIN
-
-    SELECT * INTO badge FROM rating.badge_with_orgs WHERE id = badge_id;
-
-    IF badge.horizon_age IS NULL THEN
-        RAISE EXCEPTION 'Badge "%" with id % requires a horizon age but has none.',
-            badge.name,
-            badge.id;
-    END IF;
-
-    PERFORM rating.precalc_bibs_by_copy(badge_id);
-
-    DELETE FROM precalc_copy_filter_bib_list WHERE id NOT IN (
-        SELECT id FROM precalc_filter_bib_list
-            INTERSECT
-        SELECT id FROM precalc_bibs_by_copy_list
-    );
-
-    ANALYZE precalc_copy_filter_bib_list;
-
-    iint := EXTRACT(EPOCH FROM badge.importance_interval);
-    IF badge.importance_age IS NOT NULL THEN
-        iage := (EXTRACT(EPOCH FROM badge.importance_age) / iint)::INT;
-    END IF;
-
-    -- if iscale is smaller than 1, scaling slope will be shallow ... BEWARE!
-    iscale := COALESCE(badge.importance_scale, 1.0);
-
-    RETURN QUERY
-     SELECT bib,
-            SUM( uses * GREATEST( iscale * (iage - cage), 1.0 ))
-      FROM (
-         SELECT cn.record AS bib,
-                (1 + EXTRACT(EPOCH FROM AGE(u.use_time)) / iint)::INT AS cage,
-                COUNT(u.id)::INT AS uses
-          FROM  action.in_house_use u
-                JOIN precalc_copy_filter_bib_list cf ON (u.item = cf.copy)
-                JOIN asset.copy cp ON (cp.id = u.item)
-                JOIN asset.call_number cn ON (cn.id = cp.call_number)
-          WHERE u.use_time >= NOW() - badge.horizon_age
-                AND cn.owning_lib = ANY (badge.orgs)
-          GROUP BY 1, 2
-      ) x
-      GROUP BY 1;
-END;
-$f$ LANGUAGE PLPGSQL STRICT;
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-INSERT INTO rating.popularity_parameter (id, name, func, require_horizon,require_percentile) VALUES
-    (18,'In-House Use Over Time', 'rating.inhouse_over_time', TRUE, TRUE);
-END IF; END $INSERT$;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1053', :eg_version);
-
-CREATE OR REPLACE FUNCTION rating.org_unit_count(badge_id INT)
-    RETURNS TABLE (record INT, value NUMERIC) AS $f$
-DECLARE
-    badge   rating.badge_with_orgs%ROWTYPE;
-BEGIN
-
-    SELECT * INTO badge FROM rating.badge_with_orgs WHERE id = badge_id;
-
-    PERFORM rating.precalc_bibs_by_copy(badge_id);
-
-    DELETE FROM precalc_copy_filter_bib_list WHERE id NOT IN (
-        SELECT id FROM precalc_filter_bib_list
-            INTERSECT
-        SELECT id FROM precalc_bibs_by_copy_list
-    );
-    ANALYZE precalc_copy_filter_bib_list;
-
-    -- Use circ rather than owning lib here as that means "on the shelf at..."
-    RETURN QUERY
-     SELECT f.id::INT AS bib,
-            COUNT(DISTINCT cp.circ_lib)::NUMERIC
-     FROM asset.copy cp
-          JOIN precalc_copy_filter_bib_list f ON (cp.id = f.copy)
-     WHERE cp.circ_lib = ANY (badge.orgs) GROUP BY 1;
-
-END;
-$f$ LANGUAGE PLPGSQL STRICT;
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-INSERT INTO rating.popularity_parameter (id, name, func, require_percentile) VALUES
-    (17,'Circulation Library Count', 'rating.org_unit_count', TRUE);
-
--- SELECT evergreen.upgrade_deps_block_check('1054', :eg_version);
-
-INSERT into config.org_unit_setting_type
-( name, grp, label, description, datatype ) VALUES
-
-( 'lib.timezone', 'lib',
-    oils_i18n_gettext('lib.timezone',
-        'Library time zone',
-        'coust', 'label'),
-    oils_i18n_gettext('lib.timezone',
-        'Define the time zone in which a library physically resides',
-        'coust', 'description'),
-    'string');
-END IF; END $INSERT$;
-
-ALTER TABLE actor.org_unit_closed ADD COLUMN full_day BOOLEAN DEFAULT FALSE;
-ALTER TABLE actor.org_unit_closed ADD COLUMN multi_day BOOLEAN DEFAULT FALSE;
-
-UPDATE actor.org_unit_closed SET multi_day = TRUE
-  WHERE close_start::DATE <> close_end::DATE;
-
-UPDATE actor.org_unit_closed SET full_day = TRUE
-  WHERE close_start::DATE = close_end::DATE
-        AND SUBSTRING(close_start::time::text FROM 1 FOR 8) = '00:00:00'
-        AND SUBSTRING(close_end::time::text FROM 1 FOR 8) = '23:59:59';
-
-CREATE OR REPLACE FUNCTION action.push_circ_due_time () RETURNS TRIGGER AS $$
-DECLARE
-    proper_tz TEXT := COALESCE(
-        oils_json_to_text((
-            SELECT value
-              FROM  actor.org_unit_ancestor_setting('lib.timezone',NEW.circ_lib)
-              LIMIT 1
-        )),
-        CURRENT_SETTING('timezone')
-    );
-BEGIN
-
-    IF (EXTRACT(EPOCH FROM NEW.duration)::INT % EXTRACT(EPOCH FROM '1 day'::INTERVAL)::INT) = 0 -- day-granular duration
-        AND SUBSTRING((NEW.due_date AT TIME ZONE proper_tz)::TIME::TEXT FROM 1 FOR 8) <> '23:59:59' THEN -- has not yet been pushed
-        NEW.due_date = ((NEW.due_date AT TIME ZONE proper_tz)::DATE + '1 day'::INTERVAL - '1 second'::INTERVAL) || ' ' || proper_tz;
-    END IF;
-
-    RETURN NEW;
-END;
-$$ LANGUAGE PLPGSQL;
-
--- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1056', :eg_version); -- miker/gmcharlt
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-INSERT INTO permission.perm_list (id,code,description) VALUES (592,'CONTAINER_BATCH_UPDATE','Allow batch update via buckets');
-
-INSERT INTO container.user_bucket_type (code,label) SELECT code,label FROM container.copy_bucket_type where code = 'staff_client';
-END IF; END $INSERT$;                                                          
-
-
-CREATE TABLE action.fieldset_group (
-    id              SERIAL  PRIMARY KEY,
-    name            TEXT        NOT NULL,
-    create_time     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-    complete_time   TIMESTAMPTZ,
-    container       INT,        -- Points to a container of some type ...
-    container_type  TEXT,       -- One of 'biblio_record_entry', 'user', 'call_number', 'copy'
-    can_rollback    BOOL        DEFAULT TRUE,
-    rollback_group  INT         REFERENCES action.fieldset_group (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    rollback_time   TIMESTAMPTZ,
-    creator         INT         NOT NULL REFERENCES actor.usr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    owning_lib      INT         NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
-);
-
-ALTER TABLE action.fieldset ADD COLUMN fieldset_group INT REFERENCES action.fieldset_group (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
-ALTER TABLE action.fieldset ADD COLUMN error_msg TEXT;
-ALTER TABLE container.biblio_record_entry_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
-ALTER TABLE container.user_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
-ALTER TABLE container.call_number_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
-ALTER TABLE container.copy_bucket ADD COLUMN owning_lib INT REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
-
-UPDATE query.stored_query SET id = id + 1000 WHERE id < 1000;
-UPDATE query.from_relation SET id = id + 1000 WHERE id < 1000;
-UPDATE query.expression SET id = id + 1000 WHERE id < 1000;
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-PERFORM SETVAL('query.stored_query_id_seq', 1, FALSE);
-PERFORM SETVAL('query.from_relation_id_seq', 1, FALSE);
-PERFORM SETVAL('query.expression_id_seq', 1, FALSE);
-
-INSERT INTO query.bind_variable (name,type,description,label)
-    SELECT  'bucket','number','ID of the bucket to pull items from','Bucket ID'
-      WHERE NOT EXISTS (SELECT 1 FROM query.bind_variable WHERE name = 'bucket');
-
--- Assumes completely empty 'query' schema
-INSERT INTO query.stored_query (type, use_distinct) VALUES ('SELECT', TRUE); -- 1
-
-INSERT INTO query.from_relation (type, table_name, class_name, table_alias) VALUES ('RELATION', 'container.user_bucket_item', 'cubi', 'cubi'); -- 1
-UPDATE query.stored_query SET from_clause = 1;
-
-INSERT INTO query.expr_xcol (table_alias, column_name) VALUES ('cubi', 'target_user'); -- 1
-INSERT INTO query.select_item (stored_query,seq_no,expression) VALUES (1,1,1);
-
-INSERT INTO query.expr_xcol (table_alias, column_name) VALUES ('cubi', 'bucket'); -- 2
-INSERT INTO query.expr_xbind (bind_variable) VALUES ('bucket'); -- 3
-
-INSERT INTO query.expr_xop (left_operand, operator, right_operand) VALUES (2, '=', 3); -- 4
-UPDATE query.stored_query SET where_clause = 4;
-
-PERFORM SETVAL('query.stored_query_id_seq', 1000, TRUE) FROM query.stored_query;
-PERFORM SETVAL('query.from_relation_id_seq', 1000, TRUE) FROM query.from_relation;
-PERFORM SETVAL('query.expression_id_seq', 10000, TRUE) FROM query.expression;
-
-END IF; END $INSERT$;                                                          
-
-CREATE OR REPLACE FUNCTION action.apply_fieldset(
-    fieldset_id IN INT,        -- id from action.fieldset
-    table_name  IN TEXT,       -- table to be updated
-    pkey_name   IN TEXT,       -- name of primary key column in that table
-    query       IN TEXT        -- query constructed by qstore (for query-based
-                               --    fieldsets only; otherwise null
-)
-RETURNS TEXT AS $$
-DECLARE
-    statement TEXT;
-    where_clause TEXT;
-    fs_status TEXT;
-    fs_pkey_value TEXT;
-    fs_query TEXT;
-    sep CHAR;
-    status_code TEXT;
-    msg TEXT;
-    fs_id INT;
-    fsg_id INT;
-    update_count INT;
-    cv RECORD;
-    fs_obj action.fieldset%ROWTYPE;
-    fs_group action.fieldset_group%ROWTYPE;
-    rb_row RECORD;
-BEGIN
-    -- Sanity checks
-    IF fieldset_id IS NULL THEN
-        RETURN 'Fieldset ID parameter is NULL';
-    END IF;
-    IF table_name IS NULL THEN
-        RETURN 'Table name parameter is NULL';
-    END IF;
-    IF pkey_name IS NULL THEN
-        RETURN 'Primary key name parameter is NULL';
-    END IF;
-
-    SELECT
-        status,
-        quote_literal( pkey_value )
-    INTO
-        fs_status,
-        fs_pkey_value
-    FROM
-        action.fieldset
-    WHERE
-        id = fieldset_id;
-
-    --
-    -- Build the WHERE clause.  This differs according to whether it's a
-    -- single-row fieldset or a query-based fieldset.
-    --
-    IF query IS NULL        AND fs_pkey_value IS NULL THEN
-        RETURN 'Incomplete fieldset: neither a primary key nor a query available';
-    ELSIF query IS NOT NULL AND fs_pkey_value IS NULL THEN
-        fs_query := rtrim( query, ';' );
-        where_clause := 'WHERE ' || pkey_name || ' IN ( '
-                     || fs_query || ' )';
-    ELSIF query IS NULL     AND fs_pkey_value IS NOT NULL THEN
-        where_clause := 'WHERE ' || pkey_name || ' = ';
-        IF pkey_name = 'id' THEN
-            where_clause := where_clause || fs_pkey_value;
-        ELSIF pkey_name = 'code' THEN
-            where_clause := where_clause || quote_literal(fs_pkey_value);
-        ELSE
-            RETURN 'Only know how to handle "id" and "code" pkeys currently, received ' || pkey_name;
-        END IF;
-    ELSE  -- both are not null
-        RETURN 'Ambiguous fieldset: both a primary key and a query provided';
-    END IF;
-
-    IF fs_status IS NULL THEN
-        RETURN 'No fieldset found for id = ' || fieldset_id;
-    ELSIF fs_status = 'APPLIED' THEN
-        RETURN 'Fieldset ' || fieldset_id || ' has already been applied';
-    END IF;
-
-    SELECT * INTO fs_obj FROM action.fieldset WHERE id = fieldset_id;
-    SELECT * INTO fs_group FROM action.fieldset_group WHERE id = fs_obj.fieldset_group;
-
-    IF fs_group.can_rollback THEN
-        -- This is part of a non-rollback group.  We need to record the current values for future rollback.
-
-        INSERT INTO action.fieldset_group (can_rollback, name, creator, owning_lib, container, container_type)
-            VALUES (FALSE, 'ROLLBACK: '|| fs_group.name, fs_group.creator, fs_group.owning_lib, fs_group.container, fs_group.container_type);
-
-        fsg_id := CURRVAL('action.fieldset_group_id_seq');
-
-        FOR rb_row IN EXECUTE 'SELECT * FROM ' || table_name || ' ' || where_clause LOOP
-            IF pkey_name = 'id' THEN
-                fs_pkey_value := rb_row.id;
-            ELSIF pkey_name = 'code' THEN
-                fs_pkey_value := rb_row.code;
-            ELSE
-                RETURN 'Only know how to handle "id" and "code" pkeys currently, received ' || pkey_name;
-            END IF;
-            INSERT INTO action.fieldset (fieldset_group,owner,owning_lib,status,classname,name,pkey_value)
-                VALUES (fsg_id, fs_obj.owner, fs_obj.owning_lib, 'PENDING', fs_obj.classname, fs_obj.name || ' ROLLBACK FOR ' || fs_pkey_value, fs_pkey_value);
-
-            fs_id := CURRVAL('action.fieldset_id_seq');
-            sep := '';
-            FOR cv IN
-                SELECT  DISTINCT col
-                FROM    action.fieldset_col_val
-                WHERE   fieldset = fieldset_id
-            LOOP
-                EXECUTE 'INSERT INTO action.fieldset_col_val (fieldset, col, val) ' || 
-                    'SELECT '|| fs_id || ', '||quote_literal(cv.col)||', '||cv.col||' FROM '||table_name||' WHERE '||pkey_name||' = '||fs_pkey_value;
-            END LOOP;
-        END LOOP;
-    END IF;
-
-    statement := 'UPDATE ' || table_name || ' SET';
-
-    sep := '';
-    FOR cv IN
-        SELECT  col,
-                val
-        FROM    action.fieldset_col_val
-        WHERE   fieldset = fieldset_id
-    LOOP
-        statement := statement || sep || ' ' || cv.col
-                     || ' = ' || coalesce( quote_literal( cv.val ), 'NULL' );
-        sep := ',';
-    END LOOP;
-
-    IF sep = '' THEN
-        RETURN 'Fieldset ' || fieldset_id || ' has no column values defined';
-    END IF;
-    statement := statement || ' ' || where_clause;
-
-    --
-    -- Execute the update
-    --
-    BEGIN
-        EXECUTE statement;
-        GET DIAGNOSTICS update_count = ROW_COUNT;
-
-        IF update_count = 0 THEN
-            RAISE data_exception;
-        END IF;
-
-        IF fsg_id IS NOT NULL THEN
-            UPDATE action.fieldset_group SET rollback_group = fsg_id WHERE id = fs_group.id;
-        END IF;
-
-        IF fs_group.id IS NOT NULL THEN
-            UPDATE action.fieldset_group SET complete_time = now() WHERE id = fs_group.id;
-        END IF;
-
-        UPDATE action.fieldset SET status = 'APPLIED', applied_time = now() WHERE id = fieldset_id;
-
-    EXCEPTION WHEN data_exception THEN
-        msg := 'No eligible rows found for fieldset ' || fieldset_id;
-        UPDATE action.fieldset SET status = 'ERROR', applied_time = now() WHERE id = fieldset_id;
-        RETURN msg;
-
-    END;
-
-    RETURN msg;
-
-EXCEPTION WHEN OTHERS THEN
-    msg := 'Unable to apply fieldset ' || fieldset_id || ': ' || sqlerrm;
-    UPDATE action.fieldset SET status = 'ERROR', applied_time = now() WHERE id = fieldset_id;
-    RETURN msg;
-
-END;
-$$ LANGUAGE plpgsql;
-
--- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1057', :eg_version); -- miker/gmcharlt/kmlussier
-
--- Thist change drops a needless join and saves 10-15% in time cost
-CREATE OR REPLACE FUNCTION search.facets_for_record_set(ignore_facet_classes text[], hits bigint[]) RETURNS TABLE(id integer, value text, count bigint)
-AS $f$
-    SELECT id, value, count
-      FROM (
-        SELECT  mfae.field AS id,
-                mfae.value,
-                COUNT(DISTINCT mfae.source),
-                row_number() OVER (
-                    PARTITION BY mfae.field ORDER BY COUNT(DISTINCT mfae.source) DESC
-                ) AS rownum
-          FROM  metabib.facet_entry mfae
-                JOIN config.metabib_field cmf ON (cmf.id = mfae.field)
-          WHERE mfae.source = ANY ($2)
-                AND cmf.facet_field
-                AND cmf.field_class NOT IN (SELECT * FROM unnest($1))
-          GROUP by 1, 2
-      ) all_facets
-      WHERE rownum <= (
-        SELECT COALESCE(
-            (SELECT value::INT FROM config.global_flag WHERE name = 'search.max_facets_per_field' AND enabled),
-            1000
-        )
-      );
-$f$ LANGUAGE SQL;
-
-CREATE OR REPLACE FUNCTION unapi.metabib_virtual_record_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit HSTORE DEFAULT NULL, soffset HSTORE DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL ) RETURNS XML AS $F$
-DECLARE
-    layout          unapi.bre_output_layout%ROWTYPE;
-    transform       config.xml_transform%ROWTYPE;
-    item_format     TEXT;
-    tmp_xml         TEXT;
-    xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
-    ouid            INT;
-    element_list    TEXT[];
-BEGIN
-
-    IF org = '-' OR org IS NULL THEN
-        SELECT shortname INTO org FROM evergreen.org_top();
-    END IF;
-
-    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
-    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
-
-    IF layout.name IS NULL THEN
-        RETURN NULL::XML;
-    END IF;
-
-    SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
-    xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
-
-    -- Gather the bib xml
-    SELECT XMLAGG( unapi.mmr(i, format, '', includes, org, depth, slimit, soffset, include_xmlns)) INTO tmp_xml FROM UNNEST( id_list ) i;
-
-    IF layout.title_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
-    END IF;
-
-    IF layout.description_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
-    END IF;
-
-    IF layout.creator_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
-    END IF;
-
-    IF layout.update_ts_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
-    END IF;
-
-    IF unapi_url IS NOT NULL THEN
-        EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
-    END IF;
-
-    IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
-
-    element_list := regexp_split_to_array(layout.feed_top,E'\\.');
-    FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
-        EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
-    END LOOP;
-
-    RETURN tmp_xml::XML;
-END;
-$F$ LANGUAGE PLPGSQL STABLE;
-
-CREATE TABLE asset.copy_vis_attr_cache (
-    id              BIGSERIAL   PRIMARY KEY,
-    record          BIGINT      NOT NULL, -- No FKEYs, managed by user triggers.
-    target_copy     BIGINT      NOT NULL,
-    vis_attr_vector INT[]
-);
-CREATE INDEX copy_vis_attr_cache_record_idx ON asset.copy_vis_attr_cache (record);
-CREATE INDEX copy_vis_attr_cache_copy_idx ON asset.copy_vis_attr_cache (target_copy);
-
-ALTER TABLE biblio.record_entry ADD COLUMN vis_attr_vector INT[];
-
-CREATE OR REPLACE FUNCTION search.calculate_visibility_attribute ( value INT, attr TEXT ) RETURNS INT AS $f$
-SELECT  ((CASE $2
-
-            WHEN 'luri_org'         THEN 0 -- "b" attr
-            WHEN 'bib_source'       THEN 1 -- "b" attr
-
-            WHEN 'copy_flags'       THEN 0 -- "c" attr
-            WHEN 'owning_lib'       THEN 1 -- "c" attr
-            WHEN 'circ_lib'         THEN 2 -- "c" attr
-            WHEN 'status'           THEN 3 -- "c" attr
-            WHEN 'location'         THEN 4 -- "c" attr
-            WHEN 'location_group'   THEN 5 -- "c" attr
-
-        END) << 28 ) | $1;
-
-/* copy_flags bit positions, LSB-first:
-
- 0: asset.copy.opac_visible
-
-
-   When adding flags, you must update asset.all_visible_flags()
-
-   Because bib and copy values are stored separately, we can reuse
-   shifts, saving us some space. We could probably take back a bit
-   too, but I'm not sure its worth squeezing that last one out. We'd
-   be left with just 2 slots for copy attrs, rather than 10.
-*/
-
-$f$ LANGUAGE SQL IMMUTABLE;
-
-CREATE OR REPLACE FUNCTION search.calculate_visibility_attribute_list ( attr TEXT, value INT[] ) RETURNS INT[] AS $f$
-    SELECT ARRAY_AGG(search.calculate_visibility_attribute(x, $1)) FROM UNNEST($2) AS X;
-$f$ LANGUAGE SQL IMMUTABLE;
-
-CREATE OR REPLACE FUNCTION search.calculate_visibility_attribute_test ( attr TEXT, value INT[], negate BOOL DEFAULT FALSE ) RETURNS TEXT AS $f$
-    SELECT  CASE WHEN $3 THEN '!' ELSE '' END || '(' || ARRAY_TO_STRING(search.calculate_visibility_attribute_list($1,$2),'|') || ')';
-$f$ LANGUAGE SQL IMMUTABLE;
-
-CREATE OR REPLACE FUNCTION asset.calculate_copy_visibility_attribute_set ( copy_id BIGINT ) RETURNS INT[] AS $f$
-DECLARE
-    copy_row    asset.copy%ROWTYPE;
-    lgroup_map  asset.copy_location_group_map%ROWTYPE;
-    attr_set    INT[];
-BEGIN
-    SELECT * INTO copy_row FROM asset.copy WHERE id = copy_id;
-
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.opac_visible::INT, 'copy_flags');
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.circ_lib, 'circ_lib');
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.status, 'status');
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.location, 'location');
-
-    SELECT  ARRAY_APPEND(
-                attr_set,
-                search.calculate_visibility_attribute(owning_lib, 'owning_lib')
-            ) INTO attr_set
-      FROM  asset.call_number
-      WHERE id = copy_row.call_number;
-
-    FOR lgroup_map IN SELECT * FROM asset.copy_location_group_map WHERE location = copy_row.location LOOP
-        attr_set := attr_set || search.calculate_visibility_attribute(lgroup_map.lgroup, 'location_group');
-    END LOOP;
-
-    RETURN attr_set;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION biblio.calculate_bib_visibility_attribute_set ( bib_id BIGINT ) RETURNS INT[] AS $f$
-DECLARE
-    bib_row     biblio.record_entry%ROWTYPE;
-    cn_row      asset.call_number%ROWTYPE;
-    attr_set    INT[];
-BEGIN
-    SELECT * INTO bib_row FROM biblio.record_entry WHERE id = bib_id;
-
-    IF bib_row.source IS NOT NULL THEN
-        attr_set := attr_set || search.calculate_visibility_attribute(bib_row.source, 'bib_source');
-    END IF;
-
-    FOR cn_row IN
-        SELECT  cn.*
-          FROM  asset.call_number cn
-                JOIN asset.uri_call_number_map m ON (cn.id = m.call_number)
-                JOIN asset.uri u ON (u.id = m.uri)
-          WHERE cn.record = bib_id
-                AND cn.label = '##URI##'
-                AND u.active
-    LOOP
-        attr_set := attr_set || search.calculate_visibility_attribute(cn_row.owning_lib, 'luri_org');
-    END LOOP;
-
-    RETURN attr_set;
-END;
-$f$ LANGUAGE PLPGSQL;
-
--- SELECT evergreen.upgrade_deps_block_check('1076', :eg_version); -- miker/gmcharlt
-
-CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
-DECLARE
-    ocn     asset.call_number%ROWTYPE;
-    ncn     asset.call_number%ROWTYPE;
-    cid     BIGINT;
-BEGIN
-
-    IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN -- Only needs ON INSERT OR DELETE, so handle separately
-        IF TG_OP = 'INSERT' THEN
-            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                NEW.peer_record,
-                NEW.target_copy,
-                asset.calculate_copy_visibility_attribute_set(NEW.target_copy)
-            );
-
-            RETURN NEW;
-        ELSIF TG_OP = 'DELETE' THEN
-            DELETE FROM asset.copy_vis_attr_cache
-              WHERE record = NEW.peer_record AND target_copy = NEW.target_copy;
-
-            RETURN OLD;
-        END IF;
-    END IF;
-
-    IF TG_OP = 'INSERT' THEN -- Handles ON INSERT. ON UPDATE is below.
-        IF TG_TABLE_NAME IN ('copy', 'unit') THEN
-            SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
-            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                ncn.record,
-                NEW.id,
-                asset.calculate_copy_visibility_attribute_set(NEW.id)
-            );
-        ELSIF TG_TABLE_NAME = 'record_entry' THEN
-            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
-        END IF;
-
-        RETURN NEW;
-    END IF;
-
-    -- handle items first, since with circulation activity
-    -- their statuses change frequently
-    IF TG_TABLE_NAME IN ('copy', 'unit') THEN -- This handles ON UPDATE OR DELETE. ON INSERT above
-
-        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
-            DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
-            RETURN OLD;
-        END IF;
-
-        SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
-
-        IF OLD.deleted <> NEW.deleted THEN
-            IF NEW.deleted THEN
-                DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
-            ELSE
-                INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                    ncn.record,
-                    NEW.id,
-                    asset.calculate_copy_visibility_attribute_set(NEW.id)
-                );
-            END IF;
-
-            RETURN NEW;
-        ELSIF OLD.call_number  <> NEW.call_number THEN
-            SELECT * INTO ocn FROM asset.call_number cn WHERE id = OLD.call_number;
-
-            IF ncn.record <> ocn.record THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(ncn.record)
-                  WHERE id = ocn.record;
-
-                -- We have to use a record-specific WHERE clause
-                -- to avoid modifying the entries for peer-bib copies.
-                UPDATE  asset.copy_vis_attr_cache
-                  SET   target_copy = NEW.id,
-                        record = ncn.record
-                  WHERE target_copy = OLD.id
-                        AND record = ocn.record;
-            END IF;
-        END IF;
-
-        IF OLD.location     <> NEW.location OR
-           OLD.status       <> NEW.status OR
-           OLD.opac_visible <> NEW.opac_visible OR
-           OLD.circ_lib     <> NEW.circ_lib
-        THEN
-            -- Any of these could change visibility, but
-            -- we'll save some queries and not try to calculate
-            -- the change directly.  We want to update peer-bib
-            -- entries in this case, unlike above.
-            UPDATE  asset.copy_vis_attr_cache
-              SET   target_copy = NEW.id,
-                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(NEW.id)
-              WHERE target_copy = OLD.id;
-
-        END IF;
-
-    ELSIF TG_TABLE_NAME = 'call_number' THEN -- Only ON UPDATE. Copy handler will deal with ON INSERT OR DELETE.
-
-        IF OLD.record <> NEW.record THEN
-            IF NEW.label = '##URI##' THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
-                  WHERE id = OLD.record;
-
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
-                  WHERE id = NEW.record;
-            END IF;
-
-            UPDATE  asset.copy_vis_attr_cache
-              SET   record = NEW.record,
-                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
-              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
-                    AND record = OLD.record;
-
-        ELSIF OLD.owning_lib <> NEW.owning_lib THEN
-            UPDATE  asset.copy_vis_attr_cache
-              SET   vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
-              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
-                    AND record = NEW.record;
-
-            IF NEW.label = '##URI##' THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
-                  WHERE id = OLD.record;
-            END IF;
-        END IF;
-
-    ELSIF TG_TABLE_NAME = 'record_entry' THEN -- Only handles ON UPDATE OR DELETE
-
-        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
-            DELETE FROM asset.copy_vis_attr_cache WHERE record = OLD.id;
-            RETURN OLD;
-        ELSIF OLD.source <> NEW.source THEN
-            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
-        END IF;
-
-    END IF;
-
-    RETURN NEW;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-
--- Helper functions for use in constructing searches --
-
-CREATE OR REPLACE FUNCTION asset.all_visible_flags () RETURNS TEXT AS $f$
-    SELECT  '(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(1 << x, 'copy_flags')),'&') || ')'
-      FROM  GENERATE_SERIES(0,0) AS x; -- increment as new flags are added.
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.visible_orgs (otype TEXT) RETURNS TEXT AS $f$
-    SELECT  '(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, $1)),'|') || ')'
-      FROM  actor.org_unit
-      WHERE opac_visible;
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.invisible_orgs (otype TEXT) RETURNS TEXT AS $f$
-    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, $1)),'|') || ')'
-      FROM  actor.org_unit
-      WHERE NOT opac_visible;
-$f$ LANGUAGE SQL STABLE;
-
--- Bib-oriented defaults for search
-CREATE OR REPLACE FUNCTION asset.bib_source_default () RETURNS TEXT AS $f$
-    SELECT  '(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'bib_source')),'|') || ')'
-      FROM  config.bib_source
-      WHERE transcendant;
-$f$ LANGUAGE SQL IMMUTABLE;
-
-CREATE OR REPLACE FUNCTION asset.luri_org_default () RETURNS TEXT AS $f$
-    SELECT  * FROM asset.invisible_orgs('luri_org');
-$f$ LANGUAGE SQL STABLE;
-
--- Copy-oriented defaults for search
-CREATE OR REPLACE FUNCTION asset.location_group_default () RETURNS TEXT AS $f$
-    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'location_group')),'|') || ')'
-      FROM  asset.copy_location_group
-      WHERE NOT opac_visible;
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.location_default () RETURNS TEXT AS $f$
-    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'location')),'|') || ')'
-      FROM  asset.copy_location
-      WHERE NOT opac_visible;
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.status_default () RETURNS TEXT AS $f$
-    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'status')),'|') || ')'
-      FROM  config.copy_status
-      WHERE NOT opac_visible;
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.owning_lib_default () RETURNS TEXT AS $f$
-    SELECT  * FROM asset.invisible_orgs('owning_lib');
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.circ_lib_default () RETURNS TEXT AS $f$
-    SELECT  * FROM asset.invisible_orgs('circ_lib');
-$f$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION asset.patron_default_visibility_mask () RETURNS TABLE (b_attrs TEXT, c_attrs TEXT)  AS $f$
-DECLARE
-    copy_flags      TEXT; -- "c" attr
-
-    owning_lib      TEXT; -- "c" attr
-    circ_lib        TEXT; -- "c" attr
-    status          TEXT; -- "c" attr
-    location        TEXT; -- "c" attr
-    location_group  TEXT; -- "c" attr
-
-    luri_org        TEXT; -- "b" attr
-    bib_sources     TEXT; -- "b" attr
-BEGIN
-    copy_flags      := asset.all_visible_flags(); -- Will always have at least one
-
-    owning_lib      := NULLIF(asset.owning_lib_default(),'!()');
-    
-    circ_lib        := NULLIF(asset.circ_lib_default(),'!()');
-    status          := NULLIF(asset.status_default(),'!()');
-    location        := NULLIF(asset.location_default(),'!()');
-    location_group  := NULLIF(asset.location_group_default(),'!()');
-
-    luri_org        := NULLIF(asset.luri_org_default(),'!()');
-    bib_sources     := NULLIF(asset.bib_source_default(),'()');
-
-    RETURN QUERY SELECT
-        '('||ARRAY_TO_STRING(
-            ARRAY[luri_org,bib_sources],
-            '|'
-        )||')',
-        '('||ARRAY_TO_STRING(
-            ARRAY[copy_flags,owning_lib,circ_lib,status,location,location_group]::TEXT[],
-            '&'
-        )||')';
-END;
-$f$ LANGUAGE PLPGSQL STABLE ROWS 1;
-
-CREATE OR REPLACE FUNCTION metabib.suggest_browse_entries(raw_query_text text, search_class text, headline_opts text, visibility_org integer, query_limit integer, normalization integer)
- RETURNS TABLE(value text, field integer, buoyant_and_class_match boolean, field_match boolean, field_weight integer, rank real, buoyant boolean, match text)
-AS $f$
-DECLARE
-    prepared_query_texts    TEXT[];
-    query                   TSQUERY;
-    plain_query             TSQUERY;
-    opac_visibility_join    TEXT;
-    search_class_join       TEXT;
-    r_fields                RECORD;
-BEGIN
-    prepared_query_texts := metabib.autosuggest_prepare_tsquery(raw_query_text);
-
-    query := TO_TSQUERY('keyword', prepared_query_texts[1]);
-    plain_query := TO_TSQUERY('keyword', prepared_query_texts[2]);
-
-    visibility_org := NULLIF(visibility_org,-1);
-    IF visibility_org IS NOT NULL THEN
-        PERFORM FROM actor.org_unit WHERE id = visibility_org AND parent_ou IS NULL;
-        IF FOUND THEN
-            opac_visibility_join := '';
-        ELSE
-            opac_visibility_join := '
-    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = x.source)
-    JOIN vm ON (acvac.vis_attr_vector @@
-            (vm.c_attrs || $$&$$ ||
-                search.calculate_visibility_attribute_test(
-                    $$circ_lib$$,
-                    (SELECT ARRAY_AGG(id) FROM actor.org_unit_descendants($4))
-                )
-            )::query_int
-         )
-';
-        END IF;
-    ELSE
-        opac_visibility_join := '';
-    END IF;
-
-    -- The following determines whether we only provide suggestsons matching
-    -- the user's selected search_class, or whether we show other suggestions
-    -- too. The reason for MIN() is that for search_classes like
-    -- 'title|proper|uniform' you would otherwise get multiple rows.  The
-    -- implication is that if title as a class doesn't have restrict,
-    -- nor does the proper field, but the uniform field does, you're going
-    -- to get 'false' for your overall evaluation of 'should we restrict?'
-    -- To invert that, change from MIN() to MAX().
-
-    SELECT
-        INTO r_fields
-            MIN(cmc.restrict::INT) AS restrict_class,
-            MIN(cmf.restrict::INT) AS restrict_field
-        FROM metabib.search_class_to_registered_components(search_class)
-            AS _registered (field_class TEXT, field INT)
-        JOIN
-            config.metabib_class cmc ON (cmc.name = _registered.field_class)
-        LEFT JOIN
-            config.metabib_field cmf ON (cmf.id = _registered.field);
-
-    -- evaluate 'should we restrict?'
-    IF r_fields.restrict_field::BOOL OR r_fields.restrict_class::BOOL THEN
-        search_class_join := '
-    JOIN
-        metabib.search_class_to_registered_components($2)
-        AS _registered (field_class TEXT, field INT) ON (
-            (_registered.field IS NULL AND
-                _registered.field_class = cmf.field_class) OR
-            (_registered.field = cmf.id)
-        )
-    ';
-    ELSE
-        search_class_join := '
-    LEFT JOIN
-        metabib.search_class_to_registered_components($2)
-        AS _registered (field_class TEXT, field INT) ON (
-            _registered.field_class = cmc.name
-        )
-    ';
-    END IF;
-
-    RETURN QUERY EXECUTE '
-WITH vm AS ( SELECT * FROM asset.patron_default_visibility_mask() ),
-     mbe AS (SELECT * FROM metabib.browse_entry WHERE index_vector @@ $1 LIMIT 10000)
-SELECT  DISTINCT
-        x.value,
-        x.id,
-        x.push,
-        x.restrict,
-        x.weight,
-        x.ts_rank_cd,
-        x.buoyant,
-        TS_HEADLINE(value, $7, $3)
-  FROM  (SELECT DISTINCT
-                mbe.value,
-                cmf.id,
-                cmc.buoyant AND _registered.field_class IS NOT NULL AS push,
-                _registered.field = cmf.id AS restrict,
-                cmf.weight,
-                TS_RANK_CD(mbe.index_vector, $1, $6),
-                cmc.buoyant,
-                mbedm.source
-          FROM  metabib.browse_entry_def_map mbedm
-                JOIN mbe ON (mbe.id = mbedm.entry)
-                JOIN config.metabib_field cmf ON (cmf.id = mbedm.def)
-                JOIN config.metabib_class cmc ON (cmf.field_class = cmc.name)
-                '  || search_class_join || '
-          ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
-          LIMIT 1000) AS x
-        ' || opac_visibility_join || '
-  ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
-  LIMIT $5
-'   -- sic, repeat the order by clause in the outer select too
-    USING
-        query, search_class, headline_opts,
-        visibility_org, query_limit, normalization, plain_query
-        ;
-
-    -- sort order:
-    --  buoyant AND chosen class = match class
-    --  chosen field = match field
-    --  field weight
-    --  rank
-    --  buoyancy
-    --  value itself
-
-END;
-$f$ LANGUAGE plpgsql ROWS 10;
-
-/* COMMENT OUT THE FIRST UPDATE SO WE THERE IS NOT NEED TO PATCH BOTH 
-CREATE OR REPLACE FUNCTION metabib.browse(search_field integer[], browse_term text, context_org integer DEFAULT NULL::integer, context_loc_group integer DEFAULT NULL::integer, staff boolean DEFAULT false, pivot_id bigint DEFAULT NULL::bigint, result_limit integer DEFAULT 10)
- RETURNS SETOF metabib.flat_browse_entry_appearance
-AS $f$
-DECLARE
-    core_query              TEXT;
-    back_query              TEXT;
-    forward_query           TEXT;
-    pivot_sort_value        TEXT;
-    pivot_sort_fallback     TEXT;
-    context_locations       INT[];
-    browse_superpage_size   INT;
-    results_skipped         INT := 0;
-    back_limit              INT;
-    back_to_pivot           INT;
-    forward_limit           INT;
-    forward_to_pivot        INT;
-BEGIN
-    -- First, find the pivot if we were given a browse term but not a pivot.
-    IF pivot_id IS NULL THEN
-        pivot_id := metabib.browse_pivot(search_field, browse_term);
-    END IF;
-
-    SELECT INTO pivot_sort_value, pivot_sort_fallback
-        sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
-
-    -- Bail if we couldn't find a pivot.
-    IF pivot_sort_value IS NULL THEN
-        RETURN;
-    END IF;
-
-    -- Transform the context_loc_group argument (if any) (logc at the
-    -- TPAC layer) into a form we'll be able to use.
-    IF context_loc_group IS NOT NULL THEN
-        SELECT INTO context_locations ARRAY_AGG(location)
-            FROM asset.copy_location_group_map
-            WHERE lgroup = context_loc_group;
-    END IF;
-
-    -- Get the configured size of browse superpages.
-    SELECT INTO browse_superpage_size COALESCE(value::INT,100)     -- NULL ok
-        FROM config.global_flag
-        WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
-
-    -- First we're going to search backward from the pivot, then we're going
-    -- to search forward.  In each direction, we need two limits.  At the
-    -- lesser of the two limits, we delineate the edge of the result set
-    -- we're going to return.  At the greater of the two limits, we find the
-    -- pivot value that would represent an offset from the current pivot
-    -- at a distance of one "page" in either direction, where a "page" is a
-    -- result set of the size specified in the "result_limit" argument.
-    --
-    -- The two limits in each direction make four derived values in total,
-    -- and we calculate them now.
-    back_limit := CEIL(result_limit::FLOAT / 2);
-    back_to_pivot := result_limit;
-    forward_limit := result_limit / 2;
-    forward_to_pivot := result_limit - 1;
-
-    -- This is the meat of the SQL query that finds browse entries.  We'll
-    -- pass this to a function which uses it with a cursor, so that individual
-    -- rows may be fetched in a loop until some condition is satisfied, without
-    -- waiting for a result set of fixed size to be collected all at once.
-    core_query := '
-SELECT  mbe.id,
-        mbe.value,
-        mbe.sort_value
-  FROM  metabib.browse_entry mbe
-  WHERE (
-            EXISTS ( -- are there any bibs using this mbe via the requested fields?
-                SELECT  1
-                  FROM  metabib.browse_entry_def_map mbedm
-                  WHERE mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ')
-            ) OR EXISTS ( -- are there any authorities using this mbe via the requested fields?
-                SELECT  1
-                  FROM  metabib.browse_entry_simple_heading_map mbeshm
-                        JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-                        JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                            ash.atag = map.authority_field
-                            AND map.metabib_field = ANY(' || quote_literal(search_field) || ')
-                        )
-                  WHERE mbeshm.entry = mbe.id
-            )
-        ) AND ';
-
-    -- This is the variant of the query for browsing backward.
-    back_query := core_query ||
-        ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
-    ' ORDER BY mbe.sort_value DESC, mbe.value DESC LIMIT 1000';
-
-    -- This variant browses forward.
-    forward_query := core_query ||
-        ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
-    ' ORDER BY mbe.sort_value, mbe.value LIMIT 1000';
-
-    -- We now call the function which applies a cursor to the provided
-    -- queries, stopping at the appropriate limits and also giving us
-    -- the next page's pivot.
-    RETURN QUERY
-        SELECT * FROM metabib.staged_browse(
-            back_query, search_field, context_org, context_locations,
-            staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
-        ) UNION
-        SELECT * FROM metabib.staged_browse(
-            forward_query, search_field, context_org, context_locations,
-            staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
-        ) ORDER BY row_number DESC;
-END; $f$ LANGUAGE plpgsql ROWS 10;
-
-CREATE OR REPLACE FUNCTION metabib.staged_browse(query text, fields integer[], context_org integer, context_locations integer[], staff boolean, browse_superpage_size integer, count_up_from_zero boolean, result_limit integer, next_pivot_pos integer)
- RETURNS SETOF metabib.flat_browse_entry_appearance
-AS $f$
-DECLARE
-    curs                    REFCURSOR;
-    rec                     RECORD;
-    qpfts_query             TEXT;
-    aqpfts_query            TEXT;
-    afields                 INT[];
-    bfields                 INT[];
-    result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
-    results_skipped         INT := 0;
-    row_counter             INT := 0;
-    row_number              INT;
-    slice_start             INT;
-    slice_end               INT;
-    full_end                INT;
-    all_records             BIGINT[];
-    all_brecords             BIGINT[];
-    all_arecords            BIGINT[];
-    superpage_of_records    BIGINT[];
-    superpage_size          INT;
-    c_tests                 TEXT := '';
-    b_tests                 TEXT := '';
-    c_orgs                  INT[];
-BEGIN
-    IF count_up_from_zero THEN
-        row_number := 0;
-    ELSE
-        row_number := -1;
-    END IF;
-
-    IF NOT staff THEN
-        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
-    END IF;
-
-    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
-    IF b_tests <> '' THEN b_tests := b_tests || '&'; END IF;
-
-    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
-    
-    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
-               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
-    
-    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
-    IF FOUND THEN
-        b_tests := b_tests || search.calculate_visibility_attribute_test(
-            'luri_org',
-            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
-        );
-    ELSE
-        b_tests := b_tests || search.calculate_visibility_attribute_test(
-            'luri_org',
-            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
-        );
-    END IF;
-
-    IF context_locations THEN
-        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
-        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_locations);
-    END IF;
-
-    OPEN curs NO SCROLL FOR EXECUTE query;
-
-    LOOP
-        FETCH curs INTO rec;
-        IF NOT FOUND THEN
-            IF result_row.pivot_point IS NOT NULL THEN
-                RETURN NEXT result_row;
-            END IF;
-            RETURN;
-        END IF;
-
-        -- Gather aggregate data based on the MBE row we're looking at now, authority axis
-        SELECT INTO all_arecords, result_row.sees, afields
-                ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
-                STRING_AGG(DISTINCT aal.source::TEXT, $$,$$), -- authority record ids
-                ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
-
-          FROM  metabib.browse_entry_simple_heading_map mbeshm
-                JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-                JOIN authority.authority_linking aal ON ( ash.record = aal.source )
-                JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
-                JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                    ash.atag = map.authority_field
-                    AND map.metabib_field = ANY(fields)
-                )
-          WHERE mbeshm.entry = rec.id;
-
-        -- Gather aggregate data based on the MBE row we're looking at now, bib axis
-        SELECT INTO all_brecords, result_row.authorities, bfields
-                ARRAY_AGG(DISTINCT source),
-                STRING_AGG(DISTINCT authority::TEXT, $$,$$),
-                ARRAY_AGG(DISTINCT def)
-          FROM  metabib.browse_entry_def_map
-          WHERE entry = rec.id
-                AND def = ANY(fields);
-
-        SELECT INTO result_row.fields STRING_AGG(DISTINCT x::TEXT, $$,$$) FROM UNNEST(afields || bfields) x;
-
-        result_row.sources := 0;
-        result_row.asources := 0;
-
-        -- Bib-linked vis checking
-        IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
-
-            SELECT  INTO result_row.sources COUNT(DISTINCT b.id)
-              FROM  biblio.record_entry b
-                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
-              WHERE b.id = ANY(all_brecords[1:browse_superpage_size])
-                    AND (
-                        acvac.vis_attr_vector @@ c_tests::query_int
-                        OR b.vis_attr_vector @@ b_tests::query_int
-                    );
-
-            result_row.accurate := TRUE;
-
-        END IF;
-
-        -- Authority-linked vis checking
-        IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
-
-            SELECT  INTO result_row.asources COUNT(DISTINCT b.id)
-              FROM  biblio.record_entry b
-                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
-              WHERE b.id = ANY(all_arecords[1:browse_superpage_size])
-                    AND (
-                        acvac.vis_attr_vector @@ c_tests::query_int
-                        OR b.vis_attr_vector @@ b_tests::query_int
-                    );
-
-            result_row.aaccurate := TRUE;
-
-        END IF;
-
-        IF result_row.sources > 0 OR result_row.asources > 0 THEN
-
-            -- The function that calls this function needs row_number in order
-            -- to correctly order results from two different runs of this
-            -- functions.
-            result_row.row_number := row_number;
-
-            -- Now, if row_counter is still less than limit, return a row.  If
-            -- not, but it is less than next_pivot_pos, continue on without
-            -- returning actual result rows until we find
-            -- that next pivot, and return it.
-
-            IF row_counter < result_limit THEN
-                result_row.browse_entry := rec.id;
-                result_row.value := rec.value;
-
-                RETURN NEXT result_row;
-            ELSE
-                result_row.browse_entry := NULL;
-                result_row.authorities := NULL;
-                result_row.fields := NULL;
-                result_row.value := NULL;
-                result_row.sources := NULL;
-                result_row.sees := NULL;
-                result_row.accurate := NULL;
-                result_row.aaccurate := NULL;
-                result_row.pivot_point := rec.id;
-
-                IF row_counter >= next_pivot_pos THEN
-                    RETURN NEXT result_row;
-                    RETURN;
-                END IF;
-            END IF;
-
-            IF count_up_from_zero THEN
-                row_number := row_number + 1;
-            ELSE
-                row_number := row_number - 1;
-            END IF;
-
-            -- row_counter is different from row_number.
-            -- It simply counts up from zero so that we know when
-            -- we've reached our limit.
-            row_counter := row_counter + 1;
-        END IF;
-    END LOOP;
-END;
-$f$ LANGUAGE plpgsql ROWS 10;
-*/
-
-CREATE OR REPLACE FUNCTION asset.opac_ou_record_copy_count (org INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
-DECLARE
-    ans RECORD;
-    trans INT;
-BEGIN
-    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
-
-    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
-        RETURN QUERY
-        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
-             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
-             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
-        SELECT  ans.depth,
-                ans.id,
-                COUNT( av.id ),
-                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
-                COUNT( av.id ),
-                trans
-          FROM  mask,
-                available_statuses,
-                org_list,
-                asset.copy_vis_attr_cache av
-                JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
-          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
-          GROUP BY 1,2,6;
-
-        IF NOT FOUND THEN
-            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
-        END IF;
-
-    END LOOP;
-
-    RETURN;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION asset.opac_lasso_record_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
-DECLARE
-    ans RECORD;
-    trans INT;
-BEGIN
-    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
-
-    FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
-        RETURN QUERY
-        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
-             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
-             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
-        SELECT  -1,
-                ans.id,
-                COUNT( av.id ),
-                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
-                COUNT( av.id ),
-                trans
-          FROM  mask,
-                org_list,
-                asset.copy_vis_attr_cache av
-                JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
-          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
-          GROUP BY 1,2,6;
-
-        IF NOT FOUND THEN
-            RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
-        END IF;
-
-    END LOOP;
-
-    RETURN;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION asset.opac_ou_metarecord_copy_count (org INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
-DECLARE
-    ans RECORD;
-    trans INT;
-BEGIN
-    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) JOIN metabib.metarecord_source_map m ON (m.source = b.id) WHERE src.transcendant AND m.metarecord = rid;
-
-    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
-        RETURN QUERY
-        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
-             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
-             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
-        SELECT  ans.depth,
-                ans.id,
-                COUNT( av.id ),
-                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
-                COUNT( av.id ),
-                trans
-          FROM  mask,
-                org_list,
-                available_statuses,
-                asset.copy_vis_attr_cache av
-                JOIN asset.copy cp ON (cp.id = av.target_copy)
-                JOIN metabib.metarecord_source_map m ON (m.metarecord = rid AND m.source = av.record)
-          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
-          GROUP BY 1,2,6;
-
-        IF NOT FOUND THEN
-            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
-        END IF;
-
-    END LOOP;
-
-    RETURN;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION asset.opac_lasso_metarecord_copy_count (i_lasso INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
-DECLARE
-    ans RECORD;
-    trans INT;
-BEGIN
-    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) JOIN metabib.metarecord_source_map m ON (m.source = b.id) WHERE src.transcendant AND m.metarecord = rid;
-
-    FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
-        RETURN QUERY
-        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
-             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
-             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
-        SELECT  -1,
-                ans.id,
-                COUNT( av.id ),
-                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
-                COUNT( av.id ),
-                trans
-          FROM  mask,
-                org_list,
-                available_statuses,
-                asset.copy_vis_attr_cache av
-                JOIN asset.copy cp ON (cp.id = av.target_copy)
-                JOIN metabib.metarecord_source_map m ON (m.metarecord = rid AND m.source = av.record)
-          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
-          GROUP BY 1,2,6;
-
-        IF NOT FOUND THEN
-            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
-        END IF;
-
-    END LOOP;
-
-    RETURN;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION unapi.mmr_mra (
-    obj_id BIGINT,
-    format TEXT,
-    ename TEXT,
-    includes TEXT[],
-    org TEXT,
-    depth INT DEFAULT NULL,
-    slimit HSTORE DEFAULT NULL,
-    soffset HSTORE DEFAULT NULL,
-    include_xmlns BOOL DEFAULT TRUE,
-    pref_lib INT DEFAULT NULL
-) RETURNS XML AS $F$
-    SELECT  XMLELEMENT(
-        name attributes,
-        XMLATTRIBUTES(
-            CASE WHEN $9 THEN 'http://open-ils.org/spec/indexing/v1' ELSE NULL END AS xmlns,
-            'tag:open-ils.org:U2@mmr/' || $1 AS metarecord
-        ),
-        (SELECT XMLAGG(foo.y)
-          FROM (
-            WITH sourcelist AS (
-                WITH aou AS (SELECT COALESCE(id, (evergreen.org_top()).id) AS id FROM actor.org_unit WHERE shortname = $5 LIMIT 1),
-                     basevm AS (SELECT c_attrs FROM  asset.patron_default_visibility_mask()),
-                     circvm AS (SELECT search.calculate_visibility_attribute_test('circ_lib', ARRAY_AGG(aoud.id)) AS mask
-                                  FROM aou, LATERAL actor.org_unit_descendants(aou.id, $6) aoud)
-                SELECT  source
-                  FROM  aou, circvm, basevm, metabib.metarecord_source_map mmsm
-                  WHERE mmsm.metarecord = $1 AND (
-                    EXISTS (
-                        SELECT  1
-                          FROM  circvm, basevm, asset.copy_vis_attr_cache acvac
-                          WHERE acvac.vis_attr_vector @@ (basevm.c_attrs || '&' || circvm.mask)::query_int
-                                AND acvac.record = mmsm.source
-                    )
-                    OR EXISTS (SELECT 1 FROM evergreen.located_uris(source, aou.id, $10) LIMIT 1)
-                    OR EXISTS (SELECT 1 FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = mmsm.source)
-                )
-            )
-            SELECT  cmra.aid,
-                    XMLELEMENT(
-                        name field,
-                        XMLATTRIBUTES(
-                            cmra.attr AS name,
-                            cmra.value AS "coded-value",
-                            cmra.aid AS "cvmid",
-                            rad.composite,
-                            rad.multi,
-                            rad.filter,
-                            rad.sorter,
-                            cmra.source_list
-                        ),
-                        cmra.value
-                    )
-              FROM  (
-                SELECT DISTINCT aid, attr, value, STRING_AGG(x.id::TEXT, ',') AS source_list
-                  FROM (
-                    SELECT  v.source AS id,
-                            c.id AS aid,
-                            c.ctype AS attr,
-                            c.code AS value
-                      FROM  metabib.record_attr_vector_list v
-                            JOIN config.coded_value_map c ON ( c.id = ANY( v.vlist ) )
-                    ) AS x
-                    JOIN sourcelist ON (x.id = sourcelist.source)
-                    GROUP BY 1, 2, 3
-                ) AS cmra
-                JOIN config.record_attr_definition rad ON (cmra.attr = rad.name)
-                UNION ALL
-            SELECT  umra.aid,
-                    XMLELEMENT(
-                        name field,
-                        XMLATTRIBUTES(
-                            umra.attr AS name,
-                            rad.composite,
-                            rad.multi,
-                            rad.filter,
-                            rad.sorter
-                        ),
-                        umra.value
-                    )
-              FROM  (
-                SELECT DISTINCT aid, attr, value
-                  FROM (
-                    SELECT  v.source AS id,
-                            m.id AS aid,
-                            m.attr AS attr,
-                            m.value AS value
-                      FROM  metabib.record_attr_vector_list v
-                            JOIN metabib.uncontrolled_record_attr_value m ON ( m.id = ANY( v.vlist ) )
-                    ) AS x
-                    JOIN sourcelist ON (x.id = sourcelist.source)
-                ) AS umra
-                JOIN config.record_attr_definition rad ON (umra.attr = rad.name)
-                ORDER BY 1
-
-            )foo(id,y)
-        )
-    )
-$F$ LANGUAGE SQL STABLE;
-
-CREATE OR REPLACE FUNCTION evergreen.ranked_volumes(
-    bibid BIGINT[],
-    ouid INT,
-    depth INT DEFAULT NULL,
-    slimit HSTORE DEFAULT NULL,
-    soffset HSTORE DEFAULT NULL,
-    pref_lib INT DEFAULT NULL,
-    includes TEXT[] DEFAULT NULL::TEXT[]
-) RETURNS TABLE(id BIGINT, name TEXT, label_sortkey TEXT, rank BIGINT) AS $$
-    WITH RECURSIVE ou_depth AS (
-        SELECT COALESCE(
-            $3,
-            (
-                SELECT depth
-                FROM actor.org_unit_type aout
-                    INNER JOIN actor.org_unit ou ON ou_type = aout.id
-                WHERE ou.id = $2
-            )
-        ) AS depth
-    ), descendant_depth AS (
-        SELECT  ou.id,
-                ou.parent_ou,
-                out.depth
-        FROM  actor.org_unit ou
-                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
-                JOIN anscestor_depth ad ON (ad.id = ou.id),
-                ou_depth
-        WHERE ad.depth = ou_depth.depth
-            UNION ALL
-        SELECT  ou.id,
-                ou.parent_ou,
-                out.depth
-        FROM  actor.org_unit ou
-                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
-                JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
-    ), anscestor_depth AS (
-        SELECT  ou.id,
-                ou.parent_ou,
-                out.depth
-        FROM  actor.org_unit ou
-                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
-        WHERE ou.id = $2
-            UNION ALL
-        SELECT  ou.id,
-                ou.parent_ou,
-                out.depth
-        FROM  actor.org_unit ou
-                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
-                JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
-    ), descendants as (
-        SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id)
-    )
-
-    SELECT ua.id, ua.name, ua.label_sortkey, MIN(ua.rank) AS rank FROM (
-        SELECT acn.id, owning_lib.name, acn.label_sortkey,
-            evergreen.rank_cp(acp),
-            RANK() OVER w
-        FROM asset.call_number acn
-            JOIN asset.copy acp ON (acn.id = acp.call_number)
-            JOIN descendants AS aou ON (acp.circ_lib = aou.id)
-            JOIN actor.org_unit AS owning_lib ON (acn.owning_lib = owning_lib.id)
-        WHERE acn.record = ANY ($1)
-            AND acn.deleted IS FALSE
-            AND acp.deleted IS FALSE
-            AND CASE WHEN ('exclude_invisible_acn' = ANY($7)) THEN
-                EXISTS (
-                    WITH basevm AS (SELECT c_attrs FROM  asset.patron_default_visibility_mask()),
-                         circvm AS (SELECT search.calculate_visibility_attribute_test('circ_lib', ARRAY[acp.circ_lib]) AS mask)
-                    SELECT  1
-                      FROM  basevm, circvm, asset.copy_vis_attr_cache acvac
-                      WHERE acvac.vis_attr_vector @@ (basevm.c_attrs || '&' || circvm.mask)::query_int
-                            AND acvac.target_copy = acp.id
-                            AND acvac.record = acn.record
-                ) ELSE TRUE END
-        GROUP BY acn.id, evergreen.rank_cp(acp), owning_lib.name, acn.label_sortkey, aou.id
-        WINDOW w AS (
-            ORDER BY
-                COALESCE(
-                    CASE WHEN aou.id = $2 THEN -20000 END,
-                    CASE WHEN aou.id = $6 THEN -10000 END,
-                    (SELECT distance - 5000
-                        FROM actor.org_unit_descendants_distance($6) as x
-                        WHERE x.id = aou.id AND $6 IN (
-                            SELECT q.id FROM actor.org_unit_descendants($2) as q)),
-                    (SELECT e.distance FROM actor.org_unit_descendants_distance($2) as e WHERE e.id = aou.id),
-                    1000
-                ),
-                evergreen.rank_cp(acp)
-        )
-    ) AS ua
-    GROUP BY ua.id, ua.name, ua.label_sortkey
-    ORDER BY rank, ua.name, ua.label_sortkey
-    LIMIT ($4 -> 'acn')::INT
-    OFFSET ($5 -> 'acn')::INT;
-$$ LANGUAGE SQL STABLE ROWS 10;
-
-
--- Evergreen DB patch XXXX.schema.action-trigger.event_definition.sms_preminder.sql
---
--- New action trigger event definition: 3 Day Courtesy Notice by SMS
---
-
--- check whether patch can be applied
--- SELECT evergreen.upgrade_deps_block_check('1058', :eg_version); -- mccanna/csharp/gmcharlt
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-INSERT INTO action_trigger.event_definition (id, active, owner, name, hook,
-        validator, reactor, delay, max_delay, delay_field, group_field, template)
-    VALUES (54, FALSE, 1,
-        '3 Day Courtesy Notice by SMS',
-        'checkout.due',
-        'CircIsOpen', 'SendSMS', '-3 days', '-2 days', 'due_date', 'usr',
-$$
-[%- USE date -%]
-[%- user = target.0.usr -%]
-[%- homelib = user.home_ou -%]
-[%- sms_number = helpers.get_user_setting(user.id, 'opac.default_sms_notify') -%]
-[%- sms_carrier = helpers.get_user_setting(user.id, 'opac.default_sms_carrier') -%]
-From: [%- helpers.get_org_setting(homelib.id, 'org.bounced_emails') || homelib.email || params.sender_email || default_sender %]
-To: [%- helpers.get_sms_gateway_email(sms_carrier,sms_number) %]
-Subject: Library Materials Due Soon
-
-You have items due soon:
-
-[% FOR circ IN target %]
-[%- copy_details = helpers.get_copy_bib_basics(circ.target_copy.id) -%]
-[% copy_details.title FILTER ucfirst %] by [% copy_details.author FILTER ucfirst %] due on [% date.format(helpers.format_date(circ.due_date), '%m-%d-%Y') %]
-
-[% END %]
-
-$$);
-
-INSERT INTO action_trigger.environment (event_def, path) VALUES
-    (54, 'circ_lib.billing_address'),
-    (54, 'target_copy.call_number'),
-    (54, 'usr'),
-    (54, 'usr.home_ou');
-
-END IF; END $INSERT$;                                                          
-
-
--- check whether patch can be applied
--- SELECT evergreen.upgrade_deps_block_check('1059', :eg_version); --Stompro/DPearl/kmlussier
-
-CREATE OR REPLACE VIEW reporter.old_super_simple_record AS
-SELECT  r.id,
-    r.fingerprint,
-    r.quality,
-    r.tcn_source,
-    r.tcn_value,
-    CONCAT_WS(' ', FIRST(title.value),FIRST(title_np.val)) AS title,
-    FIRST(author.value) AS author,
-    STRING_AGG(DISTINCT publisher.value, ', ') AS publisher,
-    STRING_AGG(DISTINCT SUBSTRING(pubdate.value FROM $$\d+$$), ', ') AS pubdate,
-    CASE WHEN ARRAY_AGG( DISTINCT REPLACE(SUBSTRING(isbn.value FROM $$^\S+$$), '-', '') ) = '{NULL}'
-        THEN NULL
-        ELSE ARRAY_AGG( DISTINCT REPLACE(SUBSTRING(isbn.value FROM $$^\S+$$), '-', '') )
-    END AS isbn,
-    CASE WHEN ARRAY_AGG( DISTINCT REGEXP_REPLACE(issn.value, E'^\\S*(\\d{4})[-\\s](\\d{3,4}x?)', E'\\1 \\2') ) = '{NULL}'
-        THEN NULL
-        ELSE ARRAY_AGG( DISTINCT REGEXP_REPLACE(issn.value, E'^\\S*(\\d{4})[-\\s](\\d{3,4}x?)', E'\\1 \\2') )
-    END AS issn
-  FROM  biblio.record_entry r
-    LEFT JOIN metabib.full_rec title ON (r.id = title.record AND title.tag = '245' AND title.subfield = 'a')
-    LEFT JOIN ( -- Grab 245 N and P subfields in the order that they appear.
-      SELECT b.record, string_agg(val, ' ') AS val FROM (
-            SELECT title_np.record, title_np.value AS val
-             FROM metabib.full_rec title_np
-             WHERE
-             title_np.tag = '245'
-                       AND title_np.subfield IN ('p','n')                      
-                       ORDER BY title_np.id
-               ) b
-               GROUP BY 1
-        ) title_np ON (title_np.record=r.id) 
-    LEFT JOIN metabib.full_rec author ON (r.id = author.record AND author.tag IN ('100','110','111') AND author.subfield = 'a')
-    LEFT JOIN metabib.full_rec publisher ON (r.id = publisher.record AND (publisher.tag = '260' OR (publisher.tag = '264' AND publisher.ind2 = '1')) AND publisher.subfield = 'b')
-    LEFT JOIN metabib.full_rec pubdate ON (r.id = pubdate.record AND (pubdate.tag = '260' OR (pubdate.tag = '264' AND pubdate.ind2 = '1')) AND pubdate.subfield = 'c')
-    LEFT JOIN metabib.full_rec isbn ON (r.id = isbn.record AND isbn.tag IN ('024', '020') AND isbn.subfield IN ('a','z'))
-    LEFT JOIN metabib.full_rec issn ON (r.id = issn.record AND issn.tag = '022' AND issn.subfield = 'a')
-  GROUP BY 1,2,3,4,5;
-
-  
-  -- Remove trigger on biblio.record_entry
-  SELECT reporter.disable_materialized_simple_record_trigger();
-  
-  -- Rebuild reporter.materialized_simple_record
-  SELECT reporter.enable_materialized_simple_record_trigger();
-  
-
--- SELECT evergreen.upgrade_deps_block_check('1060', :eg_version);
-
-DROP VIEW IF EXISTS extend_reporter.copy_count_per_org;
-
-CREATE OR REPLACE VIEW extend_reporter.copy_count_per_org AS
- SELECT acn.record AS bibid,
-    ac.circ_lib,
-    acn.owning_lib,
-    max(ac.edit_date) AS last_edit_time,
-    min(ac.deleted::integer) AS has_only_deleted_copies,
-    count(
-        CASE
-            WHEN ac.deleted THEN ac.id
-            ELSE NULL::bigint
-        END) AS deleted_count,
-    count(
-        CASE
-            WHEN NOT ac.deleted THEN ac.id
-            ELSE NULL::bigint
-        END) AS visible_count,
-    count(*) AS total_count
-   FROM asset.call_number acn,
-    asset.copy ac
-  WHERE ac.call_number = acn.id
-  GROUP BY acn.record, acn.owning_lib, ac.circ_lib;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1061', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-INSERT INTO config.org_unit_setting_type
-    (name, label, description, grp, datatype)
-VALUES (
-    'ui.staff.max_recent_patrons',
-    oils_i18n_gettext(
-        'ui.staff.max_recent_patrons',
-        'Number of Retrievable Recent Patrons',
-        'coust',
-        'label'
-    ),
-    oils_i18n_gettext(
-        'ui.staff.max_recent_patrons',
-        'Number of most recently accessed patrons that can be re-retrieved ' ||
-        'in the staff client.  A value of 0 or less disables the feature. Defaults to 1.',
-        'coust',
-        'description'
-    ),
-    'circ',
-    'integer'
-);
-
-END IF; END $INSERT$;                                                          
-
--- SELECT evergreen.upgrade_deps_block_check('1062', :eg_version);
-
-CREATE TABLE acq.edi_attr (
-    key     TEXT PRIMARY KEY,
-    label   TEXT NOT NULL UNIQUE
-);
-
-CREATE TABLE acq.edi_attr_set (
-    id      SERIAL  PRIMARY KEY,
-    label   TEXT NOT NULL UNIQUE
-);
-
-CREATE TABLE acq.edi_attr_set_map (
-    id          SERIAL  PRIMARY KEY,
-    attr_set    INTEGER NOT NULL REFERENCES acq.edi_attr_set(id) 
-                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    attr        TEXT NOT NULL REFERENCES acq.edi_attr(key) 
-                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    CONSTRAINT edi_attr_set_map_attr_once UNIQUE (attr_set, attr)
-);
-
--- An attr_set is not strictly required, since some edi_accounts/vendors 
--- may not need to apply any attributes.
-ALTER TABLE acq.edi_account 
-    ADD COLUMN attr_set INTEGER REFERENCES acq.edi_attr_set(id),
-    ADD COLUMN use_attrs BOOLEAN NOT NULL DEFAULT FALSE;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1063', :eg_version);
-
-DO $temp$
-DECLARE
-       r RECORD;
-BEGIN
-
-       FOR r IN SELECT t.table_schema AS sname,
-                       t.table_name AS tname,
-                       t.column_name AS colname,
-                       t.constraint_name
-                 FROM  information_schema.referential_constraints ref
-                       JOIN information_schema.key_column_usage t USING (constraint_schema,constraint_name)
-                 WHERE ref.unique_constraint_schema = 'asset'
-                       AND ref.unique_constraint_name = 'copy_pkey'
-       LOOP
-
-               EXECUTE 'ALTER TABLE '||r.sname||'.'||r.tname||' DROP CONSTRAINT '||r.constraint_name||';';
-
-               EXECUTE '
-                       CREATE OR REPLACE FUNCTION evergreen.'||r.sname||'_'||r.tname||'_'||r.colname||'_inh_fkey() RETURNS TRIGGER AS $f$
-                       BEGIN
-                               PERFORM 1 FROM asset.copy WHERE id = NEW.'||r.colname||';
-                               IF NOT FOUND THEN
-                                       RAISE foreign_key_violation USING MESSAGE = FORMAT(
-                                               $$Referenced asset.copy id not found, '||r.colname||':%s$$, NEW.'||r.colname||'
-                                       );
-                               END IF;
-                               RETURN NEW;
-                       END;
-                       $f$ LANGUAGE PLPGSQL VOLATILE COST 50;
-               ';
-
-               EXECUTE '
-                       CREATE CONSTRAINT TRIGGER inherit_'||r.constraint_name||'
-                               AFTER UPDATE OR INSERT OR DELETE ON '||r.sname||'.'||r.tname||'
-                               DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.'||r.sname||'_'||r.tname||'_'||r.colname||'_inh_fkey();
-               ';
-       END LOOP;
-END
-$temp$;
-
-
-
--- SELECT evergreen.upgrade_deps_block_check('1064', :eg_version);
-
-ALTER TABLE serial.issuance DROP CONSTRAINT IF EXISTS issuance_caption_and_pattern_fkey;
-
--- Using NOT VALID and VALIDATE CONSTRAINT limits the impact to concurrent work.
--- For details, see: https://www.postgresql.org/docs/current/static/sql-altertable.html
-
-ALTER TABLE serial.issuance ADD CONSTRAINT issuance_caption_and_pattern_fkey
-    FOREIGN KEY (caption_and_pattern)
-    REFERENCES serial.caption_and_pattern (id)
-    ON DELETE CASCADE
-    DEFERRABLE INITIALLY DEFERRED
-    NOT VALID;
-
-ALTER TABLE serial.issuance VALIDATE CONSTRAINT issuance_caption_and_pattern_fkey;
-
-
-
--- SELECT evergreen.upgrade_deps_block_check('1065', :eg_version);
-
-CREATE TABLE serial.pattern_template (
-    id            SERIAL PRIMARY KEY,
-    name          TEXT NOT NULL,
-    pattern_code  TEXT NOT NULL,
-    owning_lib    INTEGER REFERENCES actor.org_unit(id) DEFERRABLE INITIALLY DEFERRED,
-    share_depth   INTEGER NOT NULL DEFAULT 0
-);
-CREATE INDEX serial_pattern_template_name_idx ON serial.pattern_template (evergreen.lowercase(name));
-
-CREATE OR REPLACE FUNCTION serial.pattern_templates_visible_to(org_unit INT) RETURNS SETOF serial.pattern_template AS $func$
-BEGIN
-    RETURN QUERY SELECT *
-           FROM serial.pattern_template spt
-           WHERE (
-             SELECT ARRAY_AGG(id)
-             FROM actor.org_unit_descendants(spt.owning_lib, spt.share_depth)
-           ) @@ org_unit::TEXT::QUERY_INT;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1066', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-INSERT INTO permission.perm_list ( id, code, description ) VALUES
- ( 593, 'ADMIN_SERIAL_PATTERN_TEMPLATE', oils_i18n_gettext( 593,
-    'Administer serial prediction pattern templates', 'ppl', 'description' ))
-;
-
-INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
-    SELECT
-        pgt.id, perm.id, aout.depth, FALSE
-    FROM
-        permission.grp_tree pgt,
-        permission.perm_list perm,
-        actor.org_unit_type aout
-    WHERE
-        pgt.name = 'Serials' AND
-        aout.name = 'System' AND
-        perm.code IN (
-            'ADMIN_SERIAL_PATTERN_TEMPLATE'
-        );
-
-
--- SELECT evergreen.upgrade_deps_block_check('1067', :eg_version);
-
-INSERT INTO acq.edi_attr (key, label) VALUES
-    ('INCLUDE_PO_NAME', 
-        oils_i18n_gettext('INCLUDE_PO_NAME', 
-        'Orders Include PO Name', 'aea', 'label')),
-    ('INCLUDE_COPIES', 
-        oils_i18n_gettext('INCLUDE_COPIES', 
-        'Orders Include Copy Data', 'aea', 'label')),
-    ('INCLUDE_FUND', 
-        oils_i18n_gettext('INCLUDE_FUND', 
-        'Orders Include Copy Funds', 'aea', 'label')),
-    ('INCLUDE_CALL_NUMBER', 
-        oils_i18n_gettext('INCLUDE_CALL_NUMBER', 
-        'Orders Include Copy Call Numbers', 'aea', 'label')),
-    ('INCLUDE_ITEM_TYPE', 
-        oils_i18n_gettext('INCLUDE_ITEM_TYPE', 
-        'Orders Include Copy Item Types', 'aea', 'label')),
-    ('INCLUDE_ITEM_BARCODE',
-        oils_i18n_gettext('INCLUDE_ITEM_BARCODE',
-        'Orders Include Copy Barcodes', 'aea', 'label')),
-    ('INCLUDE_LOCATION', 
-        oils_i18n_gettext('INCLUDE_LOCATION', 
-        'Orders Include Copy Locations', 'aea', 'label')),
-    ('INCLUDE_COLLECTION_CODE', 
-        oils_i18n_gettext('INCLUDE_COLLECTION_CODE', 
-        'Orders Include Copy Collection Codes', 'aea', 'label')),
-    ('INCLUDE_OWNING_LIB', 
-        oils_i18n_gettext('INCLUDE_OWNING_LIB', 
-        'Orders Include Copy Owning Library', 'aea', 'label')),
-    ('USE_ID_FOR_OWNING_LIB',
-        oils_i18n_gettext('USE_ID_FOR_OWNING_LIB',
-        'Emit Owning Library ID Rather Than Short Name. Takes effect only if INCLUDE_OWNING_LIB is in use', 'aea', 'label')),
-    ('INCLUDE_QUANTITY', 
-        oils_i18n_gettext('INCLUDE_QUANTITY', 
-        'Orders Include Copy Quantities', 'aea', 'label')),
-    ('INCLUDE_COPY_ID', 
-        oils_i18n_gettext('INCLUDE_COPY_ID', 
-        'Orders Include Copy IDs', 'aea', 'label')),
-    ('BUYER_ID_INCLUDE_VENDCODE', 
-        oils_i18n_gettext('BUYER_ID_INCLUDE_VENDCODE', 
-        'Buyer ID Qualifier Includes Vendcode', 'aea', 'label')),
-    ('BUYER_ID_ONLY_VENDCODE', 
-        oils_i18n_gettext('BUYER_ID_ONLY_VENDCODE', 
-        'Buyer ID Qualifier Only Contains Vendcode', 'aea', 'label')),
-    ('INCLUDE_BIB_EDITION', 
-        oils_i18n_gettext('INCLUDE_BIB_EDITION', 
-        'Order Lineitems Include Edition Info', 'aea', 'label')),
-    ('INCLUDE_BIB_AUTHOR', 
-        oils_i18n_gettext('INCLUDE_BIB_AUTHOR', 
-        'Order Lineitems Include Author Info', 'aea', 'label')),
-    ('INCLUDE_BIB_PAGINATION', 
-        oils_i18n_gettext('INCLUDE_BIB_PAGINATION', 
-        'Order Lineitems Include Pagination Info', 'aea', 'label')),
-    ('COPY_SPEC_CODES', 
-        oils_i18n_gettext('COPY_SPEC_CODES', 
-        'Order Lineitem Notes Include Copy Spec Codes', 'aea', 'label')),
-    ('INCLUDE_EMPTY_IMD_VALUES', 
-        oils_i18n_gettext('INCLUDE_EMPTY_IMD_VALUES',
-        'Lineitem Title, Author, etc. Fields Are Present Even if Empty', 'aea', 'label')),
-    ('INCLUDE_EMPTY_LI_NOTE', 
-        oils_i18n_gettext('INCLUDE_EMPTY_LI_NOTE', 
-        'Order Lineitem Notes Always Present (Even if Empty)', 'aea', 'label')),
-    ('INCLUDE_EMPTY_CALL_NUMBER', 
-        oils_i18n_gettext('INCLUDE_EMPTY_CALL_NUMBER', 
-        'Order Copies Always Include Call Number (Even if Empty)', 'aea', 'label')),
-    ('INCLUDE_EMPTY_ITEM_TYPE', 
-        oils_i18n_gettext('INCLUDE_EMPTY_ITEM_TYPE', 
-        'Order Copies Always Include Item Type (Even if Empty)', 'aea', 'label')),
-    ('INCLUDE_EMPTY_LOCATION', 
-        oils_i18n_gettext('INCLUDE_EMPTY_LOCATION', 
-        'Order Copies Always Include Location (Even if Empty)', 'aea', 'label')),
-    ('INCLUDE_EMPTY_COLLECTION_CODE', 
-        oils_i18n_gettext('INCLUDE_EMPTY_COLLECTION_CODE', 
-        'Order Copies Always Include Collection Code (Even if Empty)', 'aea', 'label')),
-    ('LINEITEM_IDENT_VENDOR_NUMBER',
-        oils_i18n_gettext('LINEITEM_IDENT_VENDOR_NUMBER',
-        'Lineitem Identifier Fields (LIN/PIA) Use Vendor-Encoded ID Value When Available', 'aea', 'label')),
-    ('LINEITEM_REF_ID_ONLY',
-        oils_i18n_gettext('LINEITEM_REF_ID_ONLY',
-        'Lineitem Reference Field (RFF) Uses Lineitem ID Only', 'aea', 'label'))
-
-;
-
-INSERT INTO acq.edi_attr_set (id, label) VALUES (1, 'Ingram Default');
-INSERT INTO acq.edi_attr_set (id, label) VALUES (2, 'Baker & Taylor Default');
-INSERT INTO acq.edi_attr_set (id, label) VALUES (3, 'Brodart Default');
-INSERT INTO acq.edi_attr_set (id, label) VALUES (4, 'Midwest Tape Default');
-INSERT INTO acq.edi_attr_set (id, label) VALUES (5, 'ULS Default');
-INSERT INTO acq.edi_attr_set (id, label) VALUES (6, 'Recorded Books Default');
-INSERT INTO acq.edi_attr_set (id, label) VALUES (7, 'Midwest Library Service');
-
--- carve out space for mucho defaults
-PERFORM SETVAL('acq.edi_attr_set_id_seq'::TEXT, 1000);
-
-INSERT INTO acq.edi_attr_set_map (attr_set, attr) VALUES
-
-    -- Ingram
-    (1, 'INCLUDE_PO_NAME'),
-    (1, 'INCLUDE_COPIES'),
-    (1, 'INCLUDE_ITEM_TYPE'),
-    (1, 'INCLUDE_COLLECTION_CODE'),
-    (1, 'INCLUDE_OWNING_LIB'),
-    (1, 'INCLUDE_QUANTITY'),
-    (1, 'INCLUDE_BIB_PAGINATION'),
-
-    -- B&T
-    (2, 'INCLUDE_COPIES'),
-    (2, 'INCLUDE_ITEM_TYPE'),
-    (2, 'INCLUDE_COLLECTION_CODE'),
-    (2, 'INCLUDE_CALL_NUMBER'),
-    (2, 'INCLUDE_OWNING_LIB'),
-    (2, 'INCLUDE_QUANTITY'),
-    (2, 'INCLUDE_BIB_PAGINATION'),
-    (2, 'BUYER_ID_INCLUDE_VENDCODE'),
-    (2, 'INCLUDE_EMPTY_LI_NOTE'),
-    (2, 'INCLUDE_EMPTY_CALL_NUMBER'),
-    (2, 'INCLUDE_EMPTY_ITEM_TYPE'),
-    (2, 'INCLUDE_EMPTY_COLLECTION_CODE'),
-    (2, 'INCLUDE_EMPTY_LOCATION'),
-    (2, 'LINEITEM_IDENT_VENDOR_NUMBER'),
-    (2, 'LINEITEM_REF_ID_ONLY'),
-
-    -- Brodart
-    (3, 'INCLUDE_COPIES'),
-    (3, 'INCLUDE_FUND'),
-    (3, 'INCLUDE_ITEM_TYPE'),
-    (3, 'INCLUDE_COLLECTION_CODE'),
-    (3, 'INCLUDE_OWNING_LIB'),
-    (3, 'INCLUDE_QUANTITY'),
-    (3, 'INCLUDE_BIB_PAGINATION'),
-    (3, 'COPY_SPEC_CODES'),
-
-    -- Midwest
-    (4, 'INCLUDE_COPIES'),
-    (4, 'INCLUDE_FUND'),
-    (4, 'INCLUDE_OWNING_LIB'),
-    (4, 'INCLUDE_QUANTITY'),
-    (4, 'INCLUDE_BIB_PAGINATION'),
-
-    -- ULS
-    (5, 'INCLUDE_COPIES'),
-    (5, 'INCLUDE_ITEM_TYPE'),
-    (5, 'INCLUDE_COLLECTION_CODE'),
-    (5, 'INCLUDE_OWNING_LIB'),
-    (5, 'INCLUDE_QUANTITY'),
-    (5, 'INCLUDE_BIB_AUTHOR'),
-    (5, 'INCLUDE_BIB_EDITION'),
-    (5, 'INCLUDE_EMPTY_LI_NOTE'),
-
-    -- Recorded Books
-    (6, 'INCLUDE_COPIES'),
-    (6, 'INCLUDE_ITEM_TYPE'),
-    (6, 'INCLUDE_COLLECTION_CODE'),
-    (6, 'INCLUDE_OWNING_LIB'),
-    (6, 'INCLUDE_QUANTITY'),
-    (6, 'INCLUDE_BIB_PAGINATION'),
-
-    -- Midwest Library Service
-    (7, 'INCLUDE_BIB_AUTHOR'),
-    (7, 'INCLUDE_BIB_EDITION'),
-    (7, 'BUYER_ID_ONLY_VENDCODE'),
-    (7, 'INCLUDE_EMPTY_IMD_VALUES')
-;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1068', :eg_version); --miker/gmcharlt/kmlussier
-
-INSERT INTO config.xml_transform (name,namespace_uri,prefix,xslt) VALUES ('mads21','http://www.loc.gov/mads/v2','mads21',$XSLT$<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0" xmlns:mads="http://www.loc.gov/mads/v2"
-       xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim"
-       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
-       <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
-       <xsl:strip-space elements="*"/>
-
-       <xsl:variable name="ascii">
-               <xsl:text> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
-       </xsl:variable>
-
-       <xsl:variable name="latin1">
-               <xsl:text> ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
-       </xsl:variable>
-       <!-- Characters that usually don't need to be escaped -->
-       <xsl:variable name="safe">
-               <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
-       </xsl:variable>
-
-       <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
-
-
-       <xsl:template name="datafield">
-               <xsl:param name="tag"/>
-               <xsl:param name="ind1">
-                       <xsl:text> </xsl:text>
-               </xsl:param>
-               <xsl:param name="ind2">
-                       <xsl:text> </xsl:text>
-               </xsl:param>
-               <xsl:param name="subfields"/>
-               <xsl:element name="marc:datafield">
-                       <xsl:attribute name="tag">
-                               <xsl:value-of select="$tag"/>
-                       </xsl:attribute>
-                       <xsl:attribute name="ind1">
-                               <xsl:value-of select="$ind1"/>
-                       </xsl:attribute>
-                       <xsl:attribute name="ind2">
-                               <xsl:value-of select="$ind2"/>
-                       </xsl:attribute>
-                       <xsl:copy-of select="$subfields"/>
-               </xsl:element>
-       </xsl:template>
-
-       <xsl:template name="subfieldSelect">
-               <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
-               <xsl:param name="delimeter">
-                       <xsl:text> </xsl:text>
-               </xsl:param>
-               <xsl:variable name="str">
-                       <xsl:for-each select="marc:subfield">
-                               <xsl:if test="contains($codes, @code)">
-                                       <xsl:value-of select="text()"/>
-                                       <xsl:value-of select="$delimeter"/>
-                               </xsl:if>
-                       </xsl:for-each>
-               </xsl:variable>
-               <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
-       </xsl:template>
-
-       <xsl:template name="buildSpaces">
-               <xsl:param name="spaces"/>
-               <xsl:param name="char">
-                       <xsl:text> </xsl:text>
-               </xsl:param>
-               <xsl:if test="$spaces>0">
-                       <xsl:value-of select="$char"/>
-                       <xsl:call-template name="buildSpaces">
-                               <xsl:with-param name="spaces" select="$spaces - 1"/>
-                               <xsl:with-param name="char" select="$char"/>
-                       </xsl:call-template>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="chopPunctuation">
-               <xsl:param name="chopString"/>
-               <xsl:param name="punctuation">
-                       <xsl:text>.:,;/ </xsl:text>
-               </xsl:param>
-               <xsl:variable name="length" select="string-length($chopString)"/>
-               <xsl:choose>
-                       <xsl:when test="$length=0"/>
-                       <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
-                                       <xsl:with-param name="punctuation" select="$punctuation"/>
-                               </xsl:call-template>
-                       </xsl:when>
-                       <xsl:when test="not($chopString)"/>
-                       <xsl:otherwise>
-                               <xsl:value-of select="$chopString"/>
-                       </xsl:otherwise>
-               </xsl:choose>
-       </xsl:template>
-
-       <xsl:template name="chopPunctuationFront">
-               <xsl:param name="chopString"/>
-               <xsl:variable name="length" select="string-length($chopString)"/>
-               <xsl:choose>
-                       <xsl:when test="$length=0"/>
-                       <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
-                               <xsl:call-template name="chopPunctuationFront">
-                                       <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
-                                       />
-                               </xsl:call-template>
-                       </xsl:when>
-                       <xsl:when test="not($chopString)"/>
-                       <xsl:otherwise>
-                               <xsl:value-of select="$chopString"/>
-                       </xsl:otherwise>
-               </xsl:choose>
-       </xsl:template>
-
-       <xsl:template name="chopPunctuationBack">
-               <xsl:param name="chopString"/>
-               <xsl:param name="punctuation">
-                       <xsl:text>.:,;/] </xsl:text>
-               </xsl:param>
-               <xsl:variable name="length" select="string-length($chopString)"/>
-               <xsl:choose>
-                       <xsl:when test="$length=0"/>
-                       <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
-                                       <xsl:with-param name="punctuation" select="$punctuation"/>
-                               </xsl:call-template>
-                       </xsl:when>
-                       <xsl:when test="not($chopString)"/>
-                       <xsl:otherwise>
-                               <xsl:value-of select="$chopString"/>
-                       </xsl:otherwise>
-               </xsl:choose>
-       </xsl:template>
-
-       <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
-       <xsl:template name="url-encode">
-
-               <xsl:param name="str"/>
-
-               <xsl:if test="$str">
-                       <xsl:variable name="first-char" select="substring($str,1,1)"/>
-                       <xsl:choose>
-                               <xsl:when test="contains($safe,$first-char)">
-                                       <xsl:value-of select="$first-char"/>
-                               </xsl:when>
-                               <xsl:otherwise>
-                                       <xsl:variable name="codepoint">
-                                               <xsl:choose>
-                                                       <xsl:when test="contains($ascii,$first-char)">
-                                                               <xsl:value-of
-                                                                       select="string-length(substring-before($ascii,$first-char)) + 32"
-                                                               />
-                                                       </xsl:when>
-                                                       <xsl:when test="contains($latin1,$first-char)">
-                                                               <xsl:value-of
-                                                                       select="string-length(substring-before($latin1,$first-char)) + 160"/>
-                                                               <!-- was 160 -->
-                                                       </xsl:when>
-                                                       <xsl:otherwise>
-                                                               <xsl:message terminate="no">Warning: string contains a character
-                                                                       that is out of range! Substituting "?".</xsl:message>
-                                                               <xsl:text>63</xsl:text>
-                                                       </xsl:otherwise>
-                                               </xsl:choose>
-                                       </xsl:variable>
-                                       <xsl:variable name="hex-digit1"
-                                               select="substring($hex,floor($codepoint div 16) + 1,1)"/>
-                                       <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
-                                       <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
-                                       <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
-                               </xsl:otherwise>
-                       </xsl:choose>
-                       <xsl:if test="string-length($str) &gt; 1">
-                               <xsl:call-template name="url-encode">
-                                       <xsl:with-param name="str" select="substring($str,2)"/>
-                               </xsl:call-template>
-                       </xsl:if>
-               </xsl:if>
-       </xsl:template>
-
-
-<!--
-2.14    Fixed bug in mads:geographic attributes syntax                                      ws   05/04/2016            
-2.13   fixed repeating <geographic>                                                                                                            tmee 01/31/2014
-2.12   added $2 authority for <classification>                                                                                         tmee 09/18/2012
-2.11   added delimiters between <classification> subfields                                                                     tmee 09/18/2012
-2.10   fixed type="other" and type="otherType" for mads:related                                                        tmee 09/16/2011
-2.09   fixed professionTerm and genreTerm empty tag error                                                                      tmee 09/16/2011
-2.08   fixed marc:subfield @code='i' matching error                                                                            tmee 09/16/2011
-2.07   fixed 555 duplication error                                                                                                                     tmee 08/10/2011 
-2.06   fixed topic subfield error                                                                                                                      tmee 08/10/2011 
-2.05   fixed title subfield error                                                                                                                      tmee 06/20/2011 
-2.04   fixed geographicSubdivision mapping for authority element                                                       tmee 06/16/2011
-2.03   added classification for 053, 055, 060, 065, 070, 080, 082, 083, 086, 087                       tmee 06/03/2011         
-2.02   added descriptionStandard for 008/10                                                                                            tmee 04/27/2011
-2.01   added extensions for 046, 336, 370, 374, 375, 376                                                                       tmee 04/08/2011
-2.00   redefined imported MODS elements in version 1.0 to MADS elements in version 2.0         tmee 02/08/2011
-1.08   added 372 subfields $a $s $t for <fieldOfActivity>                                                                      tmee 06/24/2010
-1.07   removed role/roleTerm 100, 110, 111, 400, 410, 411, 500, 510, 511, 700, 710, 711        tmee 06/24/2010
-1.06   added strip-space                                                                                                                                       tmee 06/24/2010
-1.05   added subfield $a for 130, 430, 530                                                                                                     tmee 06/21/2010
-1.04   fixed 550 z omission                                                                                                                            ntra 08/11/2008
-1.03   removed duplication of 550 $a text                                                                                                      tmee 11/01/2006
-1.02   fixed namespace references between mads and mods                                                                        ntra 10/06/2006
-1.01   revised                                                                                                                                                         rgue/jrad 11/29/05
-1.00   adapted from MARC21Slim2MODS3.xsl                                                                                                       ntra 07/06/05
--->
-
-       <!-- authority attribute defaults to 'naf' if not set using this authority parameter, for <authority> descriptors: name, titleInfo, geographic -->
-       <xsl:param name="authority"/>
-       <xsl:variable name="auth">
-               <xsl:choose>
-                       <xsl:when test="$authority">
-                               <xsl:value-of select="$authority"/>
-                       </xsl:when>
-                       <xsl:otherwise>naf</xsl:otherwise>
-               </xsl:choose>
-       </xsl:variable>
-       <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
-       <xsl:variable name="controlField008-06"
-               select="substring(descendant-or-self::marc:controlfield[@tag=008],7,1)"/>
-       <xsl:variable name="controlField008-11"
-               select="substring(descendant-or-self::marc:controlfield[@tag=008],12,1)"/>
-       <xsl:variable name="controlField008-14"
-               select="substring(descendant-or-self::marc:controlfield[@tag=008],15,1)"/>
-       <xsl:template match="/">
-               <xsl:choose>
-                       <xsl:when test="descendant-or-self::marc:collection">
-                               <mads:madsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-                                       xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/v2/mads-2-0.xsd">
-                                       <xsl:for-each select="descendant-or-self::marc:collection/marc:record">
-                                               <mads:mads version="2.0">
-                                                       <xsl:call-template name="marcRecord"/>
-                                               </mads:mads>
-                                       </xsl:for-each>
-                               </mads:madsCollection>
-                       </xsl:when>
-                       <xsl:otherwise>
-                               <mads:mads version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-                                       xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/mads-2-0.xsd">
-                                       <xsl:for-each select="descendant-or-self::marc:record">
-                                               <xsl:call-template name="marcRecord"/>
-                                       </xsl:for-each>
-                               </mads:mads>
-                       </xsl:otherwise>
-               </xsl:choose>
-       </xsl:template>
-
-       <xsl:template name="marcRecord">
-               <mads:authority>
-                       <!-- 2.04 -->
-                       <xsl:choose>
-                               <xsl:when test="$controlField008-06='d'">
-                                       <xsl:attribute name="geographicSubdivision">
-                                               <xsl:text>direct</xsl:text>
-                                       </xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="$controlField008-06='i'">
-                                       <xsl:attribute name="geographicSubdivision">
-                                               <xsl:text>indirect</xsl:text>
-                                       </xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="$controlField008-06='n'">
-                                       <xsl:attribute name="geographicSubdivision">
-                                               <xsl:text>not applicable</xsl:text>
-                                       </xsl:attribute>
-                               </xsl:when>
-                       </xsl:choose>
-                       
-                       <xsl:apply-templates select="marc:datafield[100 &lt;= @tag  and @tag &lt; 200]"/>               
-               </mads:authority>
-
-               <!-- related -->
-               <xsl:apply-templates
-                       select="marc:datafield[500 &lt;= @tag and @tag &lt;= 585]|marc:datafield[700 &lt;= @tag and @tag &lt;= 785]"/>
-
-               <!-- variant -->
-               <xsl:apply-templates select="marc:datafield[400 &lt;= @tag and @tag &lt;= 485]"/>
-
-               <!-- notes -->
-               <xsl:apply-templates select="marc:datafield[667 &lt;= @tag and @tag &lt;= 688]"/>
-
-               <!-- url -->
-               <xsl:apply-templates select="marc:datafield[@tag=856]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=010]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=024]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=372]"/>
-               
-               <!-- classification -->
-               <xsl:apply-templates select="marc:datafield[@tag=053]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=055]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=060]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=065]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=070]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=080]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=082]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=083]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=086]"/>
-               <xsl:apply-templates select="marc:datafield[@tag=087]"/>
-
-               <!-- affiliation-->
-               <xsl:for-each select="marc:datafield[@tag=373]">
-                       <mads:affiliation>
-                               <mads:position>
-                                       <xsl:value-of select="marc:subfield[@code='a']"/>
-                               </mads:position>
-                               <mads:dateValid point="start">
-                                       <xsl:value-of select="marc:subfield[@code='s']"/>
-                               </mads:dateValid>
-                               <mads:dateValid point="end">
-                                       <xsl:value-of select="marc:subfield[@code='t']"/>
-                               </mads:dateValid>
-                       </mads:affiliation>
-               </xsl:for-each>
-               <xsl:for-each select="marc:datafield[@tag=371]">
-                       <mads:affiliation>
-                               <mads:address>
-                                       <mads:street>
-                                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                                       </mads:street>
-                                       <mads:city>
-                                               <xsl:value-of select="marc:subfield[@code='b']"/>
-                                       </mads:city>
-                                       <mads:state>
-                                               <xsl:value-of select="marc:subfield[@code='c']"/>
-                                       </mads:state>
-                                       <mads:country>
-                                               <xsl:value-of select="marc:subfield[@code='d']"/>
-                                       </mads:country>
-                                       <mads:postcode>
-                                               <xsl:value-of select="marc:subfield[@code='e']"/>
-                                       </mads:postcode>
-                               </mads:address>
-                               <mads:email>
-                                       <xsl:value-of select="marc:subfield[@code='m']"/>
-                               </mads:email>
-                       </mads:affiliation>
-               </xsl:for-each>
-
-               <!-- extension-->
-               <xsl:for-each select="marc:datafield[@tag=336]">
-                       <mads:extension>
-                               <mads:contentType>
-                                       <mads:contentType type="text">
-                                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                                       </mads:contentType>
-                                       <mads:contentType type="code">
-                                               <xsl:value-of select="marc:subfield[@code='b']"/>
-                                       </mads:contentType>
-                               </mads:contentType>
-                       </mads:extension>
-               </xsl:for-each>
-
-               <xsl:for-each select="marc:datafield[@tag=374]">
-                       <mads:extension>
-                               <mads:profession>
-                                       <xsl:choose>
-                                               <xsl:when test="marc:subfield[@code='a']">
-                                                       <mads:professionTerm>
-                                                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                                                       </mads:professionTerm>
-                                               </xsl:when>
-                                               <xsl:when test="marc:subfield[@code='s']">
-                                                       <mads:dateValid point="start">
-                                                               <xsl:value-of select="marc:subfield[@code='s']"/>
-                                                       </mads:dateValid>
-                                               </xsl:when>
-                                               <xsl:when test="marc:subfield[@code='t']">
-                                                       <mads:dateValid point="end">
-                                                               <xsl:value-of select="marc:subfield[@code='t']"/>
-                                                       </mads:dateValid>
-                                               </xsl:when>
-                                       </xsl:choose>
-                               </mads:profession>
-                       </mads:extension>
-               </xsl:for-each>
-               
-               <xsl:for-each select="marc:datafield[@tag=375]">
-                       <mads:extension>
-                               <mads:gender>
-                                       <xsl:choose>
-                                               <xsl:when test="marc:subfield[@code='a']">
-                                                       <mads:genderTerm>
-                                                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                                                       </mads:genderTerm>
-                                               </xsl:when>
-                                               <xsl:when test="marc:subfield[@code='s']">
-                                                       <mads:dateValid point="start">
-                                                               <xsl:value-of select="marc:subfield[@code='s']"/>
-                                                       </mads:dateValid>
-                                               </xsl:when>
-                                               <xsl:when test="marc:subfield[@code='t']">
-                                                       <mads:dateValid point="end">
-                                                               <xsl:value-of select="marc:subfield[@code='t']"/>
-                                                       </mads:dateValid>
-                                               </xsl:when>
-                                       </xsl:choose>
-                               </mads:gender>
-                       </mads:extension>
-               </xsl:for-each>
-
-               <xsl:for-each select="marc:datafield[@tag=376]">
-                       <mads:extension>
-                               <mads:familyInformation>
-                                       <mads:typeOfFamily>
-                                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                                       </mads:typeOfFamily>
-                                       <mads:nameOfProminentMember>
-                                               <xsl:value-of select="marc:subfield[@code='b']"/>
-                                       </mads:nameOfProminentMember>
-                                       <mads:hereditaryTitle>
-                                               <xsl:value-of select="marc:subfield[@code='c']"/>
-                                       </mads:hereditaryTitle>
-                                       <mads:dateValid point="start">
-                                               <xsl:value-of select="marc:subfield[@code='s']"/>
-                                       </mads:dateValid>
-                                       <mads:dateValid point="end">
-                                               <xsl:value-of select="marc:subfield[@code='t']"/>
-                                       </mads:dateValid>
-                               </mads:familyInformation>
-                       </mads:extension>
-               </xsl:for-each>
-
-               <mads:recordInfo>
-                       <mads:recordOrigin>Converted from MARCXML to MADS version 2.0 (Revision 2.13)</mads:recordOrigin>
-                       <!-- <xsl:apply-templates select="marc:datafield[@tag=024]"/> -->
-
-                       <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='a']"/>
-                       <xsl:apply-templates select="marc:controlfield[@tag=005]"/>
-                       <xsl:apply-templates select="marc:controlfield[@tag=001]"/>
-                       <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='b']"/>
-                       <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='e']"/>
-                       <xsl:for-each select="marc:controlfield[@tag=008]">
-                               <xsl:if test="substring(.,11,1)='a'">
-                                       <mads:descriptionStandard>
-                                               <xsl:text>earlier rules</xsl:text>
-                                       </mads:descriptionStandard>
-                               </xsl:if>
-                               <xsl:if test="substring(.,11,1)='b'">
-                                       <mads:descriptionStandard>
-                                               <xsl:text>aacr1</xsl:text>
-                                       </mads:descriptionStandard>
-                               </xsl:if>
-                               <xsl:if test="substring(.,11,1)='c'">
-                                       <mads:descriptionStandard>
-                                               <xsl:text>aacr2</xsl:text>
-                                       </mads:descriptionStandard>
-                               </xsl:if>
-                               <xsl:if test="substring(.,11,1)='d'">
-                                       <mads:descriptionStandard>
-                                               <xsl:text>aacr2 compatible</xsl:text>
-                                       </mads:descriptionStandard>
-                               </xsl:if>
-                               <xsl:if test="substring(.,11,1)='z'">
-                                       <mads:descriptionStandard>
-                                               <xsl:text>other rules</xsl:text>
-                                       </mads:descriptionStandard>
-                               </xsl:if>
-                       </xsl:for-each>
-               </mads:recordInfo>
-       </xsl:template>
-
-       <!-- start of secondary templates -->
-
-       <!-- ======== xlink ======== -->
-
-       <!-- <xsl:template name="uri"> 
-    <xsl:for-each select="marc:subfield[@code='0']">
-      <xsl:attribute name="xlink:href">
-       <xsl:value-of select="."/>
-      </xsl:attribute>
-    </xsl:for-each>
-     </xsl:template> 
-   -->
-       <xsl:template match="marc:subfield[@code='i']">
-               <xsl:attribute name="otherType">
-                       <xsl:value-of select="."/>
-               </xsl:attribute>
-       </xsl:template>
-
-       <!-- No role/roleTerm mapped in MADS 06/24/2010
-       <xsl:template name="role">
-               <xsl:for-each select="marc:subfield[@code='e']">
-                       <mads:role>
-                               <mads:roleTerm type="text">
-                                       <xsl:value-of select="."/>
-                               </mads:roleTerm>
-                       </mads:role>
-               </xsl:for-each>
-       </xsl:template>
--->
-
-       <xsl:template name="part">
-               <xsl:variable name="partNumber">
-                       <xsl:call-template name="specialSubfieldSelect">
-                               <xsl:with-param name="axis">n</xsl:with-param>
-                               <xsl:with-param name="anyCodes">n</xsl:with-param>
-                               <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
-                       </xsl:call-template>
-               </xsl:variable>
-               <xsl:variable name="partName">
-                       <xsl:call-template name="specialSubfieldSelect">
-                               <xsl:with-param name="axis">p</xsl:with-param>
-                               <xsl:with-param name="anyCodes">p</xsl:with-param>
-                               <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
-                       </xsl:call-template>
-               </xsl:variable>
-               <xsl:if test="string-length(normalize-space($partNumber))">
-                       <mads:partNumber>
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString" select="$partNumber"/>
-                               </xsl:call-template>
-                       </mads:partNumber>
-               </xsl:if>
-               <xsl:if test="string-length(normalize-space($partName))">
-                       <mads:partName>
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString" select="$partName"/>
-                               </xsl:call-template>
-                       </mads:partName>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="nameABCDN">
-               <xsl:for-each select="marc:subfield[@code='a']">
-                       <mads:namePart>
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString" select="."/>
-                               </xsl:call-template>
-                       </mads:namePart>
-               </xsl:for-each>
-               <xsl:for-each select="marc:subfield[@code='b']">
-                       <mads:namePart>
-                               <xsl:value-of select="."/>
-                       </mads:namePart>
-               </xsl:for-each>
-               <xsl:if
-                       test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
-                       <mads:namePart>
-                               <xsl:call-template name="subfieldSelect">
-                                       <xsl:with-param name="codes">cdn</xsl:with-param>
-                               </xsl:call-template>
-                       </mads:namePart>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="nameABCDQ">
-               <mads:namePart>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:call-template name="subfieldSelect">
-                                               <xsl:with-param name="codes">aq</xsl:with-param>
-                                       </xsl:call-template>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:namePart>
-               <xsl:call-template name="termsOfAddress"/>
-               <xsl:call-template name="nameDate"/>
-       </xsl:template>
-
-       <xsl:template name="nameACDENQ">
-               <mads:namePart>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">acdenq</xsl:with-param>
-                       </xsl:call-template>
-               </mads:namePart>
-       </xsl:template>
-
-       <xsl:template name="nameDate">
-               <xsl:for-each select="marc:subfield[@code='d']">
-                       <mads:namePart type="date">
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString" select="."/>
-                               </xsl:call-template>
-                       </mads:namePart>
-               </xsl:for-each>
-       </xsl:template>
-
-       <xsl:template name="specialSubfieldSelect">
-               <xsl:param name="anyCodes"/>
-               <xsl:param name="axis"/>
-               <xsl:param name="beforeCodes"/>
-               <xsl:param name="afterCodes"/>
-               <xsl:variable name="str">
-                       <xsl:for-each select="marc:subfield">
-                               <xsl:if
-                                       test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
-                                       <xsl:value-of select="text()"/>
-                                       <xsl:text> </xsl:text>
-                               </xsl:if>
-                       </xsl:for-each>
-               </xsl:variable>
-               <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-       </xsl:template>
-
-       <xsl:template name="termsOfAddress">
-               <xsl:if test="marc:subfield[@code='b' or @code='c']">
-                       <mads:namePart type="termsOfAddress">
-                               <xsl:call-template name="chopPunctuation">
-                                       <xsl:with-param name="chopString">
-                                               <xsl:call-template name="subfieldSelect">
-                                                       <xsl:with-param name="codes">bc</xsl:with-param>
-                                               </xsl:call-template>
-                                       </xsl:with-param>
-                               </xsl:call-template>
-                       </mads:namePart>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="displayLabel">
-               <xsl:if test="marc:subfield[@code='z']">
-                       <xsl:attribute name="displayLabel">
-                               <xsl:value-of select="marc:subfield[@code='z']"/>
-                       </xsl:attribute>
-               </xsl:if>
-               <xsl:if test="marc:subfield[@code='3']">
-                       <xsl:attribute name="displayLabel">
-                               <xsl:value-of select="marc:subfield[@code='3']"/>
-                       </xsl:attribute>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="isInvalid">
-               <xsl:if test="@code='z'">
-                       <xsl:attribute name="invalid">yes</xsl:attribute>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="sub2Attribute">
-               <!-- 024 -->
-               <xsl:if test="../marc:subfield[@code='2']">
-                       <xsl:attribute name="type">
-                               <xsl:value-of select="../marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template match="marc:controlfield[@tag=001]">
-               <mads:recordIdentifier>
-                       <xsl:if test="../marc:controlfield[@tag=003]">
-                               <xsl:attribute name="source">
-                                       <xsl:value-of select="../marc:controlfield[@tag=003]"/>
-                               </xsl:attribute>
-                       </xsl:if>
-                       <xsl:value-of select="."/>
-               </mads:recordIdentifier>
-       </xsl:template>
-
-       <xsl:template match="marc:controlfield[@tag=005]">
-               <mads:recordChangeDate encoding="iso8601">
-                       <xsl:value-of select="."/>
-               </mads:recordChangeDate>
-       </xsl:template>
-
-       <xsl:template match="marc:controlfield[@tag=008]">
-               <mads:recordCreationDate encoding="marc">
-                       <xsl:value-of select="substring(.,1,6)"/>
-               </mads:recordCreationDate>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=010]">
-               <xsl:for-each select="marc:subfield">
-                       <mads:identifier type="lccn">
-                               <xsl:call-template name="isInvalid"/>
-                               <xsl:value-of select="."/>
-                       </mads:identifier>
-               </xsl:for-each>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=024]">
-               <xsl:for-each select="marc:subfield[not(@code=2)]">
-                       <mads:identifier>
-                               <xsl:call-template name="isInvalid"/>
-                               <xsl:call-template name="sub2Attribute"/>
-                               <xsl:value-of select="."/>
-                       </mads:identifier>
-               </xsl:for-each>
-       </xsl:template>
-
-       <!-- ========== 372 ========== -->
-       <xsl:template match="marc:datafield[@tag=372]">
-               <mads:fieldOfActivity>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">a</xsl:with-param>
-                       </xsl:call-template>
-                       <xsl:text>-</xsl:text>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">st</xsl:with-param>
-                       </xsl:call-template>
-               </mads:fieldOfActivity>
-       </xsl:template>
-
-
-       <!-- ========== 040 ========== -->
-       <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='a']">
-               <mads:recordContentSource authority="marcorg">
-                       <xsl:value-of select="."/>
-               </mads:recordContentSource>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='b']">
-               <mads:languageOfCataloging>
-                       <mads:languageTerm authority="iso639-2b" type="code">
-                               <xsl:value-of select="."/>
-                       </mads:languageTerm>
-               </mads:languageOfCataloging>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='e']">
-               <mads:descriptionStandard>
-                       <xsl:value-of select="."/>
-               </mads:descriptionStandard>
-       </xsl:template>
-       
-       <!-- ========== classification 2.03 ========== -->
-       
-       <xsl:template match="marc:datafield[@tag=053]">
-               <mads:classification>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       
-       <xsl:template match="marc:datafield[@tag=055]">
-               <mads:classification>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       
-       <xsl:template match="marc:datafield[@tag=060]">
-               <mads:classification>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=065]">
-               <mads:classification>
-                       <xsl:attribute name="authority">
-                               <xsl:value-of select="marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=070]">
-               <mads:classification>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=080]">
-               <mads:classification>
-                       <xsl:attribute name="authority">
-                               <xsl:value-of select="marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=082]">
-               <mads:classification>
-                       <xsl:attribute name="authority">
-                               <xsl:value-of select="marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=083]">
-               <mads:classification>
-                       <xsl:attribute name="authority">
-                               <xsl:value-of select="marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=086]">
-               <mads:classification>
-                       <xsl:attribute name="authority">
-                               <xsl:value-of select="marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=087]">
-               <mads:classification>
-                       <xsl:attribute name="authority">
-                               <xsl:value-of select="marc:subfield[@code='2']"/>
-                       </xsl:attribute>
-                       <xsl:call-template name="subfieldSelect">
-                               <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
-                               <xsl:with-param name="delimeter">-</xsl:with-param>
-                       </xsl:call-template>
-               </mads:classification>
-       </xsl:template>
-       
-
-       <!-- ========== names  ========== -->
-       <xsl:template match="marc:datafield[@tag=100]">
-               <mads:name type="personal">
-                       <xsl:call-template name="setAuthority"/>
-                       <xsl:call-template name="nameABCDQ"/>
-               </mads:name>
-               <xsl:apply-templates select="*[marc:subfield[not(contains('abcdeq',@code))]]"/>
-               <xsl:call-template name="title"/>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=110]">
-               <mads:name type="corporate">
-                       <xsl:call-template name="setAuthority"/>
-                       <xsl:call-template name="nameABCDN"/>
-               </mads:name>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=111]">
-               <mads:name type="conference">
-                       <xsl:call-template name="setAuthority"/>
-                       <xsl:call-template name="nameACDENQ"/>
-               </mads:name>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=400]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <mads:name type="personal">
-                               <xsl:call-template name="nameABCDQ"/>
-                       </mads:name>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-                       <xsl:call-template name="title"/>
-               </mads:variant>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=410]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <mads:name type="corporate">
-                               <xsl:call-template name="nameABCDN"/>
-                       </mads:name>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:variant>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=411]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <mads:name type="conference">
-                               <xsl:call-template name="nameACDENQ"/>
-                       </mads:name>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:variant>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=500]|marc:datafield[@tag=700]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <!-- <xsl:call-template name="uri"/> -->
-                       <mads:name type="personal">
-                               <xsl:call-template name="setAuthority"/>
-                               <xsl:call-template name="nameABCDQ"/>
-                       </mads:name>
-                       <xsl:call-template name="title"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=510]|marc:datafield[@tag=710]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <!-- <xsl:call-template name="uri"/> -->
-                       <mads:name type="corporate">
-                               <xsl:call-template name="setAuthority"/>
-                               <xsl:call-template name="nameABCDN"/>
-                       </mads:name>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=511]|marc:datafield[@tag=711]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <!-- <xsl:call-template name="uri"/> -->
-                       <mads:name type="conference">
-                               <xsl:call-template name="setAuthority"/>
-                               <xsl:call-template name="nameACDENQ"/>
-                       </mads:name>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-
-       <!-- ========== titles  ========== -->
-       <xsl:template match="marc:datafield[@tag=130]">
-               <xsl:call-template name="uniform-title"/>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=430]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <xsl:call-template name="uniform-title"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:variant>
-       </xsl:template>
-
-       <xsl:template match="marc:datafield[@tag=530]|marc:datafield[@tag=730]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:call-template name="uniform-title"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-
-       <xsl:template name="title">
-               <xsl:variable name="hasTitle">
-                       <xsl:for-each select="marc:subfield">
-                               <xsl:if test="(contains('tfghklmors',@code) )">
-                                       <xsl:value-of select="@code"/>
-                               </xsl:if>
-                       </xsl:for-each>
-               </xsl:variable>
-               <xsl:if test="string-length($hasTitle) &gt; 0 ">
-                       <mads:titleInfo>
-                               <xsl:call-template name="setAuthority"/>
-                               <mads:title>
-                                       <xsl:variable name="str">
-                                               <xsl:for-each select="marc:subfield">
-                                                       <xsl:if test="(contains('atfghklmors',@code) )">
-                                                               <xsl:value-of select="text()"/>
-                                                               <xsl:text> </xsl:text>
-                                                       </xsl:if>
-                                               </xsl:for-each>
-                                       </xsl:variable>
-                                       <xsl:call-template name="chopPunctuation">
-                                               <xsl:with-param name="chopString">
-                                                       <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                                               </xsl:with-param>
-                                       </xsl:call-template>
-                               </mads:title>
-                               <xsl:call-template name="part"/>
-                               <!-- <xsl:call-template name="uri"/> -->
-                       </mads:titleInfo>
-               </xsl:if>
-       </xsl:template>
-
-       <xsl:template name="uniform-title">
-               <xsl:variable name="hasTitle">
-                       <xsl:for-each select="marc:subfield">
-                               <xsl:if test="(contains('atfghklmors',@code) )">
-                                       <xsl:value-of select="@code"/>
-                               </xsl:if>
-                       </xsl:for-each>
-               </xsl:variable>
-               <xsl:if test="string-length($hasTitle) &gt; 0 ">
-                       <mads:titleInfo>
-                               <xsl:call-template name="setAuthority"/>
-                               <mads:title>
-                                       <xsl:variable name="str">
-                                               <xsl:for-each select="marc:subfield">
-                                                       <xsl:if test="(contains('adfghklmors',@code) )">
-                                                               <xsl:value-of select="text()"/>
-                                                               <xsl:text> </xsl:text>
-                                                       </xsl:if>
-                                               </xsl:for-each>
-                                       </xsl:variable>
-                                       <xsl:call-template name="chopPunctuation">
-                                               <xsl:with-param name="chopString">
-                                                       <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                                               </xsl:with-param>
-                                       </xsl:call-template>
-                               </mads:title>
-                               <xsl:call-template name="part"/>
-                               <!-- <xsl:call-template name="uri"/> -->
-                       </mads:titleInfo>
-               </xsl:if>
-       </xsl:template>
-
-
-       <!-- ========== topics  ========== -->
-       <xsl:template match="marc:subfield[@code='x']">
-               <mads:topic>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:value-of select="."/>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:topic>
-       </xsl:template>
-       
-       <!-- 2.06 fix -->
-       <xsl:template
-               match="marc:datafield[@tag=150][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=180][marc:subfield[@code='x']]">
-               <xsl:call-template name="topic"/>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=450][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=480][marc:subfield[@code='x']]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <xsl:call-template name="topic"/>
-               </mads:variant>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=550 or @tag=750][marc:subfield[@code='a' or @code='b']]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <!-- <xsl:call-template name="uri"/> -->
-                       <xsl:call-template name="topic"/>
-                       <xsl:apply-templates select="marc:subfield[@code='z']"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template name="topic">
-               <mads:topic>
-                       <xsl:call-template name="setAuthority"/>
-                       <!-- tmee2006 dedupe 550a
-                       <xsl:if test="@tag=550 or @tag=750">
-                               <xsl:call-template name="subfieldSelect">
-                                       <xsl:with-param name="codes">ab</xsl:with-param>
-                               </xsl:call-template>
-                       </xsl:if>       
-                       -->
-                       <xsl:choose>
-                               <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
-                                       <xsl:call-template name="chopPunctuation">
-                                               <xsl:with-param name="chopString">
-                                                       <xsl:apply-templates select="marc:subfield[@code='x']"/>
-                                               </xsl:with-param>
-                                       </xsl:call-template>
-                               </xsl:when>
-                       </xsl:choose>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:choose>
-                                               <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
-                                                       <xsl:apply-templates select="marc:subfield[@code='x']"/>
-                                               </xsl:when>
-                                               <xsl:otherwise>
-                                                       <xsl:call-template name="subfieldSelect">
-                                                               <xsl:with-param name="codes">ab</xsl:with-param>
-                                                       </xsl:call-template>
-                                               </xsl:otherwise>
-                                       </xsl:choose>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:topic>
-       </xsl:template>
-
-       <!-- ========= temporals  ========== -->
-       <xsl:template match="marc:subfield[@code='y']">
-               <mads:temporal>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:value-of select="."/>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:temporal>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=148][marc:subfield[@code='a']]|marc:datafield[@tag=182 ][marc:subfield[@code='y']]">
-               <xsl:call-template name="temporal"/>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=448][marc:subfield[@code='a']]|marc:datafield[@tag=482][marc:subfield[@code='y']]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <xsl:call-template name="temporal"/>
-               </mads:variant>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=548 or @tag=748][marc:subfield[@code='a']]|marc:datafield[@tag=582 or @tag=782][marc:subfield[@code='y']]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <!-- <xsl:call-template name="uri"/> -->
-                       <xsl:call-template name="temporal"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template name="temporal">
-               <mads:temporal>
-                       <xsl:call-template name="setAuthority"/>
-                       <xsl:if test="@tag=548 or @tag=748">
-                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                       </xsl:if>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:choose>
-                                               <xsl:when test="@tag=182 or @tag=482 or @tag=582 or @tag=782">
-                                                       <xsl:apply-templates select="marc:subfield[@code='y']"/>
-                                               </xsl:when>
-                                               <xsl:otherwise>
-                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
-                                               </xsl:otherwise>
-                                       </xsl:choose>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:temporal>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-
-       <!-- ========== genre  ========== -->
-       <xsl:template match="marc:subfield[@code='v']">
-               <mads:genre>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:value-of select="."/>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:genre>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=155][marc:subfield[@code='a']]|marc:datafield[@tag=185][marc:subfield[@code='v']]">
-               <xsl:call-template name="genre"/>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=455][marc:subfield[@code='a']]|marc:datafield[@tag=485 ][marc:subfield[@code='v']]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <xsl:call-template name="genre"/>
-               </mads:variant>
-       </xsl:template>
-       <!--
-       <xsl:template match="marc:datafield[@tag=555]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:call-template name="uri"/>
-                       <xsl:call-template name="genre"/>
-               </mads:related>
-       </xsl:template>
-       -->
-       <xsl:template
-               match="marc:datafield[@tag=555 or @tag=755][marc:subfield[@code='a']]|marc:datafield[@tag=585][marc:subfield[@code='v']]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:call-template name="genre"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template name="genre">
-               <mads:genre>
-                       <xsl:if test="@tag=555">
-                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                       </xsl:if>
-                       <xsl:call-template name="setAuthority"/>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:choose>
-                                               <!-- 2.07 fix -->
-                                               <xsl:when test="@tag='555'"/>
-                                               <xsl:when test="@tag=185 or @tag=485 or @tag=585">
-                                                       <xsl:apply-templates select="marc:subfield[@code='v']"/>
-                                               </xsl:when>
-                                               <xsl:otherwise>
-                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
-                                               </xsl:otherwise>
-                                       </xsl:choose>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:genre>
-               <xsl:apply-templates/>
-       </xsl:template>
-
-       <!-- ========= geographic  ========== -->
-       <xsl:template match="marc:subfield[@code='z']">
-               <mads:geographic>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:value-of select="."/>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:geographic>
-       </xsl:template>
-       <xsl:template name="geographic">
-               <mads:geographic>
-                       <!-- 2.14 -->
-                       <xsl:call-template name="setAuthority"/>
-                       <!-- 2.13 -->
-                       <xsl:if test="@tag=151 or @tag=551">
-                               <xsl:value-of select="marc:subfield[@code='a']"/>
-                       </xsl:if>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                               <xsl:if test="@tag=181 or @tag=481 or @tag=581">
-                                                               <xsl:apply-templates select="marc:subfield[@code='z']"/>
-                                               </xsl:if>
-                                               <!-- 2.13
-                                                       <xsl:choose>
-                                               <xsl:when test="@tag=181 or @tag=481 or @tag=581">
-                                                       <xsl:apply-templates select="marc:subfield[@code='z']"/>
-                                               </xsl:when>
-                                       
-                                               <xsl:otherwise>
-                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
-                                               </xsl:otherwise>
-                                               </xsl:choose>
-                                               -->
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:geographic>
-               <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=151][marc:subfield[@code='a']]|marc:datafield[@tag=181][marc:subfield[@code='z']]">
-               <xsl:call-template name="geographic"/>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=451][marc:subfield[@code='a']]|marc:datafield[@tag=481][marc:subfield[@code='z']]">
-               <mads:variant>
-                       <xsl:call-template name="variantTypeAttribute"/>
-                       <xsl:call-template name="geographic"/>
-               </mads:variant>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=551]|marc:datafield[@tag=581][marc:subfield[@code='z']]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <!-- <xsl:call-template name="uri"/> -->
-                       <xsl:call-template name="geographic"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=580]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template
-               match="marc:datafield[@tag=751][marc:subfield[@code='z']]|marc:datafield[@tag=781][marc:subfield[@code='z']]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:call-template name="geographic"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=755]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:call-template name="genre"/>
-                       <xsl:call-template name="setAuthority"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=780]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-       <xsl:template match="marc:datafield[@tag=785]">
-               <mads:related>
-                       <xsl:call-template name="relatedTypeAttribute"/>
-                       <xsl:apply-templates select="marc:subfield[@code!='i']"/>
-               </mads:related>
-       </xsl:template>
-
-       <!-- ========== notes  ========== -->
-       <xsl:template match="marc:datafield[667 &lt;= @tag and @tag &lt;= 688]">
-               <mads:note>
-                       <xsl:choose>
-                               <xsl:when test="@tag=667">
-                                       <xsl:attribute name="type">nonpublic</xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="@tag=670">
-                                       <xsl:attribute name="type">source</xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="@tag=675">
-                                       <xsl:attribute name="type">notFound</xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="@tag=678">
-                                       <xsl:attribute name="type">history</xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="@tag=681">
-                                       <xsl:attribute name="type">subject example</xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="@tag=682">
-                                       <xsl:attribute name="type">deleted heading information</xsl:attribute>
-                               </xsl:when>
-                               <xsl:when test="@tag=688">
-                                       <xsl:attribute name="type">application history</xsl:attribute>
-                               </xsl:when>
-                       </xsl:choose>
-                       <xsl:call-template name="chopPunctuation">
-                               <xsl:with-param name="chopString">
-                                       <xsl:choose>
-                                               <xsl:when test="@tag=667 or @tag=675">
-                                                       <xsl:value-of select="marc:subfield[@code='a']"/>
-                                               </xsl:when>
-                                               <xsl:when test="@tag=670 or @tag=678">
-                                                       <xsl:call-template name="subfieldSelect">
-                                                               <xsl:with-param name="codes">ab</xsl:with-param>
-                                                       </xsl:call-template>
-                                               </xsl:when>
-                                               <xsl:when test="680 &lt;= @tag and @tag &lt;=688">
-                                                       <xsl:call-template name="subfieldSelect">
-                                                               <xsl:with-param name="codes">ai</xsl:with-param>
-                                                       </xsl:call-template>
-                                               </xsl:when>
-                                       </xsl:choose>
-                               </xsl:with-param>
-                       </xsl:call-template>
-               </mads:note>
-       </xsl:template>
-
-       <!-- ========== url  ========== -->
-       <xsl:template match="marc:datafield[@tag=856][marc:subfield[@code='u']]">
-               <mads:url>
-                       <xsl:if test="marc:subfield[@code='z' or @code='3']">
-                               <xsl:attribute name="displayLabel">
-                                       <xsl:call-template name="subfieldSelect">
-                                               <xsl:with-param name="codes">z3</xsl:with-param>
-                                       </xsl:call-template>
-                               </xsl:attribute>
-                       </xsl:if>
-                       <xsl:value-of select="marc:subfield[@code='u']"/>
-               </mads:url>
-       </xsl:template>
-
-       <xsl:template name="relatedTypeAttribute">
-               <xsl:choose>
-                       <xsl:when
-                               test="@tag=500 or @tag=510 or @tag=511 or @tag=548 or @tag=550 or @tag=551 or @tag=555 or @tag=580 or @tag=581 or @tag=582 or @tag=585">
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='a'">
-                                       <xsl:attribute name="type">earlier</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='b'">
-                                       <xsl:attribute name="type">later</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='t'">
-                                       <xsl:attribute name="type">parentOrg</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='g'">
-                                       <xsl:attribute name="type">broader</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='h'">
-                                       <xsl:attribute name="type">narrower</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='r'">
-                                       <xsl:attribute name="type">other</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="contains('fin|', substring(marc:subfield[@code='w'],1,1))">
-                                       <xsl:attribute name="type">other</xsl:attribute>
-                               </xsl:if>
-                       </xsl:when>
-                       <xsl:when test="@tag=530 or @tag=730">
-                               <xsl:attribute name="type">other</xsl:attribute>
-                       </xsl:when>
-                       <xsl:otherwise>
-                               <!-- 7xx -->
-                               <xsl:attribute name="type">equivalent</xsl:attribute>
-                       </xsl:otherwise>
-               </xsl:choose>
-               <xsl:apply-templates select="marc:subfield[@code='i']"/>
-       </xsl:template>
-       
-
-
-       <xsl:template name="variantTypeAttribute">
-               <xsl:choose>
-                       <xsl:when
-                               test="@tag=400 or @tag=410 or @tag=411 or @tag=451 or @tag=455 or @tag=480 or @tag=481 or @tag=482 or @tag=485">
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='d'">
-                                       <xsl:attribute name="type">acronym</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="substring(marc:subfield[@code='w'],1,1)='n'">
-                                       <xsl:attribute name="type">other</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="contains('fit', substring(marc:subfield[@code='w'],1,1))">
-                                       <xsl:attribute name="type">other</xsl:attribute>
-                               </xsl:if>
-                       </xsl:when>
-                       <xsl:otherwise>
-                               <!-- 430  -->
-                               <xsl:attribute name="type">other</xsl:attribute>
-                       </xsl:otherwise>
-               </xsl:choose>
-               <xsl:apply-templates select="marc:subfield[@code='i']"/>
-       </xsl:template>
-
-       <xsl:template name="setAuthority">
-               <xsl:choose>
-                       <!-- can be called from the datafield or subfield level, so "..//@tag" means
-                       the tag can be at the subfield's parent level or at the datafields own level -->
-
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='a'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>naf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lcsh</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='k'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lacnaf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='a' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lcsh</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='k' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">cash</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='a'">
-                               <xsl:attribute name="authority">naf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">lcsh</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='a'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lacnaf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>cash</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='b'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lcshcl</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='c'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>nlmnaf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='d'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>nalnaf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='r'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>aat</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='s'">
-                               <xsl:attribute name="authority">sears</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='v'">
-                               <xsl:attribute name="authority">rvm</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='z'">
-                               <xsl:attribute name="authority">
-                                       <xsl:value-of
-                                               select="../marc:datafield[ancestor-or-self::marc:datafield/@tag=040]/marc:subfield[@code='f']"
-                                       />
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='a'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>naf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lcsh</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='k' ">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lacnaf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lcsh</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>lcsh</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='c' ">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>mesh</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='d' ">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>nal</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='k' ">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>cash</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='a'">
-                               <xsl:attribute name="authority">
-                                       <xsl:text>naf</xsl:text>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">lcsh</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='a'">
-                               <xsl:attribute name="authority">lacnaf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='b'">
-                               <xsl:attribute name="authority">cash</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(..//ancestor-or-self::marc:datafield/@tag=180 or ..//ancestor-or-self::marc:datafield/@tag=181 or ..//ancestor-or-self::marc:datafield/@tag=182 or ..//ancestor-or-self::marc:datafield/@tag=185) and $controlField008-11='a'">
-                               <xsl:attribute name="authority">lcsh</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='0'">
-                               <xsl:attribute name="authority">naf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='5'">
-                               <xsl:attribute name="authority">lacnaf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='0'">
-                               <xsl:attribute name="authority">lcsh</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='5'">
-                               <xsl:attribute name="authority">cash</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='1'">
-                               <xsl:attribute name="authority">lcshcl</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='2'">
-                               <xsl:attribute name="authority">nlmnaf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='3'">
-                               <xsl:attribute name="authority">nalnaf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='6'">
-                               <xsl:attribute name="authority">rvm</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='7'">
-                               <xsl:attribute name="authority">
-                                       <xsl:value-of select="marc:subfield[@code='2']"/>
-                               </xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='5'">
-                               <xsl:attribute name="authority">lacnaf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='0'">
-                               <xsl:attribute name="authority">naf</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='0'">
-                               <xsl:attribute name="authority">lcsh</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='2'">
-                               <xsl:attribute name="authority">mesh</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='3'">
-                               <xsl:attribute name="authority">nal</xsl:attribute>
-                       </xsl:when>
-                       <xsl:when
-                               test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='5'">
-                               <xsl:attribute name="authority">cash</xsl:attribute>
-                       </xsl:when>
-               </xsl:choose>
-       </xsl:template>
-       <xsl:template match="*"/>
-</xsl:stylesheet>$XSLT$);
-
-END IF; END $INSERT$;                                                          
-
-
--- SELECT evergreen.upgrade_deps_block_check('1069', :eg_version); --gmcharlt/kmlussier
-
--- subset of types listed in https://www.loc.gov/marc/authority/ad1xx3xx.html
--- for now, ignoring subdivisions
-CREATE TYPE authority.heading_type AS ENUM (
-    'personal_name',
-    'corporate_name',
-    'meeting_name',
-    'uniform_title',
-    'named_event',
-    'chronological_term',
-    'topical_term',
-    'geographic_name',
-    'genre_form_term',
-    'medium_of_performance_term'
-);
-
-CREATE TYPE authority.variant_heading_type AS ENUM (
-    'abbreviation',
-    'acronym',
-    'translation',
-    'expansion',
-    'other',
-    'hidden'
-);
-
-CREATE TYPE authority.related_heading_type AS ENUM (
-    'earlier',
-    'later',
-    'parent organization',
-    'broader',
-    'narrower',
-    'equivalent',
-    'other'
-);
-
-CREATE TYPE authority.heading_purpose AS ENUM (
-    'main',
-    'variant',
-    'related'
-);
-
-CREATE TABLE authority.heading_field (
-    id              SERIAL                      PRIMARY KEY,
-    heading_type    authority.heading_type      NOT NULL,
-    heading_purpose authority.heading_purpose   NOT NULL,
-    label           TEXT                        NOT NULL,
-    format          TEXT                        NOT NULL REFERENCES config.xml_transform (name) DEFAULT 'mads21',
-    heading_xpath   TEXT                        NOT NULL,
-    component_xpath TEXT                        NOT NULL,
-    type_xpath      TEXT                        NULL, -- to extract related or variant type
-    thesaurus_xpath TEXT                        NULL,
-    thesaurus_override_xpath TEXT               NULL,
-    joiner          TEXT                        NULL
-);
-
-CREATE TABLE authority.heading_field_norm_map (
-        id      SERIAL  PRIMARY KEY,
-        field   INT     NOT NULL REFERENCES authority.heading_field (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-        norm    INT     NOT NULL REFERENCES config.index_normalizer (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-        params  TEXT,
-        pos     INT     NOT NULL DEFAULT 0
-);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-INSERT INTO authority.heading_field(heading_type, heading_purpose, label, heading_xpath, component_xpath, type_xpath, thesaurus_xpath, thesaurus_override_xpath) VALUES
- ( 'topical_term', 'main',    'Main Topical Term',    '/mads21:mads/mads21:authority', '//mads21:topic', NULL, '/mads21:mads/mads21:authority/mads21:topic[1]/@authority', NULL )
-,( 'topical_term', 'variant', 'Variant Topical Term', '/mads21:mads/mads21:variant',   '//mads21:topic', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:topic[1]/@authority', '//mads21:topic[1]/@authority')
-,( 'topical_term', 'related', 'Related Topical Term', '/mads21:mads/mads21:related',   '//mads21:topic', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:topic[1]/@authority', '//mads21:topic[1]/@authority')
-,( 'personal_name', 'main', 'Main Personal Name',     '/mads21:mads/mads21:authority', '//mads21:name[@type="personal"]', NULL, NULL, NULL )
-,( 'personal_name', 'variant', 'Variant Personal Name',     '/mads21:mads/mads21:variant', '//mads21:name[@type="personal"]', NULL, NULL, NULL )
-,( 'personal_name', 'related', 'Related Personal Name',     '/mads21:mads/mads21:related', '//mads21:name[@type="personal"]', '/mads21:related/@type', NULL, NULL )
-,( 'corporate_name', 'main', 'Main Corporate name',     '/mads21:mads/mads21:authority', '//mads21:name[@type="corporate"]', NULL, NULL, NULL )
-,( 'corporate_name', 'variant', 'Variant Corporate Name',     '/mads21:mads/mads21:variant', '//mads21:name[@type="corporate"]', NULL, NULL, NULL )
-,( 'corporate_name', 'related', 'Related Corporate Name',     '/mads21:mads/mads21:related', '//mads21:name[@type="corporate"]', '/mads21:related/@type', NULL, NULL )
-,( 'meeting_name', 'main', 'Main Meeting name',     '/mads21:mads/mads21:authority', '//mads21:name[@type="conference"]', NULL, NULL, NULL )
-,( 'meeting_name', 'variant', 'Variant Meeting Name',     '/mads21:mads/mads21:variant', '//mads21:name[@type="conference"]', NULL, NULL, NULL )
-,( 'meeting_name', 'related', 'Related Meeting Name',     '/mads21:mads/mads21:related', '//mads21:name[@type="meeting"]', '/mads21:related/@type', NULL, NULL )
-,( 'geographic_name', 'main',    'Main Geographic Term',    '/mads21:mads/mads21:authority', '//mads21:geographic', NULL, '/mads21:mads/mads21:authority/mads21:geographic[1]/@authority', NULL )
-,( 'geographic_name', 'variant', 'Variant Geographic Term', '/mads21:mads/mads21:variant',   '//mads21:geographic', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:geographic[1]/@authority', '//mads21:geographic[1]/@authority')
-,( 'geographic_name', 'related', 'Related Geographic Term', '/mads21:mads/mads21:related',   '//mads21:geographic', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:geographic[1]/@authority', '//mads21:geographic[1]/@authority')
-,( 'genre_form_term', 'main',    'Main Genre/Form Term',    '/mads21:mads/mads21:authority', '//mads21:genre', NULL, '/mads21:mads/mads21:authority/mads21:genre[1]/@authority', NULL )
-,( 'genre_form_term', 'variant', 'Variant Genre/Form Term', '/mads21:mads/mads21:variant',   '//mads21:genre', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:genre[1]/@authority', '//mads21:genre[1]/@authority')
-,( 'genre_form_term', 'related', 'Related Genre/Form Term', '/mads21:mads/mads21:related',   '//mads21:genre', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:genre[1]/@authority', '//mads21:genre[1]/@authority')
-,( 'chronological_term', 'main',    'Main Chronological Term',    '/mads21:mads/mads21:authority', '//mads21:temporal', NULL, '/mads21:mads/mads21:authority/mads21:temporal[1]/@authority', NULL )
-,( 'chronological_term', 'variant', 'Variant Chronological Term', '/mads21:mads/mads21:variant',   '//mads21:temporal', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:temporal[1]/@authority', '//mads21:temporal[1]/@authority')
-,( 'chronological_term', 'related', 'Related Chronological Term', '/mads21:mads/mads21:related',   '//mads21:temporal', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:temporal[1]/@authority', '//mads21:temporal[1]/@authority')
-,( 'uniform_title', 'main',    'Main Uniform Title',    '/mads21:mads/mads21:authority', '//mads21:title', NULL, '/mads21:mads/mads21:authority/mads21:title[1]/@authority', NULL )
-,( 'uniform_title', 'variant', 'Variant Uniform Title', '/mads21:mads/mads21:variant',   '//mads21:title', '/mads21:variant/@type', '/mads21:mads/mads21:authority/mads21:title[1]/@authority', '//mads21:title[1]/@authority')
-,( 'uniform_title', 'related', 'Related Uniform Title', '/mads21:mads/mads21:related',   '//mads21:title', '/mads21:related/@type', '/mads21:mads/mads21:authority/mads21:title[1]/@authority', '//mads21:title[1]/@authority')
-;
-
--- NACO normalize all the things
-INSERT INTO authority.heading_field_norm_map (field, norm, pos)
-SELECT id, 1, 0
-FROM authority.heading_field;
-
-END IF; END $INSERT$;                                                          
-
-CREATE TYPE authority.heading AS (
-    field               INT,
-    type                authority.heading_type,
-    purpose             authority.heading_purpose,
-    variant_type        authority.variant_heading_type,
-    related_type        authority.related_heading_type,
-    thesaurus           TEXT,
-    heading             TEXT,
-    normalized_heading  TEXT
-);
-
-CREATE OR REPLACE FUNCTION authority.extract_headings(marc TEXT, restrict INT[] DEFAULT NULL) RETURNS SETOF authority.heading AS $func$
-DECLARE
-    idx         authority.heading_field%ROWTYPE;
-    xfrm        config.xml_transform%ROWTYPE;
-    prev_xfrm   TEXT;
-    transformed_xml TEXT;
-    heading_node    TEXT;
-    heading_node_list   TEXT[];
-    component_node    TEXT;
-    component_node_list   TEXT[];
-    raw_text    TEXT;
-    normalized_text    TEXT;
-    normalizer  RECORD;
-    curr_text   TEXT;
-    joiner      TEXT;
-    type_value  TEXT;
-    base_thesaurus TEXT := NULL;
-    output_row  authority.heading;
-BEGIN
-
-    -- Loop over the indexing entries
-    FOR idx IN SELECT * FROM authority.heading_field WHERE restrict IS NULL OR id = ANY (restrict) ORDER BY format LOOP
-
-        output_row.field   := idx.id;
-        output_row.type    := idx.heading_type;
-        output_row.purpose := idx.heading_purpose;
-
-        joiner := COALESCE(idx.joiner, ' ');
-
-        SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
-
-        -- See if we can skip the XSLT ... it's expensive
-        IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-            -- Can't skip the transform
-            IF xfrm.xslt <> '---' THEN
-                transformed_xml := oils_xslt_process(marc, xfrm.xslt);
-            ELSE
-                transformed_xml := marc;
-            END IF;
-
-            prev_xfrm := xfrm.name;
-        END IF;
-
-        IF idx.thesaurus_xpath IS NOT NULL THEN
-            base_thesaurus := ARRAY_TO_STRING(oils_xpath(idx.thesaurus_xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
-        END IF;
-
-        heading_node_list := oils_xpath( idx.heading_xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-
-        FOR heading_node IN SELECT x FROM unnest(heading_node_list) AS x LOOP
-
-            CONTINUE WHEN heading_node !~ E'^\\s*<';
-
-            output_row.variant_type := NULL;
-            output_row.related_type := NULL;
-            output_row.thesaurus    := NULL;
-            output_row.heading      := NULL;
-
-            IF idx.heading_purpose = 'variant' AND idx.type_xpath IS NOT NULL THEN
-                type_value := ARRAY_TO_STRING(oils_xpath(idx.type_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
-                BEGIN
-                    output_row.variant_type := type_value;
-                EXCEPTION WHEN invalid_text_representation THEN
-                    RAISE NOTICE 'Do not recognize variant heading type %', type_value;
-                END;
-            END IF;
-            IF idx.heading_purpose = 'related' AND idx.type_xpath IS NOT NULL THEN
-                type_value := ARRAY_TO_STRING(oils_xpath(idx.type_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
-                BEGIN
-                    output_row.related_type := type_value;
-                EXCEPTION WHEN invalid_text_representation THEN
-                    RAISE NOTICE 'Do not recognize related heading type %', type_value;
-                END;
-            END IF;
-            IF idx.thesaurus_override_xpath IS NOT NULL THEN
-                output_row.thesaurus := ARRAY_TO_STRING(oils_xpath(idx.thesaurus_override_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
-            END IF;
-            IF output_row.thesaurus IS NULL THEN
-                output_row.thesaurus := base_thesaurus;
-            END IF;
-
-            raw_text := NULL;
-
-            -- now iterate over components of heading
-            component_node_list := oils_xpath( idx.component_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-            FOR component_node IN SELECT x FROM unnest(component_node_list) AS x LOOP
-            -- XXX much of this should be moved into oils_xpath_string...
-                curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
-                    oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
-                        REGEXP_REPLACE( component_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
-                    ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
-                    joiner
-                );
-
-                CONTINUE WHEN curr_text IS NULL OR curr_text = '';
-
-                IF raw_text IS NOT NULL THEN
-                    raw_text := raw_text || joiner;
-                END IF;
-
-                raw_text := COALESCE(raw_text,'') || curr_text;
-            END LOOP;
-
-            IF raw_text IS NOT NULL THEN
-                output_row.heading := raw_text;
-                normalized_text := raw_text;
-
-                FOR normalizer IN
-                    SELECT  n.func AS func,
-                            n.param_count AS param_count,
-                            m.params AS params
-                    FROM  config.index_normalizer n
-                            JOIN authority.heading_field_norm_map m ON (m.norm = n.id)
-                    WHERE m.field = idx.id
-                    ORDER BY m.pos LOOP
-            
-                        EXECUTE 'SELECT ' || normalizer.func || '(' ||
-                            quote_literal( normalized_text ) ||
-                            CASE
-                                WHEN normalizer.param_count > 0
-                                    THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
-                                    ELSE ''
-                                END ||
-                            ')' INTO normalized_text;
-            
-                END LOOP;
-            
-                output_row.normalized_heading := normalized_text;
-            
-                RETURN NEXT output_row;
-            END IF;
-        END LOOP;
-
-    END LOOP;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION authority.extract_headings(rid BIGINT, restrict INT[] DEFAULT NULL) RETURNS SETOF authority.heading AS $func$
-DECLARE
-    auth        authority.record_entry%ROWTYPE;
-    output_row  authority.heading;
-BEGIN
-    -- Get the record
-    SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
-
-    RETURN QUERY SELECT * FROM authority.extract_headings(auth.marc, restrict);
-END;
-$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
-DECLARE
-    res             authority.simple_heading%ROWTYPE;
-    acsaf           authority.control_set_authority_field%ROWTYPE;
-    heading_row     authority.heading%ROWTYPE;
-    tag_used        TEXT;
-    nfi_used        TEXT;
-    sf              TEXT;
-    cset            INT;
-    heading_text    TEXT;
-    joiner_text     TEXT;
-    sort_text       TEXT;
-    tmp_text        TEXT;
-    tmp_xml         TEXT;
-    first_sf        BOOL;
-    auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT; 
-BEGIN
-
-    SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
-
-    IF cset IS NULL THEN
-        SELECT  control_set INTO cset
-          FROM  authority.control_set_authority_field
-          WHERE tag IN ( SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
-          LIMIT 1;
-    END IF;
-
-    res.record := auth_id;
-    res.thesaurus := authority.extract_thesaurus(marcxml);
-
-    FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
-        res.atag := acsaf.id;
-
-        IF acsaf.heading_field IS NULL THEN
-            tag_used := acsaf.tag;
-            nfi_used := acsaf.nfi;
-            joiner_text := COALESCE(acsaf.joiner, ' ');
-    
-            FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)::TEXT[]) LOOP
-    
-                heading_text := COALESCE(
-                    oils_xpath_string('./*[contains("'||acsaf.display_sf_list||'",@code)]', tmp_xml, joiner_text),
-                    ''
-                );
-    
-                IF nfi_used IS NOT NULL THEN
-    
-                    sort_text := SUBSTRING(
-                        heading_text FROM
-                        COALESCE(
-                            NULLIF(
-                                REGEXP_REPLACE(
-                                    oils_xpath_string('./@ind'||nfi_used, tmp_xml::TEXT),
-                                    $$\D+$$,
-                                    '',
-                                    'g'
-                                ),
-                                ''
-                            )::INT,
-                            0
-                        ) + 1
-                    );
-    
-                ELSE
-                    sort_text := heading_text;
-                END IF;
-    
-                IF heading_text IS NOT NULL AND heading_text <> '' THEN
-                    res.value := heading_text;
-                    res.sort_value := public.naco_normalize(sort_text);
-                    res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
-                    RETURN NEXT res;
-                END IF;
-    
-            END LOOP;
-        ELSE
-            FOR heading_row IN SELECT * FROM authority.extract_headings(marcxml, ARRAY[acsaf.heading_field]) LOOP
-                res.value := heading_row.heading;
-                res.sort_value := heading_row.normalized_heading;
-                res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
-                RETURN NEXT res;
-            END LOOP;
-        END IF;
-    END LOOP;
-
-    RETURN;
-END;
-$func$ LANGUAGE PLPGSQL STABLE STRICT;
-
-ALTER TABLE authority.control_set_authority_field ADD COLUMN heading_field INTEGER REFERENCES authority.heading_field(id);
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '100'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'personal_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '400'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'personal_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '500'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'personal_name';
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '110'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'corporate_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '410'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'corporate_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '510'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'corporate_name';
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '111'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'meeting_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '411'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'meeting_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '511'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'meeting_name';
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '130'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'uniform_title';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '430'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'uniform_title';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '530'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'uniform_title';
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '150'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'topical_term';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '450'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'topical_term';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '550'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'topical_term';
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '151'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'geographic_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '451'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'geographic_name';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '551'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'geographic_name';
-
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '155'
-AND control_set = 1
-AND ahf.heading_purpose = 'main'
-AND ahf.heading_type = 'genre_form_term';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '455'
-AND control_set = 1
-AND ahf.heading_purpose = 'variant'
-AND ahf.heading_type = 'genre_form_term';
-UPDATE authority.control_set_authority_field acsaf
-SET heading_field = ahf.id
-FROM authority.heading_field ahf
-WHERE tag = '555'
-AND control_set = 1
-AND ahf.heading_purpose = 'related'
-AND ahf.heading_type = 'genre_form_term';
-
-
--- SELECT evergreen.upgrade_deps_block_check('1070', :eg_version); --miker/gmcharlt/kmlussier
-
-CREATE TRIGGER thes_code_tracking_trigger
-    AFTER UPDATE ON authority.thesaurus
-    FOR EACH ROW EXECUTE PROCEDURE oils_i18n_code_tracking('at');
-
-ALTER TABLE authority.thesaurus ADD COLUMN short_code TEXT, ADD COLUMN uri TEXT;
-
-DELETE FROM authority.thesaurus WHERE control_set = 1 AND code NOT IN ('n',' ','|');
-UPDATE authority.thesaurus SET short_code = code;
-
-CREATE TEMP TABLE thesauri (code text, uri text, name text, xlate hstore);
-COPY thesauri (code, uri, name, xlate) FROM STDIN;
-migfg  http://id.loc.gov/vocabulary/genreFormSchemes/migfg     Moving image genre-form guide   
-reveal http://id.loc.gov/vocabulary/genreFormSchemes/reveal    REVEAL: fiction indexing and genre headings     
-dct    http://id.loc.gov/vocabulary/genreFormSchemes/dct       Dublin Core list of resource types      
-gmgpc  http://id.loc.gov/vocabulary/genreFormSchemes/gmgpc     Thesaurus for graphic materials: TGM II, Genre and physical characteristic terms        
-rbgenr http://id.loc.gov/vocabulary/genreFormSchemes/rbgenr    Genre terms: a thesaurus for use in rare book and special collections cataloguing       
-sgp    http://id.loc.gov/vocabulary/genreFormSchemes/sgp       Svenska genrebeteckningar fr periodika  "sv"=>"Svenska genrebeteckningar fr periodika"
-estc   http://id.loc.gov/vocabulary/genreFormSchemes/estc      Eighteenth century short title catalogue, the cataloguing rules. New ed.        
-ftamc  http://id.loc.gov/vocabulary/genreFormSchemes/ftamc     Form terms for archival and manuscripts control 
-alett  http://id.loc.gov/vocabulary/genreFormSchemes/alett     An alphabetical list of English text types      
-gtlm   http://id.loc.gov/vocabulary/genreFormSchemes/gtlm      Genre terms for law materials: a thesaurus      
-rbprov http://id.loc.gov/vocabulary/genreFormSchemes/rbprov    Provenance evidence: a thesaurus for use in rare book and special collections cataloging        
-rbbin  http://id.loc.gov/vocabulary/genreFormSchemes/rbbin     Binding terms: a thesaurus for use in rare book and special collections cataloguing     
-fbg    http://id.loc.gov/vocabulary/genreFormSchemes/fbg       Films by genre /dd>     
-isbdmedia      http://id.loc.gov/vocabulary/genreFormSchemes/isbdmedia ISBD Area 0 [media]     
-marccategory   http://id.loc.gov/vocabulary/genreFormSchemes/marccategory      MARC form category term list    
-gnd-music      http://id.loc.gov/vocabulary/genreFormSchemes/gnd-music Gemeinsame Normdatei: Musikalische Ausgabeform  
-proysen        http://id.loc.gov/vocabulary/genreFormSchemes/proysen   Prøysen: emneord for Prøysen-bibliografien        
-rdacarrier     http://id.loc.gov/vocabulary/genreFormSchemes/rdacarrier        Term and code list for RDA carrier types        
-gnd    http://id.loc.gov/vocabulary/genreFormSchemes/gnd       Gemeinsame Normdatei    
-cjh    http://id.loc.gov/vocabulary/genreFormSchemes/cjh       Center for Jewish History thesaurus     
-rbpri  http://id.loc.gov/vocabulary/genreFormSchemes/rbpri     Printing & publishing evidence: a thesaurus for use in rare book and special collections cataloging     
-fgtpcm http://id.loc.gov/vocabulary/genreFormSchemes/fgtpcm    Form/genre terms for printed cartoon material   
-rbpub  http://id.loc.gov/vocabulary/genreFormSchemes/rbpub     Printing and publishing evidence: a thesaurus for use in rare book and special collections cataloging   
-gmd    http://id.loc.gov/vocabulary/genreFormSchemes/gmd       Anglo-American Cataloguing Rules general material designation   
-rbpap  http://id.loc.gov/vocabulary/genreFormSchemes/rbpap     Paper terms: a thesaurus for use in rare book and special collections cataloging        
-rdamedia       http://id.loc.gov/vocabulary/genreFormSchemes/rdamedia  Term and code list for RDA media types  
-marcsmd        http://id.loc.gov/vocabulary/genreFormSchemes/marcsmd   MARC specific material form term list   
-saogf  http://id.loc.gov/vocabulary/genreFormSchemes/saogf     Svenska Ã¤mnesord - Genre/Form        "sv"=>"Svenska Ã¤mnesord - Genre/Form"
-lcgft  http://id.loc.gov/vocabulary/genreFormSchemes/lcgft     Library of Congress genre/form terms for library and archival materials 
-muzeukv        http://id.loc.gov/vocabulary/genreFormSchemes/muzeukv   MuzeVideo UK DVD and UMD film genre classification      
-mim    http://id.loc.gov/vocabulary/genreFormSchemes/mim       Moving image materials: genre terms     
-nmc    http://id.loc.gov/vocabulary/genreFormSchemes/nmc       Revised nomenclature for museum cataloging: a revised and expanded version of Robert C. Chenhall's system for classifying man-made objects      
-gnd-content    http://id.loc.gov/vocabulary/genreFormSchemes/gnd-content       Gemeinsame Normdatei: Beschreibung des Inhalts  
-bgtchm http://id.loc.gov/vocabulary/genreFormSchemes/bgtchm    Basic genre terms for cultural heritage materials       
-gsafd  http://id.loc.gov/vocabulary/genreFormSchemes/gsafd     Guidelines on subject access to individual works of fiction, drama, etc 
-marcform       http://id.loc.gov/vocabulary/genreFormSchemes/marcform  MARC form of item term list     
-marcgt http://id.loc.gov/vocabulary/genreFormSchemes/marcgt    MARC genre terms        
-barngf http://id.loc.gov/vocabulary/genreFormSchemes/barngf    Svenska Ã¤mnesord för barn - Genre/Form    "sv"=>"Svenska Ã¤mnesord för barn - Genre/Form"
-ngl    http://id.loc.gov/vocabulary/genreFormSchemes/ngl       Newspaper genre list    
-rvmgf  http://id.loc.gov/vocabulary/genreFormSchemes/rvmgf     Thésaurus des descripteurs de genre/forme de l'Université Laval   "fr"=>"Thésaurus des descripteurs de genre/forme de l'Université Laval"
-tgfbne http://id.loc.gov/vocabulary/genreFormSchemes/tgfbne    Términos de género/forma de la Biblioteca Nacional de España   
-nbdbgf http://id.loc.gov/vocabulary/genreFormSchemes/nbdbgf    NBD Biblion Genres Fictie       
-rbtyp  http://id.loc.gov/vocabulary/genreFormSchemes/rbtyp     Type evidence: a thesaurus for use in rare book and special collections cataloging      
-radfg  http://id.loc.gov/vocabulary/genreFormSchemes/radfg     Radio form / genre terms guide  
-gnd-carrier    http://id.loc.gov/vocabulary/genreFormSchemes/gnd-carrier       Gemeinsame Normdatei: Datenträgertyp 
-gatbeg http://id.loc.gov/vocabulary/genreFormSchemes/gatbeg    Gattungsbegriffe        "de"=>"Gattungsbegriffe"
-rdacontent     http://id.loc.gov/vocabulary/genreFormSchemes/rdacontent        Term and code list for RDA content types        
-isbdcontent    http://id.loc.gov/vocabulary/genreFormSchemes/isbdcontent       ISBD Area 0 [content]   
-nimafc http://id.loc.gov/vocabulary/genreFormSchemes/nimafc    NIMA form codes 
-amg    http://id.loc.gov/vocabulary/genreFormSchemes/amg       Audiovisual material glossary   
-local  http://id.loc.gov/vocabulary/subjectSchemes/local       Locally assigned term   
-taika  http://id.loc.gov/vocabulary/subjectSchemes/taika       Taideteollisuuden asiasanasto   "fi"=>"Taideteollisuuden asiasanasto"
-nasat  http://id.loc.gov/vocabulary/subjectSchemes/nasat       NASA thesaurus  
-rswkaf http://id.loc.gov/vocabulary/subjectSchemes/rswkaf      Alternativform zum Hauptschlagwort      "de"=>"Alternativform zum Hauptschlagwort"
-jhpk   http://id.loc.gov/vocabulary/subjectSchemes/jhpk        JÄ\99zyk haseÅ\82 przedmiotowych KABA   "pl"=>"JÄ\99zyk haseÅ\82 przedmiotowych KABA"
-asrcrfcd       http://id.loc.gov/vocabulary/subjectSchemes/asrcrfcd    Australian Standard Research Classification: Research Fields, Courses and Disciplines (RFCD) classification     
-bt     http://id.loc.gov/vocabulary/subjectSchemes/bt  Bioethics thesaurus     
-lcstt  http://id.loc.gov/vocabulary/subjectSchemes/lcstt       List of Chinese subject terms   
-netc   http://id.loc.gov/vocabulary/subjectSchemes/netc        National Emergency Training Center Thesaurus (NETC)     
-aat    http://id.loc.gov/vocabulary/subjectSchemes/aat Art & architecture thesaurus    
-bet    http://id.loc.gov/vocabulary/subjectSchemes/bet British education thesaurus     
-ncjt   http://id.loc.gov/vocabulary/subjectSchemes/ncjt        National criminal justice thesaurus     
-samisk http://id.loc.gov/vocabulary/subjectSchemes/samisk      Sami bibliography       "no"=>"Sámi bibliografia = Samisk bibliografi (Norge)"
-tips   http://id.loc.gov/vocabulary/subjectSchemes/tips        Tesauro ISOC de psicología   "es"=>"Tesauro ISOC de psicología"
-ukslc  http://id.loc.gov/vocabulary/subjectSchemes/ukslc       UK Standard Library Categories  
-tekord http://id.loc.gov/vocabulary/subjectSchemes/tekord      TEK-ord : UBiTs emneordliste for arkitektur, realfag, og teknolog       "no"=>"TEK-ord : UBiTs emneordliste for arkitektur, realfag, og teknolog"
-umitrist       http://id.loc.gov/vocabulary/subjectSchemes/umitrist    University of Michigan Transportation Research Institute structured thesaurus   
-wgst   http://id.loc.gov/vocabulary/subjectSchemes/wgst        Washington GILS Subject Tree    
-rasuqam        http://id.loc.gov/vocabulary/subjectSchemes/rasuqam     Répertoire d'autorités-sujet de l'UQAM    "fr"=>"Répertoire d'autorités-sujet de l'UQAM"
-ntids  http://id.loc.gov/vocabulary/subjectSchemes/ntids       Norske tidsskrifter 1700-1820: emneord  "no"=>"Norske tidsskrifter 1700-1820: emneord"
-kaa    http://id.loc.gov/vocabulary/subjectSchemes/kaa Kasvatusalan asiasanasto        "fi"=>"Kasvatusalan asiasanasto"
-yso    http://id.loc.gov/vocabulary/subjectSchemes/yso YSO - Yleinen suomalainen ontologia     "fi"=>"YSO - Yleinen suomalainen ontologia"
-gcipmedia      http://id.loc.gov/vocabulary/subjectSchemes/gcipmedia   GAMECIP - Computer Game Media Formats (GAMECIP (Game Metadata and Citation Project))    
-inspect        http://id.loc.gov/vocabulary/subjectSchemes/inspect     INSPEC thesaurus        
-ordnok http://id.loc.gov/vocabulary/subjectSchemes/ordnok      Ordnokkelen: tesaurus for kulturminnevern       "no"=>"Ordnokkelen: tesaurus for kulturminnevern"
-helecon        http://id.loc.gov/vocabulary/subjectSchemes/helecon     Asiasanasto HELECON-tietikantoihin      "fi"=>"Asiasanasto HELECON-tietikantoihin"
-dltlt  http://id.loc.gov/vocabulary/subjectSchemes/dltlt       Cuddon, J. A. A dictionary of literary terms and literary theory        
-csapa  http://id.loc.gov/vocabulary/subjectSchemes/csapa       "Controlled vocabulary" in Pollution abstracts  
-gtt    http://id.loc.gov/vocabulary/subjectSchemes/gtt GOO-trefwoorden thesaurus       "nl"=>"GOO-trefwoorden thesaurus"
-iescs  http://id.loc.gov/vocabulary/subjectSchemes/iescs       International energy subject categories and scope       
-itrt   http://id.loc.gov/vocabulary/subjectSchemes/itrt        International Thesaurus of Refugee Terminology  
-sanb   http://id.loc.gov/vocabulary/subjectSchemes/sanb        South African national bibliography authority file      
-blmlsh http://id.loc.gov/vocabulary/subjectSchemes/blmlsh      British Library - Map library subject headings  
-bhb    http://id.loc.gov/vocabulary/subjectSchemes/bhb Bibliography of the Hebrew Book 
-csh    http://id.loc.gov/vocabulary/subjectSchemes/csh Kapsner, Oliver Leonard. Catholic subject headings      
-fire   http://id.loc.gov/vocabulary/subjectSchemes/fire        FireTalk, IFSI thesaurus        
-jlabsh http://id.loc.gov/vocabulary/subjectSchemes/jlabsh      Basic subject headings  "ja"=>"Kihon kenmei hyômokuhyô"
-udc    http://id.loc.gov/vocabulary/subjectSchemes/udc Universal decimal classification        
-lcshac http://id.loc.gov/vocabulary/subjectSchemes/lcshac      Children's subject headings in Library of Congress subject headings: supplementary vocabularies 
-geonet http://id.loc.gov/vocabulary/subjectSchemes/geonet      NGA GEOnet Names Server (GNS)   
-humord http://id.loc.gov/vocabulary/subjectSchemes/humord      HUMORD  "no"=>"HUMORD"
-no-ubo-mr      http://id.loc.gov/vocabulary/subjectSchemes/no-ubo-mr   Menneskerettighets-tesaurus     "no"=>"Menneskerettighets-tesaurus"
-sgce   http://id.loc.gov/vocabulary/subjectSchemes/sgce        COBISS.SI General List of subject headings (English subject headings)   "sl"=>"SploÅ¡ni geslovnik COBISS.SI"
-kdm    http://id.loc.gov/vocabulary/subjectSchemes/kdm Khung dê muc hê thông thông tin khoa hoc và ky thuât quôc gia      "vi"=>"Khung dê muc hê thông thông tin khoa hoc và ky thuât quôc gia"
-thesoz http://id.loc.gov/vocabulary/subjectSchemes/thesoz      Thesaurus for the Social Sciences       
-asth   http://id.loc.gov/vocabulary/subjectSchemes/asth        Astronomy thesaurus     
-muzeukc        http://id.loc.gov/vocabulary/subjectSchemes/muzeukc     MuzeMusic UK classical music classification     
-norbok http://id.loc.gov/vocabulary/subjectSchemes/norbok      Norbok: emneord i Norsk bokfortegnelse  "no"=>"Norbok: emneord i Norsk bokfortegnelse"
-masa   http://id.loc.gov/vocabulary/subjectSchemes/masa        Museoalan asiasanasto   "fi"=>"Museoalan asiasanasto"
-conorsi        http://id.loc.gov/vocabulary/subjectSchemes/conorsi     CONOR.SI (name authority file) (Maribor, Slovenia: Institut informacijskih znanosti (IZUM))     
-eurovocen      http://id.loc.gov/vocabulary/subjectSchemes/eurovocen   Eurovoc thesaurus (English)     
-kto    http://id.loc.gov/vocabulary/subjectSchemes/kto KTO - Kielitieteen ontologia    "fi"=>"KTO - Kielitieteen ontologia"
-muzvukci       http://id.loc.gov/vocabulary/subjectSchemes/muzvukci    MuzeVideo UK contributor index  
-kaunokki       http://id.loc.gov/vocabulary/subjectSchemes/kaunokki    Kaunokki: kaunokirjallisuuden asiasanasto       "fi"=>"Kaunokki: kaunokirjallisuuden asiasanasto"
-maotao http://id.loc.gov/vocabulary/subjectSchemes/maotao      MAO/TAO - Ontologi för museibranschen och Konstindustriella ontologin        "fi"=>"MAO/TAO - Ontologi för museibranschen och Konstindustriella ontologin"
-psychit        http://id.loc.gov/vocabulary/subjectSchemes/psychit     Thesaurus of psychological index terms. 
-tlsh   http://id.loc.gov/vocabulary/subjectSchemes/tlsh        Subject heading authority list  
-csalsct        http://id.loc.gov/vocabulary/subjectSchemes/csalsct     CSA life sciences collection thesaurus  
-ciesiniv       http://id.loc.gov/vocabulary/subjectSchemes/ciesiniv    CIESIN indexing vocabulary      
-ebfem  http://id.loc.gov/vocabulary/subjectSchemes/ebfem       Encabezamientos bilingües de la Fundación Educativa Ana G. Mendez 
-mero   http://id.loc.gov/vocabulary/subjectSchemes/mero        MERO - Merenkulkualan ontologia "fi"=>"MERO - Merenkulkualan ontologia"
-mmm    http://id.loc.gov/vocabulary/subjectSchemes/mmm "Subject key" in Marxism and the mass media     
-pascal http://id.loc.gov/vocabulary/subjectSchemes/pascal      PASCAL database classification scheme   "fr"=>"Base de donneés PASCAL: plan de classement"
-chirosh        http://id.loc.gov/vocabulary/subjectSchemes/chirosh     Chiropractic Subject Headings   
-cilla  http://id.loc.gov/vocabulary/subjectSchemes/cilla       Cilla: specialtesaurus för musik     "fi"=>"Cilla: specialtesaurus för musik"
-aiatsisl       http://id.loc.gov/vocabulary/subjectSchemes/aiatsisl    AIATSIS language thesaurus      
-nskps  http://id.loc.gov/vocabulary/subjectSchemes/nskps       PriruÄ\8dnik za izradu predmetnog kataloga u Nacionalnoj i sveuÄ\8diliÅ¡noj knjiÄ\8dnici u Zagrebu    "hr"=>"PriruÄ\8dnik za izradu predmetnog kataloga u Nacionalnoj i sveuÄ\8diliÅ¡noj knjiÄ\8dnici u Zagrebu"
-lctgm  http://id.loc.gov/vocabulary/subjectSchemes/lctgm       Thesaurus for graphic materials: TGM I, Subject terms   
-muso   http://id.loc.gov/vocabulary/subjectSchemes/muso        MUSO - Ontologi för musik    "fi"=>"MUSO - Ontologi för musik"
-blcpss http://id.loc.gov/vocabulary/subjectSchemes/blcpss      COMPASS subject authority system        
-fast   http://id.loc.gov/vocabulary/subjectSchemes/fast        Faceted application of subject terminology      
-bisacmt        http://id.loc.gov/vocabulary/subjectSchemes/bisacmt     BISAC Merchandising Themes      
-lapponica      http://id.loc.gov/vocabulary/subjectSchemes/lapponica   Lapponica       "fi"=>"Lapponica"
-juho   http://id.loc.gov/vocabulary/subjectSchemes/juho        JUHO - Julkishallinnon ontologia        "fi"=>"JUHO - Julkishallinnon ontologia"
-idas   http://id.loc.gov/vocabulary/subjectSchemes/idas        ID-Archivschlüssel   "de"=>"ID-Archivschlüssel"
-tbjvp  http://id.loc.gov/vocabulary/subjectSchemes/tbjvp       Tesauro de la Biblioteca Dr. Jorge Villalobos Padilla, S.J.     "es"=>"Tesauro de la Biblioteca Dr. Jorge Villalobos Padilla, S.J."
-test   http://id.loc.gov/vocabulary/subjectSchemes/test        Thesaurus of engineering and scientific terms   
-finmesh        http://id.loc.gov/vocabulary/subjectSchemes/finmesh     FinMeSH "fi"=>"FinMeSH"
-kssbar http://id.loc.gov/vocabulary/subjectSchemes/kssbar      Klassifikationssystem for svenska bibliotek. Ã\84mnesordregister. Alfabetisk del        "sv"=>"Klassifikationssystem for svenska bibliotek. Ã\84mnesordregister. Alfabetisk del"
-kupu   http://id.loc.gov/vocabulary/subjectSchemes/kupu        Maori Wordnet   "mi"=>"He puna kupu"
-rpe    http://id.loc.gov/vocabulary/subjectSchemes/rpe Rubricator on economics "ru"=>"Rubrikator po ekonomike"
-dit    http://id.loc.gov/vocabulary/subjectSchemes/dit Defense intelligence thesaurus  
-she    http://id.loc.gov/vocabulary/subjectSchemes/she SHE: subject headings for engineering   
-idszbzna       http://id.loc.gov/vocabulary/subjectSchemes/idszbzna    Thesaurus IDS Nebis Zentralbibliothek Zürich, Nordamerika-Bibliothek "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Nordamerika-Bibliothek"
-msc    http://id.loc.gov/vocabulary/subjectSchemes/msc Mathematical subject classification     
-muzeukn        http://id.loc.gov/vocabulary/subjectSchemes/muzeukn     MuzeMusic UK non-classical music classification 
-ipsp   http://id.loc.gov/vocabulary/subjectSchemes/ipsp        Defense intelligence production schedule.       
-sthus  http://id.loc.gov/vocabulary/subjectSchemes/sthus       Subject Taxonomy of the History of U.S. Foreign Relations       
-poliscit       http://id.loc.gov/vocabulary/subjectSchemes/poliscit    Political science thesaurus II  
-qtglit http://id.loc.gov/vocabulary/subjectSchemes/qtglit      A queer thesaurus : an international thesaurus of gay and lesbian index terms   
-unbist http://id.loc.gov/vocabulary/subjectSchemes/unbist      UNBIS thesaurus 
-gcipplatform   http://id.loc.gov/vocabulary/subjectSchemes/gcipplatform        GAMECIP - Computer Game Platforms (GAMECIP (Game Metadata and Citation Project))        
-puho   http://id.loc.gov/vocabulary/subjectSchemes/puho        PUHO - Puolustushallinnon ontologia     "fi"=>"PUHO - Puolustushallinnon ontologia"
-thub   http://id.loc.gov/vocabulary/subjectSchemes/thub        Thesaurus de la Universitat de Barcelona        "ca"=>"Thesaurus de la Universitat de Barcelona"
-ndlsh  http://id.loc.gov/vocabulary/subjectSchemes/ndlsh       National Diet Library list of subject headings  "ja"=>"Koktsu Kokkai Toshokan kenmei hyômokuhyô"
-czenas http://id.loc.gov/vocabulary/subjectSchemes/czenas      CZENAS thesaurus: a list of subject terms used in the National Library of the Czech Republic    "cs"=>"Soubor vÄ\95cných autorit Národní knihovny Ä\8cR"
-idszbzzh       http://id.loc.gov/vocabulary/subjectSchemes/idszbzzh    Thesaurus IDS Nebis Zentralbibliothek Zürich, Handschriftenabteilung "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Handschriftenabteilung"
-unbisn http://id.loc.gov/vocabulary/subjectSchemes/unbisn      UNBIS name authority list (New York, NY: Dag Hammarskjld Library, United Nations; : Chadwyck-Healey)    
-rswk   http://id.loc.gov/vocabulary/subjectSchemes/rswk        Regeln für den Schlagwortkatalog     "de"=>"Regeln für den Schlagwortkatalog"
-larpcal        http://id.loc.gov/vocabulary/subjectSchemes/larpcal     Lista de assuntos referente ao programa de cadastramento automatizado de livros da USP  "pt"=>"Lista de assuntos referente ao programa de cadastramento automatizado de livros da USP"
-biccbmc        http://id.loc.gov/vocabulary/subjectSchemes/biccbmc     BIC Children's Books Marketing Classifications  
-kulo   http://id.loc.gov/vocabulary/subjectSchemes/kulo        KULO - Kulttuurien tutkimuksen ontologia        "fi"=>"KULO - Kulttuurien tutkimuksen ontologia"
-popinte        http://id.loc.gov/vocabulary/subjectSchemes/popinte     POPIN thesaurus: population multilingual thesaurus      
-tisa   http://id.loc.gov/vocabulary/subjectSchemes/tisa        Villagrá Rubio, Angel. Tesauro ISOC de sociología autores "es"=>"Villagrá Rubio, Angel. Tesauro ISOC de sociología autores"
-atg    http://id.loc.gov/vocabulary/subjectSchemes/atg Agricultural thesaurus and glossary     
-eflch  http://id.loc.gov/vocabulary/subjectSchemes/eflch       E4Libraries Category Headings   
-maaq   http://id.loc.gov/vocabulary/subjectSchemes/maaq        Madâkhil al-asmâ' al-'arabîyah al-qadîmah   "ar"=>"Madâkhil al-asmâ' al-'arabîyah al-qadîmah"
-rvmgd  http://id.loc.gov/vocabulary/subjectSchemes/rvmgd       Thésaurus des descripteurs de groupes démographiques de l'Université Laval     "fr"=>"Thésaurus des descripteurs de groupes démographiques de l'Université Laval"
-csahssa        http://id.loc.gov/vocabulary/subjectSchemes/csahssa     "Controlled vocabulary" in Health and safety science abstracts  
-sigle  http://id.loc.gov/vocabulary/subjectSchemes/sigle       SIGLE manual, Part 2, Subject category list     
-blnpn  http://id.loc.gov/vocabulary/subjectSchemes/blnpn       British Library newspaper place names   
-asrctoa        http://id.loc.gov/vocabulary/subjectSchemes/asrctoa     Australian Standard Research Classification: Type of Activity (TOA) classification      
-lcdgt  http://id.loc.gov/vocabulary/subjectSchemes/lcdgt       Library of Congress demographic group term and code List        
-bokbas http://id.loc.gov/vocabulary/subjectSchemes/bokbas      Bokbasen        "no"=>"Bokbasen"
-gnis   http://id.loc.gov/vocabulary/subjectSchemes/gnis        Geographic Names Information System (GNIS)      
-nbiemnfag      http://id.loc.gov/vocabulary/subjectSchemes/nbiemnfag   NBIs emneordsliste for faglitteratur    "no"=>"NBIs emneordsliste for faglitteratur"
-nlgaf  http://id.loc.gov/vocabulary/subjectSchemes/nlgaf       Archeio KathierÅ\8dmenÅ\8dn EpikephalidÅ\8dn    "el"=>"Archeio KathierÅ\8dmenÅ\8dn EpikephalidÅ\8dn"
-bhashe http://id.loc.gov/vocabulary/subjectSchemes/bhashe      BHA, Bibliography of the history of art, subject headings/English       
-tsht   http://id.loc.gov/vocabulary/subjectSchemes/tsht        Thesaurus of subject headings for television    
-scbi   http://id.loc.gov/vocabulary/subjectSchemes/scbi        Soggettario per i cataloghi delle biblioteche italiane  "it"=>"Soggettario per i cataloghi delle biblioteche italiane"
-valo   http://id.loc.gov/vocabulary/subjectSchemes/valo        VALO - Fotografiska ontologin   "fi"=>"VALO - Fotografiska ontologin"
-wpicsh http://id.loc.gov/vocabulary/subjectSchemes/wpicsh      WPIC Library thesaurus of subject headings      
-aktp   http://id.loc.gov/vocabulary/subjectSchemes/aktp        AlphavÄ\93tikos Katalogos ThematikÅ\8dn PerigrapheÅ\8dn "el"=>"AlphavÄ\93tikos Katalogos ThematikÅ\8dn PerigrapheÅ\8dn"
-stw    http://id.loc.gov/vocabulary/subjectSchemes/stw STW Thesaurus for Economics     "de"=>"Standard-Thesaurus Wirtschaft"
-mesh   http://id.loc.gov/vocabulary/subjectSchemes/mesh        Medical subject headings        
-ica    http://id.loc.gov/vocabulary/subjectSchemes/ica Index of Christian art  
-emnmus http://id.loc.gov/vocabulary/subjectSchemes/emnmus      Emneord for musikkdokument i EDB-kataloger      "no"=>"Emneord for musikkdokument i EDB-kataloger"
-sao    http://id.loc.gov/vocabulary/subjectSchemes/sao Svenska Ã¤mnesord     "sv"=>"Svenska Ã¤mnesord"
-sgc    http://id.loc.gov/vocabulary/subjectSchemes/sgc COBISS.SI General List of subject headings (Slovenian subject headings) "sl"=>"SploÅ¡ni geslovnik COBISS.SI"
-bib1814        http://id.loc.gov/vocabulary/subjectSchemes/bib1814     1814-bibliografi: emneord for 1814-bibliografi  "no"=>"1814-bibliografi: emneord for 1814-bibliografi"
-bjornson       http://id.loc.gov/vocabulary/subjectSchemes/bjornson    Bjornson: emneord for Bjornsonbibliografien     "no"=>"Bjornson: emneord for Bjornsonbibliografien"
-liito  http://id.loc.gov/vocabulary/subjectSchemes/liito       LIITO - Liiketoimintaontologia  "fi"=>"LIITO - Liiketoimintaontologia"
-apaist http://id.loc.gov/vocabulary/subjectSchemes/apaist      APAIS thesaurus: a list of subject terms used in the Australian Public Affairs Information Service      
-itglit http://id.loc.gov/vocabulary/subjectSchemes/itglit      International thesaurus of gay and lesbian index terms (Chicago?: Thesaurus Committee, Gay and Lesbian Task Force, American Library Association)        
-ntcsd  http://id.loc.gov/vocabulary/subjectSchemes/ntcsd       "National Translations Center secondary descriptors" in National Translation Center primary subject classification and secondary descriptor     
-scisshl        http://id.loc.gov/vocabulary/subjectSchemes/scisshl     SCIS subject headings   
-opms   http://id.loc.gov/vocabulary/subjectSchemes/opms        Opetusministeriön asiasanasto        "fi"=>"Opetusministeriön asiasanasto"
-ttka   http://id.loc.gov/vocabulary/subjectSchemes/ttka        Teologisen tiedekunnan kirjaston asiasanasto    "fi"=>"Teologisen tiedekunnan kirjaston asiasanasto"
-watrest        http://id.loc.gov/vocabulary/subjectSchemes/watrest     Thesaurus of water resources terms: a collection of water resources and related terms for use in indexing technical information 
-ysa    http://id.loc.gov/vocabulary/subjectSchemes/ysa Yleinen suomalainen asiasanasto "fi"=>"Yleinen suomalainen asiasanasto"
-kitu   http://id.loc.gov/vocabulary/subjectSchemes/kitu        Kirjallisuudentutkimuksen asiasanasto   "fi"=>"Kirjallisuudentutkimuksen asiasanasto"
-sk     http://id.loc.gov/vocabulary/subjectSchemes/sk  'Zhong guo gu ji shan ban shu zong mu' fen lei biao     "zh"=>"'Zhong guo gu ji shan ban shu zong mu' fen lei biao"
-aiatsisp       http://id.loc.gov/vocabulary/subjectSchemes/aiatsisp    AIATSIS place thesaurus 
-ram    http://id.loc.gov/vocabulary/subjectSchemes/ram RAMEAU: répertoire d'authorité de matières encyclopédique unifié "fr"=>"RAMEAU: répertoire d'authorité de matières encyclopédique unifié"
-aedoml http://id.loc.gov/vocabulary/subjectSchemes/aedoml      Listado de encabezamientos de materia de música      "es"=>"Listado de encabezamientos de materia de música"
-ated   http://id.loc.gov/vocabulary/subjectSchemes/ated        Australian Thesaurus of Education Descriptors (ATED)    
-cabt   http://id.loc.gov/vocabulary/subjectSchemes/cabt        CAB thesaurus (Slough [England]: Commonwealth Agricultural Bureaux)     
-kassu  http://id.loc.gov/vocabulary/subjectSchemes/kassu       Kassu - Kasvien suomenkieliset nimet    "fi"=>"Kassu - Kasvien suomenkieliset nimet"
-nbdbt  http://id.loc.gov/vocabulary/subjectSchemes/nbdbt       NBD Biblion Trefwoordenthesaurus        "nl"=>"NBD Biblion Trefwoordenthesaurus"
-jhpb   http://id.loc.gov/vocabulary/subjectSchemes/jhpb        JÄ\99zyk haseÅ\82 przedmiotowych Biblioteki Narodowej   "pl"=>"JÄ\99zyk haseÅ\82 przedmiotowych Biblioteki Narodowej"
-bidex  http://id.loc.gov/vocabulary/subjectSchemes/bidex       Bilindex: a bilingual Spanish-English subject heading list      
-ccsa   http://id.loc.gov/vocabulary/subjectSchemes/ccsa        Catalogue collectif suisse des affiches "fr"=>"Catalogue collectif suisse des affiches"
-noraf  http://id.loc.gov/vocabulary/subjectSchemes/noraf       Norwegian Authority File        
-kito   http://id.loc.gov/vocabulary/subjectSchemes/kito        KITO - Kirjallisuudentutkimuksen ontologia      "fi"=>"KITO - Kirjallisuudentutkimuksen ontologia"
-tho    http://id.loc.gov/vocabulary/subjectSchemes/tho Thesauros HellÄ\93nikÅ\8dn Oron "el"=>"Thesauros HellÄ\93nikÅ\8dn Oron"
-pmont  http://id.loc.gov/vocabulary/subjectSchemes/pmont       Powerhouse Museum Object Name Thesaurus 
-ssg    http://id.loc.gov/vocabulary/subjectSchemes/ssg SploÅ¡ni slovenski geslovnik  "sl"=>"SploÅ¡ni slovenski geslovnik"
-huc    http://id.loc.gov/vocabulary/subjectSchemes/huc U.S. Geological Survey water-supply paper 2294: hydrologic basins unit codes    
-isis   http://id.loc.gov/vocabulary/subjectSchemes/isis        "Classification scheme" in Isis 
-ibsen  http://id.loc.gov/vocabulary/subjectSchemes/ibsen       Ibsen: emneord for Den internasjonale Ibsen-bibliografien       "no"=>"Ibsen: emneord for Den internasjonale Ibsen-bibliografien"
-lacnaf http://id.loc.gov/vocabulary/subjectSchemes/lacnaf      Library and Archives Canada name authority file 
-swemesh        http://id.loc.gov/vocabulary/subjectSchemes/swemesh     Swedish MeSH    "sv"=>"Svenska MeSH"
-hamsun http://id.loc.gov/vocabulary/subjectSchemes/hamsun      Hamsun: emneord for Hamsunbibliografien "no"=>"Hamsun: emneord for Hamsunbibliografien"
-qrma   http://id.loc.gov/vocabulary/subjectSchemes/qrma        List of Arabic subject headings "ar"=>"Qâ'imat ru'ûs al-mawdûât al-'Arabîyah"
-qrmak  http://id.loc.gov/vocabulary/subjectSchemes/qrmak       Qâ'imat ru'ûs al-mawdû'ât al-'Arabîyah al-qiyâsîyah al-maktabât wa-marâkaz al-ma'lûmât wa-qawâid al-bayânât   "ar"=>"Qâ'imat ru'ûs al-mawdû'ât al-'Arabîyah al-qiyâsîyah al-maktabât wa-marâkaz al-ma'lûmât wa-qawâid al-bayânât"
-ceeus  http://id.loc.gov/vocabulary/subjectSchemes/ceeus       Counties and equivalent entities of the United States its possessions, and associated areas     
-taxhs  http://id.loc.gov/vocabulary/subjectSchemes/taxhs       A taxonomy or human services: a conceptual framework with standardized terminology and definitions for the field        
-noram  http://id.loc.gov/vocabulary/subjectSchemes/noram       Noram: emneord for Norsk-amerikansk samling     "no"=>"Noram: emneord for Norsk-amerikansk samling"
-eurovocfr      http://id.loc.gov/vocabulary/subjectSchemes/eurovocfr   Eurovoc thesaurus (French)      
-jurivoc        http://id.loc.gov/vocabulary/subjectSchemes/jurivoc     JURIVOC 
-agrifors       http://id.loc.gov/vocabulary/subjectSchemes/agrifors    AGRIFOREST-sanasto      "fi"=>"AGRIFOREST-sanasto"
-noubojur       http://id.loc.gov/vocabulary/subjectSchemes/noubojur    Thesaurus of Law        "no"=>"Thesaurus of Law"
-pha    http://id.loc.gov/vocabulary/subjectSchemes/pha Puolostushallinnon asiasanasto  "fi"=>"Puolostushallinnon asiasanasto"
-ddcrit http://id.loc.gov/vocabulary/subjectSchemes/ddcrit      DDC retrieval and indexing terminology; posting terms with hierarchy and KWOC   
-mar    http://id.loc.gov/vocabulary/subjectSchemes/mar Merenkulun asiasanasto  "fi"=>"Merenkulun asiasanasto"
-sbt    http://id.loc.gov/vocabulary/subjectSchemes/sbt Soggettario Sistema Bibliotecario Ticinese      "it"=>"Soggettario Sistema Bibliotecario Ticinese"
-nzggn  http://id.loc.gov/vocabulary/subjectSchemes/nzggn       New Zealand gazetteer of official geographic names (New Zealand Geographic Board Ngā Pou Taunaha o Aotearoa (NZGB))    
-kta    http://id.loc.gov/vocabulary/subjectSchemes/kta Kielitieteen asiasanasto        "fi"=>"Kielitieteen asiasanasto"
-snt    http://id.loc.gov/vocabulary/subjectSchemes/snt Sexual nomenclature : a thesaurus       
-francis        http://id.loc.gov/vocabulary/subjectSchemes/francis     FRANCIS database classification scheme  "fr"=>"Base de donneés FRANCIS: plan de classement"
-eurovocsl      http://id.loc.gov/vocabulary/subjectSchemes/eurovocsl   Eurovoc thesaurus       "sl"=>"Eurovoc thesaurus"
-idszbzes       http://id.loc.gov/vocabulary/subjectSchemes/idszbzes    Thesaurus IDS Nebis Bibliothek Englisches Seminar der Universität Zürich  "de"=>"Thesaurus IDS Nebis Bibliothek Englisches Seminar der Universität Zürich"
-nlmnaf http://id.loc.gov/vocabulary/subjectSchemes/nlmnaf      National Library of Medicine name authority file        
-rugeo  http://id.loc.gov/vocabulary/subjectSchemes/rugeo       Natsional'nyi normativnyi fail geograficheskikh nazvanii Rossiiskoi Federatsii  "ru"=>"Natsional'nyi normativnyi fail geograficheskikh nazvanii Rossiiskoi Federatsii"
-sipri  http://id.loc.gov/vocabulary/subjectSchemes/sipri       SIPRI library thesaurus 
-kkts   http://id.loc.gov/vocabulary/subjectSchemes/kkts        Katalogos KathierÅ\8dmenÅ\8dn TypÅ\8dn Syllogikou Katalogou Demosion Vivliothekon       "el"=>"Katalogos KathierÅ\8dmenÅ\8dn TypÅ\8dn Syllogikou Katalogou Demosion Vivliothekon"
-tucua  http://id.loc.gov/vocabulary/subjectSchemes/tucua       Thesaurus for use in college and university archives    
-pmbok  http://id.loc.gov/vocabulary/subjectSchemes/pmbok       Guide to the project management body of knowledge (PMBOK Guide) 
-agrovoc        http://id.loc.gov/vocabulary/subjectSchemes/agrovoc     AGROVOC multilingual agricultural thesaurus     
-nal    http://id.loc.gov/vocabulary/subjectSchemes/nal National Agricultural Library subject headings  
-lnmmbr http://id.loc.gov/vocabulary/subjectSchemes/lnmmbr      Lietuvos nacionalines Martyno Mazvydo bibliotekos rubrikynas    "lt"=>"Lietuvos nacionalines Martyno Mazvydo bibliotekos rubrikynas"
-vmj    http://id.loc.gov/vocabulary/subjectSchemes/vmj Vedettes-matière jeunesse    "fr"=>"Vedettes-matière jeunesse"
-ddcut  http://id.loc.gov/vocabulary/subjectSchemes/ddcut       Dewey Decimal Classification user terms 
-eks    http://id.loc.gov/vocabulary/subjectSchemes/eks Eduskunnan kirjaston asiasanasto        "fi"=>"Eduskunnan kirjaston asiasanasto"
-wot    http://id.loc.gov/vocabulary/subjectSchemes/wot A Women's thesaurus     
-noubomn        http://id.loc.gov/vocabulary/subjectSchemes/noubomn     University of Oslo Library Thesaurus of Science "no"=>"University of Oslo Library Thesaurus of Science"
-idszbzzg       http://id.loc.gov/vocabulary/subjectSchemes/idszbzzg    Thesaurus IDS Nebis Zentralbibliothek Zürich, Graphische Sammlung    "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Graphische Sammlung"
-precis http://id.loc.gov/vocabulary/subjectSchemes/precis      PRECIS: a manual of concept analysis and subject indexing       
-cstud  http://id.loc.gov/vocabulary/subjectSchemes/cstud       Classificatieschema's Bibliotheek TU Delft      "nl"=>"Classificatieschema's Bibliotheek TU Delft"
-nlgkk  http://id.loc.gov/vocabulary/subjectSchemes/nlgkk       Katalogos kathierÅ\8dmenÅ\8dn onomatÅ\8dn physikÅ\8dn prosÅ\8d\8dn    "el"=>"Katalogos kathierÅ\8dmenÅ\8dn onomatÅ\8dn physikÅ\8dn prosÅ\8d\8dn"
-pmt    http://id.loc.gov/vocabulary/subjectSchemes/pmt Project management terminology. Newtown Square, PA: Project Management Institute        
-ericd  http://id.loc.gov/vocabulary/subjectSchemes/ericd       Thesaurus of ERIC descriptors   
-rvm    http://id.loc.gov/vocabulary/subjectSchemes/rvm Répertoire de vedettes-matière    "fr"=>"Répertoire de vedettes-matière"
-sfit   http://id.loc.gov/vocabulary/subjectSchemes/sfit        Svenska filminstitutets tesaurus        "sv"=>"Svenska filminstitutets tesaurus"
-trtsa  http://id.loc.gov/vocabulary/subjectSchemes/trtsa       Teatterin ja tanssin asiasanasto        "fi"=>"Teatterin ja tanssin asiasanasto"
-ulan   http://id.loc.gov/vocabulary/subjectSchemes/ulan        Union list of artist names      
-unescot        http://id.loc.gov/vocabulary/subjectSchemes/unescot     UNESCO thesaurus        "fr"=>"Thésaurus de l'UNESCO","es"=>"Tesauro de la UNESCO"
-koko   http://id.loc.gov/vocabulary/subjectSchemes/koko        KOKO-ontologia  "fi"=>"KOKO-ontologia"
-msh    http://id.loc.gov/vocabulary/subjectSchemes/msh Trimboli, T., and Martyn S. Marianist subject headings  
-trt    http://id.loc.gov/vocabulary/subjectSchemes/trt Transportation resource thesaurus       
-agrovocf       http://id.loc.gov/vocabulary/subjectSchemes/agrovocf    AGROVOC thésaurus agricole multilingue       "fr"=>"AGROVOC thésaurus agricole multilingue"
-aucsh  http://id.loc.gov/vocabulary/subjectSchemes/aucsh       Arabic Union Catalog Subject Headings   "ar"=>"Qâ'imat ru'ûs mawdû'ât al-fahras al-'Arabîyah al-mowahad"
-ddcri  http://id.loc.gov/vocabulary/subjectSchemes/ddcri       Dewey Decimal Classification Relative Index     
-est    http://id.loc.gov/vocabulary/subjectSchemes/est International energy: subject thesaurus (: International Energy Agency, Energy Technology Data Exchange)        
-lua    http://id.loc.gov/vocabulary/subjectSchemes/lua Liikunnan ja urheilun asiasanasto       "fi"=>"Liikunnan ja urheilun asiasanasto"
-mipfesd        http://id.loc.gov/vocabulary/subjectSchemes/mipfesd     Macrothesaurus for information processing in the field of economic and social development       
-rurkp  http://id.loc.gov/vocabulary/subjectSchemes/rurkp       Predmetnye rubriki Rossiiskoi knizhnoi palaty   "ru"=>"Predmetnye rubriki Rossiiskoi knizhnoi palaty"
-albt   http://id.loc.gov/vocabulary/subjectSchemes/albt        Arbetslivsbibliotekets tesaurus "sv"=>"Arbetslivsbibliotekets tesaurus"
-fmesh  http://id.loc.gov/vocabulary/subjectSchemes/fmesh       Liste systématique et liste permutée des descripteurs français MeSH    "fr"=>"Liste systématique et liste permutée des descripteurs français MeSH"
-bicssc http://id.loc.gov/vocabulary/subjectSchemes/bicssc      BIC standard subject categories 
-cctf   http://id.loc.gov/vocabulary/subjectSchemes/cctf        Carto-Canadiana thésaurus - Français      "fr"=>"Carto-Canadiana thésaurus - Français"
-reo    http://id.loc.gov/vocabulary/subjectSchemes/reo Māori Subject Headings thesaurus       "mi"=>"Ngā Åªpoko Tukutuku"
-icpsr  http://id.loc.gov/vocabulary/subjectSchemes/icpsr       ICPSR controlled vocabulary system      
-kao    http://id.loc.gov/vocabulary/subjectSchemes/kao KVINNSAM Ã¤mnesordsregister   "sv"=>"KVINNSAM Ã¤mnesordsregister"
-asrcseo        http://id.loc.gov/vocabulary/subjectSchemes/asrcseo     Australian Standard Research Classification: Socio-Economic Objective (SEO) classification      
-georeft        http://id.loc.gov/vocabulary/subjectSchemes/georeft     GeoRef thesaurus        
-cct    http://id.loc.gov/vocabulary/subjectSchemes/cct Chinese Classified Thesaurus    "zh"=>"Zhong guo fen lei zhu ti ci biao"
-dcs    http://id.loc.gov/vocabulary/subjectSchemes/dcs Health Sciences Descriptors     "es"=>"Descriptores en Ciencias de la Salud","pt"=>"Descritores em Ciências da Saúde"
-musa   http://id.loc.gov/vocabulary/subjectSchemes/musa        Musiikin asiasanasto: erikoissanasto    "fi"=>"Musiikin asiasanasto: erikoissanasto"
-ntissc http://id.loc.gov/vocabulary/subjectSchemes/ntissc      NTIS subject categories 
-idszbz http://id.loc.gov/vocabulary/subjectSchemes/idszbz      Thesaurus IDS Nebis Zentralbibliothek Zürich "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich"
-tlka   http://id.loc.gov/vocabulary/subjectSchemes/tlka        Investigació, Procés Tècnicn kirjaston asiasanasto     "fi"=>"Investigació, Procés Tècnicn kirjaston asiasanasto"
-usaidt http://id.loc.gov/vocabulary/subjectSchemes/usaidt      USAID thesaurus: Keywords used to index documents included in the USAID Development Experience System.  
-embne  http://id.loc.gov/vocabulary/subjectSchemes/embne       Encabezamientos de Materia de la Biblioteca Nacional de España       "es"=>"Encabezamientos de Materia de la Biblioteca Nacional de España"
-vcaadu http://id.loc.gov/vocabulary/subjectSchemes/vcaadu      Vocabulario controlado de arquitectura, arte, diseño y urbanismo     "es"=>"Vocabulario controlado de arquitectura, arte, diseño y urbanismo"
-ntcpsc http://id.loc.gov/vocabulary/subjectSchemes/ntcpsc      "National Translations Center primary subject classification" in National Translations Center primary subject classification and secondary descriptors  
-quiding        http://id.loc.gov/vocabulary/subjectSchemes/quiding     Quiding, Nils Herman. Svenskt allmänt författningsregister för tiden frÃ¥n Ã¥r 1522 till och med Ã¥r 1862        "sv"=>"Quiding, Nils Herman. Svenskt allmänt författningsregister för tiden frÃ¥n Ã¥r 1522 till och med Ã¥r 1862"
-allars http://id.loc.gov/vocabulary/subjectSchemes/allars      Allärs: allmän tesaurus pä svenska     "fi"=>"Allärs: allmän tesaurus pä svenska"
-ogst   http://id.loc.gov/vocabulary/subjectSchemes/ogst        Oregon GILS Subject Tree (Oregon: Oregon State Library and Oregon Information Resource Management Division (IRMD))      
-bella  http://id.loc.gov/vocabulary/subjectSchemes/bella       Bella: specialtesaurus för skönlitteratur "fi"=>"Bella: specialtesaurus för skönlitteratur"
-bibalex        http://id.loc.gov/vocabulary/subjectSchemes/bibalex     Bibliotheca Alexandrina name and subject authority file 
-pepp   http://id.loc.gov/vocabulary/subjectSchemes/pepp        The Princeton encyclopedia of poetry and poetics        
-hkcan  http://id.loc.gov/vocabulary/subjectSchemes/hkcan       Hong Kong Chinese Authority File (Name) - HKCAN 
-dissao http://id.loc.gov/vocabulary/subjectSchemes/dissao      "Dissertation abstracts online" in Search tools: the guide to UNI/Data Courier Online   
-ltcsh  http://id.loc.gov/vocabulary/subjectSchemes/ltcsh       Land Tenure Center Library list of subject headings     
-mpirdes        http://id.loc.gov/vocabulary/subjectSchemes/mpirdes     Macrothesaurus para el procesamiento de la información relativa al desarrollo económico y social  "es"=>"Macrothesaurus para el procesamiento de la información relativa al desarrollo económico y social"
-asft   http://id.loc.gov/vocabulary/subjectSchemes/asft        Aquatic sciences and fisheries thesaurus        
-naf    http://id.loc.gov/vocabulary/subjectSchemes/naf NACO authority file     
-nimacsc        http://id.loc.gov/vocabulary/subjectSchemes/nimacsc     NIMA cartographic subject categories    
-khib   http://id.loc.gov/vocabulary/subjectSchemes/khib        Emneord, KHiB Biblioteket       "no"=>"Emneord, KHiB Biblioteket"
-cdcng  http://id.loc.gov/vocabulary/subjectSchemes/cdcng       Catalogage des documents cartographiques: forme et structure des vedettes noms géographiques - NF Z 44-081   "fr"=>"Catalogage des documents cartographiques: forme et structure des vedettes noms géographiques - NF Z 44-081"
-afset  http://id.loc.gov/vocabulary/subjectSchemes/afset       American Folklore Society Ethnographic Thesaurus        
-erfemn http://id.loc.gov/vocabulary/subjectSchemes/erfemn      Erfaringskompetanses emneord    "no"=>"Erfaringskompetanses emneord"
-sbiao  http://id.loc.gov/vocabulary/subjectSchemes/sbiao       Svenska barnboksinstitutets Ã¤mnesordslista   "sv"=>"Svenska barnboksinstitutets Ã¤mnesordslista"
-socio  http://id.loc.gov/vocabulary/subjectSchemes/socio       Sociological Abstracts Thesaurus        
-bisacrt        http://id.loc.gov/vocabulary/subjectSchemes/bisacrt     BISAC Regional Themes   
-eum    http://id.loc.gov/vocabulary/subjectSchemes/eum Eesti uldine märksonastik    "et"=>"Eesti uldine märksonastik"
-kula   http://id.loc.gov/vocabulary/subjectSchemes/kula        Kulttuurien tutkimuksen asiasanasto     "fi"=>"Kulttuurien tutkimuksen asiasanasto"
-odlt   http://id.loc.gov/vocabulary/subjectSchemes/odlt        Baldick, C. The Oxford dictionary of literary terms     
-rerovoc        http://id.loc.gov/vocabulary/subjectSchemes/rerovoc     Indexation matiéres RERO autoritès        "fr"=>"Indexation matiéres RERO autoritès"
-tsr    http://id.loc.gov/vocabulary/subjectSchemes/tsr TSR-ontologia   "fi"=>"TSR-ontologia"
-czmesh http://id.loc.gov/vocabulary/subjectSchemes/czmesh      Czech MeSH      "cs"=>"Czech MeSH"
-dltt   http://id.loc.gov/vocabulary/subjectSchemes/dltt        Quinn, E. A dictionary of literary and thematic terms   
-idsbb  http://id.loc.gov/vocabulary/subjectSchemes/idsbb       Thesaurus IDS Basel Bern        "de"=>"Thesaurus IDS Basel Bern"
-inist  http://id.loc.gov/vocabulary/subjectSchemes/inist       INIS: thesaurus 
-idszbzzk       http://id.loc.gov/vocabulary/subjectSchemes/idszbzzk    Thesaurus IDS Nebis Zentralbibliothek Zürich, Kartensammlung "de"=>"Thesaurus IDS Nebis Zentralbibliothek Zürich, Kartensammlung"
-tesa   http://id.loc.gov/vocabulary/subjectSchemes/tesa        Tesauro Agrícola     "es"=>"Tesauro Agrícola"
-liv    http://id.loc.gov/vocabulary/subjectSchemes/liv Legislative indexing vocabulary 
-collett        http://id.loc.gov/vocabulary/subjectSchemes/collett     Collett-bibliografi: litteratur av og om Camilla Collett        "no"=>"Collett-bibliografi: litteratur av og om Camilla Collett"
-nsbncf http://id.loc.gov/vocabulary/subjectSchemes/nsbncf      Nuovo Soggettario       "it"=>"Nuovo Soggettario"
-ipat   http://id.loc.gov/vocabulary/subjectSchemes/ipat        IPA thesaurus and frequency list        
-skon   http://id.loc.gov/vocabulary/subjectSchemes/skon        Att indexera skönlitteratur: Ã\84mnesordslista, vuxenlitteratur      "sv"=>"Att indexera skönlitteratur: Ã\84mnesordslista, vuxenlitteratur"
-renib  http://id.loc.gov/vocabulary/subjectSchemes/renib       Renib   "es"=>"Renib"
-hrvmesh        http://id.loc.gov/vocabulary/subjectSchemes/hrvmesh     Croatian MeSH / Hrvatski MeSH   "no"=>"Croatian MeSH / Hrvatski MeSH"
-swd    http://id.loc.gov/vocabulary/subjectSchemes/swd Schlagwortnormdatei     "de"=>"Schlagwortnormdatei"
-aass   http://id.loc.gov/vocabulary/subjectSchemes/aass        "Asian American Studies Library subject headings" in A Guide for establishing Asian American core collections   
-cht    http://id.loc.gov/vocabulary/subjectSchemes/cht Chicano thesaurus for indexing Chicano materials in Chicano periodical index    
-galestne       http://id.loc.gov/vocabulary/subjectSchemes/galestne    Gale Group subject thesaurus and named entity vocabulary        
-nlgsh  http://id.loc.gov/vocabulary/subjectSchemes/nlgsh       Katalogos HellÄ\93nikÅ\8dn thematikÅ\8dn epikephalidÅ\8dn       "el"=>"Katalogos HellÄ\93nikÅ\8dn thematikÅ\8dn epikephalidÅ\8dn"
-hoidokki       http://id.loc.gov/vocabulary/subjectSchemes/hoidokki    Hoitotieteellinen asiasanasto   
-vffyl  http://id.loc.gov/vocabulary/subjectSchemes/vffyl       Vocabulario de la Biblioteca Central de la FFyL "es"=>"Vocabulario de la Biblioteca Central de la FFyL"
-kubikat        http://id.loc.gov/vocabulary/subjectSchemes/kubikat     kubikat "de"=>"kubikat"
-waqaf  http://id.loc.gov/vocabulary/subjectSchemes/waqaf       Maknas Uloom Al Waqaf   "ar"=>"Maknas Uloom Al Waqaf"
-hapi   http://id.loc.gov/vocabulary/subjectSchemes/hapi        HAPI thesaurus and name authority, 1970-2000    
-drama  http://id.loc.gov/vocabulary/subjectSchemes/drama       Drama: specialtesaurus för teater och dans   
-sosa   http://id.loc.gov/vocabulary/subjectSchemes/sosa        Sociaalialan asiasanasto        "fi"=>"Sociaalialan asiasanasto"
-ilpt   http://id.loc.gov/vocabulary/subjectSchemes/ilpt        Index to legal periodicals: thesaurus   
-nicem  http://id.loc.gov/vocabulary/subjectSchemes/nicem       NICEM subject headings and classification system        
-qlsp   http://id.loc.gov/vocabulary/subjectSchemes/qlsp        Queens Library Spanish language subject headings        
-eet    http://id.loc.gov/vocabulary/subjectSchemes/eet European education thesaurus    
-nalnaf http://id.loc.gov/vocabulary/subjectSchemes/nalnaf      National Agricultural Library name authority file       
-eclas  http://id.loc.gov/vocabulary/subjectSchemes/eclas       ECLAS thesaurus 
-agrovocs       http://id.loc.gov/vocabulary/subjectSchemes/agrovocs    AGROVOC tesauro agrícola multilingée      "es"=>"AGROVOC tesauro agrícola multilingée"
-shbe   http://id.loc.gov/vocabulary/subjectSchemes/shbe        Subject headings in business and economics      "sv"=>"Subject headings in business and economics"
-barn   http://id.loc.gov/vocabulary/subjectSchemes/barn        Svenska Ã¤mnesord för barn "sv"=>"Svenska Ã¤mnesord för barn"
-bhammf http://id.loc.gov/vocabulary/subjectSchemes/bhammf      BHA, Bibliographie d'histoire de l'art, mots-matière/français     "fr"=>"BHA, Bibliographie d'histoire de l'art, mots-matière/français"
-gccst  http://id.loc.gov/vocabulary/subjectSchemes/gccst       Government of Canada core subject thesaurus (Gatineau : Library and Archives Canada)    
-fnhl   http://id.loc.gov/vocabulary/subjectSchemes/fnhl        First Nations House of Learning Subject Headings        
-kauno  http://id.loc.gov/vocabulary/subjectSchemes/kauno       KAUNO - Kaunokki-ontologin      "fi"=>"KAUNO - Kaunokki-ontologin"
-dtict  http://id.loc.gov/vocabulary/subjectSchemes/dtict       Defense Technical Information Center thesaurus  
-mech   http://id.loc.gov/vocabulary/subjectSchemes/mech        Iskanje po zbirki MECH  "sl"=>"Iskanje po zbirki MECH"
-jupo   http://id.loc.gov/vocabulary/subjectSchemes/jupo        JUPO - Julkisen hallinnon palveluontologia      "fi"=>"JUPO - Julkisen hallinnon palveluontologia"
-ktpt   http://id.loc.gov/vocabulary/subjectSchemes/ktpt        Kirjasto- ja tietopalvelualan tesaurus  "fi"=>"Kirjasto- ja tietopalvelualan tesaurus"
-aiatsiss       http://id.loc.gov/vocabulary/subjectSchemes/aiatsiss    AIATSIS subject Thesaurus       
-lcac   http://id.loc.gov/vocabulary/subjectSchemes/lcac        Library of Congress Annotated Children's Cataloging Program subject headings    
-lemac  http://id.loc.gov/vocabulary/subjectSchemes/lemac       Llista d'encapçalaments de matèria en català   "ca"=>"Llista d'encapçalaments de matèria en català"
-lemb   http://id.loc.gov/vocabulary/subjectSchemes/lemb        Lista de encabezamientos de materia para bibliotecas    "es"=>"Lista de encabezamientos de materia para bibliotecas"
-henn   http://id.loc.gov/vocabulary/subjectSchemes/henn        Hennepin County Library cumulative authority list       
-mtirdes        http://id.loc.gov/vocabulary/subjectSchemes/mtirdes     Macrothésaurus pour le traitement de l'information relative au développement Ã©conomique et social      "fr"=>"Macrothésaurus pour le traitement de l'information relative au développement Ã©conomique et social"
-cash   http://id.loc.gov/vocabulary/subjectSchemes/cash        Canadian subject headings       
-nznb   http://id.loc.gov/vocabulary/subjectSchemes/nznb        New Zealand national bibliographic      
-prvt   http://id.loc.gov/vocabulary/subjectSchemes/prvt        Patent- och registreringsverkets tesaurus       "sv"=>"Patent- och registreringsverkets tesaurus"
-scgdst http://id.loc.gov/vocabulary/subjectSchemes/scgdst      Subject categorization guide for defense science and technology 
-gem    http://id.loc.gov/vocabulary/subjectSchemes/gem GEM controlled vocabularies     
-lcsh   http://id.loc.gov/vocabulary/subjectSchemes/lcsh        Library of Congress subject headings    
-rero   http://id.loc.gov/vocabulary/subjectSchemes/rero        Indexation matires RERO "fr"=>"Indexation matires RERO"
-peri   http://id.loc.gov/vocabulary/subjectSchemes/peri        Perinnetieteiden asiasanasto    "fi"=>"Perinnetieteiden asiasanasto"
-shsples        http://id.loc.gov/vocabulary/subjectSchemes/shsples     Encabezamientos de materia para bibliotecas escolares y públicas     "es"=>"Encabezamientos de materia para bibliotecas escolares y públicas"
-slem   http://id.loc.gov/vocabulary/subjectSchemes/slem        Sears: lista de encabezamientos de materia      "es"=>"Sears: lista de encabezamientos de materia"
-afo    http://id.loc.gov/vocabulary/subjectSchemes/afo AFO - Viikin kampuskirjaston ontologia  "fi"=>"AFO - Viikin kampuskirjaston ontologia"
-gst    http://id.loc.gov/vocabulary/subjectSchemes/gst Gay studies thesaurus: a controlled vocabulary for indexing and accessing materials of relevance to gay culture, history, politics and psychology       
-hlasstg        http://id.loc.gov/vocabulary/subjectSchemes/hlasstg     HLAS subject term glossary      
-iest   http://id.loc.gov/vocabulary/subjectSchemes/iest        International energy: subject thesaurus 
-pkk    http://id.loc.gov/vocabulary/subjectSchemes/pkk Predmetnik za katoliÅ¡ke knjižnice "sl"=>"Predmetnik za katoliÅ¡ke knjižnice"
-atla   http://id.loc.gov/vocabulary/subjectSchemes/atla        Religion indexes: thesaurus     
-scot   http://id.loc.gov/vocabulary/subjectSchemes/scot        Schools Online Thesaurus (ScOT) 
-smda   http://id.loc.gov/vocabulary/subjectSchemes/smda        Smithsonian National Air and Space Museum Directory of Airplanes        
-solstad        http://id.loc.gov/vocabulary/subjectSchemes/solstad     Solstad: emneord for Solstadbibliografien       "no"=>"Solstad: emneord for Solstadbibliografien"
-abne   http://id.loc.gov/vocabulary/subjectSchemes/abne        Autoridades de la Biblioteca Nacional de España      "es"=>"Autoridades de la Biblioteca Nacional de España"
-spines http://id.loc.gov/vocabulary/subjectSchemes/spines      Tesauro SPINES: un vocabulario controlado y estructurado para el tratamiento de información sobre ciencia y tecnología para el desarrollo "es"=>"Tesauro SPINES: un vocabulario controlado y estructurado para el tratamiento de información sobre ciencia y tecnología para el desarrollo"
-ktta   http://id.loc.gov/vocabulary/subjectSchemes/ktta        Käsi - ja taideteollisuuden asiasanasto      "fi"=>"Käsi - ja taideteollisuuden asiasanasto"
-ccte   http://id.loc.gov/vocabulary/subjectSchemes/ccte        Carto-Canadiana thesaurus - English     
-pmcsg  http://id.loc.gov/vocabulary/subjectSchemes/pmcsg       Combined standards glossary     
-bisacsh        http://id.loc.gov/vocabulary/subjectSchemes/bisacsh     BISAC Subject Headings  
-fssh   http://id.loc.gov/vocabulary/subjectSchemes/fssh        FamilySearch Subject Headings (FamilySearch)    
-tasmas http://id.loc.gov/vocabulary/subjectSchemes/tasmas      Tesaurus de Asuntos Sociales del Ministerio de Asuntos Sociales de España    "es"=>"Tesaurus de Asuntos Sociales del Ministerio de Asuntos Sociales de España"
-tero   http://id.loc.gov/vocabulary/subjectSchemes/tero        TERO - Terveyden ja hyvinvoinnin ontologia      "fi"=>"TERO - Terveyden ja hyvinvoinnin ontologia"
-rma    http://id.loc.gov/vocabulary/subjectSchemes/rma Ru'us al-mawdu'at al-'Arabiyah  "ar"=>"Ru'us al-mawdu'at al-'Arabiyah"
-tgn    http://id.loc.gov/vocabulary/subjectSchemes/tgn Getty thesaurus of geographic names     
-tha    http://id.loc.gov/vocabulary/subjectSchemes/tha Barcala de Moyano, Graciela G., Cristina Voena. Tesauro de Historia Argentina   "es"=>"Barcala de Moyano, Graciela G., Cristina Voena. Tesauro de Historia Argentina"
-ttll   http://id.loc.gov/vocabulary/subjectSchemes/ttll        Roggau, Zunilda. Tell. Tesauro de lengua y literatura   "es"=>"Roggau, Zunilda. Tell. Tesauro de lengua y literatura"
-sears  http://id.loc.gov/vocabulary/subjectSchemes/sears       Sears list of subject headings  
-csht   http://id.loc.gov/vocabulary/subjectSchemes/csht        Chinese subject headings        
-\.
-
--- ' ...blah
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
-INSERT INTO authority.thesaurus (code, uri, name, control_set)
-  SELECT code, uri, name, 1 FROM thesauri;
-END IF; END $INSERT$;                                                          
-
-
-UPDATE authority.thesaurus SET short_code = 'a' WHERE code = 'lcsh';
-UPDATE authority.thesaurus SET short_code = 'b' WHERE code = 'lcshac';
-UPDATE authority.thesaurus SET short_code = 'c' WHERE code = 'mesh';
-UPDATE authority.thesaurus SET short_code = 'd' WHERE code = 'nal';
-UPDATE authority.thesaurus SET short_code = 'k' WHERE code = 'cash';
-UPDATE authority.thesaurus SET short_code = 'r' WHERE code = 'aat';
-UPDATE authority.thesaurus SET short_code = 's' WHERE code = 'sears';
-UPDATE authority.thesaurus SET short_code = 'v' WHERE code = 'rvm';
-
-UPDATE  authority.thesaurus
-  SET   short_code = 'z'
-  WHERE short_code IS NULL
-        AND control_set = 1;
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-INSERT INTO config.i18n_core (fq_field, identity_value, translation, string )
-  SELECT  'at.name', t.code, xlate->key, xlate->value
-    FROM  thesauri t
-          JOIN LATERAL each(t.xlate) AS xlate ON TRUE
-    WHERE NOT EXISTS
-            (SELECT id
-              FROM  config.i18n_core
-              WHERE fq_field = 'at.name'
-                    AND identity_value = t.code
-                    AND translation = xlate->key)
-          AND t.xlate IS NOT NULL
-          AND t.name <> (xlate->value);
-END IF; END $INSERT$;                                                          
-
-
-CREATE OR REPLACE FUNCTION authority.extract_thesaurus( marcxml TEXT ) RETURNS TEXT AS $func$
-DECLARE
-    thes_code TEXT;
-BEGIN
-    thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
-    IF thes_code IS NULL THEN
-        thes_code := '|';
-    ELSIF thes_code = 'z' THEN
-        thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), 'z' );
-    ELSE
-        SELECT code INTO thes_code FROM authority.thesaurus WHERE short_code = thes_code;
-        IF NOT FOUND THEN
-            thes_code := '|'; -- default
-        END IF;
-    END IF;
-    RETURN thes_code;
-END;
-$func$ LANGUAGE PLPGSQL STABLE STRICT;
-
-CREATE OR REPLACE FUNCTION authority.map_thesaurus_to_control_set () RETURNS TRIGGER AS $func$
-BEGIN
-    IF NEW.control_set IS NULL THEN
-        SELECT control_set INTO NEW.control_set
-        FROM authority.thesaurus
-        WHERE code = authority.extract_thesaurus(NEW.marc);
-    END IF;
-
-    RETURN NEW;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION authority.reingest_authority_rec_descriptor( auth_id BIGINT ) RETURNS VOID AS $func$
-BEGIN
-    DELETE FROM authority.rec_descriptor WHERE record = auth_id;
-    INSERT INTO authority.rec_descriptor (record, record_status, encoding_level, thesaurus)
-        SELECT  auth_id,
-                vandelay.marc21_extract_fixed_field(marc,'RecStat'),
-                vandelay.marc21_extract_fixed_field(marc,'ELvl'),
-                authority.extract_thesaurus(marc)
-          FROM  authority.record_entry
-          WHERE id = auth_id;
-    RETURN;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-
-
--- SELECT evergreen.upgrade_deps_block_check('1071', :eg_version); --gmcharlt/kmlussier
-
-CREATE OR REPLACE FUNCTION metabib.staged_browse(query text, fields integer[], context_org integer, context_locations integer[], staff boolean, browse_superpage_size integer, count_up_from_zero boolean, result_limit integer, next_pivot_pos integer)
- RETURNS SETOF metabib.flat_browse_entry_appearance
-AS $f$
-DECLARE
-    curs                    REFCURSOR;
-    rec                     RECORD;
-    qpfts_query             TEXT;
-    aqpfts_query            TEXT;
-    afields                 INT[];
-    bfields                 INT[];
-    result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
-    results_skipped         INT := 0;
-    row_counter             INT := 0;
-    row_number              INT;
-    slice_start             INT;
-    slice_end               INT;
-    full_end                INT;
-    all_records             BIGINT[];
-    all_brecords             BIGINT[];
-    all_arecords            BIGINT[];
-    superpage_of_records    BIGINT[];
-    superpage_size          INT;
-    c_tests                 TEXT := '';
-    b_tests                 TEXT := '';
-    c_orgs                  INT[];
-    unauthorized_entry      RECORD;
-BEGIN
-    IF count_up_from_zero THEN
-        row_number := 0;
-    ELSE
-        row_number := -1;
-    END IF;
-
-    IF NOT staff THEN
-        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
-    END IF;
-
-    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
-    IF b_tests <> '' THEN b_tests := b_tests || '&'; END IF;
-
-    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
-
-    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
-               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
-
-    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
-    IF FOUND THEN
-        b_tests := b_tests || search.calculate_visibility_attribute_test(
-            'luri_org',
-            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
-        );
-    ELSE
-        b_tests := b_tests || search.calculate_visibility_attribute_test(
-            'luri_org',
-            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
-        );
-    END IF;
-
-    IF context_locations THEN
-        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
-        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_locations);
-    END IF;
-
-    OPEN curs NO SCROLL FOR EXECUTE query;
-
-    LOOP
-        FETCH curs INTO rec;
-        IF NOT FOUND THEN
-            IF result_row.pivot_point IS NOT NULL THEN
-                RETURN NEXT result_row;
-            END IF;
-            RETURN;
-        END IF;
-
-        --Is unauthorized?
-        SELECT INTO unauthorized_entry *
-        FROM metabib.browse_entry_simple_heading_map mbeshm
-        INNER JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-        INNER JOIN authority.control_set_authority_field acsaf ON ( acsaf.id = ash.atag )
-        JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
-        WHERE mbeshm.entry = rec.id
-        AND   ahf.heading_purpose = 'variant';
-
-        -- Gather aggregate data based on the MBE row we're looking at now, authority axis
-        IF (unauthorized_entry.record IS NOT NULL) THEN
-            --unauthorized term belongs to an auth linked to a bib?
-            SELECT INTO all_arecords, result_row.sees, afields
-                    ARRAY_AGG(DISTINCT abl.bib),
-                    STRING_AGG(DISTINCT abl.authority::TEXT, $$,$$),
-                    ARRAY_AGG(DISTINCT map.metabib_field)
-            FROM authority.bib_linking abl
-            INNER JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                    map.authority_field = unauthorized_entry.atag
-                    AND map.metabib_field = ANY(fields)
-            )
-            WHERE abl.authority = unauthorized_entry.record;
-        ELSE
-            --do usual procedure
-            SELECT INTO all_arecords, result_row.sees, afields
-                    ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
-                    STRING_AGG(DISTINCT aal.source::TEXT, $$,$$), -- authority record ids
-                    ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
-
-            FROM  metabib.browse_entry_simple_heading_map mbeshm
-                    JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-                    JOIN authority.authority_linking aal ON ( ash.record = aal.source )
-                    JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
-                    JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                        ash.atag = map.authority_field
-                        AND map.metabib_field = ANY(fields)
-                    )
-                    JOIN authority.control_set_authority_field acsaf ON (
-                        map.authority_field = acsaf.id
-                    )
-                    JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
-              WHERE mbeshm.entry = rec.id
-              AND   ahf.heading_purpose = 'variant';
-
-        END IF;
-
-        -- Gather aggregate data based on the MBE row we're looking at now, bib axis
-        SELECT INTO all_brecords, result_row.authorities, bfields
-                ARRAY_AGG(DISTINCT source),
-                STRING_AGG(DISTINCT authority::TEXT, $$,$$),
-                ARRAY_AGG(DISTINCT def)
-          FROM  metabib.browse_entry_def_map
-          WHERE entry = rec.id
-                AND def = ANY(fields);
-
-        SELECT INTO result_row.fields STRING_AGG(DISTINCT x::TEXT, $$,$$) FROM UNNEST(afields || bfields) x;
-
-        result_row.sources := 0;
-        result_row.asources := 0;
-
-        -- Bib-linked vis checking
-        IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
-
-            SELECT  INTO result_row.sources COUNT(DISTINCT b.id)
-              FROM  biblio.record_entry b
-                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
-              WHERE b.id = ANY(all_brecords[1:browse_superpage_size])
-                    AND (
-                        acvac.vis_attr_vector @@ c_tests::query_int
-                        OR b.vis_attr_vector @@ b_tests::query_int
-                    );
-
-            result_row.accurate := TRUE;
-
-        END IF;
-
-        -- Authority-linked vis checking
-        IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
-
-            SELECT  INTO result_row.asources COUNT(DISTINCT b.id)
-              FROM  biblio.record_entry b
-                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
-              WHERE b.id = ANY(all_arecords[1:browse_superpage_size])
-                    AND (
-                        acvac.vis_attr_vector @@ c_tests::query_int
-                        OR b.vis_attr_vector @@ b_tests::query_int
-                    );
-
-            result_row.aaccurate := TRUE;
-
-        END IF;
-
-        IF result_row.sources > 0 OR result_row.asources > 0 THEN
-
-            -- The function that calls this function needs row_number in order
-            -- to correctly order results from two different runs of this
-            -- functions.
-            result_row.row_number := row_number;
-
-            -- Now, if row_counter is still less than limit, return a row.  If
-            -- not, but it is less than next_pivot_pos, continue on without
-            -- returning actual result rows until we find
-            -- that next pivot, and return it.
-
-            IF row_counter < result_limit THEN
-                result_row.browse_entry := rec.id;
-                result_row.value := rec.value;
-
-                RETURN NEXT result_row;
-            ELSE
-                result_row.browse_entry := NULL;
-                result_row.authorities := NULL;
-                result_row.fields := NULL;
-                result_row.value := NULL;
-                result_row.sources := NULL;
-                result_row.sees := NULL;
-                result_row.accurate := NULL;
-                result_row.aaccurate := NULL;
-                result_row.pivot_point := rec.id;
-
-                IF row_counter >= next_pivot_pos THEN
-                    RETURN NEXT result_row;
-                    RETURN;
-                END IF;
-            END IF;
-
-            IF count_up_from_zero THEN
-                row_number := row_number + 1;
-            ELSE
-                row_number := row_number - 1;
-            END IF;
-
-            -- row_counter is different from row_number.
-            -- It simply counts up from zero so that we know when
-            -- we've reached our limit.
-            row_counter := row_counter + 1;
-        END IF;
-    END LOOP;
-END;
-$f$ LANGUAGE plpgsql ROWS 10;
-
-CREATE OR REPLACE FUNCTION metabib.browse(search_field integer[], browse_term text, context_org integer DEFAULT NULL::integer, context_loc_group integer DEFAULT NULL::integer, staff boolean DEFAULT false, pivot_id bigint DEFAULT NULL::bigint, result_limit integer DEFAULT 10)
- RETURNS SETOF metabib.flat_browse_entry_appearance
-AS $f$
-DECLARE
-    core_query              TEXT;
-    back_query              TEXT;
-    forward_query           TEXT;
-    pivot_sort_value        TEXT;
-    pivot_sort_fallback     TEXT;
-    context_locations       INT[];
-    browse_superpage_size   INT;
-    results_skipped         INT := 0;
-    back_limit              INT;
-    back_to_pivot           INT;
-    forward_limit           INT;
-    forward_to_pivot        INT;
-BEGIN
-    -- First, find the pivot if we were given a browse term but not a pivot.
-    IF pivot_id IS NULL THEN
-        pivot_id := metabib.browse_pivot(search_field, browse_term);
-    END IF;
-
-    SELECT INTO pivot_sort_value, pivot_sort_fallback
-        sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
-
-    -- Bail if we couldn't find a pivot.
-    IF pivot_sort_value IS NULL THEN
-        RETURN;
-    END IF;
-
-    -- Transform the context_loc_group argument (if any) (logc at the
-    -- TPAC layer) into a form we'll be able to use.
-    IF context_loc_group IS NOT NULL THEN
-        SELECT INTO context_locations ARRAY_AGG(location)
-            FROM asset.copy_location_group_map
-            WHERE lgroup = context_loc_group;
-    END IF;
-
-    -- Get the configured size of browse superpages.
-    SELECT INTO browse_superpage_size COALESCE(value::INT,100)     -- NULL ok
-        FROM config.global_flag
-        WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
-
-    -- First we're going to search backward from the pivot, then we're going
-    -- to search forward.  In each direction, we need two limits.  At the
-    -- lesser of the two limits, we delineate the edge of the result set
-    -- we're going to return.  At the greater of the two limits, we find the
-    -- pivot value that would represent an offset from the current pivot
-    -- at a distance of one "page" in either direction, where a "page" is a
-    -- result set of the size specified in the "result_limit" argument.
-    --
-    -- The two limits in each direction make four derived values in total,
-    -- and we calculate them now.
-    back_limit := CEIL(result_limit::FLOAT / 2);
-    back_to_pivot := result_limit;
-    forward_limit := result_limit / 2;
-    forward_to_pivot := result_limit - 1;
-
-    -- This is the meat of the SQL query that finds browse entries.  We'll
-    -- pass this to a function which uses it with a cursor, so that individual
-    -- rows may be fetched in a loop until some condition is satisfied, without
-    -- waiting for a result set of fixed size to be collected all at once.
-    core_query := '
-SELECT  mbe.id,
-        mbe.value,
-        mbe.sort_value
-  FROM  metabib.browse_entry mbe
-  WHERE (
-            EXISTS ( -- are there any bibs using this mbe via the requested fields?
-                SELECT  1
-                  FROM  metabib.browse_entry_def_map mbedm
-                  WHERE mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ')
-            ) OR EXISTS ( -- are there any authorities using this mbe via the requested fields?
-                SELECT  1
-                  FROM  metabib.browse_entry_simple_heading_map mbeshm
-                        JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-                        JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                            ash.atag = map.authority_field
-                            AND map.metabib_field = ANY(' || quote_literal(search_field) || ')
-                        )
-                        JOIN authority.control_set_authority_field acsaf ON (
-                            map.authority_field = acsaf.id
-                        )
-                        JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
-                  WHERE mbeshm.entry = mbe.id
-                    AND ahf.heading_purpose IN (' || $$'variant'$$ || ')
-                    -- and authority that variant is coming from is linked to a bib
-                    AND EXISTS (
-                        SELECT  1
-                        FROM  metabib.browse_entry_def_map mbedm2
-                        WHERE mbedm2.authority = ash.record AND mbedm2.def = ANY(' || quote_literal(search_field) || ')
-                    )
-            )
-        ) AND ';
-
-    -- This is the variant of the query for browsing backward.
-    back_query := core_query ||
-        ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
-    ' ORDER BY mbe.sort_value DESC, mbe.value DESC LIMIT 1000';
-
-    -- This variant browses forward.
-    forward_query := core_query ||
-        ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
-    ' ORDER BY mbe.sort_value, mbe.value LIMIT 1000';
-
-    -- We now call the function which applies a cursor to the provided
-    -- queries, stopping at the appropriate limits and also giving us
-    -- the next page's pivot.
-    RETURN QUERY
-        SELECT * FROM metabib.staged_browse(
-            back_query, search_field, context_org, context_locations,
-            staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
-        ) UNION
-        SELECT * FROM metabib.staged_browse(
-            forward_query, search_field, context_org, context_locations,
-            staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
-        ) ORDER BY row_number DESC;
-
-END;
-$f$ LANGUAGE plpgsql ROWS 10;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1072', :eg_version); --gmcharlt/kmlussier
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN                         
-
-INSERT INTO config.global_flag (name, label, enabled) VALUES (
-    'opac.show_related_headings_in_browse',
-    oils_i18n_gettext(
-        'opac.show_related_headings_in_browse',
-        'Display related headings (see-also) in browse',
-        'cgf',
-        'label'
-    ),
-    TRUE
-);
-
-END IF; END $INSERT$;                                                          
-
--- SELECT evergreen.upgrade_deps_block_check('1073', :eg_version);
-
-ALTER TABLE config.metabib_field 
-    ADD COLUMN display_xpath TEXT, 
-    ADD COLUMN display_field BOOL NOT NULL DEFAULT FALSE;
-
-CREATE TABLE config.display_field_map (
-    name    TEXT   PRIMARY KEY,
-    field   INTEGER REFERENCES config.metabib_field (id),
-    multi   BOOLEAN DEFAULT FALSE
-);
-
-CREATE TABLE metabib.display_entry (
-    id      BIGSERIAL  PRIMARY KEY,
-    source  BIGINT     NOT NULL REFERENCES biblio.record_entry (id),
-    field   INT        NOT NULL REFERENCES config.metabib_field (id),
-    value   TEXT       NOT NULL
-);
-
-CREATE INDEX metabib_display_entry_field_idx ON metabib.display_entry (field);
-CREATE INDEX metabib_display_entry_source_idx ON metabib.display_entry (source);
-
--- one row per display entry fleshed with field info
-CREATE VIEW metabib.flat_display_entry AS
-    SELECT
-        mde.source,
-        cdfm.name,
-        cdfm.multi,
-        cmf.label,
-        cmf.id AS field,
-        mde.value
-    FROM metabib.display_entry mde
-    JOIN config.metabib_field cmf ON (cmf.id = mde.field)
-    JOIN config.display_field_map cdfm ON (cdfm.field = mde.field)
-;
-
--- like flat_display_entry except values are compressed 
--- into one row per display_field_map and JSON-ified.
-CREATE VIEW metabib.compressed_display_entry AS
-    SELECT 
-        source,
-        name,
-        multi,
-        label,
-        field,
-        CASE WHEN multi THEN
-            TO_JSON(ARRAY_AGG(value))
-        ELSE
-            TO_JSON(MIN(value))
-        END AS value
-    FROM metabib.flat_display_entry
-    GROUP BY 1, 2, 3, 4, 5
-;
-
--- TODO: expand to encompass all well-known fields
-CREATE VIEW metabib.wide_display_entry AS
-    SELECT 
-        bre.id AS source,
-        COALESCE(mcde_title.value, 'null') AS title,
-        COALESCE(mcde_author.value, 'null') AS author,
-        COALESCE(mcde_subject.value, 'null') AS subject,
-        COALESCE(mcde_creators.value, 'null') AS creators,
-        COALESCE(mcde_isbn.value, 'null') AS isbn
-    -- ensure one row per bre regardless of any display fields
-    FROM biblio.record_entry bre 
-    LEFT JOIN metabib.compressed_display_entry mcde_title 
-        ON (bre.id = mcde_title.source AND mcde_title.name = 'title')
-    LEFT JOIN metabib.compressed_display_entry mcde_author 
-        ON (bre.id = mcde_author.source AND mcde_author.name = 'author')
-    LEFT JOIN metabib.compressed_display_entry mcde_subject 
-        ON (bre.id = mcde_subject.source AND mcde_subject.name = 'subject')
-    LEFT JOIN metabib.compressed_display_entry mcde_creators 
-        ON (bre.id = mcde_creators.source AND mcde_creators.name = 'creators')
-    LEFT JOIN metabib.compressed_display_entry mcde_isbn 
-        ON (bre.id = mcde_isbn.source AND mcde_isbn.name = 'isbn')
-;
-
-
-CREATE OR REPLACE FUNCTION metabib.display_field_normalize_trigger () 
-    RETURNS TRIGGER AS $$
-DECLARE
-    normalizer  RECORD;
-    display_field_text  TEXT;
-BEGIN
-    display_field_text := NEW.value;
-
-    FOR normalizer IN
-        SELECT  n.func AS func,
-                n.param_count AS param_count,
-                m.params AS params
-          FROM  config.index_normalizer n
-                JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
-          WHERE m.field = NEW.field AND m.pos < 0
-          ORDER BY m.pos LOOP
-
-            EXECUTE 'SELECT ' || normalizer.func || '(' ||
-                quote_literal( display_field_text ) ||
-                CASE
-                    WHEN normalizer.param_count > 0
-                        THEN ',' || REPLACE(REPLACE(BTRIM(
-                            normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
-                        ELSE ''
-                    END ||
-                ')' INTO display_field_text;
-
-    END LOOP;
-
-    NEW.value = display_field_text;
-
-    RETURN NEW;
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE TRIGGER display_field_normalize_tgr
-       BEFORE UPDATE OR INSERT ON metabib.display_entry
-       FOR EACH ROW EXECUTE PROCEDURE metabib.display_field_normalize_trigger();
-
-CREATE OR REPLACE FUNCTION evergreen.display_field_force_nfc() 
-    RETURNS TRIGGER AS $$
-BEGIN
-    NEW.value := force_unicode_normal_form(NEW.value,'NFC');
-    RETURN NEW;
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE TRIGGER display_field_force_nfc_tgr
-       BEFORE UPDATE OR INSERT ON metabib.display_entry
-       FOR EACH ROW EXECUTE PROCEDURE evergreen.display_field_force_nfc();
-
-ALTER TYPE metabib.field_entry_template ADD ATTRIBUTE display_field BOOL;
-
-DROP FUNCTION metabib.reingest_metabib_field_entries(BIGINT, BOOL, BOOL, BOOL);
-DROP FUNCTION biblio.extract_metabib_field_entry(BIGINT);
-DROP FUNCTION biblio.extract_metabib_field_entry(BIGINT, TEXT);
-
-CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry (
-    rid BIGINT,
-    default_joiner TEXT,
-    field_types TEXT[],
-    only_fields INT[]
-) RETURNS SETOF metabib.field_entry_template AS $func$
-DECLARE
-    bib     biblio.record_entry%ROWTYPE;
-    idx     config.metabib_field%ROWTYPE;
-    xfrm        config.xml_transform%ROWTYPE;
-    prev_xfrm   TEXT;
-    transformed_xml TEXT;
-    xml_node    TEXT;
-    xml_node_list   TEXT[];
-    facet_text  TEXT;
-    display_text TEXT;
-    browse_text TEXT;
-    sort_value  TEXT;
-    raw_text    TEXT;
-    curr_text   TEXT;
-    joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
-    authority_text TEXT;
-    authority_link BIGINT;
-    output_row  metabib.field_entry_template%ROWTYPE;
-    process_idx BOOL;
-BEGIN
-
-    -- Start out with no field-use bools set
-    output_row.browse_field = FALSE;
-    output_row.facet_field = FALSE;
-    output_row.display_field = FALSE;
-    output_row.search_field = FALSE;
-
-    -- Get the record
-    SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
-
-    -- Loop over the indexing entries
-    FOR idx IN SELECT * FROM config.metabib_field WHERE id = ANY (only_fields) ORDER BY format LOOP
-
-        process_idx := FALSE;
-        IF idx.display_field AND 'display' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        IF idx.browse_field AND 'browse' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        IF idx.search_field AND 'search' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        IF idx.facet_field AND 'facet' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        CONTINUE WHEN process_idx = FALSE;
-
-        joiner := COALESCE(idx.joiner, default_joiner);
-
-        SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
-
-        -- See if we can skip the XSLT ... it's expensive
-        IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-            -- Can't skip the transform
-            IF xfrm.xslt <> '---' THEN
-                transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
-            ELSE
-                transformed_xml := bib.marc;
-            END IF;
-
-            prev_xfrm := xfrm.name;
-        END IF;
-
-        xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-
-        raw_text := NULL;
-        FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
-            CONTINUE WHEN xml_node !~ E'^\\s*<';
-
-            -- XXX much of this should be moved into oils_xpath_string...
-            curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
-                oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
-                    REGEXP_REPLACE( xml_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
-                ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
-                joiner
-            );
-
-            CONTINUE WHEN curr_text IS NULL OR curr_text = '';
-
-            IF raw_text IS NOT NULL THEN
-                raw_text := raw_text || joiner;
-            END IF;
-
-            raw_text := COALESCE(raw_text,'') || curr_text;
-
-            -- autosuggest/metabib.browse_entry
-            IF idx.browse_field THEN
-
-                IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
-                    browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-                ELSE
-                    browse_text := curr_text;
-                END IF;
-
-                IF idx.browse_sort_xpath IS NOT NULL AND
-                    idx.browse_sort_xpath <> '' THEN
-
-                    sort_value := oils_xpath_string(
-                        idx.browse_sort_xpath, xml_node, joiner,
-                        ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
-                    );
-                ELSE
-                    sort_value := browse_text;
-                END IF;
-
-                output_row.field_class = idx.field_class;
-                output_row.field = idx.id;
-                output_row.source = rid;
-                output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
-
-                -- output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
-                -- outer regexp_replace keeps all '.' expect the last one.
-                -- inner regexp_replace removes all connecting whitespace and replaces it with a single space
-                output_row.value = BTRIM(REGEXP_REPLACE(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'), E'\\.$', '', 'g'));
-                -- /KCLS 
-
-                output_row.sort_value :=
-                    public.naco_normalize(sort_value);
-
-                output_row.authority := NULL;
-
-                IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
-                    authority_text := oils_xpath_string(
-                        idx.authority_xpath, xml_node, joiner,
-                        ARRAY[
-                            ARRAY[xfrm.prefix, xfrm.namespace_uri],
-                            ARRAY['xlink','http://www.w3.org/1999/xlink']
-                        ]
-                    );
-
-                    IF authority_text ~ '^\d+$' THEN
-                        authority_link := authority_text::BIGINT;
-                        PERFORM * FROM authority.record_entry WHERE id = authority_link;
-                        IF FOUND THEN
-                            output_row.authority := authority_link;
-                        END IF;
-                    END IF;
-
-                END IF;
-
-                output_row.browse_field = TRUE;
-                -- Returning browse rows with search_field = true for search+browse
-                -- configs allows us to retain granularity of being able to search
-                -- browse fields with "starts with" type operators (for example, for
-                -- titles of songs in music albums)
-                IF idx.search_field THEN
-                    output_row.search_field = TRUE;
-                END IF;
-                RETURN NEXT output_row;
-                output_row.browse_field = FALSE;
-                output_row.search_field = FALSE;
-                output_row.sort_value := NULL;
-            END IF;
-
-            -- insert raw node text for faceting
-            IF idx.facet_field THEN
-
-                IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
-                    facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-                ELSE
-                    facet_text := curr_text;
-                END IF;
-
-                output_row.field_class = idx.field_class;
-                output_row.field = -1 * idx.id;
-                output_row.source = rid;
-                output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
-
-                output_row.facet_field = TRUE;
-                RETURN NEXT output_row;
-                output_row.facet_field = FALSE;
-            END IF;
-
-            -- insert raw node text for display
-            IF idx.display_field THEN
-
-                IF idx.display_xpath IS NOT NULL AND idx.display_xpath <> '' THEN
-                    display_text := oils_xpath_string( idx.display_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-                ELSE
-                    display_text := curr_text;
-                END IF;
-
-                output_row.field_class = idx.field_class;
-                output_row.field = -1 * idx.id;
-                output_row.source = rid;
-                output_row.value = BTRIM(REGEXP_REPLACE(display_text, E'\\s+', ' ', 'g'));
-
-                output_row.display_field = TRUE;
-                RETURN NEXT output_row;
-                output_row.display_field = FALSE;
-            END IF;
-
-        END LOOP;
-
-        CONTINUE WHEN raw_text IS NULL OR raw_text = '';
-
-        -- insert combined node text for searching
-        IF idx.search_field THEN
-            output_row.field_class = idx.field_class;
-            -- KCLS
-            -- TODO: move these mods into configs / search normalizers
-            IF idx.field_class = 'identifier' AND idx.name = 'bibcn' THEN
-                output_row.field_class = 'call_number';
-                output_row.browse_field = TRUE;
-                output_row.sort_value = public.naco_normalize_keep_decimal(raw_text,'');
-                output_row.value = raw_text;
-            ELSE
-                output_row.field_class = idx.field_class;
-                output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
-            END IF;
-            -- /KCLS
-            output_row.field = idx.id;
-            output_row.source = rid;
-            -- KCLS -- value is set above
-            -- output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
-            -- /KCLS
-
-            output_row.search_field = TRUE;
-            RETURN NEXT output_row;
-            output_row.search_field = FALSE;
-        END IF;
-
-    END LOOP;
-
-END;
-
-$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries( 
-    bib_id BIGINT,
-    skip_facet BOOL DEFAULT FALSE, 
-    skip_display BOOL DEFAULT FALSE,
-    skip_browse BOOL DEFAULT FALSE, 
-    skip_search BOOL DEFAULT FALSE,
-    only_fields INT[] DEFAULT '{}'::INT[]
-) RETURNS VOID AS $func$
-DECLARE
-    fclass          RECORD;
-    ind_data        metabib.field_entry_template%ROWTYPE;
-    mbe_row         metabib.browse_entry%ROWTYPE;
-    mbe_id          BIGINT;
-    b_skip_facet    BOOL;
-    b_skip_display    BOOL;
-    b_skip_browse   BOOL;
-    b_skip_search   BOOL;
-    value_prepped   TEXT;
-    field_list      INT[] := only_fields;
-    field_types     TEXT[] := '{}'::TEXT[];
-BEGIN
-
-    IF field_list = '{}'::INT[] THEN
-        SELECT ARRAY_AGG(id) INTO field_list FROM config.metabib_field;
-    END IF;
-
-    SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
-    SELECT COALESCE(NULLIF(skip_display, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_display_indexing' AND enabled)) INTO b_skip_display;
-    SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
-    SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
-
-    IF NOT b_skip_facet THEN field_types := field_types || '{facet}'; END IF;
-    IF NOT b_skip_display THEN field_types := field_types || '{display}'; END IF;
-    IF NOT b_skip_browse THEN field_types := field_types || '{browse}'; END IF;
-    IF NOT b_skip_search THEN field_types := field_types || '{search}'; END IF;
-
-    PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
-    IF NOT FOUND THEN
-        IF NOT b_skip_search THEN
-            FOR fclass IN SELECT * FROM config.metabib_class LOOP
-                -- RAISE NOTICE 'Emptying out %', fclass.name;
-                EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
-            END LOOP;
-        END IF;
-        IF NOT b_skip_facet THEN
-            DELETE FROM metabib.facet_entry WHERE source = bib_id;
-        END IF;
-        IF NOT b_skip_display THEN
-            DELETE FROM metabib.display_entry WHERE source = bib_id;
-        END IF;
-        IF NOT b_skip_browse THEN
-            DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
-        END IF;
-    END IF;
-
-    FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id, ' ', field_types, field_list ) LOOP
-
-       -- don't store what has been normalized away
-        CONTINUE WHEN ind_data.value IS NULL;
-
-        IF ind_data.field < 0 THEN
-            ind_data.field = -1 * ind_data.field;
-        END IF;
-
-        IF ind_data.facet_field AND NOT b_skip_facet THEN
-            INSERT INTO metabib.facet_entry (field, source, value)
-                VALUES (ind_data.field, ind_data.source, ind_data.value);
-        END IF;
-
-        IF ind_data.display_field AND NOT b_skip_display THEN
-            INSERT INTO metabib.display_entry (field, source, value)
-                VALUES (ind_data.field, ind_data.source, ind_data.value);
-        END IF;
-
-
-        IF ind_data.browse_field AND NOT b_skip_browse THEN
-            -- A caveat about this SELECT: this should take care of replacing
-            -- old mbe rows when data changes, but not if normalization (by
-            -- which I mean specifically the output of
-            -- evergreen.oils_tsearch2()) changes.  It may or may not be
-            -- expensive to add a comparison of index_vector to index_vector
-            -- to the WHERE clause below.
-
-            CONTINUE WHEN ind_data.sort_value IS NULL;
-
-            value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
-            SELECT INTO mbe_row * FROM metabib.browse_entry
-                WHERE value = value_prepped AND sort_value = ind_data.sort_value;
-
-            IF FOUND THEN
-                mbe_id := mbe_row.id;
-            ELSE
-                INSERT INTO metabib.browse_entry
-                    ( value, sort_value ) VALUES
-                    ( value_prepped, ind_data.sort_value );
-
-                mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
-            END IF;
-
-            INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
-                VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
-        END IF;
-
-        IF ind_data.search_field AND NOT b_skip_search THEN
-            -- Avoid inserting duplicate rows
-            EXECUTE 'SELECT 1 FROM metabib.' || ind_data.field_class ||
-                '_field_entry WHERE field = $1 AND source = $2 AND value = $3'
-                INTO mbe_id USING ind_data.field, ind_data.source, ind_data.value;
-                -- RAISE NOTICE 'Search for an already matching row returned %', mbe_id;
-            IF mbe_id IS NULL THEN
-                EXECUTE $$
-                INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
-                    VALUES ($$ ||
-                        quote_literal(ind_data.field) || $$, $$ ||
-                        quote_literal(ind_data.source) || $$, $$ ||
-                        quote_literal(ind_data.value) ||
-                    $$);$$;
-            END IF;
-        END IF;
-
-    END LOOP;
-
-    IF NOT b_skip_search THEN
-        PERFORM metabib.update_combined_index_vectors(bib_id);
-    END IF;
-
-    RETURN;
-END;
-$func$ LANGUAGE PLPGSQL;
-
--- AFTER UPDATE OR INSERT trigger for biblio.record_entry
-CREATE OR REPLACE FUNCTION biblio.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
-DECLARE
-    tmp_bool BOOL;
-BEGIN
-
-    IF NEW.deleted THEN -- If this bib is deleted
-
-        PERFORM * FROM config.internal_flag WHERE
-            name = 'ingest.metarecord_mapping.preserve_on_delete' AND enabled;
-
-        tmp_bool := FOUND; -- Just in case this is changed by some other statement
-
-        PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint, TRUE, tmp_bool );
-
-        IF NOT tmp_bool THEN
-            -- One needs to keep these around to support searches
-            -- with the #deleted modifier, so one should turn on the named
-            -- internal flag for that functionality.
-            DELETE FROM metabib.record_attr_vector_list WHERE source = NEW.id;
-        END IF;
-
-        DELETE FROM authority.bib_linking WHERE bib = NEW.id; -- Avoid updating fields in bibs that are no longer visible
-        DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = NEW.id; -- Separate any multi-homed items
-        -- DELETE FROM metabib.browse_entry_def_map WHERE source = NEW.id; -- Don't auto-suggest deleted bibs
-        -- KCLS
-        -- DELETE FROM metabib.browse_entry_def_map WHERE source = NEW.id; -- Don't auto-suggest deleted bibs
-        DELETE FROM metabib.browse_author_entry_def_map WHERE source = NEW.id;
-        DELETE FROM metabib.browse_series_entry_def_map WHERE source = NEW.id;
-        DELETE FROM metabib.browse_subject_entry_def_map WHERE source = NEW.id;
-        DELETE FROM metabib.browse_title_entry_def_map WHERE source = NEW.id;
-        DELETE FROM metabib.browse_call_number_entry_def_map WHERE source = NEW.id;
-        -- /KCLS
-        RETURN NEW; -- and we're done
-    END IF;
-
-    IF TG_OP = 'UPDATE' THEN -- re-ingest?
-        PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
-
-        IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
-            RETURN NEW;
-        END IF;
-    END IF;
-
-    -- Record authority linking
-    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_linking' AND enabled;
-    IF NOT FOUND THEN
-        PERFORM biblio.map_authority_linking( NEW.id, NEW.marc );
-    END IF;
-
-    -- Flatten and insert the mfr data
-    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_full_rec' AND enabled;
-    IF NOT FOUND THEN
-        PERFORM metabib.reingest_metabib_full_rec(NEW.id);
-
-        -- Now we pull out attribute data, which is dependent on the mfr for all but XPath-based fields
-        PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_rec_descriptor' AND enabled;
-        IF NOT FOUND THEN
-            PERFORM metabib.reingest_record_attributes(NEW.id, NULL, NEW.marc, TG_OP = 'INSERT' OR OLD.deleted);
-        END IF;
-    END IF;
-
-    -- Gather and insert the field entry data
-    PERFORM metabib.reingest_metabib_field_entries(NEW.id);
-
-    -- Located URI magic
-    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_located_uri' AND enabled;
-    IF NOT FOUND THEN PERFORM biblio.extract_located_uris( NEW.id, NEW.marc, NEW.editor ); END IF;
-
-    -- (re)map metarecord-bib linking
-    IF TG_OP = 'INSERT' THEN -- if not deleted and performing an insert, check for the flag
-        PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_insert' AND enabled;
-        IF NOT FOUND THEN
-            PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
-        END IF;
-    ELSE -- we're doing an update, and we're not deleted, remap
-        PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_update' AND enabled;
-        IF NOT FOUND THEN
-            PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
-        END IF;
-    END IF;
-
-    RETURN NEW;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-
--- SELECT evergreen.upgrade_deps_block_check('1074', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
-
-INSERT INTO config.internal_flag (name, enabled) 
-    VALUES ('ingest.skip_display_indexing', FALSE);
-
--- Adds seed data to replace (for now) values from the 'mvr' class
-
-UPDATE config.metabib_field SET display_field = TRUE WHERE id IN (6, 8, 16, 18);
-
-INSERT INTO config.metabib_field ( id, field_class, name, label,
-    format, xpath, display_field, display_xpath ) VALUES
-    (37, 'author', 'creator', oils_i18n_gettext(37, 'All Creators', 'cmf', 'label'),
-     'mods32', $$//mods32:mods/mods32:name[mods32:role/mods32:roleTerm[text()='creator']]$$, 
-     TRUE, $$//*[local-name()='namePart']$$ ); -- /* to fool vim */;
-
--- 'author' field
-UPDATE config.metabib_field SET display_xpath = 
-    $$//*[local-name()='namePart']$$ -- /* to fool vim */
-    WHERE id = 8;
-
-INSERT INTO config.display_field_map (name, field, multi) VALUES
-    ('title', 6, FALSE),
-    ('author', 8, FALSE),
-    ('creators', 37, TRUE),
-    ('subject', 16, TRUE),
-    ('isbn', 18, TRUE)
-;
-END IF; END $INSERT$;                                                          
-
-
--- SELECT evergreen.upgrade_deps_block_check('1075', :eg_version);
-
-CREATE OR REPLACE FUNCTION evergreen.vandelay_import_item_imported_as_inh_fkey() RETURNS TRIGGER AS $f$
-BEGIN   
-        IF NEW.imported_as IS NULL THEN
-                RETURN NEW;
-        END IF;
-        PERFORM 1 FROM asset.copy WHERE id = NEW.imported_as;
-        IF NOT FOUND THEN
-                RAISE foreign_key_violation USING MESSAGE = FORMAT(
-                        $$Referenced asset.copy id not found, imported_as:%s$$, NEW.imported_as
-                );
-        END IF;
-        RETURN NEW;
-END;
-$f$ LANGUAGE PLPGSQL VOLATILE COST 50;
-
--- SELECT evergreen.upgrade_deps_block_check('1077', :eg_version); -- csharp/gmcharlt
-
--- if the "public" version of this function exists, drop it to prevent confusion/trouble
-
--- drop triggers that depend on this first
-DROP TRIGGER IF EXISTS c_maintain_control_numbers ON biblio.record_entry;
-DROP TRIGGER IF EXISTS c_maintain_control_numbers ON serial.record_entry;
-DROP TRIGGER IF EXISTS c_maintain_control_numbers ON authority.record_entry;
-
-DROP FUNCTION IF EXISTS public.maintain_control_numbers();
-
--- create the function within the "evergreen" schema
-
-CREATE OR REPLACE FUNCTION evergreen.maintain_control_numbers() RETURNS TRIGGER AS $func$
-use strict;
-use MARC::Record;
-use MARC::File::XML (BinaryEncoding => 'UTF-8');
-use MARC::Charset;
-use Encode;
-use Unicode::Normalize;
-
-MARC::Charset->assume_unicode(1);
-
-my $record = MARC::Record->new_from_xml($_TD->{new}{marc});
-my $schema = $_TD->{table_schema};
-my $rec_id = $_TD->{new}{id};
-
-# Short-circuit if maintaining control numbers per MARC21 spec is not enabled
-my $enable = spi_exec_query("SELECT enabled FROM config.global_flag WHERE name = 'cat.maintain_control_numbers'");
-if (!($enable->{processed}) or $enable->{rows}[0]->{enabled} eq 'f') {
-    return;
-}
-
-# Get the control number identifier from an OU setting based on $_TD->{new}{owner}
-my $ou_cni = 'EVRGRN';
-
-my $owner;
-if ($schema eq 'serial') {
-    $owner = $_TD->{new}{owning_lib};
-} else {
-    # are.owner and bre.owner can be null, so fall back to the consortial setting
-    $owner = $_TD->{new}{owner} || 1;
-}
-
-my $ous_rv = spi_exec_query("SELECT value FROM actor.org_unit_ancestor_setting('cat.marc_control_number_identifier', $owner)");
-if ($ous_rv->{processed}) {
-    $ou_cni = $ous_rv->{rows}[0]->{value};
-    $ou_cni =~ s/"//g; # Stupid VIM syntax highlighting"
-} else {
-    # Fall back to the shortname of the OU if there was no OU setting
-    $ous_rv = spi_exec_query("SELECT shortname FROM actor.org_unit WHERE id = $owner");
-    if ($ous_rv->{processed}) {
-        $ou_cni = $ous_rv->{rows}[0]->{shortname};
-    }
-}
-
-my ($create, $munge) = (0, 0);
-
-my @scns = $record->field('035');
-
-foreach my $id_field ('001', '003') {
-    my $spec_value;
-    my @controls = $record->field($id_field);
-
-    if ($id_field eq '001') {
-        $spec_value = $rec_id;
-    } else {
-        $spec_value = $ou_cni;
-    }
-
-    # Create the 001/003 if none exist
-    if (scalar(@controls) == 1) {
-        # Only one field; check to see if we need to munge it
-        unless (grep $_->data() eq $spec_value, @controls) {
-            $munge = 1;
-        }
-    } else {
-        # Delete the other fields, as with more than 1 001/003 we do not know which 003/001 to match
-        foreach my $control (@controls) {
-            $record->delete_field($control);
-        }
-        $record->insert_fields_ordered(MARC::Field->new($id_field, $spec_value));
-        $create = 1;
-    }
-}
-
-my $cn = $record->field('001')->data();
-# Special handling of OCLC numbers, often found in records that lack 003
-if ($cn =~ /^o(c[nm]|n)\d/) {
-    $cn =~ s/^o(c[nm]|n)0*(\d+)/$2/;
-    $record->field('003')->data('OCoLC');
-    $create = 0;
-}
-
-# Now, if we need to munge the 001, we will first push the existing 001/003
-# into the 035; but if the record did not have one (and one only) 001 and 003
-# to begin with, skip this process
-if ($munge and not $create) {
-
-    my $scn = "(" . $record->field('003')->data() . ")" . $cn;
-
-    # Do not create duplicate 035 fields
-    unless (grep $_->subfield('a') eq $scn, @scns) {
-        $record->insert_fields_ordered(MARC::Field->new('035', '', '', 'a' => $scn));
-    }
-}
-
-# Set the 001/003 and update the MARC
-if ($create or $munge) {
-    $record->field('001')->data($rec_id);
-    $record->field('003')->data($ou_cni);
-
-    my $xml = $record->as_xml_record();
-    $xml =~ s/\n//sgo;
-    $xml =~ s/^<\?xml.+\?\s*>//go;
-    $xml =~ s/>\s+</></go;
-    $xml =~ s/\p{Cc}//go;
-
-    # Embed a version of OpenILS::Application::AppUtils->entityize()
-    # to avoid having to set PERL5LIB for PostgreSQL as well
-
-    $xml = NFC($xml);
-
-    # Convert raw ampersands to entities
-    $xml =~ s/&(?!\S+;)/&amp;/gso;
-
-    # Convert Unicode characters to entities
-    $xml =~ s/([\x{0080}-\x{fffd}])/sprintf('&#x%X;',ord($1))/sgoe;
-
-    $xml =~ s/[\x00-\x1f]//go;
-    $_TD->{new}{marc} = $xml;
-
-    return "MODIFY";
-}
-
-return;
-$func$ LANGUAGE PLPERLU;
-
--- re-create the triggers
-CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON serial.record_entry FOR EACH ROW EXECUTE PROCEDURE evergreen.maintain_control_numbers();
-CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON authority.record_entry FOR EACH ROW EXECUTE PROCEDURE evergreen.maintain_control_numbers();
-CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE evergreen.maintain_control_numbers();
-
--- INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.1', :eg_version);
--- PERFORM evergreen.upgrade_deps_block_check('1078', :eg_version); -- csharp/bshum/gmcharlt
-
-/* KCLS ALREADY HAS 
-DO $INSERT$
-BEGIN
-    IF evergreen.insert_on_deploy() THEN
-INSERT INTO config.billing_type (id, name, owner)
-    SELECT 7, 'Damaged Item', 1
-    WHERE NOT EXISTS (SELECT 1 FROM config.billing_type WHERE name = 'Damaged Item');
-
-INSERT INTO config.billing_type (id, name, owner)
-    SELECT 8, 'Damaged Item Processing Fee', 1
-    WHERE NOT EXISTS (SELECT 1 FROM config.billing_type WHERE name = 'Damaged Item Processing Fee');
-
-INSERT INTO config.billing_type (id, name, owner)
-    SELECT 9, 'Notification Fee', 1
-    WHERE NOT EXISTS (SELECT 1 FROM config.billing_type WHERE name = 'Notification Fee');
-    END IF;
-END $INSERT$;
-*/
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.2', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1079', :eg_version); -- rhamby/cesardv/gmcharlt
--- KCLS ALREADY HAS - FUNC UPDATE WON'T HURT, MIGHT HELP
-
-CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
-DECLARE
-    moved_objects INT := 0;
-    source_cn     asset.call_number%ROWTYPE;
-    target_cn     asset.call_number%ROWTYPE;
-    metarec       metabib.metarecord%ROWTYPE;
-    hold          action.hold_request%ROWTYPE;
-    ser_rec       serial.record_entry%ROWTYPE;
-    ser_sub       serial.subscription%ROWTYPE;
-    acq_lineitem  acq.lineitem%ROWTYPE;
-    acq_request   acq.user_request%ROWTYPE;
-    booking       booking.resource_type%ROWTYPE;
-    source_part   biblio.monograph_part%ROWTYPE;
-    target_part   biblio.monograph_part%ROWTYPE;
-    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
-    uri_count     INT := 0;
-    counter       INT := 0;
-    uri_datafield TEXT;
-    uri_text      TEXT := '';
-BEGIN
-
-    -- move any 856 entries on records that have at least one MARC-mapped URI entry
-    SELECT  INTO uri_count COUNT(*)
-      FROM  asset.uri_call_number_map m
-            JOIN asset.call_number cn ON (m.call_number = cn.id)
-      WHERE cn.record = source_record;
-
-    IF uri_count > 0 THEN
-        
-        -- This returns more nodes than you might expect:
-        -- 7 instead of 1 for an 856 with $u $y $9
-        SELECT  COUNT(*) INTO counter
-          FROM  oils_xpath_table(
-                    'id',
-                    'marc',
-                    'biblio.record_entry',
-                    '//*[@tag="856"]',
-                    'id=' || source_record
-                ) as t(i int,c text);
-    
-        FOR i IN 1 .. counter LOOP
-            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
-                       ' tag="856"' ||
-                       ' ind1="' || FIRST(ind1) || '"'  ||
-                       ' ind2="' || FIRST(ind2) || '">' ||
-                        STRING_AGG(
-                            '<subfield code="' || subfield || '">' ||
-                            regexp_replace(
-                                regexp_replace(
-                                    regexp_replace(data,'&','&amp;','g'),
-                                    '>', '&gt;', 'g'
-                                ),
-                                '<', '&lt;', 'g'
-                            ) || '</subfield>', ''
-                        ) || '</datafield>' INTO uri_datafield
-              FROM  oils_xpath_table(
-                        'id',
-                        'marc',
-                        'biblio.record_entry',
-                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
-                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
-                        'id=' || source_record
-                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
-
-            -- As most of the results will be NULL, protect against NULLifying
-            -- the valid content that we do generate
-            uri_text := uri_text || COALESCE(uri_datafield, '');
-        END LOOP;
-
-        IF uri_text <> '' THEN
-            UPDATE  biblio.record_entry
-              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
-              WHERE id = target_record;
-        END IF;
-
-    END IF;
-
-       -- Find and move metarecords to the target record
-       SELECT  INTO metarec *
-         FROM  metabib.metarecord
-         WHERE master_record = source_record;
-
-       IF FOUND THEN
-               UPDATE  metabib.metarecord
-                 SET   master_record = target_record,
-                       mods = NULL
-                 WHERE id = metarec.id;
-
-               moved_objects := moved_objects + 1;
-       END IF;
-
-       -- Find call numbers attached to the source ...
-       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
-
-               SELECT  INTO target_cn *
-                 FROM  asset.call_number
-                 WHERE label = source_cn.label
-            AND prefix = source_cn.prefix
-            AND suffix = source_cn.suffix
-                       AND owning_lib = source_cn.owning_lib
-                       AND record = target_record
-                       AND NOT deleted;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copies to that, and ...
-                       UPDATE  asset.copy
-                         SET   call_number = target_cn.id
-                         WHERE call_number = source_cn.id;
-
-                       -- ... move V holds to the move-target call number
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_cn.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-        
-            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the call number to the target record
-                       UPDATE  asset.call_number
-                         SET   record = target_record
-                         WHERE id = source_cn.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find T holds targeting the source record ...
-       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
-
-               -- ... and move them to the target record
-               UPDATE  action.hold_request
-                 SET   target = target_record
-                 WHERE id = hold.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial records targeting the source record ...
-       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.record_entry
-                 SET   record = target_record
-                 WHERE id = ser_rec.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial subscriptions targeting the source record ...
-       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.subscription
-                 SET   record_entry = target_record
-                 WHERE id = ser_sub.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find booking resource types targeting the source record ...
-       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  booking.resource_type
-                 SET   record = target_record
-                 WHERE id = booking.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq lineitems targeting the source record ...
-       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.lineitem
-                 SET   eg_bib_id = target_record
-                 WHERE id = acq_lineitem.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq user purchase requests targeting the source record ...
-       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.user_request
-                 SET   eg_bib = target_record
-                 WHERE id = acq_request.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find parts attached to the source ...
-       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
-
-               SELECT  INTO target_part *
-                 FROM  biblio.monograph_part
-                 WHERE label = source_part.label
-                       AND record = target_record;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copy-part maps to that, and ...
-                       UPDATE  asset.copy_part_map
-                         SET   part = target_part.id
-                         WHERE part = source_part.id;
-
-                       -- ... move P holds to the move-target part
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_part.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the part to the target record
-                       UPDATE  biblio.monograph_part
-                         SET   record = target_record
-                         WHERE id = source_part.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find multi_home items attached to the source ...
-       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  biblio.peer_bib_copy_map
-                 SET   peer_record = target_record
-                 WHERE id = multi_home.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- And delete mappings where the item's home bib was merged with the peer bib
-       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
-               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
-               FROM asset.copy WHERE id = target_copy
-       );
-
-    -- Finally, "delete" the source record
-    DELETE FROM biblio.record_entry WHERE id = source_record;
-
-       -- That's all, folks!
-       RETURN moved_objects;
-END;
-$func$ LANGUAGE plpgsql;
-
-
---SELECT evergreen.upgrade_deps_block_check('1080', :eg_version); -- miker/jboyer/gmcharlt
-
-CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
-DECLARE
-    ocn     asset.call_number%ROWTYPE;
-    ncn     asset.call_number%ROWTYPE;
-    cid     BIGINT;
-BEGIN
-
-    IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN -- Only needs ON INSERT OR DELETE, so handle separately
-        IF TG_OP = 'INSERT' THEN
-            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                NEW.peer_record,
-                NEW.target_copy,
-                asset.calculate_copy_visibility_attribute_set(NEW.target_copy)
-            );
-
-            RETURN NEW;
-        ELSIF TG_OP = 'DELETE' THEN
-            DELETE FROM asset.copy_vis_attr_cache
-              WHERE record = OLD.peer_record AND target_copy = OLD.target_copy;
-
-            RETURN OLD;
-        END IF;
-    END IF;
-
-    IF TG_OP = 'INSERT' THEN -- Handles ON INSERT. ON UPDATE is below.
-        IF TG_TABLE_NAME IN ('copy', 'unit') THEN
-            SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
-            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                ncn.record,
-                NEW.id,
-                asset.calculate_copy_visibility_attribute_set(NEW.id)
-            );
-        ELSIF TG_TABLE_NAME = 'record_entry' THEN
-            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
-        END IF;
-
-        RETURN NEW;
-    END IF;
-
-    -- handle items first, since with circulation activity
-    -- their statuses change frequently
-    IF TG_TABLE_NAME IN ('copy', 'unit') THEN -- This handles ON UPDATE OR DELETE. ON INSERT above
-
-        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
-            DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
-            RETURN OLD;
-        END IF;
-
-        SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
-
-        IF OLD.deleted <> NEW.deleted THEN
-            IF NEW.deleted THEN
-                DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
-            ELSE
-                INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                    ncn.record,
-                    NEW.id,
-                    asset.calculate_copy_visibility_attribute_set(NEW.id)
-                );
-            END IF;
-
-            RETURN NEW;
-        ELSIF OLD.call_number  <> NEW.call_number THEN
-            SELECT * INTO ocn FROM asset.call_number cn WHERE id = OLD.call_number;
-
-            IF ncn.record <> ocn.record THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(ncn.record)
-                  WHERE id = ocn.record;
-
-                -- We have to use a record-specific WHERE clause
-                -- to avoid modifying the entries for peer-bib copies.
-                UPDATE  asset.copy_vis_attr_cache
-                  SET   target_copy = NEW.id,
-                        record = ncn.record
-                  WHERE target_copy = OLD.id
-                        AND record = ocn.record;
-            END IF;
-        END IF;
-
-        IF OLD.location     <> NEW.location OR
-           OLD.status       <> NEW.status OR
-           OLD.opac_visible <> NEW.opac_visible OR
-           OLD.circ_lib     <> NEW.circ_lib
-        THEN
-            -- Any of these could change visibility, but
-            -- we'll save some queries and not try to calculate
-            -- the change directly.  We want to update peer-bib
-            -- entries in this case, unlike above.
-            UPDATE  asset.copy_vis_attr_cache
-              SET   target_copy = NEW.id,
-                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(NEW.id)
-              WHERE target_copy = OLD.id;
-
-        END IF;
-
-    ELSIF TG_TABLE_NAME = 'call_number' THEN -- Only ON UPDATE. Copy handler will deal with ON INSERT OR DELETE.
-
-        IF OLD.record <> NEW.record THEN
-            IF NEW.label = '##URI##' THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
-                  WHERE id = OLD.record;
-
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
-                  WHERE id = NEW.record;
-            END IF;
-
-            UPDATE  asset.copy_vis_attr_cache
-              SET   record = NEW.record,
-                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
-              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
-                    AND record = OLD.record;
-
-        ELSIF OLD.owning_lib <> NEW.owning_lib THEN
-            UPDATE  asset.copy_vis_attr_cache
-              SET   vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
-              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
-                    AND record = NEW.record;
-
-            IF NEW.label = '##URI##' THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
-                  WHERE id = OLD.record;
-            END IF;
-        END IF;
-
-    ELSIF TG_TABLE_NAME = 'record_entry' THEN -- Only handles ON UPDATE OR DELETE
-
-        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
-            DELETE FROM asset.copy_vis_attr_cache WHERE record = OLD.id;
-            RETURN OLD;
-        ELSIF OLD.source <> NEW.source THEN
-            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id);
-        END IF;
-
-    END IF;
-
-    RETURN NEW;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-
---SELECT evergreen.upgrade_deps_block_check('1081', :eg_version); -- jboyer/gmcharlt
-
-DROP TRIGGER IF EXISTS inherit_copy_bucket_item_target_copy_fkey ON container.copy_bucket_item;
-DROP TRIGGER IF EXISTS inherit_import_item_imported_as_fkey ON vandelay.import_item;
-DROP TRIGGER IF EXISTS inherit_asset_copy_note_copy_fkey ON asset.copy_note;
-DROP TRIGGER IF EXISTS inherit_asset_copy_tag_copy_map_copy_fkey ON asset.copy_tag_copy_map;
-
-CREATE CONSTRAINT TRIGGER inherit_copy_bucket_item_target_copy_fkey
-  AFTER UPDATE OR INSERT ON container.copy_bucket_item
-  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.container_copy_bucket_item_target_copy_inh_fkey();
-CREATE CONSTRAINT TRIGGER inherit_import_item_imported_as_fkey
-  AFTER UPDATE OR INSERT ON vandelay.import_item
-  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.vandelay_import_item_imported_as_inh_fkey();
-CREATE CONSTRAINT TRIGGER inherit_asset_copy_note_copy_fkey
-  AFTER UPDATE OR INSERT ON asset.copy_note
-  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_note_owning_copy_inh_fkey();
-CREATE CONSTRAINT TRIGGER inherit_asset_copy_tag_copy_map_copy_fkey
-  AFTER UPDATE OR INSERT ON asset.copy_tag_copy_map
-  DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_tag_copy_map_copy_inh_fkey();
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1082', :eg_version); -- jboyer/gmcharlt
-
-DELETE FROM asset.copy_vis_attr_cache WHERE target_copy IN (SELECT id FROM asset.copy WHERE deleted);
-
--- Evergreen DB patch XXXX.schema.qualify_unaccent_refs.sql
---
--- LP#1671150 Fix unaccent() function call in evergreen.unaccent_and_squash()
---
-
-
--- check whether patch can be applied
---SELECT evergreen.upgrade_deps_block_check('1083', :eg_version);
-
-/* KCLS ALREADY HAS
-CREATE OR REPLACE FUNCTION evergreen.unaccent_and_squash ( IN arg text) RETURNS text
-    IMMUTABLE STRICT AS $$
-        BEGIN
-        RETURN evergreen.lowercase(public.unaccent('public.unaccent', regexp_replace(arg, '[\s[:punct:]]','','g')));
-        END;
-$$ LANGUAGE PLPGSQL;
-
--- Drop indexes if present, so that we can re-create them
-DROP INDEX IF EXISTS actor.actor_usr_first_given_name_unaccent_idx;
-DROP INDEX IF EXISTS actor.actor_usr_second_given_name_unaccent_idx;
-DROP INDEX IF EXISTS actor.actor_usr_family_name_unaccent_idx; 
-DROP INDEX IF EXISTS actor.actor_usr_usrname_unaccent_idx; 
-
--- Create (or re-create) indexes -- they may be missing if pg_restore failed to create
--- them due to the previously unqualified call to unaccent()
-CREATE INDEX actor_usr_first_given_name_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(first_given_name));
-CREATE INDEX actor_usr_second_given_name_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(second_given_name));
-CREATE INDEX actor_usr_family_name_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(family_name));
-CREATE INDEX actor_usr_usrname_unaccent_idx ON actor.usr (evergreen.unaccent_and_squash(usrname));
-*/
-
---SELECT evergreen.upgrade_deps_block_check('1084', :eg_version);
-DO $INSERT$
-BEGIN
-    IF evergreen.insert_on_deploy() THEN
-INSERT INTO config.usr_setting_type (name, label, description, datatype)
-  VALUES ('webstaff.cat.copy.templates', 'Web Client Copy Editor Templates', 
-    'Web Client Copy Editor Templates', 'object');
-    END IF;
-END $INSERT$;
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.3', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1085', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.calculate_copy_visibility_attribute_set ( copy_id BIGINT ) RETURNS INT[] AS $f$
-DECLARE
-    copy_row    asset.copy%ROWTYPE;
-    lgroup_map  asset.copy_location_group_map%ROWTYPE;
-    attr_set    INT[] := '{}'::INT[];
-BEGIN
-    SELECT * INTO copy_row FROM asset.copy WHERE id = copy_id;
-
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.opac_visible::INT, 'copy_flags');
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.circ_lib, 'circ_lib');
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.status, 'status');
-    attr_set := attr_set || search.calculate_visibility_attribute(copy_row.location, 'location');
-
-    SELECT  ARRAY_APPEND(
-                attr_set,
-                search.calculate_visibility_attribute(owning_lib, 'owning_lib')
-            ) INTO attr_set
-      FROM  asset.call_number
-      WHERE id = copy_row.call_number;
-
-    FOR lgroup_map IN SELECT * FROM asset.copy_location_group_map WHERE location = copy_row.location LOOP
-        attr_set := attr_set || search.calculate_visibility_attribute(lgroup_map.lgroup, 'location_group');
-    END LOOP;
-
-    RETURN attr_set;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-DROP FUNCTION IF EXISTS biblio.calculate_bib_visibility_attribute_set ( BIGINT );
-CREATE OR REPLACE FUNCTION biblio.calculate_bib_visibility_attribute_set ( bib_id BIGINT, new_source INT DEFAULT NULL, force_source BOOL DEFAULT FALSE ) RETURNS INT[] AS $f$
-DECLARE
-    bib_row     biblio.record_entry%ROWTYPE;
-    cn_row      asset.call_number%ROWTYPE;
-    attr_set    INT[] := '{}'::INT[];
-BEGIN
-    SELECT * INTO bib_row FROM biblio.record_entry WHERE id = bib_id;
-
-    IF force_source THEN
-        IF new_source IS NOT NULL THEN
-            attr_set := attr_set || search.calculate_visibility_attribute(new_source, 'bib_source');
-        END IF;
-    ELSIF bib_row.source IS NOT NULL THEN
-        attr_set := attr_set || search.calculate_visibility_attribute(bib_row.source, 'bib_source');
-    END IF;
-
-    FOR cn_row IN
-        SELECT  *
-          FROM  asset.call_number
-          WHERE record = bib_id
-                AND label = '##URI##'
-                AND NOT deleted
-    LOOP
-        attr_set := attr_set || search.calculate_visibility_attribute(cn_row.owning_lib, 'luri_org');
-    END LOOP;
-
-    RETURN attr_set;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
-DECLARE
-    ocn     asset.call_number%ROWTYPE;
-    ncn     asset.call_number%ROWTYPE;
-    cid     BIGINT;
-    dobib   BOOL;
-BEGIN
-
-    SELECT enabled = FALSE INTO dobib FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc';
-
-    IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN -- Only needs ON INSERT OR DELETE, so handle separately
-        IF TG_OP = 'INSERT' THEN
-            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                NEW.peer_record,
-                NEW.target_copy,
-                asset.calculate_copy_visibility_attribute_set(NEW.target_copy)
-            );
-
-            RETURN NEW;
-        ELSIF TG_OP = 'DELETE' THEN
-            DELETE FROM asset.copy_vis_attr_cache
-              WHERE record = OLD.peer_record AND target_copy = OLD.target_copy;
-
-            RETURN OLD;
-        END IF;
-    END IF;
-
-    IF TG_OP = 'INSERT' THEN -- Handles ON INSERT. ON UPDATE is below.
-        IF TG_TABLE_NAME IN ('copy', 'unit') THEN
-            SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
-            INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                ncn.record,
-                NEW.id,
-                asset.calculate_copy_visibility_attribute_set(NEW.id)
-            );
-        ELSIF TG_TABLE_NAME = 'record_entry' THEN
-            NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id, NEW.source, TRUE);
-        ELSIF TG_TABLE_NAME = 'call_number' AND NEW.label = '##URI##' AND dobib THEN -- New located URI
-            UPDATE  biblio.record_entry
-              SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
-              WHERE id = NEW.record;
-
-        END IF;
-
-        RETURN NEW;
-    END IF;
-
-    -- handle items first, since with circulation activity
-    -- their statuses change frequently
-    IF TG_TABLE_NAME IN ('copy', 'unit') THEN -- This handles ON UPDATE OR DELETE. ON INSERT above
-
-        IF TG_OP = 'DELETE' THEN -- Shouldn't get here, normally
-            DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
-            RETURN OLD;
-        END IF;
-
-        SELECT * INTO ncn FROM asset.call_number cn WHERE id = NEW.call_number;
-
-        IF OLD.deleted <> NEW.deleted THEN
-            IF NEW.deleted THEN
-                DELETE FROM asset.copy_vis_attr_cache WHERE target_copy = OLD.id;
-            ELSE
-                INSERT INTO asset.copy_vis_attr_cache (record, target_copy, vis_attr_vector) VALUES (
-                    ncn.record,
-                    NEW.id,
-                    asset.calculate_copy_visibility_attribute_set(NEW.id)
-                );
-            END IF;
-
-            RETURN NEW;
-        ELSIF OLD.location   <> NEW.location OR
-            OLD.status       <> NEW.status OR
-            OLD.opac_visible <> NEW.opac_visible OR
-            OLD.circ_lib     <> NEW.circ_lib OR
-            OLD.call_number  <> NEW.call_number
-        THEN
-            IF OLD.call_number  <> NEW.call_number THEN -- Special check since it's more expensive than the next branch
-                SELECT * INTO ocn FROM asset.call_number cn WHERE id = OLD.call_number;
-
-                IF ncn.record <> ocn.record THEN
-                    -- We have to use a record-specific WHERE clause
-                    -- to avoid modifying the entries for peer-bib copies.
-                    UPDATE  asset.copy_vis_attr_cache
-                      SET   target_copy = NEW.id,
-                            record = ncn.record
-                      WHERE target_copy = OLD.id
-                            AND record = ocn.record;
-
-                END IF;
-            ELSE
-                -- Any of these could change visibility, but
-                -- we'll save some queries and not try to calculate
-                -- the change directly.  We want to update peer-bib
-                -- entries in this case, unlike above.
-                UPDATE  asset.copy_vis_attr_cache
-                  SET   target_copy = NEW.id,
-                        vis_attr_vector = asset.calculate_copy_visibility_attribute_set(NEW.id)
-                  WHERE target_copy = OLD.id;
-            END IF;
-        END IF;
-
-    ELSIF TG_TABLE_NAME = 'call_number' THEN
-
-        IF TG_OP = 'DELETE' AND OLD.label = '##URI##' AND dobib THEN -- really deleted located URI, if the delete protection rule is disabled...
-            UPDATE  biblio.record_entry
-              SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
-              WHERE id = OLD.record;
-            RETURN OLD;
-        END IF;
-
-        IF OLD.label = '##URI##' AND dobib THEN -- Located URI
-            IF OLD.deleted <> NEW.deleted OR OLD.record <> NEW.record OR OLD.owning_lib <> NEW.owning_lib THEN
-                UPDATE  biblio.record_entry
-                  SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(NEW.record)
-                  WHERE id = NEW.record;
-
-                IF OLD.record <> NEW.record THEN -- maybe on merge?
-                    UPDATE  biblio.record_entry
-                      SET   vis_attr_vector = biblio.calculate_bib_visibility_attribute_set(OLD.record)
-                      WHERE id = OLD.record;
-                END IF;
-            END IF;
-
-        ELSIF OLD.record <> NEW.record OR OLD.owning_lib <> NEW.owning_lib THEN
-            UPDATE  asset.copy_vis_attr_cache
-              SET   record = NEW.record,
-                    vis_attr_vector = asset.calculate_copy_visibility_attribute_set(target_copy)
-              WHERE target_copy IN (SELECT id FROM asset.copy WHERE call_number = NEW.id)
-                    AND record = OLD.record;
-
-        END IF;
-
-    ELSIF TG_TABLE_NAME = 'record_entry' AND OLD.source IS DISTINCT FROM NEW.source THEN -- Only handles ON UPDATE, INSERT above
-        NEW.vis_attr_vector := biblio.calculate_bib_visibility_attribute_set(NEW.id, NEW.source, TRUE);
-    END IF;
-
-    RETURN NEW;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-/* created again later in the data file
-DROP TRIGGER IF EXISTS z_opac_vis_mat_view_tgr ON asset.call_number;
-DROP TRIGGER IF EXISTS z_opac_vis_mat_view_tgr ON biblio.record_entry;
-CREATE TRIGGER z_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE OR DELETE ON asset.call_number FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-CREATE TRIGGER z_opac_vis_mat_view_tgr BEFORE INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
-*/
-
---SELECT evergreen.upgrade_deps_block_check('1086', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.location_group_default () RETURNS TEXT AS $f$
-    SELECT '!()'::TEXT; -- For now, as there's no way to cause a location group to hide all copies.
-/*
-    SELECT  '!(' || ARRAY_TO_STRING(ARRAY_AGG(search.calculate_visibility_attribute(id, 'location_group')),'|') || ')'
-      FROM  asset.copy_location_group
-      WHERE NOT opac_visible;
-*/
-$f$ LANGUAGE SQL IMMUTABLE;
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1087', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.patron_default_visibility_mask () RETURNS TABLE (b_attrs TEXT, c_attrs TEXT)  AS $f$
-DECLARE
-    copy_flags      TEXT; -- "c" attr
-
-    owning_lib      TEXT; -- "c" attr
-    circ_lib        TEXT; -- "c" attr
-    status          TEXT; -- "c" attr
-    location        TEXT; -- "c" attr
-    location_group  TEXT; -- "c" attr
-
-    luri_org        TEXT; -- "b" attr
-    bib_sources     TEXT; -- "b" attr
-
-    bib_tests       TEXT := '';
-BEGIN
-    copy_flags      := asset.all_visible_flags(); -- Will always have at least one
-
-    owning_lib      := NULLIF(asset.owning_lib_default(),'!()');
-
-    circ_lib        := NULLIF(asset.circ_lib_default(),'!()');
-    status          := NULLIF(asset.status_default(),'!()');
-    location        := NULLIF(asset.location_default(),'!()');
-    location_group  := NULLIF(asset.location_group_default(),'!()');
-
-    -- LURIs will be handled at the perl layer directly
-    -- luri_org        := NULLIF(asset.luri_org_default(),'!()');
-    bib_sources     := NULLIF(asset.bib_source_default(),'()');
-
-
-    IF luri_org IS NOT NULL AND bib_sources IS NOT NULL THEN
-        bib_tests := '('||ARRAY_TO_STRING( ARRAY[luri_org,bib_sources], '|')||')&('||luri_org||')&';
-    ELSIF luri_org IS NOT NULL THEN
-        bib_tests := luri_org || '&';
-    ELSIF bib_sources IS NOT NULL THEN
-        bib_tests := bib_sources || '|';
-    END IF;
-
-    RETURN QUERY SELECT bib_tests,
-        '('||ARRAY_TO_STRING(
-            ARRAY[copy_flags,owning_lib,circ_lib,status,location,location_group]::TEXT[],
-            '&'
-        )||')';
-END;
-$f$ LANGUAGE PLPGSQL STABLE ROWS 1;
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.4', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1088', :eg_version);
-
-CREATE OR REPLACE FUNCTION metabib.staged_browse(query text, fields integer[], context_org integer, context_locations integer[], staff boolean, browse_superpage_size integer, count_up_from_zero boolean, result_limit integer, next_pivot_pos integer)
- RETURNS SETOF metabib.flat_browse_entry_appearance
-AS $f$
-DECLARE
-    curs                    REFCURSOR;
-    rec                     RECORD;
-    qpfts_query             TEXT;
-    aqpfts_query            TEXT;
-    afields                 INT[];
-    bfields                 INT[];
-    result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
-    results_skipped         INT := 0;
-    row_counter             INT := 0;
-    row_number              INT;
-    slice_start             INT;
-    slice_end               INT;
-    full_end                INT;
-    all_records             BIGINT[];
-    all_brecords             BIGINT[];
-    all_arecords            BIGINT[];
-    superpage_of_records    BIGINT[];
-    superpage_size          INT;
-    c_tests                 TEXT := '';
-    b_tests                 TEXT := '';
-    c_orgs                  INT[];
-    unauthorized_entry      RECORD;
-BEGIN
-    IF count_up_from_zero THEN
-        row_number := 0;
-    ELSE
-        row_number := -1;
-    END IF;
-
-    IF NOT staff THEN
-        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
-    END IF;
-
-    -- b_tests supplies its own query_int operator, c_tests does not
-    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
-
-    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
-
-    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
-               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
-
-    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
-    IF FOUND THEN
-        b_tests := b_tests || search.calculate_visibility_attribute_test(
-            'luri_org',
-            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
-        );
-    ELSE
-        b_tests := b_tests || search.calculate_visibility_attribute_test(
-            'luri_org',
-            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
-        );
-    END IF;
-
-    IF context_locations THEN
-        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
-        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_locations);
-    END IF;
-
-    OPEN curs NO SCROLL FOR EXECUTE query;
-
-    LOOP
-        FETCH curs INTO rec;
-        IF NOT FOUND THEN
-            IF result_row.pivot_point IS NOT NULL THEN
-                RETURN NEXT result_row;
-            END IF;
-            RETURN;
-        END IF;
-
-        --Is unauthorized?
-        SELECT INTO unauthorized_entry *
-        FROM metabib.browse_entry_simple_heading_map mbeshm
-        INNER JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-        INNER JOIN authority.control_set_authority_field acsaf ON ( acsaf.id = ash.atag )
-        JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
-        WHERE mbeshm.entry = rec.id
-        AND   ahf.heading_purpose = 'variant';
-
-        -- Gather aggregate data based on the MBE row we're looking at now, authority axis
-        IF (unauthorized_entry.record IS NOT NULL) THEN
-            --unauthorized term belongs to an auth linked to a bib?
-            SELECT INTO all_arecords, result_row.sees, afields
-                    ARRAY_AGG(DISTINCT abl.bib),
-                    STRING_AGG(DISTINCT abl.authority::TEXT, $$,$$),
-                    ARRAY_AGG(DISTINCT map.metabib_field)
-            FROM authority.bib_linking abl
-            INNER JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                    map.authority_field = unauthorized_entry.atag
-                    AND map.metabib_field = ANY(fields)
-            )
-            WHERE abl.authority = unauthorized_entry.record;
-        ELSE
-            --do usual procedure
-            SELECT INTO all_arecords, result_row.sees, afields
-                    ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
-                    STRING_AGG(DISTINCT aal.source::TEXT, $$,$$), -- authority record ids
-                    ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
-
-            FROM  metabib.browse_entry_simple_heading_map mbeshm
-                    JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
-                    JOIN authority.authority_linking aal ON ( ash.record = aal.source )
-                    JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
-                    JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
-                        ash.atag = map.authority_field
-                        AND map.metabib_field = ANY(fields)
-                    )
-                    JOIN authority.control_set_authority_field acsaf ON (
-                        map.authority_field = acsaf.id
-                    )
-                    JOIN authority.heading_field ahf ON (ahf.id = acsaf.heading_field)
-              WHERE mbeshm.entry = rec.id
-              AND   ahf.heading_purpose = 'variant';
-
-        END IF;
-
-        -- Gather aggregate data based on the MBE row we're looking at now, bib axis
-        SELECT INTO all_brecords, result_row.authorities, bfields
-                ARRAY_AGG(DISTINCT source),
-                STRING_AGG(DISTINCT authority::TEXT, $$,$$),
-                ARRAY_AGG(DISTINCT def)
-          FROM  metabib.browse_entry_def_map
-          WHERE entry = rec.id
-                AND def = ANY(fields);
-
-        SELECT INTO result_row.fields STRING_AGG(DISTINCT x::TEXT, $$,$$) FROM UNNEST(afields || bfields) x;
-
-        result_row.sources := 0;
-        result_row.asources := 0;
-
-        -- Bib-linked vis checking
-        IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
-
-            SELECT  INTO result_row.sources COUNT(DISTINCT b.id)
-              FROM  biblio.record_entry b
-                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
-              WHERE b.id = ANY(all_brecords[1:browse_superpage_size])
-                    AND (
-                        acvac.vis_attr_vector @@ c_tests::query_int
-                        OR b.vis_attr_vector @@ b_tests::query_int
-                    );
-
-            result_row.accurate := TRUE;
-
-        END IF;
-
-        -- Authority-linked vis checking
-        IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
-
-            SELECT  INTO result_row.asources COUNT(DISTINCT b.id)
-              FROM  biblio.record_entry b
-                    JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
-              WHERE b.id = ANY(all_arecords[1:browse_superpage_size])
-                    AND (
-                        acvac.vis_attr_vector @@ c_tests::query_int
-                        OR b.vis_attr_vector @@ b_tests::query_int
-                    );
-
-            result_row.aaccurate := TRUE;
-
-        END IF;
-
-        IF result_row.sources > 0 OR result_row.asources > 0 THEN
-
-            -- The function that calls this function needs row_number in order
-            -- to correctly order results from two different runs of this
-            -- functions.
-            result_row.row_number := row_number;
-
-            -- Now, if row_counter is still less than limit, return a row.  If
-            -- not, but it is less than next_pivot_pos, continue on without
-            -- returning actual result rows until we find
-            -- that next pivot, and return it.
-
-            IF row_counter < result_limit THEN
-                result_row.browse_entry := rec.id;
-                result_row.value := rec.value;
-
-                RETURN NEXT result_row;
-            ELSE
-                result_row.browse_entry := NULL;
-                result_row.authorities := NULL;
-                result_row.fields := NULL;
-                result_row.value := NULL;
-                result_row.sources := NULL;
-                result_row.sees := NULL;
-                result_row.accurate := NULL;
-                result_row.aaccurate := NULL;
-                result_row.pivot_point := rec.id;
-
-                IF row_counter >= next_pivot_pos THEN
-                    RETURN NEXT result_row;
-                    RETURN;
-                END IF;
-            END IF;
-
-            IF count_up_from_zero THEN
-                row_number := row_number + 1;
-            ELSE
-                row_number := row_number - 1;
-            END IF;
-
-            -- row_counter is different from row_number.
-            -- It simply counts up from zero so that we know when
-            -- we've reached our limit.
-            row_counter := row_counter + 1;
-        END IF;
-    END LOOP;
-END;
-$f$ LANGUAGE plpgsql ROWS 10;
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.6', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1107', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
-DECLARE
-    moved_objects INT := 0;
-    source_cn     asset.call_number%ROWTYPE;
-    target_cn     asset.call_number%ROWTYPE;
-    metarec       metabib.metarecord%ROWTYPE;
-    hold          action.hold_request%ROWTYPE;
-    ser_rec       serial.record_entry%ROWTYPE;
-    ser_sub       serial.subscription%ROWTYPE;
-    acq_lineitem  acq.lineitem%ROWTYPE;
-    acq_request   acq.user_request%ROWTYPE;
-    booking       booking.resource_type%ROWTYPE;
-    source_part   biblio.monograph_part%ROWTYPE;
-    target_part   biblio.monograph_part%ROWTYPE;
-    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
-    uri_count     INT := 0;
-    counter       INT := 0;
-    uri_datafield TEXT;
-    uri_text      TEXT := '';
-BEGIN
-
-    -- move any 856 entries on records that have at least one MARC-mapped URI entry
-    SELECT  INTO uri_count COUNT(*)
-      FROM  asset.uri_call_number_map m
-            JOIN asset.call_number cn ON (m.call_number = cn.id)
-      WHERE cn.record = source_record;
-
-    IF uri_count > 0 THEN
-        
-        -- This returns more nodes than you might expect:
-        -- 7 instead of 1 for an 856 with $u $y $9
-        SELECT  COUNT(*) INTO counter
-          FROM  oils_xpath_table(
-                    'id',
-                    'marc',
-                    'biblio.record_entry',
-                    '//*[@tag="856"]',
-                    'id=' || source_record
-                ) as t(i int,c text);
-    
-        FOR i IN 1 .. counter LOOP
-            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
-                       ' tag="856"' ||
-                       ' ind1="' || FIRST(ind1) || '"'  ||
-                       ' ind2="' || FIRST(ind2) || '">' ||
-                        STRING_AGG(
-                            '<subfield code="' || subfield || '">' ||
-                            regexp_replace(
-                                regexp_replace(
-                                    regexp_replace(data,'&','&amp;','g'),
-                                    '>', '&gt;', 'g'
-                                ),
-                                '<', '&lt;', 'g'
-                            ) || '</subfield>', ''
-                        ) || '</datafield>' INTO uri_datafield
-              FROM  oils_xpath_table(
-                        'id',
-                        'marc',
-                        'biblio.record_entry',
-                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
-                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
-                        'id=' || source_record
-                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
-
-            -- As most of the results will be NULL, protect against NULLifying
-            -- the valid content that we do generate
-            uri_text := uri_text || COALESCE(uri_datafield, '');
-        END LOOP;
-
-        IF uri_text <> '' THEN
-            UPDATE  biblio.record_entry
-              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
-              WHERE id = target_record;
-        END IF;
-
-    END IF;
-
-       -- Find and move metarecords to the target record
-       SELECT  INTO metarec *
-         FROM  metabib.metarecord
-         WHERE master_record = source_record;
-
-       IF FOUND THEN
-               UPDATE  metabib.metarecord
-                 SET   master_record = target_record,
-                       mods = NULL
-                 WHERE id = metarec.id;
-
-               moved_objects := moved_objects + 1;
-       END IF;
-
-       -- Find call numbers attached to the source ...
-       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
-
-               SELECT  INTO target_cn *
-                 FROM  asset.call_number
-                 WHERE label = source_cn.label
-            AND prefix = source_cn.prefix
-            AND suffix = source_cn.suffix
-                       AND owning_lib = source_cn.owning_lib
-                       AND record = target_record
-                       AND NOT deleted;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copies to that, and ...
-                       UPDATE  asset.copy
-                         SET   call_number = target_cn.id
-                         WHERE call_number = source_cn.id;
-
-                       -- ... move V holds to the move-target call number
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_cn.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-        
-            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the call number to the target record
-                       UPDATE  asset.call_number
-                         SET   record = target_record
-                         WHERE id = source_cn.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find T holds targeting the source record ...
-       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
-
-               -- ... and move them to the target record
-               UPDATE  action.hold_request
-                 SET   target = target_record
-                 WHERE id = hold.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial records targeting the source record ...
-       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.record_entry
-                 SET   record = target_record
-                 WHERE id = ser_rec.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial subscriptions targeting the source record ...
-       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.subscription
-                 SET   record_entry = target_record
-                 WHERE id = ser_sub.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find booking resource types targeting the source record ...
-       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  booking.resource_type
-                 SET   record = target_record
-                 WHERE id = booking.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq lineitems targeting the source record ...
-       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.lineitem
-                 SET   eg_bib_id = target_record
-                 WHERE id = acq_lineitem.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq user purchase requests targeting the source record ...
-       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.user_request
-                 SET   eg_bib = target_record
-                 WHERE id = acq_request.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find parts attached to the source ...
-       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
-
-               SELECT  INTO target_part *
-                 FROM  biblio.monograph_part
-                 WHERE label = source_part.label
-                       AND record = target_record;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copy-part maps to that, and ...
-                       UPDATE  asset.copy_part_map
-                         SET   part = target_part.id
-                         WHERE part = source_part.id;
-
-                       -- ... move P holds to the move-target part
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_part.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the part to the target record
-                       UPDATE  biblio.monograph_part
-                         SET   record = target_record
-                         WHERE id = source_part.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find multi_home items attached to the source ...
-       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  biblio.peer_bib_copy_map
-                 SET   peer_record = target_record
-                 WHERE id = multi_home.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- And delete mappings where the item's home bib was merged with the peer bib
-       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
-               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
-               FROM asset.copy WHERE id = target_copy
-       );
-
-    -- replace book bag entries of source_record with target_record
-    UPDATE container.biblio_record_entry_bucket_item
-        SET target_biblio_record_entry = target_record
-        WHERE bucket IN (SELECT id FROM container.biblio_record_entry_bucket WHERE btype = 'bookbag')
-        AND target_biblio_record_entry = source_record;
-
-    -- Finally, "delete" the source record
-    DELETE FROM biblio.record_entry WHERE id = source_record;
-
-       -- That's all, folks!
-       RETURN moved_objects;
-END;
-$func$ LANGUAGE plpgsql;
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.0', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1089', :eg_version);
-
--- Add the circ.holds.max_duplicate_holds org. unit setting type.
-DO $INSERT$                                                                    
-BEGIN                                                                          
-    IF evergreen.insert_on_deploy() THEN 
-
-INSERT into config.org_unit_setting_type
-( name, grp, label, description, datatype, fm_class )
-VALUES
-( 'circ.holds.max_duplicate_holds', 'holds',
-   oils_i18n_gettext(
-     'circ.holds.max_duplicate_holds',
-     'Maximum number of duplicate holds allowed.',
-     'coust', 'label'),
-   oils_i18n_gettext(
-     'circ.holds.max_duplicate_holds',
-     'Maximum number of duplicate title or metarecord holds allowed per patron.',
-     'coust', 'description'),
-   'integer', null );
-    END IF;                                                                    
-END $INSERT$; 
-
-
---SELECT evergreen.upgrade_deps_block_check('1090', :eg_version);
-
-/* KCLS ALREAD HAS THIS
-ALTER TABLE biblio.record_entry
-    ADD COLUMN merge_date TIMESTAMP WITH TIME ZONE,
-    ADD COLUMN merged_to BIGINT REFERENCES biblio.record_entry(id);
-*/
-
-CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
-DECLARE
-    moved_objects INT := 0;
-    source_cn     asset.call_number%ROWTYPE;
-    target_cn     asset.call_number%ROWTYPE;
-    metarec       metabib.metarecord%ROWTYPE;
-    hold          action.hold_request%ROWTYPE;
-    ser_rec       serial.record_entry%ROWTYPE;
-    ser_sub       serial.subscription%ROWTYPE;
-    acq_lineitem  acq.lineitem%ROWTYPE;
-    acq_request   acq.user_request%ROWTYPE;
-    booking       booking.resource_type%ROWTYPE;
-    source_part   biblio.monograph_part%ROWTYPE;
-    target_part   biblio.monograph_part%ROWTYPE;
-    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
-    uri_count     INT := 0;
-    counter       INT := 0;
-    uri_datafield TEXT;
-    uri_text      TEXT := '';
-BEGIN
-
-    -- move any 856 entries on records that have at least one MARC-mapped URI entry
-    SELECT  INTO uri_count COUNT(*)
-      FROM  asset.uri_call_number_map m
-            JOIN asset.call_number cn ON (m.call_number = cn.id)
-      WHERE cn.record = source_record;
-
-    IF uri_count > 0 THEN
-        
-        -- This returns more nodes than you might expect:
-        -- 7 instead of 1 for an 856 with $u $y $9
-        SELECT  COUNT(*) INTO counter
-          FROM  oils_xpath_table(
-                    'id',
-                    'marc',
-                    'biblio.record_entry',
-                    '//*[@tag="856"]',
-                    'id=' || source_record
-                ) as t(i int,c text);
-    
-        FOR i IN 1 .. counter LOOP
-            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
-                       ' tag="856"' ||
-                       ' ind1="' || FIRST(ind1) || '"'  ||
-                       ' ind2="' || FIRST(ind2) || '">' ||
-                        STRING_AGG(
-                            '<subfield code="' || subfield || '">' ||
-                            regexp_replace(
-                                regexp_replace(
-                                    regexp_replace(data,'&','&amp;','g'),
-                                    '>', '&gt;', 'g'
-                                ),
-                                '<', '&lt;', 'g'
-                            ) || '</subfield>', ''
-                        ) || '</datafield>' INTO uri_datafield
-              FROM  oils_xpath_table(
-                        'id',
-                        'marc',
-                        'biblio.record_entry',
-                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
-                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
-                        'id=' || source_record
-                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
-
-            -- As most of the results will be NULL, protect against NULLifying
-            -- the valid content that we do generate
-            uri_text := uri_text || COALESCE(uri_datafield, '');
-        END LOOP;
-
-        IF uri_text <> '' THEN
-            UPDATE  biblio.record_entry
-              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
-              WHERE id = target_record;
-        END IF;
-
-    END IF;
-
-       -- Find and move metarecords to the target record
-       SELECT  INTO metarec *
-         FROM  metabib.metarecord
-         WHERE master_record = source_record;
-
-       IF FOUND THEN
-               UPDATE  metabib.metarecord
-                 SET   master_record = target_record,
-                       mods = NULL
-                 WHERE id = metarec.id;
-
-               moved_objects := moved_objects + 1;
-       END IF;
-
-       -- Find call numbers attached to the source ...
-       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
-
-               SELECT  INTO target_cn *
-                 FROM  asset.call_number
-                 WHERE label = source_cn.label
-            AND prefix = source_cn.prefix
-            AND suffix = source_cn.suffix
-                       AND owning_lib = source_cn.owning_lib
-                       AND record = target_record
-                       AND NOT deleted;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copies to that, and ...
-                       UPDATE  asset.copy
-                         SET   call_number = target_cn.id
-                         WHERE call_number = source_cn.id;
-
-                       -- ... move V holds to the move-target call number
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_cn.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-        
-            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the call number to the target record
-                       UPDATE  asset.call_number
-                         SET   record = target_record
-                         WHERE id = source_cn.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find T holds targeting the source record ...
-       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
-
-               -- ... and move them to the target record
-               UPDATE  action.hold_request
-                 SET   target = target_record
-                 WHERE id = hold.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial records targeting the source record ...
-       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.record_entry
-                 SET   record = target_record
-                 WHERE id = ser_rec.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial subscriptions targeting the source record ...
-       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.subscription
-                 SET   record_entry = target_record
-                 WHERE id = ser_sub.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find booking resource types targeting the source record ...
-       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  booking.resource_type
-                 SET   record = target_record
-                 WHERE id = booking.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq lineitems targeting the source record ...
-       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.lineitem
-                 SET   eg_bib_id = target_record
-                 WHERE id = acq_lineitem.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq user purchase requests targeting the source record ...
-       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.user_request
-                 SET   eg_bib = target_record
-                 WHERE id = acq_request.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find parts attached to the source ...
-       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
-
-               SELECT  INTO target_part *
-                 FROM  biblio.monograph_part
-                 WHERE label = source_part.label
-                       AND record = target_record;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copy-part maps to that, and ...
-                       UPDATE  asset.copy_part_map
-                         SET   part = target_part.id
-                         WHERE part = source_part.id;
-
-                       -- ... move P holds to the move-target part
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_part.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the part to the target record
-                       UPDATE  biblio.monograph_part
-                         SET   record = target_record
-                         WHERE id = source_part.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find multi_home items attached to the source ...
-       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  biblio.peer_bib_copy_map
-                 SET   peer_record = target_record
-                 WHERE id = multi_home.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- And delete mappings where the item's home bib was merged with the peer bib
-       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
-               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
-               FROM asset.copy WHERE id = target_copy
-       );
-
-    -- Apply merge tracking
-    UPDATE biblio.record_entry 
-        SET merge_date = NOW() WHERE id = target_record;
-
-    UPDATE biblio.record_entry
-        SET merge_date = NOW(), merged_to = target_record
-        WHERE id = source_record;
-
-    -- Finally, "delete" the source record
-    DELETE FROM biblio.record_entry WHERE id = source_record;
-
-       -- That's all, folks!
-       RETURN moved_objects;
-END;
-$func$ LANGUAGE plpgsql;
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1091', :eg_version);
-
-ALTER TABLE acq.funding_source DROP CONSTRAINT funding_source_code_key;
-ALTER TABLE acq.funding_source ALTER COLUMN code SET NOT NULL;
-ALTER TABLE acq.funding_source ADD CONSTRAINT funding_source_code_once_per_owner UNIQUE (code,owner);
-
-
---SELECT evergreen.upgrade_deps_block_check('1092', :eg_version);
-
-CREATE OR REPLACE FUNCTION metabib.reingest_record_attributes (rid BIGINT, pattr_list TEXT[] DEFAULT NULL, prmarc TEXT DEFAULT NULL, rdeleted BOOL DEFAULT TRUE) RETURNS VOID AS $func$
-DECLARE
-    transformed_xml TEXT;
-    rmarc           TEXT := prmarc;
-    tmp_val         TEXT;
-    prev_xfrm       TEXT;
-    normalizer      RECORD;
-    xfrm            config.xml_transform%ROWTYPE;
-    attr_vector     INT[] := '{}'::INT[];
-    attr_vector_tmp INT[];
-    attr_list       TEXT[] := pattr_list;
-    attr_value      TEXT[];
-    norm_attr_value TEXT[];
-    tmp_xml         TEXT;
-    tmp_array       TEXT[];
-    attr_def        config.record_attr_definition%ROWTYPE;
-    ccvm_row        config.coded_value_map%ROWTYPE;
-    jump_past       BOOL;
-BEGIN
-
-    IF attr_list IS NULL OR rdeleted THEN -- need to do the full dance on INSERT or undelete
-        SELECT ARRAY_AGG(name) INTO attr_list FROM config.record_attr_definition
-        WHERE (
-            tag IS NOT NULL OR
-            fixed_field IS NOT NULL OR
-            xpath IS NOT NULL OR
-            phys_char_sf IS NOT NULL OR
-            composite
-        ) AND (
-            filter OR sorter
-        );
-    END IF;
-
-    IF rmarc IS NULL THEN
-        SELECT marc INTO rmarc FROM biblio.record_entry WHERE id = rid;
-    END IF;
-
-    FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE NOT composite AND name = ANY( attr_list ) ORDER BY format LOOP
-
-        jump_past := FALSE; -- This gets set when we are non-multi and have found something
-        attr_value := '{}'::TEXT[];
-        norm_attr_value := '{}'::TEXT[];
-        attr_vector_tmp := '{}'::INT[];
-
-        SELECT * INTO ccvm_row FROM config.coded_value_map c WHERE c.ctype = attr_def.name LIMIT 1; 
-
-        IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
-            SELECT  ARRAY_AGG(value) INTO attr_value
-              FROM  (SELECT * FROM metabib.full_rec ORDER BY tag, subfield) AS x
-              WHERE record = rid
-                    AND tag LIKE attr_def.tag
-                    AND CASE
-                        WHEN attr_def.sf_list IS NOT NULL 
-                            THEN POSITION(subfield IN attr_def.sf_list) > 0
-                        ELSE TRUE
-                    END
-              GROUP BY tag
-              ORDER BY tag;
-
-            IF NOT attr_def.multi THEN
-                attr_value := ARRAY[ARRAY_TO_STRING(attr_value, COALESCE(attr_def.joiner,' '))];
-                jump_past := TRUE;
-            END IF;
-        END IF;
-
-        IF NOT jump_past AND attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
-            attr_value := attr_value || vandelay.marc21_extract_fixed_field_list(rmarc, attr_def.fixed_field);
-
-            IF NOT attr_def.multi THEN
-                attr_value := ARRAY[attr_value[1]];
-                jump_past := TRUE;
-            END IF;
-        END IF;
-
-        IF NOT jump_past AND attr_def.xpath IS NOT NULL THEN -- and xpath expression
-
-            SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
-        
-            -- See if we can skip the XSLT ... it's expensive
-            IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-                -- Can't skip the transform
-                IF xfrm.xslt <> '---' THEN
-                    transformed_xml := oils_xslt_process(rmarc,xfrm.xslt);
-                ELSE
-                    transformed_xml := rmarc;
-                END IF;
-    
-                prev_xfrm := xfrm.name;
-            END IF;
-
-            IF xfrm.name IS NULL THEN
-                -- just grab the marcxml (empty) transform
-                SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
-                prev_xfrm := xfrm.name;
-            END IF;
-
-            FOR tmp_xml IN SELECT UNNEST(oils_xpath(attr_def.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]])) LOOP
-                tmp_val := oils_xpath_string(
-                                '//*',
-                                tmp_xml,
-                                COALESCE(attr_def.joiner,' '),
-                                ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
-                            );
-                IF tmp_val IS NOT NULL AND BTRIM(tmp_val) <> '' THEN
-                    attr_value := attr_value || tmp_val;
-                    EXIT WHEN NOT attr_def.multi;
-                END IF;
-            END LOOP;
-        END IF;
-
-        IF NOT jump_past AND attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
-            SELECT  ARRAY_AGG(m.value) INTO tmp_array
-              FROM  vandelay.marc21_physical_characteristics(rmarc) v
-                    LEFT JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
-              WHERE v.subfield = attr_def.phys_char_sf AND (m.value IS NOT NULL AND BTRIM(m.value) <> '')
-                    AND ( ccvm_row.id IS NULL OR ( ccvm_row.id IS NOT NULL AND v.id IS NOT NULL) );
-
-            attr_value := attr_value || tmp_array;
-
-            IF NOT attr_def.multi THEN
-                attr_value := ARRAY[attr_value[1]];
-            END IF;
-
-        END IF;
-
-                -- apply index normalizers to attr_value
-        FOR tmp_val IN SELECT value FROM UNNEST(attr_value) x(value) LOOP
-            FOR normalizer IN
-                SELECT  n.func AS func,
-                        n.param_count AS param_count,
-                        m.params AS params
-                  FROM  config.index_normalizer n
-                        JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
-                  WHERE attr = attr_def.name
-                  ORDER BY m.pos LOOP
-                    EXECUTE 'SELECT ' || normalizer.func || '(' ||
-                    COALESCE( quote_literal( tmp_val ), 'NULL' ) ||
-                        CASE
-                            WHEN normalizer.param_count > 0
-                                THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
-                                ELSE ''
-                            END ||
-                    ')' INTO tmp_val;
-
-            END LOOP;
-            IF tmp_val IS NOT NULL AND tmp_val <> '' THEN
-                -- note that a string that contains only blanks
-                -- is a valid value for some attributes
-                norm_attr_value := norm_attr_value || tmp_val;
-            END IF;
-        END LOOP;
-        
-        IF attr_def.filter THEN
-            -- Create unknown uncontrolled values and find the IDs of the values
-            IF ccvm_row.id IS NULL THEN
-                FOR tmp_val IN SELECT value FROM UNNEST(norm_attr_value) x(value) LOOP
-                    IF tmp_val IS NOT NULL AND BTRIM(tmp_val) <> '' THEN
-                        BEGIN -- use subtransaction to isolate unique constraint violations
-                            INSERT INTO metabib.uncontrolled_record_attr_value ( attr, value ) VALUES ( attr_def.name, tmp_val );
-                        EXCEPTION WHEN unique_violation THEN END;
-                    END IF;
-                END LOOP;
-
-                SELECT ARRAY_AGG(id) INTO attr_vector_tmp FROM metabib.uncontrolled_record_attr_value WHERE attr = attr_def.name AND value = ANY( norm_attr_value );
-            ELSE
-                SELECT ARRAY_AGG(id) INTO attr_vector_tmp FROM config.coded_value_map WHERE ctype = attr_def.name AND code = ANY( norm_attr_value );
-            END IF;
-
-            -- Add the new value to the vector
-            attr_vector := attr_vector || attr_vector_tmp;
-        END IF;
-
-        IF attr_def.sorter THEN
-            DELETE FROM metabib.record_sorter WHERE source = rid AND attr = attr_def.name;
-            IF norm_attr_value[1] IS NOT NULL THEN
-                INSERT INTO metabib.record_sorter (source, attr, value) VALUES (rid, attr_def.name, norm_attr_value[1]);
-            END IF;
-        END IF;
-
-    END LOOP;
-
-/* We may need to rewrite the vlist to contain
-   the intersection of new values for requested
-   attrs and old values for ignored attrs. To
-   do this, we take the old attr vlist and
-   subtract any values that are valid for the
-   requested attrs, and then add back the new
-   set of attr values. */
-
-    IF ARRAY_LENGTH(pattr_list, 1) > 0 THEN 
-        SELECT vlist INTO attr_vector_tmp FROM metabib.record_attr_vector_list WHERE source = rid;
-        SELECT attr_vector_tmp - ARRAY_AGG(id::INT) INTO attr_vector_tmp FROM metabib.full_attr_id_map WHERE attr = ANY (pattr_list);
-        attr_vector := attr_vector || attr_vector_tmp;
-    END IF;
-
-    -- On to composite attributes, now that the record attrs have been pulled.  Processed in name order, so later composite
-    -- attributes can depend on earlier ones.
-    PERFORM metabib.compile_composite_attr_cache_init();
-    FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE composite AND name = ANY( attr_list ) ORDER BY name LOOP
-
-        FOR ccvm_row IN SELECT * FROM config.coded_value_map c WHERE c.ctype = attr_def.name ORDER BY value LOOP
-
-            tmp_val := metabib.compile_composite_attr( ccvm_row.id );
-            CONTINUE WHEN tmp_val IS NULL OR tmp_val = ''; -- nothing to do
-
-            IF attr_def.filter THEN
-                IF attr_vector @@ tmp_val::query_int THEN
-                    attr_vector = attr_vector + intset(ccvm_row.id);
-                    EXIT WHEN NOT attr_def.multi;
-                END IF;
-            END IF;
-
-            IF attr_def.sorter THEN
-                IF attr_vector @@ tmp_val THEN
-                    DELETE FROM metabib.record_sorter WHERE source = rid AND attr = attr_def.name;
-                    INSERT INTO metabib.record_sorter (source, attr, value) VALUES (rid, attr_def.name, ccvm_row.code);
-                END IF;
-            END IF;
-
-        END LOOP;
-
-    END LOOP;
-
-    IF ARRAY_LENGTH(attr_vector, 1) > 0 THEN
-        IF rdeleted THEN -- initial insert OR revivication
-            DELETE FROM metabib.record_attr_vector_list WHERE source = rid;
-            INSERT INTO metabib.record_attr_vector_list (source, vlist) VALUES (rid, attr_vector);
-        ELSE
-            UPDATE metabib.record_attr_vector_list SET vlist = attr_vector WHERE source = rid;
-        END IF;
-    END IF;
-
-END;
-
-$func$ LANGUAGE PLPGSQL;
-
---SELECT evergreen.upgrade_deps_block_check('1095', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.copy_state (cid BIGINT) RETURNS TEXT AS $$
-DECLARE
-    last_circ_stop     TEXT;
-    the_copy       asset.copy%ROWTYPE;
-BEGIN
-
-    SELECT * INTO the_copy FROM asset.copy WHERE id = cid;
-    IF NOT FOUND THEN RETURN NULL; END IF;
-
-    IF the_copy.status = 3 THEN -- Lost
-        RETURN 'LOST';
-    ELSIF the_copy.status = 4 THEN -- Missing
-        RETURN 'MISSING';
-    ELSIF the_copy.status = 14 THEN -- Damaged
-        RETURN 'DAMAGED';
-    ELSIF the_copy.status = 17 THEN -- Lost and paid
-        RETURN 'LOST_AND_PAID';
-    END IF;
-
-    SELECT stop_fines INTO last_circ_stop
-      FROM  action.circulation
-      WHERE target_copy = cid
-      ORDER BY xact_start DESC LIMIT 1;
-
-    IF FOUND THEN
-        IF last_circ_stop IN (
-            'CLAIMSNEVERCHECKEDOUT',
-            'CLAIMSRETURNED',
-            'LONGOVERDUE'
-        ) THEN
-            RETURN last_circ_stop;
-        END IF;
-    END IF;
-
-    RETURN 'NORMAL';
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE TYPE config.copy_alert_type_state AS ENUM (
-    'NORMAL',
-    'LOST',
-    'LOST_AND_PAID',
-    'MISSING',
-    'DAMAGED',
-    'CLAIMSRETURNED',
-    'LONGOVERDUE',
-    'CLAIMSNEVERCHECKEDOUT'
-);
-
-CREATE TYPE config.copy_alert_type_event AS ENUM (
-    'CHECKIN',
-    'CHECKOUT'
-);
-
-CREATE TABLE config.copy_alert_type (
-    id         serial  primary key, -- reserve 1-100 for system
-    scope_org   int not null references actor.org_unit (id) on delete cascade,
-    active      bool    not null default true,
-    name        text    not null unique,
-    state       config.copy_alert_type_state,
-    event       config.copy_alert_type_event,
-    in_renew    bool,
-    invert_location bool    not null default false,
-    at_circ     bool,
-    at_owning   bool,
-    next_status int[]
-);
-SELECT SETVAL('config.copy_alert_type_id_seq'::TEXT, 100);
-
-CREATE OR REPLACE FUNCTION evergreen.asset_copy_alert_copy_inh_fkey() RETURNS TRIGGER AS $f$
-BEGIN
-        PERFORM 1 FROM asset.copy WHERE id = NEW.copy;
-        IF NOT FOUND THEN
-                RAISE foreign_key_violation USING MESSAGE = FORMAT(
-                        $$Referenced asset.copy id not found, copy:%s$$, NEW.copy
-                );
-        END IF;
-        RETURN NEW;
-END;
-$f$ LANGUAGE PLPGSQL VOLATILE COST 50;
-
-CREATE TABLE actor.copy_alert_suppress (
-    id          serial primary key,
-    org         int not null references actor.org_unit (id) on delete cascade,
-    alert_type  int not null references config.copy_alert_type (id) on delete cascade
-);
-
-CREATE TABLE asset.copy_alert (
-    id      bigserial   primary key,
-    alert_type  int     not null references config.copy_alert_type (id) on delete cascade,
-    copy        bigint  not null,
-    temp        bool    not null default false,
-    create_time timestamptz not null default now(),
-    create_staff    bigint  not null references actor.usr (id) on delete set null,
-    note        text,
-    ack_time    timestamptz,
-    ack_staff   bigint references actor.usr (id) on delete set null
-);
-
-CREATE CONSTRAINT TRIGGER inherit_asset_copy_alert_copy_fkey
-        AFTER UPDATE OR INSERT ON asset.copy_alert
-        DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_alert_copy_inh_fkey();
-
-CREATE VIEW asset.active_copy_alert AS
-    SELECT  *
-      FROM  asset.copy_alert
-      WHERE ack_time IS NULL;
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1096', :eg_version);
-
-DO $INSERT$                                                                    
-BEGIN                                                                          
-    IF evergreen.insert_on_deploy() THEN
-
--- staff-usable alert types with no location awareness
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew)
-VALUES (1, 1, TRUE, 'Normal checkout', 'NORMAL', 'CHECKOUT', FALSE);
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew)
-VALUES (2, 1, TRUE, 'Normal checkin', 'NORMAL', 'CHECKIN', FALSE);
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew)
-VALUES (3, 1, FALSE, 'Normal renewal', 'NORMAL', 'CHECKIN', TRUE);
-
--- copy alerts upon checkin or renewal of exceptional copy statuses are not active by
--- default; they're meant to be turned once a site is ready to fully
--- commit to using the webstaff client for circulation
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (4, 1, FALSE, 'Checkin of lost copy', 'LOST', 'CHECKIN');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (5, 1, FALSE, 'Checkin of missing copy', 'MISSING', 'CHECKIN');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (6, 1, FALSE, 'Checkin of lost-and-paid copy', 'LOST_AND_PAID', 'CHECKIN');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (7, 1, FALSE, 'Checkin of damaged copy', 'DAMAGED', 'CHECKIN');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (8, 1, FALSE, 'Checkin of claims-returned copy', 'CLAIMSRETURNED', 'CHECKIN');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (9, 1, FALSE, 'Checkin of long overdue copy', 'LONGOVERDUE', 'CHECKIN');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (10, 1, FALSE, 'Checkin of claims-never-checked-out copy', 'CLAIMSNEVERCHECKEDOUT', 'CHECKIN');
-
--- copy alerts upon checkout of exceptional copy statuses are not active by
--- default; they're meant to be turned once a site is ready to fully
--- commit to using the webstaff client for circulation
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (11, 1, FALSE, 'Checkout of lost copy', 'LOST', 'CHECKOUT');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (12, 1, FALSE, 'Checkout of missing copy', 'MISSING', 'CHECKOUT');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (13, 1, FALSE, 'Checkout of lost-and-paid copy', 'LOST_AND_PAID', 'CHECKOUT');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (14, 1, FALSE, 'Checkout of damaged copy', 'DAMAGED', 'CHECKOUT');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (15, 1, FALSE, 'Checkout of claims-returned copy', 'CLAIMSRETURNED', 'CHECKOUT');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (16, 1, FALSE, 'Checkout of long overdue copy', 'LONGOVERDUE', 'CHECKOUT');
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event)
-VALUES (17, 1, FALSE, 'Checkout of claims-never-checked-out copy', 'CLAIMSNEVERCHECKEDOUT', 'CHECKOUT');
-
--- staff-usable alert types based on location
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_circ)
-VALUES (18, 1, FALSE, 'Normal checkout at circ lib', 'NORMAL', 'CHECKOUT', FALSE, TRUE);
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_circ)
-VALUES (19, 1, FALSE, 'Normal checkin at circ lib', 'NORMAL', 'CHECKIN', FALSE, TRUE);
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_circ)
-VALUES (20, 1, FALSE, 'Normal renewal at circ lib', 'NORMAL', 'CHECKIN', TRUE, TRUE);
-
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_owning)
-VALUES (21, 1, FALSE, 'Normal checkout at owning lib', 'NORMAL', 'CHECKOUT', FALSE, TRUE);
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_owning)
-VALUES (22, 1, FALSE, 'Normal checkin at owning lib', 'NORMAL', 'CHECKIN', FALSE, TRUE);
-INSERT INTO config.copy_alert_type (id, scope_org, active, name, state, event, in_renew, at_owning)
-VALUES (23, 1, FALSE, 'Normal renewal at owning lib', 'NORMAL', 'CHECKIN', TRUE, TRUE);
-
-
---SELECT evergreen.upgrade_deps_block_check('1097', :eg_version);
-
-INSERT INTO config.org_unit_setting_type
-    (name, grp, label, description, datatype)
-    VALUES
-        ('circ.copy_alerts.forgive_fines_on_lost_checkin',
-         'circ',
-         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_lost_checkin',
-            'Forgive fines when checking out a lost item and copy alert is suppressed?',
-            'coust', 'label'),
-         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_lost_checkin',
-            'Controls whether fines are automatically forgiven when checking out an '||
-            'item that has been marked as lost, and the corresponding copy alert has been '||
-            'suppressed.',
-            'coust', 'description'),
-        'bool');
-
-INSERT INTO config.org_unit_setting_type
-    (name, grp, label, description, datatype)
-    VALUES
-        ('circ.copy_alerts.forgive_fines_on_long_overdue_checkin',
-         'circ',
-         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_long_overdue_checkin',
-            'Forgive fines when checking out a long-overdue item and copy alert is suppressed?',
-            'coust', 'label'),
-         oils_i18n_gettext('circ.copy_alerts.forgive_fines_on_lost_checkin',
-            'Controls whether fines are automatically forgiven when checking out an '||
-            'item that has been marked as lost, and the corresponding copy alert has been '||
-            'suppressed.',
-            'coust', 'description'),
-        'bool');
-
-    END IF;                                                                    
-END $INSERT$; 
-
---SELECT evergreen.upgrade_deps_block_check('1098', :eg_version);
-
-\qecho Copying copy alert messages to normal checkout copy alerts...
-INSERT INTO asset.copy_alert (alert_type, copy, note, create_staff)
-SELECT 1, id, alert_message, 1
-FROM asset.copy
-WHERE alert_message IS NOT NULL
-AND   alert_message <> '';
-
-\qecho Copying copy alert messages to normal checkin copy alerts...
-INSERT INTO asset.copy_alert (alert_type, copy, note, create_staff)
-SELECT 2, id, alert_message, 1
-FROM asset.copy
-WHERE alert_message IS NOT NULL
-AND   alert_message <> '';
-
-\qecho Clearing legacy copy alert field; this may take a while
-UPDATE asset.copy SET alert_message = NULL
-WHERE alert_message IS NOT NULL;
-
-
---SELECT evergreen.upgrade_deps_block_check('1099', :eg_version);
--- moved update to data file
-
---SELECT evergreen.upgrade_deps_block_check('1100', :eg_version);
-
--- NEW config.metabib_field entries
-
-UPDATE config.metabib_field SET display_xpath = facet_xpath, display_field = TRUE WHERE id = 33;
-
-                                                                               
-DO $INSERT$                                                                    
-BEGIN                                                                          
-   IF evergreen.insert_on_deploy() THEN     
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    38, 'identifier', 'edition', 
-    oils_i18n_gettext(38, 'Edition', 'cmf', 'label'),
-    $$//mods33:mods/mods33:originInfo//mods33:edition[1]$$,
-    TRUE, TRUE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    39, 'keyword', 'physical_description', 
-    oils_i18n_gettext(39, 'Physical Descrption', 'cmf', 'label'),
-    $$(//mods33:mods/mods33:physicalDescription/mods33:form|//mods33:mods/mods33:physicalDescription/mods33:extent|//mods33:mods/mods33:physicalDescription/mods33:reformattingQuality|//mods33:mods/mods33:physicalDescription/mods33:internetMediaType|//mods33:mods/mods33:physicalDescription/mods33:digitalOrigin)$$,
-    TRUE, TRUE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    40, 'identifier', 'publisher', 
-    oils_i18n_gettext(40, 'Publisher', 'cmf', 'label'),
-    $$//mods33:mods/mods33:originInfo//mods33:publisher[1]$$,
-    TRUE, TRUE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    41, 'keyword', 'abstract', 
-    oils_i18n_gettext(41, 'Abstract', 'cmf', 'label'),
-    $$//mods33:mods/mods33:abstract$$,
-    TRUE, TRUE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    42, 'keyword', 'toc', 
-    oils_i18n_gettext(42, 'Table of Contents', 'cmf', 'label'),
-    $$//mods33:tableOfContents$$,
-    TRUE, TRUE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    43, 'identifier', 'type_of_resource', 
-    oils_i18n_gettext(43, 'Type of Resource', 'cmf', 'label'),
-    $$//mods33:mods/mods33:typeOfResource$$,
-    TRUE, FALSE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    44, 'identifier', 'pubdate', 
-    oils_i18n_gettext(44, 'Publication Date', 'cmf', 'label'),
-    $$//mods33:mods/mods33:originInfo//mods33:dateIssued[@encoding="marc"]|//mods33:mods/mods33:originInfo//mods33:dateIssued[1]$$,
-    TRUE, FALSE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, 
-    label, xpath, display_field, search_field, browse_field)
-VALUES (
-    46, 'keyword', 'bibliography', 
-    oils_i18n_gettext(46, 'Bibliography', 'cmf', 'label'),
-    $$//mods33:note[@type='bibliography']$$,
-    TRUE, TRUE, FALSE
-),(
-    47, 'keyword', 'thesis', 
-    oils_i18n_gettext(47, 'Thesis', 'cmf', 'label'),
-    $$//mods33:note[@type='thesis']$$,
-    TRUE, TRUE, FALSE
-),(
-    48, 'keyword', 'production_credits', 
-    oils_i18n_gettext(48, 'Creation/Production Credits', 'cmf', 'label'),
-    $$//mods33:note[@type='creation/production credits']$$,
-    TRUE, TRUE, FALSE
-),(
-    49, 'keyword', 'performers', 
-    oils_i18n_gettext(49, 'Performers', 'cmf', 'label'),
-    $$//mods33:note[@type='performers']$$,
-    TRUE, TRUE, FALSE
-),(
-    50, 'keyword', 'general_note', 
-    oils_i18n_gettext(50, 'General Note', 'cmf', 'label'),
-    $$//mods33:note[not(@type)]$$,
-    TRUE, TRUE, FALSE
-)
-;
-
-INSERT INTO config.metabib_field (id, field_class, name, format,
-    label, xpath, display_xpath, display_field, search_field, browse_field)
-VALUES (
-    51, 'author', 'first_author', 'mods32',
-    oils_i18n_gettext(51, 'Author', 'cmf', 'label'),
-    $$//mods32:mods/mods32:name[mods32:role/mods32:roleTerm[text()='creator']][1]$$,
-    $$//*[local-name()='namePart']$$,
-    TRUE, TRUE, FALSE
-);
-
-INSERT INTO config.metabib_field (id, field_class, name, format,
-    label, xpath, display_xpath, display_field, search_field, browse_field)
-VALUES (
-    52, 'identifier', 'origin_info', 'marcxml',
-    oils_i18n_gettext(52, 'Origin Info', 'cmf', 'label'),
-    $$//*[@tag='260']$$,
-    $$//*[local-name()='subfield' and contains('abc',@code)]$$,
-    TRUE, FALSE, FALSE
-);
-
-
--- Modify existing config.metabib_field entries
-
-UPDATE config.metabib_field SET display_field = TRUE WHERE id IN (
-    1,  -- seriestitle
-    11, -- subject_geographic 
-    12, -- subject_name
-    13, -- subject_temporal
-    14, -- subject_topic
-    19, -- ISSN
-    20, -- UPC
-    26  -- TCN
-);
-
--- Map display field names to config.metabib_field entries
-
-INSERT INTO config.display_field_map (name, field, multi) VALUES 
-    ('series_title',         1, TRUE),
-    ('subject_geographic',  11, TRUE),
-    ('subject_name',        12, TRUE),
-    ('subject_temporal',    13, TRUE),
-    ('subject_topic',       14, TRUE),
-    ('issn',                19, TRUE),
-    ('upc',                 20, TRUE),
-    ('tcn',                 26, FALSE),
-    ('edition',             38, FALSE),
-    ('physical_description',39, TRUE),
-    ('genre',               33, TRUE),
-    ('bibliography',        46, TRUE),
-    ('thesis',              47, TRUE),
-    ('performers',          49, TRUE),
-    ('production_credits',  48, TRUE),
-    ('general_note',        50, TRUE),
-    ('publisher',           52, FALSE),
-    ('abstract',            41, FALSE),
-    ('toc',                 42, FALSE),
-    ('type_of_resource',    43, FALSE),
-    ('pubdate',             44, FALSE)
-;
-
-UPDATE config.display_field_map SET field = 51 WHERE name = 'author';
-
-    END IF;                                                                    
-END $INSERT$;
-
--- Add a column to wide-display-entry per well-known field
-
-DROP VIEW IF EXISTS metabib.wide_display_entry;
-CREATE VIEW metabib.wide_display_entry AS
-    SELECT 
-        bre.id AS source,
-        COALESCE(mcde_title.value, 'null')::TEXT AS title,
-        COALESCE(mcde_author.value, 'null')::TEXT AS author,
-        COALESCE(mcde_subject_geographic.value, 'null')::TEXT AS subject_geographic,
-        COALESCE(mcde_subject_name.value, 'null')::TEXT AS subject_name,
-        COALESCE(mcde_subject_temporal.value, 'null')::TEXT AS subject_temporal,
-        COALESCE(mcde_subject_topic.value, 'null')::TEXT AS subject_topic,
-        COALESCE(mcde_creators.value, 'null')::TEXT AS creators,
-        COALESCE(mcde_isbn.value, 'null')::TEXT AS isbn,
-        COALESCE(mcde_issn.value, 'null')::TEXT AS issn,
-        COALESCE(mcde_upc.value, 'null')::TEXT AS upc,
-        COALESCE(mcde_tcn.value, 'null')::TEXT AS tcn,
-        COALESCE(mcde_edition.value, 'null')::TEXT AS edition,
-        COALESCE(mcde_physical_description.value, 'null')::TEXT AS physical_description,
-        COALESCE(mcde_publisher.value, 'null')::TEXT AS publisher,
-        COALESCE(mcde_series_title.value, 'null')::TEXT AS series_title,
-        COALESCE(mcde_abstract.value, 'null')::TEXT AS abstract,
-        COALESCE(mcde_toc.value, 'null')::TEXT AS toc,
-        COALESCE(mcde_pubdate.value, 'null')::TEXT AS pubdate,
-        COALESCE(mcde_type_of_resource.value, 'null')::TEXT AS type_of_resource
-    FROM biblio.record_entry bre 
-    LEFT JOIN metabib.compressed_display_entry mcde_title 
-        ON (bre.id = mcde_title.source AND mcde_title.name = 'title')
-    LEFT JOIN metabib.compressed_display_entry mcde_author 
-        ON (bre.id = mcde_author.source AND mcde_author.name = 'author')
-    LEFT JOIN metabib.compressed_display_entry mcde_subject 
-        ON (bre.id = mcde_subject.source AND mcde_subject.name = 'subject')
-    LEFT JOIN metabib.compressed_display_entry mcde_subject_geographic 
-        ON (bre.id = mcde_subject_geographic.source 
-            AND mcde_subject_geographic.name = 'subject_geographic')
-    LEFT JOIN metabib.compressed_display_entry mcde_subject_name 
-        ON (bre.id = mcde_subject_name.source 
-            AND mcde_subject_name.name = 'subject_name')
-    LEFT JOIN metabib.compressed_display_entry mcde_subject_temporal 
-        ON (bre.id = mcde_subject_temporal.source 
-            AND mcde_subject_temporal.name = 'subject_temporal')
-    LEFT JOIN metabib.compressed_display_entry mcde_subject_topic 
-        ON (bre.id = mcde_subject_topic.source 
-            AND mcde_subject_topic.name = 'subject_topic')
-    LEFT JOIN metabib.compressed_display_entry mcde_creators 
-        ON (bre.id = mcde_creators.source AND mcde_creators.name = 'creators')
-    LEFT JOIN metabib.compressed_display_entry mcde_isbn 
-        ON (bre.id = mcde_isbn.source AND mcde_isbn.name = 'isbn')
-    LEFT JOIN metabib.compressed_display_entry mcde_issn 
-        ON (bre.id = mcde_issn.source AND mcde_issn.name = 'issn')
-    LEFT JOIN metabib.compressed_display_entry mcde_upc 
-        ON (bre.id = mcde_upc.source AND mcde_upc.name = 'upc')
-    LEFT JOIN metabib.compressed_display_entry mcde_tcn 
-        ON (bre.id = mcde_tcn.source AND mcde_tcn.name = 'tcn')
-    LEFT JOIN metabib.compressed_display_entry mcde_edition 
-        ON (bre.id = mcde_edition.source AND mcde_edition.name = 'edition')
-    LEFT JOIN metabib.compressed_display_entry mcde_physical_description 
-        ON (bre.id = mcde_physical_description.source 
-            AND mcde_physical_description.name = 'physical_description')
-    LEFT JOIN metabib.compressed_display_entry mcde_publisher 
-        ON (bre.id = mcde_publisher.source AND mcde_publisher.name = 'publisher')
-    LEFT JOIN metabib.compressed_display_entry mcde_series_title 
-        ON (bre.id = mcde_series_title.source AND mcde_series_title.name = 'series_title')
-    LEFT JOIN metabib.compressed_display_entry mcde_abstract 
-        ON (bre.id = mcde_abstract.source AND mcde_abstract.name = 'abstract')
-    LEFT JOIN metabib.compressed_display_entry mcde_toc 
-        ON (bre.id = mcde_toc.source AND mcde_toc.name = 'toc')
-    LEFT JOIN metabib.compressed_display_entry mcde_pubdate 
-        ON (bre.id = mcde_pubdate.source AND mcde_pubdate.name = 'pubdate')
-    LEFT JOIN metabib.compressed_display_entry mcde_type_of_resource 
-        ON (bre.id = mcde_type_of_resource.source 
-            AND mcde_type_of_resource.name = 'type_of_resource')
-;
-
-CREATE OR REPLACE VIEW reporter.old_super_simple_record AS
-SELECT  r.id,
-    r.fingerprint,
-    r.quality,
-    r.tcn_source,
-    r.tcn_value,
-    evergreen.oils_json_to_text(d.title) AS title,
-    evergreen.oils_json_to_text(d.author) AS author,
-    evergreen.oils_json_to_text(d.publisher) AS publisher,
-    evergreen.oils_json_to_text(d.pubdate) AS pubdate,
-    CASE WHEN d.isbn = 'null'
-        THEN NULL
-        ELSE (SELECT ARRAY(SELECT json_array_elements_text(d.isbn::JSON)))
-    END AS isbn,
-    CASE WHEN d.issn = 'null'
-        THEN NULL
-        ELSE (SELECT ARRAY(SELECT json_array_elements_text(d.issn::JSON)))
-    END AS issn
-  FROM  biblio.record_entry r
-        JOIN metabib.wide_display_entry d ON (r.id = d.source);
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1101', :eg_version);
-
-ALTER TABLE config.metabib_field ALTER COLUMN xpath DROP NOT NULL;
-
-CREATE TABLE config.metabib_field_virtual_map (
-    id      SERIAL  PRIMARY KEY,
-    real    INT NOT NULL REFERENCES config.metabib_field (id),
-    virtual INT NOT NULL REFERENCES config.metabib_field (id),
-    weight  INT NOT NULL DEFAULT 1
-);
-COMMENT ON TABLE config.metabib_field_virtual_map IS $$
-Maps between real (physically extracted) index definitions
-and virtual (target sync, no required extraction of its own)
-index definitions.
-
-The virtual side may not extract any data of its own, but
-will collect data from all of the real fields.  This reduces
-extraction (ingest) overhead by eliminating duplcated extraction,
-and allows for searching across novel combinations of fields, such
-as names used as either subjects or authors.  By preserving this
-mapping rather than defining duplicate extractions, information
-about the originating, "real" index definitions can be used
-in interesting ways, such as highlighting in search results.
-$$;
-
-CREATE OR REPLACE VIEW metabib.combined_all_field_entry AS
-    SELECT * FROM metabib.combined_title_field_entry
-        UNION ALL
-    SELECT * FROM metabib.combined_author_field_entry
-        UNION ALL
-    SELECT * FROM metabib.combined_subject_field_entry
-        UNION ALL
-    SELECT * FROM metabib.combined_keyword_field_entry
-        UNION ALL
-    SELECT * FROM metabib.combined_identifier_field_entry
-        UNION ALL
-    SELECT * FROM metabib.combined_series_field_entry;
-
-
-CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry (
-    rid BIGINT,
-    default_joiner TEXT,
-    field_types TEXT[],
-    only_fields INT[]
-) RETURNS SETOF metabib.field_entry_template AS $func$
-DECLARE
-    bib     biblio.record_entry%ROWTYPE;
-    idx     config.metabib_field%ROWTYPE;
-    xfrm        config.xml_transform%ROWTYPE;
-    prev_xfrm   TEXT;
-    transformed_xml TEXT;
-    xml_node    TEXT;
-    xml_node_list   TEXT[];
-    facet_text  TEXT;
-    display_text TEXT;
-    browse_text TEXT;
-    sort_value  TEXT;
-    raw_text    TEXT;
-    curr_text   TEXT;
-    joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
-    authority_text TEXT;
-    authority_link BIGINT;
-    output_row  metabib.field_entry_template%ROWTYPE;
-    process_idx BOOL;
-BEGIN
-
-    -- Start out with no field-use bools set
-    output_row.browse_field = FALSE;
-    output_row.facet_field = FALSE;
-    output_row.display_field = FALSE;
-    output_row.search_field = FALSE;
-
-    -- Get the record
-    SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
-
-    -- Loop over the indexing entries
-    FOR idx IN SELECT * FROM config.metabib_field WHERE id = ANY (only_fields) ORDER BY format LOOP
-        CONTINUE WHEN idx.xpath IS NULL OR idx.xpath = ''; -- pure virtual field
-
-        process_idx := FALSE;
-        IF idx.display_field AND 'display' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        IF idx.browse_field AND 'browse' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        IF idx.search_field AND 'search' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        IF idx.facet_field AND 'facet' = ANY (field_types) THEN process_idx = TRUE; END IF;
-        CONTINUE WHEN process_idx = FALSE; -- disabled for all types
-
-        joiner := COALESCE(idx.joiner, default_joiner);
-
-        SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
-
-        -- See if we can skip the XSLT ... it's expensive
-        IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-            -- Can't skip the transform
-            IF xfrm.xslt <> '---' THEN
-                transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
-            ELSE
-                transformed_xml := bib.marc;
-            END IF;
-
-            prev_xfrm := xfrm.name;
-        END IF;
-
-        xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-
-        raw_text := NULL;
-        FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
-            CONTINUE WHEN xml_node !~ E'^\\s*<';
-
-            -- XXX much of this should be moved into oils_xpath_string...
-            curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
-                oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
-                    REGEXP_REPLACE( xml_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
-                ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
-                joiner
-            );
-
-            CONTINUE WHEN curr_text IS NULL OR curr_text = '';
-
-            IF raw_text IS NOT NULL THEN
-                raw_text := raw_text || joiner;
-            END IF;
-
-            raw_text := COALESCE(raw_text,'') || curr_text;
-
-            -- autosuggest/metabib.browse_entry
-            IF idx.browse_field THEN
-
-                IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
-                    browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-                ELSE
-                    browse_text := curr_text;
-                END IF;
-
-                IF idx.browse_sort_xpath IS NOT NULL AND
-                    idx.browse_sort_xpath <> '' THEN
-
-                    sort_value := oils_xpath_string(
-                        idx.browse_sort_xpath, xml_node, joiner,
-                        ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
-                    );
-                ELSE
-                    sort_value := browse_text;
-                END IF;
-
-                output_row.field_class = idx.field_class;
-                output_row.field = idx.id;
-                output_row.source = rid;
-                output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
-                output_row.sort_value :=
-                    public.naco_normalize(sort_value);
-
-                output_row.authority := NULL;
-
-                IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
-                    authority_text := oils_xpath_string(
-                        idx.authority_xpath, xml_node, joiner,
-                        ARRAY[
-                            ARRAY[xfrm.prefix, xfrm.namespace_uri],
-                            ARRAY['xlink','http://www.w3.org/1999/xlink']
-                        ]
-                    );
-
-                    IF authority_text ~ '^\d+$' THEN
-                        authority_link := authority_text::BIGINT;
-                        PERFORM * FROM authority.record_entry WHERE id = authority_link;
-                        IF FOUND THEN
-                            output_row.authority := authority_link;
-                        END IF;
-                    END IF;
-
-                END IF;
-
-                output_row.browse_field = TRUE;
-                -- Returning browse rows with search_field = true for search+browse
-                -- configs allows us to retain granularity of being able to search
-                -- browse fields with "starts with" type operators (for example, for
-                -- titles of songs in music albums)
-                IF idx.search_field THEN
-                    output_row.search_field = TRUE;
-                END IF;
-                RETURN NEXT output_row;
-                output_row.browse_field = FALSE;
-                output_row.search_field = FALSE;
-                output_row.sort_value := NULL;
-            END IF;
-
-            -- insert raw node text for faceting
-            IF idx.facet_field THEN
-
-                IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
-                    facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-                ELSE
-                    facet_text := curr_text;
-                END IF;
-
-                output_row.field_class = idx.field_class;
-                output_row.field = -1 * idx.id;
-                output_row.source = rid;
-                output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
-
-                output_row.facet_field = TRUE;
-                RETURN NEXT output_row;
-                output_row.facet_field = FALSE;
-            END IF;
-
-            -- insert raw node text for display
-            IF idx.display_field THEN
-
-                IF idx.display_xpath IS NOT NULL AND idx.display_xpath <> '' THEN
-                    display_text := oils_xpath_string( idx.display_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
-                ELSE
-                    display_text := curr_text;
-                END IF;
-
-                output_row.field_class = idx.field_class;
-                output_row.field = -1 * idx.id;
-                output_row.source = rid;
-                output_row.value = BTRIM(REGEXP_REPLACE(display_text, E'\\s+', ' ', 'g'));
-
-                output_row.display_field = TRUE;
-                RETURN NEXT output_row;
-                output_row.display_field = FALSE;
-            END IF;
-
-        END LOOP;
-
-        CONTINUE WHEN raw_text IS NULL OR raw_text = '';
-
-        -- insert combined node text for searching
-        IF idx.search_field THEN
-            output_row.field_class = idx.field_class;
-            output_row.field = idx.id;
-            output_row.source = rid;
-            output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
-
-            output_row.search_field = TRUE;
-            RETURN NEXT output_row;
-            output_row.search_field = FALSE;
-        END IF;
-
-    END LOOP;
-
-END;
-$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION metabib.update_combined_index_vectors(bib_id BIGINT) RETURNS VOID AS $func$
-DECLARE
-    rdata       TSVECTOR;
-    vclass      TEXT;
-    vfield      INT;
-    rfields     INT[];
-BEGIN
-    DELETE FROM metabib.combined_keyword_field_entry WHERE record = bib_id;
-    INSERT INTO metabib.combined_keyword_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.keyword_field_entry WHERE source = bib_id GROUP BY field;
-    INSERT INTO metabib.combined_keyword_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.keyword_field_entry WHERE source = bib_id;
-
-    DELETE FROM metabib.combined_title_field_entry WHERE record = bib_id;
-    INSERT INTO metabib.combined_title_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.title_field_entry WHERE source = bib_id GROUP BY field;
-    INSERT INTO metabib.combined_title_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.title_field_entry WHERE source = bib_id;
-
-    DELETE FROM metabib.combined_author_field_entry WHERE record = bib_id;
-    INSERT INTO metabib.combined_author_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.author_field_entry WHERE source = bib_id GROUP BY field;
-    INSERT INTO metabib.combined_author_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.author_field_entry WHERE source = bib_id;
-
-    DELETE FROM metabib.combined_subject_field_entry WHERE record = bib_id;
-    INSERT INTO metabib.combined_subject_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.subject_field_entry WHERE source = bib_id GROUP BY field;
-    INSERT INTO metabib.combined_subject_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.subject_field_entry WHERE source = bib_id;
-
-    DELETE FROM metabib.combined_series_field_entry WHERE record = bib_id;
-    INSERT INTO metabib.combined_series_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.series_field_entry WHERE source = bib_id GROUP BY field;
-    INSERT INTO metabib.combined_series_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.series_field_entry WHERE source = bib_id;
-
-    DELETE FROM metabib.combined_identifier_field_entry WHERE record = bib_id;
-    INSERT INTO metabib.combined_identifier_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, field, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.identifier_field_entry WHERE source = bib_id GROUP BY field;
-    INSERT INTO metabib.combined_identifier_field_entry(record, metabib_field, index_vector)
-        SELECT bib_id, NULL, strip(COALESCE(string_agg(index_vector::TEXT,' '),'')::tsvector)
-        FROM metabib.identifier_field_entry WHERE source = bib_id;
-
-    -- For each virtual def, gather the data from the combined real field
-    -- entries and append it to the virtual combined entry.
-    FOR vfield, rfields IN SELECT virtual, ARRAY_AGG(real)  FROM config.metabib_field_virtual_map GROUP BY virtual LOOP
-        SELECT  field_class INTO vclass
-          FROM  config.metabib_field
-          WHERE id = vfield;
-
-        SELECT  string_agg(index_vector::TEXT,' ')::tsvector INTO rdata
-          FROM  metabib.combined_all_field_entry
-          WHERE record = bib_id
-                AND metabib_field = ANY (rfields);
-
-        BEGIN -- I cannot wait for INSERT ON CONFLICT ... 9.5, though
-            EXECUTE $$
-                INSERT INTO metabib.combined_$$ || vclass || $$_field_entry
-                    (record, metabib_field, index_vector) VALUES ($1, $2, $3)
-            $$ USING bib_id, vfield, rdata;
-        EXCEPTION WHEN unique_violation THEN
-            EXECUTE $$
-                UPDATE  metabib.combined_$$ || vclass || $$_field_entry
-                  SET   index_vector = index_vector || $3
-                  WHERE record = $1
-                        AND metabib_field = $2
-            $$ USING bib_id, vfield, rdata;
-        WHEN OTHERS THEN
-            -- ignore and move on
-        END;
-    END LOOP;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE VIEW search.best_tsconfig AS
-    SELECT  m.id AS id,
-            COALESCE(f.ts_config, c.ts_config, 'simple') AS ts_config
-      FROM  config.metabib_field m
-            LEFT JOIN config.metabib_class_ts_map c ON (c.field_class = m.field_class AND c.index_weight = 'C')
-            LEFT JOIN config.metabib_field_ts_map f ON (f.metabib_field = m.id AND f.index_weight = 'C');
-
-CREATE TYPE search.highlight_result AS ( id BIGINT, source BIGINT, field INT, value TEXT, highlight TEXT );
-
-CREATE OR REPLACE FUNCTION search.highlight_display_fields_impl(
-    rid         BIGINT,
-    tsq         TEXT,
-    field_list  INT[] DEFAULT '{}'::INT[],
-    css_class   TEXT DEFAULT 'oils_SH',
-    hl_all      BOOL DEFAULT TRUE,
-    minwords    INT DEFAULT 5,
-    maxwords    INT DEFAULT 25,
-    shortwords  INT DEFAULT 0,
-    maxfrags    INT DEFAULT 0,
-    delimiter   TEXT DEFAULT ' ... '
-) RETURNS SETOF search.highlight_result AS $f$
-DECLARE
-    opts            TEXT := '';
-    v_css_class     TEXT := css_class;
-    v_delimiter     TEXT := delimiter;
-    v_field_list    INT[] := field_list;
-    hl_query        TEXT;
-BEGIN
-    IF v_delimiter LIKE $$%'%$$ OR v_delimiter LIKE '%"%' THEN --"
-        v_delimiter := ' ... ';
-    END IF;
-
-    IF NOT hl_all THEN
-        opts := opts || 'MinWords=' || minwords;
-        opts := opts || ', MaxWords=' || maxwords;
-        opts := opts || ', ShortWords=' || shortwords;
-        opts := opts || ', MaxFragments=' || maxfrags;
-        opts := opts || ', FragmentDelimiter="' || delimiter || '"';
-    ELSE
-        opts := opts || 'HighlightAll=TRUE';
-    END IF;
-
-    IF v_css_class LIKE $$%'%$$ OR v_css_class LIKE '%"%' THEN -- "
-        v_css_class := 'oils_SH';
-    END IF;
-
-    opts := opts || $$, StopSel=</b>, StartSel="<b class='$$ || v_css_class; -- "
-
-    IF v_field_list = '{}'::INT[] THEN
-        SELECT ARRAY_AGG(id) INTO v_field_list FROM config.metabib_field WHERE display_field;
-    END IF;
-
-    hl_query := $$
-        SELECT  de.id,
-                de.source,
-                de.field,
-                de.value AS value,
-                ts_headline(
-                    ts_config::REGCONFIG,
-                    evergreen.escape_for_html(de.value),
-                    $$ || quote_literal(tsq) || $$,
-                    $1 || ' ' || mf.field_class || ' ' || mf.name || $xx$'>"$xx$ -- "'
-                ) AS highlight
-          FROM  metabib.display_entry de
-                JOIN config.metabib_field mf ON (mf.id = de.field)
-                JOIN search.best_tsconfig t ON (t.id = de.field)
-          WHERE de.source = $2
-                AND field = ANY ($3)
-          ORDER BY de.id;$$;
-
-    RETURN QUERY EXECUTE hl_query USING opts, rid, v_field_list;
-END;
-$f$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION evergreen.escape_for_html (TEXT) RETURNS TEXT AS $$
-    SELECT  regexp_replace(
-                regexp_replace(
-                    regexp_replace(
-                        $1,
-                        '&',
-                        '&amp;',
-                        'g'
-                    ),
-                    '<',
-                    '&lt;',
-                    'g'
-                ),
-                '>',
-                '&gt;',
-                'g'
-            );
-$$ LANGUAGE SQL IMMUTABLE LEAKPROOF STRICT COST 10;
-
-CREATE OR REPLACE FUNCTION search.highlight_display_fields(
-    rid         BIGINT,
-    tsq_map     TEXT, -- { '(a | b) & c' => '1,2,3,4', ...}
-    css_class   TEXT DEFAULT 'oils_SH',
-    hl_all      BOOL DEFAULT TRUE,
-    minwords    INT DEFAULT 5,
-    maxwords    INT DEFAULT 25,
-    shortwords  INT DEFAULT 0,
-    maxfrags    INT DEFAULT 0,
-    delimiter   TEXT DEFAULT ' ... '
-) RETURNS SETOF search.highlight_result AS $f$
-DECLARE
-    tsq_hstore  HSTORE;
-    tsq         TEXT;
-    fields      TEXT;
-    afields     INT[];
-    seen        INT[];
-BEGIN
-
-    IF (tsq_map ILIKE 'hstore%') THEN
-        EXECUTE 'SELECT ' || tsq_map INTO tsq_hstore;
-    ELSE
-        tsq_hstore := tsq_map::HSTORE;
-    END IF;
-    
-    FOR tsq, fields IN SELECT key, value FROM each(tsq_hstore::HSTORE) LOOP
-        SELECT  ARRAY_AGG(unnest::INT) INTO afields
-          FROM  unnest(regexp_split_to_array(fields,','));
-        seen := seen || afields;
-
-        RETURN QUERY
-            SELECT * FROM search.highlight_display_fields_impl(
-                rid, tsq, afields, css_class, hl_all,minwords,
-                maxwords, shortwords, maxfrags, delimiter
-            );
-    END LOOP;
-
-    RETURN QUERY
-        SELECT  id,
-                source,
-                field,
-                value,
-                value AS highlight
-          FROM  metabib.display_entry
-          WHERE source = rid
-                AND NOT (field = ANY (seen));
-END;
-$f$ LANGUAGE PLPGSQL ROWS 10;
-CREATE OR REPLACE FUNCTION metabib.remap_metarecord_for_bib(
-    bib_id bigint,
-    fp text,
-    bib_is_deleted boolean DEFAULT false,
-    retain_deleted boolean DEFAULT false
-) RETURNS bigint AS $function$
-DECLARE
-    new_mapping     BOOL := TRUE;
-    source_count    INT;
-    old_mr          BIGINT;
-    tmp_mr          metabib.metarecord%ROWTYPE;
-    deleted_mrs     BIGINT[];
-BEGIN
-
-    -- We need to make sure we're not a deleted master record of an MR
-    IF bib_is_deleted THEN
-        IF NOT retain_deleted THEN -- Go away for any MR that we're master of, unless retained
-            DELETE FROM metabib.metarecord_source_map WHERE source = bib_id;
-        END IF;
-
-        FOR old_mr IN SELECT id FROM metabib.metarecord WHERE master_record = bib_id LOOP
-
-            -- Now, are there any more sources on this MR?
-            SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = old_mr;
-
-            IF source_count = 0 AND NOT retain_deleted THEN -- No other records
-                deleted_mrs := ARRAY_APPEND(deleted_mrs, old_mr); -- Just in case...
-                DELETE FROM metabib.metarecord WHERE id = old_mr;
-
-            ELSE -- indeed there are. Update it with a null cache and recalcualated master record
-                UPDATE  metabib.metarecord
-                  SET   mods = NULL,
-                        master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC LIMIT 1)
-                  WHERE id = old_mr;
-            END IF;
-        END LOOP;
-
-    ELSE -- insert or update
-
-        FOR tmp_mr IN SELECT m.* FROM metabib.metarecord m JOIN metabib.metarecord_source_map s ON (s.metarecord = m.id) WHERE s.source = bib_id LOOP
-
-            -- Find the first fingerprint-matching
-            IF old_mr IS NULL AND fp = tmp_mr.fingerprint THEN
-                old_mr := tmp_mr.id;
-                new_mapping := FALSE;
-
-            ELSE -- Our fingerprint changed ... maybe remove the old MR
-                DELETE FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id AND source = bib_id; -- remove the old source mapping
-                SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id;
-                IF source_count = 0 THEN -- No other records
-                    deleted_mrs := ARRAY_APPEND(deleted_mrs, tmp_mr.id);
-                    DELETE FROM metabib.metarecord WHERE id = tmp_mr.id;
-                END IF;
-            END IF;
-
-        END LOOP;
-
-        -- we found no suitable, preexisting MR based on old source maps
-        IF old_mr IS NULL THEN
-            SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp; -- is there one for our current fingerprint?
-
-            IF old_mr IS NULL THEN -- nope, create one and grab its id
-                INSERT INTO metabib.metarecord ( fingerprint, master_record ) VALUES ( fp, bib_id );
-                SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp;
-
-            ELSE -- indeed there is. update it with a null cache and recalcualated master record
-                UPDATE  metabib.metarecord
-                  SET   mods = NULL,
-                        master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC LIMIT 1)
-                  WHERE id = old_mr;
-            END IF;
-
-        ELSE -- there was one we already attached to, update its mods cache and master_record
-            UPDATE  metabib.metarecord
-              SET   mods = NULL,
-                    master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC LIMIT 1)
-              WHERE id = old_mr;
-        END IF;
-
-        IF new_mapping THEN
-            INSERT INTO metabib.metarecord_source_map (metarecord, source) VALUES (old_mr, bib_id); -- new source mapping
-        END IF;
-
-    END IF;
-
-    IF ARRAY_UPPER(deleted_mrs,1) > 0 THEN
-        UPDATE action.hold_request SET target = old_mr WHERE target IN ( SELECT unnest(deleted_mrs) ) AND hold_type = 'M'; -- if we had to delete any MRs above, make sure their holds are moved
-    END IF;
-
-    RETURN old_mr;
-
-END;
-$function$ LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION evergreen.marc_to (marc text, xfrm text) RETURNS TEXT AS $$
-    SELECT evergreen.xml_pretty_print(xslt_process($1,xslt)::XML)::TEXT FROM config.xml_transform WHERE name = $2;
-$$ LANGUAGE SQL;
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1102', :eg_version);
-
-update config.xml_transform set xslt = $XXXX$<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc" version="1.0">
-        <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
-<!--
-Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements
-  with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
-
-Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28 tmee
-
-Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11 tmee
-
-Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>
-      2006/04/08  jrad
-
-Revision 1.10 MODS 3.1 revisions to language and classification elements
-                                (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)
-                                2006/02/06  ggar
-
-Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
-
-Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
-
-Revision 1.7 2004/03/25 08:29 jrad
-
-Revision 1.6 various validation fixes 2004/02/20 ntra
-
-Revision 1.5  2003/10/02 16:18:58  ntra
-MODS2 to MODS3 updates, language unstacking and
-de-duping, chopPunctuation expanded
-
-Revision 1.3  2003/04/03 00:07:19  ntra
-Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
-
-Revision 1.2  2003/03/24 19:37:42  ckeith
-Added Log Comment
-
--->
-        <xsl:template match="/">
-                <xsl:choose>
-                        <xsl:when test="//marc:collection">
-                                <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
-                                        <xsl:for-each select="//marc:collection/marc:record">
-                                                <mods version="3.2">
-                                                        <xsl:call-template name="marcRecord"/>
-                                                </mods>
-                                        </xsl:for-each>
-                                </modsCollection>
-                        </xsl:when>
-                        <xsl:otherwise>
-                                <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
-                                        <xsl:for-each select="//marc:record">
-                                                <xsl:call-template name="marcRecord"/>
-                                        </xsl:for-each>
-                                </mods>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="marcRecord">
-                <xsl:variable name="leader" select="marc:leader"/>
-                <xsl:variable name="leader6" select="substring($leader,7,1)"/>
-                <xsl:variable name="leader7" select="substring($leader,8,1)"/>
-                <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
-                <xsl:variable name="typeOf008">
-                        <xsl:choose>
-                                <xsl:when test="$leader6='a'">
-                                        <xsl:choose>
-                                                <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
-                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
-                                        </xsl:choose>
-                                </xsl:when>
-                                <xsl:when test="$leader6='t'">BK</xsl:when>
-                                <xsl:when test="$leader6='p'">MM</xsl:when>
-                                <xsl:when test="$leader6='m'">CF</xsl:when>
-                                <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
-                                <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
-                                <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:for-each select="marc:datafield[@tag='245']">
-                        <titleInfo>
-                                <xsl:variable name="title">
-                                        <xsl:choose>
-                                                <xsl:when test="marc:subfield[@code='b']">
-                                                        <xsl:call-template name="specialSubfieldSelect">
-                                                                <xsl:with-param name="axis">b</xsl:with-param>
-                                                                <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:when>
-                                                <xsl:otherwise>
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:otherwise>
-                                        </xsl:choose>
-                                </xsl:variable>
-                                <xsl:variable name="titleChop">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="$title"/>
-                                                </xsl:with-param>
-                                                <xsl:with-param name="punctuation">
-                                                    <xsl:text>,;/ </xsl:text>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:variable>
-                                <xsl:choose>
-                                        <xsl:when test="@ind2>0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleChop,1,@ind2)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleChop,@ind2+1)"/>
-                                                </title>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleChop"/>
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:if test="marc:subfield[@code='b']">
-                                        <subTitle>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="axis">b</xsl:with-param>
-                                                                        <xsl:with-param name="anyCodes">b</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">afgk</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </subTitle>
-                                </xsl:if>
-                                <xsl:call-template name="part"></xsl:call-template>
-                        </titleInfo>
-                        <!-- A form of title that ignores non-filing characters; useful
-                                 for not converting "L'Oreal" into "L' Oreal" at index time -->
-                        <titleNonfiling>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="part"></xsl:call-template>
-                        </titleNonfiling>
-                        <!-- hybrid of titleInfo and titleNonfiling which will give us a preformatted string (for punctuation)
-                                 but also keep the nonSort stuff in a separate field (for sorting) -->
-                        <titleBrowse>
-                                <xsl:variable name="titleBrowseChop">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:variable>
-                                <xsl:choose>
-                                        <xsl:when test="@ind2>0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleBrowseChop,1,@ind2)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleBrowseChop,@ind2+1)"/>
-                                                </title>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleBrowseChop"/>
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:call-template name="part"></xsl:call-template>
-                        </titleBrowse>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='210']">
-                        <titleInfo type="abbreviated">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">a</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="subtitle"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='242']">
-                        <xsl:variable name="titleChop">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <!-- 1/04 removed $h, b -->
-                                                        <xsl:with-param name="codes">a</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:variable>
-                        <titleInfo type="translated">
-                                <!--09/01/04 Added subfield $y-->
-                                <xsl:for-each select="marc:subfield[@code='y']">
-                                        <xsl:attribute name="lang">
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:attribute>
-                                </xsl:for-each>
-                                <title>
-                                        <xsl:value-of select="$titleChop" />
-                                </title>
-                                <!-- 1/04 fix -->
-                                <xsl:call-template name="subtitle"/>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                        <titleInfo type="translated-nfi">
-                                <xsl:for-each select="marc:subfield[@code='y']">
-                                        <xsl:attribute name="lang">
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:attribute>
-                                </xsl:for-each>
-                                <xsl:choose>
-                                        <xsl:when test="@ind2>0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleChop,1,@ind2)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleChop,@ind2+1)"/>
-                                                </title>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleChop" />
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:call-template name="subtitle"/>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='246']">
-                        <titleInfo type="alternative">
-                                <xsl:for-each select="marc:subfield[@code='i']">
-                                        <xsl:attribute name="displayLabel">
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:attribute>
-                                </xsl:for-each>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <!-- 1/04 removed $h, $b -->
-                                                                <xsl:with-param name="codes">af</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="subtitle"/>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
-                        <xsl:variable name="nfi">
-                                <xsl:choose>
-                                        <xsl:when test="@tag='240'">
-                                                <xsl:value-of select="@ind2"/>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <xsl:value-of select="@ind1"/>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </xsl:variable>
-                        <xsl:variable name="titleChop">
-                                <xsl:call-template name="uri" />
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield">
-                                                <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
-                                                        <xsl:value-of select="text()"/>
-                                                        <xsl:text> </xsl:text>
-                                                </xsl:if>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:variable>
-                        <titleInfo type="uniform">
-                                <title>
-                                        <xsl:value-of select="$titleChop"/>
-                                </title>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                        <titleInfo type="uniform-nfi">
-                                <xsl:choose>
-                                        <xsl:when test="$nfi>0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleChop,1,$nfi)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleChop,$nfi+1)"/>
-                                                </title>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleChop"/>
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
-                        <xsl:variable name="titleChop">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">ah</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:variable>
-                        <titleInfo type="alternative">
-                                <title>
-                                        <xsl:value-of select="$titleChop" />
-                                </title>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                        <titleInfo type="alternative-nfi">
-                                <xsl:choose>
-                                        <xsl:when test="@ind1>0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleChop,1,@ind1)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleChop,@ind1+1)"/>
-                                                </title>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleChop" />
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='100']">
-                        <name type="personal">
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="nameABCDQ"/>
-                                <xsl:call-template name="affiliation"/>
-                                <role>
-                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
-                                </role>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='110']">
-                        <name type="corporate">
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="nameABCDN"/>
-                                <role>
-                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
-                                </role>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='111']">
-                        <name type="conference">
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="nameACDEQ"/>
-                                <role>
-                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
-                                </role>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
-                        <name type="personal">
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="nameABCDQ"/>
-                                <xsl:call-template name="affiliation"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
-                        <name type="corporate">
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="nameABCDN"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
-                        <name type="conference">
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="nameACDEQ"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
-                        <name>
-                                <xsl:if test="@ind1=1">
-                                        <xsl:attribute name="type">
-                                                <xsl:text>personal</xsl:text>
-                                        </xsl:attribute>
-                                </xsl:if>
-                                <namePart>
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </namePart>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <typeOfResource>
-                        <xsl:if test="$leader7='c'">
-                                <xsl:attribute name="collection">yes</xsl:attribute>
-                        </xsl:if>
-                        <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
-                                <xsl:attribute name="manuscript">yes</xsl:attribute>
-                        </xsl:if>
-                        <xsl:choose>
-                                <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
-                                <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
-                                <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
-                                <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
-                                <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
-                                <xsl:when test="$leader6='k'">still image</xsl:when>
-                                <xsl:when test="$leader6='g'">moving image</xsl:when>
-                                <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
-                                <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
-                                <xsl:when test="$leader6='p'">mixed material</xsl:when>
-                        </xsl:choose>
-                </typeOfResource>
-                <xsl:if test="substring($controlField008,26,1)='d'">
-                        <genre authority="marc">globe</genre>
-                </xsl:if>
-                <xsl:if test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
-                        <genre authority="marc">remote sensing image</genre>
-                </xsl:if>
-                <xsl:if test="$typeOf008='MP'">
-                        <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
-                                        <genre authority="marc">map</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
-                                        <genre authority="marc">atlas</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='SE'">
-                        <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-21='d'">
-                                        <genre authority="marc">database</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='l'">
-                                        <genre authority="marc">loose-leaf</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='m'">
-                                        <genre authority="marc">series</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='n'">
-                                        <genre authority="marc">newspaper</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='p'">
-                                        <genre authority="marc">periodical</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='w'">
-                                        <genre authority="marc">web site</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
-                        <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="contains($controlField008-24,'a')">
-                                        <genre authority="marc">abstract or summary</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'b')">
-                                        <genre authority="marc">bibliography</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'c')">
-                                        <genre authority="marc">catalog</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'d')">
-                                        <genre authority="marc">dictionary</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'e')">
-                                        <genre authority="marc">encyclopedia</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'f')">
-                                        <genre authority="marc">handbook</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'g')">
-                                        <genre authority="marc">legal article</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'i')">
-                                        <genre authority="marc">index</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'k')">
-                                        <genre authority="marc">discography</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'l')">
-                                        <genre authority="marc">legislation</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'m')">
-                                        <genre authority="marc">theses</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'n')">
-                                        <genre authority="marc">survey of literature</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'o')">
-                                        <genre authority="marc">review</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'p')">
-                                        <genre authority="marc">programmed text</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'q')">
-                                        <genre authority="marc">filmography</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'r')">
-                                        <genre authority="marc">directory</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'s')">
-                                        <genre authority="marc">statistics</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'t')">
-                                        <genre authority="marc">technical report</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'v')">
-                                        <genre authority="marc">legal case and case notes</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'w')">
-                                        <genre authority="marc">law report or digest</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'z')">
-                                        <genre authority="marc">treaty</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-29='1'">
-                                        <genre authority="marc">conference publication</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='CF'">
-                        <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-26='a'">
-                                        <genre authority="marc">numeric data</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-26='e'">
-                                        <genre authority="marc">database</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-26='f'">
-                                        <genre authority="marc">font</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-26='g'">
-                                        <genre authority="marc">game</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='BK'">
-                        <xsl:if test="substring($controlField008,25,1)='j'">
-                                <genre authority="marc">patent</genre>
-                        </xsl:if>
-                        <xsl:if test="substring($controlField008,31,1)='1'">
-                                <genre authority="marc">festschrift</genre>
-                        </xsl:if>
-                        <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"></xsl:variable>
-                        <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
-                                <genre authority="marc">biography</genre>
-                        </xsl:if>
-                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-33='e'">
-                                        <genre authority="marc">essay</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='d'">
-                                        <genre authority="marc">drama</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='c'">
-                                        <genre authority="marc">comic strip</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='l'">
-                                        <genre authority="marc">fiction</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='h'">
-                                        <genre authority="marc">humor, satire</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='i'">
-                                        <genre authority="marc">letter</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='f'">
-                                        <genre authority="marc">novel</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='j'">
-                                        <genre authority="marc">short story</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='s'">
-                                        <genre authority="marc">speech</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='MU'">
-                        <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"></xsl:variable>
-                        <xsl:if test="contains($controlField008-30-31,'b')">
-                                <genre authority="marc">biography</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'c')">
-                                <genre authority="marc">conference publication</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'d')">
-                                <genre authority="marc">drama</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'e')">
-                                <genre authority="marc">essay</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'f')">
-                                <genre authority="marc">fiction</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'o')">
-                                <genre authority="marc">folktale</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'h')">
-                                <genre authority="marc">history</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'k')">
-                                <genre authority="marc">humor, satire</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'m')">
-                                <genre authority="marc">memoir</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'p')">
-                                <genre authority="marc">poetry</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'r')">
-                                <genre authority="marc">rehearsal</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'g')">
-                                <genre authority="marc">reporting</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'s')">
-                                <genre authority="marc">sound</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'l')">
-                                <genre authority="marc">speech</genre>
-                        </xsl:if>
-                </xsl:if>
-                <xsl:if test="$typeOf008='VM'">
-                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-33='a'">
-                                        <genre authority="marc">art original</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='b'">
-                                        <genre authority="marc">kit</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='c'">
-                                        <genre authority="marc">art reproduction</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='d'">
-                                        <genre authority="marc">diorama</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='f'">
-                                        <genre authority="marc">filmstrip</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='g'">
-                                        <genre authority="marc">legal article</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='i'">
-                                        <genre authority="marc">picture</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='k'">
-                                        <genre authority="marc">graphic</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='l'">
-                                        <genre authority="marc">technical drawing</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='m'">
-                                        <genre authority="marc">motion picture</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='n'">
-                                        <genre authority="marc">chart</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='o'">
-                                        <genre authority="marc">flash card</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='p'">
-                                        <genre authority="marc">microscope slide</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
-                                        <genre authority="marc">model</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='r'">
-                                        <genre authority="marc">realia</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='s'">
-                                        <genre authority="marc">slide</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='t'">
-                                        <genre authority="marc">transparency</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='v'">
-                                        <genre authority="marc">videorecording</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='w'">
-                                        <genre authority="marc">toy</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=655]">
-                        <genre authority="marc">
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"/>
-                                </xsl:attribute>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abvxyz</xsl:with-param>
-                                        <xsl:with-param name="delimeter">-</xsl:with-param>
-                                </xsl:call-template>
-                        </genre>
-                </xsl:for-each>
-                <originInfo>
-                        <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"></xsl:variable>
-                        <xsl:if test="translate($MARCpublicationCode,'|','')">
-                                <place>
-                                        <placeTerm>
-                                                <xsl:attribute name="type">code</xsl:attribute>
-                                                <xsl:attribute name="authority">marccountry</xsl:attribute>
-                                                <xsl:value-of select="$MARCpublicationCode"/>
-                                        </placeTerm>
-                                </place>
-                        </xsl:if>
-                        <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
-                                <place>
-                                        <placeTerm>
-                                                <xsl:attribute name="type">code</xsl:attribute>
-                                                <xsl:attribute name="authority">iso3166</xsl:attribute>
-                                                <xsl:value-of select="."/>
-                                        </placeTerm>
-                                </place>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
-                                <place>
-                                        <placeTerm>
-                                                <xsl:attribute name="type">text</xsl:attribute>
-                                                <xsl:call-template name="chopPunctuationFront">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="chopPunctuation">
-                                                                        <xsl:with-param name="chopString" select="."/>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </placeTerm>
-                                </place>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
-                                <dateValid point="start">
-                                        <xsl:value-of select="."/>
-                                </dateValid>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
-                                <dateValid point="end">
-                                        <xsl:value-of select="."/>
-                                </dateValid>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
-                                <dateModified>
-                                        <xsl:value-of select="."/>
-                                </dateModified>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
-                                <xsl:choose>
-                                        <xsl:when test="@code='b'">
-                                                <publisher>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                                <xsl:with-param name="punctuation">
-                                                                        <xsl:text>:,;/ </xsl:text>
-                                                                </xsl:with-param>
-                                                        </xsl:call-template>
-                                                </publisher>
-                                        </xsl:when>
-                                        <xsl:when test="@code='c'">
-                                                <dateIssued>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </dateIssued>
-                                        </xsl:when>
-                                        <xsl:when test="@code='g'">
-                                                <dateCreated>
-                                                        <xsl:value-of select="."/>
-                                                </dateCreated>
-                                        </xsl:when>
-                                </xsl:choose>
-                        </xsl:for-each>
-                        <xsl:variable name="dataField260c">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"></xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:variable>
-                        <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"></xsl:variable>
-                        <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"></xsl:variable>
-                        <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"></xsl:variable>
-                        <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
-                                <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
-                                        <dateIssued encoding="marc">
-                                                <xsl:value-of select="$controlField008-7-10"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
-                                <xsl:if test="$controlField008-7-10">
-                                        <dateIssued encoding="marc" point="start">
-                                                <xsl:value-of select="$controlField008-7-10"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
-                                <xsl:if test="$controlField008-11-14">
-                                        <dateIssued encoding="marc" point="end">
-                                                <xsl:value-of select="$controlField008-11-14"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='q'">
-                                <xsl:if test="$controlField008-7-10">
-                                        <dateIssued encoding="marc" point="start" qualifier="questionable">
-                                                <xsl:value-of select="$controlField008-7-10"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='q'">
-                                <xsl:if test="$controlField008-11-14">
-                                        <dateIssued encoding="marc" point="end" qualifier="questionable">
-                                                <xsl:value-of select="$controlField008-11-14"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='t'">
-                                <xsl:if test="$controlField008-11-14">
-                                        <copyrightDate encoding="marc">
-                                                <xsl:value-of select="$controlField008-11-14"/>
-                                        </copyrightDate>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
-                                <dateCaptured encoding="iso8601">
-                                        <xsl:value-of select="."/>
-                                </dateCaptured>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
-                                <dateCaptured encoding="iso8601" point="start">
-                                        <xsl:value-of select="."/>
-                                </dateCaptured>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
-                                <dateCaptured encoding="iso8601" point="end">
-                                        <xsl:value-of select="."/>
-                                </dateCaptured>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
-                                <edition>
-                                        <xsl:value-of select="."/>
-                                </edition>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:leader">
-                                <issuance>
-                                        <xsl:choose>
-                                                <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
-                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
-                                        </xsl:choose>
-                                </issuance>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
-                                <frequency>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">ab</xsl:with-param>
-                                        </xsl:call-template>
-                                </frequency>
-                        </xsl:for-each>
-                </originInfo>
-                <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"></xsl:variable>
-                <xsl:if test="$controlField008-35-37">
-                        <language>
-                                <languageTerm authority="iso639-2b" type="code">
-                                        <xsl:value-of select="substring($controlField008,36,3)"/>
-                                </languageTerm>
-                        </language>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=041]">
-                        <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
-                                <xsl:variable name="langCodes" select="."/>
-                                <xsl:choose>
-                                        <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
-                                                <!-- not stacked but could be repeated -->
-                                                <xsl:call-template name="rfcLanguages">
-                                                        <xsl:with-param name="nodeNum">
-                                                                <xsl:value-of select="1"/>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="usedLanguages">
-                                                                <xsl:text></xsl:text>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="controlField008-35-37">
-                                                                <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <!-- iso -->
-                                                <xsl:variable name="allLanguages">
-                                                        <xsl:copy-of select="$langCodes"></xsl:copy-of>
-                                                </xsl:variable>
-                                                <xsl:variable name="currentLanguage">
-                                                        <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
-                                                </xsl:variable>
-                                                <xsl:call-template name="isoLanguage">
-                                                        <xsl:with-param name="currentLanguage">
-                                                                <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="remainingLanguages">
-                                                                <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"></xsl:value-of>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="usedLanguages">
-                                                                <xsl:if test="$controlField008-35-37">
-                                                                        <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
-                                                                </xsl:if>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </xsl:for-each>
-                </xsl:for-each>
-                <xsl:variable name="physicalDescription">
-                        <!--3.2 change tmee 007/11 -->
-                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
-                                <digitalOrigin>reformatted digital</digitalOrigin>
-                        </xsl:if>
-                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
-                                <digitalOrigin>digitized microfilm</digitalOrigin>
-                        </xsl:if>
-                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
-                                <digitalOrigin>digitized other analog</digitalOrigin>
-                        </xsl:if>
-                        <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"></xsl:variable>
-                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
-                        <xsl:variable name="check008-23">
-                                <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
-                                        <xsl:value-of select="true()"></xsl:value-of>
-                                </xsl:if>
-                        </xsl:variable>
-                        <xsl:variable name="check008-29">
-                                <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
-                                        <xsl:value-of select="true()"></xsl:value-of>
-                                </xsl:if>
-                        </xsl:variable>
-                        <xsl:choose>
-                                <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
-                                        <form authority="marcform">braille</form>
-                                </xsl:when>
-                                <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
-                                        <form authority="marcform">print</form>
-                                </xsl:when>
-                                <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
-                                        <form authority="marcform">electronic</form>
-                                </xsl:when>
-                                <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
-                                        <form authority="marcform">microfiche</form>
-                                </xsl:when>
-                                <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
-                                        <form authority="marcform">microfilm</form>
-                                </xsl:when>
-                        </xsl:choose>
-                        <!-- 1/04 fix -->
-                        <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
-                                <form>
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </form>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
-                                <xsl:choose>
-                                        <xsl:when test="substring(text(),14,1)='a'">
-                                                <reformattingQuality>access</reformattingQuality>
-                                        </xsl:when>
-                                        <xsl:when test="substring(text(),14,1)='p'">
-                                                <reformattingQuality>preservation</reformattingQuality>
-                                        </xsl:when>
-                                        <xsl:when test="substring(text(),14,1)='r'">
-                                                <reformattingQuality>replacement</reformattingQuality>
-                                        </xsl:when>
-                                </xsl:choose>
-                        </xsl:for-each>
-                        <!--3.2 change tmee 007/01 -->
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
-                                <form authority="smd">chip cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
-                                <form authority="smd">computer optical disc cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
-                                <form authority="smd">magnetic disc</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
-                                <form authority="smd">magneto-optical disc</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
-                                <form authority="smd">optical disc</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
-                                <form authority="smd">remote</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
-                                <form authority="smd">tape cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
-                                <form authority="smd">tape cassette</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
-                                <form authority="smd">tape reel</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
-                                <form authority="smd">celestial globe</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
-                                <form authority="smd">earth moon globe</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
-                                <form authority="smd">planetary or lunar globe</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
-                                <form authority="smd">terrestrial globe</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
-                                <form authority="smd">kit</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
-                                <form authority="smd">atlas</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
-                                <form authority="smd">diagram</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
-                                <form authority="smd">map</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
-                                <form authority="smd">model</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
-                                <form authority="smd">profile</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
-                                <form authority="smd">remote-sensing image</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
-                                <form authority="smd">section</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
-                                <form authority="smd">view</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
-                                <form authority="smd">aperture card</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
-                                <form authority="smd">microfiche</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
-                                <form authority="smd">microfiche cassette</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
-                                <form authority="smd">microfilm cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
-                                <form authority="smd">microfilm cassette</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
-                                <form authority="smd">microfilm reel</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
-                                <form authority="smd">microopaque</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
-                                <form authority="smd">film cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
-                                <form authority="smd">film cassette</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
-                                <form authority="smd">film reel</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
-                                <form authority="smd">chart</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
-                                <form authority="smd">collage</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
-                                <form authority="smd">drawing</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
-                                <form authority="smd">flash card</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
-                                <form authority="smd">painting</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
-                                <form authority="smd">photomechanical print</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
-                                <form authority="smd">photonegative</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
-                                <form authority="smd">photoprint</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
-                                <form authority="smd">picture</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
-                                <form authority="smd">print</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
-                                <form authority="smd">technical drawing</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
-                                <form authority="smd">notated music</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
-                                <form authority="smd">filmslip</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
-                                <form authority="smd">filmstrip cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
-                                <form authority="smd">filmstrip roll</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
-                                <form authority="smd">other filmstrip type</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
-                                <form authority="smd">slide</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
-                                <form authority="smd">transparency</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
-                                <form authority="smd">remote-sensing image</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
-                                <form authority="smd">cylinder</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
-                                <form authority="smd">roll</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
-                                <form authority="smd">sound cartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
-                                <form authority="smd">sound cassette</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
-                                <form authority="smd">sound disc</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
-                                <form authority="smd">sound-tape reel</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
-                                <form authority="smd">sound-track film</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
-                                <form authority="smd">wire recording</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
-                                <form authority="smd">braille</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
-                                <form authority="smd">combination</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
-                                <form authority="smd">moon</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
-                                <form authority="smd">tactile, with no writing system</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
-                                <form authority="smd">braille</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
-                                <form authority="smd">large print</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
-                                <form authority="smd">regular print</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
-                                <form authority="smd">text in looseleaf binder</form>
-                        </xsl:if>
-
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
-                                <form authority="smd">videocartridge</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
-                                <form authority="smd">videocassette</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
-                                <form authority="smd">videodisc</form>
-                        </xsl:if>
-                        <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
-                                <form authority="smd">videoreel</form>
-                        </xsl:if>
-
-                        <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
-                                <internetMediaType>
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </internetMediaType>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=300]">
-                                <extent>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abce</xsl:with-param>
-                                        </xsl:call-template>
-                                </extent>
-                        </xsl:for-each>
-                </xsl:variable>
-                <xsl:if test="string-length(normalize-space($physicalDescription))">
-                        <physicalDescription>
-                                <xsl:copy-of select="$physicalDescription"></xsl:copy-of>
-                        </physicalDescription>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=520]">
-                        <abstract>
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </abstract>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=505]">
-                        <tableOfContents>
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">agrt</xsl:with-param>
-                                </xsl:call-template>
-                        </tableOfContents>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=521]">
-                        <targetAudience>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </targetAudience>
-                </xsl:for-each>
-                <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
-                        <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"></xsl:variable>
-                        <xsl:choose>
-                                <!-- 01/04 fix -->
-                                <xsl:when test="$controlField008-22='d'">
-                                        <targetAudience authority="marctarget">adolescent</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='e'">
-                                        <targetAudience authority="marctarget">adult</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='g'">
-                                        <targetAudience authority="marctarget">general</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
-                                        <targetAudience authority="marctarget">juvenile</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='a'">
-                                        <targetAudience authority="marctarget">preschool</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='f'">
-                                        <targetAudience authority="marctarget">specialized</targetAudience>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
-                        <note type="statement of responsibility">
-                                <xsl:value-of select="."></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=500]">
-                        <note>
-                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                                <xsl:call-template name="uri"></xsl:call-template>
-                        </note>
-                </xsl:for-each>
-
-                <!--3.2 change tmee additional note fields-->
-
-                <xsl:for-each select="marc:datafield[@tag=502]">
-                        <note type="thesis">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=504]">
-                        <note type="bibliography">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=508]">
-                        <note type="creation/production credits">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=506]">
-                        <note type="restrictions">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=510]">
-                        <note  type="citation/reference">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-
-                <xsl:for-each select="marc:datafield[@tag=511]">
-                        <note type="performers">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=518]">
-                        <note type="venue">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=530]">
-                        <note  type="additional physical form">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=533]">
-                        <note  type="reproduction">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=534]">
-                        <note  type="original version">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=538]">
-                        <note  type="system details">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=583]">
-                        <note type="action">
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-
-
-
-
-
-                <xsl:for-each select="marc:datafield[@tag=501 or @tag=507 or  @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
-                        <note>
-                                <xsl:call-template name="uri"></xsl:call-template>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
-                        <subject>
-                                <cartographics>
-                                        <coordinates>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">defg</xsl:with-param>
-                                                </xsl:call-template>
-                                        </coordinates>
-                                </cartographics>
-                        </subject>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=043]">
-                        <subject>
-                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
-                                        <geographicCode>
-                                                <xsl:attribute name="authority">
-                                                        <xsl:if test="@code='a'">
-                                                                <xsl:text>marcgac</xsl:text>
-                                                        </xsl:if>
-                                                        <xsl:if test="@code='b'">
-                                                                <xsl:value-of select="following-sibling::marc:subfield[@code=2]"></xsl:value-of>
-                                                        </xsl:if>
-                                                        <xsl:if test="@code='c'">
-                                                                <xsl:text>iso3166</xsl:text>
-                                                        </xsl:if>
-                                                </xsl:attribute>
-                                                <xsl:value-of select="self::marc:subfield"></xsl:value-of>
-                                        </geographicCode>
-                                </xsl:for-each>
-                        </subject>
-                </xsl:for-each>
-                <!-- tmee 2006/11/27 -->
-                <xsl:for-each select="marc:datafield[@tag=255]">
-                        <subject>
-                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
-                                <cartographics>
-                                        <xsl:if test="@code='a'">
-                                                <scale>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </scale>
-                                        </xsl:if>
-                                        <xsl:if test="@code='b'">
-                                                <projection>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </projection>
-                                        </xsl:if>
-                                        <xsl:if test="@code='c'">
-                                                <coordinates>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </coordinates>
-                                        </xsl:if>
-                                </cartographics>
-                                </xsl:for-each>
-                        </subject>
-                </xsl:for-each>
-
-                <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"></xsl:apply-templates>
-                <xsl:apply-templates select="marc:datafield[@tag=656]"></xsl:apply-templates>
-                <xsl:for-each select="marc:datafield[@tag=752]">
-                        <subject>
-                                <hierarchicalGeographic>
-                                        <xsl:for-each select="marc:subfield[@code='a']">
-                                                <country>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                                        </xsl:call-template>
-                                                </country>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='b']">
-                                                <state>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                                        </xsl:call-template>
-                                                </state>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='c']">
-                                                <county>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                                        </xsl:call-template>
-                                                </county>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='d']">
-                                                <city>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                                        </xsl:call-template>
-                                                </city>
-                                        </xsl:for-each>
-                                </hierarchicalGeographic>
-                        </subject>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
-                        <subject>
-                                <xsl:choose>
-                                        <xsl:when test="@ind1=2">
-                                                <temporal encoding="iso8601" point="start">
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString">
-                                                                        <xsl:value-of select="marc:subfield[@code='b'][1]"></xsl:value-of>
-                                                                </xsl:with-param>
-                                                        </xsl:call-template>
-                                                </temporal>
-                                                <temporal encoding="iso8601" point="end">
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString">
-                                                                        <xsl:value-of select="marc:subfield[@code='b'][2]"></xsl:value-of>
-                                                                </xsl:with-param>
-                                                        </xsl:call-template>
-                                                </temporal>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <xsl:for-each select="marc:subfield[@code='b']">
-                                                        <temporal encoding="iso8601">
-                                                                <xsl:call-template name="chopPunctuation">
-                                                                        <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </temporal>
-                                                </xsl:for-each>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </subject>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=050]">
-                        <xsl:for-each select="marc:subfield[@code='b']">
-                                <classification authority="lcc">
-                                        <xsl:if test="../marc:subfield[@code='3']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"></xsl:value-of>
-                                        <xsl:text> </xsl:text>
-                                        <xsl:value-of select="text()"></xsl:value-of>
-                                </classification>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
-                                <classification authority="lcc">
-                                        <xsl:if test="../marc:subfield[@code='3']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="text()"></xsl:value-of>
-                                </classification>
-                        </xsl:for-each>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=082]">
-                        <classification authority="ddc">
-                                <xsl:if test="marc:subfield[@code='2']">
-                                        <xsl:attribute name="edition">
-                                                <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
-                                        </xsl:attribute>
-                                </xsl:if>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=080]">
-                        <classification authority="udc">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abx</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=060]">
-                        <classification authority="nlm">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
-                        <classification authority="sudocs">
-                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
-                        <classification authority="candoc">
-                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=086]">
-                        <classification>
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
-                                </xsl:attribute>
-                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=084]">
-                        <classification>
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
-                                </xsl:attribute>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=440]">
-                        <relatedItem type="series">
-                                <xsl:variable name="titleChop">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">av</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:variable>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:value-of select="$titleChop" />
-                                        </title>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                                <titleInfo type="nfi">
-                                        <xsl:choose>
-                                                <xsl:when test="@ind2>0">
-                                                        <nonSort>
-                                                                <xsl:value-of select="substring($titleChop,1,@ind2)"/>
-                                                        </nonSort>
-                                                        <title>
-                                                                <xsl:value-of select="substring($titleChop,@ind2+1)"/>
-                                                        </title>
-                                                        <xsl:call-template name="part"/>
-                                                </xsl:when>
-                                                <xsl:otherwise>
-                                                        <title>
-                                                                <xsl:value-of select="$titleChop" />
-                                                        </title>
-                                                </xsl:otherwise>
-                                        </xsl:choose>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">av</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=510]">
-                        <relatedItem type="isReferencedBy">
-                                <note>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abcx3</xsl:with-param>
-                                        </xsl:call-template>
-                                </note>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=534]">
-                        <relatedItem type="original">
-                                <xsl:call-template name="relatedTitle"></xsl:call-template>
-                                <xsl:call-template name="relatedName"></xsl:call-template>
-                                <xsl:if test="marc:subfield[@code='b' or @code='c']">
-                                        <originInfo>
-                                                <xsl:for-each select="marc:subfield[@code='c']">
-                                                        <publisher>
-                                                                <xsl:value-of select="."></xsl:value-of>
-                                                        </publisher>
-                                                </xsl:for-each>
-                                                <xsl:for-each select="marc:subfield[@code='b']">
-                                                        <edition>
-                                                                <xsl:value-of select="."></xsl:value-of>
-                                                        </edition>
-                                                </xsl:for-each>
-                                        </originInfo>
-                                </xsl:if>
-                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
-                                <xsl:for-each select="marc:subfield[@code='z']">
-                                        <identifier type="isbn">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </identifier>
-                                </xsl:for-each>
-                                <xsl:call-template name="relatedNote"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                                <name type="personal">
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="termsOfAddress"></xsl:call-template>
-                                        <xsl:call-template name="nameDate"></xsl:call-template>
-                                        <xsl:call-template name="role"></xsl:call-template>
-                                </name>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
-                                </titleInfo>
-                                <name type="corporate">
-                                        <xsl:for-each select="marc:subfield[@code='a']">
-                                                <namePart>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='b']">
-                                                <namePart>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <xsl:variable name="tempNamePart">
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:variable>
-                                        <xsl:if test="normalize-space($tempNamePart)">
-                                                <namePart>
-                                                        <xsl:value-of select="$tempNamePart"></xsl:value-of>
-                                                </namePart>
-                                        </xsl:if>
-                                        <xsl:call-template name="role"></xsl:call-template>
-                                </name>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
-                                </titleInfo>
-                                <name type="conference">
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                </name>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
-                                <xsl:variable name="titleChop">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:variable>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:value-of select="$titleChop" />
-                                        </title>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                                <titleInfo type="nfi">
-                                        <xsl:choose>
-                                                <xsl:when test="@ind1>0">
-                                                        <nonSort>
-                                                                <xsl:value-of select="substring($titleChop,1,@ind1)"/>
-                                                        </nonSort>
-                                                        <title>
-                                                                <xsl:value-of select="substring($titleChop,@ind1+1)"/>
-                                                        </title>
-                                                </xsl:when>
-                                                <xsl:otherwise>
-                                                        <title>
-                                                                <xsl:value-of select="$titleChop" />
-                                                        </title>
-                                                </xsl:otherwise>
-                                        </xsl:choose>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
-                        <relatedItem type="series">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
-                        <relatedItem>
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=775]">
-                        <relatedItem type="otherVersion">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
-                        <relatedItem type="constituent">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
-                        <relatedItem type="host">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=776]">
-                        <relatedItem type="otherFormat">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=780]">
-                        <relatedItem type="preceding">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=785]">
-                        <relatedItem type="succeeding">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=786]">
-                        <relatedItem type="original">
-                                <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=800]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"></xsl:call-template>
-                                </titleInfo>
-                                <name type="personal">
-                                        <namePart>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="termsOfAddress"></xsl:call-template>
-                                        <xsl:call-template name="nameDate"></xsl:call-template>
-                                        <xsl:call-template name="role"></xsl:call-template>
-                                </name>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=810]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
-                                </titleInfo>
-                                <name type="corporate">
-                                        <xsl:for-each select="marc:subfield[@code='a']">
-                                                <namePart>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='b']">
-                                                <namePart>
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="role"></xsl:call-template>
-                                </name>
-                                <xsl:call-template name="relatedForm"></xsl:call-template>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=811]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </titleInfo>
-                                <name type="conference">
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="role"/>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='830']">
-                        <relatedItem type="series">
-                                <xsl:variable name="titleChop">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:variable>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:value-of select="$titleChop" />
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <titleInfo type="nfi">
-                                        <xsl:choose>
-                                                <xsl:when test="@ind2>0">
-                                                        <nonSort>
-                                                                <xsl:value-of select="substring($titleChop,1,@ind2)"/>
-                                                        </nonSort>
-                                                        <title>
-                                                                <xsl:value-of select="substring($titleChop,@ind2+1)"/>
-                                                        </title>
-                                                </xsl:when>
-                                                <xsl:otherwise>
-                                                        <title>
-                                                                <xsl:value-of select="$titleChop" />
-                                                        </title>
-                                                </xsl:otherwise>
-                                        </xsl:choose>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
-                        <relatedItem>
-                                <internetMediaType>
-                                        <xsl:value-of select="."/>
-                                </internetMediaType>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='020']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">isbn</xsl:with-param>
-                        </xsl:call-template>
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <identifier type="isbn">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">isrc</xsl:with-param>
-                        </xsl:call-template>
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <identifier type="isrc">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">ismn</xsl:with-param>
-                        </xsl:call-template>
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <identifier type="ismn">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">sici</xsl:with-param>
-                        </xsl:call-template>
-                        <identifier type="sici">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='022']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">issn</xsl:with-param>
-                        </xsl:call-template>
-                        <identifier type="issn">
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='010']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">lccn</xsl:with-param>
-                        </xsl:call-template>
-                        <identifier type="lccn">
-                                <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='028']">
-                        <identifier>
-                                <xsl:attribute name="type">
-                                        <xsl:choose>
-                                                <xsl:when test="@ind1='0'">issue number</xsl:when>
-                                                <xsl:when test="@ind1='1'">matrix number</xsl:when>
-                                                <xsl:when test="@ind1='2'">music plate</xsl:when>
-                                                <xsl:when test="@ind1='3'">music publisher</xsl:when>
-                                                <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
-                                        </xsl:choose>
-                                </xsl:attribute>
-                                <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 028 -->
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">
-                                                <xsl:choose>
-                                                        <xsl:when test="@ind1='0'">ba</xsl:when>
-                                                        <xsl:otherwise>ab</xsl:otherwise>
-                                                </xsl:choose>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='037']">
-                        <identifier type="stock number">
-                                <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 037 -->
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
-                        <identifier>
-                                <xsl:attribute name="type">
-                                        <xsl:choose>
-                                                <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
-                                                <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
-                                                <xsl:otherwise>uri</xsl:otherwise>
-                                        </xsl:choose>
-                                </xsl:attribute>
-                                <xsl:choose>
-                                        <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
-                                                <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </identifier>
-                        <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
-                                <identifier type="hdl">
-                                        <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">y3z</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
-                        <identifier type="upc">
-                                <xsl:call-template name="isInvalid"/>
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </identifier>
-                </xsl:for-each>
-                <!-- 1/04 fix added $y -->
-                <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
-                        <location>
-                                <url>
-                                        <xsl:if test="marc:subfield[@code='y' or @code='3']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">y3</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:if test="marc:subfield[@code='z' ]">
-                                                <xsl:attribute name="note">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">z</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
-
-                                </url>
-                        </location>
-                </xsl:for-each>
-
-                        <!-- 3.2 change tmee 856z  -->
-
-
-                <xsl:for-each select="marc:datafield[@tag=852]">
-                        <location>
-                                <physicalLocation>
-                                        <xsl:call-template name="displayLabel"></xsl:call-template>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abje</xsl:with-param>
-                                        </xsl:call-template>
-                                </physicalLocation>
-                        </location>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=506]">
-                        <accessCondition type="restrictionOnAccess">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abcd35</xsl:with-param>
-                                </xsl:call-template>
-                        </accessCondition>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=540]">
-                        <accessCondition type="useAndReproduction">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abcde35</xsl:with-param>
-                                </xsl:call-template>
-                        </accessCondition>
-                </xsl:for-each>
-                <recordInfo>
-                        <xsl:for-each select="marc:datafield[@tag=040]">
-                                <recordContentSource authority="marcorg">
-                                        <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                                </recordContentSource>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=008]">
-                                <recordCreationDate encoding="marc">
-                                        <xsl:value-of select="substring(.,1,6)"></xsl:value-of>
-                                </recordCreationDate>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=005]">
-                                <recordChangeDate encoding="iso8601">
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </recordChangeDate>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=001]">
-                                <recordIdentifier>
-                                        <xsl:if test="../marc:controlfield[@tag=003]">
-                                                <xsl:attribute name="source">
-                                                        <xsl:value-of select="../marc:controlfield[@tag=003]"></xsl:value-of>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </recordIdentifier>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
-                                <languageOfCataloging>
-                                        <languageTerm authority="iso639-2b" type="code">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </languageTerm>
-                                </languageOfCataloging>
-                        </xsl:for-each>
-                </recordInfo>
-        </xsl:template>
-        <xsl:template name="displayForm">
-                <xsl:for-each select="marc:subfield[@code='c']">
-                        <displayForm>
-                                <xsl:value-of select="."></xsl:value-of>
-                        </displayForm>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="affiliation">
-                <xsl:for-each select="marc:subfield[@code='u']">
-                        <affiliation>
-                                <xsl:value-of select="."></xsl:value-of>
-                        </affiliation>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="uri">
-                <xsl:for-each select="marc:subfield[@code='u']">
-                        <xsl:attribute name="xlink:href">
-                                <xsl:value-of select="."></xsl:value-of>
-                        </xsl:attribute>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='0']">
-                        <xsl:choose>
-                                <xsl:when test="contains(text(), ')')">
-                                        <xsl:attribute name="xlink:href">
-                                                <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
-                                        </xsl:attribute>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:attribute name="xlink:href">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </xsl:attribute>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="role">
-                <xsl:for-each select="marc:subfield[@code='e']">
-                        <role>
-                                <roleTerm type="text">
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </roleTerm>
-                        </role>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='4']">
-                        <role>
-                                <roleTerm authority="marcrelator" type="code">
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </roleTerm>
-                        </role>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="part">
-                <xsl:variable name="partNumber">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">n</xsl:with-param>
-                                <xsl:with-param name="anyCodes">n</xsl:with-param>
-                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:variable name="partName">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">p</xsl:with-param>
-                                <xsl:with-param name="anyCodes">p</xsl:with-param>
-                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:if test="string-length(normalize-space($partNumber))">
-                        <partNumber>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="$partNumber"></xsl:with-param>
-                                </xsl:call-template>
-                        </partNumber>
-                </xsl:if>
-                <xsl:if test="string-length(normalize-space($partName))">
-                        <partName>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="$partName"></xsl:with-param>
-                                </xsl:call-template>
-                        </partName>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedPart">
-                <xsl:if test="@tag=773">
-                        <xsl:for-each select="marc:subfield[@code='g']">
-                                <part>
-                                        <text>
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </text>
-                                </part>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:subfield[@code='q']">
-                                <part>
-                                        <xsl:call-template name="parsePart"></xsl:call-template>
-                                </part>
-                        </xsl:for-each>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedPartNumName">
-                <xsl:variable name="partNumber">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">g</xsl:with-param>
-                                <xsl:with-param name="anyCodes">g</xsl:with-param>
-                                <xsl:with-param name="afterCodes">pst</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:variable name="partName">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">p</xsl:with-param>
-                                <xsl:with-param name="anyCodes">p</xsl:with-param>
-                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:if test="string-length(normalize-space($partNumber))">
-                        <partNumber>
-                                <xsl:value-of select="$partNumber"></xsl:value-of>
-                        </partNumber>
-                </xsl:if>
-                <xsl:if test="string-length(normalize-space($partName))">
-                        <partName>
-                                <xsl:value-of select="$partName"></xsl:value-of>
-                        </partName>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedName">
-                <xsl:for-each select="marc:subfield[@code='a']">
-                        <name>
-                                <namePart>
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </namePart>
-                        </name>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedForm">
-                <xsl:for-each select="marc:subfield[@code='h']">
-                        <physicalDescription>
-                                <form>
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </form>
-                        </physicalDescription>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedExtent">
-                <xsl:for-each select="marc:subfield[@code='h']">
-                        <physicalDescription>
-                                <extent>
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </extent>
-                        </physicalDescription>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedNote">
-                <xsl:for-each select="marc:subfield[@code='n']">
-                        <note>
-                                <xsl:value-of select="."></xsl:value-of>
-                        </note>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedSubject">
-                <xsl:for-each select="marc:subfield[@code='j']">
-                        <subject>
-                                <temporal encoding="iso8601">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                        </xsl:call-template>
-                                </temporal>
-                        </subject>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedIdentifierISSN">
-                <xsl:for-each select="marc:subfield[@code='x']">
-                        <identifier type="issn">
-                                <xsl:value-of select="."></xsl:value-of>
-                        </identifier>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedIdentifierLocal">
-                <xsl:for-each select="marc:subfield[@code='w']">
-                        <identifier type="local">
-                                <xsl:value-of select="."></xsl:value-of>
-                        </identifier>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedIdentifier">
-                <xsl:for-each select="marc:subfield[@code='o']">
-                        <identifier>
-                                <xsl:value-of select="."></xsl:value-of>
-                        </identifier>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedItem76X-78X">
-                <xsl:call-template name="displayLabel"></xsl:call-template>
-                <xsl:call-template name="relatedTitle76X-78X"></xsl:call-template>
-                <xsl:call-template name="relatedName"></xsl:call-template>
-                <xsl:call-template name="relatedOriginInfo"></xsl:call-template>
-                <xsl:call-template name="relatedLanguage"></xsl:call-template>
-                <xsl:call-template name="relatedExtent"></xsl:call-template>
-                <xsl:call-template name="relatedNote"></xsl:call-template>
-                <xsl:call-template name="relatedSubject"></xsl:call-template>
-                <xsl:call-template name="relatedIdentifier"></xsl:call-template>
-                <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
-                <xsl:call-template name="relatedIdentifierLocal"></xsl:call-template>
-                <xsl:call-template name="relatedPart"></xsl:call-template>
-        </xsl:template>
-        <xsl:template name="subjectGeographicZ">
-                <geographic>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                        </xsl:call-template>
-                </geographic>
-        </xsl:template>
-        <xsl:template name="subjectTemporalY">
-                <temporal>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                        </xsl:call-template>
-                </temporal>
-        </xsl:template>
-        <xsl:template name="subjectTopic">
-                <topic>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                        </xsl:call-template>
-                </topic>
-        </xsl:template>
-        <!-- 3.2 change tmee 6xx $v genre -->
-        <xsl:template name="subjectGenre">
-                <genre>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                        </xsl:call-template>
-                </genre>
-        </xsl:template>
-
-        <xsl:template name="nameABCDN">
-                <xsl:for-each select="marc:subfield[@code='a']">
-                        <namePart>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='b']">
-                        <namePart>
-                                <xsl:value-of select="."></xsl:value-of>
-                        </namePart>
-                </xsl:for-each>
-                <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
-                        <namePart>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">cdn</xsl:with-param>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="nameABCDQ">
-                <namePart>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString">
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">aq</xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:with-param>
-                                <xsl:with-param name="punctuation">
-                                        <xsl:text>:,;/ </xsl:text>
-                                </xsl:with-param>
-                        </xsl:call-template>
-                </namePart>
-                <xsl:call-template name="termsOfAddress"></xsl:call-template>
-                <xsl:call-template name="nameDate"></xsl:call-template>
-        </xsl:template>
-        <xsl:template name="nameACDEQ">
-                <namePart>
-                        <xsl:call-template name="subfieldSelect">
-                                <xsl:with-param name="codes">acdeq</xsl:with-param>
-                        </xsl:call-template>
-                </namePart>
-        </xsl:template>
-        <xsl:template name="constituentOrRelatedType">
-                <xsl:if test="@ind2=2">
-                        <xsl:attribute name="type">constituent</xsl:attribute>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedTitle">
-                <xsl:for-each select="marc:subfield[@code='t']">
-                        <titleInfo>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                        </titleInfo>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedTitle76X-78X">
-                <xsl:for-each select="marc:subfield[@code='t']">
-                        <titleInfo>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
-                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
-                                </xsl:if>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='p']">
-                        <titleInfo type="abbreviated">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
-                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
-                                </xsl:if>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='s']">
-                        <titleInfo type="uniform">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
-                                        <xsl:call-template name="relatedPartNumName"></xsl:call-template>
-                                </xsl:if>
-                        </titleInfo>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedOriginInfo">
-                <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
-                        <originInfo>
-                                <xsl:if test="@tag=775">
-                                        <xsl:for-each select="marc:subfield[@code='f']">
-                                                <place>
-                                                        <placeTerm>
-                                                                <xsl:attribute name="type">code</xsl:attribute>
-                                                                <xsl:attribute name="authority">marcgac</xsl:attribute>
-                                                                <xsl:value-of select="."></xsl:value-of>
-                                                        </placeTerm>
-                                                </place>
-                                        </xsl:for-each>
-                                </xsl:if>
-                                <xsl:for-each select="marc:subfield[@code='d']">
-                                        <publisher>
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </publisher>
-                                </xsl:for-each>
-                                <xsl:for-each select="marc:subfield[@code='b']">
-                                        <edition>
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </edition>
-                                </xsl:for-each>
-                        </originInfo>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedLanguage">
-                <xsl:for-each select="marc:subfield[@code='e']">
-                        <xsl:call-template name="getLanguage">
-                                <xsl:with-param name="langString">
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </xsl:with-param>
-                        </xsl:call-template>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="nameDate">
-                <xsl:for-each select="marc:subfield[@code='d']">
-                        <namePart type="date">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="subjectAuthority">
-                <xsl:if test="@ind2!=4">
-                        <xsl:if test="@ind2!=' '">
-                                <xsl:if test="@ind2!=8">
-                                        <xsl:if test="@ind2!=9">
-                                                <xsl:attribute name="authority">
-                                                        <xsl:choose>
-                                                                <xsl:when test="@ind2=0">lcsh</xsl:when>
-                                                                <xsl:when test="@ind2=1">lcshac</xsl:when>
-                                                                <xsl:when test="@ind2=2">mesh</xsl:when>
-                                                                <!-- 1/04 fix -->
-                                                                <xsl:when test="@ind2=3">nal</xsl:when>
-                                                                <xsl:when test="@ind2=5">csh</xsl:when>
-                                                                <xsl:when test="@ind2=6">rvm</xsl:when>
-                                                                <xsl:when test="@ind2=7">
-                                                                        <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
-                                                                </xsl:when>
-                                                        </xsl:choose>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                </xsl:if>
-                        </xsl:if>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="subjectAnyOrder">
-                <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
-                        <xsl:choose>
-                                <xsl:when test="@code='v'">
-                                        <xsl:call-template name="subjectGenre"></xsl:call-template>
-                                </xsl:when>
-                                <xsl:when test="@code='x'">
-                                        <xsl:call-template name="subjectTopic"></xsl:call-template>
-                                </xsl:when>
-                                <xsl:when test="@code='y'">
-                                        <xsl:call-template name="subjectTemporalY"></xsl:call-template>
-                                </xsl:when>
-                                <xsl:when test="@code='z'">
-                                        <xsl:call-template name="subjectGeographicZ"></xsl:call-template>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="specialSubfieldSelect">
-                <xsl:param name="anyCodes"></xsl:param>
-                <xsl:param name="axis"></xsl:param>
-                <xsl:param name="beforeCodes"></xsl:param>
-                <xsl:param name="afterCodes"></xsl:param>
-                <xsl:variable name="str">
-                        <xsl:for-each select="marc:subfield">
-                                <xsl:if test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
-                                        <xsl:value-of select="text()"></xsl:value-of>
-                                        <xsl:text> </xsl:text>
-                                </xsl:if>
-                        </xsl:for-each>
-                </xsl:variable>
-                <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
-        </xsl:template>
-
-        <!-- 3.2 change tmee 6xx $v genre -->
-        <xsl:template match="marc:datafield[@tag=600]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
-                        <name type="personal">
-                                <xsl:call-template name="uri" />
-                                <namePart>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">aq</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </namePart>
-                                <xsl:call-template name="termsOfAddress"></xsl:call-template>
-                                <xsl:call-template name="nameDate"></xsl:call-template>
-                                <xsl:call-template name="affiliation"></xsl:call-template>
-                                <xsl:call-template name="role"></xsl:call-template>
-                        </name>
-                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=610]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
-                        <name type="corporate">
-                                <xsl:call-template name="uri" />
-                                <xsl:for-each select="marc:subfield[@code='a']">
-                                        <namePart>
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </namePart>
-                                </xsl:for-each>
-                                <xsl:for-each select="marc:subfield[@code='b']">
-                                        <namePart>
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </namePart>
-                                </xsl:for-each>
-                                <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
-                                        <namePart>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">cdnp</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                </xsl:if>
-                                <xsl:call-template name="role"></xsl:call-template>
-                        </name>
-                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=611]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
-                        <name type="conference">
-                                <xsl:call-template name="uri" />
-                                <namePart>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
-                                        </xsl:call-template>
-                                </namePart>
-                                <xsl:for-each select="marc:subfield[@code='4']">
-                                        <role>
-                                                <roleTerm authority="marcrelator" type="code">
-                                                        <xsl:value-of select="."></xsl:value-of>
-                                                </roleTerm>
-                                        </role>
-                                </xsl:for-each>
-                        </name>
-                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=630]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
-                        <xsl:variable name="titleChop">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">adfhklor</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:variable>
-                        <titleInfo>
-                                <title>
-                                        <xsl:value-of select="$titleChop" />
-                                </title>
-                                <xsl:call-template name="part"></xsl:call-template>
-                        </titleInfo>
-                        <titleInfo type="nfi">
-                                <xsl:choose>
-                                        <xsl:when test="@ind1>0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleChop,1,@ind1)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleChop,@ind1+1)"/>
-                                                </title>
-                                                <xsl:call-template name="part"/>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleChop" />
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:call-template name="part"></xsl:call-template>
-                        </titleInfo>
-                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=650]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
-                        <topic>
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">abcd</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </topic>
-                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=651]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"></xsl:call-template>
-                        <xsl:for-each select="marc:subfield[@code='a']">
-                                <geographic>
-                                        <xsl:call-template name="uri" />
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString" select="."></xsl:with-param>
-                                        </xsl:call-template>
-                                </geographic>
-                        </xsl:for-each>
-                        <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=653]">
-                <subject>
-                        <xsl:for-each select="marc:subfield[@code='a']">
-                                <topic>
-                                        <xsl:call-template name="uri" />
-                                        <xsl:value-of select="."></xsl:value-of>
-                                </topic>
-                        </xsl:for-each>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=656]">
-                <subject>
-                        <xsl:if test="marc:subfield[@code=2]">
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code=2]"></xsl:value-of>
-                                </xsl:attribute>
-                        </xsl:if>
-                        <occupation>
-                                <xsl:call-template name="uri" />
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </occupation>
-                </subject>
-        </xsl:template>
-        <xsl:template name="termsOfAddress">
-                <xsl:if test="marc:subfield[@code='b' or @code='c']">
-                        <namePart type="termsOfAddress">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">bc</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="displayLabel">
-                <xsl:if test="marc:subfield[@code='i']">
-                        <xsl:attribute name="displayLabel">
-                                <xsl:value-of select="marc:subfield[@code='i']"></xsl:value-of>
-                        </xsl:attribute>
-                </xsl:if>
-                <xsl:if test="marc:subfield[@code='3']">
-                        <xsl:attribute name="displayLabel">
-                                <xsl:value-of select="marc:subfield[@code='3']"></xsl:value-of>
-                        </xsl:attribute>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="isInvalid">
-                <xsl:param name="type"/>
-                <xsl:if test="marc:subfield[@code='z'] or marc:subfield[@code='y']">
-                        <identifier>
-                                <xsl:attribute name="type">
-                                        <xsl:value-of select="$type"/>
-                                </xsl:attribute>
-                                <xsl:attribute name="invalid">
-                                        <xsl:text>yes</xsl:text>
-                                </xsl:attribute>
-                                <xsl:if test="marc:subfield[@code='z']">
-                                        <xsl:value-of select="marc:subfield[@code='z']"/>
-                                </xsl:if>
-                                <xsl:if test="marc:subfield[@code='y']">
-                                        <xsl:value-of select="marc:subfield[@code='y']"/>
-                                </xsl:if>
-                        </identifier>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="subtitle">
-                <xsl:if test="marc:subfield[@code='b']">
-                        <subTitle>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:value-of select="marc:subfield[@code='b']"/>
-                                                <!--<xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">b</xsl:with-param>
-                                                </xsl:call-template>-->
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </subTitle>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="script">
-                <xsl:param name="scriptCode"></xsl:param>
-                <xsl:attribute name="script">
-                        <xsl:choose>
-                                <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
-                                <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
-                                <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
-                                <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
-                                <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
-                                <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
-                        </xsl:choose>
-                </xsl:attribute>
-        </xsl:template>
-        <xsl:template name="parsePart">
-                <!-- assumes 773$q= 1:2:3<4
-                     with up to 3 levels and one optional start page
-                -->
-                <xsl:variable name="level1">
-                        <xsl:choose>
-                                <xsl:when test="contains(text(),':')">
-                                        <!-- 1:2 -->
-                                        <xsl:value-of select="substring-before(text(),':')"></xsl:value-of>
-                                </xsl:when>
-                                <xsl:when test="not(contains(text(),':'))">
-                                        <!-- 1 or 1<3 -->
-                                        <xsl:if test="contains(text(),'&lt;')">
-                                                <!-- 1<3 -->
-                                                <xsl:value-of select="substring-before(text(),'&lt;')"></xsl:value-of>
-                                        </xsl:if>
-                                        <xsl:if test="not(contains(text(),'&lt;'))">
-                                                <!-- 1 -->
-                                                <xsl:value-of select="text()"></xsl:value-of>
-                                        </xsl:if>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="sici2">
-                        <xsl:choose>
-                                <xsl:when test="starts-with(substring-after(text(),$level1),':')">
-                                        <xsl:value-of select="substring(substring-after(text(),$level1),2)"></xsl:value-of>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="substring-after(text(),$level1)"></xsl:value-of>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="level2">
-                        <xsl:choose>
-                                <xsl:when test="contains($sici2,':')">
-                                        <!--  2:3<4  -->
-                                        <xsl:value-of select="substring-before($sici2,':')"></xsl:value-of>
-                                </xsl:when>
-                                <xsl:when test="contains($sici2,'&lt;')">
-                                        <!-- 1: 2<4 -->
-                                        <xsl:value-of select="substring-before($sici2,'&lt;')"></xsl:value-of>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="$sici2"></xsl:value-of>
-                                        <!-- 1:2 -->
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="sici3">
-                        <xsl:choose>
-                                <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
-                                        <xsl:value-of select="substring(substring-after($sici2,$level2),2)"></xsl:value-of>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="substring-after($sici2,$level2)"></xsl:value-of>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="level3">
-                        <xsl:choose>
-                                <xsl:when test="contains($sici3,'&lt;')">
-                                        <!-- 2<4 -->
-                                        <xsl:value-of select="substring-before($sici3,'&lt;')"></xsl:value-of>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="$sici3"></xsl:value-of>
-                                        <!-- 3 -->
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="page">
-                        <xsl:if test="contains(text(),'&lt;')">
-                                <xsl:value-of select="substring-after(text(),'&lt;')"></xsl:value-of>
-                        </xsl:if>
-                </xsl:variable>
-                <xsl:if test="$level1">
-                        <detail level="1">
-                                <number>
-                                        <xsl:value-of select="$level1"></xsl:value-of>
-                                </number>
-                        </detail>
-                </xsl:if>
-                <xsl:if test="$level2">
-                        <detail level="2">
-                                <number>
-                                        <xsl:value-of select="$level2"></xsl:value-of>
-                                </number>
-                        </detail>
-                </xsl:if>
-                <xsl:if test="$level3">
-                        <detail level="3">
-                                <number>
-                                        <xsl:value-of select="$level3"></xsl:value-of>
-                                </number>
-                        </detail>
-                </xsl:if>
-                <xsl:if test="$page">
-                        <extent unit="page">
-                                <start>
-                                        <xsl:value-of select="$page"></xsl:value-of>
-                                </start>
-                        </extent>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="getLanguage">
-                <xsl:param name="langString"></xsl:param>
-                <xsl:param name="controlField008-35-37"></xsl:param>
-                <xsl:variable name="length" select="string-length($langString)"></xsl:variable>
-                <xsl:choose>
-                        <xsl:when test="$length=0"></xsl:when>
-                        <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
-                                <xsl:call-template name="getLanguage">
-                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
-                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:otherwise>
-                                <language>
-                                        <languageTerm authority="iso639-2b" type="code">
-                                                <xsl:value-of select="substring($langString,1,3)"></xsl:value-of>
-                                        </languageTerm>
-                                </language>
-                                <xsl:call-template name="getLanguage">
-                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
-                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="isoLanguage">
-                <xsl:param name="currentLanguage"></xsl:param>
-                <xsl:param name="usedLanguages"></xsl:param>
-                <xsl:param name="remainingLanguages"></xsl:param>
-                <xsl:choose>
-                        <xsl:when test="string-length($currentLanguage)=0"></xsl:when>
-                        <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
-                                <language>
-                                        <xsl:if test="@code!='a'">
-                                                <xsl:attribute name="objectPart">
-                                                        <xsl:choose>
-                                                                <xsl:when test="@code='b'">summary or subtitle</xsl:when>
-                                                                <xsl:when test="@code='d'">sung or spoken text</xsl:when>
-                                                                <xsl:when test="@code='e'">libretto</xsl:when>
-                                                                <xsl:when test="@code='f'">table of contents</xsl:when>
-                                                                <xsl:when test="@code='g'">accompanying material</xsl:when>
-                                                                <xsl:when test="@code='h'">translation</xsl:when>
-                                                        </xsl:choose>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <languageTerm authority="iso639-2b" type="code">
-                                                <xsl:value-of select="$currentLanguage"></xsl:value-of>
-                                        </languageTerm>
-                                </language>
-                                <xsl:call-template name="isoLanguage">
-                                        <xsl:with-param name="currentLanguage">
-                                                <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="usedLanguages">
-                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="remainingLanguages">
-                                                <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:otherwise>
-                                <xsl:call-template name="isoLanguage">
-                                        <xsl:with-param name="currentLanguage">
-                                                <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="usedLanguages">
-                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="remainingLanguages">
-                                                <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="chopBrackets">
-                <xsl:param name="chopString"></xsl:param>
-                <xsl:variable name="string">
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="$chopString"></xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:if test="substring($string, 1,1)='['">
-                        <xsl:value-of select="substring($string,2, string-length($string)-2)"></xsl:value-of>
-                </xsl:if>
-                <xsl:if test="substring($string, 1,1)!='['">
-                        <xsl:value-of select="$string"></xsl:value-of>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="rfcLanguages">
-                <xsl:param name="nodeNum"></xsl:param>
-                <xsl:param name="usedLanguages"></xsl:param>
-                <xsl:param name="controlField008-35-37"></xsl:param>
-                <xsl:variable name="currentLanguage" select="."></xsl:variable>
-                <xsl:choose>
-                        <xsl:when test="not($currentLanguage)"></xsl:when>
-                        <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
-                                <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
-                                        <language>
-                                                <xsl:if test="@code!='a'">
-                                                        <xsl:attribute name="objectPart">
-                                                                <xsl:choose>
-                                                                        <xsl:when test="@code='b'">summary or subtitle</xsl:when>
-                                                                        <xsl:when test="@code='d'">sung or spoken text</xsl:when>
-                                                                        <xsl:when test="@code='e'">libretto</xsl:when>
-                                                                        <xsl:when test="@code='f'">table of contents</xsl:when>
-                                                                        <xsl:when test="@code='g'">accompanying material</xsl:when>
-                                                                        <xsl:when test="@code='h'">translation</xsl:when>
-                                                                </xsl:choose>
-                                                        </xsl:attribute>
-                                                </xsl:if>
-                                                <languageTerm authority="rfc3066" type="code">
-                                                        <xsl:value-of select="$currentLanguage"/>
-                                                </languageTerm>
-                                        </language>
-                                </xsl:if>
-                        </xsl:when>
-                        <xsl:otherwise>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="datafield">
-                <xsl:param name="tag"/>
-                <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
-                <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
-                <xsl:param name="subfields"/>
-                <xsl:element name="marc:datafield">
-                        <xsl:attribute name="tag">
-                                <xsl:value-of select="$tag"/>
-                        </xsl:attribute>
-                        <xsl:attribute name="ind1">
-                                <xsl:value-of select="$ind1"/>
-                        </xsl:attribute>
-                        <xsl:attribute name="ind2">
-                                <xsl:value-of select="$ind2"/>
-                        </xsl:attribute>
-                        <xsl:copy-of select="$subfields"/>
-                </xsl:element>
-        </xsl:template>
-
-        <xsl:template name="subfieldSelect">
-                <xsl:param name="codes"/>
-                <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
-                <xsl:variable name="str">
-                        <xsl:for-each select="marc:subfield">
-                                <xsl:if test="contains($codes, @code)">
-                                        <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
-                                </xsl:if>
-                        </xsl:for-each>
-                </xsl:variable>
-                <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
-        </xsl:template>
-
-        <xsl:template name="buildSpaces">
-                <xsl:param name="spaces"/>
-                <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
-                <xsl:if test="$spaces>0">
-                        <xsl:value-of select="$char"/>
-                        <xsl:call-template name="buildSpaces">
-                                <xsl:with-param name="spaces" select="$spaces - 1"/>
-                                <xsl:with-param name="char" select="$char"/>
-                        </xsl:call-template>
-                </xsl:if>
-        </xsl:template>
-
-        <xsl:template name="chopPunctuation">
-                <xsl:param name="chopString"/>
-                <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
-                <xsl:variable name="length" select="string-length($chopString)"/>
-                <xsl:choose>
-                        <xsl:when test="$length=0"/>
-                        <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
-                                        <xsl:with-param name="punctuation" select="$punctuation"/>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:when test="not($chopString)"/>
-                        <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-
-        <xsl:template name="chopPunctuationFront">
-                <xsl:param name="chopString"/>
-                <xsl:variable name="length" select="string-length($chopString)"/>
-                <xsl:choose>
-                        <xsl:when test="$length=0"/>
-                        <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
-                                <xsl:call-template name="chopPunctuationFront">
-                                        <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:when test="not($chopString)"/>
-                        <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-</xsl:stylesheet>$XXXX$ where name = $$mods32$$;
-
-update config.xml_transform set xslt = $XXXX$<xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim"
-        xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-        exclude-result-prefixes="xlink marc" version="1.0">
-        <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
-
-        <xsl:variable name="ascii">
-                <xsl:text> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
-        </xsl:variable>
-
-        <xsl:variable name="latin1">
-                <xsl:text> ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
-        </xsl:variable>
-        <!-- Characters that usually don't need to be escaped -->
-        <xsl:variable name="safe">
-                <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
-        </xsl:variable>
-
-        <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
-
-    <!-- Evergreen specific: revert Revision 1.23, so we can have those authority xlink attributes back. -->
-
-        <!--MARC21slim2MODS3-3.xsl
-Revision 1.27 - Mapped 648 to <subject> 2009/03/13 tmee
-Revision 1.26 - Added subfield $s mapping for 130/240/730  2008/10/16 tmee
-Revision 1.25 - Mapped 040e to <descriptiveStandard> and Leader/18 to <descriptive standard>aacr2  2008/09/18 tmee
-Revision 1.24 - Mapped 852 subfields $h, $i, $j, $k, $l, $m, $t to <shelfLocation> and 852 subfield $u to <physicalLocation> with @xlink 2008/09/17 tmee
-Revision 1.23 - Commented out xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711 as these are currently unactionable  2008/09/17  tmee
-Revision 1.22 - Mapped 022 subfield $l to type "issn-l" subfield $m to output identifier element with corresponding @type and @invalid eq 'yes'2008/09/17  tmee
-Revision 1.21 - Mapped 856 ind2=1 or ind2=2 to <relatedItem><location><url>  2008/07/03  tmee
-Revision 1.20 - Added genre w/@auth="contents of 2" and type= "musical composition"  2008/07/01  tmee
-Revision 1.19 - Added genre offprint for 008/24+ BK code 2  2008/07/01  tmee
-Revision 1.18 - Added xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711  2008/06/26  tmee
-Revision 1.17 - Added mapping of 662 2008/05/14 tmee
-Revision 1.16 - Changed @authority from "marc" to "marcgt" for 007 and 008 codes mapped to a term in <genre> 2007/07/10  tmee
-Revision 1.15 - For field 630, moved call to part template outside title element  2007/07/10  tmee
-Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
-Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28  tmee
-Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11  tmee
-Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>  2006/04/08  jrad
-Revision 1.10 - MODS 3.1 revisions to language and classification elements  (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)  2006/02/06  ggar
-Revision 1.9 - Subfield $y was added to field 242 2004/09/02 10:57 jrad
-Revision 1.8 - Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
-Revision 1.7 - 2004/03/25 08:29 jrad
-Revision 1.6 - Various validation fixes 2004/02/20 ntra
-Revision 1.5 - MODS2 to MODS3 updates, language unstacking and de-duping, chopPunctuation expanded  2003/10/02 16:18:58  ntra
-Revision 1.3 - Additional Changes not related to MODS Version 2.0 by ntra
-Revision 1.2 - Added Log Comment  2003/03/24 19:37:42  ckeith
--->
-        <xsl:template match="/">
-                <xsl:choose>
-                        <xsl:when test="//marc:collection">
-                                <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-                                        xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
-                                        <xsl:for-each select="//marc:collection/marc:record">
-                                                <mods version="3.3">
-                                                        <xsl:call-template name="marcRecord"/>
-                                                </mods>
-                                        </xsl:for-each>
-                                </modsCollection>
-                        </xsl:when>
-                        <xsl:otherwise>
-                                <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
-                                        xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
-                                        <xsl:for-each select="//marc:record">
-                                                <xsl:call-template name="marcRecord"/>
-                                        </xsl:for-each>
-                                </mods>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="marcRecord">
-                <xsl:variable name="leader" select="marc:leader"/>
-                <xsl:variable name="leader6" select="substring($leader,7,1)"/>
-                <xsl:variable name="leader7" select="substring($leader,8,1)"/>
-                <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
-                <xsl:variable name="typeOf008">
-                        <xsl:choose>
-                                <xsl:when test="$leader6='a'">
-                                        <xsl:choose>
-                                                <xsl:when
-                                                        test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
-                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
-                                        </xsl:choose>
-                                </xsl:when>
-                                <xsl:when test="$leader6='t'">BK</xsl:when>
-                                <xsl:when test="$leader6='p'">MM</xsl:when>
-                                <xsl:when test="$leader6='m'">CF</xsl:when>
-                                <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
-                                <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
-                                <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'"
-                                >MU</xsl:when>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:for-each select="marc:datafield[@tag='245']">
-                        <titleInfo>
-                                <xsl:variable name="title">
-                                        <xsl:choose>
-                                                <xsl:when test="marc:subfield[@code='b']">
-                                                        <xsl:call-template name="specialSubfieldSelect">
-                                                                <xsl:with-param name="axis">b</xsl:with-param>
-                                                                <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:when>
-                                                <xsl:otherwise>
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">abfgk</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:otherwise>
-                                        </xsl:choose>
-                                </xsl:variable>
-                                <xsl:variable name="titleChop">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="$title"/>
-                                                </xsl:with-param>
-                                                <xsl:with-param name="punctuation">
-                                                    <xsl:text>,;/ </xsl:text>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:variable>
-                                <xsl:choose>
-                                        <xsl:when test="@ind2&gt;0">
-                                                <nonSort>
-                                                        <xsl:value-of select="substring($titleChop,1,@ind2)"/>
-                                                </nonSort>
-                                                <title>
-                                                        <xsl:value-of select="substring($titleChop,@ind2+1)"/>
-                                                </title>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <title>
-                                                        <xsl:value-of select="$titleChop"/>
-                                                </title>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                                <xsl:if test="marc:subfield[@code='b']">
-                                        <subTitle>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="axis">b</xsl:with-param>
-                                                                        <xsl:with-param name="anyCodes">b</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">afgk</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </subTitle>
-                                </xsl:if>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='210']">
-                        <titleInfo type="abbreviated">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">a</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="subtitle"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='242']">
-                        <titleInfo type="translated">
-                                <!--09/01/04 Added subfield $y-->
-                                <xsl:for-each select="marc:subfield[@code='y']">
-                                        <xsl:attribute name="lang">
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:attribute>
-                                </xsl:for-each>
-                                <xsl:for-each select="marc:subfield[@code='i']">
-                                        <xsl:attribute name="displayLabel">
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:attribute>
-                                </xsl:for-each>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <!-- 1/04 removed $h, b -->
-                                                                <xsl:with-param name="codes">a</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <!-- 1/04 fix -->
-                                <xsl:call-template name="subtitle"/>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='246']">
-                        <titleInfo type="alternative">
-                                <xsl:for-each select="marc:subfield[@code='i']">
-                                        <xsl:attribute name="displayLabel">
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:attribute>
-                                </xsl:for-each>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <!-- 1/04 removed $h, $b -->
-                                                                <xsl:with-param name="codes">af</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="subtitle"/>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each
-                        select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
-                        <titleInfo type="uniform">
-                                <title>
-                                                <xsl:call-template name="uri"/>
-
-                                        <xsl:variable name="str">
-                                                <xsl:for-each select="marc:subfield">
-                                                        <xsl:if
-                                                                test="(contains('adfklmors',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
-                                                                <xsl:value-of select="text()"/>
-                                                                <xsl:text> </xsl:text>
-                                                        </xsl:if>
-                                                </xsl:for-each>
-                                        </xsl:variable>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
-                        <titleInfo type="alternative">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">ah</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='100']">
-                        <name type="personal">
-
-                                <xsl:call-template name="uri"/>
-
-                                <xsl:call-template name="nameABCDQ"/>
-                                <xsl:call-template name="affiliation"/>
-                                <role>
-                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
-                                </role>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='110']">
-                        <name type="corporate">
-
-                                        <xsl:call-template name="uri"/>
-
-                                <xsl:call-template name="nameABCDN"/>
-                                <role>
-                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
-                                </role>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='111']">
-                        <name type="conference">
-
-                                        <xsl:call-template name="uri"/>
-
-                                <xsl:call-template name="nameACDEQ"/>
-                                <role>
-                                        <roleTerm authority="marcrelator" type="text">creator</roleTerm>
-                                </role>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
-                        <name type="personal">
-
-                                        <xsl:call-template name="uri"/>
-
-                                <xsl:call-template name="nameABCDQ"/>
-                                <xsl:call-template name="affiliation"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
-                        <name type="corporate">
-
-                                        <xsl:call-template name="uri"/>
-
-                                <xsl:call-template name="nameABCDN"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
-                        <name type="conference">
-
-                                        <xsl:call-template name="uri"/>
-
-                                <xsl:call-template name="nameACDEQ"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
-                        <name>
-                                <xsl:if test="@ind1=1">
-                                        <xsl:attribute name="type">
-                                                <xsl:text>personal</xsl:text>
-                                        </xsl:attribute>
-                                </xsl:if>
-                                <namePart>
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </namePart>
-                                <xsl:call-template name="role"/>
-                        </name>
-                </xsl:for-each>
-                <typeOfResource>
-                        <xsl:if test="$leader7='c'">
-                                <xsl:attribute name="collection">yes</xsl:attribute>
-                        </xsl:if>
-                        <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
-                                <xsl:attribute name="manuscript">yes</xsl:attribute>
-                        </xsl:if>
-                        <xsl:choose>
-                                <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
-                                <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
-                                <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
-                                <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
-                                <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
-                                <xsl:when test="$leader6='k'">still image</xsl:when>
-                                <xsl:when test="$leader6='g'">moving image</xsl:when>
-                                <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
-                                <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
-                                <xsl:when test="$leader6='p'">mixed material</xsl:when>
-                        </xsl:choose>
-                </typeOfResource>
-                <xsl:if test="substring($controlField008,26,1)='d'">
-                        <genre authority="marcgt">globe</genre>
-                </xsl:if>
-                <xsl:if
-                        test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
-                        <genre authority="marcgt">remote-sensing image</genre>
-                </xsl:if>
-                <xsl:if test="$typeOf008='MP'">
-                        <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"/>
-                        <xsl:choose>
-                                <xsl:when
-                                        test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
-                                        <genre authority="marcgt">map</genre>
-                                </xsl:when>
-                                <xsl:when
-                                        test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
-                                        <genre authority="marcgt">atlas</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='SE'">
-                        <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"/>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-21='d'">
-                                        <genre authority="marcgt">database</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='l'">
-                                        <genre authority="marcgt">loose-leaf</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='m'">
-                                        <genre authority="marcgt">series</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='n'">
-                                        <genre authority="marcgt">newspaper</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='p'">
-                                        <genre authority="marcgt">periodical</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-21='w'">
-                                        <genre authority="marcgt">web site</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
-                        <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"/>
-                        <xsl:choose>
-                                <xsl:when test="contains($controlField008-24,'a')">
-                                        <genre authority="marcgt">abstract or summary</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'b')">
-                                        <genre authority="marcgt">bibliography</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'c')">
-                                        <genre authority="marcgt">catalog</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'d')">
-                                        <genre authority="marcgt">dictionary</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'e')">
-                                        <genre authority="marcgt">encyclopedia</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'f')">
-                                        <genre authority="marcgt">handbook</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'g')">
-                                        <genre authority="marcgt">legal article</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'i')">
-                                        <genre authority="marcgt">index</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'k')">
-                                        <genre authority="marcgt">discography</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'l')">
-                                        <genre authority="marcgt">legislation</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'m')">
-                                        <genre authority="marcgt">theses</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'n')">
-                                        <genre authority="marcgt">survey of literature</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'o')">
-                                        <genre authority="marcgt">review</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'p')">
-                                        <genre authority="marcgt">programmed text</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'q')">
-                                        <genre authority="marcgt">filmography</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'r')">
-                                        <genre authority="marcgt">directory</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'s')">
-                                        <genre authority="marcgt">statistics</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'t')">
-                                        <genre authority="marcgt">technical report</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'v')">
-                                        <genre authority="marcgt">legal case and case notes</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'w')">
-                                        <genre authority="marcgt">law report or digest</genre>
-                                </xsl:when>
-                                <xsl:when test="contains($controlField008-24,'z')">
-                                        <genre authority="marcgt">treaty</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-29='1'">
-                                        <genre authority="marcgt">conference publication</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='CF'">
-                        <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"/>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-26='a'">
-                                        <genre authority="marcgt">numeric data</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-26='e'">
-                                        <genre authority="marcgt">database</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-26='f'">
-                                        <genre authority="marcgt">font</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-26='g'">
-                                        <genre authority="marcgt">game</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='BK'">
-                        <xsl:if test="substring($controlField008,25,1)='j'">
-                                <genre authority="marcgt">patent</genre>
-                        </xsl:if>
-                        <xsl:if test="substring($controlField008,25,1)='2'">
-                                <genre authority="marcgt">offprint</genre>
-                        </xsl:if>
-                        <xsl:if test="substring($controlField008,31,1)='1'">
-                                <genre authority="marcgt">festschrift</genre>
-                        </xsl:if>
-                        <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"/>
-                        <xsl:if
-                                test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
-                                <genre authority="marcgt">biography</genre>
-                        </xsl:if>
-                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-33='e'">
-                                        <genre authority="marcgt">essay</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='d'">
-                                        <genre authority="marcgt">drama</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='c'">
-                                        <genre authority="marcgt">comic strip</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='l'">
-                                        <genre authority="marcgt">fiction</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='h'">
-                                        <genre authority="marcgt">humor, satire</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='i'">
-                                        <genre authority="marcgt">letter</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='f'">
-                                        <genre authority="marcgt">novel</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='j'">
-                                        <genre authority="marcgt">short story</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='s'">
-                                        <genre authority="marcgt">speech</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:if test="$typeOf008='MU'">
-                        <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>
-                        <xsl:if test="contains($controlField008-30-31,'b')">
-                                <genre authority="marcgt">biography</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'c')">
-                                <genre authority="marcgt">conference publication</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'d')">
-                                <genre authority="marcgt">drama</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'e')">
-                                <genre authority="marcgt">essay</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'f')">
-                                <genre authority="marcgt">fiction</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'o')">
-                                <genre authority="marcgt">folktale</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'h')">
-                                <genre authority="marcgt">history</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'k')">
-                                <genre authority="marcgt">humor, satire</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'m')">
-                                <genre authority="marcgt">memoir</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'p')">
-                                <genre authority="marcgt">poetry</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'r')">
-                                <genre authority="marcgt">rehearsal</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'g')">
-                                <genre authority="marcgt">reporting</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'s')">
-                                <genre authority="marcgt">sound</genre>
-                        </xsl:if>
-                        <xsl:if test="contains($controlField008-30-31,'l')">
-                                <genre authority="marcgt">speech</genre>
-                        </xsl:if>
-                </xsl:if>
-                <xsl:if test="$typeOf008='VM'">
-                        <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
-                        <xsl:choose>
-                                <xsl:when test="$controlField008-33='a'">
-                                        <genre authority="marcgt">art original</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='b'">
-                                        <genre authority="marcgt">kit</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='c'">
-                                        <genre authority="marcgt">art reproduction</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='d'">
-                                        <genre authority="marcgt">diorama</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='f'">
-                                        <genre authority="marcgt">filmstrip</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='g'">
-                                        <genre authority="marcgt">legal article</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='i'">
-                                        <genre authority="marcgt">picture</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='k'">
-                                        <genre authority="marcgt">graphic</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='l'">
-                                        <genre authority="marcgt">technical drawing</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='m'">
-                                        <genre authority="marcgt">motion picture</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='n'">
-                                        <genre authority="marcgt">chart</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='o'">
-                                        <genre authority="marcgt">flash card</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='p'">
-                                        <genre authority="marcgt">microscope slide</genre>
-                                </xsl:when>
-                                <xsl:when
-                                        test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
-                                        <genre authority="marcgt">model</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='r'">
-                                        <genre authority="marcgt">realia</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='s'">
-                                        <genre authority="marcgt">slide</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='t'">
-                                        <genre authority="marcgt">transparency</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='v'">
-                                        <genre authority="marcgt">videorecording</genre>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-33='w'">
-                                        <genre authority="marcgt">toy</genre>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-
-                <!-- 1.20 047 genre tmee-->
-
-                <xsl:for-each select="marc:datafield[@tag=047]">
-                        <genre authority="marcgt">
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"/>
-                                </xsl:attribute>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abcdef</xsl:with-param>
-                                        <xsl:with-param name="delimeter">-</xsl:with-param>
-                                </xsl:call-template>
-                        </genre>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=655]">
-                        <genre authority="marcgt">
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"/>
-                                </xsl:attribute>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abvxyz</xsl:with-param>
-                                        <xsl:with-param name="delimeter">-</xsl:with-param>
-                                </xsl:call-template>
-                        </genre>
-                </xsl:for-each>
-                <originInfo>
-                        <xsl:variable name="MARCpublicationCode"
-                                select="normalize-space(substring($controlField008,16,3))"/>
-                        <xsl:if test="translate($MARCpublicationCode,'|','')">
-                                <place>
-                                        <placeTerm>
-                                                <xsl:attribute name="type">code</xsl:attribute>
-                                                <xsl:attribute name="authority">marccountry</xsl:attribute>
-                                                <xsl:value-of select="$MARCpublicationCode"/>
-                                        </placeTerm>
-                                </place>
-                        </xsl:if>
-                        <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
-                                <place>
-                                        <placeTerm>
-                                                <xsl:attribute name="type">code</xsl:attribute>
-                                                <xsl:attribute name="authority">iso3166</xsl:attribute>
-                                                <xsl:value-of select="."/>
-                                        </placeTerm>
-                                </place>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
-                                <place>
-                                        <placeTerm>
-                                                <xsl:attribute name="type">text</xsl:attribute>
-                                                <xsl:call-template name="chopPunctuationFront">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="chopPunctuation">
-                                                                        <xsl:with-param name="chopString" select="."/>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </placeTerm>
-                                </place>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
-                                <dateValid point="start">
-                                        <xsl:value-of select="."/>
-                                </dateValid>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
-                                <dateValid point="end">
-                                        <xsl:value-of select="."/>
-                                </dateValid>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
-                                <dateModified>
-                                        <xsl:value-of select="."/>
-                                </dateModified>
-                        </xsl:for-each>
-                        <xsl:for-each
-                                select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
-                                <xsl:choose>
-                                        <xsl:when test="@code='b'">
-                                                <publisher>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                                <xsl:with-param name="punctuation">
-                                                                        <xsl:text>:,;/ </xsl:text>
-                                                                </xsl:with-param>
-                                                        </xsl:call-template>
-                                                </publisher>
-                                        </xsl:when>
-                                        <xsl:when test="@code='c'">
-                                                <dateIssued>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </dateIssued>
-                                        </xsl:when>
-                                        <xsl:when test="@code='g'">
-                                                <dateCreated>
-                                                        <xsl:value-of select="."/>
-                                                </dateCreated>
-                                        </xsl:when>
-                                </xsl:choose>
-                        </xsl:for-each>
-                        <xsl:variable name="dataField260c">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString"
-                                                select="marc:datafield[@tag=260]/marc:subfield[@code='c']"/>
-                                </xsl:call-template>
-                        </xsl:variable>
-                        <xsl:variable name="controlField008-7-10"
-                                select="normalize-space(substring($controlField008, 8, 4))"/>
-                        <xsl:variable name="controlField008-11-14"
-                                select="normalize-space(substring($controlField008, 12, 4))"/>
-                        <xsl:variable name="controlField008-6"
-                                select="normalize-space(substring($controlField008, 7, 1))"/>
-                        <xsl:if
-                                test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
-                                <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
-                                        <dateIssued encoding="marc">
-                                                <xsl:value-of select="$controlField008-7-10"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if
-                                test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
-                                <xsl:if test="$controlField008-7-10">
-                                        <dateIssued encoding="marc" point="start">
-                                                <xsl:value-of select="$controlField008-7-10"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if
-                                test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
-                                <xsl:if test="$controlField008-11-14">
-                                        <dateIssued encoding="marc" point="end">
-                                                <xsl:value-of select="$controlField008-11-14"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='q'">
-                                <xsl:if test="$controlField008-7-10">
-                                        <dateIssued encoding="marc" point="start" qualifier="questionable">
-                                                <xsl:value-of select="$controlField008-7-10"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='q'">
-                                <xsl:if test="$controlField008-11-14">
-                                        <dateIssued encoding="marc" point="end" qualifier="questionable">
-                                                <xsl:value-of select="$controlField008-11-14"/>
-                                        </dateIssued>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:if test="$controlField008-6='t'">
-                                <xsl:if test="$controlField008-11-14">
-                                        <copyrightDate encoding="marc">
-                                                <xsl:value-of select="$controlField008-11-14"/>
-                                        </copyrightDate>
-                                </xsl:if>
-                        </xsl:if>
-                        <xsl:for-each
-                                select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
-                                <dateCaptured encoding="iso8601">
-                                        <xsl:value-of select="."/>
-                                </dateCaptured>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
-                                <dateCaptured encoding="iso8601" point="start">
-                                        <xsl:value-of select="."/>
-                                </dateCaptured>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
-                                <dateCaptured encoding="iso8601" point="end">
-                                        <xsl:value-of select="."/>
-                                </dateCaptured>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
-                                <edition>
-                                        <xsl:value-of select="."/>
-                                </edition>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:leader">
-                                <issuance>
-                                        <xsl:choose>
-                                                <xsl:when
-                                                        test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'"
-                                                        >monographic</xsl:when>
-                                                <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'"
-                                                >continuing</xsl:when>
-                                        </xsl:choose>
-                                </issuance>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
-                                <frequency>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">ab</xsl:with-param>
-                                        </xsl:call-template>
-                                </frequency>
-                        </xsl:for-each>
-                </originInfo>
-                <xsl:variable name="controlField008-35-37"
-                        select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"/>
-                <xsl:if test="$controlField008-35-37">
-                        <language>
-                                <languageTerm authority="iso639-2b" type="code">
-                                        <xsl:value-of select="substring($controlField008,36,3)"/>
-                                </languageTerm>
-                        </language>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=041]">
-                        <xsl:for-each
-                                select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
-                                <xsl:variable name="langCodes" select="."/>
-                                <xsl:choose>
-                                        <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
-                                                <!-- not stacked but could be repeated -->
-                                                <xsl:call-template name="rfcLanguages">
-                                                        <xsl:with-param name="nodeNum">
-                                                                <xsl:value-of select="1"/>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="usedLanguages">
-                                                                <xsl:text/>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="controlField008-35-37">
-                                                                <xsl:value-of select="$controlField008-35-37"/>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <!-- iso -->
-                                                <xsl:variable name="allLanguages">
-                                                        <xsl:copy-of select="$langCodes"/>
-                                                </xsl:variable>
-                                                <xsl:variable name="currentLanguage">
-                                                        <xsl:value-of select="substring($allLanguages,1,3)"/>
-                                                </xsl:variable>
-                                                <xsl:call-template name="isoLanguage">
-                                                        <xsl:with-param name="currentLanguage">
-                                                                <xsl:value-of select="substring($allLanguages,1,3)"/>
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="remainingLanguages">
-                                                                <xsl:value-of
-                                                                        select="substring($allLanguages,4,string-length($allLanguages)-3)"
-                                                                />
-                                                        </xsl:with-param>
-                                                        <xsl:with-param name="usedLanguages">
-                                                                <xsl:if test="$controlField008-35-37">
-                                                                        <xsl:value-of select="$controlField008-35-37"/>
-                                                                </xsl:if>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </xsl:for-each>
-                </xsl:for-each>
-                <xsl:variable name="physicalDescription">
-                        <!--3.2 change tmee 007/11 -->
-                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
-                                <digitalOrigin>reformatted digital</digitalOrigin>
-                        </xsl:if>
-                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
-                                <digitalOrigin>digitized microfilm</digitalOrigin>
-                        </xsl:if>
-                        <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
-                                <digitalOrigin>digitized other analog</digitalOrigin>
-                        </xsl:if>
-                        <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"/>
-                        <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
-                        <xsl:variable name="check008-23">
-                                <xsl:if
-                                        test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
-                                        <xsl:value-of select="true()"/>
-                                </xsl:if>
-                        </xsl:variable>
-                        <xsl:variable name="check008-29">
-                                <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
-                                        <xsl:value-of select="true()"/>
-                                </xsl:if>
-                        </xsl:variable>
-                        <xsl:choose>
-                                <xsl:when
-                                        test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
-                                        <form authority="marcform">braille</form>
-                                </xsl:when>
-                                <xsl:when
-                                        test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
-                                        <form authority="marcform">print</form>
-                                </xsl:when>
-                                <xsl:when
-                                        test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
-                                        <form authority="marcform">electronic</form>
-                                </xsl:when>
-                                <xsl:when
-                                        test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
-                                        <form authority="marcform">microfiche</form>
-                                </xsl:when>
-                                <xsl:when
-                                        test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
-                                        <form authority="marcform">microfilm</form>
-                                </xsl:when>
-                        </xsl:choose>
-                        <!-- 1/04 fix -->
-                        <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"
-                                                        />
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"
-                                                        />
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"
-                                                        />
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"
-                                                        />
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"
-                                                        />
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
-                                <form authority="gmd">
-                                        <xsl:call-template name="chopBrackets">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"
-                                                        />
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </form>
-                        </xsl:if>
-                        <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
-                                <form>
-                                        <xsl:value-of select="."/>
-                                </form>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
-                                <xsl:choose>
-                                        <xsl:when test="substring(text(),14,1)='a'">
-                                                <reformattingQuality>access</reformattingQuality>
-                                        </xsl:when>
-                                        <xsl:when test="substring(text(),14,1)='p'">
-                                                <reformattingQuality>preservation</reformattingQuality>
-                                        </xsl:when>
-                                        <xsl:when test="substring(text(),14,1)='r'">
-                                                <reformattingQuality>replacement</reformattingQuality>
-                                        </xsl:when>
-                                </xsl:choose>
-                        </xsl:for-each>
-                        <!--3.2 change tmee 007/01 -->
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
-                                <form authority="smd">chip cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
-                                <form authority="smd">computer optical disc cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
-                                <form authority="smd">magnetic disc</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
-                                <form authority="smd">magneto-optical disc</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
-                                <form authority="smd">optical disc</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
-                                <form authority="smd">remote</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
-                                <form authority="smd">tape cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
-                                <form authority="smd">tape cassette</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
-                                <form authority="smd">tape reel</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
-                                <form authority="smd">celestial globe</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
-                                <form authority="smd">earth moon globe</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
-                                <form authority="smd">planetary or lunar globe</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
-                                <form authority="smd">terrestrial globe</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
-                                <form authority="smd">kit</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
-                                <form authority="smd">atlas</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
-                                <form authority="smd">diagram</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
-                                <form authority="smd">map</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
-                                <form authority="smd">model</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
-                                <form authority="smd">profile</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
-                                <form authority="smd">remote-sensing image</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
-                                <form authority="smd">section</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
-                                <form authority="smd">view</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
-                                <form authority="smd">aperture card</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
-                                <form authority="smd">microfiche</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
-                                <form authority="smd">microfiche cassette</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
-                                <form authority="smd">microfilm cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
-                                <form authority="smd">microfilm cassette</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
-                                <form authority="smd">microfilm reel</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
-                                <form authority="smd">microopaque</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
-                                <form authority="smd">film cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
-                                <form authority="smd">film cassette</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
-                                <form authority="smd">film reel</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
-                                <form authority="smd">chart</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
-                                <form authority="smd">collage</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
-                                <form authority="smd">drawing</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
-                                <form authority="smd">flash card</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
-                                <form authority="smd">painting</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
-                                <form authority="smd">photomechanical print</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
-                                <form authority="smd">photonegative</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
-                                <form authority="smd">photoprint</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
-                                <form authority="smd">picture</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
-                                <form authority="smd">print</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
-                                <form authority="smd">technical drawing</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
-                                <form authority="smd">notated music</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
-                                <form authority="smd">filmslip</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
-                                <form authority="smd">filmstrip cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
-                                <form authority="smd">filmstrip roll</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
-                                <form authority="smd">other filmstrip type</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
-                                <form authority="smd">slide</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
-                                <form authority="smd">transparency</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
-                                <form authority="smd">remote-sensing image</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
-                                <form authority="smd">cylinder</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
-                                <form authority="smd">roll</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
-                                <form authority="smd">sound cartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
-                                <form authority="smd">sound cassette</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
-                                <form authority="smd">sound disc</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
-                                <form authority="smd">sound-tape reel</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
-                                <form authority="smd">sound-track film</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
-                                <form authority="smd">wire recording</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
-                                <form authority="smd">braille</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
-                                <form authority="smd">combination</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
-                                <form authority="smd">moon</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
-                                <form authority="smd">tactile, with no writing system</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
-                                <form authority="smd">braille</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
-                                <form authority="smd">large print</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
-                                <form authority="smd">regular print</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
-                                <form authority="smd">text in looseleaf binder</form>
-                        </xsl:if>
-
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
-                                <form authority="smd">videocartridge</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
-                                <form authority="smd">videocassette</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
-                                <form authority="smd">videodisc</form>
-                        </xsl:if>
-                        <xsl:if
-                                test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
-                                <form authority="smd">videoreel</form>
-                        </xsl:if>
-
-                        <xsl:for-each
-                                select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)&gt;1]">
-                                <internetMediaType>
-                                        <xsl:value-of select="."/>
-                                </internetMediaType>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=300]">
-                                <extent>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abce</xsl:with-param>
-                                        </xsl:call-template>
-                                </extent>
-                        </xsl:for-each>
-                </xsl:variable>
-                <xsl:if test="string-length(normalize-space($physicalDescription))">
-                        <physicalDescription>
-                                <xsl:copy-of select="$physicalDescription"/>
-                        </physicalDescription>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=520]">
-                        <abstract>
-                                <xsl:call-template name="uri"/>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </abstract>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=505]">
-                        <tableOfContents>
-                                <xsl:call-template name="uri"/>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">agrt</xsl:with-param>
-                                </xsl:call-template>
-                        </tableOfContents>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=521]">
-                        <targetAudience>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </targetAudience>
-                </xsl:for-each>
-                <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
-                        <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"/>
-                        <xsl:choose>
-                                <!-- 01/04 fix -->
-                                <xsl:when test="$controlField008-22='d'">
-                                        <targetAudience authority="marctarget">adolescent</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='e'">
-                                        <targetAudience authority="marctarget">adult</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='g'">
-                                        <targetAudience authority="marctarget">general</targetAudience>
-                                </xsl:when>
-                                <xsl:when
-                                        test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
-                                        <targetAudience authority="marctarget">juvenile</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='a'">
-                                        <targetAudience authority="marctarget">preschool</targetAudience>
-                                </xsl:when>
-                                <xsl:when test="$controlField008-22='f'">
-                                        <targetAudience authority="marctarget">specialized</targetAudience>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:if>
-                <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
-                        <note type="statement of responsibility">
-                                <xsl:value-of select="."/>
-                        </note>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=500]">
-                        <note>
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                                <xsl:call-template name="uri"/>
-                        </note>
-                </xsl:for-each>
-
-                <!--3.2 change tmee additional note fields-->
-
-                <xsl:for-each select="marc:datafield[@tag=502]">
-                        <note type="thesis">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=504]">
-                        <note type="bibliography">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=508]">
-                        <note type="creation/production credits">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=506]">
-                        <note type="restrictions">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=510]">
-                        <note type="citation/reference">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-
-                <xsl:for-each select="marc:datafield[@tag=511]">
-                        <note type="performers">
-                                <xsl:call-template name="uri"/>
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </note>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=518]">
-                        <note type="venue">
-                                <xsl:call-template name="uri"/>
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=530]">
-                        <note type="additional physical form">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=533]">
-                        <note type="reproduction">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=534]">
-                        <note type="original version">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=538]">
-                        <note type="system details">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=583]">
-                        <note type="action">
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-
-                <xsl:for-each
-                        select="marc:datafield[@tag=501 or @tag=507 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
-                        <note>
-                                <xsl:call-template name="uri"/>
-                                <xsl:variable name="str">
-                                        <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
-                                                <xsl:value-of select="."/>
-                                                <xsl:text> </xsl:text>
-                                        </xsl:for-each>
-                                </xsl:variable>
-                                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-                        </note>
-                </xsl:for-each>
-                <xsl:for-each
-                        select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
-                        <subject>
-                                <cartographics>
-                                        <coordinates>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">defg</xsl:with-param>
-                                                </xsl:call-template>
-                                        </coordinates>
-                                </cartographics>
-                        </subject>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=043]">
-                        <subject>
-                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
-                                        <geographicCode>
-                                                <xsl:attribute name="authority">
-                                                        <xsl:if test="@code='a'">
-                                                                <xsl:text>marcgac</xsl:text>
-                                                        </xsl:if>
-                                                        <xsl:if test="@code='b'">
-                                                                <xsl:value-of select="following-sibling::marc:subfield[@code=2]"/>
-                                                        </xsl:if>
-                                                        <xsl:if test="@code='c'">
-                                                                <xsl:text>iso3166</xsl:text>
-                                                        </xsl:if>
-                                                </xsl:attribute>
-                                                <xsl:value-of select="self::marc:subfield"/>
-                                        </geographicCode>
-                                </xsl:for-each>
-                        </subject>
-                </xsl:for-each>
-                <!-- tmee 2006/11/27 -->
-                <xsl:for-each select="marc:datafield[@tag=255]">
-                        <subject>
-                                <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
-                                        <cartographics>
-                                                <xsl:if test="@code='a'">
-                                                        <scale>
-                                                                <xsl:value-of select="."/>
-                                                        </scale>
-                                                </xsl:if>
-                                                <xsl:if test="@code='b'">
-                                                        <projection>
-                                                                <xsl:value-of select="."/>
-                                                        </projection>
-                                                </xsl:if>
-                                                <xsl:if test="@code='c'">
-                                                        <coordinates>
-                                                                <xsl:value-of select="."/>
-                                                        </coordinates>
-                                                </xsl:if>
-                                        </cartographics>
-                                </xsl:for-each>
-                        </subject>
-                </xsl:for-each>
-
-                <xsl:apply-templates select="marc:datafield[653 &gt;= @tag and @tag &gt;= 600]"/>
-                <xsl:apply-templates select="marc:datafield[@tag=656]"/>
-                <xsl:for-each select="marc:datafield[@tag=752 or @tag=662]">
-                        <subject>
-                                <hierarchicalGeographic>
-                                        <xsl:for-each select="marc:subfield[@code='a']">
-                                                <country>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </country>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='b']">
-                                                <state>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </state>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='c']">
-                                                <county>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </county>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='d']">
-                                                <city>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </city>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='e']">
-                                                <citySection>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </citySection>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='g']">
-                                                <region>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </region>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='h']">
-                                                <extraterrestrialArea>
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString" select="."/>
-                                                        </xsl:call-template>
-                                                </extraterrestrialArea>
-                                        </xsl:for-each>
-                                </hierarchicalGeographic>
-                        </subject>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
-                        <subject>
-                                <xsl:choose>
-                                        <xsl:when test="@ind1=2">
-                                                <temporal encoding="iso8601" point="start">
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString">
-                                                                        <xsl:value-of select="marc:subfield[@code='b'][1]"/>
-                                                                </xsl:with-param>
-                                                        </xsl:call-template>
-                                                </temporal>
-                                                <temporal encoding="iso8601" point="end">
-                                                        <xsl:call-template name="chopPunctuation">
-                                                                <xsl:with-param name="chopString">
-                                                                        <xsl:value-of select="marc:subfield[@code='b'][2]"/>
-                                                                </xsl:with-param>
-                                                        </xsl:call-template>
-                                                </temporal>
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <xsl:for-each select="marc:subfield[@code='b']">
-                                                        <temporal encoding="iso8601">
-                                                                <xsl:call-template name="chopPunctuation">
-                                                                        <xsl:with-param name="chopString" select="."/>
-                                                                </xsl:call-template>
-                                                        </temporal>
-                                                </xsl:for-each>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </subject>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=050]">
-                        <xsl:for-each select="marc:subfield[@code='b']">
-                                <classification authority="lcc">
-                                        <xsl:if test="../marc:subfield[@code='3']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:value-of select="../marc:subfield[@code='3']"/>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
-                                        <xsl:text> </xsl:text>
-                                        <xsl:value-of select="text()"/>
-                                </classification>
-                        </xsl:for-each>
-                        <xsl:for-each
-                                select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
-                                <classification authority="lcc">
-                                        <xsl:if test="../marc:subfield[@code='3']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:value-of select="../marc:subfield[@code='3']"/>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="text()"/>
-                                </classification>
-                        </xsl:for-each>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=082]">
-                        <classification authority="ddc">
-                                <xsl:if test="marc:subfield[@code='2']">
-                                        <xsl:attribute name="edition">
-                                                <xsl:value-of select="marc:subfield[@code='2']"/>
-                                        </xsl:attribute>
-                                </xsl:if>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=080]">
-                        <classification authority="udc">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abx</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=060]">
-                        <classification authority="nlm">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
-                        <classification authority="sudocs">
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
-                        <classification authority="candoc">
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=086]">
-                        <classification>
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"/>
-                                </xsl:attribute>
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=084]">
-                        <classification>
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code='2']"/>
-                                </xsl:attribute>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </classification>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=440]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">av</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">av</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=510]">
-                        <relatedItem type="isReferencedBy">
-                                <note>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abcx3</xsl:with-param>
-                                        </xsl:call-template>
-                                </note>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=534]">
-                        <relatedItem type="original">
-                                <xsl:call-template name="relatedTitle"/>
-                                <xsl:call-template name="relatedName"/>
-                                <xsl:if test="marc:subfield[@code='b' or @code='c']">
-                                        <originInfo>
-                                                <xsl:for-each select="marc:subfield[@code='c']">
-                                                        <publisher>
-                                                                <xsl:value-of select="."/>
-                                                        </publisher>
-                                                </xsl:for-each>
-                                                <xsl:for-each select="marc:subfield[@code='b']">
-                                                        <edition>
-                                                                <xsl:value-of select="."/>
-                                                        </edition>
-                                                </xsl:for-each>
-                                        </originInfo>
-                                </xsl:if>
-                                <xsl:call-template name="relatedIdentifierISSN"/>
-                                <xsl:for-each select="marc:subfield[@code='z']">
-                                        <identifier type="isbn">
-                                                <xsl:value-of select="."/>
-                                        </identifier>
-                                </xsl:for-each>
-                                <xsl:call-template name="relatedNote"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"/>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <name type="personal">
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="termsOfAddress"/>
-                                        <xsl:call-template name="nameDate"/>
-                                        <xsl:call-template name="role"/>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                                <xsl:call-template name="relatedIdentifierISSN"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"/>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </titleInfo>
-                                <name type="corporate">
-                                        <xsl:for-each select="marc:subfield[@code='a']">
-                                                <namePart>
-                                                        <xsl:value-of select="."/>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='b']">
-                                                <namePart>
-                                                        <xsl:value-of select="."/>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <xsl:variable name="tempNamePart">
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:variable>
-                                        <xsl:if test="normalize-space($tempNamePart)">
-                                                <namePart>
-                                                        <xsl:value-of select="$tempNamePart"/>
-                                                </namePart>
-                                        </xsl:if>
-                                        <xsl:call-template name="role"/>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                                <xsl:call-template name="relatedIdentifierISSN"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"/>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </titleInfo>
-                                <name type="conference">
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                                <xsl:call-template name="relatedIdentifierISSN"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"/>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <xsl:call-template name="relatedForm"/>
-                                <xsl:call-template name="relatedIdentifierISSN"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
-                        <relatedItem>
-                                <xsl:call-template name="constituentOrRelatedType"/>
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
-                        <relatedItem type="series">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each
-                        select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
-                        <relatedItem>
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=775]">
-                        <relatedItem type="otherVersion">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
-                        <relatedItem type="constituent">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
-                        <relatedItem type="host">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=776]">
-                        <relatedItem type="otherFormat">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=780]">
-                        <relatedItem type="preceding">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=785]">
-                        <relatedItem type="succeeding">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=786]">
-                        <relatedItem type="original">
-                                <xsl:call-template name="relatedItem76X-78X"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=800]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <name type="personal">
-                                        <namePart>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">aq</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="beforeCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="termsOfAddress"/>
-                                        <xsl:call-template name="nameDate"/>
-                                        <xsl:call-template name="role"/>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=810]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">dg</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </titleInfo>
-                                <name type="corporate">
-                                        <xsl:for-each select="marc:subfield[@code='a']">
-                                                <namePart>
-                                                        <xsl:value-of select="."/>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <xsl:for-each select="marc:subfield[@code='b']">
-                                                <namePart>
-                                                        <xsl:value-of select="."/>
-                                                </namePart>
-                                        </xsl:for-each>
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">c</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="role"/>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=811]">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="specialSubfieldSelect">
-                                                                        <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
-                                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                                        <xsl:with-param name="afterCodes">g</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </titleInfo>
-                                <name type="conference">
-                                        <namePart>
-                                                <xsl:call-template name="specialSubfieldSelect">
-                                                        <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
-                                                        <xsl:with-param name="axis">t</xsl:with-param>
-                                                        <xsl:with-param name="beforeCodes">gn</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                        <xsl:call-template name="role"/>
-                                </name>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='830']">
-                        <relatedItem type="series">
-                                <titleInfo>
-                                        <title>
-                                                <xsl:call-template name="chopPunctuation">
-                                                        <xsl:with-param name="chopString">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:with-param>
-                                                </xsl:call-template>
-                                        </title>
-                                        <xsl:call-template name="part"/>
-                                </titleInfo>
-                                <xsl:call-template name="relatedForm"/>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
-                        <relatedItem>
-                                <internetMediaType>
-                                        <xsl:value-of select="."/>
-                                </internetMediaType>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='020']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">isbn</xsl:with-param>
-                        </xsl:call-template>
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <identifier type="isbn">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">isrc</xsl:with-param>
-                        </xsl:call-template>
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <identifier type="isrc">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">ismn</xsl:with-param>
-                        </xsl:call-template>
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <identifier type="ismn">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">sici</xsl:with-param>
-                        </xsl:call-template>
-                        <identifier type="sici">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='022']">
-                        <xsl:if test="marc:subfield[@code='a']">
-                                <xsl:call-template name="isInvalid">
-                                        <xsl:with-param name="type">issn</xsl:with-param>
-                                </xsl:call-template>
-                                <identifier type="issn">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </identifier>
-                        </xsl:if>
-                        <xsl:if test="marc:subfield[@code='l']">
-                                <xsl:call-template name="isInvalid">
-                                        <xsl:with-param name="type">issn-l</xsl:with-param>
-                                </xsl:call-template>
-                                <identifier type="issn-l">
-                                        <xsl:value-of select="marc:subfield[@code='l']"/>
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-
-
-
-                <xsl:for-each select="marc:datafield[@tag='010']">
-                        <xsl:call-template name="isInvalid">
-                                <xsl:with-param name="type">lccn</xsl:with-param>
-                        </xsl:call-template>
-                        <identifier type="lccn">
-                                <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='028']">
-                        <identifier>
-                                <xsl:attribute name="type">
-                                        <xsl:choose>
-                                                <xsl:when test="@ind1='0'">issue number</xsl:when>
-                                                <xsl:when test="@ind1='1'">matrix number</xsl:when>
-                                                <xsl:when test="@ind1='2'">music plate</xsl:when>
-                                                <xsl:when test="@ind1='3'">music publisher</xsl:when>
-                                                <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
-                                        </xsl:choose>
-                                </xsl:attribute>
-                                <!--<xsl:call-template name="isInvalid"/>-->
-                                <!-- no $z in 028 -->
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">
-                                                <xsl:choose>
-                                                        <xsl:when test="@ind1='0'">ba</xsl:when>
-                                                        <xsl:otherwise>ab</xsl:otherwise>
-                                                </xsl:choose>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='037']">
-                        <identifier type="stock number">
-                                <!--<xsl:call-template name="isInvalid"/>-->
-                                <!-- no $z in 037 -->
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">ab</xsl:with-param>
-                                </xsl:call-template>
-                        </identifier>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
-                        <identifier>
-                                <xsl:attribute name="type">
-                                        <xsl:choose>
-                                                <xsl:when
-                                                        test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')"
-                                                        >doi</xsl:when>
-                                                <xsl:when
-                                                        test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')"
-                                                        >hdl</xsl:when>
-                                                <xsl:otherwise>uri</xsl:otherwise>
-                                        </xsl:choose>
-                                </xsl:attribute>
-                                <xsl:choose>
-                                        <xsl:when
-                                                test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
-                                                <xsl:value-of
-                                                        select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
-                                                />
-                                        </xsl:when>
-                                        <xsl:otherwise>
-                                                <xsl:value-of select="marc:subfield[@code='u']"/>
-                                        </xsl:otherwise>
-                                </xsl:choose>
-                        </identifier>
-                        <xsl:if
-                                test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
-                                <identifier type="hdl">
-                                        <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
-                                                <xsl:attribute name="displayLabel">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">y3z</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of
-                                                select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
-                                        />
-                                </identifier>
-                        </xsl:if>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
-                        <identifier type="upc">
-                                <xsl:call-template name="isInvalid"/>
-                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                        </identifier>
-                </xsl:for-each>
-
-                <!-- 1/04 fix added $y -->
-
-                <!-- 1.21  tmee-->
-                <xsl:for-each select="marc:datafield[@tag=856][@ind2=1][marc:subfield[@code='u']]">
-                        <relatedItem type="otherVersion">
-                                <location>
-                                        <url>
-                                                <xsl:if test="marc:subfield[@code='y' or @code='3']">
-                                                        <xsl:attribute name="displayLabel">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">y3</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:attribute>
-                                                </xsl:if>
-                                                <xsl:if test="marc:subfield[@code='z' ]">
-                                                        <xsl:attribute name="note">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">z</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:attribute>
-                                                </xsl:if>
-                                                <xsl:value-of select="marc:subfield[@code='u']"/>
-                                        </url>
-                                </location>
-                        </relatedItem>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=856][@ind2=2][marc:subfield[@code='u']]">
-                        <relatedItem>
-                                <location>
-                                        <url>
-                                                <xsl:if test="marc:subfield[@code='y' or @code='3']">
-                                                        <xsl:attribute name="displayLabel">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">y3</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:attribute>
-                                                </xsl:if>
-                                                <xsl:if test="marc:subfield[@code='z' ]">
-                                                        <xsl:attribute name="note">
-                                                                <xsl:call-template name="subfieldSelect">
-                                                                        <xsl:with-param name="codes">z</xsl:with-param>
-                                                                </xsl:call-template>
-                                                        </xsl:attribute>
-                                                </xsl:if>
-                                                <xsl:value-of select="marc:subfield[@code='u']"/>
-                                        </url>
-                                </location>
-                        </relatedItem>
-                </xsl:for-each>
-
-                <!-- 3.2 change tmee 856z  -->
-
-                <!-- 1.24  tmee  -->
-                <xsl:for-each select="marc:datafield[@tag=852]">
-                        <location>
-                                <xsl:if test="marc:subfield[@code='a' or @code='b' or @code='e']">
-                                        <physicalLocation>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">abe</xsl:with-param>
-                                                </xsl:call-template>
-                                        </physicalLocation>
-                                </xsl:if>
-
-                                <xsl:if test="marc:subfield[@code='u']">
-                                        <physicalLocation>
-                                                <xsl:call-template name="uri"/>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">u</xsl:with-param>
-                                                </xsl:call-template>
-                                        </physicalLocation>
-                                </xsl:if>
-
-                                <xsl:if
-                                        test="marc:subfield[@code='h' or @code='i' or @code='j' or @code='k' or @code='l' or @code='m' or @code='t']">
-                                        <shelfLocation>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">hijklmt</xsl:with-param>
-                                                </xsl:call-template>
-                                        </shelfLocation>
-                                </xsl:if>
-                        </location>
-                </xsl:for-each>
-
-                <xsl:for-each select="marc:datafield[@tag=506]">
-                        <accessCondition type="restrictionOnAccess">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abcd35</xsl:with-param>
-                                </xsl:call-template>
-                        </accessCondition>
-                </xsl:for-each>
-                <xsl:for-each select="marc:datafield[@tag=540]">
-                        <accessCondition type="useAndReproduction">
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">abcde35</xsl:with-param>
-                                </xsl:call-template>
-                        </accessCondition>
-                </xsl:for-each>
-
-                <recordInfo>
-                        <!-- 1.25  tmee-->
-
-
-                        <xsl:for-each select="marc:leader[substring($leader,19,1)='a']">
-                                <descriptionStandard>aacr2</descriptionStandard>
-                        </xsl:for-each>
-
-                        <xsl:for-each select="marc:datafield[@tag=040]">
-                                <xsl:if test="marc:subfield[@code='e']">
-                                        <descriptionStandard>
-                                                <xsl:value-of select="marc:subfield[@code='e']"/>
-                                        </descriptionStandard>
-                                </xsl:if>
-                                <recordContentSource authority="marcorg">
-                                        <xsl:value-of select="marc:subfield[@code='a']"/>
-                                </recordContentSource>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=008]">
-                                <recordCreationDate encoding="marc">
-                                        <xsl:value-of select="substring(.,1,6)"/>
-                                </recordCreationDate>
-                        </xsl:for-each>
-
-                        <xsl:for-each select="marc:controlfield[@tag=005]">
-                                <recordChangeDate encoding="iso8601">
-                                        <xsl:value-of select="."/>
-                                </recordChangeDate>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:controlfield[@tag=001]">
-                                <recordIdentifier>
-                                        <xsl:if test="../marc:controlfield[@tag=003]">
-                                                <xsl:attribute name="source">
-                                                        <xsl:value-of select="../marc:controlfield[@tag=003]"/>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <xsl:value-of select="."/>
-                                </recordIdentifier>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
-                                <languageOfCataloging>
-                                        <languageTerm authority="iso639-2b" type="code">
-                                                <xsl:value-of select="."/>
-                                        </languageTerm>
-                                </languageOfCataloging>
-                        </xsl:for-each>
-                </recordInfo>
-        </xsl:template>
-        <xsl:template name="displayForm">
-                <xsl:for-each select="marc:subfield[@code='c']">
-                        <displayForm>
-                                <xsl:value-of select="."/>
-                        </displayForm>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="affiliation">
-                <xsl:for-each select="marc:subfield[@code='u']">
-                        <affiliation>
-                                <xsl:value-of select="."/>
-                        </affiliation>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="uri">
-                <xsl:for-each select="marc:subfield[@code='u']">
-                        <xsl:attribute name="xlink:href">
-                                <xsl:value-of select="."/>
-                        </xsl:attribute>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='0']">
-                        <xsl:choose>
-                                <xsl:when test="contains(text(), ')')">
-                                        <xsl:attribute name="xlink:href">
-                                                <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
-                                        </xsl:attribute>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:attribute name="xlink:href">
-                                                <xsl:value-of select="."></xsl:value-of>
-                                        </xsl:attribute>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="role">
-                <xsl:for-each select="marc:subfield[@code='e']">
-                        <role>
-                                <roleTerm type="text">
-                                        <xsl:value-of select="."/>
-                                </roleTerm>
-                        </role>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='4']">
-                        <role>
-                                <roleTerm authority="marcrelator" type="code">
-                                        <xsl:value-of select="."/>
-                                </roleTerm>
-                        </role>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="part">
-                <xsl:variable name="partNumber">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">n</xsl:with-param>
-                                <xsl:with-param name="anyCodes">n</xsl:with-param>
-                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:variable name="partName">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">p</xsl:with-param>
-                                <xsl:with-param name="anyCodes">p</xsl:with-param>
-                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:if test="string-length(normalize-space($partNumber))">
-                        <partNumber>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="$partNumber"/>
-                                </xsl:call-template>
-                        </partNumber>
-                </xsl:if>
-                <xsl:if test="string-length(normalize-space($partName))">
-                        <partName>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="$partName"/>
-                                </xsl:call-template>
-                        </partName>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedPart">
-                <xsl:if test="@tag=773">
-                        <xsl:for-each select="marc:subfield[@code='g']">
-                                <part>
-                                        <text>
-                                                <xsl:value-of select="."/>
-                                        </text>
-                                </part>
-                        </xsl:for-each>
-                        <xsl:for-each select="marc:subfield[@code='q']">
-                                <part>
-                                        <xsl:call-template name="parsePart"/>
-                                </part>
-                        </xsl:for-each>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedPartNumName">
-                <xsl:variable name="partNumber">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">g</xsl:with-param>
-                                <xsl:with-param name="anyCodes">g</xsl:with-param>
-                                <xsl:with-param name="afterCodes">pst</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:variable name="partName">
-                        <xsl:call-template name="specialSubfieldSelect">
-                                <xsl:with-param name="axis">p</xsl:with-param>
-                                <xsl:with-param name="anyCodes">p</xsl:with-param>
-                                <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:if test="string-length(normalize-space($partNumber))">
-                        <partNumber>
-                                <xsl:value-of select="$partNumber"/>
-                        </partNumber>
-                </xsl:if>
-                <xsl:if test="string-length(normalize-space($partName))">
-                        <partName>
-                                <xsl:value-of select="$partName"/>
-                        </partName>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedName">
-                <xsl:for-each select="marc:subfield[@code='a']">
-                        <name>
-                                <namePart>
-                                        <xsl:value-of select="."/>
-                                </namePart>
-                        </name>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedForm">
-                <xsl:for-each select="marc:subfield[@code='h']">
-                        <physicalDescription>
-                                <form>
-                                        <xsl:value-of select="."/>
-                                </form>
-                        </physicalDescription>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedExtent">
-                <xsl:for-each select="marc:subfield[@code='h']">
-                        <physicalDescription>
-                                <extent>
-                                        <xsl:value-of select="."/>
-                                </extent>
-                        </physicalDescription>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedNote">
-                <xsl:for-each select="marc:subfield[@code='n']">
-                        <note>
-                                <xsl:value-of select="."/>
-                        </note>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedSubject">
-                <xsl:for-each select="marc:subfield[@code='j']">
-                        <subject>
-                                <temporal encoding="iso8601">
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString" select="."/>
-                                        </xsl:call-template>
-                                </temporal>
-                        </subject>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedIdentifierISSN">
-                <xsl:for-each select="marc:subfield[@code='x']">
-                        <identifier type="issn">
-                                <xsl:value-of select="."/>
-                        </identifier>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedIdentifierLocal">
-                <xsl:for-each select="marc:subfield[@code='w']">
-                        <identifier type="local">
-                                <xsl:value-of select="."/>
-                        </identifier>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedIdentifier">
-                <xsl:for-each select="marc:subfield[@code='o']">
-                        <identifier>
-                                <xsl:value-of select="."/>
-                        </identifier>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedItem76X-78X">
-                <xsl:call-template name="displayLabel"/>
-                <xsl:call-template name="relatedTitle76X-78X"/>
-                <xsl:call-template name="relatedName"/>
-                <xsl:call-template name="relatedOriginInfo"/>
-                <xsl:call-template name="relatedLanguage"/>
-                <xsl:call-template name="relatedExtent"/>
-                <xsl:call-template name="relatedNote"/>
-                <xsl:call-template name="relatedSubject"/>
-                <xsl:call-template name="relatedIdentifier"/>
-                <xsl:call-template name="relatedIdentifierISSN"/>
-                <xsl:call-template name="relatedIdentifierLocal"/>
-                <xsl:call-template name="relatedPart"/>
-        </xsl:template>
-        <xsl:template name="subjectGeographicZ">
-                <geographic>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."/>
-                        </xsl:call-template>
-                </geographic>
-        </xsl:template>
-        <xsl:template name="subjectTemporalY">
-                <temporal>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."/>
-                        </xsl:call-template>
-                </temporal>
-        </xsl:template>
-        <xsl:template name="subjectTopic">
-                <topic>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."/>
-                        </xsl:call-template>
-                </topic>
-        </xsl:template>
-        <!-- 3.2 change tmee 6xx $v genre -->
-        <xsl:template name="subjectGenre">
-                <genre>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="."/>
-                        </xsl:call-template>
-                </genre>
-        </xsl:template>
-
-        <xsl:template name="nameABCDN">
-                <xsl:for-each select="marc:subfield[@code='a']">
-                        <namePart>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="."/>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='b']">
-                        <namePart>
-                                <xsl:value-of select="."/>
-                        </namePart>
-                </xsl:for-each>
-                <xsl:if
-                        test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
-                        <namePart>
-                                <xsl:call-template name="subfieldSelect">
-                                        <xsl:with-param name="codes">cdn</xsl:with-param>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="nameABCDQ">
-                <namePart>
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString">
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">aq</xsl:with-param>
-                                        </xsl:call-template>
-                                </xsl:with-param>
-                                <xsl:with-param name="punctuation">
-                                        <xsl:text>:,;/ </xsl:text>
-                                </xsl:with-param>
-                        </xsl:call-template>
-                </namePart>
-                <xsl:call-template name="termsOfAddress"/>
-                <xsl:call-template name="nameDate"/>
-        </xsl:template>
-        <xsl:template name="nameACDEQ">
-                <namePart>
-                        <xsl:call-template name="subfieldSelect">
-                                <xsl:with-param name="codes">acdeq</xsl:with-param>
-                        </xsl:call-template>
-                </namePart>
-        </xsl:template>
-        <xsl:template name="constituentOrRelatedType">
-                <xsl:if test="@ind2=2">
-                        <xsl:attribute name="type">constituent</xsl:attribute>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedTitle">
-                <xsl:for-each select="marc:subfield[@code='t']">
-                        <titleInfo>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."/>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                        </titleInfo>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedTitle76X-78X">
-                <xsl:for-each select="marc:subfield[@code='t']">
-                        <titleInfo>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."/>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </xsl:if>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='p']">
-                        <titleInfo type="abbreviated">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."/>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </xsl:if>
-                        </titleInfo>
-                </xsl:for-each>
-                <xsl:for-each select="marc:subfield[@code='s']">
-                        <titleInfo type="uniform">
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:value-of select="."/>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
-                                        <xsl:call-template name="relatedPartNumName"/>
-                                </xsl:if>
-                        </titleInfo>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="relatedOriginInfo">
-                <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
-                        <originInfo>
-                                <xsl:if test="@tag=775">
-                                        <xsl:for-each select="marc:subfield[@code='f']">
-                                                <place>
-                                                        <placeTerm>
-                                                                <xsl:attribute name="type">code</xsl:attribute>
-                                                                <xsl:attribute name="authority">marcgac</xsl:attribute>
-                                                                <xsl:value-of select="."/>
-                                                        </placeTerm>
-                                                </place>
-                                        </xsl:for-each>
-                                </xsl:if>
-                                <xsl:for-each select="marc:subfield[@code='d']">
-                                        <publisher>
-                                                <xsl:value-of select="."/>
-                                        </publisher>
-                                </xsl:for-each>
-                                <xsl:for-each select="marc:subfield[@code='b']">
-                                        <edition>
-                                                <xsl:value-of select="."/>
-                                        </edition>
-                                </xsl:for-each>
-                        </originInfo>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="relatedLanguage">
-                <xsl:for-each select="marc:subfield[@code='e']">
-                        <xsl:call-template name="getLanguage">
-                                <xsl:with-param name="langString">
-                                        <xsl:value-of select="."/>
-                                </xsl:with-param>
-                        </xsl:call-template>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="nameDate">
-                <xsl:for-each select="marc:subfield[@code='d']">
-                        <namePart type="date">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="."/>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="subjectAuthority">
-                <xsl:if test="@ind2!=4">
-                        <xsl:if test="@ind2!=' '">
-                                <xsl:if test="@ind2!=8">
-                                        <xsl:if test="@ind2!=9">
-                                                <xsl:attribute name="authority">
-                                                        <xsl:choose>
-                                                                <xsl:when test="@ind2=0">lcsh</xsl:when>
-                                                                <xsl:when test="@ind2=1">lcshac</xsl:when>
-                                                                <xsl:when test="@ind2=2">mesh</xsl:when>
-                                                                <!-- 1/04 fix -->
-                                                                <xsl:when test="@ind2=3">nal</xsl:when>
-                                                                <xsl:when test="@ind2=5">csh</xsl:when>
-                                                                <xsl:when test="@ind2=6">rvm</xsl:when>
-                                                                <xsl:when test="@ind2=7">
-                                                                        <xsl:value-of select="marc:subfield[@code='2']"/>
-                                                                </xsl:when>
-                                                        </xsl:choose>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                </xsl:if>
-                        </xsl:if>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="subjectAnyOrder">
-                <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
-                        <xsl:choose>
-                                <xsl:when test="@code='v'">
-                                        <xsl:call-template name="subjectGenre"/>
-                                </xsl:when>
-                                <xsl:when test="@code='x'">
-                                        <xsl:call-template name="subjectTopic"/>
-                                </xsl:when>
-                                <xsl:when test="@code='y'">
-                                        <xsl:call-template name="subjectTemporalY"/>
-                                </xsl:when>
-                                <xsl:when test="@code='z'">
-                                        <xsl:call-template name="subjectGeographicZ"/>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:for-each>
-        </xsl:template>
-        <xsl:template name="specialSubfieldSelect">
-                <xsl:param name="anyCodes"/>
-                <xsl:param name="axis"/>
-                <xsl:param name="beforeCodes"/>
-                <xsl:param name="afterCodes"/>
-                <xsl:variable name="str">
-                        <xsl:for-each select="marc:subfield">
-                                <xsl:if
-                                        test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
-                                        <xsl:value-of select="text()"/>
-                                        <xsl:text> </xsl:text>
-                                </xsl:if>
-                        </xsl:for-each>
-                </xsl:variable>
-                <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
-        </xsl:template>
-
-        <!-- 3.2 change tmee 6xx $v genre -->
-        <xsl:template match="marc:datafield[@tag=600]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"/>
-                        <name type="personal">
-                                <xsl:call-template name="termsOfAddress"/>
-                                <namePart>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">aq</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </namePart>
-                                <xsl:call-template name="nameDate"/>
-                                <xsl:call-template name="affiliation"/>
-                                <xsl:call-template name="role"/>
-                        </name>
-                        <xsl:call-template name="subjectAnyOrder"/>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=610]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"/>
-                        <name type="corporate">
-                                <xsl:for-each select="marc:subfield[@code='a']">
-                                        <namePart>
-                                                <xsl:value-of select="."/>
-                                        </namePart>
-                                </xsl:for-each>
-                                <xsl:for-each select="marc:subfield[@code='b']">
-                                        <namePart>
-                                                <xsl:value-of select="."/>
-                                        </namePart>
-                                </xsl:for-each>
-                                <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
-                                        <namePart>
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">cdnp</xsl:with-param>
-                                                </xsl:call-template>
-                                        </namePart>
-                                </xsl:if>
-                                <xsl:call-template name="role"/>
-                        </name>
-                        <xsl:call-template name="subjectAnyOrder"/>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=611]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"/>
-                        <name type="conference">
-                                <namePart>
-                                        <xsl:call-template name="subfieldSelect">
-                                                <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
-                                        </xsl:call-template>
-                                </namePart>
-                                <xsl:for-each select="marc:subfield[@code='4']">
-                                        <role>
-                                                <roleTerm authority="marcrelator" type="code">
-                                                        <xsl:value-of select="."/>
-                                                </roleTerm>
-                                        </role>
-                                </xsl:for-each>
-                        </name>
-                        <xsl:call-template name="subjectAnyOrder"/>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=630]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"/>
-                        <titleInfo>
-                                <title>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString">
-                                                        <xsl:call-template name="subfieldSelect">
-                                                                <xsl:with-param name="codes">adfhklor</xsl:with-param>
-                                                        </xsl:call-template>
-                                                </xsl:with-param>
-                                        </xsl:call-template>
-                                </title>
-                                <xsl:call-template name="part"/>
-                        </titleInfo>
-                        <xsl:call-template name="subjectAnyOrder"/>
-                </subject>
-        </xsl:template>
-        <!-- 1.27 648 tmee-->
-        <xsl:template match="marc:datafield[@tag=648]">
-                <subject>
-                        <xsl:if test="marc:subfield[@code=2]">
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code=2]"/>
-                                </xsl:attribute>
-                        </xsl:if>
-                        <xsl:call-template name="uri"/>
-
-                        <xsl:call-template name="subjectAuthority"/>
-                        <temporal>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">abcd</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </temporal>
-                        <xsl:call-template name="subjectAnyOrder"/>
-
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=650]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"/>
-                        <topic>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">abcd</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </topic>
-                        <xsl:call-template name="subjectAnyOrder"/>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=651]">
-                <subject>
-                        <xsl:call-template name="subjectAuthority"/>
-                        <xsl:for-each select="marc:subfield[@code='a']">
-                                <geographic>
-                                        <xsl:call-template name="chopPunctuation">
-                                                <xsl:with-param name="chopString" select="."/>
-                                        </xsl:call-template>
-                                </geographic>
-                        </xsl:for-each>
-                        <xsl:call-template name="subjectAnyOrder"/>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=653]">
-                <subject>
-                        <xsl:for-each select="marc:subfield[@code='a']">
-                                <topic>
-                                        <xsl:value-of select="."/>
-                                </topic>
-                        </xsl:for-each>
-                </subject>
-        </xsl:template>
-        <xsl:template match="marc:datafield[@tag=656]">
-                <subject>
-                        <xsl:if test="marc:subfield[@code=2]">
-                                <xsl:attribute name="authority">
-                                        <xsl:value-of select="marc:subfield[@code=2]"/>
-                                </xsl:attribute>
-                        </xsl:if>
-                        <occupation>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:value-of select="marc:subfield[@code='a']"/>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </occupation>
-                </subject>
-        </xsl:template>
-        <xsl:template name="termsOfAddress">
-                <xsl:if test="marc:subfield[@code='b' or @code='c']">
-                        <namePart type="termsOfAddress">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">bc</xsl:with-param>
-                                                </xsl:call-template>
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </namePart>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="displayLabel">
-                <xsl:if test="marc:subfield[@code='i']">
-                        <xsl:attribute name="displayLabel">
-                                <xsl:value-of select="marc:subfield[@code='i']"/>
-                        </xsl:attribute>
-                </xsl:if>
-                <xsl:if test="marc:subfield[@code='3']">
-                        <xsl:attribute name="displayLabel">
-                                <xsl:value-of select="marc:subfield[@code='3']"/>
-                        </xsl:attribute>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="isInvalid">
-                <xsl:param name="type"/>
-                <xsl:if
-                        test="marc:subfield[@code='z'] or marc:subfield[@code='y']  or marc:subfield[@code='m']">
-                        <identifier>
-                                <xsl:attribute name="type">
-                                        <xsl:value-of select="$type"/>
-                                </xsl:attribute>
-                                <xsl:attribute name="invalid">
-                                        <xsl:text>yes</xsl:text>
-                                </xsl:attribute>
-                                <xsl:if test="marc:subfield[@code='z']">
-                                        <xsl:value-of select="marc:subfield[@code='z']"/>
-                                </xsl:if>
-                                <xsl:if test="marc:subfield[@code='y']">
-                                        <xsl:value-of select="marc:subfield[@code='y']"/>
-                                </xsl:if>
-                                <xsl:if test="marc:subfield[@code='m']">
-                                        <xsl:value-of select="marc:subfield[@code='m']"/>
-                                </xsl:if>
-                        </identifier>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="subtitle">
-                <xsl:if test="marc:subfield[@code='b']">
-                        <subTitle>
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString">
-                                                <xsl:value-of select="marc:subfield[@code='b']"/>
-                                                <!--<xsl:call-template name="subfieldSelect">
-                                                        <xsl:with-param name="codes">b</xsl:with-param>
-                                                </xsl:call-template>-->
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </subTitle>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="script">
-                <xsl:param name="scriptCode"/>
-                <xsl:attribute name="script">
-                        <xsl:choose>
-                                <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
-                                <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
-                                <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
-                                <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
-                                <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
-                                <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
-                        </xsl:choose>
-                </xsl:attribute>
-        </xsl:template>
-        <xsl:template name="parsePart">
-                <!-- assumes 773$q= 1:2:3<4
-                     with up to 3 levels and one optional start page
-                -->
-                <xsl:variable name="level1">
-                        <xsl:choose>
-                                <xsl:when test="contains(text(),':')">
-                                        <!-- 1:2 -->
-                                        <xsl:value-of select="substring-before(text(),':')"/>
-                                </xsl:when>
-                                <xsl:when test="not(contains(text(),':'))">
-                                        <!-- 1 or 1<3 -->
-                                        <xsl:if test="contains(text(),'&lt;')">
-                                                <!-- 1<3 -->
-                                                <xsl:value-of select="substring-before(text(),'&lt;')"/>
-                                        </xsl:if>
-                                        <xsl:if test="not(contains(text(),'&lt;'))">
-                                                <!-- 1 -->
-                                                <xsl:value-of select="text()"/>
-                                        </xsl:if>
-                                </xsl:when>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="sici2">
-                        <xsl:choose>
-                                <xsl:when test="starts-with(substring-after(text(),$level1),':')">
-                                        <xsl:value-of select="substring(substring-after(text(),$level1),2)"/>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="substring-after(text(),$level1)"/>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="level2">
-                        <xsl:choose>
-                                <xsl:when test="contains($sici2,':')">
-                                        <!--  2:3<4  -->
-                                        <xsl:value-of select="substring-before($sici2,':')"/>
-                                </xsl:when>
-                                <xsl:when test="contains($sici2,'&lt;')">
-                                        <!-- 1: 2<4 -->
-                                        <xsl:value-of select="substring-before($sici2,'&lt;')"/>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="$sici2"/>
-                                        <!-- 1:2 -->
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="sici3">
-                        <xsl:choose>
-                                <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
-                                        <xsl:value-of select="substring(substring-after($sici2,$level2),2)"/>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="substring-after($sici2,$level2)"/>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="level3">
-                        <xsl:choose>
-                                <xsl:when test="contains($sici3,'&lt;')">
-                                        <!-- 2<4 -->
-                                        <xsl:value-of select="substring-before($sici3,'&lt;')"/>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:value-of select="$sici3"/>
-                                        <!-- 3 -->
-                                </xsl:otherwise>
-                        </xsl:choose>
-                </xsl:variable>
-                <xsl:variable name="page">
-                        <xsl:if test="contains(text(),'&lt;')">
-                                <xsl:value-of select="substring-after(text(),'&lt;')"/>
-                        </xsl:if>
-                </xsl:variable>
-                <xsl:if test="$level1">
-                        <detail level="1">
-                                <number>
-                                        <xsl:value-of select="$level1"/>
-                                </number>
-                        </detail>
-                </xsl:if>
-                <xsl:if test="$level2">
-                        <detail level="2">
-                                <number>
-                                        <xsl:value-of select="$level2"/>
-                                </number>
-                        </detail>
-                </xsl:if>
-                <xsl:if test="$level3">
-                        <detail level="3">
-                                <number>
-                                        <xsl:value-of select="$level3"/>
-                                </number>
-                        </detail>
-                </xsl:if>
-                <xsl:if test="$page">
-                        <extent unit="page">
-                                <start>
-                                        <xsl:value-of select="$page"/>
-                                </start>
-                        </extent>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="getLanguage">
-                <xsl:param name="langString"/>
-                <xsl:param name="controlField008-35-37"/>
-                <xsl:variable name="length" select="string-length($langString)"/>
-                <xsl:choose>
-                        <xsl:when test="$length=0"/>
-                        <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
-                                <xsl:call-template name="getLanguage">
-                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
-                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:otherwise>
-                                <language>
-                                        <languageTerm authority="iso639-2b" type="code">
-                                                <xsl:value-of select="substring($langString,1,3)"/>
-                                        </languageTerm>
-                                </language>
-                                <xsl:call-template name="getLanguage">
-                                        <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
-                                        <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
-                                </xsl:call-template>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="isoLanguage">
-                <xsl:param name="currentLanguage"/>
-                <xsl:param name="usedLanguages"/>
-                <xsl:param name="remainingLanguages"/>
-                <xsl:choose>
-                        <xsl:when test="string-length($currentLanguage)=0"/>
-                        <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
-                                <language>
-                                        <xsl:if test="@code!='a'">
-                                                <xsl:attribute name="objectPart">
-                                                        <xsl:choose>
-                                                                <xsl:when test="@code='b'">summary or subtitle</xsl:when>
-                                                                <xsl:when test="@code='d'">sung or spoken text</xsl:when>
-                                                                <xsl:when test="@code='e'">libretto</xsl:when>
-                                                                <xsl:when test="@code='f'">table of contents</xsl:when>
-                                                                <xsl:when test="@code='g'">accompanying material</xsl:when>
-                                                                <xsl:when test="@code='h'">translation</xsl:when>
-                                                        </xsl:choose>
-                                                </xsl:attribute>
-                                        </xsl:if>
-                                        <languageTerm authority="iso639-2b" type="code">
-                                                <xsl:value-of select="$currentLanguage"/>
-                                        </languageTerm>
-                                </language>
-                                <xsl:call-template name="isoLanguage">
-                                        <xsl:with-param name="currentLanguage">
-                                                <xsl:value-of select="substring($remainingLanguages,1,3)"/>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="usedLanguages">
-                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="remainingLanguages">
-                                                <xsl:value-of
-                                                        select="substring($remainingLanguages,4,string-length($remainingLanguages))"
-                                                />
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:otherwise>
-                                <xsl:call-template name="isoLanguage">
-                                        <xsl:with-param name="currentLanguage">
-                                                <xsl:value-of select="substring($remainingLanguages,1,3)"/>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="usedLanguages">
-                                                <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
-                                        </xsl:with-param>
-                                        <xsl:with-param name="remainingLanguages">
-                                                <xsl:value-of
-                                                        select="substring($remainingLanguages,4,string-length($remainingLanguages))"
-                                                />
-                                        </xsl:with-param>
-                                </xsl:call-template>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-        <xsl:template name="chopBrackets">
-                <xsl:param name="chopString"/>
-                <xsl:variable name="string">
-                        <xsl:call-template name="chopPunctuation">
-                                <xsl:with-param name="chopString" select="$chopString"/>
-                        </xsl:call-template>
-                </xsl:variable>
-                <xsl:if test="substring($string, 1,1)='['">
-                        <xsl:value-of select="substring($string,2, string-length($string)-2)"/>
-                </xsl:if>
-                <xsl:if test="substring($string, 1,1)!='['">
-                        <xsl:value-of select="$string"/>
-                </xsl:if>
-        </xsl:template>
-        <xsl:template name="rfcLanguages">
-                <xsl:param name="nodeNum"/>
-                <xsl:param name="usedLanguages"/>
-                <xsl:param name="controlField008-35-37"/>
-                <xsl:variable name="currentLanguage" select="."/>
-                <xsl:choose>
-                        <xsl:when test="not($currentLanguage)"/>
-                        <xsl:when
-                                test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
-                                <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
-                                        <language>
-                                                <xsl:if test="@code!='a'">
-                                                        <xsl:attribute name="objectPart">
-                                                                <xsl:choose>
-                                                                        <xsl:when test="@code='b'">summary or subtitle</xsl:when>
-                                                                        <xsl:when test="@code='d'">sung or spoken text</xsl:when>
-                                                                        <xsl:when test="@code='e'">libretto</xsl:when>
-                                                                        <xsl:when test="@code='f'">table of contents</xsl:when>
-                                                                        <xsl:when test="@code='g'">accompanying material</xsl:when>
-                                                                        <xsl:when test="@code='h'">translation</xsl:when>
-                                                                </xsl:choose>
-                                                        </xsl:attribute>
-                                                </xsl:if>
-                                                <languageTerm authority="rfc3066" type="code">
-                                                        <xsl:value-of select="$currentLanguage"/>
-                                                </languageTerm>
-                                        </language>
-                                </xsl:if>
-                        </xsl:when>
-                        <xsl:otherwise> </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-
-    <xsl:template name="datafield">
-                <xsl:param name="tag"/>
-                <xsl:param name="ind1">
-                        <xsl:text> </xsl:text>
-                </xsl:param>
-                <xsl:param name="ind2">
-                        <xsl:text> </xsl:text>
-                </xsl:param>
-                <xsl:param name="subfields"/>
-                <xsl:element name="marc:datafield">
-                        <xsl:attribute name="tag">
-                                <xsl:value-of select="$tag"/>
-                        </xsl:attribute>
-                        <xsl:attribute name="ind1">
-                                <xsl:value-of select="$ind1"/>
-                        </xsl:attribute>
-                        <xsl:attribute name="ind2">
-                                <xsl:value-of select="$ind2"/>
-                        </xsl:attribute>
-                        <xsl:copy-of select="$subfields"/>
-                </xsl:element>
-        </xsl:template>
-
-        <xsl:template name="subfieldSelect">
-                <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
-                <xsl:param name="delimeter">
-                        <xsl:text> </xsl:text>
-                </xsl:param>
-                <xsl:variable name="str">
-                        <xsl:for-each select="marc:subfield">
-                                <xsl:if test="contains($codes, @code)">
-                                        <xsl:value-of select="text()"/>
-                                        <xsl:value-of select="$delimeter"/>
-                                </xsl:if>
-                        </xsl:for-each>
-                </xsl:variable>
-                <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
-        </xsl:template>
-
-        <xsl:template name="buildSpaces">
-                <xsl:param name="spaces"/>
-                <xsl:param name="char">
-                        <xsl:text> </xsl:text>
-                </xsl:param>
-                <xsl:if test="$spaces>0">
-                        <xsl:value-of select="$char"/>
-                        <xsl:call-template name="buildSpaces">
-                                <xsl:with-param name="spaces" select="$spaces - 1"/>
-                                <xsl:with-param name="char" select="$char"/>
-                        </xsl:call-template>
-                </xsl:if>
-        </xsl:template>
-
-        <xsl:template name="chopPunctuation">
-                <xsl:param name="chopString"/>
-                <xsl:param name="punctuation">
-                        <xsl:text>.:,;/ </xsl:text>
-                </xsl:param>
-                <xsl:variable name="length" select="string-length($chopString)"/>
-                <xsl:choose>
-                        <xsl:when test="$length=0"/>
-                        <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
-                                        <xsl:with-param name="punctuation" select="$punctuation"/>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:when test="not($chopString)"/>
-                        <xsl:otherwise>
-                                <xsl:value-of select="$chopString"/>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-
-        <xsl:template name="chopPunctuationFront">
-                <xsl:param name="chopString"/>
-                <xsl:variable name="length" select="string-length($chopString)"/>
-                <xsl:choose>
-                        <xsl:when test="$length=0"/>
-                        <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
-                                <xsl:call-template name="chopPunctuationFront">
-                                        <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
-                                        />
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:when test="not($chopString)"/>
-                        <xsl:otherwise>
-                                <xsl:value-of select="$chopString"/>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-
-        <xsl:template name="chopPunctuationBack">
-                <xsl:param name="chopString"/>
-                <xsl:param name="punctuation">
-                        <xsl:text>.:,;/] </xsl:text>
-                </xsl:param>
-                <xsl:variable name="length" select="string-length($chopString)"/>
-                <xsl:choose>
-                        <xsl:when test="$length=0"/>
-                        <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
-                                <xsl:call-template name="chopPunctuation">
-                                        <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
-                                        <xsl:with-param name="punctuation" select="$punctuation"/>
-                                </xsl:call-template>
-                        </xsl:when>
-                        <xsl:when test="not($chopString)"/>
-                        <xsl:otherwise>
-                                <xsl:value-of select="$chopString"/>
-                        </xsl:otherwise>
-                </xsl:choose>
-        </xsl:template>
-
-        <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
-        <xsl:template name="url-encode">
-
-                <xsl:param name="str"/>
-
-                <xsl:if test="$str">
-                        <xsl:variable name="first-char" select="substring($str,1,1)"/>
-                        <xsl:choose>
-                                <xsl:when test="contains($safe,$first-char)">
-                                        <xsl:value-of select="$first-char"/>
-                                </xsl:when>
-                                <xsl:otherwise>
-                                        <xsl:variable name="codepoint">
-                                                <xsl:choose>
-                                                        <xsl:when test="contains($ascii,$first-char)">
-                                                                <xsl:value-of
-                                                                        select="string-length(substring-before($ascii,$first-char)) + 32"
-                                                                />
-                                                        </xsl:when>
-                                                        <xsl:when test="contains($latin1,$first-char)">
-                                                                <xsl:value-of
-                                                                        select="string-length(substring-before($latin1,$first-char)) + 160"/>
-                                                                <!-- was 160 -->
-                                                        </xsl:when>
-                                                        <xsl:otherwise>
-                                                                <xsl:message terminate="no">Warning: string contains a character
-                                                                        that is out of range! Substituting "?".</xsl:message>
-                                                                <xsl:text>63</xsl:text>
-                                                        </xsl:otherwise>
-                                                </xsl:choose>
-                                        </xsl:variable>
-                                        <xsl:variable name="hex-digit1"
-                                                select="substring($hex,floor($codepoint div 16) + 1,1)"/>
-                                        <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
-                                        <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
-                                        <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
-                                </xsl:otherwise>
-                        </xsl:choose>
-                        <xsl:if test="string-length($str) &gt; 1">
-                                <xsl:call-template name="url-encode">
-                                        <xsl:with-param name="str" select="substring($str,2)"/>
-                                </xsl:call-template>
-                        </xsl:if>
-                </xsl:if>
-        </xsl:template>
-</xsl:stylesheet>$XXXX$ where name = $$mods33$$;
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1103', :eg_version);
-
-DO $INSERT$                                                                    
-BEGIN                                                                          
-    IF evergreen.insert_on_deploy() THEN
-
-INSERT INTO config.metabib_field (id, field_class, name, label, browse_field)
-    VALUES (45, 'keyword', 'blob', 'All searchable fields', FALSE);
-
-INSERT INTO config.metabib_field (id, field_class, name, format, weight,
-    label, xpath, display_field, search_field, browse_field, facet_field)
-VALUES (
-    53, 'title', 'maintitle', 'marcxml', 10,
-    oils_i18n_gettext(53, 'Main Title', 'cmf', 'label'),
-    $$//*[@tag='245']/*[@code='a']$$,
-    FALSE, TRUE, FALSE, FALSE
-);
-
-INSERT INTO config.metabib_field_virtual_map (real, virtual)
-    SELECT  id,
-            45
-      FROM  config.metabib_field
-      WHERE search_field
-            AND id NOT IN (15, 45, 38, 40) -- keyword|keyword, self, edition, publisher
-            AND id NOT IN (SELECT real FROM config.metabib_field_virtual_map);
-
-UPDATE config.metabib_field SET xpath=$$//mods32:mods/mods32:subject[not(descendant::mods32:geographicCode)]$$ WHERE id = 16;
-
-UPDATE config.metabib_field_virtual_map SET weight = -1 WHERE real = 39;
-UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 41;
-UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 42;
-UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 46;
-UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 47;
-UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 48;
-UPDATE config.metabib_field_virtual_map SET weight = 0 WHERE real = 50;
-UPDATE config.metabib_field_virtual_map SET weight = 8 WHERE real = 6;
-UPDATE config.metabib_field_virtual_map SET weight = 8 WHERE real = 8;
-UPDATE config.metabib_field_virtual_map SET weight = 8 WHERE real = 16;
-UPDATE config.metabib_field_virtual_map SET weight = 12 WHERE real = 53;
-
--- Stemming for genre
-INSERT INTO config.metabib_field_ts_map (metabib_field, ts_config)
-    SELECT 33, 'english_nostop' WHERE NOT EXISTS (
-        SELECT 1 FROM config.metabib_field_ts_map WHERE metabib_field = 33 AND ts_config = 'english_nostop'
-    )
-;
-
-
---SELECT evergreen.upgrade_deps_block_check('1104', :eg_version);
-
-INSERT INTO config.org_unit_setting_type
-( name, grp, label, description, datatype )
-VALUES
-       ('circ.clear_hold_on_checkout',
-        'circ',
-       oils_i18n_gettext('circ.clear_hold_on_checkout',
-               'Clear hold when other patron checks out item',
-               'coust', 'label'),
-        oils_i18n_gettext('circ.clear_hold_on_checkout',
-            'Default to cancel the hold when patron A checks out item on hold for patron B.',
-               'coust', 'description'),
-       'bool');
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1105', :eg_version);
-
-INSERT into config.org_unit_setting_type (name, label, grp, description, datatype) 
-values ('webstaff.circ.itemsout_notice_count_excludes_courtesies','Exclude Courtesy Notices from Patrons Itemsout Notices Count',
-    'circ', 'Exclude Courtesy Notices from Patron Itemsout Notices Count', 'bool');
-
-    END IF;                                                                    
-END $INSERT$;
-
-
---SELECT evergreen.upgrade_deps_block_check('1106', :eg_version);
-
-ALTER TABLE money.billing
-       ADD COLUMN create_date TIMESTAMP WITH TIME ZONE,
-       ADD COLUMN period_start    TIMESTAMP WITH TIME ZONE,
-       ADD COLUMN period_end  TIMESTAMP WITH TIME ZONE;
-
---Disable materialized update trigger
---It takes forever, and doesn't matter yet for what we are doing, as the
---view definition is unchanged (still using billing_ts)
-ALTER TABLE money.billing DISABLE TRIGGER mat_summary_upd_tgr;
-
---Limit to btype=1 / 'Overdue Materials'
---Update day-granular fines first (i.e. 24 hour, 1 day, 2 day, etc., all of which are multiples of 86400 seconds), and simply remove the time portion of timestamp
-UPDATE money.billing mb
-       SET period_start = date_trunc('day', billing_ts), period_end = date_trunc('day', billing_ts) + (ac.fine_interval - '1 second')
-       FROM action.circulation ac
-WHERE mb.xact = ac.id
-       AND mb.btype = 1
-       AND (EXTRACT(EPOCH FROM ac.fine_interval))::integer % 86400 = 0;
-
---Update fines for non-day intervals
-UPDATE money.billing mb
-       SET period_start = billing_ts - ac.fine_interval + interval '1 sec', period_end = billing_ts
-       FROM action.circulation ac
-WHERE mb.xact = ac.id
-       AND mb.btype = 1
-       AND (EXTRACT(EPOCH FROM ac.fine_interval))::integer % 86400 > 0;
-
-SET CONSTRAINTS ALL IMMEDIATE;
-UPDATE money.billing SET create_date = COALESCE(period_start, billing_ts);
-
---Re-enable update trigger
-ALTER TABLE money.billing ENABLE TRIGGER mat_summary_upd_tgr;
-
-ALTER TABLE money.billing ALTER COLUMN create_date SET DEFAULT NOW();
-ALTER TABLE money.billing ALTER COLUMN create_date SET NOT NULL;
-
-CREATE INDEX m_b_create_date_idx ON money.billing (create_date);
-CREATE INDEX m_b_period_start_idx ON money.billing (period_start);
-CREATE INDEX m_b_period_end_idx ON money.billing (period_end);
-
-CREATE OR REPLACE FUNCTION money.maintain_billing_ts () RETURNS TRIGGER AS $$
-BEGIN
-       NEW.billing_ts := COALESCE(NEW.period_end, NEW.create_date);
-       RETURN NEW;
-END;
-$$ LANGUAGE PLPGSQL;
-CREATE TRIGGER maintain_billing_ts_tgr BEFORE INSERT OR UPDATE ON money.billing FOR EACH ROW EXECUTE PROCEDURE money.maintain_billing_ts();
-
-  
---SELECT evergreen.upgrade_deps_block_check('1108', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
-DECLARE
-    moved_objects INT := 0;
-    source_cn     asset.call_number%ROWTYPE;
-    target_cn     asset.call_number%ROWTYPE;
-    metarec       metabib.metarecord%ROWTYPE;
-    hold          action.hold_request%ROWTYPE;
-    ser_rec       serial.record_entry%ROWTYPE;
-    ser_sub       serial.subscription%ROWTYPE;
-    acq_lineitem  acq.lineitem%ROWTYPE;
-    acq_request   acq.user_request%ROWTYPE;
-    booking       booking.resource_type%ROWTYPE;
-    source_part   biblio.monograph_part%ROWTYPE;
-    target_part   biblio.monograph_part%ROWTYPE;
-    multi_home    biblio.peer_bib_copy_map%ROWTYPE;
-    uri_count     INT := 0;
-    counter       INT := 0;
-    uri_datafield TEXT;
-    uri_text      TEXT := '';
-BEGIN
-
-    -- move any 856 entries on records that have at least one MARC-mapped URI entry
-    SELECT  INTO uri_count COUNT(*)
-      FROM  asset.uri_call_number_map m
-            JOIN asset.call_number cn ON (m.call_number = cn.id)
-      WHERE cn.record = source_record;
-
-    IF uri_count > 0 THEN
-        
-        -- This returns more nodes than you might expect:
-        -- 7 instead of 1 for an 856 with $u $y $9
-        SELECT  COUNT(*) INTO counter
-          FROM  oils_xpath_table(
-                    'id',
-                    'marc',
-                    'biblio.record_entry',
-                    '//*[@tag="856"]',
-                    'id=' || source_record
-                ) as t(i int,c text);
-    
-        FOR i IN 1 .. counter LOOP
-            SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
-                       ' tag="856"' ||
-                       ' ind1="' || FIRST(ind1) || '"'  ||
-                       ' ind2="' || FIRST(ind2) || '">' ||
-                        STRING_AGG(
-                            '<subfield code="' || subfield || '">' ||
-                            regexp_replace(
-                                regexp_replace(
-                                    regexp_replace(data,'&','&amp;','g'),
-                                    '>', '&gt;', 'g'
-                                ),
-                                '<', '&lt;', 'g'
-                            ) || '</subfield>', ''
-                        ) || '</datafield>' INTO uri_datafield
-              FROM  oils_xpath_table(
-                        'id',
-                        'marc',
-                        'biblio.record_entry',
-                        '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
-                        '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
-                        '//*[@tag="856"][position()=' || i || ']/*[@code]',
-                        'id=' || source_record
-                    ) as t(id int,ind1 text, ind2 text,subfield text,data text);
-
-            -- As most of the results will be NULL, protect against NULLifying
-            -- the valid content that we do generate
-            uri_text := uri_text || COALESCE(uri_datafield, '');
-        END LOOP;
-
-        IF uri_text <> '' THEN
-            UPDATE  biblio.record_entry
-              SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
-              WHERE id = target_record;
-        END IF;
-
-    END IF;
-
-       -- Find and move metarecords to the target record
-       SELECT  INTO metarec *
-         FROM  metabib.metarecord
-         WHERE master_record = source_record;
-
-       IF FOUND THEN
-               UPDATE  metabib.metarecord
-                 SET   master_record = target_record,
-                       mods = NULL
-                 WHERE id = metarec.id;
-
-               moved_objects := moved_objects + 1;
-       END IF;
-
-       -- Find call numbers attached to the source ...
-       FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
-
-               SELECT  INTO target_cn *
-                 FROM  asset.call_number
-                 WHERE label = source_cn.label
-            AND prefix = source_cn.prefix
-            AND suffix = source_cn.suffix
-                       AND owning_lib = source_cn.owning_lib
-                       AND record = target_record
-                       AND NOT deleted;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copies to that, and ...
-                       UPDATE  asset.copy
-                         SET   call_number = target_cn.id
-                         WHERE call_number = source_cn.id;
-
-                       -- ... move V holds to the move-target call number
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_cn.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-        
-            UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the call number to the target record
-                       UPDATE  asset.call_number
-                         SET   record = target_record
-                         WHERE id = source_cn.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find T holds targeting the source record ...
-       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
-
-               -- ... and move them to the target record
-               UPDATE  action.hold_request
-                 SET   target = target_record
-                 WHERE id = hold.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial records targeting the source record ...
-       FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.record_entry
-                 SET   record = target_record
-                 WHERE id = ser_rec.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find serial subscriptions targeting the source record ...
-       FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  serial.subscription
-                 SET   record_entry = target_record
-                 WHERE id = ser_sub.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find booking resource types targeting the source record ...
-       FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  booking.resource_type
-                 SET   record = target_record
-                 WHERE id = booking.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq lineitems targeting the source record ...
-       FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.lineitem
-                 SET   eg_bib_id = target_record
-                 WHERE id = acq_lineitem.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find acq user purchase requests targeting the source record ...
-       FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  acq.user_request
-                 SET   eg_bib = target_record
-                 WHERE id = acq_request.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find parts attached to the source ...
-       FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
-
-               SELECT  INTO target_part *
-                 FROM  biblio.monograph_part
-                 WHERE label = source_part.label
-                       AND record = target_record;
-
-               -- ... and if there's a conflicting one on the target ...
-               IF FOUND THEN
-
-                       -- ... move the copy-part maps to that, and ...
-                       UPDATE  asset.copy_part_map
-                         SET   part = target_part.id
-                         WHERE part = source_part.id;
-
-                       -- ... move P holds to the move-target part
-                       FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
-               
-                               UPDATE  action.hold_request
-                                 SET   target = target_part.id
-                                 WHERE id = hold.id;
-               
-                               moved_objects := moved_objects + 1;
-                       END LOOP;
-
-               -- ... if not ...
-               ELSE
-                       -- ... just move the part to the target record
-                       UPDATE  biblio.monograph_part
-                         SET   record = target_record
-                         WHERE id = source_part.id;
-               END IF;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- Find multi_home items attached to the source ...
-       FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
-               -- ... and move them to the target record
-               UPDATE  biblio.peer_bib_copy_map
-                 SET   peer_record = target_record
-                 WHERE id = multi_home.id;
-
-               moved_objects := moved_objects + 1;
-       END LOOP;
-
-       -- And delete mappings where the item's home bib was merged with the peer bib
-       DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
-               SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
-               FROM asset.copy WHERE id = target_copy
-       );
-
-    -- Apply merge tracking
-    UPDATE biblio.record_entry 
-        SET merge_date = NOW() WHERE id = target_record;
-
-    UPDATE biblio.record_entry
-        SET merge_date = NOW(), merged_to = target_record
-        WHERE id = source_record;
-
-    -- replace book bag entries of source_record with target_record
-    UPDATE container.biblio_record_entry_bucket_item
-        SET target_biblio_record_entry = target_record
-        WHERE bucket IN (SELECT id FROM container.biblio_record_entry_bucket WHERE btype = 'bookbag')
-        AND target_biblio_record_entry = source_record;
-
-    -- Finally, "delete" the source record
-    DELETE FROM biblio.record_entry WHERE id = source_record;
-
-       -- That's all, folks!
-       RETURN moved_objects;
-END;
-$func$ LANGUAGE plpgsql;
-
-
---SELECT evergreen.upgrade_deps_block_check('1109', :eg_version);
-
-DO $INSERT$                                                                    
-BEGIN                                                                          
-    IF evergreen.insert_on_deploy() THEN 
-INSERT into config.org_unit_setting_type (name, label, grp, description, datatype)
-values ('circ.staff_placed_holds_fallback_to_ws_ou','Workstation OU fallback for staff-placed holds',
-        'circ', 'For staff-placed holds, in the absence of a patron preferred pickup location, fall back to using the staff workstation OU (rather than patron home OU)', 'bool');
-    END IF;                                                                    
-END $INSERT$;     
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.2', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1110', :eg_version);
-
-DROP FUNCTION IF EXISTS unapi.biblio_record_entry_feed (BIGINT[], TEXT, TEXT[], TEXT, INT, HSTORE, HSTORE,
-                                                        BOOL, TEXT, TEXT, TEXT, TEXT, TEXT, XML);
-DROP FUNCTION IF EXISTS unapi.metabib_virtual_record_feed (BIGINT[], TEXT, TEXT[], TEXT, INT, HSTORE, HSTORE,
-                                                           BOOL, TEXT, TEXT, TEXT, TEXT, TEXT, XML);
-
-CREATE OR REPLACE FUNCTION unapi.biblio_record_entry_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit HSTORE DEFAULT NULL, soffset HSTORE DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL, pref_lib INT DEFAULT NULL ) RETURNS XML AS $F$
-DECLARE
-    layout          unapi.bre_output_layout%ROWTYPE;
-    transform       config.xml_transform%ROWTYPE;
-    item_format     TEXT;
-    tmp_xml         TEXT;
-    xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
-    ouid            INT;
-    element_list    TEXT[];
-BEGIN
-
-    IF org = '-' OR org IS NULL THEN
-        SELECT shortname INTO org FROM evergreen.org_top();
-    END IF;
-
-    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
-    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
-
-    IF layout.name IS NULL THEN
-        RETURN NULL::XML;
-    END IF;
-
-    SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
-    xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
-
-    -- Gather the bib xml
-    SELECT XMLAGG( unapi.bre(i, format, '', includes, org, depth, slimit, soffset, include_xmlns, pref_lib)) INTO tmp_xml FROM UNNEST( id_list ) i;
-
-    IF layout.title_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
-    END IF;
-
-    IF layout.description_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
-    END IF;
-
-    IF layout.creator_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
-    END IF;
-
-    IF layout.update_ts_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
-    END IF;
-
-    IF unapi_url IS NOT NULL THEN
-        EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
-    END IF;
-
-    IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
-
-    element_list := regexp_split_to_array(layout.feed_top,E'\\.');
-    FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
-        EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
-    END LOOP;
-
-    RETURN tmp_xml::XML;
-END;
-$F$ LANGUAGE PLPGSQL STABLE;
-
-CREATE OR REPLACE FUNCTION unapi.metabib_virtual_record_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit HSTORE DEFAULT NULL, soffset HSTORE DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL, pref_lib INT DEFAULT NULL ) RETURNS XML AS $F$
-DECLARE
-    layout          unapi.bre_output_layout%ROWTYPE;
-    transform       config.xml_transform%ROWTYPE;
-    item_format     TEXT;
-    tmp_xml         TEXT;
-    xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
-    ouid            INT;
-    element_list    TEXT[];
-BEGIN
-
-    IF org = '-' OR org IS NULL THEN
-        SELECT shortname INTO org FROM evergreen.org_top();
-    END IF;
-
-    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
-    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
-
-    IF layout.name IS NULL THEN
-        RETURN NULL::XML;
-    END IF;
-
-    SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
-    xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
-
-    -- Gather the bib xml
-    SELECT XMLAGG( unapi.mmr(i, format, '', includes, org, depth, slimit, soffset, include_xmlns, pref_lib)) INTO tmp_xml FROM UNNEST( id_list ) i;
-
-    IF layout.title_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
-    END IF;
-
-    IF layout.description_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
-    END IF;
-
-    IF layout.creator_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
-    END IF;
-
-    IF layout.update_ts_element IS NOT NULL THEN
-        EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
-    END IF;
-
-    IF unapi_url IS NOT NULL THEN
-        EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
-    END IF;
-
-    IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
-
-    element_list := regexp_split_to_array(layout.feed_top,E'\\.');
-    FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
-        EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
-    END LOOP;
-
-    RETURN tmp_xml::XML;
-END;
-$F$ LANGUAGE PLPGSQL STABLE;
-
-
---SELECT evergreen.upgrade_deps_block_check('1111', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN 
-INSERT INTO permission.perm_list ( id, code, description ) VALUES
- ( 594, 'ADMIN_COPY_ALERT_TYPE', oils_i18n_gettext( 594,
-    'Administer copy alert types', 'ppl', 'description' )),
- ( 595, 'CREATE_COPY_ALERT_TYPE', oils_i18n_gettext( 595,
-    'Create copy alert types', 'ppl', 'description' )),
- ( 596, 'UPDATE_COPY_ALERT_TYPE', oils_i18n_gettext( 596,
-    'Update copy alert types', 'ppl', 'description' )),
- ( 597, 'DELETE_COPY_ALERT_TYPE', oils_i18n_gettext( 597,
-    'Delete copy alert types', 'ppl', 'description' )),
- ( 598, 'ADMIN_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 598,
-    'Administer copy alert suppression', 'ppl', 'description' )),
- ( 599, 'CREATE_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 599,
-    'Create copy alert suppression', 'ppl', 'description' )),
- ( 600, 'UPDATE_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 600,
-    'Update copy alert suppression', 'ppl', 'description' )),
- ( 601, 'DELETE_COPY_ALERT_SUPPRESS', oils_i18n_gettext( 601,
-    'Delete copy alert suppression', 'ppl', 'description' )),
- ( 602, 'ADMIN_COPY_ALERT', oils_i18n_gettext( 602,
-    'Administer copy alerts', 'ppl', 'description' )),
- ( 603, 'CREATE_COPY_ALERT', oils_i18n_gettext( 603,
-    'Create copy alerts', 'ppl', 'description' )),
- ( 604, 'VIEW_COPY_ALERT', oils_i18n_gettext( 604,
-    'View copy alerts', 'ppl', 'description' )),
- ( 605, 'UPDATE_COPY_ALERT', oils_i18n_gettext( 605,
-    'Update copy alerts', 'ppl', 'description' )),
- ( 606, 'DELETE_COPY_ALERT', oils_i18n_gettext( 606,
-    'Delete copy alerts', 'ppl', 'description' ))
-;
-END IF; END $INSERT$;
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.3', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1112', :eg_version);
-
--- Add an index to action.usr_circ_history (source_circ) to speed up aging circs and purging accounts
-
-/* KCLS already has this one.
-CREATE INDEX action_usr_circ_history_source_circ_idx 
-  ON action.usr_circ_history
-  USING btree
-  (source_circ);
-  */
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.4', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1113', :eg_version); 
-
-CREATE OR REPLACE FUNCTION acq.rollover_funds_by_org_tree(
-    old_year INTEGER,
-    user_id INTEGER,
-    org_unit_id INTEGER,
-    encumb_only BOOL DEFAULT FALSE,
-    include_desc BOOL DEFAULT TRUE
-) RETURNS VOID AS $$
-DECLARE
---
-new_fund    INT;
-new_year    INT := old_year + 1;
-org_found   BOOL;
-perm_ous    BOOL;
-xfer_amount NUMERIC := 0;
-roll_fund   RECORD;
-deb         RECORD;
-detail      RECORD;
-roll_distrib_forms BOOL;
---
-BEGIN
-    --
-    -- Sanity checks
-    --
-    IF old_year IS NULL THEN
-        RAISE EXCEPTION 'Input year argument is NULL';
-    ELSIF old_year NOT BETWEEN 2008 and 2200 THEN
-        RAISE EXCEPTION 'Input year is out of range';
-    END IF;
-    --
-    IF user_id IS NULL THEN
-        RAISE EXCEPTION 'Input user id argument is NULL';
-    END IF;
-    --
-    IF org_unit_id IS NULL THEN
-        RAISE EXCEPTION 'Org unit id argument is NULL';
-    ELSE
-        --
-        -- Validate the org unit
-        --
-        SELECT TRUE
-        INTO org_found
-        FROM actor.org_unit
-        WHERE id = org_unit_id;
-        --
-        IF org_found IS NULL THEN
-            RAISE EXCEPTION 'Org unit id % is invalid', org_unit_id;
-        ELSIF encumb_only THEN
-            SELECT INTO perm_ous value::BOOL FROM
-            actor.org_unit_ancestor_setting(
-                'acq.fund.allow_rollover_without_money', org_unit_id
-            );
-            IF NOT FOUND OR NOT perm_ous THEN
-                RAISE EXCEPTION 'Encumbrance-only rollover not permitted at org %', org_unit_id;
-            END IF;
-        END IF;
-    END IF;
-    --
-    -- Loop over the propagable funds to identify the details
-    -- from the old fund plus the id of the new one, if it exists.
-    --
-    FOR roll_fund in
-    SELECT
-        oldf.id AS old_fund,
-        oldf.org,
-        oldf.name,
-        oldf.currency_type,
-        oldf.code,
-        oldf.rollover,
-        newf.id AS new_fund_id
-    FROM
-        acq.fund AS oldf
-        LEFT JOIN acq.fund AS newf
-            ON ( oldf.code = newf.code AND oldf.org = newf.org )
-    WHERE
-            oldf.year = old_year
-        AND oldf.propagate
-        AND newf.year = new_year
-        AND ( ( include_desc AND oldf.org IN ( SELECT id FROM actor.org_unit_descendants( org_unit_id ) ) )
-                OR (NOT include_desc AND oldf.org = org_unit_id ) )
-    LOOP
-        --RAISE NOTICE 'Processing fund %', roll_fund.old_fund;
-        --
-        IF roll_fund.new_fund_id IS NULL THEN
-            --
-            -- The old fund hasn't been propagated yet.  Propagate it now.
-            --
-            INSERT INTO acq.fund (
-                org,
-                name,
-                year,
-                currency_type,
-                code,
-                rollover,
-                propagate,
-                balance_warning_percent,
-                balance_stop_percent
-            ) VALUES (
-                roll_fund.org,
-                roll_fund.name,
-                new_year,
-                roll_fund.currency_type,
-                roll_fund.code,
-                true,
-                true,
-                roll_fund.balance_warning_percent,
-                roll_fund.balance_stop_percent
-            )
-            RETURNING id INTO new_fund;
-
-                PERFORM acq.copy_fund_tags(roll_fund.id,new_fund);
-
-        ELSE
-            new_fund = roll_fund.new_fund_id;
-        END IF;
-        --
-        -- Determine the amount to transfer
-        --
-        SELECT amount
-        INTO xfer_amount
-        FROM acq.fund_spent_balance
-        WHERE fund = roll_fund.old_fund;
-        --
-        IF xfer_amount <> 0 THEN
-            IF NOT encumb_only AND roll_fund.rollover THEN
-                --
-                -- Transfer balance from old fund to new
-                --
-                --RAISE NOTICE 'Transferring % from fund % to %', xfer_amount, roll_fund.old_fund, new_fund;
-                --
-                PERFORM acq.transfer_fund(
-                    roll_fund.old_fund,
-                    xfer_amount,
-                    new_fund,
-                    xfer_amount,
-                    user_id,
-                    'Rollover'
-                );
-            ELSE
-                --
-                -- Transfer balance from old fund to the void
-                --
-                -- RAISE NOTICE 'Transferring % from fund % to the void', xfer_amount, roll_fund.old_fund;
-                --
-                PERFORM acq.transfer_fund(
-                    roll_fund.old_fund,
-                    xfer_amount,
-                    NULL,
-                    NULL,
-                    user_id,
-                    'Rollover into the void'
-                );
-            END IF;
-        END IF;
-        --
-        IF roll_fund.rollover THEN
-            --
-            -- Move any lineitems from the old fund to the new one
-            -- where the associated debit is an encumbrance.
-            --
-            -- Any other tables tying expenditure details to funds should
-            -- receive similar treatment.  At this writing there are none.
-            --
-            UPDATE acq.lineitem_detail
-            SET fund = new_fund
-            WHERE
-                fund = roll_fund.old_fund -- this condition may be redundant
-                AND fund_debit in
-                (
-                    SELECT id
-                    FROM acq.fund_debit
-                    WHERE
-                        fund = roll_fund.old_fund
-                        AND encumbrance
-                );
-            --
-            -- Move encumbrance debits from the old fund to the new fund
-            --
-            UPDATE acq.fund_debit
-            SET fund = new_fund
-            wHERE
-                fund = roll_fund.old_fund
-                AND encumbrance;
-        END IF;
-
-        -- Rollover distribution formulae funds
-        SELECT INTO roll_distrib_forms value::BOOL FROM
-            actor.org_unit_ancestor_setting(
-                'acq.fund.rollover_distrib_forms', org_unit_id
-            );
-
-        IF roll_distrib_forms THEN
-            UPDATE acq.distribution_formula_entry 
-                SET fund = roll_fund.new_fund_id
-                WHERE fund = roll_fund.old_fund;
-        END IF;
-
-        --
-        -- Mark old fund as inactive, now that we've closed it
-        --
-        UPDATE acq.fund
-        SET active = FALSE
-        WHERE id = roll_fund.old_fund;
-    END LOOP;
-END;
-$$ LANGUAGE plpgsql;
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1114', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.copy_state (cid BIGINT) RETURNS TEXT AS $$
-DECLARE
-    last_circ_stop      TEXT;
-    the_copy        asset.copy%ROWTYPE;
-BEGIN
-
-    SELECT * INTO the_copy FROM asset.copy WHERE id = cid;
-    IF NOT FOUND THEN RETURN NULL; END IF;
-
-    IF the_copy.status = 3 THEN -- Lost
-        RETURN 'LOST';
-    ELSIF the_copy.status = 4 THEN -- Missing
-        RETURN 'MISSING';
-    ELSIF the_copy.status = 14 THEN -- Damaged
-        RETURN 'DAMAGED';
-    ELSIF the_copy.status = 17 THEN -- Lost and paid
-        RETURN 'LOST_AND_PAID';
-    END IF;
-
-    SELECT stop_fines INTO last_circ_stop
-      FROM  action.circulation
-      WHERE target_copy = cid AND checkin_time IS NULL
-      ORDER BY xact_start DESC LIMIT 1;
-
-    IF FOUND THEN
-        IF last_circ_stop IN (
-            'CLAIMSNEVERCHECKEDOUT',
-            'CLAIMSRETURNED',
-            'LONGOVERDUE'
-        ) THEN
-            RETURN last_circ_stop;
-        END IF;
-    END IF;
-
-    RETURN 'NORMAL';
-END;
-$$ LANGUAGE PLPGSQL;
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.5', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1119', :eg_version);
-
-CREATE OR REPLACE FUNCTION asset.staff_ou_record_copy_count(org integer, rid bigint)
- RETURNS TABLE(depth integer, org_unit integer, visible bigint, available bigint, unshadow bigint, transcendant integer)
- LANGUAGE plpgsql
-AS $function$
-DECLARE
-    ans RECORD;
-    trans INT;
-BEGIN
-    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
-
-    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
-        RETURN QUERY
-        WITH available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
-            cp AS(
-                SELECT  cp.id,
-                        (cp.status = ANY (available_statuses.ids))::INT as available,
-                        (cl.opac_visible AND cp.opac_visible)::INT as opac_visible
-                  FROM
-                        available_statuses,
-                        actor.org_unit_descendants(ans.id) d
-                        JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
-                        JOIN asset.copy_location cl ON (cp.location = cl.id AND NOT cl.deleted)
-                        JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
-            ),
-            peer AS (
-                SELECT  cp.id,
-                        (cp.status = ANY  (available_statuses.ids))::INT as available,
-                        (cl.opac_visible AND cp.opac_visible)::INT as opac_visible
-                FROM
-                        available_statuses,
-                        actor.org_unit_descendants(ans.id) d
-                        JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
-                        JOIN asset.copy_location cl ON (cp.location = cl.id AND NOT cl.deleted)
-                        JOIN biblio.peer_bib_copy_map bp ON (bp.peer_record = rid AND bp.target_copy = cp.id)
-            )
-        SELECT ans.depth, ans.id, count(id), sum(x.available::int), sum(x.opac_visible::int), trans
-        FROM ((select * from cp) union (select * from peer)) x
-        GROUP BY 1,2,6;
-
-        IF NOT FOUND THEN
-            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
-        END IF;
-
-    END LOOP;
-    RETURN;
-END;
-$function$;
-
-CREATE OR REPLACE FUNCTION asset.opac_ou_record_copy_count(org integer, rid bigint)
- RETURNS TABLE(depth integer, org_unit integer, visible bigint, available bigint, unshadow bigint, transcendant integer)
- LANGUAGE plpgsql
-AS $function$
-DECLARE
-    ans RECORD;
-    trans INT;
-BEGIN
-    SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
-
-    FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
-        RETURN QUERY
-        WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
-             available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
-             mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
-        SELECT  ans.depth,
-                ans.id,
-                COUNT( av.id ),
-                SUM( (cp.status = ANY (available_statuses.ids))::INT ),
-                COUNT( av.id ),
-                trans
-          FROM  mask,
-                available_statuses,
-                org_list,
-                asset.copy_vis_attr_cache av
-                JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
-                JOIN asset.call_number cn ON (cp.call_number = cn.id AND not cn.deleted)
-          WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
-          GROUP BY 1,2,6;
-
-        IF NOT FOUND THEN
-            RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
-        END IF;
-
-    END LOOP;
-
-    RETURN;
-END;
-$function$;
-
-
---INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.2-beta1', :eg_version);
---SELECT evergreen.upgrade_deps_block_check('1115', :eg_version);
-
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-INSERT INTO permission.perm_list (id,code,description) VALUES ( 607, 'EMERGENCY_CLOSING', 'Create and manage Emergency Closings');
-
-INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('checkout.due.emergency_closing','aecc','Circulation due date was adjusted by the Emergency Closing handler');
-INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('hold.shelf_expire.emergency_closing','aech','Hold shelf expire time was adjusted by the Emergency Closing handler');
-INSERT INTO action_trigger.hook (key,core_type,description) VALUES ('booking.due.emergency_closing','aecr','Booking reservation return date was adjusted by the Emergency Closing handler');
-END IF; END $INSERT$;
-
-CREATE TABLE action.emergency_closing (
-    id                  SERIAL      PRIMARY KEY,
-    creator             INT         NOT NULL REFERENCES actor.usr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    create_time         TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-    process_start_time  TIMESTAMPTZ,
-    process_end_time    TIMESTAMPTZ,
-    last_update_time    TIMESTAMPTZ
-);
-
-ALTER TABLE actor.org_unit_closed
-    ADD COLUMN emergency_closing INT
-        REFERENCES action.emergency_closing (id) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED;
-
-CREATE TABLE action.emergency_closing_circulation (
-    id                  BIGSERIAL   PRIMARY KEY,
-    emergency_closing   INT         NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    circulation         INT         NOT NULL REFERENCES action.circulation (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    original_due_date   TIMESTAMPTZ,
-    process_time        TIMESTAMPTZ
-);
-CREATE INDEX emergency_closing_circulation_emergency_closing_idx ON action.emergency_closing_circulation (emergency_closing);
-CREATE INDEX emergency_closing_circulation_circulation_idx ON action.emergency_closing_circulation (circulation);
-
-CREATE TABLE action.emergency_closing_reservation (
-    id                  BIGSERIAL   PRIMARY KEY,
-    emergency_closing   INT         NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    reservation         INT         NOT NULL REFERENCES booking.reservation (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    original_end_time   TIMESTAMPTZ,
-    process_time        TIMESTAMPTZ
-);
-CREATE INDEX emergency_closing_reservation_emergency_closing_idx ON action.emergency_closing_reservation (emergency_closing);
-CREATE INDEX emergency_closing_reservation_reservation_idx ON action.emergency_closing_reservation (reservation);
-
-CREATE TABLE action.emergency_closing_hold (
-    id                  BIGSERIAL   PRIMARY KEY,
-    emergency_closing   INT         NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    hold                INT         NOT NULL REFERENCES action.hold_request (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    original_shelf_expire_time   TIMESTAMPTZ,
-    process_time        TIMESTAMPTZ
-);
-CREATE INDEX emergency_closing_hold_emergency_closing_idx ON action.emergency_closing_hold (emergency_closing);
-CREATE INDEX emergency_closing_hold_hold_idx ON action.emergency_closing_hold (hold);
-
-CREATE OR REPLACE VIEW action.emergency_closing_status AS
-    SELECT  e.*,
-            COALESCE(c.count, 0) AS circulations,
-            COALESCE(c.completed, 0) AS circulations_complete,
-            COALESCE(b.count, 0) AS reservations,
-            COALESCE(b.completed, 0) AS reservations_complete,
-            COALESCE(h.count, 0) AS holds,
-            COALESCE(h.completed, 0) AS holds_complete
-      FROM  action.emergency_closing e
-            LEFT JOIN (SELECT emergency_closing, count(*) count, SUM((process_time IS NOT NULL)::INT) completed FROM action.emergency_closing_circulation GROUP BY 1) c ON (c.emergency_closing = e.id)
-            LEFT JOIN (SELECT emergency_closing, count(*) count, SUM((process_time IS NOT NULL)::INT) completed FROM action.emergency_closing_reservation GROUP BY 1) b ON (b.emergency_closing = e.id)
-            LEFT JOIN (SELECT emergency_closing, count(*) count, SUM((process_time IS NOT NULL)::INT) completed FROM action.emergency_closing_hold GROUP BY 1) h ON (h.emergency_closing = e.id)
-;
-
-CREATE OR REPLACE FUNCTION evergreen.find_next_open_time ( circ_lib INT, initial TIMESTAMPTZ, hourly BOOL DEFAULT FALSE, initial_time TIME DEFAULT NULL, dow_count INT DEFAULT 0 )
-    RETURNS TIMESTAMPTZ AS $$
-DECLARE
-    day_number      INT;
-    plus_days       INT;
-    final_time      TEXT;
-    time_adjusted   BOOL;
-    hoo_open        TIME WITHOUT TIME ZONE;
-    hoo_close       TIME WITHOUT TIME ZONE;
-    adjacent        actor.org_unit_closed%ROWTYPE;
-    breakout        INT := 0;
-BEGIN
-
-    IF dow_count > 6 THEN
-        RETURN initial;
-    END IF;
-
-    IF initial_time IS NULL THEN
-        initial_time := initial::TIME;
-    END IF;
-
-    final_time := (initial + '1 second'::INTERVAL)::TEXT;
-    LOOP
-        breakout := breakout + 1;
-
-        time_adjusted := FALSE;
-
-        IF dow_count > 0 THEN -- we're recursing, so check for HOO closing
-            day_number := EXTRACT(ISODOW FROM final_time::TIMESTAMPTZ) - 1;
-            plus_days := 0;
-            FOR i IN 1..7 LOOP
-                EXECUTE 'SELECT dow_' || day_number || '_open, dow_' || day_number || '_close FROM actor.hours_of_operation WHERE id = $1'
-                    INTO hoo_open, hoo_close
-                    USING circ_lib;
-
-                -- RAISE NOTICE 'initial time: %; dow: %; close: %',initial_time,day_number,hoo_close;
-
-                IF hoo_close = '00:00:00' THEN -- bah ... I guess we'll check the next day
-                    day_number := (day_number + 1) % 7;
-                    plus_days := plus_days + 1;
-                    time_adjusted := TRUE;
-                    CONTINUE;
-                END IF;
-
-                IF hoo_close IS NULL THEN -- no hours of operation ... assume no closing?
-                    hoo_close := '23:59:59';
-                END IF;
-
-                EXIT;
-            END LOOP;
-
-            final_time := DATE(final_time::TIMESTAMPTZ + (plus_days || ' days')::INTERVAL)::TEXT;
-            IF hoo_close <> '00:00:00' AND hourly THEN -- Not a day-granular circ
-                final_time := final_time||' '|| hoo_close;
-            ELSE
-                final_time := final_time||' 23:59:59';
-            END IF;
-        END IF;
-
-        -- Loop through other closings
-        LOOP 
-            SELECT * INTO adjacent FROM actor.org_unit_closed WHERE org_unit = circ_lib AND final_time::TIMESTAMPTZ between close_start AND close_end;
-            EXIT WHEN adjacent.id IS NULL;
-            time_adjusted := TRUE;
-            -- RAISE NOTICE 'recursing for closings with final_time: %',final_time;
-            final_time := evergreen.find_next_open_time(circ_lib, adjacent.close_end::TIMESTAMPTZ, hourly, initial_time, dow_count + 1)::TEXT;
-        END LOOP;
-
-        EXIT WHEN breakout > 100;
-        EXIT WHEN NOT time_adjusted;
-
-    END LOOP;
-
-    RETURN final_time;
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE TYPE action.emergency_closing_stage_1_count AS (circulations INT, reservations INT, holds INT);
-CREATE OR REPLACE FUNCTION action.emergency_closing_stage_1 ( e_closing INT )
-    RETURNS SETOF action.emergency_closing_stage_1_count AS $$
-DECLARE
-    tmp     INT;
-    touched action.emergency_closing_stage_1_count%ROWTYPE;
-BEGIN
-    -- First, gather circs
-    INSERT INTO action.emergency_closing_circulation (emergency_closing, circulation)
-        SELECT  e_closing,
-                circ.id
-          FROM  actor.org_unit_closed closing
-                JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
-                JOIN action.circulation circ ON (
-                    circ.circ_lib = closing.org_unit
-                    AND circ.due_date BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
-                    AND circ.xact_finish IS NULL
-                )
-          WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_circulation t WHERE t.emergency_closing = e_closing AND t.circulation = circ.id);
-
-    GET DIAGNOSTICS tmp = ROW_COUNT;
-    touched.circulations := tmp;
-
-    INSERT INTO action.emergency_closing_reservation (emergency_closing, reservation)
-        SELECT  e_closing,
-                res.id
-          FROM  actor.org_unit_closed closing
-                JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
-                JOIN booking.reservation res ON (
-                    res.pickup_lib = closing.org_unit
-                    AND res.end_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
-                )
-          WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_reservation t WHERE t.emergency_closing = e_closing AND t.reservation = res.id);
-
-    GET DIAGNOSTICS tmp = ROW_COUNT;
-    touched.reservations := tmp;
-
-    INSERT INTO action.emergency_closing_hold (emergency_closing, hold)
-        SELECT  e_closing,
-                hold.id
-          FROM  actor.org_unit_closed closing
-                JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
-                JOIN action.hold_request hold ON (
-                    pickup_lib = closing.org_unit
-                    AND hold.shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
-                    AND hold.fulfillment_time IS NULL
-                    AND hold.cancel_time IS NULL
-                )
-          WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_hold t WHERE t.emergency_closing = e_closing AND t.hold = hold.id);
-
-    GET DIAGNOSTICS tmp = ROW_COUNT;
-    touched.holds := tmp;
-
-    UPDATE  action.emergency_closing
-      SET   process_start_time = NOW(),
-            last_update_time = NOW()
-      WHERE id = e_closing;
-
-    RETURN NEXT touched;
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_hold ( hold_closing_entry INT )
-    RETURNS BOOL AS $$
-DECLARE
-    hold        action.hold_request%ROWTYPE;
-    e_closing   action.emergency_closing%ROWTYPE;
-    e_c_hold    action.emergency_closing_hold%ROWTYPE;
-    closing     actor.org_unit_closed%ROWTYPE;
-    day_number  INT;
-    hoo_close   TIME WITHOUT TIME ZONE;
-    plus_days   INT;
-BEGIN
-    -- Gather objects involved
-    SELECT  * INTO e_c_hold
-      FROM  action.emergency_closing_hold
-      WHERE id = hold_closing_entry;
-
-    IF e_c_hold.process_time IS NOT NULL THEN
-        -- Already processed ... moving on
-        RETURN FALSE;
-    END IF;
-
-    SELECT  * INTO e_closing
-      FROM  action.emergency_closing
-      WHERE id = e_c_hold.emergency_closing;
-
-    IF e_closing.process_start_time IS NULL THEN
-        -- Huh... that's odd. And wrong.
-        RETURN FALSE;
-    END IF;
-
-    SELECT  * INTO closing
-      FROM  actor.org_unit_closed
-      WHERE emergency_closing = e_closing.id;
-
-    SELECT  * INTO hold
-      FROM  action.hold_request h
-      WHERE id = e_c_hold.hold;
-
-    -- Record the processing
-    UPDATE  action.emergency_closing_hold
-      SET   original_shelf_expire_time = hold.shelf_expire_time,
-            process_time = NOW()
-      WHERE id = hold_closing_entry;
-
-    UPDATE  action.emergency_closing
-      SET   last_update_time = NOW()
-      WHERE id = e_closing.id;
-
-    UPDATE  action.hold_request
-      SET   shelf_expire_time = evergreen.find_next_open_time(closing.org_unit, hold.shelf_expire_time, TRUE)
-      WHERE id = hold.id;
-
-    RETURN TRUE;
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_circ ( circ_closing_entry INT )
-    RETURNS BOOL AS $$
-DECLARE
-    circ            action.circulation%ROWTYPE;
-    e_closing       action.emergency_closing%ROWTYPE;
-    e_c_circ        action.emergency_closing_circulation%ROWTYPE;
-    closing         actor.org_unit_closed%ROWTYPE;
-    adjacent        actor.org_unit_closed%ROWTYPE;
-    bill            money.billing%ROWTYPE;
-    last_bill       money.billing%ROWTYPE;
-    day_number      INT;
-    hoo_close       TIME WITHOUT TIME ZONE;
-    plus_days       INT;
-    avoid_negative  BOOL;
-    extend_grace    BOOL;
-    new_due_date    TEXT;
-BEGIN
-    -- Gather objects involved
-    SELECT  * INTO e_c_circ
-      FROM  action.emergency_closing_circulation
-      WHERE id = circ_closing_entry;
-
-    IF e_c_circ.process_time IS NOT NULL THEN
-        -- Already processed ... moving on
-        RETURN FALSE;
-    END IF;
-
-    SELECT  * INTO e_closing
-      FROM  action.emergency_closing
-      WHERE id = e_c_circ.emergency_closing;
-
-    IF e_closing.process_start_time IS NULL THEN
-        -- Huh... that's odd. And wrong.
-        RETURN FALSE;
-    END IF;
-
-    SELECT  * INTO closing
-      FROM  actor.org_unit_closed
-      WHERE emergency_closing = e_closing.id;
-
-    SELECT  * INTO circ
-      FROM  action.circulation
-      WHERE id = e_c_circ.circulation;
-
-    -- Record the processing
-    UPDATE  action.emergency_closing_circulation
-      SET   original_due_date = circ.due_date,
-            process_time = NOW()
-      WHERE id = circ_closing_entry;
-
-    UPDATE  action.emergency_closing
-      SET   last_update_time = NOW()
-      WHERE id = e_closing.id;
-
-    SELECT value::BOOL INTO avoid_negative FROM actor.org_unit_ancestor_setting('bill.prohibit_negative_balance_on_overdues', circ.circ_lib);
-    SELECT value::BOOL INTO extend_grace FROM actor.org_unit_ancestor_setting('circ.grace.extend', circ.circ_lib);
-
-    new_due_date := evergreen.find_next_open_time( closing.org_unit, circ.due_date, EXTRACT(EPOCH FROM circ.duration)::INT % 86400 > 0 )::TEXT;
-    UPDATE action.circulation SET due_date = new_due_date::TIMESTAMPTZ WHERE id = circ.id;
-
-    -- Now, see if we need to get rid of some fines
-    SELECT  * INTO last_bill
-      FROM  money.billing b
-      WHERE b.xact = circ.id
-            AND NOT b.voided
-            AND b.btype = 1
-      ORDER BY billing_ts DESC
-      LIMIT 1;
-
-    FOR bill IN
-        SELECT  *
-          FROM  money.billing b
-          WHERE b.xact = circ.id
-                AND b.btype = 1
-                AND NOT b.voided
-                AND (
-                    b.billing_ts BETWEEN closing.close_start AND new_due_date::TIMESTAMPTZ
-                    OR (extend_grace AND last_bill.billing_ts <= new_due_date::TIMESTAMPTZ + circ.grace_period)
-                )
-                AND NOT EXISTS (SELECT 1 FROM money.account_adjustment a WHERE a.billing = b.id)
-          ORDER BY billing_ts
-    LOOP
-        IF avoid_negative THEN
-            PERFORM FROM money.materialized_billable_xact_summary WHERE id = circ.id AND balanced_owd < bill.amount;
-            EXIT WHEN FOUND; -- We can't go negative, and voiding this bill would do that...
-        END IF;
-
-        UPDATE  money.billing
-          SET   voided = TRUE,
-                void_time = NOW(),
-                note = COALESCE(note,'') || ' :: Voided by emergency closing handler'
-          WHERE id = bill.id;
-    END LOOP;
-    
-    RETURN TRUE;
-END;
-$$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_reservation ( res_closing_entry INT )
-    RETURNS BOOL AS $$
-DECLARE
-    res             booking.reservation%ROWTYPE;
-    e_closing       action.emergency_closing%ROWTYPE;
-    e_c_res         action.emergency_closing_reservation%ROWTYPE;
-    closing         actor.org_unit_closed%ROWTYPE;
-    adjacent        actor.org_unit_closed%ROWTYPE;
-    bill            money.billing%ROWTYPE;
-    day_number      INT;
-    hoo_close       TIME WITHOUT TIME ZONE;
-    plus_days       INT;
-    avoid_negative  BOOL;
-    new_due_date    TEXT;
-BEGIN
-    -- Gather objects involved
-    SELECT  * INTO e_c_res
-      FROM  action.emergency_closing_reservation
-      WHERE id = res_closing_entry;
-
-    IF e_c_res.process_time IS NOT NULL THEN
-        -- Already processed ... moving on
-        RETURN FALSE;
-    END IF;
-
-    SELECT  * INTO e_closing
-      FROM  action.emergency_closing
-      WHERE id = e_c_res.emergency_closing;
-
-    IF e_closing.process_start_time IS NULL THEN
-        -- Huh... that's odd. And wrong.
-        RETURN FALSE;
-    END IF;
-
-    SELECT  * INTO closing
-      FROM  actor.org_unit_closed
-      WHERE emergency_closing = e_closing.id;
-
-    SELECT  * INTO res
-      FROM  booking.reservation
-      WHERE id = e_c_res.reservation;
-
-    IF res.pickup_lib IS NULL THEN -- Need to be far enough along to have a pickup lib
-        RETURN FALSE;
-    END IF;
-
-    -- Record the processing
-    UPDATE  action.emergency_closing_reservation
-      SET   original_end_time = res.end_time,
-            process_time = NOW()
-      WHERE id = res_closing_entry;
-
-    UPDATE  action.emergency_closing
-      SET   last_update_time = NOW()
-      WHERE id = e_closing.id;
-
-    SELECT value::BOOL INTO avoid_negative FROM actor.org_unit_ancestor_setting('bill.prohibit_negative_balance_on_overdues', res.pickup_lib);
-
-    new_due_date := evergreen.find_next_open_time( closing.org_unit, res.end_time, EXTRACT(EPOCH FROM res.booking_interval)::INT % 86400 > 0 )::TEXT;
-    UPDATE booking.reservation SET end_time = new_due_date::TIMESTAMPTZ WHERE id = res.id;
-
-    -- Now, see if we need to get rid of some fines
-    FOR bill IN
-        SELECT  *
-          FROM  money.billing b
-          WHERE b.xact = res.id
-                AND b.btype = 1
-                AND NOT b.voided
-                AND b.billing_ts BETWEEN closing.close_start AND new_due_date::TIMESTAMPTZ
-                AND NOT EXISTS (SELECT 1 FROM money.account_adjustment a WHERE a.billing = b.id)
-    LOOP
-        IF avoid_negative THEN
-            PERFORM FROM money.materialized_billable_xact_summary WHERE id = res.id AND balanced_owd < bill.amount;
-            EXIT WHEN FOUND; -- We can't go negative, and voiding this bill would do that...
-        END IF;
-
-        UPDATE  money.billing
-          SET   voided = TRUE,
-                void_time = NOW(),
-                note = COALESCE(note,'') || ' :: Voided by emergency closing handler'
-          WHERE id = bill.id;
-    END LOOP;
-    
-    RETURN TRUE;
-END;
-$$ LANGUAGE PLPGSQL;
-
-
-
-CREATE TYPE actor.cascade_setting_summary AS (
-    name TEXT,
-    value JSON,
-    has_org_setting BOOLEAN,
-    has_user_setting BOOLEAN,
-    has_workstation_setting BOOLEAN
-);
-
---SELECT evergreen.upgrade_deps_block_check('1116', :eg_version);
-
-CREATE TABLE config.workstation_setting_type (
-    name            TEXT    PRIMARY KEY,
-    label           TEXT    UNIQUE NOT NULL,
-    grp             TEXT    REFERENCES config.settings_group (name),
-    description     TEXT,
-    datatype        TEXT    NOT NULL DEFAULT 'string',
-    fm_class        TEXT,
-    --
-    -- define valid datatypes
-    --
-    CONSTRAINT cwst_valid_datatype CHECK ( datatype IN
-    ( 'bool', 'integer', 'float', 'currency', 'interval',
-      'date', 'string', 'object', 'array', 'link' ) ),
-    --
-    -- fm_class is meaningful only for 'link' datatype
-    --
-    CONSTRAINT cwst_no_empty_link CHECK
-    ( ( datatype =  'link' AND fm_class IS NOT NULL ) OR
-      ( datatype <> 'link' AND fm_class IS NULL ) )
-);
-
-CREATE TABLE actor.workstation_setting (
-    id          SERIAL PRIMARY KEY,
-    workstation INT    NOT NULL REFERENCES actor.workstation (id) 
-                       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    name        TEXT   NOT NULL REFERENCES config.workstation_setting_type (name) 
-                       ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
-    value       JSON   NOT NULL
-);
-
-
-CREATE INDEX actor_workstation_setting_workstation_idx 
-    ON actor.workstation_setting (workstation);
-
-CREATE OR REPLACE FUNCTION config.setting_is_user_or_ws()
-RETURNS TRIGGER AS $FUNC$
-BEGIN
-
-    IF TG_TABLE_NAME = 'usr_setting_type' THEN
-        PERFORM TRUE FROM config.workstation_setting_type cwst
-            WHERE cwst.name = NEW.name;
-        IF NOT FOUND THEN
-            RETURN NULL;
-        END IF;
-    END IF;
-
-    IF TG_TABLE_NAME = 'workstation_setting_type' THEN
-        PERFORM TRUE FROM config.usr_setting_type cust
-            WHERE cust.name = NEW.name;
-        IF NOT FOUND THEN
-            RETURN NULL;
-        END IF;
-    END IF;
-
-    RAISE EXCEPTION 
-        '% Cannot be used as both a user setting and a workstation setting.', 
-        NEW.name;
-END;
-$FUNC$ LANGUAGE PLPGSQL STABLE;
-
-CREATE CONSTRAINT TRIGGER check_setting_is_usr_or_ws
-  AFTER INSERT OR UPDATE ON config.usr_setting_type
-  FOR EACH ROW EXECUTE PROCEDURE config.setting_is_user_or_ws();
-
-CREATE CONSTRAINT TRIGGER check_setting_is_usr_or_ws
-  AFTER INSERT OR UPDATE ON config.workstation_setting_type
-  FOR EACH ROW EXECUTE PROCEDURE config.setting_is_user_or_ws();
-
-CREATE OR REPLACE FUNCTION actor.get_cascade_setting(
-    setting_name TEXT, org_id INT, user_id INT, workstation_id INT) 
-    RETURNS actor.cascade_setting_summary AS
-$FUNC$
-DECLARE
-    setting_value JSON;
-    summary actor.cascade_setting_summary;
-    org_setting_type config.org_unit_setting_type%ROWTYPE;
-BEGIN
-
-    summary.name := setting_name;
-
-    -- Collect the org setting type status first in case we exit early.
-    -- The existance of an org setting type is not considered
-    -- privileged information.
-    SELECT INTO org_setting_type * 
-        FROM config.org_unit_setting_type WHERE name = setting_name;
-    IF FOUND THEN
-        summary.has_org_setting := TRUE;
-    ELSE
-        summary.has_org_setting := FALSE;
-    END IF;
-
-    -- User and workstation settings have the same priority.
-    -- Start with user settings since that's the simplest code path.
-    -- The workstation_id is ignored if no user_id is provided.
-    IF user_id IS NOT NULL THEN
-
-        SELECT INTO summary.value value FROM actor.usr_setting
-            WHERE usr = user_id AND name = setting_name;
-
-        IF FOUND THEN
-            -- if we have a value, we have a setting type
-            summary.has_user_setting := TRUE;
-
-            IF workstation_id IS NOT NULL THEN
-                -- Only inform the caller about the workstation
-                -- setting type disposition when a workstation id is
-                -- provided.  Otherwise, it's NULL to indicate UNKNOWN.
-                summary.has_workstation_setting := FALSE;
-            END IF;
-
-            RETURN summary;
-        END IF;
-
-        -- no user setting value, but a setting type may exist
-        SELECT INTO summary.has_user_setting EXISTS (
-            SELECT TRUE FROM config.usr_setting_type 
-            WHERE name = setting_name
-        );
-
-        IF workstation_id IS NOT NULL THEN 
-
-            IF NOT summary.has_user_setting THEN
-                -- A workstation setting type may only exist when a user
-                -- setting type does not.
-
-                SELECT INTO summary.value value 
-                    FROM actor.workstation_setting         
-                    WHERE workstation = workstation_id AND name = setting_name;
-
-                IF FOUND THEN
-                    -- if we have a value, we have a setting type
-                    summary.has_workstation_setting := TRUE;
-                    RETURN summary;
-                END IF;
-
-                -- no value, but a setting type may exist
-                SELECT INTO summary.has_workstation_setting EXISTS (
-                    SELECT TRUE FROM config.workstation_setting_type 
-                    WHERE name = setting_name
-                );
-            END IF;
-
-            -- Finally make use of the workstation to determine the org
-            -- unit if none is provided.
-            IF org_id IS NULL AND summary.has_org_setting THEN
-                SELECT INTO org_id owning_lib 
-                    FROM actor.workstation WHERE id = workstation_id;
-            END IF;
-        END IF;
-    END IF;
-
-    -- Some org unit settings are protected by a view permission.
-    -- First see if we have any data that needs protecting, then 
-    -- check the permission if needed.
-
-    IF NOT summary.has_org_setting THEN
-        RETURN summary;
-    END IF;
-
-    -- avoid putting the value into the summary until we confirm
-    -- the value should be visible to the caller.
-    SELECT INTO setting_value value 
-        FROM actor.org_unit_ancestor_setting(setting_name, org_id);
-
-    IF NOT FOUND THEN
-        -- No value found -- perm check is irrelevant.
-        RETURN summary;
-    END IF;
-
-    IF org_setting_type.view_perm IS NOT NULL THEN
-
-        IF user_id IS NULL THEN
-            RAISE NOTICE 'Perm check required but no user_id provided';
-            RETURN summary;
-        END IF;
-
-        IF NOT permission.usr_has_perm(
-            user_id, (SELECT code FROM permission.perm_list 
-                WHERE id = org_setting_type.view_perm), org_id) 
-        THEN
-            RAISE NOTICE 'Perm check failed for user % on %',
-                user_id, org_setting_type.view_perm;
-            RETURN summary;
-        END IF;
-    END IF;
-
-    -- Perm check succeeded or was not necessary.
-    summary.value := setting_value;
-    RETURN summary;
-END;
-$FUNC$ LANGUAGE PLPGSQL;
-
-
-CREATE OR REPLACE FUNCTION actor.get_cascade_setting_batch(
-    setting_names TEXT[], org_id INT, user_id INT, workstation_id INT) 
-    RETURNS SETOF actor.cascade_setting_summary AS
-$FUNC$
--- Returns a row per setting matching the setting name order.  If no 
--- value is applied, NULL is returned to retain name-response ordering.
-DECLARE
-    setting_name TEXT;
-    summary actor.cascade_setting_summary;
-BEGIN
-    FOREACH setting_name IN ARRAY setting_names LOOP
-        SELECT INTO summary * FROM actor.get_cascade_setting(
-            setting_Name, org_id, user_id, workstation_id);
-        RETURN NEXT summary;
-    END LOOP;
-END;
-$FUNC$ LANGUAGE PLPGSQL;
-
-
-
-
-
---SELECT evergreen.upgrade_deps_block_check('1117', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-
-INSERT INTO permission.perm_list (id, code, description) VALUES
- (608, 'APPLY_WORKSTATION_SETTING',
-   oils_i18n_gettext(608, 'APPLY_WORKSTATION_SETTING', 'ppl', 'description'));
-
-INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
-VALUES (
-    'eg.circ.checkin.no_precat_alert', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.no_precat_alert',
-        'Checkin: Ignore Precataloged Items',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.noop', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.noop',
-        'Checkin: Suppress Holds and Transits',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.void_overdues', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.void_overdues',
-        'Checkin: Amnesty Mode',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.auto_print_holds_transits', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.auto_print_holds_transits',
-        'Checkin: Auto-Print Holds and Transits',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.clear_expired', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.clear_expired',
-        'Checkin: Clear Holds Shelf',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.retarget_holds', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.retarget_holds',
-        'Checkin: Retarget Local Holds',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.retarget_holds_all', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.retarget_holds_all',
-        'Checkin: Retarget All Statuses',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.hold_as_transit', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.hold_as_transit',
-        'Checkin: Capture Local Holds as Transits',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.checkin.manual_float', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.checkin.manual_float',
-        'Checkin: Manual Floating Active',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.patron.summary.collapse', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.patron.summary.collapse',
-        'Collaps Patron Summary Display',
-        'cwst', 'label'
-    )
-), (
-    'circ.bills.receiptonpay', 'circ', 'bool',
-    oils_i18n_gettext(
-        'circ.bills.receiptonpay',
-        'Print Receipt On Payment',
-        'cwst', 'label'
-    )
-), (
-    'circ.renew.strict_barcode', 'circ', 'bool',
-    oils_i18n_gettext(
-        'circ.renew.strict_barcode',
-        'Renew: Strict Barcode',
-        'cwst', 'label'
-    )
-), (
-    'circ.checkin.strict_barcode', 'circ', 'bool',
-    oils_i18n_gettext(
-        'circ.checkin.strict_barcode',
-        'Checkin: Strict Barcode',
-        'cwst', 'label'
-    )
-), (
-    'circ.checkout.strict_barcode', 'circ', 'bool',
-    oils_i18n_gettext(
-        'circ.checkout.strict_barcode',
-        'Checkout: Strict Barcode',
-        'cwst', 'label'
-    )
-), (
-    'cat.holdings_show_copies', 'cat', 'bool',
-    oils_i18n_gettext(
-        'cat.holdings_show_copies',
-        'Holdings View Show Copies',
-        'cwst', 'label'
-    )
-), (
-    'cat.holdings_show_empty', 'cat', 'bool',
-    oils_i18n_gettext(
-        'cat.holdings_show_empty',
-        'Holdings View Show Empty Volumes',
-        'cwst', 'label'
-    )
-), (
-    'cat.holdings_show_empty_org', 'cat', 'bool',
-    oils_i18n_gettext(
-        'cat.holdings_show_empty_org',
-        'Holdings View Show Empty Orgs',
-        'cwst', 'label'
-    )
-), (
-    'cat.holdings_show_vols', 'cat', 'bool',
-    oils_i18n_gettext(
-        'cat.holdings_show_vols',
-        'Holdings View Show Volumes',
-        'cwst', 'label'
-    )
-), (
-    'cat.copy.defaults', 'cat', 'object',
-    oils_i18n_gettext(
-        'cat.copy.defaults',
-        'Copy Edit Default Values',
-        'cwst', 'label'
-    )
-), (
-    'cat.printlabels.default_template', 'cat', 'string',
-    oils_i18n_gettext(
-        'cat.printlabels.default_template',
-        'Print Label Default Template',
-        'cwst', 'label'
-    )
-), (
-    'cat.printlabels.templates', 'cat', 'object',
-    oils_i18n_gettext(
-        'cat.printlabels.templates',
-        'Print Label Templates',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.patron.search.include_inactive', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.patron.search.include_inactive',
-        'Patron Search Include Inactive',
-        'cwst', 'label'
-    )
-), (
-    'eg.circ.patron.search.show_extras', 'circ', 'bool',
-    oils_i18n_gettext(
-        'eg.circ.patron.search.show_extras',
-        'Patron Search Show Extra Search Options',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.checkin.checkin', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.checkin.checkin',
-        'Grid Config: circ.checkin.checkin',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.checkin.capture', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.checkin.capture',
-        'Grid Config: circ.checkin.capture',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.server.config.copy_tag_type', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.server.config.copy_tag_type',
-        'Grid Config: admin.server.config.copy_tag_type',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.server.config.metabib_field_virtual_map.grid', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.server.config.metabib_field_virtual_map.grid',
-        'Grid Config: admin.server.config.metabib_field_virtual_map.grid',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.server.config.metabib_field.grid', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.server.config.metabib_field.grid',
-        'Grid Config: admin.server.config.metabib_field.grid',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.server.config.marc_field', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.server.config.marc_field',
-        'Grid Config: admin.server.config.marc_field',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.server.asset.copy_tag', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.server.asset.copy_tag',
-        'Grid Config: admin.server.asset.copy_tag',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.local.circ.neg_balance_users', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.local.circ.neg_balance_users',
-        'Grid Config: admin.local.circ.neg_balance_users',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.local.rating.badge', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.local.rating.badge',
-        'Grid Config: admin.local.rating.badge',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.workstation.work_log', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.workstation.work_log',
-        'Grid Config: admin.workstation.work_log',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.workstation.patron_log', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.workstation.patron_log',
-        'Grid Config: admin.workstation.patron_log',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.serials.pattern_template', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.admin.serials.pattern_template',
-        'Grid Config: admin.serials.pattern_template',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.serials.copy_templates', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.serials.copy_templates',
-        'Grid Config: serials.copy_templates',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.record_overlay.holdings', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.record_overlay.holdings',
-        'Grid Config: cat.record_overlay.holdings',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.bucket.record.search', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.bucket.record.search',
-        'Grid Config: cat.bucket.record.search',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.bucket.record.view', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.bucket.record.view',
-        'Grid Config: cat.bucket.record.view',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.bucket.record.pending', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.bucket.record.pending',
-        'Grid Config: cat.bucket.record.pending',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.bucket.copy.view', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.bucket.copy.view',
-        'Grid Config: cat.bucket.copy.view',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.bucket.copy.pending', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.bucket.copy.pending',
-        'Grid Config: cat.bucket.copy.pending',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.items', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.items',
-        'Grid Config: cat.items',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.volcopy.copies', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.volcopy.copies',
-        'Grid Config: cat.volcopy.copies',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.volcopy.copies.complete', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.volcopy.copies.complete',
-        'Grid Config: cat.volcopy.copies.complete',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.peer_bibs', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.peer_bibs',
-        'Grid Config: cat.peer_bibs',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.catalog.holds', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.catalog.holds',
-        'Grid Config: cat.catalog.holds',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.holdings', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.holdings',
-        'Grid Config: cat.holdings',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.z3950_results', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.z3950_results',
-        'Grid Config: cat.z3950_results',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.holds.shelf', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.holds.shelf',
-        'Grid Config: circ.holds.shelf',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.holds.pull', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.holds.pull',
-        'Grid Config: circ.holds.pull',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.in_house_use', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.in_house_use',
-        'Grid Config: circ.in_house_use',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.renew', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.renew',
-        'Grid Config: circ.renew',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.transits.list', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.transits.list',
-        'Grid Config: circ.transits.list',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.holds', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.holds',
-        'Grid Config: circ.patron.holds',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.pending_patrons.list', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.pending_patrons.list',
-        'Grid Config: circ.pending_patrons.list',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.items_out.noncat', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.items_out.noncat',
-        'Grid Config: circ.patron.items_out.noncat',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.items_out', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.items_out',
-        'Grid Config: circ.patron.items_out',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.billhistory_payments', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.billhistory_payments',
-        'Grid Config: circ.patron.billhistory_payments',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.user.bucket.view', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.user.bucket.view',
-        'Grid Config: user.bucket.view',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.user.bucket.pending', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.user.bucket.pending',
-        'Grid Config: user.bucket.pending',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.staff_messages', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.staff_messages',
-        'Grid Config: circ.patron.staff_messages',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.archived_messages', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.archived_messages',
-        'Grid Config: circ.patron.archived_messages',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.bills', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.bills',
-        'Grid Config: circ.patron.bills',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.checkout', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.checkout',
-        'Grid Config: circ.patron.checkout',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.serials.mfhd_grid', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.serials.mfhd_grid',
-        'Grid Config: serials.mfhd_grid',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.serials.view_item_grid', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.serials.view_item_grid',
-        'Grid Config: serials.view_item_grid',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.serials.dist_stream_grid', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.serials.dist_stream_grid',
-        'Grid Config: serials.dist_stream_grid',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.circ.patron.search', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.circ.patron.search',
-        'Grid Config: circ.patron.search',
-        'cwst', 'label'
-    )
-), (
-    'eg.cat.record.summary.collapse', 'gui', 'bool',
-    oils_i18n_gettext(
-        'eg.cat.record.summary.collapse',
-        'Collapse Bib Record Summary',
-        'cwst', 'label'
-    )
-), (
-    'cat.marcedit.flateditor', 'gui', 'bool',
-    oils_i18n_gettext(
-        'cat.marcedit.flateditor',
-        'Use Flat MARC Editor',
-        'cwst', 'label'
-    )
-), (
-    'cat.marcedit.stack_subfields', 'gui', 'bool',
-    oils_i18n_gettext(
-        'cat.marcedit.stack_subfields',
-        'MARC Editor Stack Subfields',
-        'cwst', 'label'
-    )
-), (
-    'eg.offline.print_receipt', 'gui', 'bool',
-    oils_i18n_gettext(
-        'eg.offline.print_receipt',
-        'Offline Print Receipt',
-        'cwst', 'label'
-    )
-), (
-    'eg.offline.strict_barcode', 'gui', 'bool',
-    oils_i18n_gettext(
-        'eg.offline.strict_barcode',
-        'Offline Use Strict Barcode',
-        'cwst', 'label'
-    )
-), (
-    'cat.default_bib_marc_template', 'gui', 'string',
-    oils_i18n_gettext(
-        'cat.default_bib_marc_template',
-        'Default MARC Template',
-        'cwst', 'label'
-    )
-), (
-    'eg.audio.disable', 'gui', 'bool',
-    oils_i18n_gettext(
-        'eg.audio.disable',
-        'Disable Staff Client Notification Audio',
-        'cwst', 'label'
-    )
-), (
-    'eg.search.adv_pane', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.search.adv_pane',
-        'Catalog Advanced Search Default Pane',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.bills_current', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.bills_current',
-        'Print Template Context: bills_current',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.bills_current', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.bills_current',
-        'Print Template: bills_current',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.bills_historical', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.bills_historical',
-        'Print Template Context: bills_historical',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.bills_historical', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.bills_historical',
-        'Print Template: bills_historical',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.bill_payment', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.bill_payment',
-        'Print Template Context: bill_payment',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.bill_payment', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.bill_payment',
-        'Print Template: bill_payment',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.checkin', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.checkin',
-        'Print Template Context: checkin',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.checkin', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.checkin',
-        'Print Template: checkin',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.checkout', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.checkout',
-        'Print Template Context: checkout',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.checkout', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.checkout',
-        'Print Template: checkout',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.hold_transit_slip', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.hold_transit_slip',
-        'Print Template Context: hold_transit_slip',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.hold_transit_slip', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.hold_transit_slip',
-        'Print Template: hold_transit_slip',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.hold_shelf_slip', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.hold_shelf_slip',
-        'Print Template Context: hold_shelf_slip',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.hold_shelf_slip', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.hold_shelf_slip',
-        'Print Template: hold_shelf_slip',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.holds_for_bib', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.holds_for_bib',
-        'Print Template Context: holds_for_bib',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.holds_for_bib', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.holds_for_bib',
-        'Print Template: holds_for_bib',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.holds_for_patron', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.holds_for_patron',
-        'Print Template Context: holds_for_patron',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.holds_for_patron', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.holds_for_patron',
-        'Print Template: holds_for_patron',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.hold_pull_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.hold_pull_list',
-        'Print Template Context: hold_pull_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.hold_pull_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.hold_pull_list',
-        'Print Template: hold_pull_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.hold_shelf_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.hold_shelf_list',
-        'Print Template Context: hold_shelf_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.hold_shelf_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.hold_shelf_list',
-        'Print Template: hold_shelf_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.in_house_use_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.in_house_use_list',
-        'Print Template Context: in_house_use_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.in_house_use_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.in_house_use_list',
-        'Print Template: in_house_use_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.item_status', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.item_status',
-        'Print Template Context: item_status',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.item_status', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.item_status',
-        'Print Template: item_status',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.items_out', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.items_out',
-        'Print Template Context: items_out',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.items_out', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.items_out',
-        'Print Template: items_out',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.patron_address', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.patron_address',
-        'Print Template Context: patron_address',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.patron_address', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.patron_address',
-        'Print Template: patron_address',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.patron_data', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.patron_data',
-        'Print Template Context: patron_data',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.patron_data', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.patron_data',
-        'Print Template: patron_data',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.patron_note', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.patron_note',
-        'Print Template Context: patron_note',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.patron_note', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.patron_note',
-        'Print Template: patron_note',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.renew', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.renew',
-        'Print Template Context: renew',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.renew', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.renew',
-        'Print Template: renew',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.transit_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.transit_list',
-        'Print Template Context: transit_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.transit_list', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.transit_list',
-        'Print Template: transit_list',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.transit_slip', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.transit_slip',
-        'Print Template Context: transit_slip',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.transit_slip', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.transit_slip',
-        'Print Template: transit_slip',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.offline_checkout', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.offline_checkout',
-        'Print Template Context: offline_checkout',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.offline_checkout', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.offline_checkout',
-        'Print Template: offline_checkout',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.offline_renew', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.offline_renew',
-        'Print Template Context: offline_renew',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.offline_renew', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.offline_renew',
-        'Print Template: offline_renew',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.offline_checkin', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.offline_checkin',
-        'Print Template Context: offline_checkin',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.offline_checkin', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.offline_checkin',
-        'Print Template: offline_checkin',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template_context.offline_in_house_use', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template_context.offline_in_house_use',
-        'Print Template Context: offline_in_house_use',
-        'cwst', 'label'
-    )
-), (
-    'eg.print.template.offline_in_house_use', 'gui', 'string',
-    oils_i18n_gettext(
-        'eg.print.template.offline_in_house_use',
-        'Print Template: offline_in_house_use',
-        'cwst', 'label'
-    )
-), (
-    'eg.serials.stream_names', 'gui', 'array',
-    oils_i18n_gettext(
-        'eg.serials.stream_names',
-        'Serials Local Stream Names',
-        'cwst', 'label'
-    )
-), (
-    'eg.serials.items.do_print_routing_lists', 'gui', 'bool',
-    oils_i18n_gettext(
-        'eg.serials.items.do_print_routing_lists',
-        'Serials Print Routing Lists',
-        'cwst', 'label'
-    )
-), (
-    'eg.serials.items.receive_and_barcode', 'gui', 'bool',
-    oils_i18n_gettext(
-        'eg.serials.items.receive_and_barcode',
-        'Serials Barcode On Receive',
-        'cwst', 'label'
-    )
-);
-
-
--- More values with fm_class'es
-INSERT INTO config.workstation_setting_type (name, grp, datatype, fm_class, label)
-VALUES (
-    'eg.search.search_lib', 'gui', 'link', 'aou',
-    oils_i18n_gettext(
-        'eg.search.search_lib',
-        'Staff Catalog Default Search Library',
-        'cwst', 'label'
-    )
-), (
-    'eg.search.pref_lib', 'gui', 'link', 'aou',
-    oils_i18n_gettext(
-        'eg.search.pref_lib',
-        'Staff Catalog Preferred Library',
-        'cwst', 'label'
-    )
-);
-
-
-END IF; END $INSERT$;
-
-
---SELECT evergreen.upgrade_deps_block_check('1118', :eg_version);
-
-UPDATE action_trigger.event_definition
-SET template =
-$$
-[%- USE date -%]
-[%- SET user = target.0.owner -%]
-To: [%- params.recipient_email || user.email %]
-From: [%- params.sender_email || default_sender %]
-Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
-Subject: Bibliographic Records
-Auto-Submitted: auto-generated
-
-[% FOR cbreb IN target %]
-[% FOR item IN cbreb.items;
-    bre_id = item.target_biblio_record_entry;
-
-    bibxml = helpers.unapi_bre(bre_id, {flesh => '{mra}'});
-    title = '';
-    FOR part IN bibxml.findnodes('//*[@tag="245"]/*[@code="a" or @code="b"]');
-        title = title _ part.textContent;
-    END;
-
-    author = bibxml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
-    item_type = bibxml.findnodes('//*[local-name()="attributes"]/*[local-name()="field"][@name="item_type"]').getAttribute('coded-value');
-    publisher = bibxml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
-    pubdate = bibxml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
-    isbn = bibxml.findnodes('//*[@tag="020"]/*[@code="a"]').textContent;
-    issn = bibxml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
-    upc = bibxml.findnodes('//*[@tag="024"]/*[@code="a"]').textContent;
-%]
-
-[% loop.count %]/[% loop.size %].  Bib ID# [% bre_id %] 
-[% IF isbn %]ISBN: [% isbn _ "\n" %][% END -%]
-[% IF issn %]ISSN: [% issn _ "\n" %][% END -%]
-[% IF upc  %]UPC:  [% upc _ "\n" %] [% END -%]
-Title: [% title %]
-Author: [% author %]
-Publication Info: [% publisher %] [% pubdate %]
-Item Type: [% item_type %]
-
-[% END %]
-[% END %]
-$$
-WHERE hook = 'biblio.format.record_entry.email'
--- from previous stock definition
-AND MD5(template) = 'ee4e6c1b3049086c570c7a77413d46c1';
-
-UPDATE action_trigger.event_definition
-SET template =
-$$
-<div>
-    <style> li { padding: 8px; margin 5px; }</style>
-    <ol>
-    [% FOR cbreb IN target %]
-    [% FOR item IN cbreb.items;
-        bre_id = item.target_biblio_record_entry;
-
-        bibxml = helpers.unapi_bre(bre_id, {flesh => '{mra}'});
-        title = '';
-        FOR part IN bibxml.findnodes('//*[@tag="245"]/*[@code="a" or @code="b"]');
-            title = title _ part.textContent;
-        END;
-
-        author = bibxml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
-        item_type = bibxml.findnodes('//*[local-name()="attributes"]/*[local-name()="field"][@name="item_type"]').getAttribute('coded-value');
-        publisher = bibxml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
-        pubdate = bibxml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
-        isbn = bibxml.findnodes('//*[@tag="020"]/*[@code="a"]').textContent;
-        %]
-
-        <li>
-            Bib ID# [% bre_id %] ISBN: [% isbn %]<br />
-            Title: [% title %]<br />
-            Author: [% author %]<br />
-            Publication Info: [% publisher %] [% pubdate %]<br/>
-            Item Type: [% item_type %]
-        </li>
-    [% END %]
-    [% END %]
-    </ol>
-</div>
-$$
-WHERE hook = 'biblio.format.record_entry.print'
--- from previous stock definition
-AND MD5(template) = '9ada7ea8417cb23f89d0dc8f15ec68d0';
-
-
---SELECT evergreen.upgrade_deps_block_check('1120', :eg_version);
-
---Only insert if the attributes are not already present
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-
-INSERT INTO config.z3950_attr (source, name, label, code, format, truncation)
-SELECT 'oclc','upc','UPC','1007','6','0'
-WHERE NOT EXISTS (SELECT name FROM config.z3950_attr WHERE source = 'oclc' AND name = 'upc');
-
-INSERT INTO config.z3950_attr (source, name, label, code, format, truncation)
-SELECT 'loc','upc','UPC','1007','1','1'
-WHERE NOT EXISTS (SELECT name FROM config.z3950_attr WHERE source = 'loc' AND name = 'upc');
-
-END IF; END $INSERT$;
-
---SELECT evergreen.upgrade_deps_block_check('1121', :eg_version);
-
-CREATE TABLE permission.grp_tree_display_entry (
-    id      SERIAL PRIMARY KEY,
-    position INTEGER NOT NULL,
-    org     INTEGER NOT NULL REFERENCES actor.org_unit (id)
-            DEFERRABLE INITIALLY DEFERRED,
-    grp     INTEGER NOT NULL REFERENCES permission.grp_tree (id)
-            DEFERRABLE INITIALLY DEFERRED,
-    CONSTRAINT pgtde_once_per_org UNIQUE (org, grp)
-);
-
-ALTER TABLE permission.grp_tree_display_entry
-    ADD COLUMN parent integer REFERENCES permission.grp_tree_display_entry (id)
-            DEFERRABLE INITIALLY DEFERRED;
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-INSERT INTO permission.perm_list (id, code, description)
-VALUES (609, 'MANAGE_CUSTOM_PERM_GRP_TREE', oils_i18n_gettext( 609,
-    'Allows a user to manage custom permission group lists.', 'ppl', 'description' ));
-END IF; END $INSERT$;
-
---SELECT evergreen.upgrade_deps_block_check('1122', :eg_version);
-
-ALTER TABLE actor.usr 
-    ADD COLUMN pref_prefix TEXT,
-    ADD COLUMN pref_first_given_name TEXT,
-    ADD COLUMN pref_second_given_name TEXT,
-    ADD COLUMN pref_family_name TEXT,
-    ADD COLUMN pref_suffix TEXT,
-    ADD COLUMN name_keywords TEXT,
-    ADD COLUMN name_kw_tsvector TSVECTOR;
-
-ALTER TABLE staging.user_stage
-    ADD COLUMN pref_first_given_name TEXT,
-    ADD COLUMN pref_second_given_name TEXT,
-    ADD COLUMN pref_family_name TEXT;
-
-CREATE INDEX actor_usr_pref_first_given_name_idx 
-    ON actor.usr (evergreen.lowercase(pref_first_given_name));
-CREATE INDEX actor_usr_pref_second_given_name_idx 
-    ON actor.usr (evergreen.lowercase(pref_second_given_name));
-CREATE INDEX actor_usr_pref_family_name_idx 
-    ON actor.usr (evergreen.lowercase(pref_family_name));
-CREATE INDEX actor_usr_pref_first_given_name_unaccent_idx 
-    ON actor.usr (evergreen.unaccent_and_squash(pref_first_given_name));
-CREATE INDEX actor_usr_pref_second_given_name_unaccent_idx 
-    ON actor.usr (evergreen.unaccent_and_squash(pref_second_given_name));
-CREATE INDEX actor_usr_pref_family_name_unaccent_idx 
-   ON actor.usr (evergreen.unaccent_and_squash(pref_family_name));
-
-CREATE OR REPLACE FUNCTION actor.user_ingest_name_keywords() 
-    RETURNS TRIGGER AS $func$
-BEGIN
-    NEW.name_kw_tsvector := TO_TSVECTOR(
-        COALESCE(NEW.prefix, '')                || ' ' || 
-        COALESCE(NEW.first_given_name, '')      || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(NEW.first_given_name), '') || ' ' || 
-        COALESCE(NEW.second_given_name, '')     || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(NEW.second_given_name), '') || ' ' || 
-        COALESCE(NEW.family_name, '')           || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(NEW.family_name), '') || ' ' || 
-        COALESCE(NEW.suffix, '')                || ' ' || 
-        COALESCE(NEW.pref_prefix, '')            || ' ' || 
-        COALESCE(NEW.pref_first_given_name, '')  || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(NEW.pref_first_given_name), '') || ' ' || 
-        COALESCE(NEW.pref_second_given_name, '') || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(NEW.pref_second_given_name), '') || ' ' || 
-        COALESCE(NEW.pref_family_name, '')       || ' ' || 
-        COALESCE(evergreen.unaccent_and_squash(NEW.pref_family_name), '') || ' ' || 
-        COALESCE(NEW.pref_suffix, '')            || ' ' || 
-        COALESCE(NEW.name_keywords, '')
-    );
-    RETURN NEW;
-END;
-$func$ LANGUAGE PLPGSQL;
-
--- Add after the batch upate above to avoid duplicate updates.
-CREATE TRIGGER user_ingest_name_keywords_tgr 
-    BEFORE INSERT OR UPDATE ON actor.usr 
-    FOR EACH ROW EXECUTE PROCEDURE actor.user_ingest_name_keywords();
-
--- merge pref names from source user to target user, except when
--- clobbering existing pref names.
-CREATE OR REPLACE FUNCTION actor.usr_merge(src_usr INT, dest_usr INT, 
-    del_addrs BOOLEAN, del_cards BOOLEAN, deactivate_cards BOOLEAN ) 
-    RETURNS VOID AS $$
-DECLARE
-       suffix TEXT;
-       bucket_row RECORD;
-       picklist_row RECORD;
-       queue_row RECORD;
-       folder_row RECORD;
-BEGIN
-
-    -- do some initial cleanup 
-    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
-    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
-    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
-
-    -- actor.*
-    IF del_cards THEN
-        DELETE FROM actor.card where usr = src_usr;
-    ELSE
-        IF deactivate_cards THEN
-            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
-        END IF;
-        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
-    END IF;
-
-
-    IF del_addrs THEN
-        DELETE FROM actor.usr_address WHERE usr = src_usr;
-    ELSE
-        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
-    END IF;
-
-    UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
-    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
-    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
-    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
-
-    -- permission.*
-    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
-
-
-    -- container.*
-       
-       -- For each *_bucket table: transfer every bucket belonging to src_usr
-       -- into the custody of dest_usr.
-       --
-       -- In order to avoid colliding with an existing bucket owned by
-       -- the destination user, append the source user's id (in parenthesese)
-       -- to the name.  If you still get a collision, add successive
-       -- spaces to the name and keep trying until you succeed.
-       --
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.biblio_record_entry_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.biblio_record_entry_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.call_number_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.call_number_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.copy_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.copy_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.user_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.user_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
-
-    -- vandelay.*
-       -- transfer queues the same way we transfer buckets (see above)
-       FOR queue_row in
-               SELECT id, name
-               FROM   vandelay.queue
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  vandelay.queue
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = queue_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    -- money.*
-    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
-    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
-    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
-
-    -- action.*
-    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
-    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
-    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;
-
-    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
-    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
-    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
-
-    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
-    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
-
-    -- acq.*
-    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
-       UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
-
-       -- transfer picklists the same way we transfer buckets (see above)
-       FOR picklist_row in
-               SELECT id, name
-               FROM   acq.picklist
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  acq.picklist
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = picklist_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
-    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
-
-    -- asset.*
-    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
-
-    -- serial.*
-    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
-
-    -- reporter.*
-    -- It's not uncommon to define the reporter schema in a replica 
-    -- DB only, so don't assume these tables exist in the write DB.
-    BEGIN
-       UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-       UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-       UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.template_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.template_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.report_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.report_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.output_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.output_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-
-    -- propagate preferred name values from the source user to the
-    -- destination user, but only when values are not being replaced.
-    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr)
-    UPDATE actor.usr SET 
-        pref_prefix = 
-            COALESCE(pref_prefix, (SELECT pref_prefix FROM susr)),
-        pref_first_given_name = 
-            COALESCE(pref_first_given_name, (SELECT pref_first_given_name FROM susr)),
-        pref_second_given_name = 
-            COALESCE(pref_second_given_name, (SELECT pref_second_given_name FROM susr)),
-        pref_family_name = 
-            COALESCE(pref_family_name, (SELECT pref_family_name FROM susr)),
-        pref_suffix = 
-            COALESCE(pref_suffix, (SELECT pref_suffix FROM susr))
-    WHERE id = dest_usr;
-
-    -- Copy and deduplicate name keywords
-    -- String -> array -> rows -> DISTINCT -> array -> string
-    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr),
-         dusr AS (SELECT * FROM actor.usr WHERE id = dest_usr)
-    UPDATE actor.usr SET name_keywords = (
-        WITH keywords AS (
-            SELECT DISTINCT UNNEST(
-                REGEXP_SPLIT_TO_ARRAY(
-                    COALESCE((SELECT name_keywords FROM susr), '') || ' ' ||
-                    COALESCE((SELECT name_keywords FROM dusr), ''),  E'\\s+'
-                )
-            ) AS parts
-        ) SELECT ARRAY_TO_STRING(ARRAY_AGG(kw.parts), ' ') FROM keywords kw
-    ) WHERE id = dest_usr;
-
-    -- Finally, delete the source user
-    DELETE FROM actor.usr WHERE id = src_usr;
-
-END;
-$$ LANGUAGE plpgsql;
-
-
---SELECT evergreen.upgrade_deps_block_check('1123', :eg_version);
-
-    ALTER TABLE config.rule_circ_duration
-    ADD column max_auto_renewals INTEGER;
-
-    ALTER TABLE action.circulation
-    ADD column auto_renewal BOOLEAN;
-
-    ALTER TABLE action.circulation
-    ADD column auto_renewal_remaining INTEGER;
-
-    ALTER TABLE action.aged_circulation
-    ADD column auto_renewal BOOLEAN;
-
-    ALTER TABLE action.aged_circulation
-    ADD column auto_renewal_remaining INTEGER;
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-
-    INSERT INTO action_trigger.validator values('CircIsAutoRenewable', 'Checks whether the circulation is able to be autorenewed.');
-    INSERT INTO action_trigger.reactor values('Circ::AutoRenew', 'Auto-Renews a circulation.');
-    INSERT INTO action_trigger.hook(key, core_type, description) values('autorenewal', 'circ', 'Item was auto-renewed to patron.');
-
-    -- AutoRenewer A/T Def: 
-    INSERT INTO action_trigger.event_definition(active, owner, name, hook, validator, reactor, delay, max_delay, delay_field, group_field)
-        values (false, 1, 'Autorenew', 'checkout.due', 'CircIsOpen', 'Circ::AutoRenew', '-23 hours'::interval,'-1 minute'::interval, 'due_date', 'usr');
-
-    -- AutoRenewal outcome Email notifier A/T Def:
-    INSERT INTO action_trigger.event_definition(active, owner, name, hook, validator, reactor, group_field, template)
-        values (false, 1, 'AutorenewNotify', 'autorenewal', 'NOOP_True', 'SendEmail', 'usr', 
-$$
-[%- USE date -%]
-[%- user = target.0.usr -%]
-To: [%- params.recipient_email || user.email %]
-From: [%- params.sender_email || default_sender %]
-Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
-Subject: Items Out Auto-Renewal Notification 
-Auto-Submitted: auto-generated
-
-Dear [% user.family_name %], [% user.first_given_name %]
-An automatic renewal attempt was made for the following items:
-
-[% FOR circ IN target %]
-    [%- SET idx = loop.count - 1; SET udata =  user_data.$idx -%]
-    [%- SET cid = circ.target_copy || udata.copy -%]
-    [%- SET copy_details = helpers.get_copy_bib_basics(cid) -%]
-    Item# [% loop.count %]
-    Title: [% copy_details.title %]
-    Author: [% copy_details.author %]
-    [%- IF udata.is_renewed %]
-    Status: Loan Renewed
-    New Due Date: [% date.format(helpers.format_date(udata.new_due_date), '%Y-%m-%d') %]
-    [%- ELSE %]
-    Status: Not Renewed
-    Reason: [% udata.reason %]
-    Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]
-    [% END %]
-[% END %]
-$$
-    );
-
-    INSERT INTO action_trigger.environment (event_def, path ) VALUES
-    ( currval('action_trigger.event_definition_id_seq'), 'usr' ),
-    ( currval('action_trigger.event_definition_id_seq'), 'circ_lib' );
-
-END IF; END $INSERT$;
-
-
-DROP VIEW action.all_circulation;
-CREATE OR REPLACE VIEW action.all_circulation AS
-    SELECT  id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
-        copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
-        circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
-        stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
-        max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
-        max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ,
-        auto_renewal, auto_renewal_remaining, NULL AS usr
-      FROM  action.aged_circulation
-            UNION ALL
-    SELECT  DISTINCT circ.id,COALESCE(a.post_code,b.post_code) AS usr_post_code, p.home_ou AS usr_home_ou, p.profile AS usr_profile, EXTRACT(YEAR FROM p.dob)::INT AS usr_birth_year,
-        cp.call_number AS copy_call_number, circ.copy_location, cn.owning_lib AS copy_owning_lib, cp.circ_lib AS copy_circ_lib,
-        cn.record AS copy_bib_record, circ.xact_start, circ.xact_finish, circ.target_copy, circ.circ_lib, circ.circ_staff, circ.checkin_staff,
-        circ.checkin_lib, circ.renewal_remaining, circ.grace_period, circ.due_date, circ.stop_fines_time, circ.checkin_time, circ.create_time, circ.duration,
-        circ.fine_interval, circ.recurring_fine, circ.max_fine, circ.phone_renewal, circ.desk_renewal, circ.opac_renewal, circ.duration_rule,
-        circ.recurring_fine_rule, circ.max_fine_rule, circ.stop_fines, circ.workstation, circ.checkin_workstation, circ.checkin_scan_time,
-        circ.parent_circ, circ.auto_renewal, circ.auto_renewal_remaining, circ.usr
-      FROM  action.circulation circ
-        JOIN asset.copy cp ON (circ.target_copy = cp.id)
-        JOIN asset.call_number cn ON (cp.call_number = cn.id)
-        JOIN actor.usr p ON (circ.usr = p.id)
-        LEFT JOIN actor.usr_address a ON (p.mailing_address = a.id)
-        LEFT JOIN actor.usr_address b ON (p.billing_address = b.id);
-
-
-DROP FUNCTION action.summarize_all_circ_chain (INTEGER);
-DROP FUNCTION action.all_circ_chain (INTEGER);
-
--- rebuild slim circ view
-DROP VIEW action.all_circulation_slim;
-CREATE OR REPLACE VIEW action.all_circulation_slim AS
-    SELECT
-        id,
-        usr,
-        xact_start,
-        xact_finish,
-        unrecovered,
-        target_copy,
-        circ_lib,
-        circ_staff,
-        checkin_staff,
-        checkin_lib,
-        renewal_remaining,
-        grace_period,
-        due_date,
-        stop_fines_time,
-        checkin_time,
-        create_time,
-        duration,
-        fine_interval,
-        recurring_fine,
-        max_fine,
-        phone_renewal,
-        desk_renewal,
-        opac_renewal,
-        duration_rule,
-        recurring_fine_rule,
-        max_fine_rule,
-        stop_fines,
-        workstation,
-        checkin_workstation,
-        copy_location,
-        checkin_scan_time,
-        auto_renewal,
-        auto_renewal_remaining,
-        parent_circ
-    FROM action.circulation
-UNION ALL
-    SELECT
-        id,
-        NULL AS usr,
-        xact_start,
-        xact_finish,
-        unrecovered,
-        target_copy,
-        circ_lib,
-        circ_staff,
-        checkin_staff,
-        checkin_lib,
-        renewal_remaining,
-        grace_period,
-        due_date,
-        stop_fines_time,
-        checkin_time,
-        create_time,
-        duration,
-        fine_interval,
-        recurring_fine,
-        max_fine,
-        phone_renewal,
-        desk_renewal,
-        opac_renewal,
-        duration_rule,
-        recurring_fine_rule,
-        max_fine_rule,
-        stop_fines,
-        workstation,
-        checkin_workstation,
-        copy_location,
-        checkin_scan_time,
-        auto_renewal,
-        auto_renewal_remaining,
-        parent_circ
-    FROM action.aged_circulation
-;
-
-CREATE OR REPLACE FUNCTION action.all_circ_chain (ctx_circ_id INTEGER) 
-    RETURNS SETOF action.all_circulation_slim AS $$
-DECLARE
-    tmp_circ action.all_circulation_slim%ROWTYPE;
-    circ_0 action.all_circulation_slim%ROWTYPE;
-BEGIN
-
-    SELECT INTO tmp_circ * FROM action.all_circulation_slim WHERE id = ctx_circ_id;
-
-    IF tmp_circ IS NULL THEN
-        RETURN NEXT tmp_circ;
-    END IF;
-    circ_0 := tmp_circ;
-
-    -- find the front of the chain
-    WHILE TRUE LOOP
-        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
-            WHERE id = tmp_circ.parent_circ;
-        IF tmp_circ IS NULL THEN
-            EXIT;
-        END IF;
-        circ_0 := tmp_circ;
-    END LOOP;
-
-    -- now send the circs to the caller, oldest to newest
-    tmp_circ := circ_0;
-    WHILE TRUE LOOP
-        IF tmp_circ IS NULL THEN
-            EXIT;
-        END IF;
-        RETURN NEXT tmp_circ;
-        SELECT INTO tmp_circ * FROM action.all_circulation_slim 
-            WHERE parent_circ = tmp_circ.id;
-    END LOOP;
-
-END;
-$$ LANGUAGE 'plpgsql';
-
--- same as action.summarize_circ_chain, but returns data collected
--- from action.all_circulation, which may include aged circulations.
-CREATE OR REPLACE FUNCTION action.summarize_all_circ_chain 
-    (ctx_circ_id INTEGER) RETURNS action.circ_chain_summary AS $$
-
-DECLARE
-
-    -- first circ in the chain
-    circ_0 action.all_circulation_slim%ROWTYPE;
-
-    -- last circ in the chain
-    circ_n action.all_circulation_slim%ROWTYPE;
-
-    -- circ chain under construction
-    chain action.circ_chain_summary;
-    tmp_circ action.all_circulation_slim%ROWTYPE;
-
-BEGIN
-    
-    chain.num_circs := 0;
-    FOR tmp_circ IN SELECT * FROM action.all_circ_chain(ctx_circ_id) LOOP
-
-        IF chain.num_circs = 0 THEN
-            circ_0 := tmp_circ;
-        END IF;
-
-        chain.num_circs := chain.num_circs + 1;
-        circ_n := tmp_circ;
-    END LOOP;
-
-    chain.start_time := circ_0.xact_start;
-    chain.last_stop_fines := circ_n.stop_fines;
-    chain.last_stop_fines_time := circ_n.stop_fines_time;
-    chain.last_checkin_time := circ_n.checkin_time;
-    chain.last_checkin_scan_time := circ_n.checkin_scan_time;
-    SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
-    SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
-
-    IF chain.num_circs > 1 THEN
-        chain.last_renewal_time := circ_n.xact_start;
-        SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
-    END IF;
-
-    RETURN chain;
-
-END;
-$$ LANGUAGE 'plpgsql';
-
---SELECT evergreen.upgrade_deps_block_check('1124', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-
-INSERT into config.workstation_setting_type (name, grp, datatype, label)
-VALUES (
-    'eg.grid.circ.wide_holds.shelf', 'gui', 'object',
-    oils_i18n_gettext (
-        'eg.grid.circ.wide_holds.shelf',
-        'Grid Config: circ.wide_holds.shelf',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.cat.catalog.wide_holds', 'gui', 'object',
-    oils_i18n_gettext(
-        'eg.grid.cat.catalog.wide_holds',
-        'Grid Config: cat.catalog.wide_holds',
-        'cwst', 'label'
-    )
-);
-
-DELETE from config.workstation_setting_type
-WHERE name = 'eg.grid.cat.catalog.holds' OR name = 'eg.grid.circ.holds.shelf';
-END IF; END $INSERT$;
-
---SELECT evergreen.upgrade_deps_block_check('1125', :eg_version);
-
-CREATE TABLE asset.latest_inventory (
-    id                          SERIAL                      PRIMARY KEY,
-    inventory_workstation       INTEGER                     REFERENCES actor.workstation (id) DEFERRABLE INITIALLY DEFERRED,
-    inventory_date              TIMESTAMP WITH TIME ZONE    DEFAULT NOW(),
-    copy                        BIGINT                      NOT NULL
-);
-CREATE INDEX latest_inventory_copy_idx ON asset.latest_inventory (copy);
-
-CREATE OR REPLACE FUNCTION evergreen.asset_latest_inventory_copy_inh_fkey() RETURNS TRIGGER AS $f$
-BEGIN
-        PERFORM 1 FROM asset.copy WHERE id = NEW.copy;
-        IF NOT FOUND THEN
-                RAISE foreign_key_violation USING MESSAGE = FORMAT(
-                        $$Referenced asset.copy id not found, copy:%s$$, NEW.copy
-                );
-        END IF;
-        RETURN NEW;
-END;
-$f$ LANGUAGE PLPGSQL VOLATILE COST 50;
-
-CREATE CONSTRAINT TRIGGER inherit_asset_latest_inventory_copy_fkey
-        AFTER UPDATE OR INSERT ON asset.latest_inventory
-        DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_latest_inventory_copy_inh_fkey();
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-INSERT into config.workstation_setting_type (name, grp, datatype, label)
-VALUES (
-    'eg.circ.checkin.do_inventory_update', 'circ', 'bool',
-    oils_i18n_gettext (
-             'eg.circ.checkin.do_inventory_update',
-             'Checkin: Update Inventory',
-             'cwst', 'label'
-    )
-);
-END IF; END $INSERT$;
-
---SELECT evergreen.upgrade_deps_block_check('1126', :eg_version);
-
-CREATE TABLE vandelay.session_tracker (
-    id          BIGSERIAL PRIMARY KEY,
-
-    -- string of characters (e.g. md5) used for linking trackers
-    -- of different actions into a series.  There can be multiple
-    -- session_keys of each action type, creating the opportunity
-    -- to link multiple action trackers into a single session.
-    session_key TEXT NOT NULL,
-
-    -- optional user-supplied name
-    name        TEXT NOT NULL, 
-
-    usr         INTEGER NOT NULL REFERENCES actor.usr(id)
-                DEFERRABLE INITIALLY DEFERRED,
-
-    -- org unit can be derived from WS
-    workstation INTEGER NOT NULL REFERENCES actor.workstation(id)
-                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-
-    -- bib/auth
-    record_type vandelay.bib_queue_queue_type NOT NULL DEFAULT 'bib',
-
-    -- Queue defines the source of the data, it does not necessarily
-    -- mean that an action is being performed against an entire queue.
-    -- E.g. some imports are misc. lists of record IDs, but they always 
-    -- come from one queue.
-    -- No foreign key -- could be auth or bib queue.
-    queue       BIGINT NOT NULL,
-
-    create_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
-    update_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
-
-    state       TEXT NOT NULL DEFAULT 'active',
-
-    action_type TEXT NOT NULL DEFAULT 'enqueue', -- import
-
-    -- total number of tasks to perform / loosely defined
-    -- could be # of recs to import or # of recs + # of copies 
-    -- depending on the import context
-    total_actions INTEGER NOT NULL DEFAULT 0,
-
-    -- total number of tasked performed so far
-    actions_performed INTEGER NOT NULL DEFAULT 0,
-
-    CONSTRAINT vand_tracker_valid_state 
-        CHECK (state IN ('active','error','complete')),
-
-    CONSTRAINT vand_tracker_valid_action_type
-        CHECK (action_type IN ('upload', 'enqueue', 'import'))
-);
-
-
-CREATE OR REPLACE FUNCTION actor.usr_merge( src_usr INT, dest_usr INT, del_addrs BOOLEAN, del_cards BOOLEAN, deactivate_cards BOOLEAN ) RETURNS VOID AS $$
-DECLARE
-       suffix TEXT;
-       bucket_row RECORD;
-       picklist_row RECORD;
-       queue_row RECORD;
-       folder_row RECORD;
-BEGIN
-
-    -- do some initial cleanup 
-    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
-    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
-    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
-
-    -- actor.*
-    IF del_cards THEN
-        DELETE FROM actor.card where usr = src_usr;
-    ELSE
-        IF deactivate_cards THEN
-            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
-        END IF;
-        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
-    END IF;
-
-
-    IF del_addrs THEN
-        DELETE FROM actor.usr_address WHERE usr = src_usr;
-    ELSE
-        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
-    END IF;
-
-    UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
-    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
-    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
-    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
-
-    -- permission.*
-    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
-
-
-    -- container.*
-       
-       -- For each *_bucket table: transfer every bucket belonging to src_usr
-       -- into the custody of dest_usr.
-       --
-       -- In order to avoid colliding with an existing bucket owned by
-       -- the destination user, append the source user's id (in parenthesese)
-       -- to the name.  If you still get a collision, add successive
-       -- spaces to the name and keep trying until you succeed.
-       --
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.biblio_record_entry_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.biblio_record_entry_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.call_number_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.call_number_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.copy_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.copy_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.user_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.user_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
-
-    -- vandelay.*
-       -- transfer queues the same way we transfer buckets (see above)
-       FOR queue_row in
-               SELECT id, name
-               FROM   vandelay.queue
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  vandelay.queue
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = queue_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    UPDATE vandelay.session_tracker SET usr = dest_usr WHERE usr = src_usr;
-
-    -- money.*
-    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
-    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
-    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
-
-    -- action.*
-    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
-    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
-    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;
-
-    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
-    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
-    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
-
-    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
-    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
-
-    -- acq.*
-    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
-       UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
-
-       -- transfer picklists the same way we transfer buckets (see above)
-       FOR picklist_row in
-               SELECT id, name
-               FROM   acq.picklist
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  acq.picklist
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = picklist_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
-    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
-
-    -- asset.*
-    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
-
-    -- serial.*
-    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
-
-    -- reporter.*
-    -- It's not uncommon to define the reporter schema in a replica 
-    -- DB only, so don't assume these tables exist in the write DB.
-    BEGIN
-       UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-       UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-       UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.template_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.template_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.report_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.report_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.output_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.output_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-
-    -- propagate preferred name values from the source user to the
-    -- destination user, but only when values are not being replaced.
-    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr)
-    UPDATE actor.usr SET 
-        pref_prefix = 
-            COALESCE(pref_prefix, (SELECT pref_prefix FROM susr)),
-        pref_first_given_name = 
-            COALESCE(pref_first_given_name, (SELECT pref_first_given_name FROM susr)),
-        pref_second_given_name = 
-            COALESCE(pref_second_given_name, (SELECT pref_second_given_name FROM susr)),
-        pref_family_name = 
-            COALESCE(pref_family_name, (SELECT pref_family_name FROM susr)),
-        pref_suffix = 
-            COALESCE(pref_suffix, (SELECT pref_suffix FROM susr))
-    WHERE id = dest_usr;
-
-    -- Copy and deduplicate name keywords
-    -- String -> array -> rows -> DISTINCT -> array -> string
-    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr),
-         dusr AS (SELECT * FROM actor.usr WHERE id = dest_usr)
-    UPDATE actor.usr SET name_keywords = (
-        WITH keywords AS (
-            SELECT DISTINCT UNNEST(
-                REGEXP_SPLIT_TO_ARRAY(
-                    COALESCE((SELECT name_keywords FROM susr), '') || ' ' ||
-                    COALESCE((SELECT name_keywords FROM dusr), ''),  E'\\s+'
-                )
-            ) AS parts
-        ) SELECT ARRAY_TO_STRING(ARRAY_AGG(kw.parts), ' ') FROM keywords kw
-    ) WHERE id = dest_usr;
-
-    -- Finally, delete the source user
-    DELETE FROM actor.usr WHERE id = src_usr;
-
-END;
-$$ LANGUAGE plpgsql;
-
-
-CREATE OR REPLACE FUNCTION actor.usr_purge_data(
-       src_usr  IN INTEGER,
-       specified_dest_usr IN INTEGER
-) RETURNS VOID AS $$
-DECLARE
-       suffix TEXT;
-       renamable_row RECORD;
-       dest_usr INTEGER;
-BEGIN
-
-       IF specified_dest_usr IS NULL THEN
-               dest_usr := 1; -- Admin user on stock installs
-       ELSE
-               dest_usr := specified_dest_usr;
-       END IF;
-
-       -- acq.*
-       UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
-       UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
-       UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
-       DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;
-
-       -- Update with a rename to avoid collisions
-       FOR renamable_row in
-               SELECT id, name
-               FROM   acq.picklist
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  acq.picklist
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
-       UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;
-
-       -- action.*
-       DELETE FROM action.circulation WHERE usr = src_usr;
-       UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
-       UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
-       UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
-       UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
-       UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
-       DELETE FROM action.hold_request WHERE usr = src_usr;
-       UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
-       UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
-       DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
-       UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
-       DELETE FROM action.survey_response WHERE usr = src_usr;
-       UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
-       DELETE FROM action.usr_circ_history WHERE usr = src_usr;
-
-       -- actor.*
-       DELETE FROM actor.card WHERE usr = src_usr;
-       DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
-
-       -- The following update is intended to avoid transient violations of a foreign
-       -- key constraint, whereby actor.usr_address references itself.  It may not be
-       -- necessary, but it does no harm.
-       UPDATE actor.usr_address SET replaces = NULL
-               WHERE usr = src_usr AND replaces IS NOT NULL;
-       DELETE FROM actor.usr_address WHERE usr = src_usr;
-       DELETE FROM actor.usr_note WHERE usr = src_usr;
-       UPDATE actor.usr_note SET creator = dest_usr WHERE creator = src_usr;
-       DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
-       UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
-       DELETE FROM actor.usr_setting WHERE usr = src_usr;
-       DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
-       UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
-
-       -- asset.*
-       UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
-
-       -- auditor.*
-       DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
-       DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
-       UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE auditor.asset_call_number_history SET editor  = dest_usr WHERE editor  = src_usr;
-       UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE auditor.asset_copy_history SET editor  = dest_usr WHERE editor  = src_usr;
-       UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE auditor.biblio_record_entry_history SET editor  = dest_usr WHERE editor  = src_usr;
-
-       -- biblio.*
-       UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;
-
-       -- container.*
-       -- Update buckets with a rename to avoid collisions
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.biblio_record_entry_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.biblio_record_entry_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.call_number_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.call_number_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.copy_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.copy_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.user_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.user_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       DELETE FROM container.user_bucket_item WHERE target_user = src_usr;
-
-       -- money.*
-       DELETE FROM money.billable_xact WHERE usr = src_usr;
-       DELETE FROM money.collections_tracker WHERE usr = src_usr;
-       UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;
-
-       -- permission.*
-       DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
-       DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
-       DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
-       DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;
-
-       -- reporter.*
-       -- Update with a rename to avoid collisions
-       BEGIN
-               FOR renamable_row in
-                       SELECT id, name
-                       FROM   reporter.output_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.output_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = renamable_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       BEGIN
-               UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       -- Update with a rename to avoid collisions
-       BEGIN
-               FOR renamable_row in
-                       SELECT id, name
-                       FROM   reporter.report_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.report_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = renamable_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       BEGIN
-               UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       BEGIN
-               UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       -- Update with a rename to avoid collisions
-       BEGIN
-               FOR renamable_row in
-                       SELECT id, name
-                       FROM   reporter.template_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.template_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = renamable_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-       EXCEPTION WHEN undefined_table THEN
-       -- do nothing
-       END;
-
-       -- vandelay.*
-       -- Update with a rename to avoid collisions
-       FOR renamable_row in
-               SELECT id, name
-               FROM   vandelay.queue
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  vandelay.queue
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    UPDATE vandelay.session_tracker SET usr = dest_usr WHERE usr = src_usr;
-
-    -- NULL-ify addresses last so other cleanup (e.g. circ anonymization)
-    -- can access the information before deletion.
-       UPDATE actor.usr SET
-               active = FALSE,
-               card = NULL,
-               mailing_address = NULL,
-               billing_address = NULL
-       WHERE id = src_usr;
-
-END;
-$$ LANGUAGE plpgsql;
-
-
---SELECT evergreen.upgrade_deps_block_check('1127', :eg_version);
-
-ALTER TABLE acq.user_request ADD COLUMN cancel_time TIMESTAMPTZ;
-ALTER TABLE acq.user_request ADD COLUMN upc TEXT;
-ALTER TABLE action.hold_request ADD COLUMN acq_request INT REFERENCES acq.user_request (id);
-
-UPDATE
-    config.org_unit_setting_type
-SET
-    label = oils_i18n_gettext(
-        'circ.holds.canceled.display_age',
-        'Canceled holds/requests display age',
-        'coust', 'label'),
-    description = oils_i18n_gettext(
-        'circ.holds.canceled.display_age',
-        'Show all canceled entries in patron holds and patron acquisition requests interfaces that were canceled within this amount of time',
-        'coust', 'description')
-WHERE
-    name = 'circ.holds.canceled.display_age'
-;
-
-UPDATE
-    config.org_unit_setting_type
-SET
-    label = oils_i18n_gettext(
-        'circ.holds.canceled.display_count',
-        'Canceled holds/requests display count',
-        'coust', 'label'),
-    description = oils_i18n_gettext(
-        'circ.holds.canceled.display_count',
-        'How many canceled entries to show in patron holds and patron acquisition requests interfaces',
-        'coust', 'description')
-WHERE
-    name = 'circ.holds.canceled.display_count'
-;
-
-
--- replace existing, unused cancel reason with the new one.
-UPDATE acq.cancel_reason SET org_unit = 1, keep_debits = FALSE, 
-    label = 'Canceled: Fulfilled', 
-    description = 'This acquisition request has been fulfilled.' 
-    WHERE id = 1015;
-
-/*
-INSERT INTO acq.cancel_reason (org_unit, keep_debits, id, label, description)
-    VALUES (
-        1, 'f', 1015,
-        oils_i18n_gettext(1015, 'Canceled: Fulfilled', 'acqcr', 'label'),
-        oils_i18n_gettext(1015, 'This acquisition request has been fulfilled.', 'acqcr', 'description')
-    )
-;
-*/
-
-UPDATE
-    acq.user_request_type
-SET
-    label = oils_i18n_gettext('2', 'Articles', 'aurt', 'label')
-WHERE
-    id = 2
-;
-
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-
-INSERT INTO acq.user_request_type (id,label)
-    SELECT 6, oils_i18n_gettext('6', 'Other', 'aurt', 'label');
-
-INSERT INTO permission.perm_list ( id, code, description ) VALUES
- ( 610, 'CLEAR_PURCHASE_REQUEST', oils_i18n_gettext(610,
-    'Clear Completed User Purchase Requests', 'ppl', 'description'))
-;
-
-END IF; END $INSERT$;
-
-SELECT SETVAL('acq.user_request_type_id_seq'::TEXT, (SELECT MAX(id)+1 FROM acq.user_request_type));
-
-CREATE TABLE acq.user_request_status_type (
-     id  SERIAL  PRIMARY KEY
-    ,label TEXT
-);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-INSERT INTO acq.user_request_status_type (id,label) VALUES
-     (0,oils_i18n_gettext(0,'Error','aurst','label'))
-    ,(1,oils_i18n_gettext(1,'New','aurst','label'))
-    ,(2,oils_i18n_gettext(2,'Pending','aurst','label'))
-    ,(3,oils_i18n_gettext(3,'Ordered, Hold Not Placed','aurst','label'))
-    ,(4,oils_i18n_gettext(4,'Ordered, Hold Placed','aurst','label'))
-    ,(5,oils_i18n_gettext(5,'Received','aurst','label'))
-    ,(6,oils_i18n_gettext(6,'Fulfilled','aurst','label'))
-    ,(7,oils_i18n_gettext(7,'Canceled','aurst','label'))
-;
-
-END IF; END $INSERT$;
-
-SELECT SETVAL('acq.user_request_status_type_id_seq'::TEXT, 100);
-
--- not used
-DELETE FROM actor.org_unit_setting WHERE name = 'acq.holds.allow_holds_from_purchase_request';
-DELETE FROM config.org_unit_setting_type_log WHERE field_name = 'acq.holds.allow_holds_from_purchase_request';
-DELETE FROM config.org_unit_setting_type WHERE name = 'acq.holds.allow_holds_from_purchase_request';
-
-
---SELECT evergreen.upgrade_deps_block_check('1128', :eg_version);
-
--- KCLS already had this
-/*
-DROP VIEW auditor.acq_invoice_lifecycle;
-
-ALTER TABLE acq.invoice
-    ADD COLUMN close_date TIMESTAMPTZ,
-    ADD COLUMN closed_by  INTEGER 
-        REFERENCES actor.usr (id) DEFERRABLE INITIALLY DEFERRED;
-
--- duplicate steps for auditor table
-ALTER TABLE auditor.acq_invoice_history
-    ADD COLUMN close_date TIMESTAMPTZ,
-    ADD COLUMN closed_by  INTEGER;
-
-UPDATE acq.invoice SET close_date = NOW() WHERE complete;
-UPDATE auditor.acq_invoice_history SET close_date = NOW() WHERE complete;
-
-ALTER TABLE acq.invoice DROP COLUMN complete;
-ALTER TABLE auditor.acq_invoice_history DROP COLUMN complete;
-
--- this recreates auditor.acq_invoice_lifecycle;
-SELECT auditor.update_auditors();
-*/
-
-CREATE OR REPLACE FUNCTION actor.usr_merge( src_usr INT, dest_usr INT, del_addrs BOOLEAN, del_cards BOOLEAN, deactivate_cards BOOLEAN ) RETURNS VOID AS $$
-DECLARE
-       suffix TEXT;
-       bucket_row RECORD;
-       picklist_row RECORD;
-       queue_row RECORD;
-       folder_row RECORD;
-BEGIN
-
-    -- do some initial cleanup 
-    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
-    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
-    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
-
-    -- actor.*
-    IF del_cards THEN
-        DELETE FROM actor.card where usr = src_usr;
-    ELSE
-        IF deactivate_cards THEN
-            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
-        END IF;
-        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
-    END IF;
-
-
-    IF del_addrs THEN
-        DELETE FROM actor.usr_address WHERE usr = src_usr;
-    ELSE
-        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
-    END IF;
-
-    UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
-    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
-    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
-    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
-
-    -- permission.*
-    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
-
-
-    -- container.*
-       
-       -- For each *_bucket table: transfer every bucket belonging to src_usr
-       -- into the custody of dest_usr.
-       --
-       -- In order to avoid colliding with an existing bucket owned by
-       -- the destination user, append the source user's id (in parenthesese)
-       -- to the name.  If you still get a collision, add successive
-       -- spaces to the name and keep trying until you succeed.
-       --
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.biblio_record_entry_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.biblio_record_entry_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.call_number_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.call_number_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.copy_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.copy_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR bucket_row in
-               SELECT id, name
-               FROM   container.user_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.user_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = bucket_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
-
-    -- vandelay.*
-       -- transfer queues the same way we transfer buckets (see above)
-       FOR queue_row in
-               SELECT id, name
-               FROM   vandelay.queue
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  vandelay.queue
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = queue_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    -- money.*
-    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
-    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
-    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
-    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
-
-    -- action.*
-    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
-    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
-    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;
-
-    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
-    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
-    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
-    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
-
-    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
-    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
-    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
-
-    -- acq.*
-    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
-       UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
-    UPDATE acq.invoice SET closed_by = dest_usr WHERE closed_by = src_usr;
-
-       -- transfer picklists the same way we transfer buckets (see above)
-       FOR picklist_row in
-               SELECT id, name
-               FROM   acq.picklist
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  acq.picklist
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = picklist_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
-    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
-
-    -- asset.*
-    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
-
-    -- serial.*
-    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
-    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
-
-    -- reporter.*
-    -- It's not uncommon to define the reporter schema in a replica 
-    -- DB only, so don't assume these tables exist in the write DB.
-    BEGIN
-       UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-       UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-       UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.template_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.template_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.report_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.report_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-    BEGIN
-               -- transfer folders the same way we transfer buckets (see above)
-               FOR folder_row in
-                       SELECT id, name
-                       FROM   reporter.output_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.output_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = folder_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-    EXCEPTION WHEN undefined_table THEN
-        -- do nothing
-    END;
-
-    -- Finally, delete the source user
-    DELETE FROM actor.usr WHERE id = src_usr;
-
-END;
-$$ LANGUAGE plpgsql;
-
-
-CREATE OR REPLACE FUNCTION actor.usr_purge_data(
-       src_usr  IN INTEGER,
-       specified_dest_usr IN INTEGER
-) RETURNS VOID AS $$
-DECLARE
-       suffix TEXT;
-       renamable_row RECORD;
-       dest_usr INTEGER;
-BEGIN
-
-       IF specified_dest_usr IS NULL THEN
-               dest_usr := 1; -- Admin user on stock installs
-       ELSE
-               dest_usr := specified_dest_usr;
-       END IF;
-
-       -- acq.*
-       UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
-       UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
-       UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
-    UPDATE acq.invoice SET closed_by = dest_usr WHERE closed_by = src_usr;
-       DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;
-
-       -- Update with a rename to avoid collisions
-       FOR renamable_row in
-               SELECT id, name
-               FROM   acq.picklist
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  acq.picklist
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
-       UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;
-
-       -- action.*
-       DELETE FROM action.circulation WHERE usr = src_usr;
-       UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
-       UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
-       UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
-       UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
-       UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
-       DELETE FROM action.hold_request WHERE usr = src_usr;
-       UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
-       UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
-       DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
-       UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
-       DELETE FROM action.survey_response WHERE usr = src_usr;
-       UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
-       DELETE FROM action.usr_circ_history WHERE usr = src_usr;
-
-       -- actor.*
-       DELETE FROM actor.card WHERE usr = src_usr;
-       DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
-
-       -- The following update is intended to avoid transient violations of a foreign
-       -- key constraint, whereby actor.usr_address references itself.  It may not be
-       -- necessary, but it does no harm.
-       UPDATE actor.usr_address SET replaces = NULL
-               WHERE usr = src_usr AND replaces IS NOT NULL;
-       DELETE FROM actor.usr_address WHERE usr = src_usr;
-       DELETE FROM actor.usr_note WHERE usr = src_usr;
-       UPDATE actor.usr_note SET creator = dest_usr WHERE creator = src_usr;
-       DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
-       UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
-       DELETE FROM actor.usr_setting WHERE usr = src_usr;
-       DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
-       UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
-
-       -- asset.*
-       UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
-
-       -- auditor.*
-       DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
-       DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
-       UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE auditor.asset_call_number_history SET editor  = dest_usr WHERE editor  = src_usr;
-       UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE auditor.asset_copy_history SET editor  = dest_usr WHERE editor  = src_usr;
-       UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE auditor.biblio_record_entry_history SET editor  = dest_usr WHERE editor  = src_usr;
-
-       -- biblio.*
-       UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
-       UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
-       UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;
-
-       -- container.*
-       -- Update buckets with a rename to avoid collisions
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.biblio_record_entry_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.biblio_record_entry_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.call_number_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.call_number_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.copy_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.copy_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       FOR renamable_row in
-               SELECT id, name
-               FROM   container.user_bucket
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  container.user_bucket
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-       DELETE FROM container.user_bucket_item WHERE target_user = src_usr;
-
-       -- money.*
-       DELETE FROM money.billable_xact WHERE usr = src_usr;
-       DELETE FROM money.collections_tracker WHERE usr = src_usr;
-       UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;
-
-       -- permission.*
-       DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
-       DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
-       DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
-       DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;
-
-       -- reporter.*
-       -- Update with a rename to avoid collisions
-       BEGIN
-               FOR renamable_row in
-                       SELECT id, name
-                       FROM   reporter.output_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.output_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = renamable_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       BEGIN
-               UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       -- Update with a rename to avoid collisions
-       BEGIN
-               FOR renamable_row in
-                       SELECT id, name
-                       FROM   reporter.report_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.report_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = renamable_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       BEGIN
-               UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       BEGIN
-               UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
-       EXCEPTION WHEN undefined_table THEN
-               -- do nothing
-       END;
-
-       -- Update with a rename to avoid collisions
-       BEGIN
-               FOR renamable_row in
-                       SELECT id, name
-                       FROM   reporter.template_folder
-                       WHERE  owner = src_usr
-               LOOP
-                       suffix := ' (' || src_usr || ')';
-                       LOOP
-                               BEGIN
-                                       UPDATE  reporter.template_folder
-                                       SET     owner = dest_usr, name = name || suffix
-                                       WHERE   id = renamable_row.id;
-                               EXCEPTION WHEN unique_violation THEN
-                                       suffix := suffix || ' ';
-                                       CONTINUE;
-                               END;
-                               EXIT;
-                       END LOOP;
-               END LOOP;
-       EXCEPTION WHEN undefined_table THEN
-       -- do nothing
-       END;
-
-       -- vandelay.*
-       -- Update with a rename to avoid collisions
-       FOR renamable_row in
-               SELECT id, name
-               FROM   vandelay.queue
-               WHERE  owner = src_usr
-       LOOP
-               suffix := ' (' || src_usr || ')';
-               LOOP
-                       BEGIN
-                               UPDATE  vandelay.queue
-                               SET     owner = dest_usr, name = name || suffix
-                               WHERE   id = renamable_row.id;
-                       EXCEPTION WHEN unique_violation THEN
-                               suffix := suffix || ' ';
-                               CONTINUE;
-                       END;
-                       EXIT;
-               END LOOP;
-       END LOOP;
-
-    -- NULL-ify addresses last so other cleanup (e.g. circ anonymization)
-    -- can access the information before deletion.
-       UPDATE actor.usr SET
-               active = FALSE,
-               card = NULL,
-               mailing_address = NULL,
-               billing_address = NULL
-       WHERE id = src_usr;
-
-END;
-$$ LANGUAGE plpgsql;
-
-
-
-
-
--- UNDO (minus user purge/merge changes)
-/*
-
-DROP VIEW auditor.acq_invoice_lifecycle;
-ALTER TABLE acq.invoice ADD COLUMN complete BOOLEAN NOT NULL DEFAULT FALSE;
-ALTER TABLE auditor.acq_invoice_history 
-    ADD COLUMN complete BOOLEAN NOT NULL DEFAULT FALSE;
-UPDATE acq.invoice SET complete = TRUE where close_date IS NOT NULL;
-UPDATE auditor.acq_invoice_history 
-    SET complete = TRUE where close_date IS NOT NULL;
-SET CONSTRAINTS ALL IMMEDIATE; -- or get pending triggers error.
-ALTER TABLE acq.invoice DROP COLUMN close_date, DROP COLUMN closed_by;
-ALTER TABLE auditor.acq_invoice_history
-    DROP COLUMN close_date, DROP COLUMN closed_by;
-SELECT auditor.update_auditors();
-
-*/
-
-
---SELECT evergreen.upgrade_deps_block_check('1129', :eg_version);
-
-DO $INSERT$ BEGIN IF evergreen.insert_on_deploy() THEN
-
-INSERT into config.workstation_setting_type (name, grp, datatype, label)
-VALUES (
-    'eg.grid.admin.acq.cancel_reason', 'gui', 'object',
-    oils_i18n_gettext (
-        'eg.grid.admin.acq.cancel_reason',
-        'Grid Config: admin.acq.cancel_reason',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.claim_event_type', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.claim_event_type',
-        'Grid Config: admin.acq.claim_event_type',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.claim_policy', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.claim_policy',
-        'Grid Config: admin.acq.claim_policy',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.claim_policy_action', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.claim_policy_action',
-        'Grid Config: admin.acq.claim_policy_action',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.claim_type', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.claim_type',
-        'Grid Config: admin.acq.claim_type',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.currency_type', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.currency_type',
-        'Grid Config: admin.acq.currency_type',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.edi_account', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.edi_account',
-        'Grid Config: admin.acq.edi_account',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.edi_message', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.edi_message',
-        'Grid Config: admin.acq.edi_message',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.exchange_rate', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.exchange_rate',
-        'Grid Config: admin.acq.exchange_rate',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.fund_tag', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.fund_tag',
-        'Grid Config: admin.acq.fund_tag',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.invoice_item_type', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.invoice_item_type',
-        'Grid Config: admin.acq.invoice_item_type',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.invoice_payment_method', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.invoice_payment_method',
-        'Grid Config: admin.acq.invoice_payment_method',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.lineitem_alert_text', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.lineitem_alert_text',
-        'Grid Config: admin.acq.lineitem_alert_text',
-        'cwst', 'label'
-    )
-), (
-    'eg.grid.admin.acq.lineitem_marc_attr_definition', 'gui', 'object',
-    oils_i18n_gettext (
-    'eg.grid.admin.acq.lineitem_marc_attr_definition',
-        'Grid Config: admin.acq.lineitem_marc_attr_definition',
-        'cwst', 'label'
-    )
-);
-
-END IF; END $INSERT$;
-
-----------------------------------------------------------------------------
--- VERSION INSERTS
-----------------------------------------------------------------------------
-
-DO $INSERT$
-BEGIN
-    IF evergreen.insert_on_deploy() THEN
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.0', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1032', '3.0.0'); -- Bmagic/csharp/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1034', '3.0.0');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1035', '3.0.0'); -- dyrcona/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1036', '3.0.0');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1041', '3.0.0'); -- stompro/csharp/gmcharlt
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1042', '3.0.0'); -- mmorgan/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1043', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1044', '3.0.0');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1045', '3.0.0'); -- csharp/berick/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1046', '3.0.0'); -- phasefx/berick/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1047', '3.0.0'); -- gmcharlt/stompro
-PERFORM evergreen.upgrade_deps_block_check('1048', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1049', '3.0.0'); -- mmorgan/stompro/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1050', '3.0.0'); -- mmorgan/cesardv/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1051', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1052', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1053', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1054', '3.0.0');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1056', '3.0.0'); -- miker/gmcharlt
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1057', '3.0.0'); -- miker/gmcharlt/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1076', '3.0.0'); -- miker/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1058', '3.0.0'); -- mccanna/csharp/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1059', '3.0.0'); --Stompro/DPearl/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1060', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1061', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1062', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1063', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1064', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1065', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1066', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1067', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1068', '3.0.0'); --miker/gmcharlt/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1069', '3.0.0'); --gmcharlt/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1070', '3.0.0'); --miker/gmcharlt/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1071', '3.0.0'); --gmcharlt/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1072', '3.0.0'); --gmcharlt/kmlussier
-PERFORM evergreen.upgrade_deps_block_check('1073', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1074', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1075', '3.0.0');
-PERFORM evergreen.upgrade_deps_block_check('1077', '3.0.0'); -- csharp/gmcharlt
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.1', '3.0.0');
---PERFORM evergreen.upgrade_deps_block_check('1078', '3.0.1'); -- csharp/bshum/gmcharlt
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.2', '3.0.1');
---PERFORM evergreen.upgrade_deps_block_check('1079', '3.0.2'); -- rhamby/cesardv/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1080', '3.0.2'); -- miker/jboyer/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1081', '3.0.2'); -- jboyer/gmcharlt
-PERFORM evergreen.upgrade_deps_block_check('1082', '3.0.2'); -- jboyer/gmcharlt
---PERFORM evergreen.upgrade_deps_block_check('1083', '3.0.2');
-PERFORM evergreen.upgrade_deps_block_check('1084', '3.0.2');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.3', '3.0.2');
-PERFORM evergreen.upgrade_deps_block_check('1085', '3.0.3');
-PERFORM evergreen.upgrade_deps_block_check('1086', '3.0.3');
-PERFORM evergreen.upgrade_deps_block_check('1087', '3.0.3');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.4', '3.0.3');
-PERFORM evergreen.upgrade_deps_block_check('1088', '3.0.4');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.5', '3.0.4');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.0.6', '3.0.5');
-PERFORM evergreen.upgrade_deps_block_check('1107', '3.0.6');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.0', '3.0.6');
-PERFORM evergreen.upgrade_deps_block_check('1089', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1090', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1091', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1092', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1093', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1094', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1095', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1096', '3.1.0');
-
-PERFORM evergreen.upgrade_deps_block_check('1097', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1098', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1099', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1100', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1101', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1102', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1103', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1104', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1105', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1106', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1108', '3.1.0');
-PERFORM evergreen.upgrade_deps_block_check('1109', '3.1.0');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.1', '3.1.0');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.2', '3.1.1');
-PERFORM evergreen.upgrade_deps_block_check('1110', '3.1.2');
-PERFORM evergreen.upgrade_deps_block_check('1111', '3.1.2');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.3', '3.1.2');
-PERFORM evergreen.upgrade_deps_block_check('1112', '3.1.3');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.4', '3.1.3');
-PERFORM evergreen.upgrade_deps_block_check('1113', '3.1.4'); 
-PERFORM evergreen.upgrade_deps_block_check('1114', '3.1.4');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.1.5', '3.1.4');
-PERFORM evergreen.upgrade_deps_block_check('1119', '3.1.5');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.2.1', '3.1.5');
-PERFORM evergreen.upgrade_deps_block_check('1115', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1116', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1117', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1118', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1120', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1121', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1122', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1123', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1124', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1125', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1126', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1127', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1128', '3.2.1');
-PERFORM evergreen.upgrade_deps_block_check('1129', '3.2.1');
-    END IF;
-END $INSERT$;
-
-COMMIT;
---ROLLBACK;
-