diff --git a/vendor/File/MARC.php b/vendor/File/MARC.php
new file mode 100644
index 0000000000000000000000000000000000000000..43de35bb4ed7e5b40db24b8c1420ba07382bbf04
--- /dev/null
+++ b/vendor/File/MARC.php
@@ -0,0 +1,385 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2010 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: MARC.php 308144 2011-02-08 20:28:20Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ * @example   read.php Retrieve specific fields and subfields from a record
+ * @example   subfields.php Create new subfields and add them in specific order
+ * @example   marc_yaz.php Pretty print a MARC record retrieved through the PECL yaz extension
+ */
+
+require_once 'PEAR/Exception.php';
+require_once 'Structures/LinkedList/Double.php';
+require_once 'File/MARCBASE.php';
+require_once 'File/MARC/Record.php';
+require_once 'File/MARC/Field.php';
+require_once 'File/MARC/Control_Field.php';
+require_once 'File/MARC/Data_Field.php';
+require_once 'File/MARC/Subfield.php';
+require_once 'File/MARC/Exception.php';
+require_once 'File/MARC/List.php';
+
+// {{{ class File_MARC
+/**
+ * The main File_MARC class enables you to return File_MARC_Record
+ * objects from a stream or string.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Christoffer Landtman <landtman@realnode.com>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC extends File_MARCBASE
+{
+
+    // {{{ constants
+
+    /**
+     * MARC records retrieved from a file
+     */
+    const SOURCE_FILE = 1;
+
+    /**
+     * MARC records retrieved from a binary string 
+     */
+    const SOURCE_STRING = 2;
+
+    /**
+     * Hexadecimal value for Subfield indicator
+     */
+    const SUBFIELD_INDICATOR = "\x1F";
+
+    /**
+     * Hexadecimal value for End of Field
+     */
+    const END_OF_FIELD = "\x1E";
+
+    /**
+     * Hexadecimal value for End of Record
+     */
+    const END_OF_RECORD = "\x1D";
+
+    /**
+     * Length of the Directory
+     */
+    const DIRECTORY_ENTRY_LEN = 12;
+
+    /**
+     * Length of the Leader
+     */
+    const LEADER_LEN = 24;
+
+    /**
+     * Maximum record length
+     */
+    const MAX_RECORD_LENGTH = 99999;
+    // }}}
+
+    // {{{ properties
+    /**
+     * Source containing raw records
+     * 
+     * @var resource
+     */
+    protected $source;
+
+    /**
+     * Source type (SOURCE_FILE or SOURCE_STRING)
+     * 
+     * @var int
+     */
+    protected $type;
+
+    /**
+     * XMLWriter for writing collections
+     * 
+     * @var XMLWriter
+     */
+    protected $xmlwriter;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Read in MARC records
+     *
+     * This function reads in MARC record files or strings that
+     * contain one or more MARC records.
+     *
+     * <code>
+     * <?php
+     * // Retrieve MARC records from a file
+     * $journals = new File_MARC('journals.mrc', SOURCE_FILE);
+     *
+     * // Retrieve MARC records from a string (e.g. Z39 query results)
+     * $monographs = new File_MARC($raw_marc, SOURCE_STRING);
+     * ?>
+     * </code>
+     *
+     * @param string $source Name of the file, or a raw MARC string
+     * @param int    $type   Source of the input, either SOURCE_FILE or SOURCE_STRING
+     */
+    function __construct($source, $type = self::SOURCE_FILE)
+    {
+
+        parent::__construct($source, $type);
+
+        switch ($type) {
+
+        case self::SOURCE_FILE:
+            $this->type = self::SOURCE_FILE;
+            $this->source = fopen($source, 'rb');
+            if (!$this->source) {
+                 $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_FILE], array('filename' => $source));
+                 throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_FILE);
+            }
+            break;
+
+        case self::SOURCE_STRING:
+            $this->type = self::SOURCE_STRING;
+            $this->source = explode(File_MARC::END_OF_RECORD, $source);
+            break;
+
+        default:
+             throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_SOURCE], File_MARC_Exception::ERROR_INVALID_SOURCE);
+        }
+    }
+    // }}}
+
+    // {{{ nextRaw()
+    /**
+     * Return the next raw MARC record
+     *
+     * Returns the next raw MARC record, unless all records already have
+     * been read.
+     *
+     * @return string Either a raw record or false
+     */
+    function nextRaw()
+    {
+        if ($this->type == self::SOURCE_FILE) {
+            $record = stream_get_line($this->source, File_MARC::MAX_RECORD_LENGTH, File_MARC::END_OF_RECORD);
+
+            // Remove illegal stuff that sometimes occurs between records
+            $record = preg_replace('/^[\\x0a\\x0d\\x00]+/', "", $record);
+
+        } elseif ($this->type == self::SOURCE_STRING) {
+            $record = array_shift($this->source);
+        }
+
+        // Exit if we are at the end of the file
+        if (!$record) {
+            return false;
+        }
+
+        // Append the end of record we lost during stream_get_line() or explode()
+        $record .= File_MARC::END_OF_RECORD;
+        return $record;
+    }
+    // }}}
+
+    // {{{ next()
+    /**
+     * Return next {@link File_MARC_Record} object
+     *
+     * Decodes the next raw MARC record and returns the {@link File_MARC_Record}
+     * object.
+     * <code>
+     * <?php
+     * // Retrieve a set of MARC records from a file
+     * $journals = new File_MARC('journals.mrc', SOURCE_FILE);
+     *
+     * // Iterate through the retrieved records
+     * while ($record = $journals->next()) {
+     *     print $record;
+     *     print "\n";
+     * }
+     *
+     * ?>
+     * </code>
+     *
+     * @return File_MARC_Record next record, or false if there are
+     * no more records
+     */
+    function next()
+    {
+        $raw = $this->nextRaw();
+        if ($raw) {
+            return $this->_decode($raw);
+        } else {
+            return false;
+        }
+    }
+    // }}}
+
+    // {{{ _decode()
+    /**
+     * Decode a given raw MARC record
+     *
+     * Port of Andy Lesters MARC::File::USMARC->decode() Perl function into PHP.
+     *
+     * @param string $text Raw MARC record
+     *
+     * @return File_MARC_Record Decoded File_MARC_Record object
+     */
+    private function _decode($text)
+    {
+        $marc = new File_MARC_Record($this);
+
+        // fallback on the actual byte length
+        $record_length = strlen($text);
+
+        $matches = array();
+        if (preg_match("/^(\d{5})/", $text, $matches)) {
+            // Store record length
+            $record_length = $matches[1];
+            if ($record_length != strlen($text)) {
+                $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INCORRECT_LENGTH], array("record_length" => $record_length, "actual" => strlen($text))));
+                // Real beats declared byte length
+                $record_length = strlen($text);
+            }
+        } else {
+            $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_NONNUMERIC_LENGTH], array("record_length" => substr($text, 0, 5))));
+        }
+
+        if (substr($text, -1, 1) != File_MARC::END_OF_RECORD)
+             throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_TERMINATOR], File_MARC_Exception::ERROR_INVALID_TERMINATOR);
+
+        // Store leader
+        $marc->setLeader(substr($text, 0, File_MARC::LEADER_LEN));
+
+        // bytes 12 - 16 of leader give offset to the body of the record
+        $data_start = 0 + substr($text, 12, 5);
+
+        // immediately after the leader comes the directory (no separator)
+        $dir = substr($text, File_MARC::LEADER_LEN, $data_start - File_MARC::LEADER_LEN - 1);  // -1 to allow for \x1e at end of directory
+
+        // character after the directory must be \x1e
+        if (substr($text, $data_start-1, 1) != File_MARC::END_OF_FIELD) {
+            $marc->addWarning(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_NO_DIRECTORY]);
+        }
+
+        // All directory entries 12 bytes long, so length % 12 must be 0
+        if (strlen($dir) % File_MARC::DIRECTORY_ENTRY_LEN != 0) {
+            $marc->addWarning(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_LENGTH]);
+        }
+
+        // go through all the fields
+        $nfields = strlen($dir) / File_MARC::DIRECTORY_ENTRY_LEN;
+        for ($n=0; $n<$nfields; $n++) {
+            // As pack returns to key 1, leave place 0 in list empty
+            list(, $tag) = unpack("A3", substr($dir, $n*File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN));
+            list(, $len) = unpack("A3/A4", substr($dir, $n*File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN));
+            list(, $offset) = unpack("A3/A4/A5", substr($dir, $n*File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN));
+
+            // Check directory validity
+            if (!preg_match("/^[0-9A-Za-z]{3}$/", $tag)) {
+                $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_TAG], array("tag" => $tag)));
+            }
+            if (!preg_match("/^\d{4}$/", $len)) {
+                $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_TAG_LENGTH], array("tag" => $tag, "len" => $len)));
+            }
+            if (!preg_match("/^\d{5}$/", $offset)) {
+                $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_OFFSET], array("tag" => $tag, "offset" => $offset)));
+            }
+            if ($offset + $len > $record_length) {
+                $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY], array("tag" => $tag)));
+            }
+
+            $tag_data = substr($text, $data_start + $offset, $len);
+
+            if (substr($tag_data, -1, 1) == File_MARC::END_OF_FIELD) {
+                /* get rid of the end-of-tag character */
+                $tag_data = substr($tag_data, 0, -1);
+                $len--;
+            } else {
+                $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_FIELD_EOF], array("tag" => $tag)));
+            }
+
+            if (preg_match("/^\d+$/", $tag) and ($tag < 10)) {
+                $marc->appendField(new File_MARC_Control_Field($tag, $tag_data));
+            } else {
+                $subfields = explode(File_MARC::SUBFIELD_INDICATOR, $tag_data);
+                $indicators = array_shift($subfields);
+
+                if (strlen($indicators) != 2) {
+                    $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATORS], array("tag" => $tag, "indicators" => $indicators));
+                    $marc->addWarning($errorMessage);
+                    // Do the best with the indicators we've got
+                    if (strlen($indicators) == 1) {
+                        $ind1 = $indicators;
+                        $ind2 = " ";
+                    } else {
+                        list($ind1,$ind2) = array(" ", " ");
+                    }
+                } else {
+                    $ind1 = substr($indicators, 0, 1);
+                    $ind2 = substr($indicators, 1, 1);
+                }
+
+                // Split the subfield data into subfield name and data pairs
+                $subfield_data = array();
+                foreach ($subfields as $subfield) {
+                    if (strlen($subfield) > 0) {
+                        $subfield_data[] = new File_MARC_Subfield(substr($subfield, 0, 1), substr($subfield, 1));
+                    } else {
+                         $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_EMPTY_SUBFIELD], array("tag" => $tag));
+                         $marc->addWarning($errorMessage);
+                    }
+                }
+
+                if (!isset($subfield_data)) {
+                     $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_EMPTY_SUBFIELD], array("tag" => $tag));
+                     $marc->addWarning($errorMessage);
+                }
+
+
+                // If the data is invalid, let's just ignore the one field
+                try {
+                    $new_field = new File_MARC_Data_Field($tag, $subfield_data, $ind1, $ind2);
+                    $marc->appendField($new_field);
+                } catch (Exception $e) {
+                    $marc->addWarning($e->getMessage());
+                }
+            }
+        }
+
+        return $marc;
+    }
+    // }}}
+
+}
+// }}}
+
diff --git a/vendor/File/MARC/Control_Field.php b/vendor/File/MARC/Control_Field.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd29f94804cf52ff96d9f191de221c7e8261ff8a
--- /dev/null
+++ b/vendor/File/MARC/Control_Field.php
@@ -0,0 +1,177 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Control_Field.php 301737 2010-07-31 04:14:44Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Control_Field extends File_MARC_Field
+/**
+ * The File_MARC_Control_Field class represents a single control field
+ * in a MARC record.
+ *
+ * A MARC control field consists of a tag name and control data.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Christoffer Landtman <landtman@realnode.com>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Control_Field extends File_MARC_Field
+{
+
+    // {{{ Properties
+    /**
+     * Value of field, if field is a Control field
+     * @var string
+     */
+    protected $data;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Field init function
+     *
+     * Create a new {@link File_MARC_Control_Field} object from passed arguments
+     *
+     * @param string $tag  tag
+     * @param string $data control field data
+     * @param string $ind1 placeholder for class strictness
+     * @param string $ind2 placeholder for class strictness
+     */
+    function __construct($tag, $data, $ind1 = null, $ind2 = null) 
+    {
+        $this->data = $data;
+        parent::__construct($tag);
+
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Destroys the control field
+     */
+    function __destruct()
+    {
+        $this->data = null;
+        parent::__destruct();
+    }
+    // }}}
+
+    // {{{ Explicit destructor: function delete()
+    /**
+     * Destroys the control field
+     *
+     * @return true
+     */
+    function delete()
+    {
+        $this->__destruct();
+    }
+    // }}}
+
+    // {{{ getData()
+    /**
+     * Get control field data
+     *
+     * @return string returns data in control field
+     */
+    function getData()
+    {
+        return (string)$this->data;
+    }
+    // }}}
+
+    // {{{ isEmpty()
+    /**
+     * Is empty
+     *
+     * Checks if the field contains data
+     *
+     * @return bool Returns true if the field is empty, otherwise false
+     */
+    function isEmpty()
+    {
+        return ($this->data) ? false : true;
+    }
+    // }}}
+
+    // {{{ setData()
+    /**
+     * Set control field data
+     *
+     * @param string $data data for the control field
+     *
+     * @return bool returns the new data in the control field
+     */
+    function setData($data)
+    {
+        $this->data = $data;
+        return $this->getData();
+    }
+    // }}}
+
+    // {{{ __toString()
+    /**
+     * Return as a formatted string
+     *
+     * Return the control field as a formatted string for pretty printing
+     *
+     * @return string Formatted output of control Field
+     */
+    function __toString()
+    {
+        return sprintf("%3s     %s", $this->tag, $this->data);
+    }
+    // }}}
+
+    // {{{ toRaw()
+    /**
+     * Return as raw MARC
+     *
+     * Return the control field formatted in Raw MARC for saving into MARC files
+     *
+     * @return string Raw MARC
+     */
+    function toRaw()
+    {
+        return (string)$this->data.File_MARC::END_OF_FIELD;
+    }
+    // }}}
+
+}
+// }}}
+
diff --git a/vendor/File/MARC/Data_Field.php b/vendor/File/MARC/Data_Field.php
new file mode 100644
index 0000000000000000000000000000000000000000..691e243c28273e9cfde0bb64001bcffb4eac1aad
--- /dev/null
+++ b/vendor/File/MARC/Data_Field.php
@@ -0,0 +1,481 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Data_Field.php 301737 2010-07-31 04:14:44Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Data_Field extends File_MARC_Field
+/**
+ * The File_MARC_Data_Field class represents a single field in a MARC record.
+ *
+ * A MARC data field consists of a tag name, two indicators which may be null,
+ * and zero or more subfields represented by {@link File_MARC_Subfield} objects.
+ * Subfields are held within a linked list structure.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Christoffer Landtman <landtman@realnode.com>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Data_Field extends File_MARC_Field
+{
+
+    // {{{ properties
+    /**
+     * Value of the first indicator
+     * @var string
+     */
+    protected $ind1;
+
+    /**
+     * Value of the second indicator
+     * @var string
+     */
+    protected $ind2;
+
+    /**
+     * Linked list of subfields
+     * @var File_MARC_List
+     */
+    protected $subfields;
+
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * {@link File_MARC_Data_Field} constructor
+     *
+     * Create a new {@link File_MARC_Data_Field} object. The only required
+     * parameter is a tag. This enables programs to build up new fields
+     * programmatically.
+     *
+     * <code>
+     * // Example: Create a new data field
+     *
+     * // We can optionally create an array of subfields first
+     * $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.');
+     *
+     * // Create the new 100 field complete with a _a subfield and an indicator
+     * $new_field = new File_MARC_Data_Field('100', $subfields, 0, null);
+     * </code>
+     *
+     * @param string $tag       tag
+     * @param array  $subfields array of {@link File_MARC_Subfield} objects
+     * @param string $ind1      first indicator
+     * @param string $ind2      second indicator
+     */
+    function __construct($tag, array $subfields = null, $ind1 = null, $ind2 = null) 
+    {
+        $this->subfields = new File_MARC_List();
+
+        parent::__construct($tag);
+
+        $this->ind1 = $this->_validateIndicator($ind1);
+        $this->ind2 = $this->_validateIndicator($ind2);
+
+        // we'll let users add subfields after if they so desire
+        if ($subfields) {
+            $this->addSubfields($subfields);
+        }
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Destroys the data field
+     */
+    function __destruct()
+    {
+        $this->subfields = null;
+        $this->ind1 = null;
+        $this->ind2 = null;
+        parent::__destruct();
+    }
+    // }}}
+
+    // {{{ Explicit destructor: function delete()
+    /**
+     * Destroys the data field
+     *
+     * @return true
+     */
+    function delete()
+    {
+        $this->__destruct();
+    }
+    // }}}
+
+    // {{{ protected function _validateIndicator()
+    /**
+     * Validates an indicator field
+     *
+     * Validates the value passed in for an indicator. This routine ensures
+     * that an indicator is a single character. If the indicator value is null,
+     * then this method returns a single character.
+     *
+     * If the indicator value contains more than a single character, this
+     * throws an exception.
+     *
+     * @param string $indicator Value of the indicator to be validated
+     *
+     * @return string Returns the indicator, or space if the indicator was null
+     */
+    private function _validateIndicator($indicator)
+    {
+        if ($indicator == null) {
+            $indicator = ' ';
+        } elseif (strlen($indicator) > 1) {
+            $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR], array("tag" => $this->getTag(), "indicator" => $indicator));
+            throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR);
+        }
+        return $indicator;
+    }
+    // }}}
+
+    // {{{ appendSubfield()
+    /**
+     * Appends subfield to subfield list
+     *
+     * Adds a File_MARC_Subfield object to the end of the existing list
+     * of subfields.
+     *
+     * @param File_MARC_Subfield $new_subfield The subfield to add
+     *
+     * @return File_MARC_Subfield the new File_MARC_Subfield object
+     */
+    function appendSubfield(File_MARC_Subfield $new_subfield)
+    {
+        /* Append as the last field in the record */
+        $this->subfields->appendNode($new_subfield);
+        return $new_subfield;
+    }
+    // }}}
+
+    // {{{ prependSubfield()
+    /**
+     * Prepends subfield to subfield liss 
+     *
+     * Adds a File_MARC_Subfield object to the  start of the existing list
+     * of subfields.
+     *
+     * @param File_MARC_Subfield $new_subfield The subfield to add
+     *
+     * @return File_MARC_Subfield the new File_MARC_Subfield object
+     */
+    function prependSubfield(File_MARC_Subfield $new_subfield)
+    {
+        $this->subfields->prependNode($new_subfield);
+        return $new_subfield;
+    }
+    // }}}
+
+    // {{{ insertSubfield()
+    /**
+     * Inserts a field in the MARC record relative to an existing field
+     *
+     * Inserts a {@link File_MARC_Subfield} object before or after an existing
+     * subfield.
+     *
+     * @param File_MARC_Subfield $new_field      The subfield to add
+     * @param File_MARC_Subfield $existing_field The target subfield
+     * @param bool               $before         Insert the subfield before the existing subfield if true; after the existing subfield if false
+     *
+     * @return File_MARC_Subfield                The new subfield
+     */
+    function insertSubfield(File_MARC_Subfield $new_field, File_MARC_Subfield $existing_field, $before = false)
+    {
+        switch ($before) {
+        /* Insert before the specified subfield in the record */
+        case true:
+            $this->subfields->insertNode($new_field, $existing_field, true);
+            break;
+
+        /* Insert after the specified subfield in the record */
+        case false:
+            $this->subfields->insertNode($new_field, $existing_field);
+            break;
+
+        default: 
+             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INSERTSUBFIELD_MODE], array("mode" => $mode));
+             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INSERTSUBFIELD_MODE);
+            return false;
+        }
+        return $new_field;
+    }
+    // }}}
+
+    // {{{ addSubfields()
+    /**
+     * Adds an array of subfields to a {@link File_MARC_Data_Field} object
+     *
+     * Appends subfields to existing subfields in the order in which
+     * they appear in the array. For finer grained control of the subfield
+     * order, use {@link appendSubfield()}, {@link prependSubfield()},
+     * or {@link insertSubfield()} to add each subfield individually.
+     *
+     * @param array $subfields array of {@link File_MARC_Subfield} objects
+     *
+     * @return int returns the number of subfields that were added
+     */
+    function addSubfields(array $subfields)
+    {
+        /*
+         * Just in case someone passes in a single File_MARC_Subfield
+         * instead of an array
+         */
+        if ($subfields instanceof File_MARC_Subfield) {
+            $this->appendSubfield($subfields);
+            return 1;
+        }
+
+        // Add subfields
+        $cnt = 0;
+        foreach ($subfields as $subfield) {
+            $this->appendSubfield($subfield);
+            $cnt++;
+        }
+
+        return $cnt;
+    }
+    // }}}
+
+    // {{{ deleteSubfield()
+    /**
+     * Delete a subfield from the field.
+     *
+     * @param File_MARC_Subfield $subfield The subfield to delete
+     *
+     * @return bool                         Success or failure
+     */
+    function deleteSubfield(File_MARC_Subfield $subfield)
+    {
+        if ($this->subfields->deleteNode($subfield)) {
+            return true;
+        }
+        return false;
+    }
+    // }}}
+
+    // {{{ getIndicator()
+    /**
+     * Get the value of an indicator
+     *
+     * @param int $ind number of the indicator (1 or 2)
+     *
+     * @return string returns indicator value if it exists, otherwise false
+     */
+    function getIndicator($ind)
+    {
+        if ($ind == 1) {
+            return (string)$this->ind1;
+        } elseif ($ind == 2) {
+            return (string)$this->ind2;
+        } else {
+             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST], array("indicator" => $indicator));
+             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST);
+        }
+        return false;
+    }
+    // }}}
+
+    // {{{ setIndicator()
+    /**
+     * Set the value of an indicator
+     *
+     * @param int    $ind   number of the indicator (1 or 2)
+     * @param string $value value of the indicator
+     *
+     * @return string       returns indicator value if it exists, otherwise false
+     */
+    function setIndicator($ind, $value)
+    {
+        switch ($ind) {
+
+        case 1:
+            $this->ind1 = $this->_validateIndicator($value);
+            break;
+
+        case 2:
+            $this->ind2 = $this->_validateIndicator($value);
+            break;
+
+        default:
+             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST], array("indicator" => $ind));
+             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST);
+            return false;
+        }
+
+        return $this->getIndicator($ind);
+    }
+    // }}}
+
+    // {{{ getSubfield()
+    /**
+     * Returns the first subfield that matches a requested code.
+     *
+     * @param string $code subfield code for which the
+     * {@link File_MARC_Subfield} is retrieved
+     *
+     * @return File_MARC_Subfield returns the first subfield that matches
+     * $code, or false if no codes match $code
+     */
+    function getSubfield($code = null)
+    {
+        // iterate merrily through the subfields looking for the requested code
+        foreach ($this->subfields as $sf) {
+            if ($sf->getCode() == $code) {
+                return $sf;
+            }
+        }
+
+        // No matches were found
+        return false;
+    }
+    // }}}
+
+    // {{{ getSubfields()
+    /**
+     * Returns an array of subfields that match a requested code,
+     * or a {@link File_MARC_List} that contains all of the subfields
+     * if the requested code is null.
+     *
+     * @param string $code subfield code for which the
+     * {@link File_MARC_Subfield} is retrieved
+     *
+     * @return File_MARC_List|array returns a linked list of all subfields
+     * if $code is null, an array of {@link File_MARC_Subfield} objects if
+     * one or more subfields match, or false if no codes match $code
+     */
+    function getSubfields($code = null)
+    {
+        $results = array();
+
+        // return all subfields if no specific subfields were requested
+        if ($code === null) {
+            $results = $this->subfields;
+            return $results;
+        }
+
+        // iterate merrily through the subfields looking for the requested code
+        foreach ($this->subfields as $sf) {
+            if ($sf->getCode() == $code) {
+                $results[] = $sf;
+            }
+        }
+        return $results;
+    }
+    // }}}
+
+    // {{{ isEmpty()
+    /**
+     * Checks if the field is empty.
+     *
+     * Checks if the field is empty. If the field has at least one subfield
+     * with data, it is not empty.
+     *
+     * @return bool Returns true if the field is empty, otherwise false
+     */
+    function isEmpty()
+    {
+        // If $this->subfields is null, we must have deleted it
+        if (!$this->subfields) {
+            return true;
+        }
+
+        // Iterate through the subfields looking for some data
+        foreach ($this->subfields as $subfield) {
+            // Check if subfield has data
+            if (!$subfield->isEmpty()) {
+                return false;
+            }
+        }
+        // It is empty
+        return true;
+    }
+    // }}}
+
+    /**
+     * ========== OUTPUT METHODS ==========
+     */
+
+    // {{{ __toString()
+    /**
+     * Return Field formatted
+     *
+     * Return Field as a formatted string.
+     *
+     * @return string Formatted output of Field
+     */
+    function __toString()
+    {
+        // Variables
+        $lines = array();
+        // Process tag and indicators
+        $pre = sprintf("%3s %1s%1s", $this->tag, $this->ind1, $this->ind2);
+
+        // Process subfields
+        foreach ($this->subfields as $subfield) {
+            $lines[] = sprintf("%6s _%1s%s", $pre, $subfield->getCode(), $subfield->getData());
+            $pre = "";
+        }
+
+        return join("\n", $lines);
+    }
+    // }}}
+
+    // {{{ toRaw()
+    /**
+     * Return Field in Raw MARC
+     *
+     * Return the Field formatted in Raw MARC for saving into MARC files
+     *
+     * @return string Raw MARC
+     */
+    function toRaw()
+    {
+        $subfields = array();
+        foreach ($this->subfields as $subfield) {
+            if (!$subfield->isEmpty()) {
+                $subfields[] = $subfield->toRaw();
+            }
+        }
+        return (string)$this->ind1.$this->ind2.implode("", $subfields).File_MARC::END_OF_FIELD;
+    }
+    // }}}
+}
+// }}}
+
diff --git a/vendor/File/MARC/Exception.php b/vendor/File/MARC/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..48f521c2c30fc2bbf7ebca240fe2dc39203f4c0b
--- /dev/null
+++ b/vendor/File/MARC/Exception.php
@@ -0,0 +1,214 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Exception.php 268035 2008-10-30 17:01:14Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Exception extends PEAR_Exception
+/**
+ * The File_MARC_Exception class enables error-handling
+ * for the File_MARC package.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Exception extends PEAR_Exception
+{
+    // {{{ Error codes
+    /**
+     * File could not be opened
+     */
+    const ERROR_INVALID_FILE = -1;
+
+    /**
+     * User passed an unknown SOURCE_ constant
+     */
+    const ERROR_INVALID_SOURCE = -2;
+
+    /**
+     * MARC record ended with an invalid terminator
+     */
+    const ERROR_INVALID_TERMINATOR = -3;
+
+    /**
+     * No directory was found for the MARC record
+     */
+    const ERROR_NO_DIRECTORY = -4;
+
+    /**
+     * An entry in the MARC directory was not 12 bytes
+     */
+    const ERROR_INVALID_DIRECTORY_LENGTH = -5;
+
+    /**
+     * An entry in the MARC directory specified an invalid tag
+     */
+    const ERROR_INVALID_DIRECTORY_TAG = -6;
+
+    /**
+     * An entry in the MARC directory specified an invalid tag length
+     */
+    const ERROR_INVALID_DIRECTORY_TAG_LENGTH = -7;
+
+    /**
+     * An entry in the MARC directory specified an invalid field offset
+     */
+    const ERROR_INVALID_DIRECTORY_OFFSET = -8;
+
+    /**
+     * An entry in the MARC directory runs past the end of the record
+     */
+    const ERROR_INVALID_DIRECTORY = -9;
+
+    /**
+     * A field does not end with the expected end-of-field character
+     */
+    const ERROR_FIELD_EOF = -10;
+
+    /**
+     * A field has invalid indicators
+     */
+    const ERROR_INVALID_INDICATORS = -11;
+
+    /**
+     * A subfield is defined, but has no data
+     */
+    const ERROR_EMPTY_SUBFIELD = -12;
+
+    /**
+     * An indicator other than 1 or 2 was requested
+     */
+    const ERROR_INVALID_INDICATOR_REQUEST = -13;
+
+    /**
+     * An invalid mode for adding a field was specified
+     */
+    const ERROR_INSERTFIELD_MODE = -14;
+
+    /**
+     * An invalid object was passed instead of a File_MARC_Field object
+     */
+    const ERROR_INVALID_FIELD = -15;
+
+    /**
+     * An invalid object was passed instead of a File_MARC_Subfield object
+     */
+    const ERROR_INVALID_SUBFIELD = -16;
+
+    /**
+     * An invalid mode for adding a subfield was specified
+     */
+    const ERROR_INSERTSUBFIELD_MODE = -17;
+
+    /**
+     * The length in the MARC leader does not match the actual record length
+     */
+    const ERROR_INCORRECT_LENGTH = -18;
+
+    /**
+     * The length field in the leader was less than five characters long
+     */
+    const ERROR_MISSING_LENGTH = -19;
+
+    /**
+     * A five-digit length could not be found in the MARC leader
+     */
+    const ERROR_NONNUMERIC_LENGTH = -20;
+
+    /**
+     * Tag does not adhere to MARC standards
+     */
+    const ERROR_INVALID_TAG = -21;
+
+    /**
+     * A field has invalid indicators
+     */
+    const ERROR_INVALID_INDICATOR = -22;
+    // }}}
+
+    // {{{ error messages
+    public static $messages = array(
+        self::ERROR_EMPTY_SUBFIELD => 'No subfield data found in tag "%tag%"', 
+        self::ERROR_FIELD_EOF => 'Field for tag "%tag%" does not end with an end of field character', 
+        self::ERROR_INCORRECT_LENGTH => 'Invalid record length: Leader says "%record_length%" bytes; actual record length is "%actual%"', 
+        self::ERROR_INSERTFIELD_MODE => 'insertField() mode "%mode%" was not recognized', 
+        self::ERROR_INSERTSUBFIELD_MODE => 'insertSubfield() mode "%mode%" was not recognized', 
+        self::ERROR_INVALID_DIRECTORY => 'Directory entry for tag "%tag%" runs past the end of the record', 
+        self::ERROR_INVALID_DIRECTORY_LENGTH => 'Invalid directory length', 
+        self::ERROR_INVALID_DIRECTORY_OFFSET => 'Invalid offset "%offset%" for tag "%tag%" in directory', 
+        self::ERROR_INVALID_DIRECTORY_TAG => 'Invalid tag "%tag%" in directory', 
+        self::ERROR_INVALID_DIRECTORY_TAG_LENGTH => 'Invalid length "%len%" in directory for tag "%tag%"', 
+        self::ERROR_INVALID_FIELD => 'Specified field must be a File_MARC_Data_Field or File_MARC_Control_Field object, but was "%field%"', 
+        self::ERROR_INVALID_FILE => 'Invalid input file "%filename%"', 
+        self::ERROR_INVALID_INDICATOR_REQUEST => 'Attempt to access indicator "%indicator%" failed; 1 and 2 are the only valid indicators', 
+        self::ERROR_INVALID_INDICATORS => 'Invalid indicators "%indicators%" forced to blanks for tag "%tag%"', 
+        self::ERROR_INVALID_SOURCE => "Invalid source for MARC records", 
+        self::ERROR_INVALID_SUBFIELD => 'Specified field must be a File_MARC_Subfield object, but was "%class%"', 
+        self::ERROR_INVALID_TAG => 'Tag "%tag%" is not a valid tag.', 
+        self::ERROR_INVALID_TERMINATOR => 'Invalid record terminator', 
+        self::ERROR_MISSING_LENGTH => "Couldn't find record length", 
+        self::ERROR_NO_DIRECTORY => 'No directory found', 
+        self::ERROR_NONNUMERIC_LENGTH => 'Record length "%record_length%" is not numeric',
+        self::ERROR_INVALID_INDICATOR => 'Illegal indicator "%indicator%" in field "%tag%" forced to blank', 
+    );
+    // }}}
+
+    // {{{ formatError()
+    /**
+     * Replaces placeholder tokens in an error message with actual values.
+     *
+     * This method enables you to internationalize the messages for the
+     * File_MARC class by simply replacing the File_MARC_Exception::$messages
+     * array with translated values for the messages.
+     *
+     * @param string $message     Error message containing placeholders
+     * @param array  $errorValues Actual values to substitute for placeholders
+     *
+     * @return string             Formatted message
+     */
+    public static function formatError($message, $errorValues)
+    {
+        foreach ($errorValues as $token => $value) {
+            $message = preg_replace("/\%$token\%/", $value, $message);
+        }
+        return $message;
+    }
+    // }}}
+}
+// }}}
+
diff --git a/vendor/File/MARC/Field.php b/vendor/File/MARC/Field.php
new file mode 100644
index 0000000000000000000000000000000000000000..85883b2448618ab346fb35c14ada4d1e5af72bdd
--- /dev/null
+++ b/vendor/File/MARC/Field.php
@@ -0,0 +1,241 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Field.php 301737 2010-07-31 04:14:44Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Field extends Structures_LinkedList_DoubleNode
+/**
+ * The File_MARC_Field class is expected to be extended to reflect the
+ * requirements of control and data fields.
+ *
+ * Every MARC field contains a tag name.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Christoffer Landtman <landtman@realnode.com>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Field extends Structures_LinkedList_DoubleNode
+{
+
+    // {{{ properties
+    /**
+     * The tag name of the Field
+     * @var string
+     */
+    protected $tag;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * File_MARC_Field constructor
+     *
+     * Create a new {@link File_MARC_Field} object from passed arguments. We
+     * define placeholders for the arguments required by child classes.
+     *
+     * @param string $tag       tag
+     * @param string $subfields placeholder for subfields or control data
+     * @param string $ind1      placeholder for first indicator
+     * @param string $ind2      placeholder for second indicator
+     */
+    function __construct($tag, $subfields = null, $ind1 = null, $ind2 = null) 
+    {
+        $this->tag = $tag;
+
+        // Check if valid tag
+        if (!preg_match("/^[0-9A-Za-z]{3}$/", $tag)) {
+             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_TAG], array("tag" => $tag));
+             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_TAG);
+        }
+
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Destroys the data field
+     */
+    function __destruct()
+    {
+        $this->tag = null;
+        parent::__destruct();
+    }
+    // }}}
+
+    // {{{ getTag()
+    /**
+     * Returns the tag for this {@link File_MARC_Field} object
+     *
+     * @return string returns the tag number of the field
+     */
+    function getTag()
+    {
+        return (string)$this->tag;
+    }
+    // }}}
+
+    // {{{ setTag()
+    /**
+     * Sets the tag for this {@link File_MARC_Field} object
+     *
+     * @param string $tag new value for the tag
+     *
+     * @return string returns the tag number of the field
+     */
+    function setTag($tag)
+    {
+        $this->tag = $tag;
+        return $this->getTag();
+    }
+    // }}}
+
+    // {{{ isEmpty()
+    /**
+     * Is empty
+     *
+     * Checks if the field is empty.
+     *
+     * @return bool Returns true if the field is empty, otherwise false
+     */
+    function isEmpty()
+    {
+        if ($this->getTag()) {
+            return false;
+        }
+        // It is empty
+        return true;
+    }
+    // }}}
+
+    // {{{ isControlField()
+    /**
+     * Is control field
+     *
+     * Checks if the field is a control field.
+     *
+     * @return bool Returns true if the field is a control field, otherwise false
+     */
+    function isControlField()
+    {
+        if (get_class($this) == 'File_MARC_Control_Field') {
+            return true;
+        }
+        return false;
+    }
+    // }}}
+
+    // {{{ isDataField()
+    /**
+     * Is data field
+     *
+     * Checks if the field is a data field.
+     *
+     * @return bool Returns true if the field is a data field, otherwise false
+     */
+    function isDataField()
+    {
+        if (get_class($this) == 'File_MARC_Data_Field') {
+            return true;
+        }
+        return false;
+    }
+    // }}}
+
+
+    /**
+     * ========== OUTPUT METHODS ==========
+     */
+
+    // {{{ __toString()
+    /**
+     * Return Field formatted
+     *
+     * Return Field as a formatted string.
+     *
+     * @return string Formatted output of Field
+     */
+    function __toString()
+    {
+        return (string)$this->getTag();
+    }
+    // }}}
+
+    // {{{ toRaw()
+    /**
+     * Return field in raw MARC format (stub)
+     *
+     * Return the field formatted in raw MARC for saving into MARC files. This
+     * stub method is extended by the child classes.
+     *
+     * @return bool Raw MARC
+     */
+    function toRaw()
+    {
+        return false;
+    }
+    // }}}
+
+    // {{{ formatField()
+    /**
+     * Pretty print a MARC_Field object without tags, indicators, etc.
+     *
+     * @param array $exclude Subfields to exclude from formatted output
+     * 
+     * @return string Returns the formatted field data
+     */
+
+    function formatField($exclude = array('2'))
+    {
+        if ($this->isControlField()) {
+            return $this->getData();
+        } else {
+            $out = '';
+            foreach ($this->getSubfields() as $subfield) {
+                if (substr($this->getTag(), 0, 1) == '6' and (in_array($subfield->getCode(), array('v','x','y','z')))) {
+                    $out .= ' -- ' . $subfield->getData();
+                } elseif (!in_array($subfield->getCode(), $exclude)) {
+                    $out .= ' ' . $subfield->getData();
+                }
+            }
+            return trim($out);
+        }
+    }
+    // }}}
+}
+// }}}
+
diff --git a/vendor/File/MARC/Lint.php b/vendor/File/MARC/Lint.php
new file mode 100644
index 0000000000000000000000000000000000000000..67705570b41ee9f14bce63ef1c559b2e59a4a96a
--- /dev/null
+++ b/vendor/File/MARC/Lint.php
@@ -0,0 +1,3750 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Lint for MARC records
+ *
+ * This module is adapted from the MARC::Lint CPAN module for Perl, maintained by
+ * Bryan Baldus <eijabb@cpan.org> and available at http://search.cpan.org/~eijabb/
+ *
+ * Current MARC::Lint version used as basis for this module: 1.44
+ *
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Demian Katz <demian.katz@villanova.edu>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Record.php 308146 2011-02-08 20:36:20Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+require_once 'File/MARC/Lint/CodeData.php';
+require_once 'Validate/ISPN.php';
+
+// {{{ class File_MARC_Lint
+/**
+ * Class for testing validity of MARC records against MARC21 standard.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Lint
+{
+
+    // {{{ properties
+    /**
+     * Rules used for testing records
+     * @var array
+     */
+    protected $rules;
+
+    /**
+     * A File_MARC_Lint_CodeData object for validating codes
+     * @var File_MARC_Lint_CodeData
+     */
+    protected $data;
+
+    /**
+     * Warnings generated during analysis
+     * @var array
+     */
+    protected $warnings = array();
+
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Start function
+     *
+     * Set up rules for testing MARC records.
+     *
+     * @return true
+     */
+    public function __construct()
+    {
+        $this->parseRules();
+        $this->data = new File_MARC_Lint_CodeData();
+    }
+    // }}}
+
+    // {{{ getWarnings()
+    /**
+     * Check the provided MARC record and return an array of warning messages.
+     *
+     * @param File_MARC_Record $marc Record to check
+     *
+     * @return array
+     */
+    public function checkRecord($marc)
+    {
+        // Reset warnings:
+        $this->warnings = array();
+
+        // Fail if we didn't get a valid object:
+        if (!is_a($marc, 'File_MARC_Record')) {
+            $this->warn('Must pass a File_MARC_Record object to checkRecord');
+        } else {
+            $this->checkDuplicate1xx($marc);
+            $this->checkMissing245($marc);
+            $this->standardFieldChecks($marc);
+        }
+
+        return $this->warnings;
+    }
+    // }}}
+
+    // {{{ warn()
+    /**
+     * Add a warning.
+     *
+     * @param string $warning Warning to add
+     *
+     * @return void
+     */
+    protected function warn($warning)
+    {
+        $this->warnings[] = $warning;
+    }
+    // }}}
+
+    // {{{ checkDuplicate1xx()
+    /**
+     * Check for multiple 1xx fields.
+     *
+     * @param File_MARC_Record $marc Record to check
+     *
+     * @return void
+     */
+    protected function checkDuplicate1xx($marc)
+    {
+        $result = $marc->getFields('1[0-9][0-9]', true);
+        $count = count($result);
+        if ($count > 1) {
+            $this->warn(
+                "1XX: Only one 1XX tag is allowed, but I found $count of them."
+            );
+        }
+    }
+    // }}}
+
+    // {{{ checkMissing245()
+    /**
+     * Check for missing 245 field.
+     *
+     * @param File_MARC_Record $marc Record to check
+     *
+     * @return void
+     */
+    protected function checkMissing245($marc)
+    {
+        $result = $marc->getFields('245');
+        if (count($result) == 0) {
+            $this->warn('245: No 245 tag.');
+        }
+    }
+    // }}}
+
+    // {{{ standardFieldChecks()
+    /**
+     * Check all fields against the standard rules encoded in the class.
+     *
+     * @param File_MARC_Record $marc Record to check
+     *
+     * @return void
+     */
+    protected function standardFieldChecks($marc)
+    {
+        $fieldsSeen = array();
+        foreach ($marc->getFields() as $current) {
+            $tagNo = $current->getTag();
+            // if 880 field, inherit rules from tagno in subfield _6
+            if ($tagNo == 880) {
+                if ($sub6 = $current->getSubfield(6)) {
+                    $tagNo = substr($sub6->getData(), 0, 3);
+                    $tagrules = isset($this->rules[$tagNo])
+                        ? $this->rules[$tagNo] : null;
+                    // 880 is repeatable, but its linked field may not be
+                    if (isset($tagrules['repeatable'])
+                        && $tagrules['repeatable'] == 'NR'
+                        && isset($fieldsSeen['880.'.$tagNo])
+                    ) {
+                        $this->warn("$tagNo: Field is not repeatable.");
+                    }
+                    $fieldsSeen['880.'.$tagNo] = isset($fieldsSeen['880.'.$tagNo])
+                        ? $fieldsSeen['880.'.$tagNo] + 1 : 1;
+                } else {
+                    $this->warn("880: No subfield 6.");
+                    $tagRules = null;
+                }
+            } else {
+                // Default case -- not an 880 field:
+                $tagrules = isset($this->rules[$tagNo])
+                    ? $this->rules[$tagNo] : null;
+                if (isset($tagrules['repeatable']) && $tagrules['repeatable'] == 'NR'
+                    && isset($fieldsSeen[$tagNo])
+                ) {
+                    $this->warn("$tagNo: Field is not repeatable.");
+                }
+                $fieldsSeen[$tagNo] = isset($fieldsSeen[$tagNo])
+                    ? $fieldsSeen[$tagNo] + 1 : 1;
+            }
+
+            // Treat data fields differently from control fields:
+            if (intval(ltrim($tagNo, '0')) >= 10) {
+                if (!empty($tagrules)) {
+                    $this->checkIndicators($tagNo, $current, $tagrules);
+                    $this->checkSubfields($tagNo, $current, $tagrules);
+                }
+            } else {
+                // Control field:
+                if (strstr($current->toRaw(), chr(hexdec('1F')))) {
+                    $this->warn(
+                        "$tagNo: Subfields are not allowed in fields lower than 010"
+                    );
+                }
+            }
+
+            // Check to see if a checkxxx() function exists, and call it on the
+            // field if it does
+            $method = 'check' . $tagNo;
+            if (method_exists($this, $method)) {
+                $this->$method($current);
+            }
+        }
+    }
+    // }}}
+
+    // {{{ checkIndicators()
+    /**
+     * Check the indicators for the provided field.
+     *
+     * @param string          $tagNo Tag number being checked
+     * @param File_MARC_Field $field Field to check
+     * @param array           $rules Rules to use for checking
+     *
+     * @return void
+     */
+    protected function checkIndicators($tagNo, $field, $rules)
+    {
+        for ($i = 1; $i <= 2; $i++) {
+            $ind = $field->getIndicator($i);
+            if ($ind === false || $ind == ' ') {
+                $ind = 'b';
+            }
+            if (!strstr($rules['ind' . $i]['values'], $ind)) {
+                // Make indicator blank value human-readable for message:
+                if ($ind == 'b') {
+                    $ind = 'blank';
+                }
+                $this->warn(
+                    "$tagNo: Indicator $i must be "
+                    . $rules['ind' . $i]['hr_values']
+                    . " but it's \"$ind\""
+                );
+            }
+        }
+    }
+    // }}}
+
+    // {{{ checkSubfields()
+    /**
+     * Check the subfields for the provided field.
+     *
+     * @param string          $tagNo Tag number being checked
+     * @param File_MARC_Field $field Field to check
+     * @param array           $rules Rules to use for checking
+     *
+     * @return void
+     */
+    protected function checkSubfields($tagNo, $field, $rules)
+    {
+        $subSeen = array();
+
+        foreach ($field->getSubfields() as $current) {
+            $code = $current->getCode();
+            $data = $current->getData();
+
+            $subrules = isset($rules['sub' . $code])
+                ? $rules['sub' . $code] : null;
+
+            if (empty($subrules)) {
+                $this->warn("$tagNo: Subfield _$code is not allowed.");
+            } elseif ($subrules['repeatable'] == 'NR' && isset($subSeen[$code])) {
+                $this->warn("$tagNo: Subfield _$code is not repeatable.");
+            }
+
+            if (preg_match('/\r|\t|\n/', $data)) {
+                $this->warn(
+                    "$tagNo: Subfield _$code has an invalid control character"
+                );
+            }
+
+            $subSeen[$code] = isset($subSeen[$code]) ? $subSeen[$code]++ : 1;
+        }
+    }
+    // }}}
+
+    // {{{ check020()
+    /**
+     * Looks at 020$a and reports errors if the check digit is wrong.
+     * Looks at 020$z and validates number if hyphens are present.
+     *
+     * @param File_MARC_Field $field Field to check
+     *
+     * @return void
+     */
+    protected function check020($field)
+    {
+        foreach ($field->getSubfields() as $current) {
+            $data = $current->getData();
+            // remove any hyphens
+            $isbn = str_replace('-', '', $data);
+            // remove nondigits
+            $isbn = preg_replace('/^\D*(\d{9,12}[X\d])\b.*$/', '$1', $isbn);
+
+            if ($current->getCode() == 'a') {
+                if ((substr($data, 0, strlen($isbn)) != $isbn)) {
+                    $this->warn("020: Subfield a may have invalid characters.");
+                }
+
+                // report error if no space precedes a qualifier in subfield a
+                if (preg_match('/\(/', $data) && !preg_match('/[X0-9] \(/', $data)) {
+                    $this->warn(
+                        "020: Subfield a qualifier must be preceded by space, $data."
+                    );
+                }
+
+                // report error if unable to find 10-13 digit string of digits in
+                // subfield 'a'
+                if (!preg_match('/(?:^\d{10}$)|(?:^\d{13}$)|(?:^\d{9}X$)/', $isbn)) {
+                    $this->warn(
+                        "020: Subfield a has the wrong number of digits, $data."
+                    );
+                } else {
+                    if (strlen($isbn) == 10) {
+                        if (!Validate_ISPN::isbn10($isbn)) {
+                            $this->warn("020: Subfield a has bad checksum, $data.");
+                        }
+                    } else if (strlen($isbn) == 13) {
+                        if (!Validate_ISPN::isbn13($isbn)) {
+                            $this->warn(
+                                "020: Subfield a has bad checksum (13 digit), $data."
+                            );
+                        }
+                    }
+                }
+            } else if ($current->getCode() == 'z') {
+                // look for valid isbn in 020$z
+                if (preg_match('/^ISBN/', $data)
+                    || preg_match('/^\d*\-\d+/', $data)
+                ) {
+                    // ##################################################
+                    // ## Turned on for now--Comment to unimplement  ####
+                    // ##################################################
+                    if ((strlen($isbn) == 10)
+                        && (Validate_ISPN::isbn10($isbn) == 1)
+                    ) {
+                        $this->warn("020:  Subfield z is numerically valid.");
+                    }
+                }
+            }
+        }
+    }
+    // }}}
+
+    // {{{ check041()
+    /**
+     * Warns if subfields are not evenly divisible by 3 unless second indicator is 7
+     * (future implementation would ensure that each subfield is exactly 3 characters
+     * unless ind2 is 7--since subfields are now repeatable. This is not implemented
+     * here due to the large number of records needing to be corrected.). Validates
+     * against the MARC Code List for Languages (<http://www.loc.gov/marc/>).
+     *
+     * @param File_MARC_Field $field Field to check
+     *
+     * @return void
+     */
+    protected function check041($field)
+    {
+        // warn if length of each subfield is not divisible by 3 unless ind2 is 7
+        if ($field->getIndicator(2) != '7') {
+            foreach ($field->getSubfields() as $sub) {
+                $code = $sub->getCode();
+                $data = $sub->getData();
+                if (strlen($data) % 3 != 0) {
+                    $this->warn(
+                        "041: Subfield _$code must be evenly divisible by 3 or "
+                        . "exactly three characters if ind2 is not 7, ($data)."
+                    );
+                } else {
+                    for ($i = 0; $i < strlen($data); $i += 3) {
+                        $chk = substr($data, $i, 3);
+                        if (!in_array($chk, $this->data->languageCodes)) {
+                            $obs = $this->data->obsoleteLanguageCodes;
+                            if (in_array($chk, $obs)) {
+                                $this->warn(
+                                    "041: Subfield _$code, $data, may be obsolete."
+                                );
+                            } else {
+                                $this->warn(
+                                    "041: Subfield _$code, $data ($chk),"
+                                    . " is not valid."
+                                );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    // }}}
+
+    // {{{ check043()
+    /**
+     * Warns if each subfield a is not exactly 7 characters. Validates each code
+     * against the MARC code list for Geographic Areas (<http://www.loc.gov/marc/>).
+     *
+     * @param File_MARC_Field $field Field to check
+     *
+     * @return void
+     */
+    protected function check043($field)
+    {
+        foreach ($field->getSubfields('a') as $suba) {
+            // warn if length of subfield a is not exactly 7
+            $data = $suba->getData();
+            if (strlen($data) != 7) {
+                $this->warn("043: Subfield _a must be exactly 7 characters, $data");
+            } else if (!in_array($data, $this->data->geogAreaCodes)) {
+                if (in_array($data, $this->data->obsoleteGeogAreaCodes)) {
+                    $this->warn("043: Subfield _a, $data, may be obsolete.");
+                } else {
+                    $this->warn("043: Subfield _a, $data, is not valid.");
+                }
+            }
+        }
+    }
+    // }}}
+
+    // {{{ check245()
+    /**
+     * -Makes sure $a exists (and is first subfield).
+     * -Warns if last character of field is not a period
+     * --Follows LCRI 1.0C, Nov. 2003 rather than MARC21 rule
+     * -Verifies that $c is preceded by / (space-/)
+     * -Verifies that initials in $c are not spaced
+     * -Verifies that $b is preceded by :;= (space-colon, space-semicolon,
+     *  space-equals)
+     * -Verifies that $h is not preceded by space unless it is dash-space
+     * -Verifies that data of $h is enclosed in square brackets
+     * -Verifies that $n is preceded by . (period)
+     * --As part of that, looks for no-space period, or dash-space-period
+     *  (for replaced elipses)
+     * -Verifies that $p is preceded by , (no-space-comma) when following $n and
+     *  . (period) when following other subfields.
+     * -Performs rudimentary article check of 245 2nd indicator vs. 1st word of
+     *  245$a (for manual verification).
+     *
+     * Article checking is done by internal checkArticle method, which should work
+     * for 130, 240, 245, 440, 630, 730, and 830.
+     *
+     * @param File_MARC_Field $field Field to check
+     *
+     * @return void
+     */
+    protected function check245($field)
+    {
+        if (count($field->getSubfields('a')) == 0) {
+            $this->warn("245: Must have a subfield _a.");
+        }
+
+        // Convert subfields to array and set flags indicating which subfields are
+        // present while we're at it.
+        $tmp = $field->getSubfields();
+        $hasSubfields = $subfields = array();
+        foreach ($tmp as $current) {
+            $subfields[] = $current;
+            $hasSubfields[$current->getCode()] = true;
+        }
+
+        // 245 must end in period (may want to make this less restrictive by allowing
+        // trailing spaces)
+        // do 2 checks--for final punctuation (MARC21 rule), and for period
+        // (LCRI 1.0C, Nov. 2003)
+        $lastChar = substr($subfields[count($subfields)-1]->getData(), -1);
+        if (!in_array($lastChar, array('.', '?', '!'))) {
+            $this->warn("245: Must end with . (period).");
+        } else if ($lastChar != '.') {
+            $this->warn(
+                "245: MARC21 allows ? or ! as final punctuation but LCRI 1.0C, Nov."
+                . " 2003, requires period."
+            );
+        }
+
+        // Check for first subfield
+        // subfield a should be first subfield (or 2nd if subfield '6' is present)
+        if (isset($hasSubfields['6'])) {
+            // make sure there are at least 2 subfields
+            if (count($subfields) < 2) {
+                $this->warn("245: May have too few subfields.");
+            } else {
+                $first = $subfields[0]->getCode();
+                $second = $subfields[1]->getCode();
+                if ($first != '6') {
+                    $this->warn("245: First subfield must be _6, but it is $first");
+                }
+                if ($second != 'a') {
+                    $this->warn(
+                        "245: First subfield after subfield _6 must be _a, but it "
+                        . "is _$second"
+                    );
+                }
+            }
+        } else {
+            // 1st subfield must be 'a'
+            $first = $subfields[0]->getCode();
+            if ($first != 'a') {
+                $this->warn("245: First subfield must be _a, but it is _$first");
+            }
+        }
+        // End check for first subfield
+
+        // subfield c, if present, must be preceded by /
+        // also look for space between initials
+        if (isset($hasSubfields['c'])) {
+            foreach ($subfields as $i => $current) {
+                // 245 subfield c must be preceded by / (space-/)
+                if ($current->getCode() == 'c') {
+                    if ($i > 0
+                        && !preg_match('/\s\/$/', $subfields[$i-1]->getData())
+                    ) {
+                        $this->warn("245: Subfield _c must be preceded by /");
+                    }
+                    // 245 subfield c initials should not have space
+                    if (preg_match('/\b\w\. \b\w\./', $current->getData())) {
+                        $this->warn(
+                            "245: Subfield _c initials should not have a space."
+                        );
+                    }
+                    break;
+                }
+            }
+        }
+
+        // each subfield b, if present, should be preceded by :;= (colon, semicolon,
+        // or equals sign)
+        if (isset($hasSubfields['b'])) {
+            // 245 subfield b should be preceded by space-:;= (colon, semicolon, or
+            // equals sign)
+            foreach ($subfields as $i => $current) {
+                if ($current->getCode() == 'b' && $i > 0
+                    && !preg_match('/ [:;=]$/', $subfields[$i-1]->getData())
+                ) {
+                    $this->warn(
+                        "245: Subfield _b should be preceded by space-colon, "
+                        . "space-semicolon, or space-equals sign."
+                    );
+                }
+            }
+        }
+
+        // each subfield h, if present, should be preceded by non-space
+        if (isset($hasSubfields['h'])) {
+            // 245 subfield h should not be preceded by space
+            foreach ($subfields as $i => $current) {
+                // report error if subfield 'h' is preceded by space (unless
+                // dash-space)
+                if ($current->getCode() == 'h') {
+                    $prev = $subfields[$i-1]->getData();
+                    if ($i > 0 && !preg_match('/(\S$)|(\-\- $)/', $prev)) {
+                        $this->warn(
+                            "245: Subfield _h should not be preceded by space."
+                        );
+                    }
+                    // report error if subfield 'h' does not start with open square
+                    // bracket with a matching close bracket; could have check
+                    // against list of valid values here
+                    $data = $current->getData();
+                    if (!preg_match('/^\[\w*\s*\w*\]/', $data)) {
+                        $this->warn(
+                            "245: Subfield _h must have matching square brackets,"
+                            . " $data."
+                        );
+                    }
+                }
+            }
+        }
+
+        // each subfield n, if present, must be preceded by . (period)
+        if (isset($hasSubfields['n'])) {
+            // 245 subfield n must be preceded by . (period)
+            foreach ($subfields as $i => $current) {
+                // report error if subfield 'n' is not preceded by non-space-period
+                // or dash-space-period
+                if ($current->getCode() == 'n' && $i > 0) {
+                    $prev = $subfields[$i-1]->getData();
+                    if (!preg_match('/(\S\.$)|(\-\- \.$)/', $prev)) {
+                        $this->warn(
+                            "245: Subfield _n must be preceded by . (period)."
+                        );
+                    }
+                }
+            }
+        }
+
+        // each subfield p, if present, must be preceded by a , (no-space-comma)
+        // if it follows subfield n, or by . (no-space-period or
+        // dash-space-period) following other subfields
+        if (isset($hasSubfields['p'])) {
+            // 245 subfield p must be preceded by . (period) or , (comma)
+            foreach ($subfields as $i => $current) {
+                if ($current->getCode() == 'p' && $i > 0) {
+                    $prev = $subfields[$i-1];
+                    // case for subfield 'n' being field before this one (allows
+                    // dash-space-comma)
+                    if ($prev->getCode() == 'n'
+                        && !preg_match('/(\S,$)|(\-\- ,$)/', $prev->getData())
+                    ) {
+                        $this->warn(
+                            "245: Subfield _p must be preceded by , (comma) "
+                            . "when it follows subfield _n."
+                        );
+                    } else if ($prev->getCode() != 'n'
+                        && !preg_match('/(\S\.$)|(\-\- \.$)/', $prev->getData())
+                    ) {
+                        $this->warn(
+                            "245: Subfield _p must be preceded by . (period)"
+                            . " when it follows a subfield other than _n."
+                        );
+                    }
+                }
+            }
+        }
+
+        // check for invalid 2nd indicator
+        $this->checkArticle($field);
+    }
+    // }}}
+
+    // {{{ checkArticle()
+    /**
+     * Check of articles is based on code from Ian Hamilton. This version is more
+     * limited in that it focuses on English, Spanish, French, Italian and German
+     * articles. Certain possible articles have been removed if they are valid
+     * English non-articles. This version also disregards 008_language/041 codes
+     * and just uses the list of articles to provide warnings/suggestions.
+     *
+     * source for articles = <http://www.loc.gov/marc/bibliographic/bdapp-e.html>
+     *
+     * Should work with fields 130, 240, 245, 440, 630, 730, and 830. Reports error
+     * if another field is passed in.
+     *
+     * @param File_MARC_Field $field Field to check
+     *
+     * @return void
+     */
+    protected function checkArticle($field)
+    {
+        // add articles here as needed
+        // Some omitted due to similarity with valid words (e.g. the German 'die').
+        static $article = array(
+            'a' => 'eng glg hun por',
+            'an' => 'eng',
+            'das' => 'ger',
+            'dem' => 'ger',
+            'der' => 'ger',
+            'ein' => 'ger',
+            'eine' => 'ger',
+            'einem' => 'ger',
+            'einen' => 'ger',
+            'einer' => 'ger',
+            'eines' => 'ger',
+            'el' => 'spa',
+            'en' => 'cat dan nor swe',
+            'gl' => 'ita',
+            'gli' => 'ita',
+            'il' => 'ita mlt',
+            'l' => 'cat fre ita mlt',
+            'la' => 'cat fre ita spa',
+            'las' => 'spa',
+            'le' => 'fre ita',
+            'les' => 'cat fre',
+            'lo' => 'ita spa',
+            'los' => 'spa',
+            'os' => 'por',
+            'the' => 'eng',
+            'um' => 'por',
+            'uma' => 'por',
+            'un' => 'cat spa fre ita',
+            'una' => 'cat spa ita',
+            'une' => 'fre',
+            'uno' => 'ita',
+        );
+
+        // add exceptions here as needed
+        // may want to make keys lowercase
+        static $exceptions = array(
+            'A & E',
+            'A-',
+            'A+',
+            'A is ',
+            'A isn\'t ',
+            'A l\'',
+            'A la ',
+            'A posteriori',
+            'A priori',
+            'A to ',
+            'El Nino',
+            'El Salvador',
+            'L-',
+            'La Salle',
+            'Las Vegas',
+            'Lo mein',
+            'Los Alamos',
+            'Los Angeles',
+        );
+
+        // get tagno to determine which indicator to check and for reporting
+        $tagNo = $field->getTag();
+        // retrieve tagno from subfield 6 if 880 field
+        if ($tagNo == '880' && ($sub6 = $field->getSubfield('6'))) {
+            $tagNo = substr($sub6->getData(), 0, 3);
+        }
+
+        // $ind holds nonfiling character indicator value
+        $ind = '';
+        // $first_or_second holds which indicator is for nonfiling char value
+        $first_or_second = '';
+        if (in_array($tagNo, array(130, 630, 730))) {
+            $ind = $field->getIndicator(1);
+            $first_or_second = '1st';
+        } else if (in_array($tagNo, array(240, 245, 440, 830))) {
+            $ind = $field->getIndicator(2);
+            $first_or_second = '2nd';
+        } else {
+            $this->warn(
+                'Internal error: ' . $tagNo
+                . " is not a valid field for article checking\n"
+            );
+            return;
+        }
+
+        if (!is_numeric($ind)) {
+            $this->warn($tagNo . ": Non-filing indicator is non-numeric");
+            return;
+        }
+
+        // get subfield 'a' of the title field
+        $titleField = $field->getSubfield('a');
+        $title = $titleField ? $titleField->getData() : '';
+
+        $char1_notalphanum = 0;
+        // check for apostrophe, quote, bracket,  or parenthesis, before first word
+        // remove if found and add to non-word counter
+        while (preg_match('/^["\'\[\(*]/', $title)) {
+            $char1_notalphanum++;
+            $title = preg_replace('/^["\'\[\(*]/', '', $title);
+        }
+        // split title into first word + rest on space, parens, bracket, apostrophe,
+        // quote, or hyphen
+        preg_match('/^([^ \(\)\[\]\'"\-]+)([ \(\)\[\]\'"\-])?(.*)/i', $title, $hits);
+        $firstword = isset($hits[1]) ? $hits[1] : '';
+        $separator = isset($hits[2]) ? $hits[2] : '';
+        $etc = isset($hits[3]) ? $hits[3] : '';
+
+        // get length of first word plus the number of chars removed above plus one
+        // for the separator
+        $nonfilingchars = strlen($firstword) + $char1_notalphanum + 1;
+
+        // check to see if first word is an exception
+        $isan_exception = false;
+        foreach ($exceptions as $current) {
+            if (substr($title, 0, strlen($current)) == $current) {
+                $isan_exception = true;
+                break;
+            }
+        }
+
+        // lowercase chars of $firstword for comparison with article list
+        $firstword = strtolower($firstword);
+
+        // see if first word is in the list of articles and not an exception
+        $isan_article = !$isan_exception && isset($article[$firstword]);
+
+        // if article then $nonfilingchars should match $ind
+        if ($isan_article) {
+            // account for quotes, apostrophes, parens, or brackets before 2nd word
+            if (strlen($separator) && preg_match('/^[ \(\)\[\]\'"\-]+/', $etc)) {
+                while (preg_match('/^[ "\'\[\]\(\)*]/', $etc)) {
+                    $nonfilingchars++;
+                    $etc = preg_replace('/^[ "\'\[\]\(\)*]/', '', $etc);
+                }
+            }
+            if ($nonfilingchars != $ind) {
+                $this->warn(
+                    $tagNo . ": First word, $firstword, may be an article, check "
+                    . "$first_or_second indicator ($ind)."
+                );
+            }
+        } else {
+            // not an article so warn if $ind is not 0
+            if ($ind != '0') {
+                $this->warn(
+                    $tagNo . ": First word, $firstword, does not appear to be an "
+                    . "article, check $first_or_second indicator ($ind)."
+                );
+            }
+        }
+    }
+    // }}}
+
+    // {{{ parseRules()
+    /**
+     * Support method for constructor to load MARC rules.
+     *
+     * @return void
+     */
+    protected function parseRules()
+    {
+        // Break apart the rule data on line breaks:
+        $lines = explode("\n", $this->getRawRules());
+
+        // Each group of data is split by a blank line -- process one group
+        // at a time:
+        $currentGroup = array();
+        foreach ($lines as $currentLine) {
+            if (empty($currentLine) && !empty($currentGroup)) {
+                $this->processRuleGroup($currentGroup);
+                $currentGroup = array();
+            } else {
+                $currentGroup[] = preg_replace("/\s+/", " ", $currentLine);
+            }
+        }
+
+        // Still have unprocessed data after the loop?  Handle it now:
+        if (!empty($currentGroup)) {
+            $this->processRuleGroup($currentGroup);
+        }
+    }
+    // }}}
+
+    // {{{ processRuleGroup()
+    /**
+     * Support method for parseRules() -- process one group of lines representing
+     * a single tag.
+     *
+     * @param array $rules Rule lines to process
+     *
+     * @return void
+     */
+    protected function processRuleGroup($rules)
+    {
+        // The first line is guaranteed to exist and gives us some basic info:
+        list($tag, $repeatable, $description) = explode(' ', $rules[0]);
+        $this->rules[$tag] = array(
+            'repeatable' => $repeatable,
+            'desc' => $description
+        );
+
+        // We may or may not have additional details:
+        for ($i = 1; $i < count($rules); $i++) {
+            list($key, $value, $lineDesc) = explode(' ', $rules[$i]);
+            if (substr($key, 0, 3) == 'ind') {
+                // Expand ranges:
+                $value = str_replace('0-9', '0123456789', $value);
+                $this->rules[$tag][$key] = array(
+                    'values' => $value,
+                    'hr_values' => $this->getHumanReadableIndicatorValues($value),
+                    'desc'=> $lineDesc
+                );
+            } else {
+                if (strlen($key) <= 1) {
+                    $this->rules[$tag]['sub' . $key] = array(
+                        'repeatable' => $value,
+                        'desc' => $lineDesc
+                    );
+                } elseif (strstr($key, '-')) {
+                    list($startKey, $endKey) = explode('-', $key);
+                    for ($key = $startKey; $key <= $endKey; $key++) {
+                        $this->rules[$tag]['sub' . $key] = array(
+                            'repeatable' => $value,
+                            'desc' => $lineDesc
+                        );
+                    }
+                }
+            }
+        }
+    }
+    // }}}
+
+    // {{{ getHumanReadableIndicatorValues()
+    /**
+     * Turn a set of indicator rules into a human-readable list.
+     *
+     * @param string $rules Indicator rules
+     *
+     * @return string
+     */
+    protected function getHumanReadableIndicatorValues($rules)
+    {
+        // No processing needed for blank rule:
+        if ($rules == 'blank') {
+            return $rules;
+        }
+
+        // Create string:
+        $string = '';
+        $length = strlen($rules);
+        for ($i = 0; $i < $length; $i++) {
+            $current = substr($rules, $i, 1);
+            if ($current == 'b') {
+                $current = 'blank';
+            }
+            $string .= $current;
+            if ($length - $i == 2) {
+                $string .= ' or ';
+            } else if ($length - $i > 2) {
+                $string .= ', ';
+            }
+        }
+
+        return $string;
+    }
+    // }}}
+
+    // {{{ getRawRules()
+    /**
+     * Support method for parseRules() -- get the raw rules from MARC::Lint.
+     *
+     * @return string
+     */
+    protected function getRawRules()
+    {
+        // When updating rules, don't forget to escape the dollar signs in the text!
+        // It would be simpler to change from HEREDOC to NOWDOC syntax, but that
+        // would raise the requirements to PHP 5.3.
+        // @codingStandardsIgnoreStart
+        return <<<RULES
+001     NR      CONTROL NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+        NR      Undefined
+
+002     NR      LOCALLY DEFINED (UNOFFICIAL)
+ind1    blank   Undefined
+ind2    blank   Undefined
+        NR      Undefined
+
+003     NR      CONTROL NUMBER IDENTIFIER
+ind1    blank   Undefined
+ind2    blank   Undefined
+        NR      Undefined
+
+005     NR      DATE AND TIME OF LATEST TRANSACTION
+ind1    blank   Undefined
+ind2    blank   Undefined
+        NR      Undefined
+
+006     R       FIXED-LENGTH DATA ELEMENTS--ADDITIONAL MATERIAL CHARACTERISTICS--GENERAL INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+        R       Undefined
+
+007     R       PHYSICAL DESCRIPTION FIXED FIELD--GENERAL INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+        R       Undefined
+
+008     NR      FIXED-LENGTH DATA ELEMENTS--GENERAL INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+        NR      Undefined
+
+010     NR      LIBRARY OF CONGRESS CONTROL NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      LC control number
+b       R       NUCMC control number
+z       R       Canceled/invalid LC control number
+8       R       Field link and sequence number
+
+013     R       PATENT CONTROL INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Number
+b       NR      Country
+c       NR      Type of number
+d       R       Date
+e       R       Status
+f       R       Party to document
+6       NR      Linkage
+8       R       Field link and sequence number
+
+015     R       NATIONAL BIBLIOGRAPHY NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       National bibliography number
+z       R       Canceled/Invalid national bibliography number
+2       NR      Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+016     R       NATIONAL BIBLIOGRAPHIC AGENCY CONTROL NUMBER
+ind1    b7      National bibliographic agency
+ind2    blank   Undefined
+a       NR      Record control number
+z       R       Canceled or invalid record control number
+2       NR      Source
+8       R       Field link and sequence number
+
+017     R       COPYRIGHT OR LEGAL DEPOSIT NUMBER
+ind1    blank   Undefined
+ind2    b8      Undefined
+a       R       Copyright or legal deposit number
+b       NR      Assigning agency
+d       NR      Date
+i       NR      Display text
+z       R       Canceled/invalid copyright or legal deposit number
+2       NR      Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+018     NR      COPYRIGHT ARTICLE-FEE CODE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Copyright article-fee code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+020     R       INTERNATIONAL STANDARD BOOK NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      International Standard Book Number
+c       NR      Terms of availability
+z       R       Canceled/invalid ISBN
+6       NR      Linkage
+8       R       Field link and sequence number
+
+022     R       INTERNATIONAL STANDARD SERIAL NUMBER
+ind1    b01     Level of international interest
+ind2    blank   Undefined
+a       NR      International Standard Serial Number
+l       NR      ISSN-L
+m       R       Canceled ISSN-L
+y       R       Incorrect ISSN
+z       R       Canceled ISSN
+2       NR      Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+024     R       OTHER STANDARD IDENTIFIER
+ind1    0123478    Type of standard number or code
+ind2    b01     Difference indicator
+a       NR      Standard number or code
+c       NR      Terms of availability
+d       NR      Additional codes following the standard number or code
+z       R       Canceled/invalid standard number or code
+2       NR      Source of number or code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+025     R       OVERSEAS ACQUISITION NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Overseas acquisition number
+8       R       Field link and sequence number
+
+026     R       FINGERPRINT IDENTIFIER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       First and second groups of characters
+b       R       Third and fourth groups of characters
+c       NR      Date
+d       R       Number of volume or part
+e       NR      Unparsed fingerprint
+2       NR      Source
+5       R       Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+027     R       STANDARD TECHNICAL REPORT NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Standard technical report number
+z       R       Canceled/invalid number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+028     R       PUBLISHER NUMBER
+ind1    012345  Type of publisher number
+ind2    0123    Note/added entry controller
+a       NR      Publisher number
+b       NR      Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+030     R       CODEN DESIGNATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      CODEN
+z       R       Canceled/invalid CODEN
+6       NR      Linkage
+8       R       Field link and sequence number
+
+031     R       MUSICAL INCIPITS INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Number of work
+b       NR      Number of movement
+c       NR      Number of excerpt
+d       R       Caption or heading
+e       NR      Role
+g       NR      Clef
+m       NR      Voice/instrument
+n       NR      Key signature
+o       NR      Time signature
+p       NR      Musical notation
+q       R       General note
+r       NR      Key or mode
+s       R       Coded validity note
+t       R       Text incipit
+u       R       Uniform Resource Identifier
+y       R       Link text
+z       R       Public note
+2       NR      System code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+032     R       POSTAL REGISTRATION NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Postal registration number
+b       NR      Source (agency assigning number)
+6       NR      Linkage
+8       R       Field link and sequence number
+
+033     R       DATE/TIME AND PLACE OF AN EVENT
+ind1    b012    Type of date in subfield \$a
+ind2    b012    Type of event
+a       R       Formatted date/time
+b       R       Geographic classification area code
+c       R       Geographic classification subarea code
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+034     R       CODED CARTOGRAPHIC MATHEMATICAL DATA
+ind1    013     Type of scale
+ind2    b01     Type of ring
+a       NR      Category of scale
+b       R       Constant ratio linear horizontal scale
+c       R       Constant ratio linear vertical scale
+d       NR      Coordinates--westernmost longitude
+e       NR      Coordinates--easternmost longitude
+f       NR      Coordinates--northernmost latitude
+g       NR      Coordinates--southernmost latitude
+h       R       Angular scale
+j       NR      Declination--northern limit
+k       NR      Declination--southern limit
+m       NR      Right ascension--eastern limit
+n       NR      Right ascension--western limit
+p       NR      Equinox
+r       NR      Distance from earth
+s       R       G-ring latitude
+t       R       G-ring longitude
+x       NR      Beginning date
+y       NR      Ending date
+z       NR      Name of extraterrestrial body
+2       NR      Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+035     R       SYSTEM CONTROL NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      System control number
+z       R       Canceled/invalid control number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+036     NR      ORIGINAL STUDY NUMBER FOR COMPUTER DATA FILES
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Original study number
+b       NR      Source (agency assigning number)
+6       NR      Linkage
+8       R       Field link and sequence number
+
+037     R       SOURCE OF ACQUISITION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Stock number
+b       NR      Source of stock number/acquisition
+c       R       Terms of availability
+f       R       Form of issue
+g       R       Additional format characteristics
+n       R       Note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+038     NR      RECORD CONTENT LICENSOR
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Record content licensor
+6       NR      Linkage
+8       R       Field link and sequence number
+
+040     NR      CATALOGING SOURCE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Original cataloging agency
+b       NR      Language of cataloging
+c       NR      Transcribing agency
+d       R       Modifying agency
+e       NR      Description conventions
+6       NR      Linkage
+8       R       Field link and sequence number
+
+041     R       LANGUAGE CODE
+ind1    b01      Translation indication
+ind2    b7      Source of code
+a       R       Language code of text/sound track or separate title
+b       R       Language code of summary or abstract
+d       R       Language code of sung or spoken text
+e       R       Language code of librettos
+f       R       Language code of table of contents
+g       R       Language code of accompanying material other than librettos
+h       R       Language code of original and/or intermediate translations of text
+j       R       Language code of subtitles or captions
+2       NR      Source of code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+042     NR      AUTHENTICATION CODE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Authentication code
+
+043     NR      GEOGRAPHIC AREA CODE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Geographic area code
+b       R       Local GAC code
+c       R       ISO code
+2       R       Source of local code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+044     NR      COUNTRY OF PUBLISHING/PRODUCING ENTITY CODE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       MARC country code
+b       R       Local subentity code
+c       R       ISO country code
+2       R       Source of local subentity code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+045     NR      TIME PERIOD OF CONTENT
+ind1    b012    Type of time period in subfield \$b or \$c
+ind2    blank   Undefined
+a       R       Time period code
+b       R       Formatted 9999 B.C. through C.E. time period
+c       R       Formatted pre-9999 B.C. time period
+6       NR      Linkage
+8       R       Field link and sequence number
+
+046     R       SPECIAL CODED DATES
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Type of date code
+b       NR      Date 1 (B.C. date)
+c       NR      Date 1 (C.E. date)
+d       NR      Date 2 (B.C. date)
+e       NR      Date 2 (C.E. date)
+j       NR      Date resource modified
+k       NR      Beginning or single date created
+l       NR      Ending date created
+m       NR      Beginning of date valid
+n       NR      End of date valid
+2       NR      Source of date
+6       NR      Linkage
+8       R       Field link and sequence number
+
+047     R       FORM OF MUSICAL COMPOSITION CODE
+ind1    blank   Undefined
+ind2    b7      Source of code
+a       R       Form of musical composition code
+2       NR      Source of code
+8       R       Field link and sequence number
+
+048     R       NUMBER OF MUSICAL INSTRUMENTS OR VOICES CODE
+ind1    blank   Undefined
+ind2    b7      Source specified in subfield \$2
+a       R       Performer or ensemble
+b       R       Soloist
+2       NR      Source of code
+8       R       Field link and sequence number
+
+050     R       LIBRARY OF CONGRESS CALL NUMBER
+ind1    b01     Existence in LC collection
+ind2    04      Source of call number
+a       R       Classification number
+b       NR      Item number
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+051     R       LIBRARY OF CONGRESS COPY, ISSUE, OFFPRINT STATEMENT
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Classification number
+b       NR      Item number
+c       NR      Copy information
+8       R       Field link and sequence number
+
+052     R       GEOGRAPHIC CLASSIFICATION
+ind1    b17     Code source
+ind2    blank   Undefined
+a       NR      Geographic classification area code
+b       R       Geographic classification subarea code
+d       R       Populated place name
+2       NR      Code source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+055     R       CLASSIFICATION NUMBERS ASSIGNED IN CANADA
+ind1    b01     Existence in LAC collection
+ind2    0123456789   Type, completeness, source of class/call number
+a       NR      Classification number
+b       NR      Item number
+2       NR      Source of call/class number
+8       R       Field link and sequence number
+
+060     R       NATIONAL LIBRARY OF MEDICINE CALL NUMBER
+ind1    b01     Existence in NLM collection
+ind2    04      Source of call number
+a       R       Classification number
+b       NR      Item number
+8       R       Field link and sequence number
+
+061     R       NATIONAL LIBRARY OF MEDICINE COPY STATEMENT
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Classification number
+b       NR      Item number
+c       NR      Copy information
+8       R       Field link and sequence number
+
+066     NR      CHARACTER SETS PRESENT
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Primary G0 character set
+b       NR      Primary G1 character set
+c       R       Alternate G0 or G1 character set
+
+070     R       NATIONAL AGRICULTURAL LIBRARY CALL NUMBER
+ind1    01      Existence in NAL collection
+ind2    blank   Undefined
+a       R       Classification number
+b       NR      Item number
+8       R       Field link and sequence number
+
+071     R       NATIONAL AGRICULTURAL LIBRARY COPY STATEMENT
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Classification number
+b       NR      Item number
+c       NR      Copy information
+8       R       Field link and sequence number
+
+072     R       SUBJECT CATEGORY CODE
+ind1    blank   Undefined
+ind2    07      Source specified in subfield \$2
+a       NR      Subject category code
+x       R       Subject category code subdivision
+2       NR      Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+074     R       GPO ITEM NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      GPO item number
+z       R       Canceled/invalid GPO item number
+8       R       Field link and sequence number
+
+080     R       UNIVERSAL DECIMAL CLASSIFICATION NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Universal Decimal Classification number
+b       NR      Item number
+x       R       Common auxiliary subdivision
+2       NR      Edition identifier
+6       NR      Linkage
+8       R       Field link and sequence number
+
+082     R       DEWEY DECIMAL CLASSIFICATION NUMBER
+ind1    01      Type of edition
+ind2    b04     Source of classification number
+a       R       Classification number
+b       NR      Item number
+m       NR      Standard or optional designation
+q       NR      Assigning agency
+2       NR      Edition number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+083     R       ADDITIONAL DEWEY DECIMAL CLASSIFICATION NUMBER
+ind1    01      Type of edition
+ind2    blank   Undefined
+a       R       Classification number
+c       R       Classification number--Ending number of span
+m       NR      Standard or optional designation
+q       NR      Assigning agency
+y       R       Table sequence number for internal subarrangement or add table
+z       R       Table identification
+2       NR      Edition number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+084     R       OTHER CLASSIFICATION NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Classification number
+b       NR      Item number
+2       NR      Source of number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+085     R       SYNTHESIZED CLASSIFICATION NUMBER COMPONENTS
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Number where instructions are found-single number or beginning number of span
+b       R       Base number
+c       R       Classification number-ending number of span
+f       R       Facet designator
+r       R       Root number
+s       R       Digits added from classification number in schedule or external table
+t       R       Digits added from internal subarrangement or add table
+u       R       Number being analyzed
+v       R       Number in internal subarrangement or add table where instructions are found
+w       R       Table identification-Internal subarrangement or add table
+y       R       Table sequence number for internal subarrangement or add table
+z       R       Table identification
+6       NR      Linkage
+8       R       Field link and sequence number
+
+086     R       GOVERNMENT DOCUMENT CLASSIFICATION NUMBER
+ind1    b01     Number source
+ind2    blank   Undefined
+a       NR      Classification number
+z       R       Canceled/invalid classification number
+2       NR      Number source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+088     R       REPORT NUMBER
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Report number
+z       R       Canceled/invalid report number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+100     NR      MAIN ENTRY--PERSONAL NAME
+ind1    013     Type of personal name entry element
+ind2    blank   Undefined
+a       NR      Personal name
+b       NR      Numeration
+c       R       Titles and other words associated with a name
+d       NR      Dates associated with a name
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+j       R       Attribution qualifier
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+q       NR      Fuller form of name
+t       NR      Title of a work
+u       NR      Affiliation
+0       R       Authority record control number
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+110     NR      MAIN ENTRY--CORPORATE NAME
+ind1    012     Type of corporate name entry element
+ind2    blank   Undefined
+a       NR      Corporate name or jurisdiction name as entry element
+b       R       Subordinate unit
+c       NR      Location of meeting
+d       R       Date of meeting or treaty signing
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+t       NR      Title of a work
+u       NR      Affiliation
+0       R       Authority record control number
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+111     NR      MAIN ENTRY--MEETING NAME
+ind1    012     Type of meeting name entry element
+ind2    blank   Undefined
+a       NR      Meeting name or jurisdiction name as entry element
+c       NR      Location of meeting
+d       NR      Date of meeting
+e       R       Subordinate unit
+f       NR      Date of a work
+g       NR      Miscellaneous information
+j       R       Relator term
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+q       NR      Name of meeting following jurisdiction name entry element
+t       NR      Title of a work
+u       NR      Affiliation
+0       R       Authority record control number
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+130     NR      MAIN ENTRY--UNIFORM TITLE
+ind1    0-9     Nonfiling characters
+ind2    blank   Undefined
+a       NR      Uniform title
+d       R       Date of treaty signing
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+0       R       Authority record control number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+210     R       ABBREVIATED TITLE
+ind1    01      Title added entry
+ind2    b0      Type
+a       NR      Abbreviated title
+b       NR      Qualifying information
+2       R       Source
+6       NR      Linkage
+8       R       Field link and sequence number
+
+222     R       KEY TITLE
+ind1    blank   Specifies whether variant title and/or added entry is required
+ind2    0-9     Nonfiling characters
+a       NR      Key title
+b       NR      Qualifying information
+6       NR      Linkage
+8       R       Field link and sequence number
+
+240     NR      UNIFORM TITLE
+ind1    01    Uniform title printed or displayed
+ind2    0-9    Nonfiling characters
+a       NR      Uniform title
+d       R       Date of treaty signing
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+0       R       Authority record control number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+242     R       TRANSLATION OF TITLE BY CATALOGING AGENCY
+ind1    01    Title added entry
+ind2    0-9    Nonfiling characters
+a       NR      Title
+b       NR      Remainder of title
+c       NR      Statement of responsibility, etc.
+h       NR      Medium
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+y       NR      Language code of translated title
+6       NR      Linkage
+8       R       Field link and sequence number
+
+243     NR      COLLECTIVE UNIFORM TITLE
+ind1    01    Uniform title printed or displayed
+ind2    0-9    Nonfiling characters
+a       NR      Uniform title
+d       R       Date of treaty signing
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+6       NR      Linkage
+8       R       Field link and sequence number
+
+245     NR      TITLE STATEMENT
+ind1    01    Title added entry
+ind2    0-9    Nonfiling characters
+a       NR      Title
+b       NR      Remainder of title
+c       NR      Statement of responsibility, etc.
+f       NR      Inclusive dates
+g       NR      Bulk dates
+h       NR      Medium
+k       R       Form
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+s       NR      Version
+6       NR      Linkage
+8       R       Field link and sequence number
+
+246     R       VARYING FORM OF TITLE
+ind1    0123    Note/added entry controller
+ind2    b012345678    Type of title
+a       NR      Title proper/short title
+b       NR      Remainder of title
+f       NR      Date or sequential designation
+g       NR      Miscellaneous information
+h       NR      Medium
+i       NR      Display text
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+247     R       FORMER TITLE
+ind1    01      Title added entry
+ind2    01      Note controller
+a       NR      Title
+b       NR      Remainder of title
+f       NR      Date or sequential designation
+g       NR      Miscellaneous information
+h       NR      Medium
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+x       NR      International Standard Serial Number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+250     NR      EDITION STATEMENT
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Edition statement
+b       NR      Remainder of edition statement
+6       NR      Linkage
+8       R       Field link and sequence number
+
+254     NR      MUSICAL PRESENTATION STATEMENT
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Musical presentation statement
+6       NR      Linkage
+8       R       Field link and sequence number
+
+255     R       CARTOGRAPHIC MATHEMATICAL DATA
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Statement of scale
+b       NR      Statement of projection
+c       NR      Statement of coordinates
+d       NR      Statement of zone
+e       NR      Statement of equinox
+f       NR      Outer G-ring coordinate pairs
+g       NR      Exclusion G-ring coordinate pairs
+6       NR      Linkage
+8       R       Field link and sequence number
+
+256     NR      COMPUTER FILE CHARACTERISTICS
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Computer file characteristics
+6       NR      Linkage
+8       R       Field link and sequence number
+
+257     NR      COUNTRY OF PRODUCING ENTITY FOR ARCHIVAL FILMS
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Country of producing entity
+6       NR      Linkage
+8       R       Field link and sequence number
+
+258     R       PHILATELIC ISSUE DATE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Issuing jurisdiction
+b       NR      Denomination
+6       NR      Linkage
+8       R       Field link and sequence number
+
+260     R       PUBLICATION, DISTRIBUTION, ETC. (IMPRINT)
+ind1    b23     Sequence of publishing statements
+ind2    blank   Undefined
+a       R       Place of publication, distribution, etc.
+b       R       Name of publisher, distributor, etc.
+c       R       Date of publication, distribution, etc.
+d       NR      Plate or publisher's number for music (Pre-AACR 2)
+e       R       Place of manufacture
+f       R       Manufacturer
+g       R       Date of manufacture
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+261     NR      IMPRINT STATEMENT FOR FILMS (Pre-AACR 1 Revised)
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Producing company
+b       R       Releasing company (primary distributor)
+d       R       Date of production, release, etc.
+e       R       Contractual producer
+f       R       Place of production, release, etc.
+6       NR      Linkage
+8       R       Field link and sequence number
+
+262     NR      IMPRINT STATEMENT FOR SOUND RECORDINGS (Pre-AACR 2)
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Place of production, release, etc.
+b       NR      Publisher or trade name
+c       NR      Date of production, release, etc.
+k       NR      Serial identification
+l       NR      Matrix and/or take number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+263     NR      PROJECTED PUBLICATION DATE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Projected publication date
+6       NR      Linkage
+8       R       Field link and sequence number
+
+270     R       ADDRESS
+ind1    b12     Level
+ind2    b07     Type of address
+a       R       Address
+b       NR      City
+c       NR      State or province
+d       NR      Country
+e       NR      Postal code
+f       NR      Terms preceding attention name
+g       NR      Attention name
+h       NR      Attention position
+i       NR      Type of address
+j       R       Specialized telephone number
+k       R       Telephone number
+l       R       Fax number
+m       R       Electronic mail address
+n       R       TDD or TTY number
+p       R       Contact person
+q       R       Title of contact person
+r       R       Hours
+z       R       Public note
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+300     R       PHYSICAL DESCRIPTION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Extent
+b       NR      Other physical details
+c       R       Dimensions
+e       NR      Accompanying material
+f       R       Type of unit
+g       R       Size of unit
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+306     NR      PLAYING TIME
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Playing time
+6       NR      Linkage
+8       R       Field link and sequence number
+
+307     R       HOURS, ETC.
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Hours
+b       NR      Additional information
+6       NR      Linkage
+8       R       Field link and sequence number
+
+310     NR      CURRENT PUBLICATION FREQUENCY
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Current publication frequency
+b       NR      Date of current publication frequency
+6       NR      Linkage
+8       R       Field link and sequence number
+
+321     R       FORMER PUBLICATION FREQUENCY
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Former publication frequency
+b       NR      Dates of former publication frequency
+6       NR      Linkage
+8       R       Field link and sequence number
+
+340     R       PHYSICAL MEDIUM
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Material base and configuration
+b       R       Dimensions
+c       R       Materials applied to surface
+d       R       Information recording technique
+e       R       Support
+f       R       Production rate/ratio
+h       R       Location within medium
+i       R       Technical specifications of medium
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+342     R       GEOSPATIAL REFERENCE DATA
+ind1    01      Geospatial reference dimension
+ind2    012345678    Geospatial reference method
+a       NR      Name
+b       NR      Coordinate or distance units
+c       NR      Latitude resolution
+d       NR      Longitude resolution
+e       R       Standard parallel or oblique line latitude
+f       R       Oblique line longitude
+g       NR      Longitude of central meridian or projection center
+h       NR      Latitude of projection origin or projection center
+i       NR      False easting
+j       NR      False northing
+k       NR      Scale factor
+l       NR      Height of perspective point above surface
+m       NR      Azimuthal angle
+o       NR      Landsat number and path number
+p       NR      Zone identifier
+q       NR      Ellipsoid name
+r       NR      Semi-major axis
+s       NR      Denominator of flattening ratio
+t       NR      Vertical resolution
+u       NR      Vertical encoding method
+v       NR      Local planar, local, or other projection or grid description
+w       NR      Local planar or local georeference information
+2       NR      Reference method used
+6       NR      Linkage
+8       R       Field link and sequence number
+
+343     R       PLANAR COORDINATE DATA
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Planar coordinate encoding method
+b       NR      Planar distance units
+c       NR      Abscissa resolution
+d       NR      Ordinate resolution
+e       NR      Distance resolution
+f       NR      Bearing resolution
+g       NR      Bearing units
+h       NR      Bearing reference direction
+i       NR      Bearing reference meridian
+6       NR      Linkage
+8       R       Field link and sequence number
+
+351     R       ORGANIZATION AND ARRANGEMENT OF MATERIALS
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Organization
+b       R       Arrangement
+c       NR      Hierarchical level
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+352     R       DIGITAL GRAPHIC REPRESENTATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Direct reference method
+b       R       Object type
+c       R       Object count
+d       NR      Row count
+e       NR      Column count
+f       NR      Vertical count
+g       NR      VPF topology level
+i       NR      Indirect reference description
+q       R       Format of the digital image
+6       NR      Linkage
+8       R       Field link and sequence number
+
+355     R       SECURITY CLASSIFICATION CONTROL
+ind1    0123458    Controlled element
+ind2    blank   Undefined
+a       NR      Security classification
+b       R       Handling instructions
+c       R       External dissemination information
+d       NR      Downgrading or declassification event
+e       NR      Classification system
+f       NR      Country of origin code
+g       NR      Downgrading date
+h       NR      Declassification date
+j       R       Authorization
+6       NR      Linkage
+8       R       Field link and sequence number
+
+357     NR      ORIGINATOR DISSEMINATION CONTROL
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Originator control term
+b       R       Originating agency
+c       R       Authorized recipients of material
+g       R       Other restrictions
+6       NR      Linkage
+8       R       Field link and sequence number
+
+362     R       DATES OF PUBLICATION AND/OR SEQUENTIAL DESIGNATION
+ind1    01      Format of date
+ind2    blank   Undefined
+a       NR      Dates of publication and/or sequential designation
+z       NR      Source of information
+6       NR      Linkage
+8       R       Field link and sequence number
+
+363     R       NORMALIZED DATE AND SEQUENTIAL DESIGNATION
+ind1    b01      Start/End designator
+ind2    b01      State of issuanceUndefined
+a       NR      First level of enumeration
+b       NR      Second level of enumeration
+c       NR      Third level of enumeration
+d       NR      Fourth level of enumeration
+e       NR      Fifth level of enumeration
+f       NR      Sixth level of enumeration
+g       NR      Alternative numbering scheme, first level of enumeration
+h       NR      Alternative numbering scheme, second level of enumeration
+i       NR      First level of chronology
+j       NR      Second level of chronology
+k       NR      Third level of chronology
+l       NR      Fourth level of chronology
+m       NR      Alternative numbering scheme, chronology
+u       NR      First level textual designation
+v       NR      First level of chronology, issuance
+x       R       Nonpublic note
+z       R       Public note
+6       NR      Linkage
+8       NR      Field link and sequence number
+
+365     R       TRADE PRICE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Price type code
+b       NR      Price amount
+c       NR      Currency code
+d       NR      Unit of pricing
+e       NR      Price note
+f       NR      Price effective from
+g       NR      Price effective until
+h       NR      Tax rate 1
+i       NR      Tax rate 2
+j       NR      ISO country code
+k       NR      MARC country code
+m       NR      Identification of pricing entity
+2       NR      Source of price type code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+366     R       TRADE AVAILABILITY INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Publishers' compressed title identification
+b       NR      Detailed date of publication
+c       NR      Availability status code
+d       NR      Expected next availability date
+e       NR      Note
+f       NR      Publishers' discount category
+g       NR      Date made out of print
+j       NR      ISO country code
+k       NR      MARC country code
+m       NR      Identification of agency
+2       NR      Source of availability status code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+400     R       SERIES STATEMENT/ADDED ENTRY--PERSONAL NAME
+ind1    013     Type of personal name entry element
+ind2    01      Pronoun represents main entry
+a       NR      Personal name
+b       NR      Numeration
+c       R       Titles and other words associated with a name
+d       NR      Dates associated with a name
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+t       NR      Title of a work
+u       NR      Affiliation
+v       NR      Volume number/sequential designation
+x       NR      International Standard Serial Number
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+410     R       SERIES STATEMENT/ADDED ENTRY--CORPORATE NAME
+ind1    012     Type of corporate name entry element
+ind2    01      Pronoun represents main entry
+a       NR      Corporate name or jurisdiction name as entry element
+b       R       Subordinate unit
+c       NR      Location of meeting
+d       R       Date of meeting or treaty signing
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+t       NR      Title of a work
+u       NR      Affiliation
+v       NR      Volume number/sequential designation
+x       NR      International Standard Serial Number
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+411     R       SERIES STATEMENT/ADDED ENTRY--MEETING NAME
+ind1    012     Type of meeting name entry element
+ind2    01      Pronoun represents main entry
+a       NR      Meeting name or jurisdiction name as entry element
+c       NR      Location of meeting
+d       NR      Date of meeting
+e       R       Subordinate unit
+f       NR      Date of a work
+g       NR      Miscellaneous information
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+q       NR      Name of meeting following jurisdiction name entry element
+t       NR      Title of a work
+u       NR      Affiliation
+v       NR      Volume number/sequential designation
+x       NR      International Standard Serial Number
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+440     R       SERIES STATEMENT/ADDED ENTRY--TITLE [OBSOLETE]
+ind1    blank   Undefined
+ind2    0-9     Nonfiling characters
+a       NR      Title
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+v       NR      Volume number/sequential designation
+x       NR      International Standard Serial Number
+w       R       Bibliographic record control number
+0       R       Authority record control number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+490     R       SERIES STATEMENT
+ind1    01      Specifies whether series is traced
+ind2    blank   Undefined
+a       R       Series statement
+l       NR      Library of Congress call number
+v       R       Volume number/sequential designation
+x       NR      International Standard Serial Number
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+500     R       GENERAL NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      General note
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+501     R       WITH NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      With note
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+502     R       DISSERTATION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Dissertation note
+b       NR      Degree type
+c       NR      Name of granting institution
+d       NR      Year of degree granted
+g       R       Miscellaneous information
+o       R       Dissertation identifier
+6       NR      Linkage
+8       R       Field link and sequence number
+
+504     R       BIBLIOGRAPHY, ETC. NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Bibliography, etc. note
+b       NR      Number of references
+6       NR      Linkage
+8       R       Field link and sequence number
+
+505     R       FORMATTED CONTENTS NOTE
+ind1    0128    Display constant controller
+ind2    b0      Level of content designation
+a       NR      Formatted contents note
+g       R       Miscellaneous information
+r       R       Statement of responsibility
+t       R       Title
+u       R       Uniform Resource Identifier
+6       NR      Linkage
+8       R       Field link and sequence number
+
+506     R       RESTRICTIONS ON ACCESS NOTE
+ind1    b01     Restriction
+ind2    blank   Undefined
+a       NR      Terms governing access
+b       R       Jurisdiction
+c       R       Physical access provisions
+d       R       Authorized users
+e       R       Authorization
+f       R       Standard terminology for access restiction
+u       R       Uniform Resource Identifier
+2       NR      Source of term
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+507     NR      SCALE NOTE FOR GRAPHIC MATERIAL
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Representative fraction of scale note
+b       NR      Remainder of scale note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+508     R       CREATION/PRODUCTION CREDITS NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Creation/production credits note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+510     R       CITATION/REFERENCES NOTE
+ind1    01234   Coverage/location in source
+ind2    blank   Undefined
+a       NR      Name of source
+b       NR      Coverage of source
+c       NR      Location within source
+x       NR      International Standard Serial Number
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+511     R       PARTICIPANT OR PERFORMER NOTE
+ind1    01      Display constant controller
+ind2    blank   Undefined
+a       NR      Participant or performer note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+513     R       TYPE OF REPORT AND PERIOD COVERED NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Type of report
+b       NR      Period covered
+6       NR      Linkage
+8       R       Field link and sequence number
+
+514     NR      DATA QUALITY NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Attribute accuracy report
+b       R       Attribute accuracy value
+c       R       Attribute accuracy explanation
+d       NR      Logical consistency report
+e       NR      Completeness report
+f       NR      Horizontal position accuracy report
+g       R       Horizontal position accuracy value
+h       R       Horizontal position accuracy explanation
+i       NR      Vertical positional accuracy report
+j       R       Vertical positional accuracy value
+k       R       Vertical positional accuracy explanation
+m       NR      Cloud cover
+u       R       Uniform Resource Identifier
+z       R       Display note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+515     R       NUMBERING PECULIARITIES NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Numbering peculiarities note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+516     R       TYPE OF COMPUTER FILE OR DATA NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Type of computer file or data note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+518     R       DATE/TIME AND PLACE OF AN EVENT NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Date/time and place of an event note
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+520     R       SUMMARY, ETC.
+ind1    b012348    Display constant controller
+ind2    blank   Undefined
+a       NR      Summary, etc. note
+b       NR      Expansion of summary note
+c       NR      Assigning agency
+u       R       Uniform Resource Identifier
+2       NR      Source
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+521     R       TARGET AUDIENCE NOTE
+ind1    b012348    Display constant controller
+ind2    blank   Undefined
+a       R       Target audience note
+b       NR      Source
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+522     R       GEOGRAPHIC COVERAGE NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Geographic coverage note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+524     R       PREFERRED CITATION OF DESCRIBED MATERIALS NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Preferred citation of described materials note
+2       NR      Source of schema used
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+525     R       SUPPLEMENT NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Supplement note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+526     R       STUDY PROGRAM INFORMATION NOTE
+ind1    08      Display constant controller
+ind2    blank   Undefined
+a       NR      Program name
+b       NR      Interest level
+c       NR      Reading level
+d       NR      Title point value
+i       NR      Display text
+x       R       Nonpublic note
+z       R       Public note
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+530     R       ADDITIONAL PHYSICAL FORM AVAILABLE NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Additional physical form available note
+b       NR      Availability source
+c       NR      Availability conditions
+d       NR      Order number
+u       R       Uniform Resource Identifier
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+533     R       REPRODUCTION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Type of reproduction
+b       R       Place of reproduction
+c       R       Agency responsible for reproduction
+d       NR      Date of reproduction
+e       NR      Physical description of reproduction
+f       R       Series statement of reproduction
+m       R       Dates and/or sequential designation of issues reproduced
+n       R       Note about reproduction
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+7       NR      Fixed-length data elements of reproduction
+8       R       Field link and sequence number
+
+534     R       ORIGINAL VERSION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Main entry of original
+b       NR      Edition statement of original
+c       NR      Publication, distribution, etc. of original
+e       NR      Physical description, etc. of original
+f       R       Series statement of original
+k       R       Key title of original
+l       NR      Location of original
+m       NR      Material specific details
+n       R       Note about original
+o       R       Other resource identifier
+p       NR      Introductory phrase
+t       NR      Title statement of original
+x       R       International Standard Serial Number
+z       R       International Standard Book Number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+535     R       LOCATION OF ORIGINALS/DUPLICATES NOTE
+ind1    12      Additional information about custodian
+ind2    blank   Undefined
+a       NR      Custodian
+b       R       Postal address
+c       R       Country
+d       R       Telecommunications address
+g       NR      Repository location code
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+536     R       FUNDING INFORMATION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Text of note
+b       R       Contract number
+c       R       Grant number
+d       R       Undifferentiated number
+e       R       Program element number
+f       R       Project number
+g       R       Task number
+h       R       Work unit number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+538     R       SYSTEM DETAILS NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      System details note
+i       NR      Display text
+u       R       Uniform Resource Identifier
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+540     R       TERMS GOVERNING USE AND REPRODUCTION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Terms governing use and reproduction
+b       NR      Jurisdiction
+c       NR      Authorization
+d       NR      Authorized users
+u       R       Uniform Resource Identifier
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+541     R       IMMEDIATE SOURCE OF ACQUISITION NOTE
+ind1    b01     Undefined
+ind2    blank   Undefined
+a       NR      Source of acquisition
+b       NR      Address
+c       NR      Method of acquisition
+d       NR      Date of acquisition
+e       NR      Accession number
+f       NR      Owner
+h       NR      Purchase price
+n       R       Extent
+o       R       Type of unit
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+542     R       INFORMATION RELATING TO COPYRIGHT STATUS
+ind1    b01     Relationship
+ind2    blank   Undefined
+a       NR      Personal creator
+b       NR      Personal creator death date
+c       NR      Corporate creator
+d       R       Copyright holder
+e       R       Copyright holder contact information
+f       R       Copyright statement
+g       NR      Copyright date
+h       R       Copyright renewal date
+i       NR      Publication date
+j       NR      Creation date
+k       R       Publisher
+l       NR      Copyright status
+m       NR      Publication status
+n       R       Note
+o       NR      Research date
+q       NR      Assigning agency
+r       NR      Jurisdiction of copyright assessment
+s       NR      Source of information
+u       R       Uniform Resource Identifier
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+544     R       LOCATION OF OTHER ARCHIVAL MATERIALS NOTE
+ind1    b01     Relationship
+ind2    blank   Undefined
+a       R       Custodian
+b       R       Address
+c       R       Country
+d       R       Title
+e       R       Provenance
+n       R       Note
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+545     R       BIOGRAPHICAL OR HISTORICAL DATA
+ind1    b01     Type of data
+ind2    blank   Undefined
+a       NR      Biographical or historical note
+b       NR      Expansion
+u       R       Uniform Resource Identifier
+6       NR      Linkage
+8       R       Field link and sequence number
+
+546     R       LANGUAGE NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Language note
+b       R       Information code or alphabet
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+547     R       FORMER TITLE COMPLEXITY NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Former title complexity note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+550     R       ISSUING BODY NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Issuing body note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+552     R       ENTITY AND ATTRIBUTE INFORMATION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Entity type label
+b       NR      Entity type definition and source
+c       NR      Attribute label
+d       NR      Attribute definition and source
+e       R       Enumerated domain value
+f       R       Enumerated domain value definition and source
+g       NR      Range domain minimum and maximum
+h       NR      Codeset name and source
+i       NR      Unrepresentable domain
+j       NR      Attribute units of measurement and resolution
+k       NR      Beginning date and ending date of attribute values
+l       NR      Attribute value accuracy
+m       NR      Attribute value accuracy explanation
+n       NR      Attribute measurement frequency
+o       R       Entity and attribute overview
+p       R       Entity and attribute detail citation
+u       R       Uniform Resource Identifier
+z       R       Display note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+555     R       CUMULATIVE INDEX/FINDING AIDS NOTE
+ind1    b08     Display constant controller
+ind2    blank   Undefined
+a       NR      Cumulative index/finding aids note
+b       R       Availability source
+c       NR      Degree of control
+d       NR      Bibliographic reference
+u       R       Uniform Resource Identifier
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+556     R       INFORMATION ABOUT DOCUMENTATION NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Information about documentation note
+z       R       International Standard Book Number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+561     R       OWNERSHIP AND CUSTODIAL HISTORY
+ind1    b01     Undefined
+ind2    blank   Undefined
+a       NR      History
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+562     R       COPY AND VERSION IDENTIFICATION NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Identifying markings
+b       R       Copy identification
+c       R       Version identification
+d       R       Presentation format
+e       R       Number of copies
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+563     R       BINDING INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Binding note
+u       R       Uniform Resource Identifier
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+565     R       CASE FILE CHARACTERISTICS NOTE
+ind1    b08     Display constant controller
+ind2    blank   Undefined
+a       NR      Number of cases/variables
+b       R       Name of variable
+c       R       Unit of analysis
+d       R       Universe of data
+e       R       Filing scheme or code
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+567     R       METHODOLOGY NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Methodology note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+580     R       LINKING ENTRY COMPLEXITY NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Linking entry complexity note
+6       NR      Linkage
+8       R       Field link and sequence number
+
+581     R       PUBLICATIONS ABOUT DESCRIBED MATERIALS NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Publications about described materials note
+z       R       International Standard Book Number
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+583     R       ACTION NOTE
+ind1    b01     Undefined
+ind2    blank   Undefined
+a       NR      Action
+b       R       Action identification
+c       R       Time/date of action
+d       R       Action interval
+e       R       Contingency for action
+f       R       Authorization
+h       R       Jurisdiction
+i       R       Method of action
+j       R       Site of action
+k       R       Action agent
+l       R       Status
+n       R       Extent
+o       R       Type of unit
+u       R       Uniform Resource Identifier
+x       R       Nonpublic note
+z       R       Public note
+2       NR      Source of term
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+584     R       ACCUMULATION AND FREQUENCY OF USE NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Accumulation
+b       R       Frequency of use
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+585     R       EXHIBITIONS NOTE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Exhibitions note
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+586     R       AWARDS NOTE
+ind1    b8      Display constant controller
+ind2    blank   Undefined
+a       NR      Awards note
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+600     R       SUBJECT ADDED ENTRY--PERSONAL NAME
+ind1    013     Type of personal name entry element
+ind2    01234567    Thesaurus
+a       NR      Personal name
+b       NR      Numeration
+c       R       Titles and other words associated with a name
+d       NR      Dates associated with a name
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+j       R       Attribution qualifier
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+q       NR      Fuller form of name
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+610     R       SUBJECT ADDED ENTRY--CORPORATE NAME
+ind1    012     Type of corporate name entry element
+ind2    01234567    Thesaurus
+a       NR      Corporate name or jurisdiction name as entry element
+b       R       Subordinate unit
+c       NR      Location of meeting
+d       R       Date of meeting or treaty signing
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section/meeting
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+611     R       SUBJECT ADDED ENTRY--MEETING NAME
+ind1    012     Type of meeting name entry element
+ind2    01234567    Thesaurus
+a       NR      Meeting name or jurisdiction name as entry element
+c       NR      Location of meeting
+d       NR      Date of meeting
+e       R       Subordinate unit
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+j       R       Relator term
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+q       NR      Name of meeting following jurisdiction name entry element
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+630     R       SUBJECT ADDED ENTRY--UNIFORM TITLE
+ind1    0-9     Nonfiling characters
+ind2    01234567    Thesaurus
+a       NR      Uniform title
+d       R       Date of treaty signing
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+648     R       SUBJECT ADDED ENTRY--CHRONOLOGICAL TERM
+ind1    blank   Undefined
+ind2    01234567    Thesaurus
+a       NR      Chronological term
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+650     R       SUBJECT ADDED ENTRY--TOPICAL TERM
+ind1    b012    Level of subject
+ind2    01234567    Thesaurus
+a       NR      Topical term or geographic name as entry element
+b       NR      Topical term following geographic name as entry element
+c       NR      Location of event
+d       NR      Active dates
+e       NR      Relator term
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+651     R       SUBJECT ADDED ENTRY--GEOGRAPHIC NAME
+ind1    blank   Undefined
+ind2    01234567    Thesaurus
+a       NR      Geographic name
+e       R       Relator term
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+653     R       INDEX TERM--UNCONTROLLED
+ind1    b012    Level of index term
+ind2    b0123456   Type of term or name
+a       R       Uncontrolled term
+6       NR      Linkage
+8       R       Field link and sequence number
+
+654     R       SUBJECT ADDED ENTRY--FACETED TOPICAL TERMS
+ind1    b012    Level of subject
+ind2    blank   Undefined
+a       R       Focus term
+b       R       Non-focus term
+c       R       Facet/hierarchy designation
+e       R       Relator term
+v       R       Form subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+655     R       INDEX TERM--GENRE/FORM
+ind1    b0      Type of heading
+ind2    01234567    Thesaurus
+a       NR      Genre/form data or focus term
+b       R       Non-focus term
+c       R       Facet/hierarchy designation
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of term
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+656     R       INDEX TERM--OCCUPATION
+ind1    blank   Undefined
+ind2    7       Source of term
+a       NR      Occupation
+k       NR      Form
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of term
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+657     R       INDEX TERM--FUNCTION
+ind1    blank   Undefined
+ind2    7       Source of term
+a       NR      Function
+v       R       Form subdivision
+x       R       General subdivision
+y       R       Chronological subdivision
+z       R       Geographic subdivision
+0       R       Authority record control number
+2       NR      Source of term
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+658     R       INDEX TERM--CURRICULUM OBJECTIVE
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Main curriculum objective
+b       R       Subordinate curriculum objective
+c       NR      Curriculum code
+d       NR      Correlation factor
+2       NR      Source of term or code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+662     R       SUBJECT ADDED ENTRY--HIERARCHICAL PLACE NAME
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Country or larger entity
+b       NR      First-order political jurisdiction
+c       R       Intermediate political jurisdiction
+d       NR      City
+e       R       Relator term
+f       R       City subsection
+g       R       Other nonjurisdictional geographic region and feature
+h       R       Extraterrestrial area
+0       R       Authority record control number
+2       NR      Source of heading or term
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+700     R       ADDED ENTRY--PERSONAL NAME
+ind1    013     Type of personal name entry element
+ind2    b2      Type of added entry
+a       NR      Personal name
+b       NR      Numeration
+c       R       Titles and other words associated with a name
+d       NR      Dates associated with a name
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+j       R       Attribution qualifier
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+q       NR      Fuller form of name
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+4       R       Relator code
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+710     R       ADDED ENTRY--CORPORATE NAME
+ind1    012     Type of corporate name entry element
+ind2    b2      Type of added entry
+a       NR      Corporate name or jurisdiction name as entry element
+b       R       Subordinate unit
+c       NR      Location of meeting
+d       R       Date of meeting or treaty signing
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section/meeting
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+4       R       Relator code
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+711     R       ADDED ENTRY--MEETING NAME
+ind1    012     Type of meeting name entry element
+ind2    b2      Type of added entry
+a       NR      Meeting name or jurisdiction name as entry element
+c       NR      Location of meeting
+d       NR      Date of meeting
+e       R       Subordinate unit
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+j       R       Relator term
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+q       NR      Name of meeting following jurisdiction name entry element
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+4       R       Relator code
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+720     R       ADDED ENTRY--UNCONTROLLED NAME
+ind1    b12     Type of name
+ind2    blank   Undefined
+a       NR      Name
+e       R       Relator term
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+730     R       ADDED ENTRY--UNIFORM TITLE
+ind1    0-9     Nonfiling characters
+ind2    b2      Type of added entry
+a       NR      Uniform title
+d       R       Date of treaty signing
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+740     R       ADDED ENTRY--UNCONTROLLED RELATED/ANALYTICAL TITLE
+ind1    0-9     Nonfiling characters
+ind2    b2      Type of added entry
+a       NR      Uncontrolled related/analytical title
+h       NR      Medium
+n       R       Number of part/section of a work
+p       R       Name of part/section of a work
+5       NR      Institution to which field applies
+6       NR      Linkage
+8       R       Field link and sequence number
+
+751     R       ADDED ENTRY--GEOGRAPHIC NAME
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Geographic name
+e       R       Relator term
+0       R       Authority record control number
+2       NR      Source of heading or term
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+752     R       ADDED ENTRY--HIERARCHICAL PLACE NAME
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Country or larger entity
+b       NR      First-order political jurisdiction
+c       NR      Intermediate political jurisdiction
+d       NR      City
+f       R       City subsection
+g       R       Other nonjurisdictional geographic region and feature
+h       R       Extraterrestrial area
+0       R       Authority record control number
+2       NR      Source of heading or term
+6       NR      Linkage
+8       R       Field link and sequence number
+
+753     R       SYSTEM DETAILS ACCESS TO COMPUTER FILES
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Make and model of machine
+b       NR      Programming language
+c       NR      Operating system
+6       NR      Linkage
+8       R       Field link and sequence number
+
+754     R       ADDED ENTRY--TAXONOMIC IDENTIFICATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Taxonomic name
+c       R       Taxonomic category
+d       R       Common or alternative name
+x       R       Non-public note
+z       R       Public note
+0       R       Authority record control number
+2       NR      Source of taxonomic identification
+6       NR      Linkage
+8       R       Field link and sequence number
+
+760     R       MAIN SERIES ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+s       NR      Uniform title
+t       NR      Title
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+762     R       SUBSERIES ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+s       NR      Uniform title
+t       NR      Title
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+765     R       ORIGINAL LANGUAGE ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+767     R       TRANSLATION ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+770     R       SUPPLEMENT/SPECIAL ISSUE ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+772     R       SUPPLEMENT PARENT ENTRY
+ind1    01      Note controller
+ind2    b08     Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Stan dard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+773     R       HOST ITEM ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+p       NR      Abbreviated title
+q       NR      Enumeration and first page
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+3       NR      Materials specified
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+774     R       CONSTITUENT UNIT ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+775     R       OTHER EDITION ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+e       NR      Language code
+f       NR      Country code
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+776     R       ADDITIONAL PHYSICAL FORM ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+777     R       ISSUED WITH ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+s       NR      Uniform title
+t       NR      Title
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+780     R       PRECEDING ENTRY
+ind1    01      Note controller
+ind2    01234567    Type of relationship
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+785     R       SUCCEEDING ENTRY
+ind1    01      Note controller
+ind2    012345678    Type of relationship
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standa rd Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+786     R       DATA SOURCE ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+j       NR      Period of content
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+p       NR      Abbreviated title
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+v       NR      Source Contribution
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+787     R       NONSPECIFIC RELATIONSHIP ENTRY
+ind1    01      Note controller
+ind2    b8      Display constant controller
+a       NR      Main entry heading
+b       NR      Edition
+c       NR      Qualifying information
+d       NR      Place, publisher, and date of publication
+g       R       Relationship information
+h       NR      Physical description
+i       NR      Display text
+k       R       Series data for related item
+m       NR      Material-specific details
+n       R       Note
+o       R       Other item identifier
+r       R       Report number
+s       NR      Uniform title
+t       NR      Title
+u       NR      Standard Technical Report Number
+w       R       Record control number
+x       NR      International Standard Serial Number
+y       NR      CODEN designation
+z       R       International Standard Book Number
+6       NR      Linkage
+7       NR      Control subfield
+8       R       Field link and sequence number
+
+800     R       SERIES ADDED ENTRY--PERSONAL NAME
+ind1    013     Type of personal name entry element
+ind2    blank   Undefined
+a       NR      Personal name
+b       NR      Numeration
+c       R       Titles and other words associated with a name
+d       NR      Dates associated with a name
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+j       R       Attribution qualifier
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+q       NR      Fuller form of name
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+v       NR      Volume/sequential designation
+w       R       Bibliographic record control number
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+810     R       SERIES ADDED ENTRY--CORPORATE NAME
+ind1    012     Type of corporate name entry element
+ind2    blank   Undefined
+a       NR      Corporate name or jurisdiction name as entry element
+b       R       Subordinate unit
+c       NR      Location of meeting
+d       R       Date of meeting or treaty signing
+e       R       Relator term
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section/meeting
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+v       NR      Volume/sequential designation
+w       R       Bibliographic record control number
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+811     R       SERIES ADDED ENTRY--MEETING NAME
+ind1    012     Type of meeting name entry element
+ind2    blank   Undefined
+a       NR      Meeting name or jurisdiction name as entry element
+c       NR      Location of meeting
+d       NR      Date of meeting
+e       R       Subordinate unit
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+j       R       Relator term
+k       R       Form subheading
+l       NR      Language of a work
+n       R       Number of part/section/meeting
+p       R       Name of part/section of a work
+q       NR      Name of meeting following jurisdiction name entry element
+s       NR      Version
+t       NR      Title of a work
+u       NR      Affiliation
+v       NR      Volume/sequential designation
+w       R       Bibliographic record control number
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+4       R       Relator code
+6       NR      Linkage
+8       R       Field link and sequence number
+
+830     R       SERIES ADDED ENTRY--UNIFORM TITLE
+ind1    blank   Undefined
+ind2    0-9     Nonfiling characters
+a       NR      Uniform title
+d       R       Date of treaty signing
+f       NR      Date of a work
+g       NR      Miscellaneous information
+h       NR      Medium
+k       R       Form subheading
+l       NR      Language of a work
+m       R       Medium of performance for music
+n       R       Number of part/section of a work
+o       NR      Arranged statement for music
+p       R       Name of part/section of a work
+r       NR      Key for music
+s       NR      Version
+t       NR      Title of a work
+v       NR      Volume/sequential designation
+w       R       Bibliographic record control number
+x       NR      International Standard Serial Number
+0       R       Authority record control number
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+841     NR      HOLDINGS CODED DATA VALUES
+
+842     NR      TEXTUAL PHYSICAL FORM DESIGNATOR
+
+843     R       REPRODUCTION NOTE
+
+844     NR      NAME OF UNIT
+
+845     R       TERMS GOVERNING USE AND REPRODUCTION NOTE
+
+850     R       HOLDING INSTITUTION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Holding institution
+8       R       Field link and sequence number
+
+852     R       LOCATION
+ind1    b012345678    Shelving scheme
+ind2    b012    Shelving order
+a       NR      Location
+b       R       Sublocation or collection
+c       R       Shelving location
+d       R       Former shelving location
+e       R       Address
+f       R       Coded location qualifier
+g       R       Non-coded location qualifier
+h       NR      Classification part
+i       R       Item part
+j       NR      Shelving control number
+k       R       Call number prefix
+l       NR      Shelving form of title
+m       R       Call number suffix
+n       NR      Country code
+p       NR      Piece designation
+q       NR      Piece physical condition
+s       R       Copyright article-fee code
+t       NR      Copy number
+u       R       Uniform Resource Identifier
+x       R       Nonpublic note
+z       R       Public note
+2       NR      Source of classification or shelving scheme
+3       NR      Materials specified
+6       NR      Linkage
+8       NR      Sequence number
+
+853     R       CAPTIONS AND PATTERN--BASIC BIBLIOGRAPHIC UNIT
+
+854     R       CAPTIONS AND PATTERN--SUPPLEMENTARY MATERIAL
+
+855     R       CAPTIONS AND PATTERN--INDEXES
+
+856     R       ELECTRONIC LOCATION AND ACCESS
+ind1    b012347    Access method
+ind2    b0128   Relationship
+a       R       Host name
+b       R       Access number
+c       R       Compression information
+d       R       Path
+f       R       Electronic name
+h       NR      Processor of request
+i       R       Instruction
+j       NR      Bits per second
+k       NR      Password
+l       NR      Logon
+m       R       Contact for access assistance
+n       NR      Name of location of host
+o       NR      Operating system
+p       NR      Port
+q       NR      Electronic format type
+r       NR      Settings
+s       R       File size
+t       R       Terminal emulation
+u       R       Uniform Resource Identifier
+v       R       Hours access method available
+w       R       Record control number
+x       R       Nonpublic note
+y       R       Link text
+z       R       Public note
+2       NR      Access method
+3       NR      Materials specified
+6       NR      Linkage
+8       R       Field link and sequence number
+
+863     R       ENUMERATION AND CHRONOLOGY--BASIC BIBLIOGRAPHIC UNIT
+
+864     R       ENUMERATION AND CHRONOLOGY--SUPPLEMENTARY MATERIAL
+
+865     R       ENUMERATION AND CHRONOLOGY--INDEXES
+
+866     R       TEXTUAL HOLDINGS--BASIC BIBLIOGRAPHIC UNIT
+
+867     R       TEXTUAL HOLDINGS--SUPPLEMENTARY MATERIAL
+
+868     R       TEXTUAL HOLDINGS--INDEXES
+
+876     R       ITEM INFORMATION--BASIC BIBLIOGRAPHIC UNIT
+
+877     R       ITEM INFORMATION--SUPPLEMENTARY MATERIAL
+
+878     R       ITEM INFORMATION--INDEXES
+
+880     R       ALTERNATE GRAPHIC REPRESENTATION
+ind1            Same as associated field
+ind2            Same as associated field
+6       NR      Linkage
+
+882     NR      REPLACEMENT RECORD INFORMATION
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       R       Replacement title
+i       R       Explanatory text
+w       R       Replacement bibliographic record control number
+6       NR      Linkage
+8       R       Field link and sequence number
+
+886     R       FOREIGN MARC INFORMATION FIELD
+ind1    012     Type of field
+ind2    blank   Undefined
+a       NR      Tag of the foreign MARC field
+b       NR      Content of the foreign MARC field
+c-z     NR      Foreign MARC subfield
+0-1     NR      Foreign MARC subfield
+2       NR      Source of data
+4       NR      Source of data
+3-9     NR      Source of data
+
+887     R       NON-MARC INFORMATION FIELD
+ind1    blank   Undefined
+ind2    blank   Undefined
+a       NR      Content of non-MARC field
+2       NR      Source of data
+RULES;
+        // @codingStandardsIgnoreEnd
+    }
+    // }}}
+}
+// }}}
+
diff --git a/vendor/File/MARC/Lint/CodeData.php b/vendor/File/MARC/Lint/CodeData.php
new file mode 100644
index 0000000000000000000000000000000000000000..cae0c129e9944e2b03edb18d4782c6d9e92098ed
--- /dev/null
+++ b/vendor/File/MARC/Lint/CodeData.php
@@ -0,0 +1,166 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Code Data to support Lint for MARC records
+ *
+ * This module is adapted from the MARC::Lint::CodeData CPAN module for Perl,
+ * maintained by Bryan Baldus <eijabb@cpan.org> and available for download at
+ * http://search.cpan.org/~eijabb/
+ *
+ * Current MARC::Lint::CodeData version used as basis for this module: 1.28
+ *
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Demian Katz <demian.katz@villanova.edu>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Record.php 308146 2011-02-08 20:36:20Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Lint
+/**
+ * Contains codes from the MARC code lists for Geographic Areas, Languages, and
+ * Countries.
+ *
+ * Code data is used for validating fields 008, 040, 041, and 043.
+ *
+ * Also, sources for subfield 2 in 600-651 and 655.
+ *
+ * Note: According to the official MARC documentation, Sears is not a valid 655
+ * term. The code data below treats it as valid, in anticipation of a change in
+ * the official documentation.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Lint_CodeData
+{
+
+    // {{{ properties
+    /**
+     * Valid Geographic Area Codes
+     * @var array
+     */
+    public $geogAreaCodes;
+
+    /**
+     * Obsolete Geographic Area Codes
+     * @var array
+     */
+    public $obsoleteGeogAreaCodes;
+
+    /**
+     * Valid Language Codes
+     * @var array
+     */
+    public $languageCodes;
+
+    /**
+     * Obsolete Language Codes
+     * @var array
+     */
+    public $obsoleteLanguageCodes;
+
+    /**
+     * Valid Country Codes
+     * @var array
+     */
+    public $countryCodes;
+
+    /**
+     * Obsolete Country Codes
+     * @var array
+     */
+    public $obsoleteCountryCodes;
+
+    /**
+     * Valid sources for fields 600-651
+     * @var array
+     */
+    public $sources600_651;
+
+    /**
+     * Obsolete sources for fields 600-651
+     * @var array
+     */
+    public $obsoleteSources600_651;
+
+    /**
+     * Valid sources for field 655
+     * @var array
+     */
+    public $sources655;
+
+    /**
+     * Obsolete sources for field 655
+     * @var array
+     */
+    public $obsoleteSources655;
+
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Start function
+     *
+     * Initialize code arrays.
+     *
+     * @return true 
+     */
+    public function __construct()
+    {
+        // @codingStandardsIgnoreStart
+        // fill the valid Geographic Area Codes array
+        $this->geogAreaCodes = explode("\t", "a-af---	f------	fc-----	fe-----	fq-----	ff-----	fh-----	fs-----	fb-----	fw-----	n-us-al	n-us-ak	e-aa---	n-cn-ab	f-ae---	ea-----	sa-----	poas---	aa-----	sn-----	e-an---	f-ao---	nwxa---	a-cc-an	t------	nwaq---	nwla---	n-usa--	ma-----	ar-----	au-----	r------	s-ag---	n-us-az	n-us-ar	a-ai---	nwaw---	lsai---	u-ac---	a------	ac-----	as-----	l------	fa-----	u------	u-at---	u-at-ac	e-au---	a-aj---	lnaz---	nwbf---	a-ba---	ed-----	eb-----	a-bg---	nwbb---	a-cc-pe	e-bw---	e-be---	ncbh---	el-----	ab-----	f-dm---	lnbm---	a-bt---	mb-----	a-ccp--	s-bo---	nwbn---	a-bn---	e-bn---	f-bs---	lsbv---	s-bl---	n-cn-bc	i-bi---	nwvb---	a-bx---	e-bu---	f-uv---	a-br---	f-bd---	n-us-ca	a-cb---	f-cm---	n-cn---	nccz---	lnca---	lncv---	cc-----	poci---	ak-----	e-urk--	e-urr--	nwcj---	f-cx---	nc-----	e-urc--	f-cd---	s-cl---	a-cc---	a-cc-cq	i-xa---	i-xb---	q------	s-ck---	n-us-co	b------	i-cq---	f-cf---	f-cg---	fg-----	n-us-ct	pocw---	u-cs---	nccr---	e-ci---	nwcu---	nwco---	a-cy---	e-xr---	e-cs---	f-iv---	eo-----	zd-----	n-us-de	e-dk---	dd-----	d------	f-ft---	nwdq---	nwdr---	x------	n-usr--	ae-----	an-----	a-em---	poea---	xa-----	s-ec---	f-ua---	nces---	e-uk-en	f-eg---	f-ea---	e-er---	f-et---	me-----	e------	ec-----	ee-----	en-----	es-----	ew-----	lsfk---	lnfa---	pofj---	e-fi---	n-us-fl	e-fr---	h------	s-fg---	pofp---	a-cc-fu	f-go---	pogg---	f-gm---	a-cc-ka	awgz---	n-us-ga	a-gs---	e-gx---	e-ge---	e-gw---	f-gh---	e-gi---	e-uk---	e-uk-ui	nl-----	np-----	fr-----	e-gr---	n-gl---	nwgd---	nwgp---	pogu---	a-cc-kn	a-cc-kc	ncgt---	f-gv---	f-pg---	a-cc-kw	s-gy---	a-cc-ha	nwht---	n-us-hi	i-hm---	a-cc-hp	a-cc-he	a-cc-ho	ah-----	nwhi---	ncho---	a-cc-hk	a-cc-hh	n-cnh--	a-cc-hu	e-hu---	e-ic---	n-us-id	n-us-il	a-ii---	i------	n-us-in	ai-----	a-io---	a-cc-im	m------	c------	n-us-ia	a-ir---	a-iq---	e-ie---	a-is---	e-it---	nwjm---	lnjn---	a-ja---	a-cc-ku	a-cc-ki	a-cc-kr	poji---	a-jo---	zju----	n-us-ks	a-kz---	n-us-ky	f-ke---	poki---	pokb---	a-kr---	a-kn---	a-ko---	a-cck--	a-ku---	a-kg---	a-ls---	cl-----	e-lv---	a-le---	nwli---	f-lo---	a-cc-lp	f-lb---	f-ly---	e-lh---	poln---	e-li---	n-us-la	e-lu---	a-cc-mh	e-xn---	f-mg---	lnma---	n-us-me	f-mw---	am-----	a-my---	i-xc---	f-ml---	e-mm---	n-cn-mb	poxd---	n-cnm--	zma----	poxe---	nwmq---	n-us-md	n-us-ma	f-mu---	i-mf---	i-my---	mm-----	ag-----	pome---	zme----	n-mx---	nm-----	n-us-mi	pott---	pomi---	n-usl--	aw-----	n-usc--	poxf---	n-us-mn	n-us-ms	n-usm--	n-us-mo	n-uss--	e-mv---	e-mc---	a-mp---	n-us-mt	nwmj---	zmo----	f-mr---	f-mz---	f-sx---	ponu---	n-us-nb	a-np---	zne----	e-ne---	nwna---	n-us-nv	n-cn-nk	ponl---	n-usn--	a-nw---	n-us-nh	n-us-nj	n-us-nm	u-at-ne	n-us-ny	u-nz---	n-cn-nf	ncnq---	f-ng---	fi-----	f-nr---	fl-----	a-cc-nn	poxh---	n------	ln-----	n-us-nc	n-us-nd	pn-----	n-use--	xb-----	e-uk-ni	u-at-no	n-cn-nt	e-no---	n-cn-ns	n-cn-nu	po-----	n-us-oh	n-uso--	n-us-ok	a-mk---	n-cn-on	n-us-or	zo-----	p------	a-pk---	popl---	ncpn---	a-pp---	aopf---	s-py---	n-us-pa	ap-----	s-pe---	a-ph---	popc---	zpl----	e-pl---	pops---	e-po---	n-cnp--	n-cn-pi	nwpr---	ep-----	a-qa---	a-cc-ts	u-at-qn	n-cn-qu	mr-----	er-----	n-us-ri	sp-----	nr-----	e-rm---	e-ru---	e-ur---	e-urf--	f-rw---	i-re---	nwsd---	fd-----	nweu---	lsxj---	nwxi---	nwxk---	nwst---	n-xl---	nwxm---	pows---	posh---	e-sm---	f-sf---	n-cn-sn	zsa----	a-su---	ev-----	e-uk-st	f-sg---	i-se---	a-cc-ss	a-cc-sp	a-cc-sm	a-cc-sh	e-urs--	e-ure--	e-urw--	a-cc-sz	f-sl---	a-si---	e-xo---	e-xv---	i-xo---	zs-----	pobp---	f-so---	f-sa---	s------	az-----	ls-----	u-at-sa	n-us-sc	ao-----	n-us-sd	lsxs---	ps-----	xc-----	n-usu--	n-ust--	e-urn--	e-sp---	f-sh---	aoxp---	a-ce---	f-sj---	fn-----	fu-----	zsu----	s-sr---	lnsb---	nwsv---	f-sq---	e-sw---	e-sz---	a-sy---	a-ch---	a-ta---	f-tz---	u-at-tm	n-us-tn	i-fs---	n-us-tx	a-th---	af-----	a-cc-tn	a-cc-ti	at-----	f-tg---	potl---	poto---	nwtr---	lstd---	w------	f-ti---	a-tu---	a-tk---	nwtc---	potv---	f-ug---	e-un---	a-ts---	n-us---	nwuc---	poup---	e-uru--	zur----	s-uy---	n-us-ut	a-uz---	ponn---	e-vc---	s-ve---	zve----	n-us-vt	u-at-vi	a-vt---	nwvi---	n-us-va	e-urp--	fv-----	powk---	e-uk-wl	powf---	n-us-dc	n-us-wa	n-usp--	awba---	nw-----	n-us-wv	u-at-we	xd-----	f-ss---	nwwi---	n-us-wi	n-us-wy	a-ccs--	a-cc-su	a-ccg--	a-ccy--	ay-----	a-ye---	e-yu---	n-cn-yk	a-cc-yu	fz-----	f-za---	a-cc-ch	f-rh---	u-atc--	u-ate--	u-atn--	e-rb---	e-mo---	e-kv---");
+        
+        // fill the obsolete Geographic Area Codes array
+        $this->obsoleteGeogAreaCodes = explode("\t", "t-ay---	e-ur-ai	e-ur-aj	nwbc---	e-ur-bw	f-by---	pocp---	e-url--	cr-----	v------	e-ur-er	et-----	e-ur-gs	pogn---	nwga---	nwgs---	a-hk---	ei-----	f-if---	awiy---	awiw---	awiu---	e-ur-kz	e-ur-kg	e-ur-lv	e-ur-li	a-mh---	cm-----	e-ur-mv	n-usw--	a-ok---	a-pt---	e-ur-ru	pory---	nwsb---	posc---	a-sk---	posn---	e-uro--	e-ur-ta	e-ur-tk	e-ur-un	e-ur-uz	a-vn---	a-vs---	nwvr---	e-urv--	a-ys---");
+        
+        // fill the valid Language Codes array
+        $this->languageCodes = explode("\t", "   	aar	abk	ace	ach	ada	ady	afa	afh	afr	ain	aka	akk	alb	ale	alg	alt	amh	ang	anp	apa	ara	arc	arg	arm	arn	arp	art	arw	asm	ast	ath	aus	ava	ave	awa	aym	aze	bad	bai	bak	bal	bam	ban	baq	bas	bat	bej	bel	bem	ben	ber	bho	bih	bik	bin	bis	bla	bnt	bos	bra	bre	btk	bua	bug	bul	bur	byn	cad	cai	car	cat	cau	ceb	cel	cha	chb	che	chg	chi	chk	chm	chn	cho	chp	chr	chu	chv	chy	cmc	cop	cor	cos	cpe	cpf	cpp	cre	crh	crp	csb	cus	cze	dak	dan	dar	day	del	den	dgr	din	div	doi	dra	dsb	dua	dum	dut	dyu	dzo	efi	egy	eka	elx	eng	enm	epo	est	ewe	ewo	fan	fao	fat	fij	fil	fin	fiu	fon	fre	frm	fro	frr	frs	fry	ful	fur	gaa	gay	gba	gem	geo	ger	gez	gil	gla	gle	glg	glv	gmh	goh	gon	gor	got	grb	grc	gre	grn	gsw	guj	gwi	hai	hat	hau	haw	heb	her	hil	him	hin	hit	hmn	hmo	hrv	hsb	hun	hup	iba	ibo	ice	ido	iii	ijo	iku	ile	ilo	ina	inc	ind	ine	inh	ipk	ira	iro	ita	jav	jbo	jpn	jpr	jrb	kaa	kab	kac	kal	kam	kan	kar	kas	kau	kaw	kaz	kbd	kha	khi	khm	kho	kik	kin	kir	kmb	kok	kom	kon	kor	kos	kpe	krc	krl	kro	kru	kua	kum	kur	kut	lad	lah	lam	lao	lat	lav	lez	lim	lin	lit	lol	loz	ltz	lua	lub	lug	lui	lun	luo	lus	mac	mad	mag	mah	mai	mak	mal	man	mao	map	mar	mas	may	mdf	mdr	men	mga	mic	min	mis	mkh	mlg	mlt	mnc	mni	mno	moh	mon	mos	mul	mun	mus	mwl	mwr	myn	myv	nah	nai	nap	nau	nav	nbl	nde	ndo	nds	nep	new	nia	nic	niu	nno	nob	nog	non	nor	nqo	nso	nub	nwc	nya	nym	nyn	nyo	nzi	oci	oji	ori	orm	osa	oss	ota	oto	paa	pag	pal	pam	pan	pap	pau	peo	per	phi	phn	pli	pol	pon	por	pra	pro	pus	que	raj	rap	rar	roa	roh	rom	rum	run	rup	rus	sad	sag	sah	sai	sal	sam	san	sas	sat	scn	sco	sel	sem	sga	sgn	shn	sid	sin	sio	sit	sla	slo	slv	sma	sme	smi	smj	smn	smo	sms	sna	snd	snk	sog	som	son	sot	spa	srd	srn	srp	srr	ssa	ssw	suk	sun	sus	sux	swa	swe	syc	syr	tah	tai	tam	tat	tel	tem	ter	tet	tgk	tgl	tha	tib	tig	tir	tiv	tkl	tlh	tli	tmh	tog	ton	tpi	tsi	tsn	tso	tuk	tum	tup	tur	tut	tvl	twi	tyv	udm	uga	uig	ukr	umb	und	urd	uzb	vai	ven	vie	vol	vot	wak	wal	war	was	wel	wen	wln	wol	xal	xho	yao	yap	yid	yor	ypk	zap	zbl	zen	zha	znd	zul	zun	zxx	zza");
+        
+        // fill the obsolete Language Codes array
+        $this->obsoleteLanguageCodes = explode("\t", "ajm	esk	esp	eth	far	fri	gag	gua	int	iri	cam	kus	mla	max	mol	lan	gal	lap	sao	gae	scc	scr	sho	snh	sso	swz	tag	taj	tar	tru	tsw");
+        
+        // fill the valid Country Codes array
+        $this->countryCodes = explode("\t", "aca	af 	alu	aku	aa 	abc	ae 	as 	an 	ao 	am 	ay 	aq 	ag 	azu	aru	ai 	aw 	at 	au 	aj 	bf 	ba 	bg 	bb 	bw 	be 	bh 	dm 	bm 	bt 	bo 	bn 	bs 	bv 	bl 	bcc	bi 	vb 	bx 	bu 	uv 	br 	bd 	cau	cb 	cm 	xxc	cv 	cj 	cx 	cd 	cl 	cc 	ch 	xa 	xb 	ck 	cou	cq 	cf 	cg 	ctu	cw 	cr 	ci 	cu 	cy 	xr 	iv 	deu	dk 	dcu	ft 	dq 	dr 	em 	ec 	ua 	es 	enk	eg 	ea 	er 	et 	fk 	fa 	fj 	fi 	flu	fr 	fg 	fp 	go 	gm 	gz 	gau	gs 	gw 	gh 	gi 	gr 	gl 	gd 	gp 	gu 	gt 	gv 	pg 	gy 	ht 	hiu	hm 	ho 	hu 	ic 	idu	ilu	ii 	inu	io 	iau	ir 	iq 	iy 	ie 	is 	it 	jm 	ja 	ji 	jo 	ksu	kv 	kz 	kyu	ke 	gb 	kn 	ko 	ku 	kg 	ls 	lv 	le 	lo 	lb 	ly 	lh 	li 	lau	lu 	xn 	mg 	meu	mw 	my 	xc 	ml 	mm 	mbc	xe 	mq 	mdu	mau	mu 	mf 	ot 	mx 	miu	fm 	xf 	mnu	msu	mou	mv 	mc 	mp 	mtu	mj 	mr 	mz 	sx 	nu 	nbu	np 	ne 	na 	nvu	nkc	nl 	nhu	nju	nmu	nyu	nz 	nfc	nq 	ng 	nr 	xh 	xx 	nx 	ncu	ndu	nik	nw 	ntc	no 	nsc	nuc	ohu	oku	mk 	onc	oru	pk 	pw 	pn 	pp 	pf 	py 	pau	pe 	ph 	pc 	pl 	po 	pic	pr 	qa 	qea	quc	riu	rm 	ru 	rw 	re 	xj 	xd 	xk 	xl 	xm 	ws 	sm 	sf 	snc	su 	stk	sg 	rb 	mo 	se 	sl 	si 	xo 	xv 	bp 	so 	sa 	scu	sdu	xs 	sp 	sh 	xp 	ce 	sj 	sr 	sq 	sw 	sz 	sy 	ta 	tz 	tnu	fs 	txu	th 	tg 	tl 	tma	to 	tr 	ti 	tu 	tk 	tc 	tv 	ug 	un 	ts 	xxk	uik	xxu	uc 	up 	uy 	utu	uz 	nn 	vp 	vc 	ve 	vtu	vm 	vi 	vau	vra	wea	wk 	wlk	wf 	wau	wj 	wvu	ss 	wiu	wyu	xga	xna	xoa	xra	ye 	ykc	za 	rh ");
+        
+        // fill the obsolete Country Codes array
+        $this->obsoleteCountryCodes = explode("\t", "ai 	air	ac 	ajr	bwr	cn 	cz 	cp 	ln 	cs 	err	gsr	ge 	gn 	hk 	iw 	iu 	jn 	kzr	kgr	lvr	lir	mh 	mvr	nm 	pt 	rur	ry 	xi 	sk 	xxr	sb 	sv 	tar	tt 	tkr	unr	uk 	ui 	us 	uzr	vn 	vs 	wb 	ys 	yu ");
+        
+        // the codes cash, lcsh, lcshac, mesh, nal, and rvm are covered by 2nd
+        // indicators in 600-655
+        // they are only used when indicators are not available
+        $this->sources600_651 = explode("\t", "aass	aat	abne	afset	agrifors	agrovoc	agrovocf	agrovocs	aiatsisl	aiatsisp	aiatsiss	aktp	albt	allars	amg	apaist	asft	asrcrfcd	asrcseo	asrctoa	asth	atla	aucsh	barn	bella	bet	bgtchm	bhammf	bhashe	bibalex	biccbmc	bicssc	bidex	bisacsh	bisacmt	bisacrt	blmlsh	bt	cabt	cash	cct	ccte	cctf	ceeus	chirosh	cht	ciesiniv	cilla	conorsi	csahssa	csalsct	csapa	csh	csht	cstud	czenas	dacs	dcs	ddcrit	dissao	dit	drama	dtict	ebfem	eclas	eet	eflch	eks	embne	ept	ericd	est	eurovocen	eurovocsl	fast	fgtpcm	finmesh	fire	fmesh	fnhl	francis	galestne	gem	georeft	gst	gtt	hapi	hkcan	helecon	henn	hlasstg	hoidokki	huc	iaat	ica	icpsr	idas	iescs	iest	ilot	ilpt	inist	inspect	ipat	ipsp	isis	itglit	itoamc	itrt	jhpb	jhpk	jlabsh	kaa	kao	kaunokki	kdm	kitu	kkts	kssbar	kta	ktpt	ktta	kula	kupu	lacnaf	larpcal	lcsh	lcshac	lcstt	lctgm	lemac	lemb	liv	lnmmbr	local	ltcsh	lua	maaq	mar	masa	mech	mesh	mipfesd	mmm	mpirdes	msh	mtirdes	musa	muzeukc	muzeukn	muzeukv	muzvukci	nal	nalnaf	nasat	ncjt	ndllsh	nicem	nimacsc	nlgaf	nlgkk	nlgsh	nlmnaf	nsbncf	ntcpsc	ntcsd	ntissc	nzggn	nznb	ogst	onet	opms	pascal	peri	pha	pkk	pmbok	pmcsg	pmt	poliscit	popinte	precis	prvt	psychit	quiding	qlsp	qrma	qrmak	qtglit	raam	ram	rasuqam	renib	reo	rero	rerovoc	reveal	rma	rpe	rswk	rswkaf	rugeo	rurkp	rvm	sao	sbiao	scbi	scgdst	scisshl	scot	sears	sfit	sgc	sgce	shbe	she	sigle	sipri	sk	skon	slem	smda	snt	socio	sosa	spines	ssg	swd	swemesh	taika	taxhs	tbit	tesa	test	tgn	tho	thub	tlka	tlsh	toit	trt	trtsa	tsht	ttka	tucua	ulan	umitrist	unbisn	unbist	unescot	usaidt	vmj	waqaf	watrest	wgst	wot	wpicsh	ysa");
+        $this->obsoleteSources600_651 = explode("\t", "cash	lcsh	lcshac	mesh	nal	reroa	rvm");
+        $this->sources655 = explode("\t", "aat	afset	aiatsisl	aiatsisp	aiatsiss	aktp	amg	asrcrfcd	asrcseo	asrctoa	asth	aucsh	barn	bibalex	biccbmc	bgtchm	bisacsh	bisacmt	bisacrt	bt	cash	chirosh	cct	conorsi	csht	czenas	dacs	dcs	dct	eet	eflch	embne	ept	ericd	estc	eurovocen	eurovocsl	fast	fbg	finmesh	fire	galestne	gem	gmgpc	gsafd	gst	gtlm	hapi	hkcan	hoidokki	ica	ilot	itglit	itrt	jhpb	jhpk	kkts	lacnaf	lcsh	lcshac	lcstt	lctgm	lemac	local	maaq	mar	marcgt	mech	mesh	migfg	mim	msh	muzeukc	muzeukn	muzeukv	muzvukci	nal	nalnaf	ngl	nimafc	nlgaf	nlgkk	nlgsh	nlmnaf	nmc	nsbncf	nzggn	nznb	onet	opms	pkk	pmcsg	pmt	quiding	qlsp	qrmak	qtglit	raam	radfg	rbbin	rbgenr	rbpap	rbpri	rbprov	rbpub	rbtyp	reo	rerovoc	reveal	rma	rswk	rswkaf	rugeo	rvm	sao	scbi	sears	sgc	sgce	sgp	sipri	skon	snt	socio	spines	ssg	swd	swemesh	tbit	tesa	tho	thub	toit	tsht	tucua	ulan	vmj	waqaf");
+        $this->obsoleteSources655 = explode("\t", "cash	ftamc	lcsh	lcshac	mesh	nal	reroa	rvm");
+        // @codingStandardsIgnoreEnd
+    }
+    // }}}
+}
+// }}}
diff --git a/vendor/File/MARC/List.php b/vendor/File/MARC/List.php
new file mode 100644
index 0000000000000000000000000000000000000000..878b62fea80c3bfce4ed034531d8f25578d170cc
--- /dev/null
+++ b/vendor/File/MARC/List.php
@@ -0,0 +1,98 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: List.php 268035 2008-10-30 17:01:14Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_List extends Structures_LinkedList_Double
+/**
+ * The File_MARC_List class extends the Structures_LinkedList_Double class
+ * to override the key() method in a meaningful way for foreach() iterators.
+ *
+ * For the list of {@link File_MARC_Field} objects in a {@link File_MARC_Record}
+ * object, the key() method returns the tag name of the field.
+ * 
+ * For the list of {@link File_MARC_Subfield} objects in a {@link
+ * File_MARC_Data_Field} object, the key() method returns the code of
+ * the subfield.
+ *
+ * <code>
+ * // Iterate through the fields in a record with key=>value iteration
+ * foreach ($record->getFields() as $tag=>$value) {
+ *     print "$tag: ";
+ *     if ($value instanceof File_MARC_Control_Field) {
+ *         print $value->getData();
+ *     }
+ *     else {
+ *         // Iterate through the subfields in this data field
+ *         foreach ($value->getSubfields() as $code=>$subdata) {
+ *             print "_$code";
+ *         }
+ *     }
+ *     print "\n";
+ * }
+ * </code>
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_List extends Structures_LinkedList_Double
+{
+    // {{{ key()
+    /**
+     * Returns the tag for a {@link File_MARC_Field} object, or the code
+     * for a {@link File_MARC_Subfield} object.
+     *
+     * This method enables you to use a foreach iterator to retrieve
+     * the tag or code as the key for the iterator.
+     *
+     * @return string returns the tag or code
+     */
+    function key()
+    {
+        if ($this->current() instanceof File_MARC_Field) {
+            return $this->current()->getTag();
+        } elseif ($this->current() instanceof File_MARC_Subfield) {
+            return $this->current()->getCode();
+        }
+        return false;
+    }
+    // }}}
+}
+// }}}
+
diff --git a/vendor/File/MARC/Record.php b/vendor/File/MARC/Record.php
new file mode 100644
index 0000000000000000000000000000000000000000..43e91a08edde3cc77014ea745e4d88d4017355ae
--- /dev/null
+++ b/vendor/File/MARC/Record.php
@@ -0,0 +1,691 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Record.php 308146 2011-02-08 20:36:20Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Record
+/**
+ * Represents a single MARC record
+ * 
+ * A MARC record contains a leader and zero or more fields held within a
+ * linked list structure. Fields are represented by {@link File_MARC_Data_Field}
+ * objects.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Christoffer Landtman <landtman@realnode.com>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Record
+{
+
+    // {{{ properties
+    /**
+     * Contains a linked list of {@link File_MARC_Data_Field} objects for
+     * this record
+     * @var File_MARC_List
+     */
+    protected $fields;
+
+    /**
+     * Record leader
+     * @var string
+     */
+    protected $leader;
+
+    /**
+     * Non-fatal warnings generated during parsing
+     * @var array
+     */
+    protected $warnings;
+
+    /**
+     * XMLWriter for writing collections
+     * 
+     * @var XMLWriter
+     */
+    protected $marcxml;
+
+    /**
+     * MARC instance for access to the XML header/footer methods
+     * We need this so that we can properly wrap a collection of MARC records.
+     * 
+     * @var File_MARC
+     */
+    protected $marc;
+
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Start function
+     *
+     * Set all variables to defaults to create new File_MARC_Record object
+     *
+     * @param File_MARC $marc MARC record from File_MARC or File_MARCXML
+     *
+     * @return true 
+     */
+    function __construct($marc = null)
+    {
+        $this->fields = new File_MARC_List();
+        $this->setLeader(str_repeat(' ', 24));
+        if (!$marc) {
+            $marc = new File_MARC(null, File_MARC::SOURCE_STRING); // oh the hack
+        }
+        $this->marc = $marc;
+        $this->marcxml = $marc->getXMLWriter();
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Destroys the data field
+     */
+    function __destruct()
+    {
+        $this->fields = null;
+        $this->warnings = null;
+    }
+    // }}}
+
+    // {{{ getLeader()
+    /**
+     * Get MARC leader
+     *
+     * Returns the leader for the MARC record. No validation
+     * on the specified leader is performed.
+     *
+     * @return string returns the leader
+     */
+    function getLeader()
+    {
+        return (string)$this->leader;
+    }
+    // }}}
+
+    // {{{ setLeader()
+    /**
+     * Set MARC record leader
+     *
+     * Sets the leader for the MARC record. No validation
+     * on the specified leader is performed.
+     *
+     * @param string $leader Leader
+     *
+     * @return string returns the leader
+     */
+    function setLeader($leader)
+    {
+        $this->leader = $leader;
+        return $this->leader;
+    }
+    // }}}
+
+    // {{{ appendField()
+    /**
+     * Appends field to MARC record
+     *
+     * Adds a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field}
+     * object to the end of the existing list of fields.
+     *
+     * @param File_MARC_Field $new_field The field to add
+     *
+     * @return File_MARC_Field The field that was added
+     */
+    function appendField(File_MARC_Field $new_field)
+    {
+        /* Append as the last field in the record */
+        $this->fields->appendNode($new_field);
+        return $new_field;
+    }
+    // }}}
+
+    // {{{ prependField()
+    /**
+     * Prepends field to MARC record
+     *
+     * Adds a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field}
+     * object to the start of to the existing list of fields.
+     *
+     * @param File_MARC_Field $new_field The field to add
+     *
+     * @return File_MARC_Field The field that was added
+     */
+    function prependField(File_MARC_Field $new_field)
+    {
+        $this->fields->prependNode($new_field);
+        return $new_field;
+    }
+    // }}}
+
+    // {{{ insertField()
+    /**
+     * Inserts a field in the MARC record relative to an existing field
+     *
+     * Inserts a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field}
+     * object before or after a specified existing field.
+     *
+     * <code>
+     * // Example: Insert a new field before the first 650 field
+     *
+     * // Create the new field
+     * $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.');
+     * $new_field = new File_MARC_Data_Field('100', $subfields, 0, null);
+     *
+     * // Retrieve the target field for our insertion point
+     * $subject = $record->getFields('650');
+     *
+     * // Insert the new field
+     * if (is_array($subject)) {
+     *     $record->insertField($new_field, $subject[0], true);
+     * }
+     * elseif ($subject) {
+     *     $record->insertField($new_field, $subject, true);
+     * }
+     * </code>
+     *
+     * @param File_MARC_Field $new_field      The field to add
+     * @param File_MARC_Field $existing_field The target field
+     * @param bool            $before         Insert the new field before the existing field if true, after the existing field if false
+     *
+     * @return File_MARC_Field                The field that was added
+     */
+    function insertField(File_MARC_Field $new_field, File_MARC_Field $existing_field, $before = false)
+    {
+        switch ($before) {
+        /* Insert before the specified field in the record */
+        case true:
+            $this->fields->insertNode($new_field, $existing_field, true);
+            break;
+
+        /* Insert after the specified field in the record */
+        case false:
+            $this->fields->insertNode($new_field, $existing_field);
+            break;
+
+        default: 
+             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INSERTFIELD_MODE], array("mode" => $before));
+             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INSERTFIELD_MODE);
+        }
+        return $new_field;
+    }
+    // }}}
+
+    // {{{ _buildDirectory()
+    /**
+     * Build record directory
+     *
+     * Generate the directory of the record according to the current contents
+     * of the record.
+     *
+     * @return array Array ($fields, $directory, $total, $base_address)
+     */
+    private function _buildDirectory()
+    {
+        // Vars
+        $fields = array();
+        $directory = array();
+        $data_end = 0;
+
+        foreach ($this->fields as $field) {
+            // No empty fields allowed
+            if (!$field->isEmpty()) {
+                // Get data in raw format
+                $str = $field->toRaw();
+                $fields[] = $str;
+
+                // Create directory entry
+                $len = strlen($str);
+                $direntry = sprintf("%03s%04d%05d", $field->getTag(), $len, $data_end);
+                $directory[] = $direntry;
+                $data_end += $len;
+            }
+        }
+
+        /**
+         * Rules from MARC::Record::USMARC
+         */
+        $base_address
+            = File_MARC::LEADER_LEN +    // better be 24
+                (count($directory) * File_MARC::DIRECTORY_ENTRY_LEN) +
+                                // all the directory entries
+                1;              // end-of-field marker
+
+
+        $total
+            = $base_address +  // stuff before first field
+                $data_end +      // Length of the fields
+                1;              // End-of-record marker
+
+
+        return array($fields, $directory, $total, $base_address);
+    }
+    // }}}
+
+    // {{{ setLeaderLengths()
+    /**
+     * Set MARC record leader lengths
+     *
+     * Set the Leader lengths of the record according to defaults specified in
+     * {@link http://www.loc.gov/marc/bibliographic/ecbdldrd.html}
+     *
+     * @param int $record_length Record length
+     * @param int $base_address  Base address of data
+     *
+     * @return bool              Success or failure
+     */
+    function setLeaderLengths($record_length, $base_address)
+    {
+        if (!is_int($record_length)) {
+            return false;
+        }
+        if (!is_int($base_address)) {
+            return false;
+        }
+
+        // Set record length
+        $this->setLeader(substr_replace($this->getLeader(), sprintf("%05d", $record_length), 0, 5));
+        $this->setLeader(substr_replace($this->getLeader(), sprintf("%05d", $base_address), File_MARC::DIRECTORY_ENTRY_LEN, 5));
+        $this->setLeader(substr_replace($this->getLeader(), '22', 10, 2));
+        $this->setLeader(substr_replace($this->getLeader(), '4500', 20, 4));
+
+        if (strlen($this->getLeader()) > File_MARC::LEADER_LEN) {
+            // Avoid incoming leaders that are mangled to be overly long
+            $this->setLeader(substr($this->getLeader(), 0, File_MARC::LEADER_LEN));
+            $this->addWarning("Input leader was too long; truncated to " . File_MARC::LEADER_LEN . " characters");
+        }
+        return true;
+    }
+    // }}}
+
+    // {{{ getField()
+    /**
+     * Return the first {@link File_MARC_Data_Field} or
+     * {@link File_MARC_Control_Field} object that matches the specified tag
+     * name. Returns false if no match is found.
+     *
+     * @param string $spec tag name
+     * @param bool   $pcre if true, then match as a regular expression
+     *
+     * @return {@link File_MARC_Data_Field}|{@link File_MARC_Control_Field} first field that matches the requested tag name
+     */
+    function getField($spec = null, $pcre = null)
+    {
+        foreach ($this->fields as $field) {
+            if (($pcre
+                && preg_match("/$spec/", $field->getTag()))
+                || (!$pcre
+                && $spec == $field->getTag())
+            ) {
+                return $field;
+            }
+        }
+        return false;
+    }
+    // }}}
+
+    // {{{ getFields()
+    /**
+     * Return an array or {@link File_MARC_List} containing all
+     * {@link File_MARC_Data_Field} or  {@link File_MARC_Control_Field} objects
+     * that match the specified tag name. If the tag name is omitted all
+     * fields are returned.
+     *
+     * @param string $spec tag name
+     * @param bool   $pcre if true, then match as a regular expression
+     *
+     * @return File_MARC_List|array {@link File_MARC_Data_Field} or
+     * {@link File_MARC_Control_Field} objects that match the requested tag name
+     */
+    function getFields($spec = null, $pcre = null)
+    {
+        if (!$spec) {
+            return $this->fields;
+        }
+
+        // Okay, we're actually looking for something specific
+        $matches = array();
+        foreach ($this->fields as $field) {
+            if (($pcre && preg_match("/$spec/", $field->getTag()))
+                || (!$pcre && $spec == $field->getTag())
+            ) {
+                $matches[] = $field;
+            }
+        }
+        return $matches;
+    }
+    // }}}
+
+    // {{{ deleteFields()
+    /**
+     * Delete all occurrences of a field matching a tag name from the record.
+     *
+     * @param string $tag  tag for the fields to be deleted
+     * @param bool   $pcre if true, then match as a regular expression
+     *
+     * @return int         number of fields that were deleted
+     */
+    function deleteFields($tag, $pcre = null)
+    {
+        $cnt = 0;
+        foreach ($this->getFields() as $field) {
+            if (($pcre
+                && preg_match("/$tag/", $field->getTag()))
+                || (!$pcre
+                && $tag == $field->getTag())
+            ) {
+                $field->delete();
+                $cnt++;
+            }
+        }
+        return $cnt;
+    }
+    // }}}
+
+    // {{{ addWarning()
+    /**
+     * Add a warning to the MARC record that something non-fatal occurred during
+     * parsing.
+     *
+     * @param string $warning warning message
+     *
+     * @return true
+     */
+    public function addWarning($warning)
+    {
+        $this->warnings[] = $warning;
+    }
+    // }}}
+
+    // {{{ getWarnings()
+    /**
+     * Return the array of warnings from the MARC record.
+     *
+     * @return array warning messages
+     */
+    public function getWarnings()
+    {
+        return $this->warnings;
+    }
+    // }}}
+
+    // {{{ output methods
+    /**
+     * ========== OUTPUT METHODS ==========
+     */
+
+    // {{{ toRaw()
+    /**
+     * Return the record in raw MARC format.
+     *
+     * If you have modified an existing MARC record or created a new MARC
+     * record, use this method to save the record for use in other programs
+     * that accept the MARC format -- for example, your integrated library
+     * system.
+     *
+     * <code>
+     * // Example: Modify a record and save the output to a file
+     * $record->deleteFields('650');
+     *
+     * // Now that the record has no subject fields, save it to disk
+     * fopen($file, '/home/dan/no_subject.mrc', 'w');
+     * fwrite($file, $record->toRaw());
+     * fclose($file);
+     * </code>
+     *
+     * @return string Raw MARC data
+     */
+    function toRaw()
+    {
+        list($fields, $directory, $record_length, $base_address) = $this->_buildDirectory();
+        $this->setLeaderLengths($record_length, $base_address);
+
+        /**
+         * Glue together all parts
+         */
+        return $this->getLeader().implode("", $directory).File_MARC::END_OF_FIELD.implode("", $fields).File_MARC::END_OF_RECORD;
+    }
+    // }}}
+
+    // {{{ __toString()
+    /**
+     * Return the MARC record in a pretty printed string
+     *
+     * This method produces an easy-to-read textual display of a MARC record.
+     *
+     * The structure is roughly:
+     * <tag> <ind1> <ind2> _<code><data>
+     *                     _<code><data>
+     *
+     * @return string Formatted representation of MARC record
+     */
+    function __toString()
+    {
+        // Begin output
+        $formatted = "LDR " . $this->getLeader() . "\n";
+        foreach ($this->fields as $field) {
+            if (!$field->isEmpty()) {
+                $formatted .= $field->__toString() . "\n";
+            }
+        }
+        return $formatted;
+    }
+    // }}}
+
+    // {{{ toJSON()
+    /**
+     * Return the MARC record in JSON format
+     *
+     * This method produces a JSON representation of a MARC record. The input
+     * encoding must be UTF8, otherwise the returned values will be corrupted.
+     *
+     * @return string          representation of MARC record in JSON format
+     *
+     * @todo Fix encoding input / output issues (PHP 6.0 required?)
+     */
+    function toJSON()
+    {
+        $json = new StdClass();
+        $json->leader = utf8_encode($this->getLeader());
+
+        /* Start fields */
+        $fields = array();
+        foreach ($this->fields as $field) {
+            if (!$field->isEmpty()) {
+                switch(get_class($field)) {
+                case "File_MARC_Control_Field":
+                    $fields[] = array(utf8_encode($field->getTag()) => utf8_encode($field->getData()));
+                    break;
+
+                case "File_MARC_Data_Field":
+                    $subs = array();
+                    foreach ($field->getSubfields() as $sf) {
+                        $subs[] = array(utf8_encode($sf->getCode()) => utf8_encode($sf->getData()));
+                    }
+                    $contents = new StdClass();
+                    $contents->ind1 = utf8_encode($field->getIndicator(1));
+                    $contents->ind2 = utf8_encode($field->getIndicator(2));
+                    $contents->subfields = $subs;
+                    $fields[] = array(utf8_encode($field->getTag()) => $contents);
+                    break;
+                }
+            }
+        }
+        /* End fields and record */
+
+        $json->fields = $fields;
+        return json_encode($json);
+    }
+
+    // }}}
+
+    // {{{ toJSONHash()
+    /**
+     * Return the MARC record in Bill Dueber's MARC-HASH JSON format
+     *
+     * This method produces a JSON representation of a MARC record as defined
+     * at http://robotlibrarian.billdueber.com/new-interest-in-marc-hash-json/
+     * The input * encoding must be UTF8, otherwise the returned values will
+     * be corrupted.
+     *
+     * @return string          representation of MARC record in JSON format
+     *
+     * @todo Fix encoding input / output issues (PHP 6.0 required?)
+     */
+    function toJSONHash()
+    {
+        $json = new StdClass();
+        $json->type = "marc-hash";
+        $json->version = array(1, 0);
+        $json->leader = utf8_encode($this->getLeader());
+
+        /* Start fields */
+        $fields = array();
+        foreach ($this->fields as $field) {
+            if (!$field->isEmpty()) {
+                switch(get_class($field)) {
+                case "File_MARC_Control_Field":
+                    $fields[] = array(utf8_encode($field->getTag()), utf8_encode($field->getData()));
+                    break;
+
+                case "File_MARC_Data_Field":
+                    $subs = array();
+                    foreach ($field->getSubfields() as $sf) {
+                        $subs[] = array(utf8_encode($sf->getCode()), utf8_encode($sf->getData()));
+                    }
+                    $contents = array(
+                        utf8_encode($field->getTag()),
+                        utf8_encode($field->getIndicator(1)),
+                        utf8_encode($field->getIndicator(2)),
+                        $subs
+                    );
+                    $fields[] = $contents;
+                    break;
+                }
+            }
+        }
+        /* End fields and record */
+
+        $json->fields = $fields;
+        return json_encode($json);
+    }
+
+    // }}}
+
+
+    // {{{ toXML()
+    /**
+     * Return the MARC record in MARCXML format
+     *
+     * This method produces an XML representation of a MARC record that
+     * attempts to adhere to the MARCXML standard documented at
+     * http://www.loc.gov/standards/marcxml/
+     *
+     * @param string $encoding output encoding for the MARCXML record
+     * @param bool   $indent   pretty-print the MARCXML record
+     * @param bool   $single   wrap the <record> element in a <collection> element
+     *
+     * @return string          representation of MARC record in MARCXML format
+     *
+     * @todo Fix encoding input / output issues (PHP 6.0 required?)
+     */
+    function toXML($encoding = "UTF-8", $indent = true, $single = true)
+    {
+        $this->marcxml->setIndent($indent);
+        if ($single) {
+            $this->marc->toXMLHeader();
+        }
+        $this->marcxml->startElement("record");
+
+        // MARCXML schema has some strict requirements
+        // We'll set reasonable defaults to avoid invalid MARCXML
+        $xmlLeader = $this->getLeader();
+
+        // Record status
+        if ($xmlLeader[5] == " ") {
+            // Default to "n" (new record)
+            $xmlLeader[5] = "n";
+        }
+
+        // Type of record
+        if ($xmlLeader[6] == " ") {
+            // Default to "a" (language material)
+            $xmlLeader[6] = "a";
+        }
+
+        $this->marcxml->writeElement("leader", $xmlLeader);
+
+        foreach ($this->fields as $field) {
+            if (!$field->isEmpty()) {
+                switch(get_class($field)) {
+                case "File_MARC_Control_Field":
+                    $this->marcxml->startElement("controlfield");
+                    $this->marcxml->writeAttribute("tag", $field->getTag());
+                    $this->marcxml->text($field->getData());
+                    $this->marcxml->endElement(); // end control field
+                    break;
+
+                case "File_MARC_Data_Field":
+                    $this->marcxml->startElement("datafield");
+                    $this->marcxml->writeAttribute("tag", $field->getTag());
+                    $this->marcxml->writeAttribute("ind1", $field->getIndicator(1));
+                    $this->marcxml->writeAttribute("ind2", $field->getIndicator(2));
+                    foreach ($field->getSubfields() as $subfield) {
+                        $this->marcxml->startElement("subfield");
+                        $this->marcxml->writeAttribute("code", $subfield->getCode());
+                        $this->marcxml->text($subfield->getData());
+                        $this->marcxml->endElement(); // end subfield
+                    }
+                    $this->marcxml->endElement(); // end data field
+                    break;
+                }
+            }
+        }
+
+        $this->marcxml->endElement(); // end record
+        if ($single) {
+            return $this->marc->toXMLFooter();
+        }
+    }
+
+    // }}}
+
+}
+// }}}
+
diff --git a/vendor/File/MARC/Subfield.php b/vendor/File/MARC/Subfield.php
new file mode 100644
index 0000000000000000000000000000000000000000..9654a20f8cf127c80f648a0c3c445dd695a42564
--- /dev/null
+++ b/vendor/File/MARC/Subfield.php
@@ -0,0 +1,217 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Christoffer Landtman <landtman@realnode.com>
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2003-2008 Oy Realnode Ab, Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: Subfield.php 301737 2010-07-31 04:14:44Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ */
+
+// {{{ class File_MARC_Subfield extends Structures_LinkedList_DoubleNode
+/**
+ * The File_MARC_Subfield class represents a single subfield in a MARC
+ * record field.
+ *
+ * Represents a subfield within a MARC field and implements all management
+ * functions related to a single subfield. This class also implements
+ * the possibility of duplicate subfields within a single field, for example
+ * 650 _z Test1 _z Test2.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Christoffer Landtman <landtman@realnode.com>
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARC_Subfield extends Structures_LinkedList_DoubleNode
+{
+    // {{{ properties
+    /**
+     * Subfield code, e.g. _a, _b
+     * @var string
+     */
+    protected $code;
+
+    /**
+     * Data contained by the subfield
+     * @var string
+     */
+    protected $data;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * File_MARC_Subfield constructor
+     *
+     * Create a new subfield to represent the code and data
+     *
+     * @param string $code Subfield code
+     * @param string $data Subfield data
+     */
+    function __construct($code, $data)
+    {
+        $this->code = $code;
+        $this->data = $data;
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Destroys the subfield
+     */
+    function __destruct()
+    {
+        $this->code = null;
+        $this->data = null;
+        parent::__destruct();
+    }
+    // }}}
+
+    // {{{ Explicit destructor: function delete()
+    /**
+     * Destroys the subfield
+     *
+     * @return true
+     */
+    function delete()
+    {
+        $this->__destruct();
+    }
+    // }}}
+
+    // {{{ getCode()
+    /**
+     * Return code of the subfield
+     *
+     * @return string Tag name
+     */
+    function getCode()
+    {
+        return (string)$this->code;
+    }
+    // }}}
+
+    // {{{ getData()
+    /**
+     * Return data of the subfield
+     *
+     * @return string data
+     */
+    function getData()
+    {
+        return (string)$this->data;
+    }
+    // }}}
+
+    // {{{ __toString()
+    /**
+     * Return string representation of subfield
+     *
+     * @return string String representation
+     */
+    public function __toString()
+    {
+        $pretty = '[' . $this->getCode() . ']: ' . $this->getData();
+        return $pretty;
+    }
+    // }}}
+
+    // {{{ toRaw()
+    /**
+     * Return the USMARC representation of the subfield
+     *
+     * @return string USMARC representation
+     */
+    function toRaw()
+    {
+        $result = File_MARC::SUBFIELD_INDICATOR.$this->code.$this->data;
+        return (string)$result;
+    }
+    // }}}
+
+    // {{{ setCode()
+    /**
+     * Sets code of the subfield
+     *
+     * @param string $code new code for the subfield
+     *
+     * @return string code 
+     */
+    function setCode($code)
+    {
+        if ($code) {
+            // could check more stringently; m/[a-Z]/ or the likes
+            $this->code = $code;
+        } else {
+            // code must be _something_; raise error
+            return false;
+        }
+        return true;
+    }
+    // }}}
+
+    // {{{ setData()
+    /**
+     * Sets data of the subfield
+     *
+     * @param string $data new data for the subfield
+     *
+     * @return string data
+     */
+    function setData($data)
+    {
+        $this->data = $data;
+        return true;
+    }
+    // }}}
+
+    // {{{ isEmpty()
+    /**
+     * Checks whether the subfield is empty or not
+     *
+     * @return bool True or false
+     */
+    function isEmpty()
+    {
+        // There is data
+        if ($this->data) {
+            return false;
+        }
+
+        // There is no data
+        return true;
+    }
+    // }}}
+}
+// }}}
+
diff --git a/vendor/File/MARCBASE.php b/vendor/File/MARCBASE.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea4e4bae85ca4567e95d71c55445fa1a6a44d217
--- /dev/null
+++ b/vendor/File/MARCBASE.php
@@ -0,0 +1,144 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2007-2010 Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: MARCXML.php 301727 2010-07-30 17:30:51Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ * @example   read.php Retrieve specific fields and subfields from a record
+ * @example   subfields.php Create new subfields and add them in specific order
+ * @example   marc_yaz.php Pretty print a MARC record retrieved through the PECL yaz extension
+ */
+
+// {{{ class File_MARCBASE
+/**
+ * The main File_MARCBASE class provides common methods for File_MARC and
+ * File_MARCXML - primarily for generating MARCXML output.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARCBASE
+{
+
+    /**
+     * XMLWriter for writing collections
+     * 
+     * @var XMLWriter
+     */
+    protected $xmlwriter;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Read in MARCXML records
+     *
+     * This function reads in files or strings that
+     * contain one or more MARCXML records.
+     *
+     * <code>
+     * <?php
+     * // Retrieve MARC records from a file
+     * $journals = new File_MARC('journals.mrc', SOURCE_FILE);
+     *
+     * // Retrieve MARC records from a string (e.g. Z39 query results)
+     * $monographs = new File_MARC($raw_marc, SOURCE_STRING);
+     * ?>
+     * </code>
+     *
+     * @param string $source Name of the file, or a raw MARC string
+     * @param int    $type   Source of the input, either SOURCE_FILE or SOURCE_STRING
+     */
+    function __construct($source, $type)
+    {
+        $this->xmlwriter = new XMLWriter();
+        $this->xmlwriter->openMemory();
+        $this->xmlwriter->startDocument('1.0', 'UTF-8');
+    }
+    // }}}
+
+    // {{{ toXMLHeader()
+    /**
+     * Initializes the MARCXML output of a record or collection of records 
+     *
+     * This method produces an XML representation of a MARC record that
+     * attempts to adhere to the MARCXML standard documented at
+     * http://www.loc.gov/standards/marcxml/
+     *
+     * @return bool true if successful
+     */
+    function toXMLHeader()
+    {
+        $this->xmlwriter->startElement("collection");
+        $this->xmlwriter->writeAttribute("xmlns", "http://www.loc.gov/MARC21/slim");
+        return true;
+    }
+    // }}}
+
+    // {{{ getXMLWriter()
+    /**
+     * Returns the XMLWriter object
+     *
+     * This method produces an XML representation of a MARC record that
+     * attempts to adhere to the MARCXML standard documented at
+     * http://www.loc.gov/standards/marcxml/
+     *
+     * @return XMLWriter XMLWriter instance
+     */
+    function getXMLWriter()
+    {
+        return $this->xmlwriter;
+    }
+    // }}}
+
+    // {{{ toXMLFooter()
+    /**
+     * Returns the MARCXML collection footer
+     *
+     * This method produces an XML representation of a MARC record that
+     * attempts to adhere to the MARCXML standard documented at
+     * http://www.loc.gov/standards/marcxml/
+     *
+     * @return string           representation of MARC record in MARCXML format
+     */
+    function toXMLFooter()
+    {
+        $this->xmlwriter->endElement(); // end collection
+        $this->xmlwriter->endDocument();
+        return $this->xmlwriter->outputMemory();
+    }
+    // }}}
+
+}
+// }}}
diff --git a/vendor/File/MARCXML.php b/vendor/File/MARCXML.php
new file mode 100644
index 0000000000000000000000000000000000000000..991c72a8a92e8a341d498a13a77a54e0e61a3690
--- /dev/null
+++ b/vendor/File/MARCXML.php
@@ -0,0 +1,243 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Parser for MARC records
+ *
+ * This package is based on the PHP MARC package, originally called "php-marc",
+ * that is part of the Emilda Project (http://www.emilda.org). Christoffer
+ * Landtman generously agreed to make the "php-marc" code available under the
+ * GNU LGPL so it could be used as the basis of this PEAR package.
+ * 
+ * PHP version 5
+ *
+ * LICENSE: This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category  File_Formats
+ * @package   File_MARC
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2007-2010 Dan Scott
+ * @license   http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @version   CVS: $Id: MARCXML.php 302267 2010-08-15 13:42:59Z dbs $
+ * @link      http://pear.php.net/package/File_MARC
+ * @example   read.php Retrieve specific fields and subfields from a record
+ * @example   subfields.php Create new subfields and add them in specific order
+ * @example   marc_yaz.php Pretty print a MARC record retrieved through the PECL yaz extension
+ */
+
+require_once 'PEAR/Exception.php';
+require_once 'Structures/LinkedList/Double.php';
+require_once 'File/MARCBASE.php';
+require_once 'File/MARC.php';
+require_once 'File/MARC/Record.php';
+require_once 'File/MARC/Field.php';
+require_once 'File/MARC/Control_Field.php';
+require_once 'File/MARC/Data_Field.php';
+require_once 'File/MARC/Subfield.php';
+require_once 'File/MARC/Exception.php';
+require_once 'File/MARC/List.php';
+
+// {{{ class File_MARCXML
+/**
+ * The main File_MARCXML class enables you to return File_MARC_Record
+ * objects from an XML stream or string.
+ *
+ * @category File_Formats
+ * @package  File_MARC
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
+ * @link     http://pear.php.net/package/File_MARC
+ */
+class File_MARCXML extends File_MARCBASE
+{
+
+    // {{{ constants
+
+    /**
+     * MARC records retrieved from a file
+     */
+    const SOURCE_FILE = 1;
+
+    /**
+     * MARC records retrieved from a binary string 
+     */
+    const SOURCE_STRING = 2;
+    // }}}
+
+    // {{{ properties
+    /**
+     * Source containing raw records
+     * 
+     * @var resource
+     */
+    protected $source;
+
+    /**
+     * Source type (SOURCE_FILE or SOURCE_STRING)
+     * 
+     * @var int
+     */
+    protected $type;
+
+    /**
+     * Counter for MARCXML records in a collection
+     *
+     * @var int
+     */
+    protected $counter;
+
+    /**
+     * XMLWriter for writing collections
+     * 
+     * @var XMLWriter
+     */
+    protected $xmlwriter;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Read in MARCXML records
+     *
+     * This function reads in files or strings that
+     * contain one or more MARCXML records.
+     *
+     * <code>
+     * <?php
+     * // Retrieve MARC records from a file
+     * $journals = new File_MARC('journals.mrc', SOURCE_FILE);
+     *
+     * // Retrieve MARC records from a string (e.g. Z39 query results)
+     * $monographs = new File_MARC($raw_marc, SOURCE_STRING);
+     * ?>
+     * </code>
+     *
+     * @param string $source Name of the file, or a raw MARC string
+     * @param int    $type   Source of the input, either SOURCE_FILE or SOURCE_STRING
+     */
+    function __construct($source, $type = self::SOURCE_FILE)
+    {
+        parent::__construct($source, $type);
+
+        $this->counter = 0;
+
+        switch ($type) {
+
+        case self::SOURCE_FILE:
+            $this->type = self::SOURCE_FILE;
+            $this->source = simplexml_load_file($source);
+            break;
+
+        case self::SOURCE_STRING:
+            $this->type = self::SOURCE_STRING;
+            $this->source = simplexml_load_string($source);
+            break;
+
+        default:
+             throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_SOURCE], File_MARC_Exception::ERROR_INVALID_SOURCE);
+        }
+
+        if (!$this->source) {
+            $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_FILE], array('filename' => $source));
+            throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_FILE);
+        }
+    }
+    // }}}
+
+    // {{{ next()
+    /**
+     * Return next {@link File_MARC_Record} object
+     *
+     * Decodes the next MARCXML record and returns the {@link File_MARC_Record}
+     * object.
+     * <code>
+     * <?php
+     * // Retrieve a set of MARCXML records from a file
+     * $journals = new File_MARCXML('journals.xml', SOURCE_FILE);
+     *
+     * // Iterate through the retrieved records
+     * while ($record = $journals->next()) {
+     *     print $record;
+     *     print "\n";
+     * }
+     *
+     * ?>
+     * </code>
+     *
+     * @return File_MARC_Record next record, or false if there are
+     * no more records
+     */
+    function next()
+    {
+        if (isset($this->source->record[$this->counter])) {
+            $record = $this->source->record[$this->counter++];
+        } elseif ($this->source->getName() == "record" && $this->counter == 0) {
+            $record = $this->source;
+            $this->counter++;
+        } else {
+            return false;
+        }
+        
+        if ($record) {
+            return $this->_decode($record);
+        } else {
+            return false;
+        }
+    }
+    // }}}
+
+    // {{{ _decode()
+    /**
+     * Decode a given MARCXML record
+     *
+     * @param string $text MARCXML record element
+     *
+     * @return File_MARC_Record Decoded File_MARC_Record object
+     */
+    private function _decode($text)
+    {
+        $marc = new File_MARC_Record($this);
+
+        // Store leader
+        $marc->setLeader($text->leader);
+
+        // go through all the control fields
+        foreach ($text->controlfield as $controlfield) {
+            $marc->appendField(new File_MARC_Control_Field((string)$controlfield['tag'], $controlfield));
+        }
+
+        // go through all the data fields
+        foreach ($text->datafield as $datafield) {
+            $subfield_data = array();
+            foreach ($datafield->subfield as $subfield) {
+                $subfield_data[] = new File_MARC_Subfield((string)$subfield['code'], $subfield);
+            }
+            
+            // If the data is invalid, let's just ignore the one field
+            try {
+                $new_field = new File_MARC_Data_Field((string)$datafield['tag'], $subfield_data, $datafield['ind1'], $datafield['ind2']);
+                $marc->appendField($new_field);
+            } catch (Exception $e) {
+                $marc->addWarning($e->getMessage());
+            }
+        }
+
+        return $marc;
+    }
+    // }}}
+
+}
+// }}}
+
diff --git a/vendor/Horde/Exception.php b/vendor/Horde/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0271ad4c1b8fe8e434871890f8d91a30ec7ad90
--- /dev/null
+++ b/vendor/Horde/Exception.php
@@ -0,0 +1,89 @@
+<?php
+if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+    /**
+     * Horde base exception class that supports prior exception for PHP < 5.3.0
+     *
+     * Originates from
+     * http://framework.zend.com/wiki/display/ZFPROP/previous+Exception+on+Zend_Exception+-+Marc+Bennewitz
+     *
+     * Copyright 2008-2011 The Horde Project (http://www.horde.org/)
+     *
+     * See the enclosed file COPYING for license information (LGPL). If you
+     * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+     *
+     * @category Horde
+     * @package  Exception
+     */
+    class Horde_Exception extends Exception
+    {
+        private $_previous = null;
+
+        /**
+         * Error details that should not be part of the main exception message,
+         * e.g. any additional debugging information.
+         *
+         * @var string
+         */
+        public $details;
+
+        /**
+         * Construct the exception
+         *
+         * @param string $msg
+         * @param int $code
+         * @param Exception $previous
+         */
+        public function __construct($msg = '', $code = 0, Exception $previous = null)
+        {
+            parent::__construct($msg, $code);
+            $this->_previous = $previous;
+        }
+
+        /**
+         * Returns previous Exception
+         *
+         * @return Exception|null
+         */
+        final public function getPrevious()
+        {
+            return $this->_previous;
+        }
+
+        /**
+         * String representation of the exception
+         *
+         * @return string
+         */
+        public function __toString()
+        {
+            if ($this->getPrevious()) {
+                return $this->getPrevious()->__toString() . "\n\nNext " . parent::__toString();
+            } else {
+                return parent::__toString();
+            }
+        }
+
+    }
+} else {
+    /**
+     * Horde base exception class.
+     *
+     * Copyright 2008-2011 The Horde Project (http://www.horde.org/)
+     *
+     * See the enclosed file COPYING for license information (LGPL). If you
+     * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+     *
+     * @category Horde
+     * @package  Exception
+     */
+    class Horde_Exception extends Exception
+    {
+        /**
+         * Error details that should not be part of the main exception message,
+         * e.g. any additional debugging information.
+         *
+         * @var string
+         */
+        public $details;
+    }
+}
diff --git a/vendor/Horde/Exception/LastError.php b/vendor/Horde/Exception/LastError.php
new file mode 100644
index 0000000000000000000000000000000000000000..39b1546ffa9b9cae7a359fcb9426b5bd4187894a
--- /dev/null
+++ b/vendor/Horde/Exception/LastError.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Horde exception class that accepts output of error_get_last() as $code and
+ * mask itself as that error.
+ *
+ * Copyright 2008-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Exception
+ */
+class Horde_Exception_LastError extends Horde_Exception
+{
+    /**
+     * Exception constructor
+     *
+     * If $lasterror is passed the return value of error_get_last() (or a
+     * matching format), the exception will be rewritten to have its file and
+     * line parameters match that of the array, and any message in the array
+     * will be appended to $message.
+     *
+     * @param mixed $message             The exception message, a PEAR_Error
+     *                                   object, or an Exception object.
+     * @param mixed $code_or_lasterror   Either a numeric error code, or
+     *                                   an array from error_get_last().
+     */
+    public function __construct($message = null, $code_or_lasterror = null)
+    {
+        if (is_array($code_or_lasterror)) {
+            if ($message) {
+                $message .= $code_or_lasterror['message'];
+            } else {
+                $message = $code_or_lasterror['message'];
+            }
+            parent::__construct($message, $code_or_lasterror['type']);
+            $this->file = $code_or_lasterror['file'];
+            $this->line = $code_or_lasterror['line'];
+        } else {
+            parent::__construct($message, $code_or_lasterror);
+        }
+    }
+
+}
diff --git a/vendor/Horde/Exception/NotFound.php b/vendor/Horde/Exception/NotFound.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff6b00588af843cbb7012f8c8cefde739637b6a7
--- /dev/null
+++ b/vendor/Horde/Exception/NotFound.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Exception thrown if an object wasn't found.
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Exception
+ */
+class Horde_Exception_NotFound extends Horde_Exception
+{
+    /**
+     * Constructor.
+     *
+     * @see Horde_Exception::__construct()
+     *
+     * @param mixed $message           The exception message, a PEAR_Error
+     *                                 object, or an Exception object.
+     * @param integer $code            A numeric error code.
+     */
+    public function __construct($message = null, $code = null)
+    {
+        if (is_null($message)) {
+            $message = Horde_Exception_Translation::t("Not Found");
+        }
+        parent::__construct($message, $code);
+    }
+}
\ No newline at end of file
diff --git a/vendor/Horde/Exception/Pear.php b/vendor/Horde/Exception/Pear.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c6c121d8af08294bd4b75064925c476daeaa25a
--- /dev/null
+++ b/vendor/Horde/Exception/Pear.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Horde exception class that converts PEAR errors to exceptions.
+ *
+ * Copyright 2008-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Exception
+ */
+class Horde_Exception_Pear extends Horde_Exception
+{
+    /**
+     * The class name for generated exceptions.
+     *
+     * @var string
+     */
+    static protected $_class = __CLASS__;
+
+    /**
+     * The original PEAR error.
+     *
+     * @var PEAR_Error
+     */
+    private $_error;
+
+    /**
+     * Exception constructor.
+     *
+     * @param PEAR_Error $error The PEAR error.
+     */
+    public function __construct(PEAR_Error $error)
+    {
+        parent::__construct(
+            $error->getMessage() . $this->_getPearTrace($error),
+            $error->getCode()
+        );
+        if ($details = $error->getUserInfo()) {
+            $this->details = $details;
+        }
+    }
+
+    /**
+     * Return a trace for the PEAR error.
+     *
+     * @param PEAR_Error $error The PEAR error.
+     *
+     * @return string The backtrace as a string.
+     */
+    private function _getPearTrace(PEAR_Error $error)
+    {
+        $backtrace = $error->getBacktrace();
+        if (!empty($backtrace)) {
+            $pear_error = "\n\n" . 'PEAR Error:' . "\n";
+            foreach ($backtrace as $frame) {
+                $pear_error .= '    '
+                    . (isset($frame['class']) ? $frame['class'] : '')
+                    . (isset($frame['type']) ? $frame['type'] : '')
+                    . (isset($frame['function']) ? $frame['function'] : 'unkown') . ' '
+                    . (isset($frame['file']) ? $frame['file'] : 'unkown') . ':'
+                    . (isset($frame['line']) ? $frame['line'] : 'unkown') . "\n";
+            }
+            $pear_error .= "\n";
+            return $pear_error;
+        }
+        return '';
+    }
+
+    /**
+     * Exception handling.
+     *
+     * @param mixed $result The result to be checked for a PEAR_Error.
+     *
+     * @return mixed Returns the original result if it was no PEAR_Error.
+     *
+     * @throws Horde_Exception_Pear In case the result was a PEAR_Error.
+     */
+    static public function catchError($result)
+    {
+        if ($result instanceOf PEAR_Error) {
+            throw new self::$_class($result);
+        }
+        return $result;
+    }
+}
diff --git a/vendor/Horde/Exception/PermissionDenied.php b/vendor/Horde/Exception/PermissionDenied.php
new file mode 100644
index 0000000000000000000000000000000000000000..943c7cc3f5bec6f5713b815920c09f2b77e85be8
--- /dev/null
+++ b/vendor/Horde/Exception/PermissionDenied.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Exception thrown if any access without sufficient permissions occured.
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Exception
+ */
+class Horde_Exception_PermissionDenied extends Horde_Exception
+{
+    /**
+     * Constructor.
+     *
+     * @see Horde_Exception::__construct()
+     *
+     * @param mixed $message           The exception message, a PEAR_Error
+     *                                 object, or an Exception object.
+     * @param integer $code            A numeric error code.
+     */
+    public function __construct($message = null, $code = null)
+    {
+        if (is_null($message)) {
+            $message = Horde_Exception_Translation::t("Permission Denied");
+        }
+        parent::__construct($message, $code);
+    }
+}
\ No newline at end of file
diff --git a/vendor/Horde/Exception/Translation.php b/vendor/Horde/Exception/Translation.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca98f3a24ea35a57eb27813c60cda43a4308486c
--- /dev/null
+++ b/vendor/Horde/Exception/Translation.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * @package Exception
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * Horde_Exception_Translation is the translation wrapper class for Horde_Exception.
+ *
+ * @author  Jan Schneider <jan@horde.org>
+ * @package Exception
+ */
+class Horde_Exception_Translation extends Horde_Translation
+{
+    /**
+     * Returns the translation of a message.
+     *
+     * @var string $message  The string to translate.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    static public function t($message)
+    {
+        self::$_domain = 'Horde_Exception';
+        self::$_directory = '/usr/share/php/data' == '@'.'data_dir'.'@' ? dirname(__FILE__) . '/../../../locale' : '/usr/share/php/data/Horde_Exception/locale';
+        return parent::t($message);
+    }
+
+    /**
+     * Returns the plural translation of a message.
+     *
+     * @param string $singular  The singular version to translate.
+     * @param string $plural    The plural version to translate.
+     * @param integer $number   The number that determines singular vs. plural.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    static public function ngettext($singular, $plural, $number)
+    {
+        self::$_domain = 'Horde_Exception';
+        self::$_directory = '/usr/share/php/data' == '@'.'data_dir'.'@' ? dirname(__FILE__) . '/../../../locale' : '/usr/share/php/data/Horde_Exception/locale';
+        return parent::ngettext($singular, $plural, $number);
+    }
+}
diff --git a/vendor/Horde/Exception/Wrapped.php b/vendor/Horde/Exception/Wrapped.php
new file mode 100644
index 0000000000000000000000000000000000000000..173498d714148d57a32d68b667e68d8e0be59c0d
--- /dev/null
+++ b/vendor/Horde/Exception/Wrapped.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Horde exception class that can wrap and set its details from PEAR_Error,
+ * Exception, and other objects with similar interfaces.
+ *
+ * Copyright 2008-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Exception
+ */
+class Horde_Exception_Wrapped extends Horde_Exception
+{
+    /**
+     * Exception constructor.
+     *
+     * @param mixed $message The exception message, a PEAR_Error
+     *                       object, or an Exception object.
+     * @param int   $code    A numeric error code.
+     */
+    public function __construct($message = null, $code = 0)
+    {
+        $previous = null;
+        if (is_object($message) &&
+            method_exists($message, 'getMessage')) {
+            if (empty($code) &&
+                method_exists($message, 'getCode')) {
+                $code = $message->getCode();
+            }
+            if ($message instanceof Exception) {
+                $previous = $message;
+            }
+            if (method_exists($message, 'getUserinfo') &&
+                $details = $message->getUserinfo()) {
+                $this->details = $details;
+            }
+            $message = $message->getMessage();
+        }
+
+        parent::__construct($message, $code, $previous);
+    }
+}
diff --git a/vendor/Horde/Translation.php b/vendor/Horde/Translation.php
new file mode 100644
index 0000000000000000000000000000000000000000..9eda63472b53b2bf4cb134258c040b5a79910326
--- /dev/null
+++ b/vendor/Horde/Translation.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * @package Translation
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * Horde_Translation is the base class for any translation wrapper classes in
+ * libraries that want to utilize the Horde_Translation library for
+ * translations.
+ *
+ * @author  Jan Schneider <jan@horde.org>
+ * @package Translation
+ */
+abstract class Horde_Translation
+{
+    /**
+     * The translation domain, e.g. the library name, for the default gettext
+     * handler.
+     *
+     * @var string
+     */
+    static protected $_domain;
+
+    /**
+     * The relative path to the translations for the default gettext handler.
+     *
+     * This path is relative to the
+     *
+     * @var string
+     */
+    static protected $_directory;
+
+    /**
+     * The handlers providing the actual translations.
+     *
+     * @var array
+     */
+    static protected $_handlers = array();
+
+    /**
+     * Loads a translation handler class pointing to the library's translations
+     * and assigns it to $_handler.
+     *
+     * @param string $handlerClass  The name of a class implementing the
+     *                              Horde_Translation_Handler interface.
+     */
+    static public function loadHandler($handlerClass)
+    {
+        if (!self::$_domain || !self::$_directory) {
+            throw new Horde_Translation_Exception('The domain and directory properties must be set by the class that extends Horde_Translation.');
+        }
+        self::setHandler(self::$_domain, new $handlerClass(self::$_domain, self::$_directory));
+    }
+
+    /**
+     * Assigns a translation handler object to $_handlers.
+     *
+     * Type hinting isn't used on purpose. You should extend a custom
+     * translation handler passed here from the Horde_Translation interface,
+     * but technically it's sufficient if you provide the API of that
+     * interface.
+     *
+     * @param string $domain                      The translation domain.
+     * @param Horde_Translation_Handler $handler  An object implementing the
+     *                                            Horde_Translation_Handler
+     *                                            interface.
+     */
+    static public function setHandler($domain, $handler)
+    {
+        self::$_handlers[$domain] = $handler;
+    }
+
+    /**
+     * Returns the translation of a message.
+     *
+     * @var string $message  The string to translate.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    static public function t($message)
+    {
+        if (!isset(self::$_handlers[self::$_domain])) {
+            self::loadHandler('Horde_Translation_Handler_Gettext');
+        }
+        return self::$_handlers[self::$_domain]->t($message);
+    }
+
+    /**
+     * Returns the plural translation of a message.
+     *
+     * @param string $singular  The singular version to translate.
+     * @param string $plural    The plural version to translate.
+     * @param integer $number   The number that determines singular vs. plural.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    static public function ngettext($singular, $plural, $number)
+    {
+        if (!isset(self::$_handlers[self::$_domain])) {
+            self::loadHandler('Horde_Translation_Handler_Gettext');
+        }
+        return self::$_handlers[self::$_domain]->ngettext($singular, $plural, $number);
+    }
+}
diff --git a/vendor/Horde/Translation/Exception.php b/vendor/Horde/Translation/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e89cfaaf6a38511d8a6093e47794f760888fe98
--- /dev/null
+++ b/vendor/Horde/Translation/Exception.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Exception class for Horde_Translation.
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author  Jan Schneider <jan@horde.org>
+ * @package Translation
+ */
+class Horde_Translation_Exception extends Horde_Exception_Wrapped
+{
+}
diff --git a/vendor/Horde/Translation/Handler.php b/vendor/Horde/Translation/Handler.php
new file mode 100644
index 0000000000000000000000000000000000000000..3f87df6497acf9e83bb3235e2fc910622a47734a
--- /dev/null
+++ b/vendor/Horde/Translation/Handler.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * @package Translation
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * The Horde_Translation_Handler interface defines the interface for any
+ * classes providing translations.
+ *
+ * @author  Jan Schneider <jan@horde.org>
+ * @package Translation
+ */
+interface Horde_Translation_Handler
+{
+    /**
+     * Returns the translation of a message.
+     *
+     * @var string $message  The string to translate.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    public function t($message);
+
+    /**
+     * Returns the plural translation of a message.
+     *
+     * @param string $singular  The singular version to translate.
+     * @param string $plural    The plural version to translate.
+     * @param integer $number   The number that determines singular vs. plural.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    public function ngettext($singular, $plural, $number);
+}
diff --git a/vendor/Horde/Translation/Handler/Gettext.php b/vendor/Horde/Translation/Handler/Gettext.php
new file mode 100644
index 0000000000000000000000000000000000000000..73dc181698921d0584ce5eb6b3bfafb838df523d
--- /dev/null
+++ b/vendor/Horde/Translation/Handler/Gettext.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @package Translation
+ *
+ * Copyright 2010-2011 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * The Horde_Translation_Handler_Gettext provides translations through the
+ * gettext extension, but fails gracefully if gettext is not installed.
+ *
+ * @author  Jan Schneider <jan@horde.org>
+ * @package Translation
+ */
+class Horde_Translation_Handler_Gettext implements Horde_Translation_Handler
+{
+    /**
+     * The translation domain, e.g. package name.
+     *
+     * @var string
+     */
+    protected $_domain;
+
+    /**
+     * Whether the gettext extension is installed.
+     *
+     * @var boolean
+     */
+    protected $_gettext;
+
+    /**
+     * Constructor.
+     *
+     * @param string $domain  The translation domain, e.g. package name.
+     * @param string $path    The path to the gettext catalog.
+     */
+    public function __construct($domain, $path)
+    {
+        if (!is_dir($path)) {
+            throw new InvalidArgumentException("$path is not a directory");
+        }
+        $this->_gettext = function_exists('_');
+        if (!$this->_gettext) {
+            return;
+        }
+        $this->_domain = $domain;
+        bindtextdomain($this->_domain, $path);
+    }
+
+    /**
+     * Returns the translation of a message.
+     *
+     * @param string $message  The string to translate.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    public function t($message)
+    {
+        return $this->_gettext ? dgettext($this->_domain, $message) : $message;
+    }
+
+    /**
+     * Returns the plural translation of a message.
+     *
+     * @param string $singular  The singular version to translate.
+     * @param string $plural    The plural version to translate.
+     * @param integer $number   The number that determines singular vs. plural.
+     *
+     * @return string  The string translation, or the original string if no
+     *                 translation exists.
+     */
+    public function ngettext($singular, $plural, $number)
+    {
+        return $this->_gettext
+          ? dngettext($this->_domain, $singular, $plural, $number)
+          : ($number > 1 ? $plural : $singular);
+    }
+}
diff --git a/vendor/Horde/Yaml.php b/vendor/Horde/Yaml.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a740221c915f00b1c514f215c779049ea040ccd
--- /dev/null
+++ b/vendor/Horde/Yaml.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Horde YAML package
+ *
+ * This package is heavily inspired by the Spyc PHP YAML
+ * implementation (http://spyc.sourceforge.net/), and portions are
+ * copyright 2005-2006 Chris Wanstrath.
+ *
+ * @author   Chris Wanstrath <chris@ozmm.org>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
+ * @author   Mike Naberezny <mike@maintainable.com>
+ * @license  http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package  Yaml
+ */
+
+/**
+ * Horde YAML parser.
+ *
+ * This class can be used to read a YAML file and convert its contents
+ * into a PHP array. The native PHP parser supports a limited
+ * subsection of the YAML spec, but if the syck extension is present,
+ * that will be used for parsing.
+ *
+ * @category Horde
+ * @package  Yaml
+ */
+class Horde_Yaml
+{
+    /**
+     * Callback used for alternate YAML loader, typically exported
+     * by a faster PHP extension.  This function's first argument
+     * must accept a string with YAML content.
+     *
+     * @var callback
+     */
+    public static $loadfunc = 'syck_load';
+
+    /**
+     * Callback used for alternate YAML dumper, typically exported
+     * by a faster PHP extension.  This function's first argument
+     * must accept a mixed variable to be dumped.
+     *
+     * @var callback
+     */
+    public static $dumpfunc = 'syck_dump';
+
+    /**
+     * Whitelist of classes that can be instantiated automatically
+     * when loading YAML docs that include serialized PHP objects.
+     *
+     * @var array
+     */
+    public static $allowedClasses = array('ArrayObject');
+
+    /**
+     * Load a string containing YAML and parse it into a PHP array.
+     * Returns an empty array on failure.
+     *
+     * @param  string  $yaml   String containing YAML
+     * @return array           PHP array representation of YAML content
+     */
+    public static function load($yaml)
+    {
+        if (!is_string($yaml) || !strlen($yaml)) {
+            $msg = 'YAML to parse must be a string and cannot be empty.';
+            throw new InvalidArgumentException($msg);
+        }
+
+        if (is_callable(self::$loadfunc)) {
+            return call_user_func(self::$loadfunc, $yaml);
+            return is_array($array) ? $array : array();
+        }
+
+        if (strpos($yaml, "\r") !== false) {
+            $yaml = str_replace(array("\r\n", "\r"), array("\n", "\n"), $yaml);
+        }
+        $lines = explode("\n", $yaml);
+        $loader = new Horde_Yaml_Loader;
+
+        while (list(,$line) = each($lines)) {
+            $loader->parse($line);
+        }
+
+        return $loader->toArray();
+    }
+
+    /**
+     * Load a file containing YAML and parse it into a PHP array.
+     *
+     * If the file cannot be opened, an exception is thrown.  If the
+     * file is read but parsing fails, an empty array is returned.
+     *
+     * @param  string  $filename     Filename to load
+     * @return array                 PHP array representation of YAML content
+     * @throws IllegalArgumentException  If $filename is invalid
+     * @throws Horde_Yaml_Exception  If the file cannot be opened.
+     */
+    public static function loadFile($filename)
+    {
+        if (!is_string($filename) || !strlen($filename)) {
+            $msg = 'Filename must be a string and cannot be empty';
+            throw new InvalidArgumentException($msg);
+        }
+
+        $stream = @fopen($filename, 'rb');
+        if (!$stream) {
+            throw new Horde_Yaml_Exception('Failed to open file: ', error_get_last());
+        }
+
+        return self::loadStream($stream);
+    }
+
+    /**
+     * Load YAML from a PHP stream resource.
+     *
+     * @param  resource  $stream     PHP stream resource
+     * @return array                 PHP array representation of YAML content
+     */
+    public static function loadStream($stream)
+    {
+        if (! is_resource($stream) || get_resource_type($stream) != 'stream') {
+            throw new InvalidArgumentException('Stream must be a stream resource');
+        }
+
+        if (is_callable(self::$loadfunc)) {
+            return call_user_func(self::$loadfunc, stream_get_contents($stream));
+        }
+
+        $loader = new Horde_Yaml_Loader;
+        while (!feof($stream)) {
+            $loader->parse(stream_get_line($stream, 100000, "\n"));
+        }
+
+        return $loader->toArray();
+    }
+
+    /**
+     * Dump a PHP array to YAML.
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.
+     *
+     * @param  array|Traversable  $array     PHP array or traversable object
+     * @param  integer            $options   Options to pass to dumper
+     * @return string                        YAML representation of $value
+     */
+    public static function dump($value, $options = array())
+    {
+        if (is_callable(self::$dumpfunc)) {
+            return call_user_func(self::$dumpfunc, $value);
+        }
+
+        $dumper = new Horde_Yaml_Dumper();
+        return $dumper->dump($value, $options);
+    }
+
+}
diff --git a/vendor/Horde/Yaml/Dumper.php b/vendor/Horde/Yaml/Dumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e9ea4efa97d0205e153d6241887054ac8cd5800
--- /dev/null
+++ b/vendor/Horde/Yaml/Dumper.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Horde YAML package
+ *
+ * This package is heavily inspired by the Spyc PHP YAML
+ * implementation (http://spyc.sourceforge.net/), and portions are
+ * copyright 2005-2006 Chris Wanstrath.
+ *
+ * @author   Chris Wanstrath <chris@ozmm.org>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
+ * @author   Mike Naberezny <mike@maintainable.com>
+ * @license  http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package  Yaml
+ */
+
+/**
+ * Dump PHP data structures to YAML.
+ *
+ * @category Horde
+ * @package  Yaml
+ */
+class Horde_Yaml_Dumper
+{
+    protected $_options = array();
+
+    /**
+     * Dump PHP array to YAML
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into valid YAML.
+     *
+     * Options:
+     *    `indent`:
+     *       number of spaces to indent children (default 2)
+     *    `wordwrap`:
+     *       wordwrap column number (default 40)
+     *
+     * @param  array|Traversable  $array     PHP array or traversable object
+     * @param  integer            $options   Options for dumping
+     * @return string                        YAML representation of $value
+     */
+    public function dump($value, $options = array())
+    {
+        // validate & merge default options
+        if (!is_array($options)) {
+            throw new InvalidArgumentException('Options must be an array');
+        }
+
+        $defaults = array('indent'   => 2,
+                          'wordwrap' => 40);
+        $this->_options = array_merge($defaults, $options);
+
+        if (! is_int($this->_options['indent'])) {
+            throw new InvalidArgumentException('Indent must be an integer');
+        }
+
+        if (! is_int($this->_options['wordwrap'])) {
+            throw new InvalidArgumentException('Wordwrap column must be an integer');
+        }
+
+        // new YAML document
+        $dump = "---\n";
+
+        // iterate through array and yamlize it
+        foreach ($value as $key => $value) {
+            $dump .= $this->_yamlize($key, $value, 0);
+        }
+        return $dump;
+    }
+
+    /**
+     * Attempts to convert a key / value array item to YAML
+     *
+     * @param  string        $key     The name of the key
+     * @param  string|array  $value   The value of the item
+     * @param  integer       $indent  The indent of the current node
+     * @return string
+     */
+    protected function _yamlize($key, $value, $indent)
+    {
+        if ($value instanceof Serializable) {
+            // Dump serializable objects as !php/object::classname serialize_data
+            $data = '!php/object::' . get_class($value) . ' ' . $value->serialize();
+            $string = $this->_dumpNode($key, $data, $indent);
+        } elseif (is_array($value) || $value instanceof Traversable) {
+            // It has children.  Make it the right kind of item.
+            $string = $this->_dumpNode($key, null, $indent);
+
+            // Add the indent.
+            $indent += $this->_options['indent'];
+
+            // Yamlize the array.
+            $string .= $this->_yamlizeArray($value, $indent);
+        } elseif (!is_array($value)) {
+            // No children.
+            $string = $this->_dumpNode($key, $value, $indent);
+        }
+
+        return $string;
+    }
+
+    /**
+     * Attempts to convert an array to YAML
+     *
+     * @param  array    $array The array you want to convert
+     * @param  integer  $indent The indent of the current level
+     * @return string
+     */
+    protected function _yamlizeArray($array, $indent)
+    {
+        if (!is_array($array)) {
+            return false;
+        }
+
+        $string = '';
+        foreach ($array as $key => $value) {
+            $string .= $this->_yamlize($key, $value, $indent);
+        }
+        return $string;
+    }
+
+    /**
+     * Returns YAML from a key and a value
+     *
+     * @param  string   $key     The name of the key
+     * @param  string   $value   The value of the item
+     * @param  integer  $indent  The indent of the current node
+     * @return string
+     */
+    protected function _dumpNode($key, $value, $indent)
+    {
+        $literal = false;
+        // Do some folding here, for blocks.
+        if (strpos($value, "\n") !== false
+            || strpos($value, ': ') !== false
+            || strpos($value, '- ') !== false) {
+            $value = $this->_doLiteralBlock($value, $indent);
+            $literal = true;
+        } else {
+            $value = $this->_fold($value, $indent);
+        }
+
+        if (is_bool($value)) {
+            $value = ($value) ? 'true' : 'false';
+        } elseif (is_float($value)) {
+            if (is_nan($value)) {
+                $value = '.NAN';
+            } elseif ($value === INF) {
+                $value = '.INF';
+            } elseif ($value === -INF) {
+                $value = '-.INF';
+            }
+        }
+
+        $spaces = str_repeat(' ', $indent);
+
+        // Quote strings if necessary, and not folded
+        if (!$literal && strpos($value, "\n") === false && strchr($value, '#')) {
+            $value = "'{$value}'";
+        }
+
+        if (is_int($key)) {
+            // It's a sequence.
+            $string = $spaces . '- ' . $value . "\n";
+        } else {
+            // It's mapped.
+            $string = $spaces . $key . ': ' . $value . "\n";
+        }
+
+        return $string;
+    }
+
+    /**
+     * Creates a literal block for dumping
+     *
+     * @param  string   $value
+     * @param  integer  $indent  The value of the indent.
+     * @return string
+     */
+    protected function _doLiteralBlock($value, $indent)
+    {
+        $exploded = explode("\n", $value);
+        $newValue = '|';
+        $indent += $this->_options['indent'];
+        $spaces = str_repeat(' ', $indent);
+        foreach ($exploded as $line) {
+            $newValue .= "\n" . $spaces . trim($line);
+        }
+        return $newValue;
+    }
+
+    /**
+     * Folds a string of text, if necessary
+     *
+     * @param   $value   The string you wish to fold
+     * @return  string
+     */
+    protected function _fold($value, $indent)
+    {
+        // Don't do anything if wordwrap is set to 0
+        if (! $this->_options['wordwrap']) {
+            return $value;
+        }
+
+        if (strlen($value) > $this->_options['wordwrap']) {
+            $indent += $this->_options['indent'];
+            $indent = str_repeat(' ', $indent);
+            $wrapped = wordwrap($value, $this->_options['wordwrap'], "\n$indent");
+            $value = ">\n" . $indent . $wrapped;
+        }
+
+        return $value;
+    }
+
+}
diff --git a/vendor/Horde/Yaml/Exception.php b/vendor/Horde/Yaml/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..40ba711fce9241acfd85c3273e479c81e9cecf82
--- /dev/null
+++ b/vendor/Horde/Yaml/Exception.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Horde YAML package
+ *
+ * This package is heavily inspired by the Spyc PHP YAML
+ * implementation (http://spyc.sourceforge.net/), and portions are
+ * copyright 2005-2006 Chris Wanstrath.
+ *
+ * @author   Chris Wanstrath <chris@ozmm.org>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
+ * @author   Mike Naberezny <mike@maintainable.com>
+ * @license  http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package  Yaml
+ */
+
+/**
+ * Exception class for exceptions thrown by Horde_Yaml
+ *
+ * @category Horde
+ * @package  Yaml
+ */
+class Horde_Yaml_Exception extends Horde_Exception_LastError
+{
+}
diff --git a/vendor/Horde/Yaml/Loader.php b/vendor/Horde/Yaml/Loader.php
new file mode 100644
index 0000000000000000000000000000000000000000..08160f64789c84db41adc13f5e13fa28a41a345e
--- /dev/null
+++ b/vendor/Horde/Yaml/Loader.php
@@ -0,0 +1,751 @@
+<?php
+/**
+ * Horde YAML package
+ *
+ * This package is heavily inspired by the Spyc PHP YAML
+ * implementation (http://spyc.sourceforge.net/), and portions are
+ * copyright 2005-2006 Chris Wanstrath.
+ *
+ * @author   Chris Wanstrath <chris@ozmm.org>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
+ * @author   Mike Naberezny <mike@maintainable.com>
+ * @license  http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package  Yaml
+ */
+
+/**
+ * Parse YAML strings into PHP data structures
+ *
+ * @category Horde
+ * @package  Yaml
+ */
+class Horde_Yaml_Loader
+{
+    /**
+     * List of nodes with references
+     * @var array
+     */
+    protected $_haveRefs = array();
+
+    /**
+     * All nodes
+     * @var array
+     */
+    protected $_allNodes = array();
+
+    /**
+     * Array of node parents
+     * @var array
+     */
+    protected $_allParent = array();
+
+    /**
+     * Last indent level
+     * @var integer
+     */
+    protected $_lastIndent = 0;
+
+    /**
+     * Last node id
+     * @var integer
+     */
+    protected $_lastNode = null;
+
+    /**
+     * Is the parser inside a block?
+     * @var boolean
+     */
+    protected $_inBlock = false;
+
+    /**
+     * @var boolean
+     */
+    protected $_isInline = false;
+
+    /**
+     * Next node id to use
+     * @var integer
+     */
+    protected $_nodeId = 1;
+
+    /**
+     * Last line number parsed.
+     * @var integer
+     */
+    protected $_lineNumber = 0;
+
+    /**
+     * Create a new YAML parser.
+     */
+    public function __construct()
+    {
+        $base = new Horde_Yaml_Node($this->_nodeId++);
+        $base->indent = 0;
+        $this->_lastNode = $base->id;
+    }
+
+    /**
+     * Return the PHP built from all YAML parsed so far.
+     *
+     * @return array PHP version of parsed YAML
+     */
+    public function toArray()
+    {
+        // Here we travel through node-space and pick out references
+        // (& and *).
+        $this->_linkReferences();
+
+        // Build the PHP array out of node-space.
+        return $this->_buildArray();
+    }
+
+    /**
+     * Parse a line of a YAML file.
+     *
+     * @param  string           $line  The line of YAML to parse.
+     * @return Horde_Yaml_Node         YAML Node
+     */
+    public function parse($line)
+    {
+        // Keep track of how many lines we've parsed for friendlier
+        // error messages.
+        ++$this->_lineNumber;
+
+        $trimmed = trim($line);
+
+        // If the line starts with a tab (instead of a space), throw a fit.
+        if (preg_match('/^ *(\t) *[^\t ]/', $line)) {
+            $msg = "Line {$this->_lineNumber} indent contains a tab.  "
+                 . 'YAML only allows spaces for indentation.';
+            throw new Horde_Yaml_Exception($msg);
+        }
+
+        if (!$this->_inBlock && empty($trimmed)) {
+            return;
+        } elseif ($this->_inBlock && empty($trimmed)) {
+            $last =& $this->_allNodes[$this->_lastNode];
+            $last->data[key($last->data)] .= "\n";
+        } elseif ($trimmed[0] != '#' && substr($trimmed, 0, 3) != '---') {
+            // Create a new node and get its indent
+            $node = new Horde_Yaml_Node($this->_nodeId++);
+            $node->indent = $this->_getIndent($line);
+
+            // Check where the node lies in the hierarchy
+            if ($this->_lastIndent == $node->indent) {
+                // If we're in a block, add the text to the parent's data
+                if ($this->_inBlock) {
+                    $parent =& $this->_allNodes[$this->_lastNode];
+                    $parent->data[key($parent->data)] .= trim($line) . $this->_blockEnd;
+                } else {
+                    // The current node's parent is the same as the previous node's
+                    if (isset($this->_allNodes[$this->_lastNode])) {
+                        $node->parent = $this->_allNodes[$this->_lastNode]->parent;
+                    }
+                }
+            } elseif ($this->_lastIndent < $node->indent) {
+                if ($this->_inBlock) {
+                    $parent =& $this->_allNodes[$this->_lastNode];
+                    $parent->data[key($parent->data)] .= trim($line) . $this->_blockEnd;
+                } elseif (!$this->_inBlock) {
+                    // The current node's parent is the previous node
+                    $node->parent = $this->_lastNode;
+
+                    // If the value of the last node's data was > or |
+                    // we need to start blocking i.e. taking in all
+                    // lines as a text value until we drop our indent.
+                    $parent =& $this->_allNodes[$node->parent];
+                    $this->_allNodes[$node->parent]->children = true;
+                    if (is_array($parent->data)) {
+                        if (isset($parent->data[key($parent->data)])) {
+                            $chk = $parent->data[key($parent->data)];
+                            if ($chk === '>') {
+                                $this->_inBlock = true;
+                                $this->_blockEnd = '';
+                                $parent->data[key($parent->data)] =
+                                    str_replace('>', '', $parent->data[key($parent->data)]);
+                                $parent->data[key($parent->data)] .= trim($line) . ' ';
+                                $this->_allNodes[$node->parent]->children = false;
+                                $this->_lastIndent = $node->indent;
+                            } elseif ($chk === '|') {
+                                $this->_inBlock = true;
+                                $this->_blockEnd = "\n";
+                                $parent->data[key($parent->data)] =
+                                    str_replace('|', '', $parent->data[key($parent->data)]);
+                                $parent->data[key($parent->data)] .= trim($line) . "\n";
+                                $this->_allNodes[$node->parent]->children = false;
+                                $this->_lastIndent = $node->indent;
+                            }
+                        }
+                    }
+                }
+            } elseif ($this->_lastIndent > $node->indent) {
+                // Any block we had going is dead now
+                if ($this->_inBlock) {
+                    $this->_inBlock = false;
+                    if ($this->_blockEnd == "\n") {
+                        $last =& $this->_allNodes[$this->_lastNode];
+                        $last->data[key($last->data)] =
+                            trim($last->data[key($last->data)]);
+                    }
+                }
+
+                // We don't know the parent of the node so we have to
+                // find it
+                foreach ($this->_indentSort[$node->indent] as $n) {
+                    if ($n->indent == $node->indent) {
+                        $node->parent = $n->parent;
+                    }
+                }
+            }
+
+            if (!$this->_inBlock) {
+                // Set these properties with information from our
+                // current node
+                $this->_lastIndent = $node->indent;
+
+                // Set the last node
+                $this->_lastNode = $node->id;
+
+                // Parse the YAML line and return its data
+                $node->data = $this->_parseLine($line);
+
+                // Add the node to the master list
+                $this->_allNodes[$node->id] = $node;
+
+                // Add a reference to the parent list
+                $this->_allParent[intval($node->parent)][] = $node->id;
+
+                // Add a reference to the node in an indent array
+                $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id];
+
+                // Add a reference to the node in a References array
+                // if this node has a YAML reference in it.
+                $is_array = is_array($node->data);
+                $key = key($node->data);
+                $isset = isset($node->data[$key]);
+                if ($isset) {
+                    $nodeval = $node->data[$key];
+                }
+                if (($is_array && $isset && !is_array($nodeval) && !is_object($nodeval))
+                    && (strlen($nodeval) && ($nodeval[0] == '&' || $nodeval[0] == '*') && $nodeval[1] != ' ')) {
+                    $this->_haveRefs[] =& $this->_allNodes[$node->id];
+                } elseif ($is_array && $isset && is_array($nodeval)) {
+                    // Incomplete reference making code. Needs to be
+                    // cleaned up.
+                    foreach ($node->data[$key] as $d) {
+                        if (!is_array($d) && strlen($d) && (($d[0] == '&' || $d[0] == '*') && $d[1] != ' ')) {
+                            $this->_haveRefs[] =& $this->_allNodes[$node->id];
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds and returns the indentation of a YAML line
+     *
+     * @param  string  $line  A line from the YAML file
+     * @return int            Indentation level
+     */
+    protected function _getIndent($line)
+    {
+        if (preg_match('/^\s+/', $line, $match)) {
+            return strlen($match[0]);
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Parses YAML code and returns an array for a node
+     *
+     * @param  string  $line  A line from the YAML file
+     * @return array
+     */
+    protected function _parseLine($line)
+    {
+        $array = array();
+
+        $line = trim($line);
+        if (preg_match('/^-(.*):$/', $line)) {
+            // It's a mapped sequence
+            $key = trim(substr(substr($line, 1), 0, -1));
+            $array[$key] = '';
+        } elseif ($line[0] == '-' && substr($line, 0, 3) != '---') {
+            // It's a list item but not a new stream
+            if (strlen($line) > 1) {
+                // Set the type of the value. Int, string, etc
+                $array[] = $this->_toType(trim(substr($line, 1)));
+            } else {
+                $array[] = array();
+            }
+        } elseif (preg_match('/^(.+):/', $line, $key)) {
+            // It's a key/value pair most likely
+            // If the key is in double quotes pull it out
+            if (preg_match('/^(["\'](.*)["\'](\s)*:)/', $line, $matches)) {
+                $value = trim(str_replace($matches[1], '', $line));
+                $key = $matches[2];
+            } else {
+                // Do some guesswork as to the key and the value
+                $explode = explode(':', $line);
+                $key = trim(array_shift($explode));
+                $value = trim(implode(':', $explode));
+            }
+
+            // Set the type of the value. Int, string, etc
+            $value = $this->_toType($value);
+            if (empty($key)) {
+                $array[] = $value;
+            } else {
+                $array[$key] = $value;
+            }
+        }
+
+        return $array;
+    }
+
+    /**
+     * Finds the type of the passed value, returns the value as the new type.
+     *
+     * @param  string   $value
+     * @return mixed
+     */
+    protected function _toType($value)
+    {
+        // Check for PHP specials
+        self::_unserialize($value);
+        if (!is_scalar($value)) {
+            return $value;
+        }
+
+        // Used in a lot of cases.
+        $lower_value = strtolower($value);
+
+        if (preg_match('/^("(.*)"|\'(.*)\')/', $value, $matches)) {
+            $value = (string)str_replace(array('\'\'', '\\\''), "'", end($matches));
+            $value = str_replace('\\"', '"', $value);
+        } elseif (preg_match('/^\\[(\s*)\\]$/', $value)) {
+            // empty inline mapping
+            $value = array();
+        } elseif (preg_match('/^\\[(.+)\\]$/', $value, $matches)) {
+            // Inline Sequence
+
+            // Take out strings sequences and mappings
+            $explode = $this->_inlineEscape($matches[1]);
+
+            // Propogate value array
+            $value  = array();
+            foreach ($explode as $v) {
+                $value[] = $this->_toType($v);
+            }
+        } elseif (preg_match('/^\\{(\s*)\\}$/', $value)) {
+            // empty inline mapping
+            $value = array();
+        } elseif (strpos($value, ': ') !== false && !preg_match('/^{(.+)/', $value)) {
+            // inline mapping
+            $array = explode(': ', $value);
+            $key = trim($array[0]);
+            array_shift($array);
+            $value = trim(implode(': ', $array));
+            $value = $this->_toType($value);
+            $value = array($key => $value);
+        } elseif (preg_match("/{(.+)}$/", $value, $matches)) {
+            // Inline Mapping
+
+            // Take out strings sequences and mappings
+            $explode = $this->_inlineEscape($matches[1]);
+
+            // Propogate value array
+            $array = array();
+            foreach ($explode as $v) {
+                $array = $array + $this->_toType($v);
+            }
+            $value = $array;
+        } elseif ($lower_value == 'null' || $value == '' || $value == '~') {
+            $value = null;
+        } elseif ($lower_value == '.nan') {
+            $value = NAN;
+        } elseif ($lower_value == '.inf') {
+            $value = INF;
+        } elseif ($lower_value == '-.inf') {
+            $value = -INF;
+        } elseif (ctype_digit($value)) {
+            $value = (int)$value;
+        } elseif (in_array($lower_value,
+                           array('true', 'on', '+', 'yes', 'y'))) {
+            $value = true;
+        } elseif (in_array($lower_value,
+                           array('false', 'off', '-', 'no', 'n'))) {
+            $value = false;
+        } elseif (is_numeric($value)) {
+            $value = (float)$value;
+        } else {
+            // Just a normal string, right?
+            if (($pos = strpos($value, '#')) !== false) {
+                $value = substr($value, 0, $pos);
+            }
+            $value = trim($value);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Handle PHP serialized data.
+     *
+     * @param string &$data Data to check for serialized PHP types.
+     */
+    protected function _unserialize(&$data)
+    {
+        if (substr($data, 0, 5) != '!php/') {
+            return;
+        }
+
+        $first_space = strpos($data, ' ');
+        $type = substr($data, 5, $first_space - 5);
+        $class = null;
+        if (strpos($type, '::') !== false) {
+            list($type, $class) = explode('::', $type);
+
+            if (!in_array($class, Horde_Yaml::$allowedClasses)) {
+                throw new Horde_Yaml_Exception("$class is not in the list of allowed classes");
+            }
+        }
+
+        switch ($type) {
+        case 'object':
+            if (!class_exists($class)) {
+                throw new Horde_Yaml_Exception("$class is not defined");
+            }
+
+            $reflector = new ReflectionClass($class);
+            if (!$reflector->implementsInterface('Serializable')) {
+                throw new Horde_Yaml_Exception("$class does not implement Serializable");
+            }
+
+            $class_data = substr($data, $first_space + 1);
+            $serialized = 'C:' . strlen($class) . ':"' . $class . '":' . strlen($class_data) . ':{' . $class_data . '}';
+            $data = unserialize($serialized);
+            break;
+
+        case 'array':
+        case 'hash':
+            $array_data = substr($data, $first_space + 1);
+            $array_data = Horde_Yaml::load('a: ' . $array_data);
+
+            if (is_null($class)) {
+                $data = $array_data['a'];
+            } else {
+                if (!class_exists($class)) {
+                    throw new Horde_Yaml_Exception("$class is not defined");
+                }
+
+                $array = new $class;
+                if (!$array instanceof ArrayAccess) {
+                    throw new Horde_Yaml_Exception("$class does not implement ArrayAccess");
+                }
+
+                foreach ($array_data['a'] as $key => $val) {
+                    $array[$key] = $val;
+                }
+
+                $data = $array;
+            }
+            break;
+        }
+    }
+
+    /**
+     * Used in inlines to check for more inlines or quoted strings
+     *
+     * @todo  There should be a cleaner way to do this.  While
+     *        pure sequences seem to be nesting just fine,
+     *        pure mappings and mappings with sequences inside
+     *        can't go very deep.  This needs to be fixed.
+     *
+     * @param  string  $inline  Inline data
+     * @return array
+     */
+    protected function _inlineEscape($inline)
+    {
+        $saved_strings = array();
+
+        // Check for strings
+        $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
+        if (preg_match_all($regex, $inline, $strings)) {
+            $saved_strings = $strings[0];
+            $inline = preg_replace($regex, 'YAMLString', $inline);
+        }
+
+        // Check for sequences
+        if (preg_match_all('/\[(.+)\]/U', $inline, $seqs)) {
+            $inline = preg_replace('/\[(.+)\]/U', 'YAMLSeq', $inline);
+            $seqs = $seqs[0];
+        }
+
+        // Check for mappings
+        if (preg_match_all('/{(.+)}/U', $inline, $maps)) {
+            $inline = preg_replace('/{(.+)}/U', 'YAMLMap', $inline);
+            $maps = $maps[0];
+        }
+
+        $explode = explode(', ', $inline);
+
+        // Re-add the sequences
+        if (!empty($seqs)) {
+            $i = 0;
+            foreach ($explode as $key => $value) {
+                if (strpos($value, 'YAMLSeq') !== false) {
+                    $explode[$key] = str_replace('YAMLSeq', $seqs[$i], $value);
+                    ++$i;
+                }
+            }
+        }
+
+        // Re-add the mappings
+        if (!empty($maps)) {
+            $i = 0;
+            foreach ($explode as $key => $value) {
+                if (strpos($value, 'YAMLMap') !== false) {
+                    $explode[$key] = str_replace('YAMLMap', $maps[$i], $value);
+                    ++$i;
+                }
+            }
+        }
+
+        // Re-add the strings
+        if (!empty($saved_strings)) {
+            $i = 0;
+            foreach ($explode as $key => $value) {
+                while (strpos($value, 'YAMLString') !== false) {
+                    $explode[$key] = preg_replace('/YAMLString/', $saved_strings[$i], $value, 1);
+                    ++$i;
+                    $value = $explode[$key];
+                }
+            }
+        }
+
+        return $explode;
+    }
+
+    /**
+     * Builds the PHP array from all the YAML nodes we've gathered
+     *
+     * @return array
+     */
+    protected function _buildArray()
+    {
+        $trunk = array();
+        if (!isset($this->_indentSort[0])) {
+            return $trunk;
+        }
+
+        foreach ($this->_indentSort[0] as $n) {
+            if (empty($n->parent)) {
+                $this->_nodeArrayizeData($n);
+
+                // Check for references and copy the needed data to complete them.
+                $this->_makeReferences($n);
+
+                // Merge our data with the big array we're building
+                $trunk = $this->_array_kmerge($trunk, $n->data);
+            }
+        }
+
+        return $trunk;
+    }
+
+    /**
+     * Traverses node-space and sets references (& and *) accordingly
+     *
+     * @return bool
+     */
+    protected function _linkReferences()
+    {
+        if (is_array($this->_haveRefs)) {
+            foreach ($this->_haveRefs as $node) {
+                if (!empty($node->data)) {
+                    $key = key($node->data);
+                    // If it's an array, don't check.
+                    if (is_array($node->data[$key])) {
+                        foreach ($node->data[$key] as $k => $v) {
+                            $this->_linkRef($node, $key, $k, $v);
+                        }
+                    } else {
+                        $this->_linkRef($node, $key);
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Helper for _linkReferences()
+     *
+     * @param  Horde_Yaml_Node  $n   Node
+     * @param  string           $k   Key
+     * @param  mixed            $v   Value
+     * @return void
+     */
+    function _linkRef(&$n, $key, $k = null, $v = null)
+    {
+        if (empty($k) && empty($v)) {
+            // Look for &refs
+            if (preg_match('/^&([^ ]+)/', $n->data[$key], $matches)) {
+                // Flag the node so we know it's a reference
+                $this->_allNodes[$n->id]->ref = substr($matches[0], 1);
+                $this->_allNodes[$n->id]->data[$key] =
+                    substr($n->data[$key], strlen($matches[0]) + 1);
+                // Look for *refs
+            } elseif (preg_match('/^\*([^ ]+)/', $n->data[$key], $matches)) {
+                $ref = substr($matches[0], 1);
+                // Flag the node as having a reference
+                $this->_allNodes[$n->id]->refKey = $ref;
+            }
+        } elseif (!empty($k) && !empty($v)) {
+            if (preg_match('/^&([^ ]+)/', $v, $matches)) {
+                // Flag the node so we know it's a reference
+                $this->_allNodes[$n->id]->ref = substr($matches[0], 1);
+                $this->_allNodes[$n->id]->data[$key][$k] =
+                    substr($v, strlen($matches[0]) + 1);
+                // Look for *refs
+            } elseif (preg_match('/^\*([^ ]+)/', $v, $matches)) {
+                $ref = substr($matches[0], 1);
+                // Flag the node as having a reference
+                $this->_allNodes[$n->id]->refKey = $ref;
+            }
+        }
+    }
+
+    /**
+     * Finds the children of a node and aids in the building of the PHP array
+     *
+     * @param  int    $nid   The id of the node whose children we're gathering
+     * @return array
+     */
+    protected function _gatherChildren($nid)
+    {
+        $return = array();
+        $node =& $this->_allNodes[$nid];
+        if (is_array ($this->_allParent[$node->id])) {
+            foreach ($this->_allParent[$node->id] as $nodeZ) {
+                $z =& $this->_allNodes[$nodeZ];
+                // We found a child
+                $this->_nodeArrayizeData($z);
+
+                // Check for references
+                $this->_makeReferences($z);
+
+                // Merge with the big array we're returning, the big
+                // array being all the data of the children of our
+                // parent node
+                $return = $this->_array_kmerge($return, $z->data);
+            }
+        }
+        return $return;
+    }
+
+    /**
+     * Turns a node's data and its children's data into a PHP array
+     *
+     * @param  array    $node  The node which you want to arrayize
+     * @return boolean
+     */
+    protected function _nodeArrayizeData(&$node)
+    {
+        if ($node->children == true) {
+            if (is_array($node->data)) {
+                // This node has children, so we need to find them
+                $children = $this->_gatherChildren($node->id);
+
+                // We've gathered all our children's data and are ready to use it
+                $key = key($node->data);
+                $key = empty($key) ? 0 : $key;
+                // If it's an array, add to it of course
+                if (isset($node->data[$key])) {
+                    if (is_array($node->data[$key])) {
+                        $node->data[$key] = $this->_array_kmerge($node->data[$key], $children);
+                    } else {
+                        $node->data[$key] = $children;
+                    }
+                } else {
+                    $node->data[$key] = $children;
+                }
+            } else {
+                // Same as above, find the children of this node
+                $children = $this->_gatherChildren($node->id);
+                $node->data = array();
+                $node->data[] = $children;
+            }
+        } else {
+            // The node is a single string. See if we need to unserialize it.
+            if (is_array($node->data)) {
+                $key = key($node->data);
+                $key = empty($key) ? 0 : $key;
+
+                if (!isset($node->data[$key]) || is_array($node->data[$key]) || is_object($node->data[$key])) {
+                    return true;
+                }
+
+                self::_unserialize($node->data[$key]);
+            } elseif (is_string($node->data)) {
+                self::_unserialize($node->data);
+            }
+        }
+
+        // We edited $node by reference, so just return true
+        return true;
+    }
+
+    /**
+     * Traverses node-space and copies references to / from this object.
+     *
+     * @param  Horde_Yaml_Node  $z  A node whose references we wish to make real
+     * @return bool
+     */
+    protected function _makeReferences(&$z)
+    {
+        // It is a reference
+        if (isset($z->ref)) {
+            $key = key($z->data);
+            // Copy the data to this object for easy retrieval later
+            $this->ref[$z->ref] =& $z->data[$key];
+            // It has a reference
+        } elseif (isset($z->refKey)) {
+            if (isset($this->ref[$z->refKey])) {
+                $key = key($z->data);
+                // Copy the data from this object to make the node a real reference
+                $z->data[$key] =& $this->ref[$z->refKey];
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Merges two arrays, maintaining numeric keys. If two numeric
+     * keys clash, the second one will be appended to the resulting
+     * array. If string keys clash, the last one wins.
+     *
+     * @param  array  $arr1
+     * @param  array  $arr2
+     * @return array
+     */
+    protected function _array_kmerge($arr1, $arr2)
+    {
+        while (list($key, $val) = each($arr2)) {
+            if (isset($arr1[$key]) && is_int($key)) {
+                $arr1[] = $val;
+            } else {
+                $arr1[$key] = $val;
+            }
+        }
+
+        return $arr1;
+    }
+
+}
diff --git a/vendor/Horde/Yaml/Node.php b/vendor/Horde/Yaml/Node.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc66839307b535781bdb659e2a57584f4b67c444
--- /dev/null
+++ b/vendor/Horde/Yaml/Node.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Horde YAML package
+ *
+ * This package is heavily inspired by the Spyc PHP YAML
+ * implementation (http://spyc.sourceforge.net/), and portions are
+ * copyright 2005-2006 Chris Wanstrath.
+ *
+ * @author   Chris Wanstrath <chris@ozmm.org>
+ * @author   Chuck Hagenbuch <chuck@horde.org>
+ * @author   Mike Naberezny <mike@maintainable.com>
+ * @license  http://opensource.org/licenses/bsd-license.php BSD
+ * @category Horde
+ * @package  Yaml
+ */
+
+/**
+ * A node, used for parsing YAML.
+ *
+ * @category Horde
+ * @package  Yaml
+ */
+class Horde_Yaml_Node
+{
+    /**
+     * @var string
+     */
+    public $parent;
+
+    /**
+     */
+    public $id;
+
+    /**
+     * @var mixed
+     */
+    public $data;
+
+    /**
+     * @var integer
+     */
+    public $indent;
+
+    /**
+     * @var bool
+     */
+    public $children = false;
+
+    /**
+     * The constructor assigns the node a unique ID.
+     * @return void
+     */
+    public function __construct($nodeId)
+    {
+        $this->id = $nodeId;
+    }
+
+}
diff --git a/vendor/PEAR/Exception.php b/vendor/PEAR/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..112bdd0f5ac69d191f776f47de23e5e0caaae5ff
--- /dev/null
+++ b/vendor/PEAR/Exception.php
@@ -0,0 +1,389 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+/**
+ * PEAR_Exception
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Hans Lellelid <hans@velum.net>
+ * @author     Bertrand Mansion <bmansion@mamasam.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Exception.php 299813 2010-05-26 19:50:00Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.3.3
+ */
+
+
+/**
+ * Base PEAR_Exception Class
+ *
+ * 1) Features:
+ *
+ * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
+ * - Definable triggers, shot when exceptions occur
+ * - Pretty and informative error messages
+ * - Added more context info available (like class, method or cause)
+ * - cause can be a PEAR_Exception or an array of mixed
+ *   PEAR_Exceptions/PEAR_ErrorStack warnings
+ * - callbacks for specific exception classes and their children
+ *
+ * 2) Ideas:
+ *
+ * - Maybe a way to define a 'template' for the output
+ *
+ * 3) Inherited properties from PHP Exception Class:
+ *
+ * protected $message
+ * protected $code
+ * protected $line
+ * protected $file
+ * private   $trace
+ *
+ * 4) Inherited methods from PHP Exception Class:
+ *
+ * __clone
+ * __construct
+ * getMessage
+ * getCode
+ * getFile
+ * getLine
+ * getTraceSafe
+ * getTraceSafeAsString
+ * __toString
+ *
+ * 5) Usage example
+ *
+ * <code>
+ *  require_once 'PEAR/Exception.php';
+ *
+ *  class Test {
+ *     function foo() {
+ *         throw new PEAR_Exception('Error Message', ERROR_CODE);
+ *     }
+ *  }
+ *
+ *  function myLogger($pear_exception) {
+ *     echo $pear_exception->getMessage();
+ *  }
+ *  // each time a exception is thrown the 'myLogger' will be called
+ *  // (its use is completely optional)
+ *  PEAR_Exception::addObserver('myLogger');
+ *  $test = new Test;
+ *  try {
+ *     $test->foo();
+ *  } catch (PEAR_Exception $e) {
+ *     print $e;
+ *  }
+ * </code>
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Hans Lellelid <hans@velum.net>
+ * @author     Bertrand Mansion <bmansion@mamasam.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.3
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.3.3
+ *
+ */
+class PEAR_Exception extends Exception
+{
+    const OBSERVER_PRINT = -2;
+    const OBSERVER_TRIGGER = -4;
+    const OBSERVER_DIE = -8;
+    protected $cause;
+    private static $_observers = array();
+    private static $_uniqueid = 0;
+    private $_trace;
+
+    /**
+     * Supported signatures:
+     *  - PEAR_Exception(string $message);
+     *  - PEAR_Exception(string $message, int $code);
+     *  - PEAR_Exception(string $message, Exception $cause);
+     *  - PEAR_Exception(string $message, Exception $cause, int $code);
+     *  - PEAR_Exception(string $message, PEAR_Error $cause);
+     *  - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
+     *  - PEAR_Exception(string $message, array $causes);
+     *  - PEAR_Exception(string $message, array $causes, int $code);
+     * @param string exception message
+     * @param int|Exception|PEAR_Error|array|null exception cause
+     * @param int|null exception code or null
+     */
+    public function __construct($message, $p2 = null, $p3 = null)
+    {
+        if (is_int($p2)) {
+            $code = $p2;
+            $this->cause = null;
+        } elseif (is_object($p2) || is_array($p2)) {
+            // using is_object allows both Exception and PEAR_Error
+            if (is_object($p2) && !($p2 instanceof Exception)) {
+                if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
+                    throw new PEAR_Exception('exception cause must be Exception, ' .
+                        'array, or PEAR_Error');
+                }
+            }
+            $code = $p3;
+            if (is_array($p2) && isset($p2['message'])) {
+                // fix potential problem of passing in a single warning
+                $p2 = array($p2);
+            }
+            $this->cause = $p2;
+        } else {
+            $code = null;
+            $this->cause = null;
+        }
+        parent::__construct($message, $code);
+        $this->signal();
+    }
+
+    /**
+     * @param mixed $callback  - A valid php callback, see php func is_callable()
+     *                         - A PEAR_Exception::OBSERVER_* constant
+     *                         - An array(const PEAR_Exception::OBSERVER_*,
+     *                           mixed $options)
+     * @param string $label    The name of the observer. Use this if you want
+     *                         to remove it later with removeObserver()
+     */
+    public static function addObserver($callback, $label = 'default')
+    {
+        self::$_observers[$label] = $callback;
+    }
+
+    public static function removeObserver($label = 'default')
+    {
+        unset(self::$_observers[$label]);
+    }
+
+    /**
+     * @return int unique identifier for an observer
+     */
+    public static function getUniqueId()
+    {
+        return self::$_uniqueid++;
+    }
+
+    private function signal()
+    {
+        foreach (self::$_observers as $func) {
+            if (is_callable($func)) {
+                call_user_func($func, $this);
+                continue;
+            }
+            settype($func, 'array');
+            switch ($func[0]) {
+                case self::OBSERVER_PRINT :
+                    $f = (isset($func[1])) ? $func[1] : '%s';
+                    printf($f, $this->getMessage());
+                    break;
+                case self::OBSERVER_TRIGGER :
+                    $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
+                    trigger_error($this->getMessage(), $f);
+                    break;
+                case self::OBSERVER_DIE :
+                    $f = (isset($func[1])) ? $func[1] : '%s';
+                    die(printf($f, $this->getMessage()));
+                    break;
+                default:
+                    trigger_error('invalid observer type', E_USER_WARNING);
+            }
+        }
+    }
+
+    /**
+     * Return specific error information that can be used for more detailed
+     * error messages or translation.
+     *
+     * This method may be overridden in child exception classes in order
+     * to add functionality not present in PEAR_Exception and is a placeholder
+     * to define API
+     *
+     * The returned array must be an associative array of parameter => value like so:
+     * <pre>
+     * array('name' => $name, 'context' => array(...))
+     * </pre>
+     * @return array
+     */
+    public function getErrorData()
+    {
+        return array();
+    }
+
+    /**
+     * Returns the exception that caused this exception to be thrown
+     * @access public
+     * @return Exception|array The context of the exception
+     */
+    public function getCause()
+    {
+        return $this->cause;
+    }
+
+    /**
+     * Function must be public to call on caused exceptions
+     * @param array
+     */
+    public function getCauseMessage(&$causes)
+    {
+        $trace = $this->getTraceSafe();
+        $cause = array('class'   => get_class($this),
+                       'message' => $this->message,
+                       'file' => 'unknown',
+                       'line' => 'unknown');
+        if (isset($trace[0])) {
+            if (isset($trace[0]['file'])) {
+                $cause['file'] = $trace[0]['file'];
+                $cause['line'] = $trace[0]['line'];
+            }
+        }
+        $causes[] = $cause;
+        if ($this->cause instanceof PEAR_Exception) {
+            $this->cause->getCauseMessage($causes);
+        } elseif ($this->cause instanceof Exception) {
+            $causes[] = array('class'   => get_class($this->cause),
+                              'message' => $this->cause->getMessage(),
+                              'file' => $this->cause->getFile(),
+                              'line' => $this->cause->getLine());
+        } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
+            $causes[] = array('class' => get_class($this->cause),
+                              'message' => $this->cause->getMessage(),
+                              'file' => 'unknown',
+                              'line' => 'unknown');
+        } elseif (is_array($this->cause)) {
+            foreach ($this->cause as $cause) {
+                if ($cause instanceof PEAR_Exception) {
+                    $cause->getCauseMessage($causes);
+                } elseif ($cause instanceof Exception) {
+                    $causes[] = array('class'   => get_class($cause),
+                                   'message' => $cause->getMessage(),
+                                   'file' => $cause->getFile(),
+                                   'line' => $cause->getLine());
+                } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
+                    $causes[] = array('class' => get_class($cause),
+                                      'message' => $cause->getMessage(),
+                                      'file' => 'unknown',
+                                      'line' => 'unknown');
+                } elseif (is_array($cause) && isset($cause['message'])) {
+                    // PEAR_ErrorStack warning
+                    $causes[] = array(
+                        'class' => $cause['package'],
+                        'message' => $cause['message'],
+                        'file' => isset($cause['context']['file']) ?
+                                            $cause['context']['file'] :
+                                            'unknown',
+                        'line' => isset($cause['context']['line']) ?
+                                            $cause['context']['line'] :
+                                            'unknown',
+                    );
+                }
+            }
+        }
+    }
+
+    public function getTraceSafe()
+    {
+        if (!isset($this->_trace)) {
+            $this->_trace = $this->getTrace();
+            if (empty($this->_trace)) {
+                $backtrace = debug_backtrace();
+                $this->_trace = array($backtrace[count($backtrace)-1]);
+            }
+        }
+        return $this->_trace;
+    }
+
+    public function getErrorClass()
+    {
+        $trace = $this->getTraceSafe();
+        return $trace[0]['class'];
+    }
+
+    public function getErrorMethod()
+    {
+        $trace = $this->getTraceSafe();
+        return $trace[0]['function'];
+    }
+
+    public function __toString()
+    {
+        if (isset($_SERVER['REQUEST_URI'])) {
+            return $this->toHtml();
+        }
+        return $this->toText();
+    }
+
+    public function toHtml()
+    {
+        $trace = $this->getTraceSafe();
+        $causes = array();
+        $this->getCauseMessage($causes);
+        $html =  '<table style="border: 1px" cellspacing="0">' . "\n";
+        foreach ($causes as $i => $cause) {
+            $html .= '<tr><td colspan="3" style="background: #ff9999">'
+               . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
+               . htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
+               . 'on line <b>' . $cause['line'] . '</b>'
+               . "</td></tr>\n";
+        }
+        $html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
+               . '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
+               . '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
+               . '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
+
+        foreach ($trace as $k => $v) {
+            $html .= '<tr><td style="text-align: center;">' . $k . '</td>'
+                   . '<td>';
+            if (!empty($v['class'])) {
+                $html .= $v['class'] . $v['type'];
+            }
+            $html .= $v['function'];
+            $args = array();
+            if (!empty($v['args'])) {
+                foreach ($v['args'] as $arg) {
+                    if (is_null($arg)) $args[] = 'null';
+                    elseif (is_array($arg)) $args[] = 'Array';
+                    elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
+                    elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
+                    elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
+                    else {
+                        $arg = (string)$arg;
+                        $str = htmlspecialchars(substr($arg, 0, 16));
+                        if (strlen($arg) > 16) $str .= '&hellip;';
+                        $args[] = "'" . $str . "'";
+                    }
+                }
+            }
+            $html .= '(' . implode(', ',$args) . ')'
+                   . '</td>'
+                   . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
+                   . ':' . (isset($v['line']) ? $v['line'] : 'unknown')
+                   . '</td></tr>' . "\n";
+        }
+        $html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
+               . '<td>{main}</td>'
+               . '<td>&nbsp;</td></tr>' . "\n"
+               . '</table>';
+        return $html;
+    }
+
+    public function toText()
+    {
+        $causes = array();
+        $this->getCauseMessage($causes);
+        $causeMsg = '';
+        foreach ($causes as $i => $cause) {
+            $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
+                   . $cause['message'] . ' in ' . $cause['file']
+                   . ' on line ' . $cause['line'] . "\n";
+        }
+        return $causeMsg . $this->getTraceAsString();
+    }
+}
\ No newline at end of file
diff --git a/vendor/SerialsSolutions/Summon/Base.php b/vendor/SerialsSolutions/Summon/Base.php
new file mode 100644
index 0000000000000000000000000000000000000000..af230d8b745649db8d00155f6f78ff3080e1dfcc
--- /dev/null
+++ b/vendor/SerialsSolutions/Summon/Base.php
@@ -0,0 +1,329 @@
+<?php
+/**
+ * Summon Search API Interface (abstract base class)
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Serials Solutions 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+require_once 'SerialsSolutions/Summon/Exception.php';
+
+/**
+ * Summon REST API Interface (abstract base class)
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+abstract class SerialsSolutions_Summon_Base
+{
+    /**
+     * A boolean value determining whether to print debug information
+     * @var bool
+     */
+    protected $debug = false;
+
+    /**
+     * The URL of the Summon API server
+     * @var string
+     */
+    protected $host = 'http://api.summon.serialssolutions.com';
+
+    /**
+     * The API version to use
+     *
+     * @var string
+     */
+    protected $version = '2.0.0';
+    
+    /**
+     * The secret Key used for authentication
+     * @var string
+     */
+    protected $apiKey;
+
+    /**
+     * The Client ID used for authentication
+     * @var string
+     */
+    protected $apiId;
+
+    /**
+     * The session for the current transaction
+     * @var string
+     */
+    protected $sessionId = false;
+
+    /**
+     * Is the end user authenticated or not?
+     * @var bool
+     */
+    protected $authedUser = false;
+
+    /**
+     * Constructor
+     *
+     * Sets up the Summon API Client
+     *
+     * @param string $apiId   Summon API ID
+     * @param string $apiKey  Summon API Key
+     * @param array  $options Associative array of additional options; legal keys:
+     *    <ul>
+     *      <li>authedUser - is the end-user authenticated?</li>
+     *      <li>debug - boolean to control debug mode</li>
+     *      <li>host - base URL of Summon API</li>
+     *      <li>sessionId - Summon session ID to apply</li>
+     *      <li>version - API version to use</li>
+     *    </ul>
+     */
+    public function __construct($apiId, $apiKey, $options = array())
+    {
+        // Process incoming parameters:
+        $this->apiId = $apiId;
+        $this->apiKey = $apiKey;
+        $legalOptions = array('authedUser', 'debug', 'host', 'sessionId', 'version');
+        foreach ($legalOptions as $option) {
+            if (isset($options[$option])) {
+                $this->$option = $options[$option];
+            }
+        }
+    }
+
+    /**
+     * Print a message if debug is enabled.
+     *
+     * @param string $msg Message to print
+     *
+     * @return void
+     */
+    protected function debugPrint($msg)
+    {
+        if ($this->debug) {
+            echo "<pre>{$msg}</pre>\n";
+        }
+    }
+
+    /**
+     * Retrieves a document specified by the ID.
+     *
+     * @param string $id The document to retrieve from the Summon API
+     *
+     * @return string    The requested resource
+     */
+    public function getRecord($id)
+    {
+        $this->debugPrint("Get Record: $id");
+
+        // Query String Parameters
+        $options = array('s.q' => sprintf('ID:"%s"', $id));
+        return $this->call($options);
+    }
+
+    /**
+     * Execute a search.
+     *
+     * @param SerialsSolutions_Summon_Query $query     Query object
+     * @param bool                          $returnErr On fatal error, should we fail
+     * outright (false) or treat it as an empty result set with an error key set
+     * (true)?
+     *
+     * @return array             An array of query results
+     */
+    public function query($query, $returnErr = false)
+    {
+        // Query String Parameters
+        $options = $query->getOptionsArray();
+        $options['s.role'] = $this->authedUser ? 'authenticated' : 'none';
+
+        // Special case -- if user filtered down to newspapers AND excluded them,
+        // we can't possibly have any results:
+        if (isset($options['s.fvf']) && is_array($options['s.fvf'])
+            && in_array('ContentType,Newspaper Article,true', $options['s.fvf'])
+            && in_array('ContentType,Newspaper Article', $options['s.fvf'])
+        ) {
+            return array(
+                'recordCount' => 0,
+                'documents' => array()
+            );
+        }
+
+        $this->debugPrint('Query: ' . print_r($options, true));
+
+        try {
+            $result = $this->call($options);
+        } catch (SerialsSolutions_Summon_Exception $e) {
+            if ($returnErr) {
+                return array(
+                    'recordCount' => 0,
+                    'documents' => array(),
+                    'errors' => $e->getMessage()
+                );
+            } else {
+                $this->handleFatalError($e);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Submit REST Request
+     *
+     * @param array  $params  An array of parameters for the request
+     * @param string $service The API Service to call
+     * @param string $method  The HTTP Method to use
+     * @param bool   $raw     Whether to return raw XML or processed
+     *
+     * @throws SerialsSolutions_Summon_Exception
+     * @return object         The Summon API response (or a PEAR_Error object).
+     */
+    protected function call($params = array(), $service = 'search', $method = 'GET',
+        $raw = false
+    ) {
+        $baseUrl = $this->host . '/' . $this->version . '/' . $service;
+
+        // Build Query String
+        $query = array();
+        foreach ($params as $function => $value) {
+            if (is_array($value)) {
+                foreach ($value as $additional) {
+                    $additional = urlencode($additional);
+                    $query[] = "$function=$additional";
+                }
+            } else {
+                $value = urlencode($value);
+                $query[] = "$function=$value";
+            }
+        }
+        asort($query);
+        $queryString = implode('&', $query);
+
+        // Build Authorization Headers
+        $headers = array(
+            'Accept' => 'application/json',
+            'x-summon-date' => date('D, d M Y H:i:s T'),
+            'Host' => 'api.summon.serialssolutions.com'
+        );
+        $data = implode($headers, "\n") . "\n/$this->version/$service\n" .
+            urldecode($queryString) . "\n";
+        $hmacHash = $this->hmacsha1($this->apiKey, $data);
+        $headers['Authorization'] = "Summon $this->apiId;$hmacHash";
+        if ($this->sessionId) {
+            $headers['x-summon-session-id'] = $this->sessionId;
+        }
+
+        // Send and process request
+        return $this->process(
+            $this->httpRequest($baseUrl, $method, $queryString, $headers)
+        );
+    }
+
+    /**
+     * Perform normalization and analysis of Summon return value.
+     *
+     * @param array $input The raw response from Summon
+     *
+     * @throws SerialsSolutions_Summon_Exception
+     * @return array       The processed response from Summon
+     */
+    protected function process($input)
+    {
+        // Unpack JSON Data
+        $result = json_decode($input, true);
+
+        // Catch decoding errors -- turn a bad JSON input into an empty result set
+        // containing an appropriate error code.
+        if (!$result) {
+            $result = array(
+                'recordCount' => 0,
+                'documents' => array(),
+                'errors' => array(
+                    array(
+                        'code' => 'PHP-Internal',
+                        'message' => 'Cannot decode JSON response: ' . $input
+                    )
+                )
+            );
+        }
+
+        // Detect errors
+        if (isset($result['errors']) && is_array($result['errors'])) {
+            foreach ($result['errors'] as $current) {
+                $errors[] = "{$current['code']}: {$current['message']}";
+            }
+            $msg = 'Unable to process query<br />Summon returned: ' .
+                implode('<br />', $errors);
+            throw new SerialsSolutions_Summon_Exception($msg);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Generate an HMAC hash
+     *
+     * @param string $key  Hash key
+     * @param string $data Data to hash
+     *
+     * @return string      Generated hash
+     */
+    protected function hmacsha1($key, $data)
+    {
+        $blocksize=64;
+        $hashfunc='sha1';
+        if (strlen($key)>$blocksize) {
+            $key=pack('H*', $hashfunc($key));
+        }
+        $key=str_pad($key, $blocksize, chr(0x00));
+        $ipad=str_repeat(chr(0x36), $blocksize);
+        $opad=str_repeat(chr(0x5c), $blocksize);
+        $hmac = pack(
+            'H*', $hashfunc(
+                ($key^$opad).pack(
+                    'H*', $hashfunc(
+                        ($key^$ipad).$data
+                    )
+                )
+            )
+        );
+        return base64_encode($hmac);
+    }
+
+    /**
+     * Perform an HTTP request.
+     *
+     * @param string $baseUrl     Base URL for request
+     * @param string $method      HTTP method for request
+     * @param string $queryString Query string to append to URL
+     * @param array  $headers     HTTP headers to send
+     *
+     * @throws SerialsSolutions_Summon_Exception
+     * @return string             HTTP response body
+     */
+    abstract protected function httpRequest($baseUrl, $method, $queryString,
+        $headers
+    );
+}
diff --git a/vendor/SerialsSolutions/Summon/Exception.php b/vendor/SerialsSolutions/Summon/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a6224054c5a3fc751e207e2aee98dae67b6107f
--- /dev/null
+++ b/vendor/SerialsSolutions/Summon/Exception.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Summon Search API Interface Exception
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Serials Solutions 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+
+/**
+ * Summon Search API Interface Exception
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+class SerialsSolutions_Summon_Exception extends Exception
+{
+}
diff --git a/vendor/SerialsSolutions/Summon/PEAR.php b/vendor/SerialsSolutions/Summon/PEAR.php
new file mode 100644
index 0000000000000000000000000000000000000000..21832a8ac09513021e5c821df382fc856d66b662
--- /dev/null
+++ b/vendor/SerialsSolutions/Summon/PEAR.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Summon Search API Interface (PEAR implementation)
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Serials Solutions 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+require_once 'PEAR.php';
+require_once 'HTTP/Request.php';
+require_once 'SerialsSolutions/Summon/Base.php';
+
+/**
+ * Summon Search API Interface (PEAR implementation)
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+class SerialsSolutions_Summon_PEAR extends SerialsSolutions_Summon_Base
+{
+    /**
+     * The HTTP_Request object used for API transactions
+     * @var object HTTP_Request
+     */
+    protected $client;
+
+    /**
+     * Constructor
+     *
+     * Sets up the Summon API Client
+     *
+     * @param string $apiId   Summon API ID
+     * @param string $apiKey  Summon API Key
+     * @param array  $options Associative array of additional options; legal keys:
+     *    <ul>
+     *      <li>authedUser - is the end-user authenticated?</li>
+     *      <li>debug - boolean to control debug mode</li>
+     *      <li>host - base URL of Summon API</li>
+     *      <li>sessionId - Summon session ID to apply</li>
+     *      <li>version - API version to use</li>
+     *    </ul>
+     */
+    public function __construct($apiId, $apiKey, $options = array())
+    {
+        parent::__construct($apiId, $apiKey, $options);
+        $this->client = new HTTP_Request(null, array('useBrackets' => false));
+    }
+
+    /**
+     * Handle a fatal error.
+     *
+     * @param SerialsSolutions_Summon_Exception $e Exception to process.
+     *
+     * @return void
+     */
+    public function handleFatalError($e)
+    {
+        PEAR::raiseError(new PEAR_Error($e->getMessage()));
+    }
+
+    /**
+     * Perform an HTTP request.
+     *
+     * @param string $baseUrl     Base URL for request
+     * @param string $method      HTTP method for request
+     * @param string $queryString Query string to append to URL
+     * @param array  $headers     HTTP headers to send
+     *
+     * @throws SerialsSolutions_Summon_Exception
+     * @return string             HTTP response body
+     */
+    protected function httpRequest($baseUrl, $method, $queryString, $headers)
+    {
+        $this->debugPrint(
+            "{$method}: {$baseUrl}?{$queryString}"
+        );
+
+        // Set up request
+        $this->client->setURL($baseUrl);
+        $this->client->setMethod($method);
+        $this->client->addRawQueryString($queryString);
+        foreach ($headers as $key => $value) {
+            $this->client->addHeader($key, $value);
+        }
+
+        // Send Request
+        $result = $this->client->sendRequest();
+        if (PEAR::isError($result)) {
+            throw new SerialsSolutions_Summon_Exception($result->getMessage());
+        }
+        return $this->client->getResponseBody();
+    }
+}
diff --git a/vendor/SerialsSolutions/Summon/Query.php b/vendor/SerialsSolutions/Summon/Query.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b10a4914c4f3d622ce9d09c0f7a19407a20616d
--- /dev/null
+++ b/vendor/SerialsSolutions/Summon/Query.php
@@ -0,0 +1,251 @@
+<?php
+/**
+ * Summon Search API Interface (query model)
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Serials Solutions 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+
+/**
+ * Summon REST API Interface (query model)
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+class SerialsSolutions_Summon_Query
+{
+    /**
+     * The query terms
+     * @var string
+     */
+    protected $query;
+
+    /**
+     * Whether to limit to the library's holdings or not
+     * @var bool
+     */
+    protected $holdings = true;
+
+    /**
+     * An array of facets to be requested
+     * @var array
+     */
+    protected $facets = null;
+
+    /**
+     * An array of filters to be applied
+     * @var array
+     */
+    protected $filters = array();
+
+    /**
+     * An array of range filters to be applied
+     * @var array
+     */
+    protected $rangeFilters = array();
+
+    /**
+     * Sort option
+     * @var string
+     */
+    protected $sort = null;
+
+    /**
+     * Results per page
+     * @var int
+     */
+    protected $pageSize = 25;
+
+    /**
+     * Page number to retrieve
+     * @var int
+     */
+    protected $pageNumber = 1;
+
+    /**
+     * Whether to enable spell checking
+     * @var bool
+     */
+    protected $didYouMean = false;
+
+    /**
+     * Whether to enable highlighting
+     * @var bool
+     */
+    protected $highlight = false;
+
+    /**
+     * Highlight start string
+     * @var string
+     */
+    protected $highlightStart = '';
+
+    /**
+     * Highlight end string
+     * @var boolean
+     */
+    protected $highlightEnd = '';
+
+    /**
+     * Constructor
+     *
+     * Sets up the Summon API Client
+     *
+     * @param string $query   Search query
+     * @param array  $options Other options to set (associative array)
+     */
+    public function __construct($query = null, $options = array())
+    {
+        $this->query = $query;
+
+        foreach ($options as $key => $value) {
+            if (property_exists($this, $key)) {
+                $this->$key = $value;
+            }
+        }
+
+        // Define default facets to request if necessary:
+        if (is_null($this->facets)) {
+            $this->facets = array(
+                'IsScholarly,or,1,2',
+                'Library,or,1,30',
+                'ContentType,or,1,30',
+                'SubjectTerms,or,1,30',
+                'Language,or,1,30'
+            );
+        }
+    }
+
+    /**
+     * Turn the options within this object into an array of Summon parameters.
+     *
+     * @return array
+     */
+    public function getOptionsArray()
+    {
+        $options = array(
+            's.q' => $this->query,
+            's.ps' => $this->pageSize,
+            's.pn' => $this->pageNumber,
+            's.ho' => $this->holdings ? 'true' : 'false',
+            's.dym' => $this->didYouMean ? 'true' : 'false'
+        );
+        if (!empty($this->facets)) {
+            $options['s.ff'] = $this->facets;
+        }
+        if (!empty($this->filters)) {
+            $options['s.fvf'] = $this->filters;
+        }
+        if (!empty($this->rangeFilters)) {
+            $options['s.rf'] = $this->rangeFilters;
+        }
+        if (!empty($this->sort)) {
+            $options['s.sort'] = $this->sort;
+        }
+        if ($this->highlight) {
+            $options['s.hl'] = 'true';
+            $options['s.hs'] = $this->highlightStart;
+            $options['s.he'] = $this->highlightEnd;
+        } else {
+            $options['s.hl'] = 'false';
+            $options['s.hs'] = $options['s.he'] = '';
+        }
+        return $options;
+    }
+
+    /**
+     * Add a filter
+     *
+     * @param string $f Filter to apply
+     *
+     * @return void
+     */
+    public function addFilter($f)
+    {
+        $this->filters[] = $f;
+    }
+
+    /**
+     * Add a range filter
+     *
+     * @param string $f Filter to apply
+     *
+     * @return void
+     */
+    public function addRangeFilter($f)
+    {
+        $this->rangeFilters[] = $f;
+    }
+
+    /**
+     * Magic method for getting/setting properties.
+     *
+     * @param string $method Method being called
+     * @param string $params Array of parameters
+     *
+     * @return mixed
+     */
+    public function __call($method, $params)
+    {
+        if (strlen($method) > 4) {
+            $action = substr($method, 0, 3);
+            $property = strtolower(substr($method, 3, 1)) . substr($method, 4);
+            if ($action == 'get' && property_exists($this, $property)) {
+                return $this->$property;
+            }
+            if ($action == 'set' && property_exists($this, $property)) {
+                if (isset($params[0])) {
+                    $this->$property = $params[0];
+                    return;
+                }
+                throw new ErrorException(
+                    $method . ' missing required parameter', 0, E_ERROR
+                ); 
+            }
+        }
+        throw new ErrorException(
+            'Call to Undefined Method/Class Function', 0, E_ERROR
+        ); 
+    }
+
+    /**
+     * Escape a string for inclusion as part of a Summon parameter.
+     *
+     * @param string $input The string to escape.
+     *
+     * @return string       The escaped string.
+     */
+    public static function escapeParam($input)
+    {
+        // List of characters to escape taken from:
+        //      http://api.summon.serialssolutions.com/help/api/search/parameters
+        return addcslashes($input, ",:\\()\${}");
+    }
+}
+
+?>
diff --git a/vendor/SerialsSolutions/Summon/Zend.php b/vendor/SerialsSolutions/Summon/Zend.php
new file mode 100644
index 0000000000000000000000000000000000000000..10cc5db9a940911243dd1a34ce635c5f9f3ecafd
--- /dev/null
+++ b/vendor/SerialsSolutions/Summon/Zend.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Summon Search API Interface (Zend implementation)
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Serials Solutions 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+require_once 'Zend/Http/Client.php';
+require_once 'SerialsSolutions/Summon/Base.php';
+
+/**
+ * Summon Search API Interface (Zend implementation)
+ *
+ * @category SerialsSolutions
+ * @package  Summon
+ * @author   Andrew Nagy <andrew.nagy@serialssolutions.com>
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://api.summon.serialssolutions.com/help/api/ API Documentation
+ */
+class SerialsSolutions_Summon_Zend extends SerialsSolutions_Summon_Base
+{
+    /**
+     * The HTTP_Request object used for API transactions
+     * @var object HTTP_Request
+     */
+    protected $client;
+
+    /**
+     * Constructor
+     *
+     * Sets up the Summon API Client
+     *
+     * @param string           $apiId   Summon API ID
+     * @param string           $apiKey  Summon API Key
+     * @param array            $options Associative array of additional options;
+     * legal keys:
+     *    <ul>
+     *      <li>authedUser - is the end-user authenticated?</li>
+     *      <li>debug - boolean to control debug mode</li>
+     *      <li>host - base URL of Summon API</li>
+     *      <li>sessionId - Summon session ID to apply</li>
+     *      <li>version - API version to use</li>
+     *    </ul>
+     * @param Zend_Http_Client $client  HTTP client object (optional)
+     */
+    public function __construct($apiId, $apiKey, $options = array(), $client = null)
+    {
+        parent::__construct($apiId, $apiKey, $options);
+        $this->client = is_object($client) ? $client : new Zend_Http_Client();
+    }
+
+    /**
+     * Handle a fatal error.
+     *
+     * @param SerialsSolutions_Summon_Exception $e Exception to process.
+     *
+     * @return void
+     */
+    public function handleFatalError($e)
+    {
+        throw $e;
+    }
+
+    /**
+     * Perform an HTTP request.
+     *
+     * @param string $baseUrl     Base URL for request
+     * @param string $method      HTTP method for request
+     * @param string $queryString Query string to append to URL
+     * @param array  $headers     HTTP headers to send
+     *
+     * @throws SerialsSolutions_Summon_Exception
+     * @return string             HTTP response body
+     */
+    protected function httpRequest($baseUrl, $method, $queryString, $headers)
+    {
+        $this->debugPrint(
+            "{$method}: {$baseUrl}?{$queryString}"
+        );
+
+        $this->client->resetParameters();
+        if ($method == 'GET') {
+            $baseUrl .= '?' . $queryString;
+        } elseif ($method == 'POST') {
+            $this->client->setRawData(
+                $queryString, 'application/x-www-form-urlencoded'
+            );
+        }
+
+        foreach ($headers as $key => $value) {
+            $this->client->setHeaders($key, $value);
+        }
+
+        // Send Request
+        $this->client->setUri($baseUrl);
+        $result = $this->client->request($method);
+        if ($result->isError()) {
+            throw new SerialsSolutions_Summon_Exception($result->getBody());
+        }
+        return $result->getBody();
+    }
+}
diff --git a/vendor/Structures/LinkedList/Double.php b/vendor/Structures/LinkedList/Double.php
new file mode 100644
index 0000000000000000000000000000000000000000..75e696c0e1b5cd255857a756b03157502f2aa544
--- /dev/null
+++ b/vendor/Structures/LinkedList/Double.php
@@ -0,0 +1,375 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker textwidth=80: */
+
+/**
+ * Linked list structure
+ * 
+ * This package implements a doubly linked list structure. Each node
+ * (Structures_LinkedList_DoubleNode object) in the list
+ * (Structures_LinkedList_Double) knows the previous node and the next
+ * node in the list. Unlike an array, you can insert or delete nodes at
+ * arbitrary points in the list.
+ *
+ * If your application normally traverses the linked list in a forward-only
+ * direction, use the singly-linked list implemented by
+ * {@link Structures_LinkedList_Single}. If, however, your application
+ * needs to traverse the list backwards, or insert nodes into the list before
+ * other nodes in the list, use the double-linked list implemented by
+ * {@link Structures_LinkedList_Double} to give your application better
+ * performance at the cost of a slightly larger memory footprint.
+ *
+ * Structures_LinkedList_Double implements the Iterator interface so control
+ * structures like foreach($list as $node) and while($list->next()) work
+ * as expected.
+ *
+ * To use this package, derive a child class from
+ * Structures_LinkedList_DoubleNode  and add data to the object. Then use the
+ * Structures_LinkedList_Double class to access the nodes.
+ *
+ * PHP version 5
+ *
+ * LICENSE:  Copyright 2006 Dan Scott
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @category  Structures
+ * @package   Structures_LinkedList_Double
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2006 Dan Scott
+ * @license   http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
+ * @version   CVS: $Id: Double.php -1   $
+ * @link      http://pear.php.net/package/Structures_LinkedList
+ * @example   double_link_example.php
+ *
+ * @todo Add some actual error conditions
+ **/
+
+require_once 'PEAR/Exception.php';
+require_once 'Single.php';
+
+// {{{ class Structures_LinkedList_Double
+/**
+ * The Structures_LinkedList_Double class represents a linked list structure
+ * composed of {@link Structures_LinkedList_DoubleNode} objects.
+ *
+ * @category Structures
+ * @package  Structures_LinkedList_Double
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
+ * @link     http://pear.php.net/package/Structures_LinkedList
+ */
+class Structures_LinkedList_Double extends Structures_LinkedList_Single implements Iterator
+{
+    // {{{ properties
+    /**
+     * Tail node of the linked list
+     * @var Structures_LinkedList_DoubleNode
+     */
+    protected $tail_node;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Structures_LinkedList_Double constructor
+     *
+     * @param Structures_LinkedList_DoubleNode $root root node for the
+     * linked list
+     */
+    function __construct(Structures_LinkedList_DoubleNode $root = null)
+    {
+        if ($root) {
+            $this->tail_node = $root;
+        } else {
+            $this->tail_node = null;
+        }
+        parent::__construct($root);
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Structures_LinkedList_Double destructor
+     *
+     * If we do not destroy all of the references in the linked list,
+     * we will quickly run out of memory for large / complex structures.
+     *
+     */
+    function __destruct()
+    {
+        /*
+         * Starting with root node, set last node = root_node
+         *   get next node
+         *   if next node exists:
+         *     delete last node's references to next node and previous node
+         *     make the old next node the new last node
+         */
+        if (!$last_node = $this->root_node) {
+            return;
+        }
+        while (($next_node = $last_node->next()) !== false) {
+            $last_node->setNext(null);
+            $last_node->setPrevious(null);
+            $last_node = $next_node;
+        }
+        $this->current = null;
+        $this->root_node = null;
+        $this->tail_node = null;
+        $last_node = null;
+        $next_node = null;
+    }
+    // }}}
+
+    // {{{ function end()
+    /**
+     * Sets the pointer for the linked list to its last node
+     *
+     * @return Structures_LinkedList_DoubleNode last node in the linked list
+     */
+    public function end()
+    {
+        if ($this->tail_node) {
+            $this->current = $this->tail_node;
+        } else {
+            $this->current = null;
+        }
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ function previous()
+    /**
+     * Sets the pointer for the linked list to the previous node and
+     * returns that node
+     *
+     * @return Structures_LinkedList_DoubleNode previous node in the linked list
+     */
+    public function previous()
+    {
+        if (!$this->current()->previous()) {
+            return false;
+        }
+        $this->current = $this->current()->previous();
+        return $this->current();
+    }
+    // }}}
+
+    // {{{ function insertNode()
+    /**
+     * Inserts a {@link Structures_LinkedList_DoubleNode} object into the linked
+     * list, based on a reference node that already exists in the list.
+     *
+     * @param Structures_LinkedList_DoubleNode $new_node      New node to add to the list
+     * @param Structures_LinkedList_DoubleNode $existing_node Reference position node
+     * @param bool                             $before        Insert new node before or after the existing node
+     *
+     * @return bool Success or failure
+     **/
+    public function insertNode($new_node, $existing_node, $before = false)
+    {
+        if (!$this->root_node) {
+            $this->__construct($new_node);
+        }
+
+        // Now add the node according to the requested mode
+        switch ($before) {
+
+        case true:
+            $previous_node = $existing_node->previous();
+            if ($previous_node) {
+                $previous_node->setNext($new_node);
+                $new_node->setPrevious($previous_node);
+            } else {
+                // The existing node must be root node; make new node root
+                $this->root_node = $new_node;
+                $new_node->setPrevious();
+            }
+            $new_node->setNext($existing_node);
+            $existing_node->setPrevious($new_node);
+
+            break;
+
+        case false:
+            $new_node->setPrevious($existing_node);
+            $next_node = $existing_node->next();
+            if ($next_node) {
+                $new_node->setNext($next_node);
+                $next_node->setPrevious($new_node);
+            } else {
+                // The existing node must have been the tail node
+                $this->tail_node = $new_node;
+            }
+            $existing_node->setNext($new_node);
+
+            break;
+
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ protected function getTailNode()
+    /**
+     * Returns the tail node of the linked list.
+     *
+     * This is a cheap operation for a doubly-linked list.
+     *
+     * @return bool Success or failure
+     **/
+    protected function getTailNode()
+    {
+        return $this->tail_node;
+    }
+    // }}}
+
+    // {{{ function deleteNode()
+    /**
+     * Deletes a {@link Structures_LinkedList_DoubleNode} from the list.
+     *
+     * @param Structures_LinkedList_DoubleNode $node Node to delete.
+     *
+     * @return null
+     */
+    public function deleteNode($node)
+    {
+        /* If this is the root node, and there are more nodes in the list,
+         * make the next node the new root node before deleting this node.
+         */
+        if ($node === $this->root_node) {
+            $this->root_node = $node->next();
+        }
+        
+        /* If this is the tail node, and there are more nodes in the list,
+         * make the previous node the tail node before deleting this node
+         */
+        if ($node === $this->tail_node) {
+            $this->tail_node = $node->previous();
+        }
+
+        /* If this is the current node, and there are other nodes in the list,
+         * try making the previous node the current node so that next() works
+         * as expected.
+         *
+         * If that fails, make the next node the current node.
+         *
+         * If that fails, null isn't such a bad place to be.
+         */
+        if ($node === $this->current) {
+            if ($node->previous()) {
+                $this->current = $node->previous();
+            } elseif ($node->next()) {
+                $this->current = $node->next();
+            } else {
+                $this->current = null;
+            }
+        }
+        $node->__destruct();
+    }
+    // }}}
+
+}
+// }}}
+
+// {{{ class Structures_LinkedList_DoubleNode
+/**
+ * The Structures_LinkedList_DoubleNode class represents a node in a
+ * {@link Structures_LinkedList_Double} linked list structure.
+ *
+ * @category Structures
+ * @package  Structures_LinkedList_Double
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
+ * @link     http://pear.php.net/package/Structures_LinkedList
+ */
+class Structures_LinkedList_DoubleNode extends Structures_LinkedList_SingleNode
+{
+    // {{{ properties
+    /**
+     * Previous node in the linked list
+     * @var Structures_LinkedList_DoubleNode
+     */
+    protected $previous;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Structures_LinkedList_DoubleNode constructor
+     */
+    public function __construct()
+    {
+        $this->next = null;
+        $this->previous = null;
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Removes node from the list, adjusting the related nodes accordingly.
+     *
+     * This is a problem if the node is the root node for the list.
+     * At this point, however, we do not have access to the list itself. Hmm.
+     */
+    public function __destruct()
+    {
+        $next = $this->next();
+        $previous = $this->previous();
+        if ($previous && $next) {
+            $previous->setNext($next);
+            $next->setPrevious($previous);
+        } elseif ($previous) {
+            $previous->setNext();
+        } elseif ($next) {
+            $next->setPrevious();
+        }
+    }
+    // }}}
+
+    // {{{ function previous()
+    /**
+     * Return the previous node in the linked list
+     *
+     * @return Structures_LinkedList_DoubleNode previous node in the linked list
+     */
+    public function previous()
+    {
+        if ($this->previous) {
+            return $this->previous;
+        } else {
+            return false;
+        }
+    }
+    // }}}
+
+    // {{{ function setPrevious()
+    /**
+     * Sets the pointer for the previous node in the linked list
+     * to the specified node
+     *
+     * @param Structures_LinkedList_DoubleNode $node new previous node
+     * in the linked list
+     *
+     * @return Structures_LinkedList_DoubleNode new previous node in
+     * the linked list
+     */
+    public function setPrevious($node = null)
+    {
+        $this->previous = $node;
+        return $this->previous;
+    }
+    // }}}
+
+}
+// }}}
+
+?>
diff --git a/vendor/Structures/LinkedList/Single.php b/vendor/Structures/LinkedList/Single.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f0d7078b5abf02c47692dbe4f56d60dce7e5f5a
--- /dev/null
+++ b/vendor/Structures/LinkedList/Single.php
@@ -0,0 +1,535 @@
+<?php
+
+/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker textwidth=80: */
+
+/**
+ * Linked list structure
+ * 
+ * This package implements a singly linked list structure. Each node
+ * (Structures_LinkedList_SingleNode object) in the list
+ * (Structures_LinkedList_Single) knows the the next node in the list.
+ * Unlike an array, you can insert or delete nodes at arbitrary points
+ * in the list.
+ *
+ * If your application normally traverses the linked list in a forward-only
+ * direction, use the singly-linked list implemented by
+ * {@link Structures_LinkedList_Single}. If, however, your application
+ * needs to traverse the list backwards, or insert nodes into the list before
+ * other nodes in the list, use the double-linked list implemented by
+ * {@link Structures_LinkedList_Double} to give your application better
+ * performance at the cost of a slightly larger memory footprint.
+ *
+ * Structures_LinkedList_Single implements the Iterator interface so control
+ * structures like foreach($list as $node) and while($list->next()) work
+ * as expected.
+ *
+ * To use this package, derive a child class from
+ * Structures_LinkedList_SingleNode and add data to the object. Then use the
+ * Structures_LinkedList_Single class to access the nodes.
+ *
+ * PHP version 5
+ *
+ * LICENSE:  Copyright 2006 Dan Scott
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @category  Structures
+ * @package   Structures_LinkedList_Single
+ * @author    Dan Scott <dscott@laurentian.ca>
+ * @copyright 2006 Dan Scott
+ * @license   http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
+ * @version   CVS: $Id: Single.php -1   $
+ * @link      http://pear.php.net/package/Structures_LinkedList_Single
+ * @example   single_link_example.php
+ *
+ * @todo Add some actual error conditions
+ **/
+
+require_once 'PEAR/Exception.php';
+
+// {{{ class Structures_LinkedList_Single
+/**
+ * The Structures_LinkedList_Single class represents a linked list structure
+ * composed of {@link Structures_LinkedList_SingleNode} objects.
+ *
+ * @category Structures
+ * @package  Structures_LinkedList_Single
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
+ * @link     http://pear.php.net/package/Structures_LinkedList_Single
+ */
+class Structures_LinkedList_Single implements Iterator
+{
+    // {{{ properties
+    /**
+     * Current node in the linked list
+     * @var Structures_LinkedList_SingleNode
+     */
+    protected $current;
+
+    /**
+     * Root node of the linked list
+     * @var Structures_LinkedList_SingleNode
+     */
+    protected $root_node;
+
+    /**
+     * The linked list contains no nodes
+     */
+    const ERROR_EMPTY = -1;
+
+    public static $messages = array(
+        self::ERROR_EMPTY => 'No nodes in this linked list' 
+    );
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Structures_LinkedList_Single constructor
+     *
+     * @param Structures_LinkedList_SingleNode $root root node for the
+     * linked list
+     */
+    function __construct(Structures_LinkedList_SingleNode $root = null)
+    {
+        if ($root) {
+            $this->root_node = $root;
+            $this->current = $root;
+        } else {
+            $this->root_node = null;
+            $this->current = null;
+        }
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Structures_LinkedList_Single destructor
+     *
+     * If we do not destroy all of the references in the linked list,
+     * we will quickly run out of memory for large / complex structures.
+     *
+     */
+    function __destruct()
+    {
+        /*
+         * Starting with root node, set last node = root_node
+         *   get next node
+         *   if next node exists, delete last node reference to next node
+         */
+        if (!$last_node = $this->root_node) {
+            return;
+        }
+        while (($next_node = $last_node->next()) !== false) {
+            $last_node->setNext(null);
+            $temp_node = $last_node;
+            $last_node = $next_node;
+            unset($temp_node);
+        }
+        $this->current = null;
+        $this->root_node = null;
+        $last_node = null;
+        $next_node = null;
+    }
+    // }}}
+
+    // {{{ function current()
+    /**
+     * Returns the current node in the linked list
+     *
+     * @return Structures_LinkedList_SingleNode current node in the linked list
+     */
+    public function current()
+    {
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ function rewind()
+    /**
+     * Sets the pointer for the linked list to the root node
+     *
+     * @return Structures_LinkedList_SingleNode root node in the linked list
+     */
+    public function rewind()
+    {
+        if ($this->root_node) {
+            $this->current = $this->root_node;
+        } else {
+            $this->current = null;
+        }
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ function end()
+    /**
+     * Sets the pointer for the linked list to the root node
+     *
+     * @return Structures_LinkedList_SingleNode root node in the linked list
+     */
+    public function end()
+    {
+        $this->current = $this->getTailNode();
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ function key()
+    /**
+     * Stub for Iterator interface that simply returns the current node
+     *
+     * @return Structures_LinkedList_SingleNode current node in the linked list
+     */
+    public function key()
+    {
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ function valid()
+    /**
+     * Stub for Iterator interface that simply returns the current node
+     *
+     * @return Structures_LinkedList_SingleNode current node in the linked list
+     */
+    public function valid()
+    {
+        return $this->current();
+    }
+    // }}}
+
+    // {{{ function next()
+    /**
+     * Sets the pointer for the linked list to the next node and
+     * returns that node
+     *
+     * @return Structures_LinkedList_SingleNode next node in the linked list
+     */
+    public function next()
+    {
+        if (!$this->current) {
+            return false;
+        }
+        $this->current = $this->current()->next();
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ function previous()
+    /**
+     * Sets the pointer for the linked list to the previous node and
+     * returns that node
+     *
+     * @return Structures_LinkedList_SingleNode previous node in the linked list
+     */
+    public function previous()
+    {
+        if (!$this->current) {
+            return false;
+        }
+        $this->current = $this->_getPreviousNode();
+        return $this->current;
+    }
+    // }}}
+
+    // {{{ protected function getTailNode()
+    /**
+     * Returns the tail node of the linked list.
+     *
+     * This is an expensive operation!
+     *
+     * @return bool Success or failure
+     **/
+    protected function getTailNode()
+    {
+        $tail_node = $this->root_node;
+        while (($y = $tail_node->next()) !== false) {
+            $tail_node = $y;
+        }
+        return $tail_node;
+    }
+    // }}}
+
+    // {{{ private function _getPreviousNode()
+    /**
+     * Returns the node prior to the current node in the linked list.
+     *
+     * This is an expensive operation for a singly linked list!
+     *
+     * @param Structures_LinkedList_SingleNode $node (Optional) Specific node 
+     * for which we want to find the previous node
+     *
+     * @return Structures_LinkedList_SingleNode Previous node
+     **/
+    private function _getPreviousNode($node = null)
+    {
+        if (!$node) {
+            $node = $this->current;
+        }
+        $prior_node = $this->root_node;
+        while (($y = $prior_node->next()) !== false) {
+            if ($y == $node) {
+                return $prior_node;
+            }
+            $prior_node = $y;
+        }
+        return null;
+    }
+    // }}}
+
+    // {{{ function appendNode()
+    /**
+     * Adds a {@link Structures_LinkedList_SingleNode} object to the end of
+     * the linked list.
+     *
+     * @param Structures_LinkedList_SingleNode $new_node New node to append
+     *
+     * @return bool Success or failure
+     **/
+    public function appendNode(Structures_LinkedList_SingleNode $new_node)
+    {
+        if (!$this->root_node) {
+            $this->__construct($new_node);
+            return true;
+        }
+
+        // This is just a special case of insertNode()
+        $this->insertNode($new_node, $this->getTailNode());
+
+        return true;
+    }
+    // }}}
+
+    // {{{ function insertNode()
+    /**
+     * Inserts a {@link Structures_LinkedList_SingleNode} object into the linked
+     * list, based on a reference node that already exists in the list.
+     *
+     * @param Structures_LinkedList_SingleNode $new_node      New node to add to
+     * the list
+     * @param Structures_LinkedList_SingleNode $existing_node Reference
+     * position node
+     * @param bool                             $before        Insert new node
+     * before or after the existing node
+     *
+     * @return bool Success or failure
+     **/
+    public function insertNode($new_node, $existing_node, $before = false)
+    {
+        if (!$this->root_node) {
+            $this->__construct($new_node);
+            return true;
+        }
+
+        // Now add the node according to the requested mode
+        switch ($before) {
+
+        case true:
+            if ($existing_node === $this->root_node) {
+                $this->root_node = $new_node;
+            }
+            $previous_node = $this->_getPreviousNode($existing_node);
+            if ($previous_node) {
+                $previous_node->setNext($new_node);
+            }
+            $new_node->setNext($existing_node);
+
+            break;
+
+        case false:
+            $next_node = $existing_node->next();
+            if ($next_node) {
+                $new_node->setNext($next_node);
+            }
+            $existing_node->setNext($new_node);
+
+            break;
+
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ function prependNode()
+    /**
+     * Adds a {@link Structures_LinkedList_SingleNode} object to the start
+     * of the linked list.
+     *
+     * @param Structures_LinkedList_SingleNode $new_node Node to prepend
+     * to the list
+     *
+     * @return bool Success or failure
+     **/
+    public function prependNode(Structures_LinkedList_SingleNode $new_node)
+    {
+        if (!$this->root_node) {
+            $this->__construct($new_node);
+            return true;
+        }
+
+        // This is just a special case of insertNode()
+        $this->insertNode($new_node, $this->root_node, true);
+
+        return true;
+    }
+    // }}}
+
+    // {{{ function deleteNode()
+    /**
+     * Deletes a {@link Structures_LinkedList_SingleNode} from the list.
+     *
+     * @param Structures_LinkedList_SingleNode $node Node to delete.
+     *
+     * @return null
+     */
+    public function deleteNode($node)
+    {
+        /* If this is the root node, and there are more nodes in the list,
+         * make the next node the new root node before deleting this node.
+         */
+        if ($node === $this->root_node) {
+            $this->root_node = $node->next();
+        }
+        
+        /* If this is the current node, make the next node the current node.
+         *
+         * If that fails, null isn't such a bad place to be.
+         */
+        if ($node === $this->current) {
+            if ($node->next()) {
+                $this->current = $node->next();
+            } else {
+                $this->current = null;
+            }
+        }
+        $node->__destruct();
+    }
+    // }}}
+
+}
+// }}}
+
+// {{{ class Structures_LinkedList_SingleNode
+/**
+ * The Structures_LinkedList_SingleNode class represents a node in a
+ * {@link Structures_LinkedList_Single} linked list structure.
+ *
+ * @category Structures
+ * @package  Structures_LinkedList_Single
+ * @author   Dan Scott <dscott@laurentian.ca>
+ * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
+ * @link     http://pear.php.net/package/Structures_LinkedList_Single
+ */
+class Structures_LinkedList_SingleNode
+{
+    // {{{ properties
+    /**
+     * Next node in the linked list
+     * @var Structures_LinkedList_SingleNode
+     */
+    protected $next;
+    // }}}
+
+    // {{{ Constructor: function __construct()
+    /**
+     * Structures_LinkedList_SingleNode constructor
+     */
+    public function __construct()
+    {
+        $this->next = null;
+    }
+    // }}}
+
+    // {{{ Destructor: function __destruct()
+    /**
+     * Removes node from the list, adjusting the related nodes accordingly.
+     *
+     * This is a problem if the node is the root node for the list.
+     * At this point, however, we do not have access to the list itself. Hmm.
+     */
+    public function __destruct()
+    {
+    }
+    // }}}
+
+    // {{{ function next()
+    /**
+     * Return the next node in the linked list
+     *
+     * @return Structures_LinkedList_SingleNode next node in the linked list
+     */
+    public function next()
+    {
+        if ($this->next) {
+            return $this->next;
+        } else {
+            return false;
+        }
+    }
+    // }}}
+
+    // {{{ function previous()
+    /**
+     * Return the previous node in the linked list
+     *
+     * Stub method for Structures_LinkedList_DoubleNode to override.
+     *
+     * @return Structures_LinkedList_SingleNode previous node in the linked list
+     */
+    public function previous()
+    {
+        return false;
+    }
+    // }}}
+
+    // {{{ function setNext()
+    /**
+     * Sets the pointer for the next node in the linked list to the
+     * specified node
+     *
+     * @param Structures_LinkedList_SingleNode $node new next node in
+     * the linked list
+     *
+     * @return Structures_LinkedList_SingleNode new next node in the linked list
+     */
+    public function setNext($node = null)
+    {
+        $this->next = $node;
+        return $this->next;
+    }
+    // }}}
+
+    // {{{ function setPrevious()
+    /**
+     * Sets the pointer for the next node in the linked list to the
+     * specified node
+     *
+     * Stub method for Structures_LinkedList_DoubleNode to override.
+     *
+     * @param Structures_LinkedList_SingleNode $node new next node in
+     * the linked list
+     *
+     * @return Structures_LinkedList_SingleNode new next node in the linked list
+     */
+    public function setPrevious($node = null)
+    {
+        return false;
+    }
+    // }}}
+}
+
+// }}}
+
+?>
diff --git a/vendor/Validate/ISPN.php b/vendor/Validate/ISPN.php
new file mode 100644
index 0000000000000000000000000000000000000000..85eca16dff652ba69bab47c15648a680da206517
--- /dev/null
+++ b/vendor/Validate/ISPN.php
@@ -0,0 +1,371 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2005 Piotr Klaban, Damien Seguy, Helgi Þormar     |
+// |                        Þorbjörnsson, Pierre-Alain Joye               |
+// +----------------------------------------------------------------------+
+// | This source file is subject to the New BSD license, That is bundled  |
+// | with this package in the file LICENSE, and is available through      |
+// | the world-wide-web at                                                |
+// | http://www.opensource.org/licenses/bsd-license.php                   |
+// | If you did not receive a copy of the new BSDlicense and are unable   |
+// | to obtain it through the world-wide-web, please send a note to       |
+// | pajoye@php.net so we can mail you a copy immediately.                |
+// +----------------------------------------------------------------------+
+// | Author: Tomas V.V.Cox  <cox@idecnet.com>                             |
+// |         Pierre-Alain Joye <pajoye@php.net>                           |
+// +----------------------------------------------------------------------+
+//
+/**
+ * Specific validation methods for International Standard Product Numbers (ISPN)
+ *
+ * @category   Validate
+ * @package    Validate_ISPN
+ * @author     Piotr Klaban <makler@man.torun.pl>
+ * @author     Damien Seguy <dams@nexen.net>
+ * @author     Helgi Þormar Þorbjörnsson <dufuz@php.net>
+ * @copyright   1997-2005 Piotr Klaban, Damien Seguy, Helgi Þormar Þorbjörnsson,
+ *                        Pierre-Alain Joye
+ * @license    http://www.opensource.org/licenses/bsd-license.php  new BSD
+ * @version    CVS: $Id: ISPN.php,v 1.13 2006/08/17 19:20:51 makler Exp $
+ * @link       http://pear.php.net/package/Validate_ISPN
+ */
+
+/**
+ * Data validation class for International Standard Product Numbers (ISPN)
+ *
+ * This class provides methods to validate:
+ *  - ISBN (International Standard Book Number)
+ *  - ISSN (International Standard Serial Number)
+ *  - ISMN (International Standard Music Number)
+ *  - ISRC (International Standard Recording Code)
+ *  - EAN/UCC-8 number
+ *  - EAN/UCC-13 number
+ *  - EAN/UCC-14 number
+ *  - UCC-12 (U.P.C.) ID number
+ *  - SSCC (Serial Shipping Container Code)
+ *
+ * @category   Validate
+ * @package    Validate_ISPN
+ * @author     Piotr Klaban <makler@man.torun.pl>
+ * @author     Damien Seguy <dams@nexen.net>
+ * @author     Helgi Þormar Þorbjörnsson <dufuz@php.net>
+ * @copyright   1997-2005 Piotr Klaban, Damien Seguy, Helgi Þormar Þorbjörnsson,
+ *                        Pierre-Alain Joye
+ * @license    http://www.opensource.org/licenses/bsd-license.php  new BSD
+ * @version    Release: @package_version@
+ * @link       http://pear.php.net/package/Validate_ISPN
+ */
+class Validate_ISPN
+{
+    function isbn($isbn)
+    {
+        if (preg_match("/[^0-9 IXSBN-]/", $isbn)) {
+            return false;
+        }
+
+        $isbn = strtoupper($isbn);
+        $isbn = str_replace(array('ISBN', '-', ' ', "\t", "\n"), '', $isbn);
+
+        if (strlen($isbn) == 13) {
+            return Validate_ISPN::isbn13($isbn);
+        } elseif (strlen($isbn) == 10) {
+            return Validate_ISPN::isbn10($isbn);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Validate a ISBN 13 number
+     * The ISBN is a unique machine-readable identification number,
+     * which marks any book unmistakably.
+     *
+     * This function checks given number according
+     *
+     * Manual can be found at http://www.isbn-international.org
+     *
+     * @param  string  $isbn number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @author Helgi Þormar <dufuz@php.net>
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function isbn13($isbn)
+    {
+        if (preg_match("/[^0-9 ISBN-]/", $isbn)) {
+            return false;
+        }
+
+        $isbn = strtoupper($isbn);
+        $isbn = str_replace(array('ISBN', '-', ' ', "\t", "\n"), '', $isbn);
+        if (!preg_match('/^[0-9]{13}$/', $isbn)) {
+            return false;
+        }
+
+        return Validate_ISPN::ean13($isbn);
+    }
+
+    /**
+     * Validate a ISBN 10 number
+     * The ISBN is a unique machine-readable identification number,
+     * which marks any book unmistakably.
+     *
+     * This function checks given number according
+     *
+     * Manual can be found at http://www.isbn-international.org
+     *
+     * @param  string  $isbn number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @author Damien Seguy <dams@nexen.net>
+     * @author Helgi Þormar <dufuz@php.net>
+     */
+    function isbn10($isbn)
+    {
+        static  $weights_isbn = array(10,9,8,7,6,5,4,3,2);
+
+        if (preg_match("/[^0-9 IXSBN-]/", $isbn)) {
+            return false;
+        }
+
+        $isbn = strtoupper($isbn);
+        $isbn = str_replace(array('ISBN', '-', ' ', "\t", "\n"), '', $isbn);
+        if (strlen($isbn) != 10) {
+            return false;
+        }
+
+        if (!preg_match('/^[0-9]{9}[0-9X]$/', $isbn)) {
+            return false;
+        }
+
+        // Requires base class Validate
+        require_once 'Validate.php';
+        return Validate::_checkControlNumber($isbn, $weights_isbn, 11, 11);
+    }
+
+
+    /**
+     * Validate an ISSN (International Standard Serial Number)
+     *
+     * This function checks given ISSN number
+     * ISSN identifies periodical publications:
+     * http://www.issn.org
+     *
+     * @param  string  $issn number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function issn($issn)
+    {
+        static $weights_issn = array(8,7,6,5,4,3,2);
+
+        $issn = strtoupper($issn);
+        $issn = str_replace(array('ISSN', '-', '/', ' ', "\t", "\n"), '', $issn);
+        $issn_num = str_replace('X', '0', $issn);
+
+        // check if this is an 8-digit number
+        if (!is_numeric($issn_num) || strlen($issn) != 8) {
+            return false;
+        }
+
+        // Requires base class Validate
+        require_once 'Validate.php';
+        return Validate::_checkControlNumber($issn, $weights_issn, 11, 11);
+    }
+
+    /**
+     * Validate a ISMN (International Standard Music Number)
+     *
+     * This function checks given ISMN number (ISO Standard 10957)
+     * ISMN identifies all printed music publications from all over the world
+     * whether available for sale, hire or gratis--whether a part, a score,
+     * or an element in a multi-media kit.
+     *
+     * Manual can be found at:
+     * http://www.ismn-international.org/
+     *
+     * @param  string  $ismn ISMN number
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function ismn($ismn)
+    {
+        static $weights_ismn = array(3,1,3,1,3,1,3,1,3);
+
+        $ismn = strtoupper($ismn);
+        $ismn = str_replace(array('ISMN', '-', '/', ' ', "\t", "\n"), '', $ismn);
+        // First char has to be M (after ISMN has been stripped if present)
+        if ($ismn{0} != 'M') {
+            return false;
+        }
+
+        // change M to 3
+        $ismn{0} = 3;
+
+        // check if this is a 10-digit number
+        if (!is_numeric($ismn) || strlen($ismn) != 10) {
+            return false;
+        }
+
+        // Requires base class Validate
+        require_once 'Validate.php';
+        return Validate::_checkControlNumber($ismn, $weights_ismn, 10, 10);
+    }
+
+    /**
+     * Validate a ISRC (International Standard Recording Code)
+     *
+     * This function validates an International Standard Recording Code
+     * which is the international identification system for sound recordings
+     * and music videorecordings.
+     *
+     * @param  string  $isrc ISRC number
+     * @return bool    true if number is valid, otherwise false
+     * @see    http://www.ifpi.org/isrc/isrc_handbook.html
+     * @access public
+     * @author David Grant <david@grant.org.uk>
+     */
+    function isrc($isrc)
+    {
+        $isrc = str_replace(array('ISRC', '-', ' '), '', strtoupper($isrc));
+        if (!preg_match("/[A-Z]{2}[A-Z0-9]{3}[0-9]{7}/", $isrc)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Validate a EAN/UCC-8 number
+     *
+     * This function checks given EAN8 number
+     * used to identify trade items and special applications.
+     * http://www.ean-ucc.org/
+     * http://www.uc-council.org/checkdig.htm
+     *
+     * @param  string  $ean number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @see Validate_ISPN::process()
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function ean8($ean)
+    {
+        static $weights_ean8 = array(3,1,3,1,3,1,3);
+        return Validate_ISPN::process($ean, 8, $weights_ean8, 10, 10);
+    }
+
+    /**
+     * Validate a EAN/UCC-13 number
+     *
+     * This function checks given EAN/UCC-13 number used to identify
+     * trade items, locations, and special applications (e.g., coupons)
+     * http://www.ean-ucc.org/
+     * http://www.uc-council.org/checkdig.htm
+     *
+     * @param  string  $ean number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @see Validate_ISPN::process()
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function ean13($ean)
+    {
+        static $weights_ean13 = array(1,3,1,3,1,3,1,3,1,3,1,3);
+        return Validate_ISPN::process($ean, 13, $weights_ean13, 10, 10);
+    }
+
+    /**
+     * Validate a EAN/UCC-14 number
+     *
+     * This function checks given EAN/UCC-14 number
+     * used to identify trade items.
+     * http://www.ean-ucc.org/
+     * http://www.uc-council.org/checkdig.htm
+     *
+     * @param  string  $ean number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @see Validate_ISPN::process()
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function ean14($ean)
+    {
+        static $weights_ean14 = array(3,1,3,1,3,1,3,1,3,1,3,1,3);
+        return Validate_ISPN::process($ean, 14, $weights_ean14, 10, 10);
+    }
+
+    /**
+     * Validate a UCC-12 (U.P.C.) ID number
+     *
+     * This function checks given UCC-12 number used to identify
+     * trade items, locations, and special applications (e.g., * coupons)
+     * http://www.ean-ucc.org/
+     * http://www.uc-council.org/checkdig.htm
+     *
+     * @param  string  $ucc number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @see Validate_ISPN::process()
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function ucc12($ucc)
+    {
+        static $weights_ucc12 = array(3,1,3,1,3,1,3,1,3,1,3);
+        return Validate_ISPN::process($ucc, 12, $weights_ucc12, 10, 10);
+    }
+
+    /**
+     * Validate a SSCC (Serial Shipping Container Code)
+     *
+     * This function checks given SSCC number
+     * used to identify logistic units.
+     * http://www.ean-ucc.org/
+     * http://www.uc-council.org/checkdig.htm
+     *
+     * @param  string  $sscc number (only numeric chars will be considered)
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @see Validate_ISPN::process()
+     * @author Piotr Klaban <makler@man.torun.pl>
+     */
+    function sscc($sscc)
+    {
+        static $weights_sscc = array(3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3);
+        return Validate_ISPN::process($sscc, 18, $weights_sscc, 10, 10);
+    }
+
+    /**
+     * Does all the work for EAN8, EAN13, EAN14, UCC12 and SSCC
+     * and can be used for as base for similar kind of calculations
+     *
+     * @param int $data number (only numeric chars will be considered)
+     * @param int $lenght required length of number string
+     * @param int $modulo (optionsl) number
+     * @param int $subtract (optional) numbier
+     * @param array $weights holds the weight that will be used in calculations for the validation
+     * @return bool    true if number is valid, otherwise false
+     * @access public
+     * @see Validate::_checkControlNumber()
+     */
+    function process($data, $length, &$weights, $modulo = 10, $subtract = 0)
+    {
+        //$weights = array(3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3);
+        //$weights = array_slice($weights, 0, $length);
+
+        $data = str_replace(array('-', '/', ' ', "\t", "\n"), '', $data);
+
+        // check if this is a digit number and is the right length
+        if (!is_numeric($data) || strlen($data) != $length) {
+            return false;
+        }
+
+        // Requires base class Validate
+        require_once 'Validate.php';
+        return Validate::_checkControlNumber($data, $weights, $modulo, $subtract);
+    }
+}
+?>
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
index 71800b6247d51952289c36157803ff51aaa0494b..425bed3f392ed9edf0544deb2ba1ae91c73e6e18 100644
--- a/vendor/composer/autoload_namespaces.php
+++ b/vendor/composer/autoload_namespaces.php
@@ -4,5 +4,11 @@ $vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(
+    'File' => $vendorDir,
+    'Horde' => $vendorDir,
+    'PEAR' => $vendorDir,
+    'SerialsSolutions' => $vendorDir,
+    'Structures' => $vendorDir,
+    'Validate' => $vendorDir,
     'Zend' => $vendorDir . '/ZF2/library/',
 );